DirectX 12 资源绑定
DirectX 12 Resource binding
如何将资源绑定到 D3D12 中的不同着色器阶段?
我写了两个着色器,一个顶点着色器和一个像素着色器:
这是顶点着色器:
//VertexShader.vs
float4 main(float3 posL : POSITION, uniform float4x4 gWVP) : SV_POSITION
{
return mul(float4(posL, 1.0f), gWVP);
}
这是像素着色器:
//PixelShader.ps
float4 main(float4 PosH : SV_POSITION, uniform float4 Color) : SV_Target
{
return Color;
}
如果我用 D3DCompile
函数编译这两个着色器并用 D3DReflect
反映它并检查着色器描述中的 BoundResorces 成员,它们都有一个名为 $Params 的常量缓冲区,其中包含统一变量分别。问题是这两个缓冲区都绑定到插槽 0。绑定资源时,我必须使用 ID3D12RootSignature 接口,它可以将资源绑定到资源插槽。如何将顶点着色器的 $Params 缓冲区仅绑定到顶点着色器,将像素着色器的 $Params 缓冲区仅绑定到像素着色器?
提前致谢,
Philinator
对于 DX12,这里的高性能解决方案是创建满足您的应用程序需求的根签名,理想情况下 declare it in your HLSL 也是如此。您不想经常更改根签名,因此您肯定希望制作一个适用于大量着色器的签名。
Remember DX12 is Direct3D without training wheels, magic, or shader patching so you just have to do it all explicitly yourself. Ease-of-use is a non-goal for Direct3D 12. There are plenty of good reason to stick with Direct3D 11 unless your application and developer resources merit the extra control Direct3D 12 affords you. With great power comes great responsibility.
我相信你可以通过以下方式实现你想要的:
CD3DX12_DESCRIPTOR_RANGE descRange[1];
descRange[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
CD3DX12_ROOT_PARAMETER rootParameters[2];
rootParameters[0].InitAsDescriptorTable(
1, &descRange[0], D3D12_SHADER_VISIBILITY_VERTEX); // b0
rootParameters[1].InitAsDescriptorTable(
1, &descRange[0], D3D12_SHADER_VISIBILITY_PIXEL); // b0
// Create the root signature.
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc(_countof(rootParameters),
rootParameters, 0, nullptr,
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> error;
DX::ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc,
D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
DX::ThrowIfFailed(
device->CreateRootSignature(0, signature->GetBufferPointer(),
signature->GetBufferSize(),
IID_PPV_ARGS(m_rootSignature.ReleaseAndGetAddressOf())));
如何将资源绑定到 D3D12 中的不同着色器阶段?
我写了两个着色器,一个顶点着色器和一个像素着色器:
这是顶点着色器:
//VertexShader.vs
float4 main(float3 posL : POSITION, uniform float4x4 gWVP) : SV_POSITION
{
return mul(float4(posL, 1.0f), gWVP);
}
这是像素着色器:
//PixelShader.ps
float4 main(float4 PosH : SV_POSITION, uniform float4 Color) : SV_Target
{
return Color;
}
如果我用 D3DCompile
函数编译这两个着色器并用 D3DReflect
反映它并检查着色器描述中的 BoundResorces 成员,它们都有一个名为 $Params 的常量缓冲区,其中包含统一变量分别。问题是这两个缓冲区都绑定到插槽 0。绑定资源时,我必须使用 ID3D12RootSignature 接口,它可以将资源绑定到资源插槽。如何将顶点着色器的 $Params 缓冲区仅绑定到顶点着色器,将像素着色器的 $Params 缓冲区仅绑定到像素着色器?
提前致谢,
Philinator
对于 DX12,这里的高性能解决方案是创建满足您的应用程序需求的根签名,理想情况下 declare it in your HLSL 也是如此。您不想经常更改根签名,因此您肯定希望制作一个适用于大量着色器的签名。
Remember DX12 is Direct3D without training wheels, magic, or shader patching so you just have to do it all explicitly yourself. Ease-of-use is a non-goal for Direct3D 12. There are plenty of good reason to stick with Direct3D 11 unless your application and developer resources merit the extra control Direct3D 12 affords you. With great power comes great responsibility.
我相信你可以通过以下方式实现你想要的:
CD3DX12_DESCRIPTOR_RANGE descRange[1];
descRange[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
CD3DX12_ROOT_PARAMETER rootParameters[2];
rootParameters[0].InitAsDescriptorTable(
1, &descRange[0], D3D12_SHADER_VISIBILITY_VERTEX); // b0
rootParameters[1].InitAsDescriptorTable(
1, &descRange[0], D3D12_SHADER_VISIBILITY_PIXEL); // b0
// Create the root signature.
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc(_countof(rootParameters),
rootParameters, 0, nullptr,
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> error;
DX::ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc,
D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
DX::ThrowIfFailed(
device->CreateRootSignature(0, signature->GetBufferPointer(),
signature->GetBufferSize(),
IID_PPV_ARGS(m_rootSignature.ReleaseAndGetAddressOf())));