> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 网格着色器管线 API 概述

> 网格着色器管线 API 概述

## 管线状态创建

有关这些 API 的示例用法，请参阅[网格着色器管线用法](/build/core-features/graphics/newfeatures/ms/ms-usage)。

以下代码示例展示了网格着色器功能支持相关的 API。

```c theme={null}
typedef  enum D3D12_FEATURE {
    ...
    D3D12_FEATURE_D3D12_OPTIONS7,
} D3D12_FEATURE;

typedef enum D3D12_MESH_SHADER_TIER
{
    D3D12_MESH_SHADER_TIER_NOT_SUPPORTED,
    D3D12_MESH_SHADER_TIER_1
} D3D12_MESH_SHADER_TIER;

typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS7 
{
    _Out_  D3D12_MESH_SHADER_TIER       MeshShaderTier;
    _Out_  D3D12_SAMPLER_FEEDBACK_TIER  SamplerFeedbackTier;
} D3D12_FEATURE_DATA_D3D12_OPTIONS7;

HRESULT ID3D12Device::CheckFeatureSupport(
  D3D12_FEATURE Feature,
  void*         pFeatureSupportData,
  UINT          FeatureSupportDataSize
);
```

以下代码示例展示了网格着色器管线状态规范，它使用管线流（Pipeline Stream）创建 API。

```
typedef struct D3D12_PIPELINE_STATE_STREAM_DESC {
    _In_  SIZE_T SizeInBytes;
    _In_  void*  pPipelineStateSubobjectStream;
} D3D12_PIPELINE_STATE_STREAM_DESC;

HRESULT ID3D12Device2::CreatePipelineState(
    const D3D12_PIPELINE_STATE_STREAM_DESC* pDesc,
    REFIID                                  riid,
    void**                                  ppPipelineState
);
```

以下代码示例展示了用于向 GPU 分派网格着色器管线线程组的 Direct3D 12 API。

```c theme={null}
void ID3D12GraphicsCommandList::DispatchMesh(uint groupCountX, uint groupCountY, uint groupCountZ);

typedef enum D3D12_INDIRECT_ARGUMENT_TYPE {
    ...
    D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH
} D3D12_INDIRECT_ARGUMENT_TYPE;

typedef struct D3D12_INDIRECT_ARGUMENT_DESC
{
    D3D12_INDIRECT_ARGUMENT_TYPE Type; // = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH
    union 
    {
        ...
        struct 
        {
            UINT ThreadGroupCountX;
            UINT ThreadGroupCountY;
            UINT ThreadGroupCountZ;
        } D3D12_DISPATCH_MESH_ARGUMENTS;
    }
} D3D12_INDIRECT_ARGUMENT_DESC;

void ID3D12GraphicsCommandList::ExecuteIndirect(
    ID3D12CommandSignature* pCommandSignature,
    UINT                    MaxCommandCount,
    ID3D12Resource*         pArgumentBuffer,
    UINT64                  ArgumentBufferOffset,
    ID3D12Resource*         pCountBuffer,
    UINT64                  CountBufferOffset
);
```

以下代码示例展示了如何创建并分派网格着色器管线。

```
struct MyPsoStreamDesc
{
    CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE        pRootSignature;
    CD3DX12_PIPELINE_STATE_STREAM_AS                    AS;
    CD3DX12_PIPELINE_STATE_STREAM_MS                    MS;
    CD3DX12_PIPELINE_STATE_STREAM_PS                    PS;
    CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC            BlendState;
    CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1        DepthStencilState;
    CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER            RasterizerState;
    CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTFormats;
    CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT  DepthFormat;
    CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC           SampleDesc;
    CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK           SampleMask;
}

void CreatePipelineState(ID3D12Device* d3dDevice)
{
    // Check Mesh Shader pipeline feature support.
    D3D12_FEATURE_DATA_D3D12_OPTIONS7 options;
    device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &options, sizeof(options));

    if (options.MeshShaderTier == D3D12_MESH_SHADER_TIER_NOT_SUPPORTED)
        throw std::exception("Mesh Shaders not supported!"); 

    // Set up PSO Stream Desc.
    MyPsoStreamDesc psoDesc;
    psoDesc.AS = D3D12_SHADER_BYTECODE{ ... };
    psoDesc.MS = D3D12_SHADER_BYTECODE{ ... };
    ...

    // Create Pipeline State Object with stream desc.
    D3D12_PIPELINE_STATE_STREAM_DESC desc = { sizeof(psoDesc), &psoDesc };
    device->CreatePipelineState(&desc, IID_PPV_ARGS(&msPso));
}

void Draw(ID3D12GraphicsCommandList* commandList)
{
    // Set up pipeline and root signature parameters.
    commandList->SetPipelineState(&msPso);
    commandList->SetGraphicsRootSignature(&msRootSig);
    ...

    // Dispatch threadgroups.
    commandList->DispatchMesh(someGroupCount, 1, 1);
}
```

