• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2019-2020 NVIDIA Corporation
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5[[indirectmdslayout]]
6== Indirect Commands Layout
7
8[open,refpage='VkIndirectCommandsLayoutNV',desc='Opaque handle to an indirect commands layout object',type='handles']
9--
10The device-side command generation happens through an iterative processing
11of an atomic sequence comprised of command tokens, which are represented by:
12
13include::{generated}/api/handles/VkIndirectCommandsLayoutNV.txt[]
14--
15
16
17=== Creation and Deletion
18
19[open,refpage='vkCreateIndirectCommandsLayoutNV',desc='Create an indirect command layout object',type='protos']
20--
21Indirect command layouts are created by:
22
23include::{generated}/api/protos/vkCreateIndirectCommandsLayoutNV.txt[]
24
25  * pname:device is the logical device that creates the indirect command
26    layout.
27  * pname:pCreateInfo is a pointer to a
28    sname:VkIndirectCommandsLayoutCreateInfoNV structure containing
29    parameters affecting creation of the indirect command layout.
30  * pname:pAllocator controls host memory allocation as described in the
31    <<memory-allocation, Memory Allocation>> chapter.
32  * pname:pIndirectCommandsLayout is a pointer to a
33    sname:VkIndirectCommandsLayoutNV handle in which the resulting indirect
34    command layout is returned.
35
36.Valid Usage
37****
38  * [[VUID-vkCreateIndirectCommandsLayoutNV-deviceGeneratedCommands-02929]]
39    The <<features-deviceGeneratedCommands,
40    sname:VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV::pname:deviceGeneratedCommands>>
41    feature must: be enabled
42****
43
44include::{generated}/validity/protos/vkCreateIndirectCommandsLayoutNV.txt[]
45--
46
47[open,refpage='VkIndirectCommandsLayoutCreateInfoNV',desc='Structure specifying the parameters of a newly created indirect commands layout object',type='structs']
48--
49The sname:VkIndirectCommandsLayoutCreateInfoNV structure is defined as:
50
51include::{generated}/api/structs/VkIndirectCommandsLayoutCreateInfoNV.txt[]
52
53  * pname:sType is the type of this structure.
54  * pname:pNext is `NULL` or a pointer to a structure extending this
55    structure.
56  * pname:pipelineBindPoint is the elink:VkPipelineBindPoint that this
57    layout targets.
58  * pname:flags is a bitmask of
59    elink:VkIndirectCommandsLayoutUsageFlagBitsNV specifying usage hints of
60    this layout.
61  * pname:tokenCount is the length of the individual command sequence.
62  * pname:pTokens is an array describing each command token in detail.
63    See elink:VkIndirectCommandsTokenTypeNV and
64    slink:VkIndirectCommandsLayoutTokenNV below for details.
65  * pname:streamCount is the number of streams used to provide the token
66    inputs.
67  * pname:pStreamStrides is an array defining the byte stride for each input
68    stream.
69
70The following code illustrates some of the flags:
71
72[source,c]
73~~~~
74void cmdProcessAllSequences(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsTokens, sequencesCount, indexbuffer, indexbufferOffset)
75{
76  for (s = 0; s < sequencesCount; s++)
77  {
78    sUsed = s;
79
80    if (indirectCommandsLayout.flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV) {
81      sUsed = indexbuffer.load_uint32( sUsed * sizeof(uint32_t) + indexbufferOffset);
82    }
83
84    if (indirectCommandsLayout.flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV) {
85      sUsed = incoherent_implementation_dependent_permutation[ sUsed ];
86    }
87
88    cmdProcessSequence( cmd, pipeline, indirectCommandsLayout, pIndirectCommandsTokens, sUsed );
89  }
90}
91~~~~
92
93.Valid Usage
94****
95  * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pipelineBindPoint-02930]]
96    The pname:pipelineBindPoint must: be
97    ename:VK_PIPELINE_BIND_POINT_GRAPHICS
98  * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-tokenCount-02931]]
99    pname:tokenCount must: be greater than `0` and less than or equal to
100    sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:maxIndirectCommandsTokenCount
101  * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pTokens-02932]]
102    If pname:pTokens contains an entry of
103    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV it must: be the
104    first element of the array and there must: be only a single element of
105    such token type
106  * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pTokens-02933]]
107    If pname:pTokens contains an entry of
108    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV there must: be only
109    a single element of such token type
110  * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pTokens-02934]]
111    All state tokens in pname:pTokens must: occur prior work provoking
112    tokens (ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV,
113    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV,
114    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV)
115  * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pTokens-02935]]
116    The content of pname:pTokens must: include one single work provoking
117    token that is compatible with the pname:pipelineBindPoint
118  * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-streamCount-02936]]
119    pname:streamCount must: be greater than `0` and less or equal to
120    sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:maxIndirectCommandsStreamCount
121  * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pStreamStrides-02937]]
122    each element of pname:pStreamStrides must: be greater than `0`and less
123    than or equal to
124    sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:maxIndirectCommandsStreamStride.
125    Furthermore the alignment of each token input must: be ensured
126****
127
128include::{generated}/validity/structs/VkIndirectCommandsLayoutCreateInfoNV.txt[]
129--
130
131[open,refpage='VkIndirectCommandsLayoutUsageFlagBitsNV',desc='Bitmask specifying allowed usage of an indirect commands layout',type='enums']
132--
133Bits which can: be set in
134slink:VkIndirectCommandsLayoutCreateInfoNV::pname:flags, specifying usage
135hints of an indirect command layout, are:
136
137include::{generated}/api/enums/VkIndirectCommandsLayoutUsageFlagBitsNV.txt[]
138
139  * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV
140    specifies that the layout is always used with the manual preprocessing
141    step through calling flink:vkCmdPreprocessGeneratedCommandsNV and
142    executed by flink:vkCmdExecuteGeneratedCommandsNV with `isPreprocessed`
143    set to ename:VK_TRUE.
144  * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV
145    specifies that the input data for the sequences is not implicitly
146    indexed from 0..sequencesUsed but a user provided sname:VkBuffer
147    encoding the index is provided.
148  * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV
149    specifies that the processing of sequences can: happen at an
150    implementation-dependent order, which is not: guaranteed to be coherent
151    using the same input data.
152--
153
154[open,refpage='VkIndirectCommandsLayoutUsageFlagsNV',desc='Bitmask of VkIndirectCommandsLayoutUsageFlagBitsNV',type='flags']
155--
156include::{generated}/api/flags/VkIndirectCommandsLayoutUsageFlagsNV.txt[]
157
158tname:VkIndirectCommandsLayoutUsageFlagsNV is a bitmask type for setting a
159mask of zero or more elink:VkIndirectCommandsLayoutUsageFlagBitsNV.
160--
161
162[open,refpage='vkDestroyIndirectCommandsLayoutNV',desc='Destroy an indirect commands layout',type='protos']
163--
164Indirect command layouts are destroyed by:
165
166include::{generated}/api/protos/vkDestroyIndirectCommandsLayoutNV.txt[]
167
168  * pname:device is the logical device that destroys the layout.
169  * pname:indirectCommandsLayout is the layout to destroy.
170  * pname:pAllocator controls host memory allocation as described in the
171    <<memory-allocation, Memory Allocation>> chapter.
172
173.Valid Usage
174****
175  * [[VUID-vkDestroyIndirectCommandsLayoutNV-indirectCommandsLayout-02938]]
176    All submitted commands that refer to pname:indirectCommandsLayout must:
177    have completed execution
178  * [[VUID-vkDestroyIndirectCommandsLayoutNV-indirectCommandsLayout-02939]]
179    If sname:VkAllocationCallbacks were provided when
180    pname:indirectCommandsLayout was created, a compatible set of callbacks
181    must: be provided here
182  * [[VUID-vkDestroyIndirectCommandsLayoutNV-indirectCommandsLayout-02940]]
183    If no sname:VkAllocationCallbacks were provided when
184    pname:indirectCommandsLayout was created, pname:pAllocator must: be
185    `NULL`
186  * [[VUID-vkDestroyIndirectCommandsLayoutNV-deviceGeneratedCommands-02941]]
187    The <<features-deviceGeneratedCommands,
188    sname:VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV::pname:deviceGeneratedCommands>>
189    feature must: be enabled
190****
191
192include::{generated}/validity/protos/vkDestroyIndirectCommandsLayoutNV.txt[]
193--
194
195
196=== Token Input Streams
197
198[open,refpage='VkIndirectCommandsStreamNV',desc='Structure specifying input streams for generated command tokens',type='structs']
199--
200The sname:VkIndirectCommandsStreamNV structure specifies the input data for
201one or more tokens at processing time.
202
203include::{generated}/api/structs/VkIndirectCommandsStreamNV.txt[]
204
205  * pname:buffer specifies the slink:VkBuffer storing the functional
206    arguments for each sequence.
207    These arguments can: be written by the device.
208  * pname:offset specified an offset into pname:buffer where the arguments
209    start.
210
211.Valid Usage
212****
213  * [[VUID-VkIndirectCommandsStreamNV-buffer-02942]]
214    The pname:buffer's usage flag must: have the
215    ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set
216  * [[VUID-VkIndirectCommandsStreamNV-offset-02943]]
217    The pname:offset must: be aligned to
218    sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:minIndirectCommandsBufferOffsetAlignment
219  * [[VUID-VkIndirectCommandsStreamNV-buffer-02975]]
220    If pname:buffer is non-sparse then it must: be bound completely and
221    contiguously to a single sname:VkDeviceMemory object
222****
223
224include::{generated}/validity/structs/VkIndirectCommandsStreamNV.txt[]
225--
226
227The input streams can: contain raw `uint32_t` values, existing indirect
228commands such as:
229
230* slink:VkDrawIndirectCommand
231* slink:VkDrawIndexedIndirectCommand
232ifdef::VK_NV_mesh_shader[]
233* slink:VkDrawMeshTasksIndirectCommandNV
234endif::VK_NV_mesh_shader[]
235
236or additional commands as listed below.
237How the data is used is described in the next section.
238
239[open,refpage='VkBindShaderGroupIndirectCommandNV',desc='Structure specifying input data for a single shader group command token',type='structs']
240--
241The sname:VkBindShaderGroupIndirectCommandNV structure specifies the input
242data for the ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV token.
243
244include::{generated}/api/structs/VkBindShaderGroupIndirectCommandNV.txt[]
245
246  * pname:index specifies which shader group of the current bound graphics
247    pipeline is used.
248
249.Valid Usage
250****
251  * [[VUID-VkBindShaderGroupIndirectCommandNV-None-02944]]
252    The current bound graphics pipeline, as well as the pipelines it may
253    reference, must: have been created with
254    ename:VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV
255  * [[VUID-VkBindShaderGroupIndirectCommandNV-index-02945]]
256    The pname:index must: be within range of the accessible shader groups of
257    the current bound graphics pipeline.
258    See flink:vkCmdBindPipelineShaderGroupNV for further details
259****
260
261include::{generated}/validity/structs/VkBindShaderGroupIndirectCommandNV.txt[]
262--
263
264[open,refpage='VkBindIndexBufferIndirectCommandNV',desc='Structure specifying input data for a single index buffer command token',type='structs']
265--
266The sname:VkBindIndexBufferIndirectCommandNV structure specifies the input
267data for the ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV token.
268
269include::{generated}/api/structs/VkBindIndexBufferIndirectCommandNV.txt[]
270
271  * pname:bufferAddress specifies a physical address of the slink:VkBuffer
272    used as index buffer.
273  * pname:size is the byte size range which is available for this operation
274    from the provided address.
275  * pname:indexType is a elink:VkIndexType value specifying how indices are
276    treated.
277    Instead of the Vulkan enum values, a custom `uint32_t` value can: be
278    mapped to an elink:VkIndexType by specifying the
279    sname:VkIndirectCommandsLayoutTokenNV::pname:pIndexTypes and
280    sname:VkIndirectCommandsLayoutTokenNV::pname:pIndexTypeValues arrays.
281
282.Valid Usage
283****
284  * [[VUID-VkBindIndexBufferIndirectCommandNV-None-02946]]
285    The buffer's usage flag from which the address was acquired must: have
286    the ename:VK_BUFFER_USAGE_INDEX_BUFFER_BIT bit set
287  * [[VUID-VkBindIndexBufferIndirectCommandNV-bufferAddress-02947]]
288    The pname:bufferAddress must: be aligned to the pname:indexType used
289  * [[VUID-VkBindIndexBufferIndirectCommandNV-None-02948]]
290    Each element of the buffer from which the address was acquired and that
291    is non-sparse must: be bound completely and contiguously to a single
292    sname:VkDeviceMemory object
293****
294
295include::{generated}/validity/structs/VkBindIndexBufferIndirectCommandNV.txt[]
296--
297
298[open,refpage='VkBindVertexBufferIndirectCommandNV',desc='Structure specifying input data for a single vertex buffer command token',type='structs']
299--
300The sname:VkBindVertexBufferIndirectCommandNV structure specifies the input
301data for the ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV token.
302
303include::{generated}/api/structs/VkBindVertexBufferIndirectCommandNV.txt[]
304
305  * pname:bufferAddress specifies a physical address of the slink:VkBuffer
306    used as vertex input binding.
307  * pname:size is the byte size range which is available for this operation
308    from the provided address.
309  * pname:stride is the byte size stride for this vertex input binding as in
310    sname:VkVertexInputBindingDescription::pname:stride.
311    It is only used if
312    sname:VkIndirectCommandsLayoutTokenNV::pname:vertexDynamicStride was
313    set, otherwise the stride is inherited from the current bound graphics
314    pipeline.
315
316.Valid Usage
317****
318  * [[VUID-VkBindVertexBufferIndirectCommandNV-None-02949]]
319    The buffer's usage flag from which the address was acquired must: have
320    the ename:VK_BUFFER_USAGE_VERTEX_BUFFER_BIT bit set
321  * [[VUID-VkBindVertexBufferIndirectCommandNV-None-02950]]
322    Each element of the buffer from which the address was acquired and that
323    is non-sparse must: be bound completely and contiguously to a single
324    sname:VkDeviceMemory object
325****
326
327include::{generated}/validity/structs/VkBindVertexBufferIndirectCommandNV.txt[]
328--
329
330[open,refpage='VkSetStateFlagsIndirectCommandNV',desc='Structure specifying input data for a single state flag command token',type='structs']
331--
332The sname:VkSetStateFlagsIndirectCommandNV structure specifies the input
333data for the ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV token.
334Which state is changed depends on the elink:VkIndirectStateFlagBitsNV
335specified at sname:VkIndirectCommandsLayoutNV creation time.
336
337include::{generated}/api/structs/VkSetStateFlagsIndirectCommandNV.txt[]
338
339  * pname:data encodes packed state that this command alters.
340  ** Bit `0`: If set represents ename:VK_FRONT_FACE_CLOCKWISE, otherwise
341     ename:VK_FRONT_FACE_COUNTER_CLOCKWISE
342
343include::{generated}/validity/structs/VkSetStateFlagsIndirectCommandNV.txt[]
344--
345
346[open,refpage='VkIndirectStateFlagBitsNV',desc='Bitmask specifiying state that can be altered on the device',type='enums']
347--
348A subset of the graphics pipeline state can: be altered using indirect state
349flags:
350
351include::{generated}/api/enums/VkIndirectStateFlagBitsNV.txt[]
352
353* ename:VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV allows to toggle the
354  elink:VkFrontFace rasterization state for subsequent draw operations.
355--
356
357[open,refpage='VkIndirectStateFlagsNV',desc='Bitmask of VkIndirectStateFlagBitsNV',type='flags']
358--
359include::{generated}/api/flags/VkIndirectStateFlagsNV.txt[]
360
361tname:VkIndirectStateFlagsNV is a bitmask type for setting a mask of zero or
362more elink:VkIndirectStateFlagBitsNV.
363--
364
365
366=== Tokenized Command Processing
367
368The processing is in principle illustrated below:
369
370[source,c]
371---------------------------------------------------
372void cmdProcessSequence(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsStreams, s)
373{
374  for (t = 0; t < indirectCommandsLayout.tokenCount; t++)
375  {
376    uint32_t stream  = indirectCommandsLayout.pTokens[t].stream;
377    uint32_t offset  = indirectCommandsLayout.pTokens[t].offset;
378    uint32_t stride  = indirectCommandsLayout.pStreamStrides[stream];
379    stream            = pIndirectCommandsStreams[stream];
380    const void* input = stream.buffer.pointer( stream.offset + stride * s + offset )
381
382    // further details later
383    indirectCommandsLayout.pTokens[t].command (cmd, pipeline, input, s);
384  }
385}
386
387void cmdProcessAllSequences(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsStreams, sequencesCount)
388{
389  for (s = 0; s < sequencesCount; s++)
390  {
391    cmdProcessSequence(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsStreams, s);
392  }
393}
394---------------------------------------------------
395
396The processing of each sequence is considered stateless, therefore all state
397changes must: occur prior work provoking commands within the sequence.
398A single sequence is strictly targeting the elink:VkPipelineBindPoint it was
399created with.
400
401The primary input data for each token is provided through sname:VkBuffer
402content at preprocessing using flink:vkCmdPreprocessGeneratedCommandsNV or
403execution time using flink:vkCmdExecuteGeneratedCommandsNV, however some
404functional arguments, for example binding sets, are specified at layout
405creation time.
406The input size is different for each token.
407
408[open,refpage='VkIndirectCommandsTokenTypeNV',desc='Enum specifying token commands',type='enums']
409--
410Possible values of those elements of the
411slink:VkIndirectCommandsLayoutCreateInfoNV::pname:pTokens array specifying
412command tokens (other elements of the array specify command parameters) are:
413
414include::{generated}/api/enums/VkIndirectCommandsTokenTypeNV.txt[]
415
416.Supported indirect command tokens
417[width="80%",cols="67%,33%",options="header",align="center"]
418|====
419|Token type                                                 | Equivalent command
420|ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV      | flink:vkCmdBindPipelineShaderGroupNV
421|ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV       | -
422|ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV      | flink:vkCmdBindIndexBuffer
423|ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV     | flink:vkCmdBindVertexBuffers
424|ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV     | flink:vkCmdPushConstants
425|ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV      | flink:vkCmdDrawIndexedIndirect
426|ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV              | flink:vkCmdDrawIndirect
427ifdef::VK_NV_mesh_shader[]
428|ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV        | flink:vkCmdDrawMeshTasksIndirectNV
429endif::VK_NV_mesh_shader[]
430|====
431--
432
433[open,refpage='VkIndirectCommandsLayoutTokenNV',desc='Struct specifying the details of an indirect command layout token',type='structs']
434--
435The sname:VkIndirectCommandsLayoutTokenNV structure specifies details to the
436function arguments that need to be known at layout creation time:
437
438include::{generated}/api/structs/VkIndirectCommandsLayoutTokenNV.txt[]
439
440  * pname:sType is the type of this structure.
441  * pname:pNext is `NULL` or a pointer to a structure extending this
442    structure.
443  * pname:tokenType specifies the token command type.
444  * pname:stream is the index of the input stream containing the token
445    argument data.
446  * pname:offset is a relative starting offset within the input stream
447    memory for the token argument data.
448  * pname:vertexBindingUnit is used for the vertex buffer binding command.
449  * pname:vertexDynamicStride sets if the vertex buffer stride is provided
450    by the binding command rather than the current bound graphics pipeline
451    state.
452  * pname:pushconstantPipelineLayout is the sname:VkPipelineLayout used for
453    the push constant command.
454  * pname:pushconstantShaderStageFlags are the shader stage flags used for
455    the push constant command.
456  * pname:pushconstantOffset is the offset used for the push constant
457    command.
458  * pname:pushconstantSize is the size used for the push constant command.
459  * pname:indirectStateFlags are the active states for the state flag
460    command.
461  * pname:indexTypeCount is the optional size of the pname:pIndexTypes and
462    pname:pIndexTypeValues array pairings.
463    If not zero, it allows to register a custom `uint32_t` value to be
464    treated as specific ename:VkIndexType.
465  * pname:pIndexTypes is the used ename:VkIndexType for the corresponding
466    `uint32_t` value entry in pname:pIndexTypeValues.
467
468.Valid Usage
469****
470  * [[VUID-VkIndirectCommandsLayoutTokenNV-stream-02951]]
471    pname:stream must: be smaller than
472    sname:VkIndirectCommandsLayoutCreateInfoNV::pname:streamCount
473  * [[VUID-VkIndirectCommandsLayoutTokenNV-offset-02952]]
474    pname:offset must: be less than or equal to
475    sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:maxIndirectCommandsTokenOffset
476  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02976]]
477    If pname:tokenType is
478    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV,
479    pname:vertexBindingUnit must: stay within device supported limits for
480    the appropriate commands
481  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02977]]
482    If pname:tokenType is
483    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV,
484    pname:pushconstantPipelineLayout must: be valid
485  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02978]]
486    If pname:tokenType is
487    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV,
488    pname:pushconstantOffset must: be a multiple of `4`
489  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02979]]
490    If pname:tokenType is
491    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV,
492    pname:pushconstantSize must: be a multiple of `4`
493  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02980]]
494    If pname:tokenType is
495    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV,
496    pname:pushconstantOffset must: be less than
497    sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize
498  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02981]]
499    If pname:tokenType is
500    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV,
501    pname:pushconstantSize must: be less than or equal to
502    sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize minus
503    pname:pushconstantOffset
504  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02982]]
505    If pname:tokenType is
506    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, for each byte in
507    the range specified by pname:pushconstantOffset and
508    pname:pushconstantSize and for each shader stage in
509    pname:pushconstantShaderStageFlags, there must: be a push constant range
510    in pname:pushconstantPipelineLayout that includes that byte and that
511    stage
512  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02983]]
513    If pname:tokenType is
514    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, for each byte in
515    the range specified by pname:pushconstantOffset and
516    pname:pushconstantSize and for each push constant range that overlaps
517    that byte, pname:pushconstantShaderStageFlags must: include all stages
518    in that push constant range's
519    slink:VkPushConstantRange::pname:stageFlags
520  * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02984]]
521    If pname:tokenType is
522    ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV,
523    pname:indirectStateFlags must: not be `0`
524****
525
526include::{generated}/validity/structs/VkIndirectCommandsLayoutTokenNV.txt[]
527--
528
529The following code provides detailed information on how an individual
530sequence is processed.
531For valid usage, all restrictions from the regular commands apply.
532
533[source,c]
534---------------------------------------------------
535void cmdProcessSequence(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsStreams, s)
536{
537  for (uint32_t t = 0; t < indirectCommandsLayout.tokenCount; t++){
538    token = indirectCommandsLayout.pTokens[t];
539
540    uint32_t stride   = indirectCommandsLayout.pStreamStrides[token.stream];
541    stream            = pIndirectCommandsStreams[token.stream];
542    uint32_t offset   = stream.offset + stride * s + token.offset;
543    const void* input = stream.buffer.pointer( offset )
544
545    switch(input.type){
546    VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV:
547      VkBindShaderGroupIndirectCommandNV* bind = input;
548
549      vkCmdBindPipelineShaderGroupNV(cmd, indirectCommandsLayout.pipelineBindPoint,
550        pipeline, bind->groupIndex);
551    break;
552
553    VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV:
554      VkSetStateFlagsIndirectCommandNV* state = input;
555
556      if (token.indirectStateFlags & VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV){
557        if (state.data & (1 << 0)){
558          set VK_FRONT_FACE_CLOCKWISE;
559        } else {
560          set VK_FRONT_FACE_COUNTER_CLOCKWISE;
561        }
562      }
563    break;
564
565    VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV:
566      uint32_t* data = input;
567
568      vkCmdPushConstants(cmd,
569        token.pushconstantPipelineLayout
570        token.pushconstantStageFlags,
571        token.pushconstantOffset,
572        token.pushconstantSize, data);
573    break;
574
575    VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV:
576      VkBindIndexBufferIndirectCommandNV* data = input;
577
578      // the indexType may optionally be remapped
579      // from a custom uint32_t value, via
580      // VkIndirectCommandsLayoutTokenNV::pIndexTypeValues
581
582      vkCmdBindIndexBuffer(cmd,
583        deriveBuffer(data->bufferAddress),
584        deriveOffset(data->bufferAddress),
585        data->indexType);
586    break;
587
588    VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV:
589      VkBindVertexBufferIndirectCommandNV* data = input;
590
591      // if token.vertexDynamicStride is VK_TRUE
592      // then the stride for this binding is set
593      // using data->stride as well
594
595      vkCmdBindVertexBuffers(cmd,
596        token.vertexBindingUnit, 1,
597        &deriveBuffer(data->bufferAddress),
598        &deriveOffset(data->bufferAddress));
599    break;
600
601    VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV:
602      vkCmdDrawIndexedIndirect(cmd,
603        stream.buffer, offset, 1, 0);
604    break;
605
606    VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV:
607      vkCmdDrawIndirect(cmd,
608        stream.buffer,
609        offset, 1, 0);
610    break;
611
612    // only available if VK_NV_mesh_shader is supported
613    VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NV:
614      vkCmdDrawMeshTasksIndirectNV(cmd,
615        stream.buffer, offset, 1, 0);
616    break;
617    }
618  }
619}
620---------------------------------------------------
621