// Copyright (c) 2018-2020 NVIDIA Corporation
//
// SPDX-License-Identifier: CC-BY-4.0

[[drawing-mesh-shading]]
== Programmable Mesh Shading

In this drawing approach, primitives are assembled by the mesh shader stage.
<<mesh, Mesh shading>> operates similarly to <<dispatch, dispatching
compute>> as the shaders make use of workgroups.

ifdef::VK_NV_mesh_shader[]
[open,refpage='vkCmdDrawMeshTasksNV',desc='Draw mesh task work items',type='protos']
--
:refpage: vkCmdDrawMeshTasksNV

To record a mesh tasks drawing command, call:

include::{generated}/api/protos/vkCmdDrawMeshTasksNV.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:taskCount is the number of local workgroups to dispatch in the X
    dimension.
    Y and Z dimension are implicitly set to one.
  * pname:firstTask is the X component of the first workgroup ID.

When the command is executed, a global workgroup consisting of
pname:taskCount local workgroups is assembled.

.Valid Usage
****
include::{chapters}/commonvalidity/draw_common.adoc[]
include::{chapters}/commonvalidity/draw_mesh_common.adoc[]
  * [[VUID-vkCmdDrawMeshTasksNV-taskCount-02119]]
    pname:taskCount must: be less than or equal to
    sname:VkPhysicalDeviceMeshShaderPropertiesNV::pname:maxDrawMeshTasksCount
  * [[VUID-vkCmdDrawMeshTasksNV-MeshNV-07080]]
    The current pipeline bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS
    must: contain a shader stage using the code:MeshNV {ExecutionModel}
****

include::{generated}/validity/protos/vkCmdDrawMeshTasksNV.adoc[]
--

[open,refpage='vkCmdDrawMeshTasksIndirectNV',desc='Issue an indirect mesh tasks draw into a command buffer',type='protos']
--
:refpage: vkCmdDrawMeshTasksIndirectNV

To record an indirect mesh tasks drawing command, call:

include::{generated}/api/protos/vkCmdDrawMeshTasksIndirectNV.adoc[]

  * pname:commandBuffer is the command buffer into which the command is
    recorded.
  * pname:buffer is the buffer containing draw parameters.
  * pname:offset is the byte offset into pname:buffer where parameters
    begin.
  * pname:drawCount is the number of draws to execute, and can: be zero.
  * pname:stride is the byte stride between successive sets of draw
    parameters.

fname:vkCmdDrawMeshTasksIndirectNV behaves similarly to
flink:vkCmdDrawMeshTasksNV except that the parameters are read by the device
from a buffer during execution.
pname:drawCount draws are executed by the command, with parameters taken
from pname:buffer starting at pname:offset and increasing by pname:stride
bytes for each successive draw.
The parameters of each draw are encoded in an array of
slink:VkDrawMeshTasksIndirectCommandNV structures.
If pname:drawCount is less than or equal to one, pname:stride is ignored.

.Valid Usage
****
include::{chapters}/commonvalidity/draw_common.adoc[]
include::{chapters}/commonvalidity/draw_mesh_common.adoc[]
include::{chapters}/commonvalidity/draw_dispatch_indirect_common.adoc[]
include::{chapters}/commonvalidity/draw_indirect_drawcount.adoc[]
  * [[VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146]]
    If pname:drawCount is greater than `1`, pname:stride must: be a multiple
    of `4` and must: be greater than or equal to
    code:sizeof(sname:VkDrawMeshTasksIndirectCommandNV)
  * [[VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02156]]
    If pname:drawCount is equal to `1`, [eq]#(pname:offset {plus}
    code:sizeof(slink:VkDrawMeshTasksIndirectCommandNV))# must: be less than
    or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02157]]
    If pname:drawCount is greater than `1`, [eq]#(pname:stride {times}
    (pname:drawCount - 1) {plus} pname:offset {plus}
    code:sizeof(slink:VkDrawMeshTasksIndirectCommandNV))# must: be less than
    or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectNV-MeshNV-07081]]
    The current pipeline bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS
    must: contain a shader stage using the code:MeshNV {ExecutionModel}
****

include::{generated}/validity/protos/vkCmdDrawMeshTasksIndirectNV.adoc[]
--