## 网格着色器内建

### 属性

| 名称                 | 说明                                                                                               |
| ------------------ | ------------------------------------------------------------------------------------------------ |
| **OutputTopology** | 指定着色器导出的图元类型——可以是 "line"（线）或 "triangle"（三角形）。必须与共享输出数组 *indices* 的类型匹配（线为 *uint2*，三角形为 *uint3*）。 |

### 函数

|    |                                                                                                   |
| -- | ------------------------------------------------------------------------------------------------- |
| 名称 | **SetMeshOutputCounts**                                                                           |
| 参数 | *uint numVerts* *uint numPrims*                                                                   |
| 说明 | 声明线程组要导出的顶点和图元数量——若未调用，计数默认为零。必须小于或等于共享输出数组的长度，并且必须从非发散执行上下文中调用，且假定参数值在线程组中为常量。必须先于对输出数组的所有写操作调用。 |

### 参数

| 名称              | 修饰符 | 说明                                                                                                         |
| --------------- | --- | ---------------------------------------------------------------------------------------------------------- |
| *payload*       | in  | 从放大着色器（Amplification Shader）传递到其网格着色器实例集群的、大小最多为 16 KB 的自定义类型载荷数据。此数据在集群中的所有实例之间共享。若网格着色器之前没有放大着色器阶段，则不适用。 |
| *vertices* 数组   | out | 用于导出顶点属性的共享输出数组。通过数组长度定义自定义顶点属性类型和最大顶点导出数。                                                                 |
| *indices* 数组    | out | 用于导出图元索引的共享输出数组。通过数组长度定义要导出的图元类型和最大图元导出数。这些图元索引直接索引到 *vertices* 数组。类型为线时应为 uint2，三角形时应为 uint3。             |
| *primitives* 数组 | out | 用于导出图元属性的共享输出数组。定义用户自定义的图元属性类型。其长度必须与 *indices* 数组的长度相等。                                                   |

## 放大着色器内建

### 函数

|    |                                                                                                                  |
| -- | ---------------------------------------------------------------------------------------------------------------- |
| 名称 | **DispatchMesh**                                                                                                 |
| 参数 | *uint groupsX* *uint groupsY* *uint groupsZ* *groupshared payload\_t payload*                                    |
| 说明 | 分派一个网格着色器线程组集群，并可选择附带载荷数据。只能从非发散代码路径中最多调用一次。若未调用，则分派零个线程组。后续的网格着色器线程组的 GroupID 和 DispatchThreadID 会被局部化到其所在的集群中。 |

## 另请参阅

[网格着色器管线概述](/build/core-features/graphics/newfeatures/ms/ms-overview)

[为什么使用网格着色器？](/build/core-features/graphics/newfeatures/ms/ms-why)

[网格着色器管线用法](/build/core-features/graphics/newfeatures/ms/ms-usage)


## Related topics

- [网格着色器管线概述](/zh-CN/build/core-features/graphics/newfeatures/ms/ms-overview.md)
- [为什么使用网格着色器？](/zh-CN/build/core-features/graphics/newfeatures/ms/ms-why.md)
- [XBOX Series X|S 上的网格着色器与 Meshlet](/zh-CN/build/core-features/graphics/newfeatures/ms/index.md)
- [Meshlets](/zh-CN/build/core-features/graphics/newfeatures/ms/ms-meshlet-render.md)
- [Meshlet 剔除示例](/zh-CN/build/core-features/graphics/newfeatures/ms/ms-meshlet-culling.md)
