window显示驱动开发—输入装配器阶段

发布于:2025-06-18 ⋅ 阅读:(10) ⋅ 点赞:(0)

输入装配器 (IA) 通过将源几何图形数据从 1D 缓冲区中拉取,将三角形、线条或点引入渲染管道。

顶点数据可以来自多个缓冲区,并且可以从每个缓冲区以结构数组的方式访问。 每个缓冲区都绑定到单个输入槽,并给定一个结构步幅。 跨所有缓冲区的数据布局由输入声明指定,其中每个条目定义一个 元素。 元素包含管道) 中第一个活动着色器的输入槽、结构偏移量、数据类型和目标寄存器 (。

给定的顶点序列是从缓冲区提取的数据构造的。 数据在固定函数状态和各种 Draw* () DDI 调用的组合定向的遍历中获取。 各种基元拓扑 (例如点列表、行列表、三角形列表和三角形带) 可用于使顶点数据序列表示基元序列。

可以通过以下两种方式之一生成顶点数据。 生成顶点数据的第一种方法是 非索引 呈现,这是包含顶点数据的缓冲区的顺序遍历。 顶点数据源自每个缓冲区绑定的起始偏移量。 生成顶点数据的第二种方法是 索引 呈现,这是包含标量整数索引的单个缓冲区的顺序遍历。 索引源自缓冲区的起始偏移量。 每个索引指示从包含顶点数据的缓冲区中提取数据的位置。 索引值与它们引用的缓冲区的特征无关。 缓冲区由声明描述。 非索引和索引呈现,每个呈现都以自己的方式生成地址,从中获取内存中的顶点数据,然后将结果组合到顶点和基元中。

通过允许在非索引呈现或索引呈现中,顺序遍历在每个顶点缓冲区内循环, (非索引大小写) 或索引缓冲区 (索引大小写) 来启用实例化几何图形呈现。 可以将缓冲区绑定标识为 实例数据 或 顶点数据。 此标识指定在执行实例化呈现时如何使用绑定缓冲区。 非索引或索引呈现生成的地址用于提取顶点数据,这也考虑了运行时执行实例化呈现时的循环。 另一方面,始终从每个缓冲区偏移量开始按顺序遍历实例数据,其频率等于每个实例一个步骤 (例如,在) 遍历实例中的顶点数后向前一步。 实例数据的步进速率也可以选择为实例频率 (的子调和,即,每个其他实例向前一步,每三个实例) ,依此类推。

IA 的另一个特殊情况是,它可以读取流输出阶段写入的缓冲区。 此类方案启用一种新型的绘制操作 DrawAuto。 DrawAuto 允许在不涉及 CPU 的情况下重复使用写入流输出缓冲区的动态输出量,以确定实际写入的数据量。

除了从缓冲区生成顶点数据外,IA 还可以自动生成三个标量计数器值:VertexID、PrimitiveID 和 InstanceID,以便输入到呈现管道中的着色器阶段。

在带状拓扑(如三角形带)的索引呈现中,提供了一种机制,用于使用单个 *Draw* () 调用 (绘制多个条带,即) 剪切条带的 *cut 命令。

1. 核心功能概述

输入装配器 (Input Assembler, IA) 是渲染管线的首个固定功能阶段,负责将原始几何数据(顶点、索引)组装成图元(点、线、三角形)。其核心任务包括:

  1. 数据提取:从1D缓冲区读取顶点/索引数据。
  2. 拓扑解释:将数据转换为指定图元类型(如三角形列表、线带)。
  3. 实例化支持:高效处理重复几何体(如批量渲染相同模型)。
  4. ID生成:自动生成 VertexID、PrimitiveID、InstanceID 供着色器使用。

2. 数据输入机制

(1) 数据来源

数据源 描述
顶点缓冲区 存储顶点属性(位置、法线、UV等),支持多缓冲区绑定。
索引缓冲区 存储顶点索引,支持16/32位整数,优化顶点复用。
流输出缓冲区 从几何着色器 (GS) 输出的数据可循环回IA(通过 DrawAuto)。

(2) 数据组织方式
结构数组 (Struct-of-Arrays)
每个缓冲区绑定到独立输入槽,数据按跨步(Stride)访问:

// 示例:顶点缓冲区布局(位置 + 法线)
struct Vertex { float3 Pos; float3 Normal; };
D3D10DDI_HRESOURCE hBuffer;
UINT stride = sizeof(Vertex); // 步幅为24字节
UINT offset = 0;
pDeviceFuncs->IaSetVertexBuffers(hDevice, 0, 1, &hBuffer, &stride, &offset);

输入槽声明
通过 CreateElementLayout 定义如何组合多缓冲区的数据:

D3D10DDI_ELEMENT_LAYOUT_DESC elements[] = {
    { 0, 0,  DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D10DDI_INPUT_PER_VERTEX }, // 位置
    { 0, 12, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D10DDI_INPUT_PER_VERTEX }  // 法线
};

3. 图元拓扑与绘制方式

(1) 支持的拓扑类型

拓扑类型 描述 适用场景
D3D10DDI_PRIMITIVE_POINTLIST 独立点 粒子系统
D3D10DDI_PRIMITIVE_LINELIST 独立线段 线框渲染
D3D10DDI_PRIMITIVE_TRIANGLELIST 独立三角形 通用网格渲染
D3D10DDI_PRIMITIVE_TRIANGLESTRIP 三角形带(共享顶点) 连续表面(如地形)

(2) 绘制调用
非索引绘制 (Draw)
直接顺序读取顶点缓冲区:

pDeviceFuncs->Draw(hDevice, vertexCount, startVertex);

索引绘制 (DrawIndexed)
通过索引缓冲区间接引用顶点:

pDeviceFuncs->DrawIndexed(hDevice, indexCount, startIndex, baseVertex);

实例化绘制 (DrawInstanced/DrawIndexedInstanced)
重复渲染相同几何体,支持逐实例数据步进:

pDeviceFuncs->DrawIndexedInstanced(hDevice, indexCountPerInstance, instanceCount,
                                  startIndex, baseVertex, startInstance);

4. 高级特性

(1) 实例化 (Instancing)
顶点数据:每实例更新一次(如世界矩阵)。

实例步进速率:可配置为每N实例更新一次(如每2实例一个变换)

// 绑定实例数据缓冲区(步幅较大)
UINT instanceStride = sizeof(InstanceData);
pDeviceFuncs->IaSetVertexBuffers(hDevice, 1, 1, &hInstanceBuffer, &instanceStride, &offset);

(2) 流输出循环 (DrawAuto)
允许几何着色器输出数据直接作为IA输入,完全绕过CPU:

pDeviceFuncs->DrawAuto(hDevice); // 自动读取GS写入的缓冲区

(3) 自动生成ID

ID类型 用途
SV_VertexID 标识当前顶点(非索引绘制时为顺序号)。
SV_InstanceID 标识当前实例(用于实例化区分)。
SV_PrimitiveID 标识当前图元(GS/PS中可用)。

5. 驱动函数实现

Direct3D 运行时通过以下DDI函数控制IA:

函数 职责
CalcPrivateElementLayoutSize 计算输入布局私有数据大小。
CreateElementLayout 创建输入布局对象(定义顶点数据结构)。
DestroyElementLayout 释放输入布局资源。
IaSetIndexBuffer 绑定索引缓冲区。
IaSetInputLayout 设置当前输入布局。
IaSetTopology 设置图元拓扑类型。
IaSetVertexBuffers 绑定顶点缓冲区(支持多槽位)。

示例驱动实现:

// 设置顶点缓冲区
void APIENTRY IaSetVertexBuffers(
    D3D10DDI_HDEVICE hDevice,
    UINT StartSlot,
    UINT NumBuffers,
    const D3D10DDI_HRESOURCE* phBuffers,
    const UINT* pStrides,
    const UINT* pOffsets
) {
    MyDeviceContext* pCtx = (MyDeviceContext*)hDevice.pDrvPrivate;
    for (UINT i = 0; i < NumBuffers; ++i) {
        pCtx->vertexBuffers[StartSlot + i] = phBuffers[i];
        pCtx->strides[StartSlot + i] = pStrides[i];
        pCtx->offsets[StartSlot + i] = pOffsets[i];
    }
}

6. 性能优化建议

  1. 顶点复用:优先使用索引绘制(减少重复顶点处理)。
  2. 实例化:对重复对象使用 DrawInstanced 降低API开销。
  3. 数据对齐:确保顶点缓冲区步幅符合硬件要求(如16字节对齐)。
  4. 流输出缓存:复用 DrawAuto 避免CPU-GPU同步。

总结

输入装配器 (IA) 是Direct3D 10渲染管线的数据网关,其核心价值在于:

  1. 灵活的数据组织:支持多缓冲区、结构数组、实例化。
  2. 高效的图元组装:通过索引/非索引绘制适配不同场景。
  3. 与着色器协同:自动生成ID、支持流输出循环。

网站公告

今日签到

点亮在社区的每一天
去签到