[open,refpage='VkDrawMeshTasksIndirectCommandNV',desc='Structure specifying a mesh tasks draw indirect command',type='structs',xrefs='vkCmdDrawMeshTasksIndirectNV']
--
The sname:VkDrawMeshTasksIndirectCommandNV structure is defined as:

include::{generated}/api/structs/VkDrawMeshTasksIndirectCommandNV.adoc[]

  * pname:taskCount is the number of local workgroups to dispatch in the X
    dimension.
    Y and Z dimension are implicitly set to one.
  * pname:firstTask is the X component of the first workgroup ID.

The members of sname:VkDrawMeshTasksIndirectCommandNV have the same meaning
as the similarly named parameters of flink:vkCmdDrawMeshTasksNV.

.Valid Usage
****
  * [[VUID-VkDrawMeshTasksIndirectCommandNV-taskCount-02175]]
    pname:taskCount must: be less than or equal to
    sname:VkPhysicalDeviceMeshShaderPropertiesNV::pname:maxDrawMeshTasksCount
****

include::{generated}/validity/structs/VkDrawMeshTasksIndirectCommandNV.adoc[]
--

[open,refpage='vkCmdDrawMeshTasksIndirectCountNV',desc='Perform an indirect mesh tasks draw with the draw count sourced from a buffer',type='protos']
--
:refpage: vkCmdDrawMeshTasksIndirectCountNV

To record an indirect mesh tasks drawing command with the draw count sourced
from a buffer, call:

include::{generated}/api/protos/vkCmdDrawMeshTasksIndirectCountNV.adoc[]

  * pname:commandBuffer is the command buffer into which the command is
    recorded.
  * pname:buffer is the buffer containing draw parameters.
  * pname:offset is the byte offset into pname:buffer where parameters
    begin.
  * pname:countBuffer is the buffer containing the draw count.
  * pname:countBufferOffset is the byte offset into pname:countBuffer where
    the draw count begins.
  * pname:maxDrawCount specifies the maximum number of draws that will be
    executed.
    The actual number of executed draw calls is the minimum of the count
    specified in pname:countBuffer and pname:maxDrawCount.
  * pname:stride is the byte stride between successive sets of draw
    parameters.

fname:vkCmdDrawMeshTasksIndirectCountNV behaves similarly to
flink:vkCmdDrawMeshTasksIndirectNV except that the draw count is read by the
device from a buffer during execution.
The command will read an unsigned 32-bit integer from pname:countBuffer
located at pname:countBufferOffset and use this as the draw count.

.Valid Usage
****
include::{chapters}/commonvalidity/draw_common.adoc[]
include::{chapters}/commonvalidity/draw_mesh_common.adoc[]
include::{chapters}/commonvalidity/draw_dispatch_indirect_common.adoc[]
include::{chapters}/commonvalidity/draw_indirect_count_common.adoc[]
  * [[VUID-vkCmdDrawMeshTasksIndirectCountNV-stride-02182]]
    pname:stride must: be a multiple of `4` and must: be greater than or
    equal to code:sizeof(sname:VkDrawMeshTasksIndirectCommandNV)
  * [[VUID-vkCmdDrawMeshTasksIndirectCountNV-maxDrawCount-02183]]
    If pname:maxDrawCount is greater than or equal to `1`,
    [eq]#(pname:stride {times} (pname:maxDrawCount - 1) {plus} pname:offset
    {plus} code:sizeof(sname:VkDrawMeshTasksIndirectCommandNV))# must: be
    less than or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02191]]
    If the count stored in pname:countBuffer is equal to `1`,
    [eq]#(pname:offset {plus}
    code:sizeof(sname:VkDrawMeshTasksIndirectCommandNV))# must: be less than
    or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02192]]
    If the count stored in pname:countBuffer is greater than `1`,
    [eq]#(pname:stride {times} (pname:drawCount - 1) {plus} pname:offset
    {plus} code:sizeof(sname:VkDrawMeshTasksIndirectCommandNV))# must: be
    less than or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectCountNV-MeshNV-07082]]
    The current pipeline bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS
    must: contain a shader stage using the code:MeshNV {ExecutionModel}
****

