anchor.diff:          VkRaw.vkQueueSubmit(x.Handle, 1u, &&submitInfo, VkFence.Null) 
               |> check "vkQueueWaitSemaphore"
   
  +    member x.Signal() =
  +        let sem = device.CreateSemaphore()
  +        let mutable semHandle = sem.Handle
  +        let mutable submitInfo =
  +            VkSubmitInfo(
  +                VkStructureType.SubmitInfo, 0n, 
  +                0u, NativePtr.zero, NativePtr.zero,
  +                0u, NativePtr.zero,
  +                1u, &&semHandle
  +            )
  +
  +        VkRaw.vkQueueSubmit(x.Handle, 1u, &&submitInfo, VkFence.Null) 
  +            |> check "vkQueueWaitSemaphore"
  +
  +        sem
  +
       member x.WaitIdle() =
           VkRaw.vkQueueWaitIdle(x.Handle)
               |> check "could not wait for queue"
  
positive.code:     member x.RunSynchronously(cmd : CommandBuffer) =
          let q = x.GetQueue()
          q.RunSynchronously(cmd)
  
      member x.GetQueue () : DeviceQueue =
          let next = Interlocked.Change(&current, fun c -> (c + 1) % store.Length)
  
negative.code: 
  and IQueueCommand =
      abstract member Compatible : QueueFlags
      abstract member TryEnqueue : queue : DeviceQueue * disp : byref<Disposable> -> bool
  
  and DeviceToken(queue : DeviceQueue, ref : ref<Option<DeviceToken>>) =
      let mutable current             : Option<CommandBuffer> = None
      let disposables                 : List<Disposable>      = List()
  
      let mutable isEmpty = true
      let mutable refCount = 1
  
      let cleanup() =
          for d in disposables do d.Dispose()
          disposables.Clear()
  
          match current with
              | Some b -> 
                  b.Dispose()
                  current <- None
              | _ -> ()
  
      let enqueue (buffer : CommandBuffer) (cmd : ICommand) =
          let mutable disp = Disposable.Empty
          if cmd.TryEnqueue(buffer, &disp) then
              if not (isNull disp) then disposables.Add disp
          else
              cleanup()
              failf "could not enqueue command: %A" cmd
  
      let flush() =
          match current with
              | Some buffer ->
                  buffer.End()
                  disposables.Add { new Disposable() with member x.Dispose() = buffer.Dispose() }
                  if not buffer.IsEmpty then
                      isEmpty <- false
                      queue.Start(buffer)
                  current <- None
  
              | None ->
                  ()
  
      member x.Flush() =
          flush()
  
      member x.Sync() =
          flush()
          if not isEmpty then queue.WaitIdle()
  
      member x.AddCleanup(f : unit -> unit) =
          disposables.Add { new Disposable() with member x.Dispose() = f() }
  
      member x.Enqueue (cmd : ICommand) =
          match current with
              | Some buffer -> 
                  enqueue buffer cmd
                  
              | None ->
                  let buffer = queue.Family.DefaultCommandPool.CreateCommandBuffer CommandBufferLevel.Primary
                  buffer.Begin CommandBufferUsage.OneTimeSubmit
                  current <- Some buffer
                  enqueue buffer cmd
  
      member x.Enqueue (cmd : IQueueCommand) =
          flush ()
          let mutable disp = Disposable.Empty
          if cmd.TryEnqueue(queue, &disp) then
              if not (isNull disp) then disposables.Add disp
              isEmpty <- false
          else
              cleanup()
              failf "could not enqueue command: %A" cmd
  
      member internal x.AddRef() = 
          refCount <- refCount + 1
  
      member internal x.RemoveRef() = 
          refCount <- refCount - 1
          if refCount = 0 then 
              ref := None
              x.Sync()
              cleanup()
  
      member x.Dispose() =
          x.RemoveRef()
  
      interface IDisposable with
          member x.Dispose() = x.Dispose()
  
  [<AbstractClass; Sealed; Extension>]
  type DeviceExtensions private() =
  