window显示驱动开发—外壳着色器
外壳着色器每个补丁运行一次。 可以将外壳着色器与输入装配器中的修补程序一起使用。 外壳着色器可以将构成修补程序的输入控制点转换为输出控制点。 外壳着色器可以为固定函数细化器阶段执行其他设置。 例如,外壳着色器可以输出 tess 因子,这些因子是指示 tessellate 量的数字。
Direct3D 运行时调用以下驱动程序函数来创建、设置和销毁外壳着色器:
- CalcPrivateShaderSize
- CalcPrivateTessellationShaderSize
- CreateHullShader
- DestroyShader
- HsSetShaderResources
- HsSetShader
- HsSetSamplers
- HsSetConstantBuffers
- HsSetShaderWithIfaces
外壳着色器核心机制
1. 执行特性
调用频率:每个补丁(Patch)运行一次,处理输入控制点 → 输出控制点 + 细分参数。
关键输出:
- OutputControlPoints:转换后的控制点(传递给域着色器)。
- TessFactors:细分因子(传递给固定函数细分器)。
2. 管线阶段依赖
驱动函数实现规范
1. 资源计算与创建
CalcPrivateTessellationShaderSize
cpp return sizeof(DRIVER_HS_DATA) + NumInterfaces * sizeof(IFACE_PTR);
CreateHullShader
DestroyShader
cpp pDriverHS->Release();
CreateHullShader 示例:
HRESULT CreateHullShader( D3D10DDI_HDEVICE hDevice, const UINT* pCode,// 着色器字节码 D3D10DDI_HSHADER hShader, // 驱动句柄 D3D11DDIARG_TESSELLATION_HS_DESC* pDesc // 细分参数) { // 1. 编译为硬件指令 DRIVER_HS* pDriverHS = CompileHS(pCode, pDesc->OutputControlPoints); // 2. 配置细分因子寄存器 if (pDesc->pTessFactors) { WriteRegister(HS_TESS_FACTOR_REG, pDesc->pTessFactors); } // 3. 绑定驱动私有数据 hShader.pDrvPrivate = pDriverHS; return S_OK;}
2. 运行时绑定函数
HsSetShader
HsSetShaderWithIfaces
HsSetConstantBuffers
pfnSetConstantBuffers
回调)。HsSetShaderResources
HsSetSamplers
D3D11_DDI_SAMPLER_STATE
)。硬件交互要点
1. 细分因子传递
驱动需将 TessFactors 写入特定寄存器供固定函数单元读取:
void UpdateTessFactors(const float* pFactors) { WriteRegister(TESS_INNER_FACTOR_REG, pFactors[0]); // 内部分割因子 WriteRegister(TESS_OUTER_FACTOR_REG, pFactors[1]); // 外部分割因子}
2. 控制点数据流
- 输入:从输入装配器获取原始控制点(如 D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST)。
- 输出:通过片上缓存(On-Chip Cache)传递给域着色器,避免显存往返。
3. 动态接口处理
void HsSetShaderWithIfaces( D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader, const UINT* pIfaces // 接口函数指针数组) { DRIVER_HS* pDriverHS = (DRIVER_HS*)hShader.pDrvPrivate; for (UINT i = 0; i NumIfaces; i++) { pDriverHS->Ifaces[i] = pIfaces[i]; // 更新接口表 } FlushShaderCache(); // 确保新接口生效}
状态管理与验证
1. 资源冲突检查
当HS绑定资源(如SRV/UAV)时,驱动需验证:
bool CheckHSResourceConflict(D3D10DDI_HRESOURCE hResource) { D3D11_RESOURCE_STATES state = GetResourceState(hResource); return (state & D3D11_RESOURCE_STATE_COMPUTE_WRITE); // 计算管线写入冲突}
2. 细分能力报告
在 GetCaps 中声明硬件细分支持:
D3D11_FEATURE_DATA_D3D11_OPTIONS caps = {};caps.Tessellation = HardwareSupportsTessellation();pDeviceFuncs->pfnGetCaps(pDevice, &caps);
调试与性能优化
细分因子可视化
- 通过 PIX 捕获 TessFactors 值,验证HS逻辑正确性。
控制点缓存命中率
- 使用硬件性能计数器(如 NVIDIA NSIGHT)分析HS阶段缓存效率。
动态接口开销
- 统计 HsSetShaderWithIfaces 调用频率,优化接口表更新机制。
错误处理
DXGI_ERROR_INVALID_DATA
DXGI_ERROR_DEVICE_REMOVED
E_INVALIDARG
总结
- 补丁级处理:HS需高效处理控制点转换与细分参数生成。
- 硬件协作:通过寄存器配置与固定函数单元交互(细分器)。
- 状态隔离:严格管理资源绑定,避免绘图/计算管线冲突。
- 动态支持:正确处理着色器接口与运行时能力协商。