indirectcommands.txt
  1  [[indirectmdslayout]]
  2  == Indirect Commands Layout
  3  
  4  [open,refpage='VkIndirectCommandsLayoutNVX',desc='Opaque handle to an indirect commands layout object',type='handles']
  5  --
  6  
  7  The device-side command generation happens through an iterative processing
  8  of an atomic sequence comprised of command tokens, which are represented by:
  9  
 10  include::{generated}/api/handles/VkIndirectCommandsLayoutNVX.txt[]
 11  
 12  --
 13  
 14  
 15  === Tokenized Command Processing
 16  
 17  The processing is in principle illustrated below:
 18  
 19  [source,c]
 20  ---------------------------------------------------
 21  void cmdProcessSequence(cmd, objectTable, indirectCommandsLayout, pIndirectCommandsTokens, s)
 22  {
 23    for (c = 0; c < indirectCommandsLayout.tokenCount; c++)
 24    {
 25      indirectCommandsLayout.pTokens[c].command (cmd, objectTable, pIndirectCommandsTokens[c], s);
 26    }
 27  }
 28  
 29  void cmdProcessAllSequences(cmd, objectTable, indirectCommandsLayout, pIndirectCommandsTokens, sequencesCount)
 30  {
 31    for (s = 0; s < sequencesCount; s++)
 32    {
 33      cmdProcessSequence(cmd, objectTable, indirectCommandsLayout, pIndirectCommandsTokens, s);
 34    }
 35  }
 36  ---------------------------------------------------
 37  
 38  The processing of each sequence is considered stateless, therefore all state
 39  changes must: occur prior work provoking commands within the sequence.
 40  A single sequence is either strictly targeting
 41  ename:VK_PIPELINE_BIND_POINT_GRAPHICS or
 42  ename:VK_PIPELINE_BIND_POINT_COMPUTE.
 43  
 44  The primary input data for each token is provided through sname:VkBuffer
 45  content at command generation time using flink:vkCmdProcessCommandsNVX,
 46  however some functional arguments, for example binding sets, are specified
 47  at layout creation time.
 48  The input size is different for each token.
 49  
 50  [open,refpage='VkIndirectCommandsTokenTypeNVX',desc='Enum specifying',type='enums']
 51  --
 52  
 53  Possible values of those elements of the
 54  slink:VkIndirectCommandsLayoutCreateInfoNVX::pname:pTokens array which
 55  specify command tokens (other elements of the array specify command
 56  parameters) are:
 57  
 58  include::{generated}/api/enums/VkIndirectCommandsTokenTypeNVX.txt[]
 59  
 60  .Supported indirect command tokens
 61  [width="80%",cols="67%,33%",options="header",align="center"]
 62  |====
 63  |Token type                                                 | Equivalent command
 64  |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX         | fname:vkCmdBindPipeline
 65  |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX   | fname:vkCmdBindDescriptorSets
 66  |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX     | fname:vkCmdBindIndexBuffer
 67  |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX    | fname:vkCmdBindVertexBuffers
 68  |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX    | fname:vkCmdPushConstants
 69  |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX     | fname:vkCmdDrawIndexedIndirect
 70  |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX             | fname:vkCmdDrawIndirect
 71  |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX         | fname:vkCmdDispatchIndirect
 72  |====
 73  
 74  --
 75  
 76  [open,refpage='VkIndirectCommandsLayoutTokenNVX',desc='Struct specifying the details of an indirect command layout token',type='structs']
 77  --
 78  
 79  The sname:VkIndirectCommandsLayoutTokenNVX structure specifies details to
 80  the function arguments that need to be known at layout creation time:
 81  
 82  include::{generated}/api/structs/VkIndirectCommandsLayoutTokenNVX.txt[]
 83  
 84    * pname:type specifies the token command type.
 85    * pname:bindingUnit has a different meaning depending on the type, please
 86      refer pseudo code further down for details.
 87    * pname:dynamicCount has a different meaning depending on the type, please
 88      refer pseudo code further down for details.
 89    * pname:divisor defines the rate at which the input data buffers are
 90      accessed.
 91  
 92  .Valid Usage
 93  ****
 94    * [[VUID-VkIndirectCommandsLayoutTokenNVX-bindingUnit-01342]]
 95      pname:bindingUnit must: stay within device supported limits for the
 96      appropriate commands.
 97    * [[VUID-VkIndirectCommandsLayoutTokenNVX-dynamicCount-01343]]
 98      pname:dynamicCount must: stay within device supported limits for the
 99      appropriate commands.
