spirv_std/arch/mesh_shading.rs
1#[cfg(target_arch = "spirv")]
2use core::arch::asm;
3
4/// Sets the actual output size of the primitives and vertices that the mesh shader
5/// workgroup will emit upon completion.
6///
7/// 'Vertex Count' must be a 32-bit unsigned integer value.
8/// It defines the array size of per-vertex outputs.
9///
10/// 'Primitive Count' must a 32-bit unsigned integer value.
11/// It defines the array size of per-primitive outputs.
12///
13/// The arguments are taken from the first invocation in each workgroup.
14/// Any invocation must execute this instruction no more than once and under
15/// uniform control flow.
16/// There must not be any control flow path to an output write that is not preceded
17/// by this instruction.
18///
19/// This instruction is only valid in the *`MeshEXT`* Execution Model.
20///
21/// # Safety
22/// * Must be called **exactly once** in mesh shaders
23/// * Must be called in uniform control flow
24/// * Must not write any output before this instruction in invoked
25#[spirv_std_macros::gpu_only]
26#[doc(alias = "OpSetMeshOutputsEXT")]
27#[inline]
28pub unsafe fn set_mesh_outputs_ext(vertex_count: u32, primitive_count: u32) {
29 unsafe {
30 asm! {
31 "OpSetMeshOutputsEXT {vertex_count} {primitive_count}",
32 vertex_count = in(reg) vertex_count,
33 primitive_count = in(reg) primitive_count,
34 }
35 }
36}
37
38/// Defines the grid size of subsequent mesh shader workgroups to generate
39/// upon completion of the task shader workgroup.
40///
41/// 'Group Count X Y Z' must each be a 32-bit unsigned integer value.
42/// They configure the number of local workgroups in each respective dimensions
43/// for the launch of child mesh tasks. See Vulkan API specification for more detail.
44///
45/// 'Payload' is an optional pointer to the payload structure to pass to the generated mesh shader invocations.
46/// 'Payload' must be the result of an *`OpVariable`* with a storage class of *`TaskPayloadWorkgroupEXT`*.
47///
48/// The arguments are taken from the first invocation in each workgroup.
49/// Any invocation must execute this instruction exactly once and under uniform
50/// control flow.
51/// This instruction also serves as an *OpControlBarrier* instruction, and also
52/// performs and adheres to the description and semantics of an *OpControlBarrier*
53/// instruction with the 'Execution' and 'Memory' operands set to *Workgroup* and
54/// the 'Semantics' operand set to a combination of *`WorkgroupMemory`* and
55/// *`AcquireRelease`*.
56/// Ceases all further processing: Only instructions executed before
57/// *`OpEmitMeshTasksEXT`* have observable side effects.
58///
59/// This instruction must be the last instruction in a block.
60///
61/// This instruction is only valid in the *`TaskEXT`* Execution Model.
62///
63/// # Safety
64/// * Must be called **exactly once** in task shaders
65/// * Must be called in uniform control flow
66#[spirv_std_macros::gpu_only]
67#[doc(alias = "OpEmitMeshTasksEXT")]
68#[inline]
69pub unsafe fn emit_mesh_tasks_ext(group_count_x: u32, group_count_y: u32, group_count_z: u32) -> ! {
70 unsafe {
71 asm! {
72 "OpEmitMeshTasksEXT {group_count_x} {group_count_y} {group_count_z}",
73 group_count_x = in(reg) group_count_x,
74 group_count_y = in(reg) group_count_y,
75 group_count_z = in(reg) group_count_z,
76 options(noreturn),
77 }
78 }
79}
80
81/// Defines the grid size of subsequent mesh shader workgroups to generate
82/// upon completion of the task shader workgroup.
83///
84/// 'Group Count X Y Z' must each be a 32-bit unsigned integer value.
85/// They configure the number of local workgroups in each respective dimensions
86/// for the launch of child mesh tasks. See Vulkan API specification for more detail.
87///
88/// 'Payload' is an optional pointer to the payload structure to pass to the generated mesh shader invocations.
89/// 'Payload' must be the result of an *`OpVariable`* with a storage class of *`TaskPayloadWorkgroupEXT`*.
90///
91/// The arguments are taken from the first invocation in each workgroup.
92/// Any invocation must execute this instruction exactly once and under uniform
93/// control flow.
94/// This instruction also serves as an *OpControlBarrier* instruction, and also
95/// performs and adheres to the description and semantics of an *OpControlBarrier*
96/// instruction with the 'Execution' and 'Memory' operands set to *Workgroup* and
97/// the 'Semantics' operand set to a combination of *`WorkgroupMemory`* and
98/// *`AcquireRelease`*.
99/// Ceases all further processing: Only instructions executed before
100/// *`OpEmitMeshTasksEXT`* have observable side effects.
101///
102/// This instruction must be the last instruction in a block.
103///
104/// This instruction is only valid in the *`TaskEXT`* Execution Model.
105///
106/// # Safety
107/// * Must be called **exactly once** in task shaders
108/// * Must be called in uniform control flow
109#[spirv_std_macros::gpu_only]
110#[doc(alias = "OpEmitMeshTasksEXT")]
111#[inline]
112pub unsafe fn emit_mesh_tasks_ext_payload<T>(
113 group_count_x: u32,
114 group_count_y: u32,
115 group_count_z: u32,
116 payload: &mut T,
117) -> ! {
118 unsafe {
119 asm! {
120 "OpEmitMeshTasksEXT {group_count_x} {group_count_y} {group_count_z} {payload}",
121 group_count_x = in(reg) group_count_x,
122 group_count_y = in(reg) group_count_y,
123 group_count_z = in(reg) group_count_z,
124 payload = in(reg) payload,
125 options(noreturn),
126 }
127 }
128}