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