100    * [[VUID-VkIndirectCommandsLayoutTokenNVX-divisor-01344]]
101      pname:divisor must: be greater than `0` and a power of two.
102  ****
103  
104  include::{generated}/validity/structs/VkIndirectCommandsLayoutTokenNVX.txt[]
105  --
106  
107  [open,refpage='VkIndirectCommandsTokenNVX',desc='Structure specifying parameters for the reservation of command buffer space',type='structs']
108  --
109  
110  The sname:VkIndirectCommandsTokenNVX structure specifies the input data for
111  a token at processing time.
112  
113  include::{generated}/api/structs/VkIndirectCommandsTokenNVX.txt[]
114  
115    * pname:tokenType specifies the token command type.
116    * pname:buffer specifies the slink:VkBuffer storing the functional
117      arguments for each squence.
118      These argumetns can be written by the device.
119    * pname:offset specified an offset into pname:buffer where the arguments
120      start.
121  
122  .Valid Usage
123  ****
124    * [[VUID-VkIndirectCommandsTokenNVX-buffer-01345]]
125      The pname:buffer's usage flag must: have the
126      ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set.
127    * [[VUID-VkIndirectCommandsTokenNVX-offset-01346]]
128      The pname:offset must: be aligned to
129      sname:VkDeviceGeneratedCommandsLimitsNVX::pname:minCommandsTokenBufferOffsetAlignment.
130  ****
131  
132  include::{generated}/validity/structs/VkIndirectCommandsTokenNVX.txt[]
133  --
134  
135  
136  The following code provides detailed information on how an individual
137  sequence is processed:
138  
139  [source,c]
140  ---------------------------------------------------
141  void cmdProcessSequence(cmd, objectTable, indirectCommandsLayout, pIndirectCommandsTokens, s)
142  {
143    for (uint32_t c = 0; c < indirectCommandsLayout.tokenCount; c++){
144      input   = pIndirectCommandsTokens[c];
145      i       = s / indirectCommandsLayout.pTokens[c].divisor;
146  
147      switch(input.type){
148        VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX:
149          size_t    stride  = sizeof(uint32_t);
150          uint32_t* data    = input.buffer.pointer( input.offset + stride * i );
151          uint32_t  object  = data[0];
152  
153          vkCmdBindPipeline(cmd, indirectCommandsLayout.pipelineBindPoint,
154            objectTable.pipelines[ object ].pipeline);
155        break;
156  
157        VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX:
158          size_t    stride  = sizeof(uint32_t) + sizeof(uint32_t) * indirectCommandsLayout.pTokens[c].dynamicCount;
159          uint32_t* data    = input.buffer.pointer( input.offset + stride * i);
160          uint32_t  object  = data[0];
161  
162          vkCmdBindDescriptorSets(cmd, indirectCommandsLayout.pipelineBindPoint,
163            objectTable.descriptorsets[ object ].layout,
164            indirectCommandsLayout.pTokens[ c ].bindingUnit,
165            1, &objectTable.descriptorsets[ object ].descriptorSet,
166            indirectCommandsLayout.pTokens[ c ].dynamicCount, data + 1);
167        break;
168  
169        VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX:
170          size_t    stride  = sizeof(uint32_t) + indirectCommandsLayout.pTokens[c].dynamicCount;
171          uint32_t* data    = input.buffer.pointer( input.offset + stride * i );
172          uint32_t  object  = data[0];
173  
174          vkCmdPushConstants(cmd,
175            objectTable.pushconstants[ object ].layout,
176            objectTable.pushconstants[ object ].stageFlags,
177            indirectCommandsLayout.pTokens[ c ].bindingUnit, indirectCommandsLayout.pTokens[c].dynamicCount, data + 1);
178        break;
179  
180        VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX:
181          size_t   s tride  = sizeof(uint32_t) + sizeof(uint32_t) * indirectCommandsLayout.pTokens[c].dynamicCount;
182          uint32_t* data    = input.buffer.pointer( input.offset + stride * i );
183          uint32_t  object  = data[0];
184  
185          vkCmdBindIndexBuffer(cmd,
186            objectTable.vertexbuffers[ object ].buffer,
187            indirectCommandsLayout.pTokens[ c ].dynamicCount ? data[1] : 0,
188            objectTable.vertexbuffers[ object ].indexType);
189        break;
190  
191        VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX:
192          size_t    stride  = sizeof(uint32_t) + sizeof(uint32_t) * indirectCommandsLayout.pTokens[c].dynamicCount;
193          uint32_t* data    = input.buffer.pointer( input.offset + stride * i );
194          uint32_t  object  = data[0];
195  
196          vkCmdBindVertexBuffers(cmd,
197            indirectCommandsLayout.pTokens[ c ].bindingUnit, 1,
198            &objectTable.vertexbuffers[ object ].buffer,
199            indirectCommandsLayout.pTokens[ c ].dynamicCount ? data + 1 : {0}); // device size handled as uint32_t
200        break;
201  
202        VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX:
203          vkCmdDrawIndexedIndirect(cmd,
204            input.buffer,
205            sizeof(VkDrawIndexedIndirectCommand) * i + input.offset, 1, 0);
206        break;
207  
208        VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX:
209          vkCmdDrawIndirect(cmd,
210            input.buffer,
211            sizeof(VkDrawIndirectCommand) * i  + input.offset, 1, 0);
212        break;
213  
214        VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX:
215          vkCmdDispatchIndirect(cmd,
216            input.buffer,
217            sizeof(VkDispatchIndirectCommand) * i  + input.offset);
218        break;
219      }
220    }
221  }
222  ---------------------------------------------------
223  
224  
225  === Creation and Deletion
226  
227  [open,refpage='vkCreateIndirectCommandsLayoutNVX',desc='Create an indirect command layout object',type='protos']
228  --
229  Indirect command layouts are created by:
230  
231  include::{generated}/api/protos/vkCreateIndirectCommandsLayoutNVX.txt[]
232  
233    * pname:device is the logical device that creates the indirect command
234      layout.
235    * pname:pCreateInfo is a pointer to an instance of the
236      sname:VkIndirectCommandsLayoutCreateInfoNVX structure containing
237      parameters affecting creation of the indirect command layout.
238    * pname:pAllocator controls host memory allocation as described in the
239      <<memory-allocation, Memory Allocation>> chapter.
240    * pname:pIndirectCommandsLayout points to a
241      sname:VkIndirectCommandsLayoutNVX handle in which the resulting indirect
242      command layout is returned.
243  
244  include::{generated}/validity/protos/vkCreateIndirectCommandsLayoutNVX.txt[]
245  --
246  
247  [open,refpage='VkIndirectCommandsLayoutCreateInfoNVX',desc='Structure specifying the parameters of a newly created indirect commands layout object',type='structs']
248  --
249  
250  The sname:VkIndirectCommandsLayoutCreateInfoNVX structure is defined as:
251  
252  include::{generated}/api/structs/VkIndirectCommandsLayoutCreateInfoNVX.txt[]
253  
254    * pname:sType is the type of this structure.
255    * pname:pNext is `NULL` or a pointer to an extension-specific structure.
256    * pname:pipelineBindPoint is the elink:VkPipelineBindPoint that this
257      layout targets.
258    * pname:flags is a bitmask of
259      elink:VkIndirectCommandsLayoutUsageFlagBitsNVX specifying usage hints of
260      this layout.
261    * pname:tokenCount is the length of the individual command sequnce.
262    * pname:pTokens is an array describing each command token in detail.
263      See elink:VkIndirectCommandsTokenTypeNVX and
264      slink:VkIndirectCommandsLayoutTokenNVX below for details.
265  
266  The following code illustrates some of the key flags:
267  
268  [source,c]
269  ---------------------------------------------------
270  void cmdProcessAllSequences(cmd, objectTable, indirectCommandsLayout, pIndirectCommandsTokens, sequencesCount, indexbuffer, indexbufferoffset)
271  {
272    for (s = 0; s < sequencesCount; s++)
273    {
274      sequence = s;
275  
276      if (indirectCommandsLayout.flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX) {
277        sequence = incoherent_implementation_dependent_permutation[ sequence ];
278      }
279      if (indirectCommandsLayout.flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX) {
280        sequence = indexbuffer.load_uint32( sequence * sizeof(uint32_t) + indexbufferoffset);
281      }
282  
283      cmdProcessSequence( cmd, objectTable, indirectCommandsLayout, pIndirectCommandsTokens, sequence );
284    }
285  }
286  ---------------------------------------------------
287  
288  .Valid Usage
289  ****
290    * [[VUID-VkIndirectCommandsLayoutCreateInfoNVX-tokenCount-01347]]
291      pname:tokenCount must: be greater than `0` and below
292      sname:VkDeviceGeneratedCommandsLimitsNVX::pname:maxIndirectCommandsLayoutTokenCount
293    * [[VUID-VkIndirectCommandsLayoutCreateInfoNVX-computeBindingPointSupport-01348]]
294      If the
295      sname:VkDeviceGeneratedCommandsFeaturesNVX::pname:computeBindingPointSupport
296      feature is not enabled, then pname:pipelineBindPoint must: not be
297      ename:VK_PIPELINE_BIND_POINT_COMPUTE
298    * [[VUID-VkIndirectCommandsLayoutCreateInfoNVX-pTokens-01349]]
299      If pname:pTokens contains an entry of
300      ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX it must: be the first
301      element of the array and there must: be only a single element of such
302      token type.
303    * [[VUID-VkIndirectCommandsLayoutCreateInfoNVX-pTokens-01350]]
304      All state binding tokens in pname:pTokens must: occur prior work
305      provoking tokens (ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX,
306      ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX,
307      ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX).
308    * [[VUID-VkIndirectCommandsLayoutCreateInfoNVX-pTokens-01351]]
309      The content of pname:pTokens must: include one single work provoking
310      token that is compatible with the pname:pipelineBindPoint.
311  ****
312  
313  include::{generated}/validity/structs/VkIndirectCommandsLayoutCreateInfoNVX.txt[]
314  --
315  
316  [open,refpage='VkIndirectCommandsLayoutUsageFlagBitsNVX',desc='Bitmask specifying allowed usage of an indirect commands layout',type='enums']
317  --
318  
319  Bits which can: be set in
320  slink:VkIndirectCommandsLayoutCreateInfoNVX::pname:flags, specifying usage
321  hints of an indirect command layout, are:
322  
323  include::{generated}/api/enums/VkIndirectCommandsLayoutUsageFlagBitsNVX.txt[]
324  
325    * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX
326      specifies that the processing of sequences can: happen at an
327      implementation-dependent order, which is not guaranteed to be coherent
328      across multiple invocations.
329    * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX
330      specifies that there is likely a high difference between allocated
331      number of sequences and actually used.
332    * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX
333      specifies that there are likely many draw or dispatch calls that are
334      zero-sized (zero grid dimension, no primitives to render).
335    * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX
336      specifies that the input data for the sequences is not implicitly
337      indexed from 0..sequencesUsed but a user provided sname:VkBuffer
338      encoding the index is provided.
339  
340  --
341  
342  [open,refpage='VkIndirectCommandsLayoutUsageFlagsNVX',desc='Bitmask of VkIndirectCommandsLayoutUsageFlagBitsNVX',type='flags']
343  --
344  include::{generated}/api/flags/VkIndirectCommandsLayoutUsageFlagsNVX.txt[]
345  
346  tname:VkIndirectCommandsLayoutUsageFlagsNVX is a bitmask type for setting a
347  mask of zero or more elink:VkIndirectCommandsLayoutUsageFlagBitsNVX.
348  --
349  
350  [open,refpage='vkDestroyIndirectCommandsLayoutNVX',desc='Destroy an object table',type='protos']
351  --
352  
353  Indirect command layouts are destroyed by:
354  
355  include::{generated}/api/protos/vkDestroyIndirectCommandsLayoutNVX.txt[]
356  
357    * pname:device is the logical device that destroys the layout.
358    * pname:indirectCommandsLayout is the table to destroy.
359    * pname:pAllocator controls host memory allocation as described in the
360      <<memory-allocation, Memory Allocation>> chapter.
361  
362  .Valid Usage
363  ****
364    * [[VUID-vkDestroyIndirectCommandsLayoutNVX-indirectCommandsLayout-01352]]
365      All submitted commands that refer to pname:indirectCommandsLayout must:
366      have completed execution
367    * [[VUID-vkDestroyIndirectCommandsLayoutNVX-objectTable-01353]]
368      If sname:VkAllocationCallbacks were provided when pname:objectTable was
369      created, a compatible set of callbacks must: be provided here
370    * [[VUID-vkDestroyIndirectCommandsLayoutNVX-objectTable-01354]]
371      If no sname:VkAllocationCallbacks were provided when pname:objectTable
372      was created, pname:pAllocator must: be `NULL`
373  ****
374  
375  include::{generated}/validity/protos/vkDestroyIndirectCommandsLayoutNVX.txt[]
376  --