Sarek_vulkan.Vulkan_api_kernelmodule Device = Vulkan_api_devicemodule Memory = Vulkan_api_memorymodule Stream = Vulkan_api_streamtype t = {shader_module : Vulkan_types.vk_shader_module;pipeline : Vulkan_types.vk_pipeline;pipeline_layout : Vulkan_types.vk_pipeline_layout;descriptor_set_layout : Vulkan_types.vk_descriptor_set_layout;descriptor_pool : Vulkan_types.vk_descriptor_pool;descriptor_set : Vulkan_types.vk_descriptor_set;name : string;num_bindings : int;device : Device.t;}Existential wrapper to hide buffer type parameter
Scalar kernel argument, tagged with its byte width/value so the push-constant block can be materialized in one pass at launch time (see build_push_constants) instead of being appended byte-by-byte in whatever order set_arg_* happens to be called.
type args = {buffer_store : any_buffer Spoc_framework.Kernel_args.t;scalar_store : scalar_arg Spoc_framework.Kernel_args.t;mutable descriptor_set : Vulkan_types.vk_descriptor_set;}val resolve_bindings : args -> (int * any_buffer) listVulkan descriptor binding numbers are assigned to buffer-typed kernel parameters only, in the order those parameters appear in the kernel signature (see the GLSL codegen, which numbers `layout(binding = N)` this way, skipping scalar parameters entirely). Since kernel-arg idx is shared across buffers and scalars, idx itself is not usable as a binding number directly; instead the buffer with the Nth-smallest idx among buffer args gets binding N. Because buffers cannot be reordered by the caller relative to each other without also changing which kernel parameter they represent, this rank-by-idx is stable and order-of-call-independent, unlike the previous per-call sequential counter it replaces.
val validate_buffer_indices :
expected_count:int ->
'a Spoc_framework.Kernel_args.t ->
(unit, string) Stdlib.resultValidate the set of buffer-argument indices actually bound in store against the number of buffer bindings the compiled kernel expects (expected_count, derived from the GLSL source's `binding = N` declarations \- see num_bindings in compile).
resolve_bindings above silently compresses whatever indices are present into dense, ascending descriptor bindings; that rank-mapping is correct for a valid index *set*, but gives no signal at all if the caller passed a nonsensical one (negative indices, or simply the wrong number of buffers - e.g. a caller-side idx typo that drops one buffer and duplicates another slot). This checks the set's sanity before resolve_bindings's compression can paper over it. Exposed for direct unit testing (no hardware required).
val cache : (string, t) Spoc_framework.Guarded_cache.tval create_shader_module : Device.t -> string -> Vulkan_types.vk_shader_moduleCreate shader module from SPIR-V
val create_args : unit -> argsval set_arg_buffer : args -> int -> 'a Memory.buffer -> unitval set_arg_int32 : args -> int -> int32 -> unitval set_arg_int64 : args -> int -> int64 -> unitval set_arg_float32 : args -> int -> float -> unitval set_arg_float64 : args -> int -> float -> unitval build_push_constants : args -> bytes optionMaterialize the push-constant byte block for args at launch time, from the full ordered argument set (buffers + scalars), matching EXACTLY the GLSL block layout emitted by Sarek_ir_glsl.gen_push_constants (sarek/codegen/Sarek_ir_glsl.ml:889-919): all vector lengths first, in vector-declaration order, followed by all user scalar parameters, in declaration order.
vectors list, which is built by iterating kernel params in order).scalars list, same iteration).This must not be done incrementally inside each set_arg_* call: the caller may invoke those in any call order (e.g. a vector, then a scalar, then another vector), which does not match the GLSL grouping, so the block can only be assembled correctly once every argument is known.
val launch :
t ->
args:args ->
grid:Spoc_framework.Framework_sig.dims ->
block:Spoc_framework.Framework_sig.dims ->
shared_mem:'a ->
stream:Stream.t option ->
unit