| // Copyright (c) 2019-2020 NVIDIA Corporation |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[indirectmdslayout]] |
| == Indirect Commands Layout |
| |
| [open,refpage='VkIndirectCommandsLayoutNV',desc='Opaque handle to an indirect commands layout object',type='handles'] |
| -- |
| The device-side command generation happens through an iterative processing |
| of an atomic sequence comprised of command tokens, which are represented by: |
| |
| include::{generated}/api/handles/VkIndirectCommandsLayoutNV.txt[] |
| -- |
| |
| |
| === Creation and Deletion |
| |
| [open,refpage='vkCreateIndirectCommandsLayoutNV',desc='Create an indirect command layout object',type='protos'] |
| -- |
| Indirect command layouts are created by: |
| |
| include::{generated}/api/protos/vkCreateIndirectCommandsLayoutNV.txt[] |
| |
| * pname:device is the logical device that creates the indirect command |
| layout. |
| * pname:pCreateInfo is a pointer to a |
| sname:VkIndirectCommandsLayoutCreateInfoNV structure containing |
| parameters affecting creation of the indirect command layout. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| * pname:pIndirectCommandsLayout is a pointer to a |
| sname:VkIndirectCommandsLayoutNV handle in which the resulting indirect |
| command layout is returned. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCreateIndirectCommandsLayoutNV-deviceGeneratedCommands-02929]] |
| The <<features-deviceGeneratedCommands, |
| sname:VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV::pname:deviceGeneratedCommands>> |
| feature must: be enabled |
| **** |
| |
| include::{generated}/validity/protos/vkCreateIndirectCommandsLayoutNV.txt[] |
| -- |
| |
| [open,refpage='VkIndirectCommandsLayoutCreateInfoNV',desc='Structure specifying the parameters of a newly created indirect commands layout object',type='structs'] |
| -- |
| The sname:VkIndirectCommandsLayoutCreateInfoNV structure is defined as: |
| |
| include::{generated}/api/structs/VkIndirectCommandsLayoutCreateInfoNV.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:pipelineBindPoint is the elink:VkPipelineBindPoint that this |
| layout targets. |
| * pname:flags is a bitmask of |
| elink:VkIndirectCommandsLayoutUsageFlagBitsNV specifying usage hints of |
| this layout. |
| * pname:tokenCount is the length of the individual command sequence. |
| * pname:pTokens is an array describing each command token in detail. |
| See elink:VkIndirectCommandsTokenTypeNV and |
| slink:VkIndirectCommandsLayoutTokenNV below for details. |
| * pname:streamCount is the number of streams used to provide the token |
| inputs. |
| * pname:pStreamStrides is an array defining the byte stride for each input |
| stream. |
| |
| The following code illustrates some of the flags: |
| |
| [source,c] |
| ~~~~ |
| void cmdProcessAllSequences(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsTokens, sequencesCount, indexbuffer, indexbufferOffset) |
| { |
| for (s = 0; s < sequencesCount; s++) |
| { |
| sUsed = s; |
| |
| if (indirectCommandsLayout.flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV) { |
| sUsed = indexbuffer.load_uint32( sUsed * sizeof(uint32_t) + indexbufferOffset); |
| } |
| |
| if (indirectCommandsLayout.flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV) { |
| sUsed = incoherent_implementation_dependent_permutation[ sUsed ]; |
| } |
| |
| cmdProcessSequence( cmd, pipeline, indirectCommandsLayout, pIndirectCommandsTokens, sUsed ); |
| } |
| } |
| ~~~~ |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pipelineBindPoint-02930]] |
| The pname:pipelineBindPoint must: be |
| ename:VK_PIPELINE_BIND_POINT_GRAPHICS |
| * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-tokenCount-02931]] |
| pname:tokenCount must: be greater than `0` and less than or equal to |
| sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:maxIndirectCommandsTokenCount |
| * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pTokens-02932]] |
| If pname:pTokens contains an entry of |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV it must: be the |
| first element of the array and there must: be only a single element of |
| such token type |
| * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pTokens-02933]] |
| If pname:pTokens contains an entry of |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV there must: be only |
| a single element of such token type |
| * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pTokens-02934]] |
| All state tokens in pname:pTokens must: occur prior work provoking |
| tokens (ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV, |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV, |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV) |
| * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pTokens-02935]] |
| The content of pname:pTokens must: include one single work provoking |
| token that is compatible with the pname:pipelineBindPoint |
| * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-streamCount-02936]] |
| pname:streamCount must: be greater than `0` and less or equal to |
| sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:maxIndirectCommandsStreamCount |
| * [[VUID-VkIndirectCommandsLayoutCreateInfoNV-pStreamStrides-02937]] |
| each element of pname:pStreamStrides must: be greater than `0`and less |
| than or equal to |
| sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:maxIndirectCommandsStreamStride. |
| Furthermore the alignment of each token input must: be ensured |
| **** |
| |
| include::{generated}/validity/structs/VkIndirectCommandsLayoutCreateInfoNV.txt[] |
| -- |
| |
| [open,refpage='VkIndirectCommandsLayoutUsageFlagBitsNV',desc='Bitmask specifying allowed usage of an indirect commands layout',type='enums'] |
| -- |
| Bits which can: be set in |
| slink:VkIndirectCommandsLayoutCreateInfoNV::pname:flags, specifying usage |
| hints of an indirect command layout, are: |
| |
| include::{generated}/api/enums/VkIndirectCommandsLayoutUsageFlagBitsNV.txt[] |
| |
| * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV |
| specifies that the layout is always used with the manual preprocessing |
| step through calling flink:vkCmdPreprocessGeneratedCommandsNV and |
| executed by flink:vkCmdExecuteGeneratedCommandsNV with `isPreprocessed` |
| set to ename:VK_TRUE. |
| * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV |
| specifies that the input data for the sequences is not implicitly |
| indexed from 0..sequencesUsed but a user provided sname:VkBuffer |
| encoding the index is provided. |
| * ename:VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV |
| specifies that the processing of sequences can: happen at an |
| implementation-dependent order, which is not: guaranteed to be coherent |
| using the same input data. |
| -- |
| |
| [open,refpage='VkIndirectCommandsLayoutUsageFlagsNV',desc='Bitmask of VkIndirectCommandsLayoutUsageFlagBitsNV',type='flags'] |
| -- |
| include::{generated}/api/flags/VkIndirectCommandsLayoutUsageFlagsNV.txt[] |
| |
| tname:VkIndirectCommandsLayoutUsageFlagsNV is a bitmask type for setting a |
| mask of zero or more elink:VkIndirectCommandsLayoutUsageFlagBitsNV. |
| -- |
| |
| [open,refpage='vkDestroyIndirectCommandsLayoutNV',desc='Destroy an indirect commands layout',type='protos'] |
| -- |
| Indirect command layouts are destroyed by: |
| |
| include::{generated}/api/protos/vkDestroyIndirectCommandsLayoutNV.txt[] |
| |
| * pname:device is the logical device that destroys the layout. |
| * pname:indirectCommandsLayout is the layout to destroy. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkDestroyIndirectCommandsLayoutNV-indirectCommandsLayout-02938]] |
| All submitted commands that refer to pname:indirectCommandsLayout must: |
| have completed execution |
| * [[VUID-vkDestroyIndirectCommandsLayoutNV-indirectCommandsLayout-02939]] |
| If sname:VkAllocationCallbacks were provided when |
| pname:indirectCommandsLayout was created, a compatible set of callbacks |
| must: be provided here |
| * [[VUID-vkDestroyIndirectCommandsLayoutNV-indirectCommandsLayout-02940]] |
| If no sname:VkAllocationCallbacks were provided when |
| pname:indirectCommandsLayout was created, pname:pAllocator must: be |
| `NULL` |
| * [[VUID-vkDestroyIndirectCommandsLayoutNV-deviceGeneratedCommands-02941]] |
| The <<features-deviceGeneratedCommands, |
| sname:VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV::pname:deviceGeneratedCommands>> |
| feature must: be enabled |
| **** |
| |
| include::{generated}/validity/protos/vkDestroyIndirectCommandsLayoutNV.txt[] |
| -- |
| |
| |
| === Token Input Streams |
| |
| [open,refpage='VkIndirectCommandsStreamNV',desc='Structure specifying input streams for generated command tokens',type='structs'] |
| -- |
| The sname:VkIndirectCommandsStreamNV structure specifies the input data for |
| one or more tokens at processing time. |
| |
| include::{generated}/api/structs/VkIndirectCommandsStreamNV.txt[] |
| |
| * pname:buffer specifies the slink:VkBuffer storing the functional |
| arguments for each sequence. |
| These arguments can: be written by the device. |
| * pname:offset specified an offset into pname:buffer where the arguments |
| start. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkIndirectCommandsStreamNV-buffer-02942]] |
| The pname:buffer's usage flag must: have the |
| ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set |
| * [[VUID-VkIndirectCommandsStreamNV-offset-02943]] |
| The pname:offset must: be aligned to |
| sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:minIndirectCommandsBufferOffsetAlignment |
| * [[VUID-VkIndirectCommandsStreamNV-buffer-02975]] |
| If pname:buffer is non-sparse then it must: be bound completely and |
| contiguously to a single sname:VkDeviceMemory object |
| **** |
| |
| include::{generated}/validity/structs/VkIndirectCommandsStreamNV.txt[] |
| -- |
| |
| The input streams can: contain raw `uint32_t` values, existing indirect |
| commands such as: |
| |
| * slink:VkDrawIndirectCommand |
| * slink:VkDrawIndexedIndirectCommand |
| ifdef::VK_NV_mesh_shader[] |
| * slink:VkDrawMeshTasksIndirectCommandNV |
| endif::VK_NV_mesh_shader[] |
| |
| or additional commands as listed below. |
| How the data is used is described in the next section. |
| |
| [open,refpage='VkBindShaderGroupIndirectCommandNV',desc='Structure specifying input data for a single shader group command token',type='structs'] |
| -- |
| The sname:VkBindShaderGroupIndirectCommandNV structure specifies the input |
| data for the ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV token. |
| |
| include::{generated}/api/structs/VkBindShaderGroupIndirectCommandNV.txt[] |
| |
| * pname:index specifies which shader group of the current bound graphics |
| pipeline is used. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkBindShaderGroupIndirectCommandNV-None-02944]] |
| The current bound graphics pipeline, as well as the pipelines it may |
| reference, must: have been created with |
| ename:VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV |
| * [[VUID-VkBindShaderGroupIndirectCommandNV-index-02945]] |
| The pname:index must: be within range of the accessible shader groups of |
| the current bound graphics pipeline. |
| See flink:vkCmdBindPipelineShaderGroupNV for further details |
| **** |
| |
| include::{generated}/validity/structs/VkBindShaderGroupIndirectCommandNV.txt[] |
| -- |
| |
| [open,refpage='VkBindIndexBufferIndirectCommandNV',desc='Structure specifying input data for a single index buffer command token',type='structs'] |
| -- |
| The sname:VkBindIndexBufferIndirectCommandNV structure specifies the input |
| data for the ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV token. |
| |
| include::{generated}/api/structs/VkBindIndexBufferIndirectCommandNV.txt[] |
| |
| * pname:bufferAddress specifies a physical address of the slink:VkBuffer |
| used as index buffer. |
| * pname:size is the byte size range which is available for this operation |
| from the provided address. |
| * pname:indexType is a elink:VkIndexType value specifying how indices are |
| treated. |
| Instead of the Vulkan enum values, a custom `uint32_t` value can: be |
| mapped to an elink:VkIndexType by specifying the |
| sname:VkIndirectCommandsLayoutTokenNV::pname:pIndexTypes and |
| sname:VkIndirectCommandsLayoutTokenNV::pname:pIndexTypeValues arrays. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkBindIndexBufferIndirectCommandNV-None-02946]] |
| The buffer's usage flag from which the address was acquired must: have |
| the ename:VK_BUFFER_USAGE_INDEX_BUFFER_BIT bit set |
| * [[VUID-VkBindIndexBufferIndirectCommandNV-bufferAddress-02947]] |
| The pname:bufferAddress must: be aligned to the pname:indexType used |
| * [[VUID-VkBindIndexBufferIndirectCommandNV-None-02948]] |
| Each element of the buffer from which the address was acquired and that |
| is non-sparse must: be bound completely and contiguously to a single |
| sname:VkDeviceMemory object |
| **** |
| |
| include::{generated}/validity/structs/VkBindIndexBufferIndirectCommandNV.txt[] |
| -- |
| |
| [open,refpage='VkBindVertexBufferIndirectCommandNV',desc='Structure specifying input data for a single vertex buffer command token',type='structs'] |
| -- |
| The sname:VkBindVertexBufferIndirectCommandNV structure specifies the input |
| data for the ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV token. |
| |
| include::{generated}/api/structs/VkBindVertexBufferIndirectCommandNV.txt[] |
| |
| * pname:bufferAddress specifies a physical address of the slink:VkBuffer |
| used as vertex input binding. |
| * pname:size is the byte size range which is available for this operation |
| from the provided address. |
| * pname:stride is the byte size stride for this vertex input binding as in |
| sname:VkVertexInputBindingDescription::pname:stride. |
| It is only used if |
| sname:VkIndirectCommandsLayoutTokenNV::pname:vertexDynamicStride was |
| set, otherwise the stride is inherited from the current bound graphics |
| pipeline. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkBindVertexBufferIndirectCommandNV-None-02949]] |
| The buffer's usage flag from which the address was acquired must: have |
| the ename:VK_BUFFER_USAGE_VERTEX_BUFFER_BIT bit set |
| * [[VUID-VkBindVertexBufferIndirectCommandNV-None-02950]] |
| Each element of the buffer from which the address was acquired and that |
| is non-sparse must: be bound completely and contiguously to a single |
| sname:VkDeviceMemory object |
| **** |
| |
| include::{generated}/validity/structs/VkBindVertexBufferIndirectCommandNV.txt[] |
| -- |
| |
| [open,refpage='VkSetStateFlagsIndirectCommandNV',desc='Structure specifying input data for a single state flag command token',type='structs'] |
| -- |
| The sname:VkSetStateFlagsIndirectCommandNV structure specifies the input |
| data for the ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV token. |
| Which state is changed depends on the elink:VkIndirectStateFlagBitsNV |
| specified at sname:VkIndirectCommandsLayoutNV creation time. |
| |
| include::{generated}/api/structs/VkSetStateFlagsIndirectCommandNV.txt[] |
| |
| * pname:data encodes packed state that this command alters. |
| ** Bit `0`: If set represents ename:VK_FRONT_FACE_CLOCKWISE, otherwise |
| ename:VK_FRONT_FACE_COUNTER_CLOCKWISE |
| |
| include::{generated}/validity/structs/VkSetStateFlagsIndirectCommandNV.txt[] |
| -- |
| |
| [open,refpage='VkIndirectStateFlagBitsNV',desc='Bitmask specifiying state that can be altered on the device',type='enums'] |
| -- |
| A subset of the graphics pipeline state can: be altered using indirect state |
| flags: |
| |
| include::{generated}/api/enums/VkIndirectStateFlagBitsNV.txt[] |
| |
| * ename:VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV allows to toggle the |
| elink:VkFrontFace rasterization state for subsequent draw operations. |
| -- |
| |
| [open,refpage='VkIndirectStateFlagsNV',desc='Bitmask of VkIndirectStateFlagBitsNV',type='flags'] |
| -- |
| include::{generated}/api/flags/VkIndirectStateFlagsNV.txt[] |
| |
| tname:VkIndirectStateFlagsNV is a bitmask type for setting a mask of zero or |
| more elink:VkIndirectStateFlagBitsNV. |
| -- |
| |
| |
| === Tokenized Command Processing |
| |
| The processing is in principle illustrated below: |
| |
| [source,c] |
| --------------------------------------------------- |
| void cmdProcessSequence(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsStreams, s) |
| { |
| for (t = 0; t < indirectCommandsLayout.tokenCount; t++) |
| { |
| uint32_t stream = indirectCommandsLayout.pTokens[t].stream; |
| uint32_t offset = indirectCommandsLayout.pTokens[t].offset; |
| uint32_t stride = indirectCommandsLayout.pStreamStrides[stream]; |
| stream = pIndirectCommandsStreams[stream]; |
| const void* input = stream.buffer.pointer( stream.offset + stride * s + offset ) |
| |
| // further details later |
| indirectCommandsLayout.pTokens[t].command (cmd, pipeline, input, s); |
| } |
| } |
| |
| void cmdProcessAllSequences(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsStreams, sequencesCount) |
| { |
| for (s = 0; s < sequencesCount; s++) |
| { |
| cmdProcessSequence(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsStreams, s); |
| } |
| } |
| --------------------------------------------------- |
| |
| The processing of each sequence is considered stateless, therefore all state |
| changes must: occur prior work provoking commands within the sequence. |
| A single sequence is strictly targeting the elink:VkPipelineBindPoint it was |
| created with. |
| |
| The primary input data for each token is provided through sname:VkBuffer |
| content at preprocessing using flink:vkCmdPreprocessGeneratedCommandsNV or |
| execution time using flink:vkCmdExecuteGeneratedCommandsNV, however some |
| functional arguments, for example binding sets, are specified at layout |
| creation time. |
| The input size is different for each token. |
| |
| [open,refpage='VkIndirectCommandsTokenTypeNV',desc='Enum specifying token commands',type='enums'] |
| -- |
| Possible values of those elements of the |
| slink:VkIndirectCommandsLayoutCreateInfoNV::pname:pTokens array which |
| specify command tokens (other elements of the array specify command |
| parameters) are: |
| |
| include::{generated}/api/enums/VkIndirectCommandsTokenTypeNV.txt[] |
| |
| .Supported indirect command tokens |
| [width="80%",cols="67%,33%",options="header",align="center"] |
| |==== |
| |Token type | Equivalent command |
| |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV | flink:vkCmdBindPipelineShaderGroupNV |
| |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV | - |
| |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV | flink:vkCmdBindIndexBuffer |
| |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV | flink:vkCmdBindVertexBuffers |
| |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV | flink:vkCmdPushConstants |
| |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV | flink:vkCmdDrawIndexedIndirect |
| |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV | flink:vkCmdDrawIndirect |
| ifdef::VK_NV_mesh_shader[] |
| |ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV | flink:vkCmdDrawMeshTasksIndirectNV |
| endif::VK_NV_mesh_shader[] |
| |==== |
| -- |
| |
| [open,refpage='VkIndirectCommandsLayoutTokenNV',desc='Struct specifying the details of an indirect command layout token',type='structs'] |
| -- |
| The sname:VkIndirectCommandsLayoutTokenNV structure specifies details to the |
| function arguments that need to be known at layout creation time: |
| |
| include::{generated}/api/structs/VkIndirectCommandsLayoutTokenNV.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:tokenType specifies the token command type. |
| * pname:stream is the index of the input stream that contains the token |
| argument data. |
| * pname:offset is a relative starting offset within the input stream |
| memory for the token argument data. |
| * pname:vertexBindingUnit is used for the vertex buffer binding command. |
| * pname:vertexDynamicStride sets if the vertex buffer stride is provided |
| by the binding command rather than the current bound graphics pipeline |
| state. |
| * pname:pushconstantPipelineLayout is the sname:VkPipelineLayout used for |
| the push constant command. |
| * pname:pushconstantShaderStageFlags are the shader stage flags used for |
| the push constant command. |
| * pname:pushconstantOffset is the offset used for the push constant |
| command. |
| * pname:pushconstantSize is the size used for the push constant command. |
| * pname:indirectStateFlags are the active states for the state flag |
| command. |
| * pname:indexTypeCount is the optional size of the pname:pIndexTypes and |
| pname:pIndexTypeValues array pairings. |
| If not zero, it allows to register a custom `uint32_t` value to be |
| treated as specific ename:VkIndexType. |
| * pname:pIndexTypes is the used ename:VkIndexType for the corresponding |
| `uint32_t` value entry in pname:pIndexTypeValues. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-stream-02951]] |
| pname:stream must: be smaller than |
| sname:VkIndirectCommandsLayoutCreateInfoNV::pname:streamCount |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-offset-02952]] |
| pname:offset must: be less than or equal to |
| sname:VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV::pname:maxIndirectCommandsTokenOffset |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02976]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV, |
| pname:vertexBindingUnit must: stay within device supported limits for |
| the appropriate commands |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02977]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, |
| pname:pushconstantPipelineLayout must: be valid |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02978]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, |
| pname:pushconstantOffset must: be a multiple of `4` |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02979]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, |
| pname:pushconstantSize must: be a multiple of `4` |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02980]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, |
| pname:pushconstantOffset must: be less than |
| sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02981]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, |
| pname:pushconstantSize must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize minus |
| pname:pushconstantOffset |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02982]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, for each byte in |
| the range specified by pname:pushconstantOffset and |
| pname:pushconstantSize and for each shader stage in |
| pname:pushconstantShaderStageFlags, there must: be a push constant range |
| in pname:pushconstantPipelineLayout that includes that byte and that |
| stage |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02983]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV, for each byte in |
| the range specified by pname:pushconstantOffset and |
| pname:pushconstantSize and for each push constant range that overlaps |
| that byte, pname:pushconstantShaderStageFlags must: include all stages |
| in that push constant range's |
| slink:VkPushConstantRange::pname:stageFlags |
| * [[VUID-VkIndirectCommandsLayoutTokenNV-tokenType-02984]] |
| If pname:tokenType is |
| ename:VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV, |
| pname:indirectStateFlags must: not be `0` |
| **** |
| |
| include::{generated}/validity/structs/VkIndirectCommandsLayoutTokenNV.txt[] |
| -- |
| |
| The following code provides detailed information on how an individual |
| sequence is processed. |
| For valid usage, all restrictions from the regular commands apply. |
| |
| [source,c] |
| --------------------------------------------------- |
| void cmdProcessSequence(cmd, pipeline, indirectCommandsLayout, pIndirectCommandsStreams, s) |
| { |
| for (uint32_t t = 0; t < indirectCommandsLayout.tokenCount; t++){ |
| token = indirectCommandsLayout.pTokens[t]; |
| |
| uint32_t stride = indirectCommandsLayout.pStreamStrides[token.stream]; |
| stream = pIndirectCommandsStreams[token.stream]; |
| uint32_t offset = stream.offset + stride * s + token.offset; |
| const void* input = stream.buffer.pointer( offset ) |
| |
| switch(input.type){ |
| VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV: |
| VkBindShaderGroupIndirectCommandNV* bind = input; |
| |
| vkCmdBindPipelineShaderGroupNV(cmd, indirectCommandsLayout.pipelineBindPoint, |
| pipeline, bind->groupIndex); |
| break; |
| |
| VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV: |
| VkSetStateFlagsIndirectCommandNV* state = input; |
| |
| if (token.indirectStateFlags & VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV){ |
| if (state.data & (1 << 0)){ |
| set VK_FRONT_FACE_CLOCKWISE; |
| } else { |
| set VK_FRONT_FACE_COUNTER_CLOCKWISE; |
| } |
| } |
| break; |
| |
| VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV: |
| uint32_t* data = input; |
| |
| vkCmdPushConstants(cmd, |
| token.pushconstantPipelineLayout |
| token.pushconstantStageFlags, |
| token.pushconstantOffset, |
| token.pushconstantSize, data); |
| break; |
| |
| VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV: |
| VkBindIndexBufferIndirectCommandNV* data = input; |
| |
| // the indexType may optionally be remapped |
| // from a custom uint32_t value, via |
| // VkIndirectCommandsLayoutTokenNV::pIndexTypeValues |
| |
| vkCmdBindIndexBuffer(cmd, |
| deriveBuffer(data->bufferAddress), |
| deriveOffset(data->bufferAddress), |
| data->indexType); |
| break; |
| |
| VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV: |
| VkBindVertexBufferIndirectCommandNV* data = input; |
| |
| // if token.vertexDynamicStride is VK_TRUE |
| // then the stride for this binding is set |
| // using data->stride as well |
| |
| vkCmdBindVertexBuffers(cmd, |
| token.vertexBindingUnit, 1, |
| &deriveBuffer(data->bufferAddress), |
| &deriveOffset(data->bufferAddress)); |
| break; |
| |
| VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV: |
| vkCmdDrawIndexedIndirect(cmd, |
| stream.buffer, offset, 1, 0); |
| break; |
| |
| VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV: |
| vkCmdDrawIndirect(cmd, |
| stream.buffer, |
| offset, 1, 0); |
| break; |
| |
| // only available if VK_NV_mesh_shader is supported |
| VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NV: |
| vkCmdDrawMeshTasksIndirectNV(cmd, |
| stream.buffer, offset, 1, 0); |
| break; |
| } |
| } |
| } |
| --------------------------------------------------- |