Module Sarek_vulkan.Vulkan_api_slot

State of the launch batches: a stream's two command-buffer slots, the per-device registry of streams, and the helpers that need no queue access (specs/vulkan-async-launches.md).

module Device = Vulkan_api_device
type slot = {
  1. command_buffer : Vulkan_types.vk_command_buffer Ctypes.structure Ctypes.ptr;
  2. fence : Vulkan_api_base.tracked_fence;
  3. pools : Vulkan_api_pools.t;
  4. mutable kernels : string list;
    (*

    Newest first, one entry per dispatch.

    *)
  5. mutable dispatches : int;
  6. mutable recording : bool;
  7. mutable ended : bool;
    (*

    Set just before vkEndCommandBuffer is called, after the end-of-batch barrier was recorded: from here the command buffer's state is unknown to the host after an escaped exception, and the batch may or may not run.

    *)
  8. mutable cb_open : bool;
    (*

    The command buffer may be in the recording state: set just before vkBeginCommandBuffer is called, cleared after vkEndCommandBuffer or a reset. A begin on an open buffer is invalid; Vulkan_api_batch counts it.

    *)
  9. mutable armed : bool;
    (*

    The fence was reset for a submission that may have reached the queue: set after the reset and before vkQueueSubmit, cleared by retire. An exception escaping while armed leaves it unknown whether the batch is running.

    *)
}

One command buffer with what its dispatches use. Idle: not recording, not armed and fence not pending. Open: recording. In flight: fence pending.

type awaited_event = {
  1. event_lock : Stdlib.Mutex.t;
  2. event_fence : Vulkan_api_base.tracked_fence;
}

An event a stream has been told to wait for (stream_wait_event): its fence and the lock that serialises waits on it.

type stream = {
  1. command_pool : Vulkan_types.vk_command_pool;
  2. slots : slot array;
  3. mutable active : int;
    (*

    Index of the slot the next dispatch records in.

    *)
  4. destroyed : bool Stdlib.Atomic.t;
  5. mutable deferred : (string * string) option;
    (*

    Kernels and reason of a submission that failed while launching; raised by the next wait of this stream.

    *)
  6. mutable awaited : awaited_event list;
    (*

    Events this stream waits for, newest first, guarded by batch_lock. Later work on the stream is ordered after them by the single queue and the barrier before every dispatch; the host-side effect is that Vulkan_api_batch.synchronize also waits for them. Emptied by that wait.

    *)
  7. device : Device.t;
}
val allocate_command_buffer : Device.t -> Vulkan_types.vk_command_pool -> Vulkan_types.vk_command_buffer Ctypes.structure Ctypes_static.ptr
val create_stream : Device.t -> stream

Registry

The streams of each device, so that a launch, a host access or a device wait can reach the batches of every stream. registry_lock guards short table operations only and is never held across a call that can block.

val registry : (int, stream list) Stdlib.Hashtbl.t
val registry_lock : Stdlib.Mutex.t
val default_streams : (int, stream) Stdlib.Hashtbl.t
val default_lock : Stdlib.Mutex.t

Guards default_streams.

val streams_of : Device.t -> stream list
val register : stream -> unit
val unregister : stream -> unit
val names_of_kernels : Stdlib.String.t list -> string

Kernel names of slot in launch order, a repeated name written once with its count.

val kernel_names : slot -> string
val retire : stream -> slot -> unit

The slot's work is over (completed, or never submitted): its descriptor sets and kernel list are released.

val is_idle : slot -> bool
val all_idle : Device.t -> bool
val destroy_slot : Device.t -> slot -> unit
val destroy_objects : stream -> unit