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 --