include::{generated}/validity/protos/vkCmdDrawMeshTasksIndirectCountNV.adoc[]

--
endif::VK_NV_mesh_shader[]
ifdef::VK_EXT_mesh_shader[]
[open,refpage='vkCmdDrawMeshTasksEXT',desc='Draw mesh task work items',type='protos']
--
:refpage: vkCmdDrawMeshTasksEXT

To record a mesh tasks drawing command, call:

include::{generated}/api/protos/vkCmdDrawMeshTasksEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:groupCountX is the number of local workgroups to dispatch in the X
    dimension.
  * pname:groupCountY is the number of local workgroups to dispatch in the Y
    dimension.
  * pname:groupCountZ is the number of local workgroups to dispatch in the Z
    dimension.

When the command is executed, a global workgroup consisting of
[eq]#pname:groupCountX {times} pname:groupCountY {times} pname:groupCountZ#
local workgroups is assembled.

.Valid Usage
****
include::{chapters}/commonvalidity/draw_common.adoc[]
include::{chapters}/commonvalidity/draw_mesh_common.adoc[]
include::{chapters}/commonvalidity/draw_mesh_limits_common.adoc[]
  * [[VUID-vkCmdDrawMeshTasksEXT-MeshEXT-07087]]
    The current pipeline bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS
    must: contain a shader stage using the code:MeshEXT {ExecutionModel}
****

include::{generated}/validity/protos/vkCmdDrawMeshTasksEXT.adoc[]
--

[open,refpage='vkCmdDrawMeshTasksIndirectEXT',desc='Issue an indirect mesh tasks draw into a command buffer',type='protos']
--
:refpage: vkCmdDrawMeshTasksIndirectEXT

To record an indirect mesh tasks drawing command, call:

include::{generated}/api/protos/vkCmdDrawMeshTasksIndirectEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command is
    recorded.
  * pname:buffer is the buffer containing draw parameters.
  * pname:offset is the byte offset into pname:buffer where parameters
    begin.
  * pname:drawCount is the number of draws to execute, and can: be zero.
  * pname:stride is the byte stride between successive sets of draw
    parameters.

fname:vkCmdDrawMeshTasksIndirectEXT behaves similarly to
flink:vkCmdDrawMeshTasksEXT except that the parameters are read by the
device from a buffer during execution.
pname:drawCount draws are executed by the command, with parameters taken
from pname:buffer starting at pname:offset and increasing by pname:stride
bytes for each successive draw.
The parameters of each draw are encoded in an array of
slink:VkDrawMeshTasksIndirectCommandEXT structures.
If pname:drawCount is less than or equal to one, pname:stride is ignored.

.Valid Usage
****
include::{chapters}/commonvalidity/draw_common.adoc[]
include::{chapters}/commonvalidity/draw_mesh_common.adoc[]
include::{chapters}/commonvalidity/draw_dispatch_indirect_common.adoc[]
include::{chapters}/commonvalidity/draw_indirect_drawcount.adoc[]
  * [[VUID-vkCmdDrawMeshTasksIndirectEXT-drawCount-07088]]
    If pname:drawCount is greater than `1`, pname:stride must: be a multiple
    of `4` and must: be greater than or equal to
    code:sizeof(sname:VkDrawMeshTasksIndirectCommandEXT)
  * [[VUID-vkCmdDrawMeshTasksIndirectEXT-drawCount-07089]]
    If pname:drawCount is equal to `1`, [eq]#(pname:offset {plus}
    code:sizeof(slink:VkDrawMeshTasksIndirectCommandEXT))# must: be less
    than or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectEXT-drawCount-07090]]
    If pname:drawCount is greater than `1`, [eq]#(pname:stride {times}
    (pname:drawCount - 1) {plus} pname:offset {plus}
    code:sizeof(slink:VkDrawMeshTasksIndirectCommandEXT))# must: be less
    than or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectEXT-MeshEXT-07091]]
    The current pipeline bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS
    must: contain a shader stage using the code:MeshEXT {ExecutionModel}
****

include::{generated}/validity/protos/vkCmdDrawMeshTasksIndirectEXT.adoc[]
--

[open,refpage='VkDrawMeshTasksIndirectCommandEXT',desc='Structure specifying a mesh tasks draw indirect command',type='structs',xrefs='vkCmdDrawMeshTasksIndirectEXT']
--
The sname:VkDrawMeshTasksIndirectCommandEXT structure is defined as:

include::{generated}/api/structs/VkDrawMeshTasksIndirectCommandEXT.adoc[]

  * pname:groupCountX is the number of local workgroups to dispatch in the X
    dimension.
  * pname:groupCountY is the number of local workgroups to dispatch in the Y
    dimension.
  * pname:groupCountZ is the number of local workgroups to dispatch in the Z
    dimension.

The members of sname:VkDrawMeshTasksIndirectCommandEXT have the same meaning
as the similarly named parameters of flink:vkCmdDrawMeshTasksEXT.

.Valid Usage
****
include::{chapters}/commonvalidity/draw_mesh_limits_common.adoc[]
****

include::{generated}/validity/structs/VkDrawMeshTasksIndirectCommandEXT.adoc[]
--

[open,refpage='vkCmdDrawMeshTasksIndirectCountEXT',desc='Perform an indirect mesh tasks draw with the draw count sourced from a buffer',type='protos']
--
:refpage: vkCmdDrawMeshTasksIndirectCountEXT

To record an indirect mesh tasks drawing command with the draw count sourced
from a buffer, call:

include::{generated}/api/protos/vkCmdDrawMeshTasksIndirectCountEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command is
    recorded.
  * pname:buffer is the buffer containing draw parameters.
  * pname:offset is the byte offset into pname:buffer where parameters
    begin.
  * pname:countBuffer is the buffer containing the draw count.
  * pname:countBufferOffset is the byte offset into pname:countBuffer where
    the draw count begins.
  * pname:maxDrawCount specifies the maximum number of draws that will be
    executed.
    The actual number of executed draw calls is the minimum of the count
    specified in pname:countBuffer and pname:maxDrawCount.
  * pname:stride is the byte stride between successive sets of draw
    parameters.

fname:vkCmdDrawMeshTasksIndirectCountEXT behaves similarly to
flink:vkCmdDrawMeshTasksIndirectEXT except that the draw count is read by
the device from a buffer during execution.
The command will read an unsigned 32-bit integer from pname:countBuffer
located at pname:countBufferOffset and use this as the draw count.

.Valid Usage
****
include::{chapters}/commonvalidity/draw_common.adoc[]
include::{chapters}/commonvalidity/draw_mesh_common.adoc[]
include::{chapters}/commonvalidity/draw_dispatch_indirect_common.adoc[]
include::{chapters}/commonvalidity/draw_indirect_count_common.adoc[]
  * [[VUID-vkCmdDrawMeshTasksIndirectCountEXT-stride-07096]]
    pname:stride must: be a multiple of `4` and must: be greater than or
    equal to code:sizeof(sname:VkDrawMeshTasksIndirectCommandEXT)
  * [[VUID-vkCmdDrawMeshTasksIndirectCountEXT-maxDrawCount-07097]]
    If pname:maxDrawCount is greater than or equal to `1`,
    [eq]#(pname:stride {times} (pname:maxDrawCount - 1) {plus} pname:offset
    {plus} code:sizeof(sname:VkDrawMeshTasksIndirectCommandEXT))# must: be
    less than or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectCountEXT-countBuffer-07098]]
    If the count stored in pname:countBuffer is equal to `1`,
    [eq]#(pname:offset {plus}
    code:sizeof(sname:VkDrawMeshTasksIndirectCommandEXT))# must: be less
    than or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectCountEXT-countBuffer-07099]]
    If the count stored in pname:countBuffer is greater than `1`,
    [eq]#(pname:stride {times} (pname:drawCount - 1) {plus} pname:offset
    {plus} code:sizeof(sname:VkDrawMeshTasksIndirectCommandEXT))# must: be
    less than or equal to the size of pname:buffer
  * [[VUID-vkCmdDrawMeshTasksIndirectCountEXT-MeshEXT-07100]]
    The current pipeline bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS
    must: contain a shader stage using the code:MeshEXT {ExecutionModel}
****

include::{generated}/validity/protos/vkCmdDrawMeshTasksIndirectCountEXT.adoc[]

--
endif::VK_EXT_mesh_shader[]
