调试输出中的完整错误是:
“D3D12 错误:ID3D12Device::CreateComputePipelineState:根签名与计算着色器不匹配:着色器 SRV 描述符范围(RegisterSpace=0,NumDescriptors=1,BaseShaderRegister=0)未完全绑定在根签名中”
这表明我创建 SRV/将其绑定到根签名的方式存在问题,但我不确定我到底做错了什么。我将尝试在此处粘贴最低限度的必要代码:
void Dc12DxbcHelper::CreateComputePipelineState(
_In_ ID3D12Device* pDevice,
_In_ ID3D12RootSignature* pRootSignature,
_In_reads_bytes_(length) const void* shader,
size_t length,
UINT nodeMask,
D3D12_PIPELINE_STATE_FLAGS flags,
_COM_Outptr_ ID3D12PipelineState** ppPipelineState)
{
DxbcReader reader(
reinterpret_cast<const uint8_t*>(shader),
length);
DC12::CreateComputePipelineState(
pDevice,
pRootSignature,
reader.get_Shader(),
reader.get_Length(),
nodeMask,
flags,
ppPipelineState);
}
...
void DC12::CreateRootSignature(
_In_ ID3D12Device* pDevice,
_In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* pParameters,
UINT numParameters,
_COM_Outptr_ ID3D12RootSignature** ppRootSignature)
{
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc =
{
numParameters, // NumParameters
pParameters, // pParameters
0, // NumStaticSamplers
nullptr, // pStaticSamplers
D3D12_ROOT_SIGNATURE_FLAG_NONE, // Flags
};
SafeComPointer<ID3DBlob> blob;
SafeComPointer<ID3DBlob> errorBlob;
HRESULT hr = ::D3D12SerializeRootSignature(
&rootSignatureDesc,
D3D_ROOT_SIGNATURE_VERSION_1,
blob.GetAddressOf(),
errorBlob.GetAddressOf());
if (FAILED(hr))
{
std::string errorString(ERROR_MESSAGE);
if (errorBlob)
{
errorString.append(": ");
errorString.append(
reinterpret_cast<char*>(
errorBlob->GetBufferPointer()),
errorBlob->GetBufferSize());
}
throw std::system_error(
hr,
HRESULT_error_category(),
errorString);
}
CHR(pDevice->CreateRootSignature(
0,
blob->GetBufferPointer(),
blob->GetBufferSize(),
IID_PPV_ARGS(ppRootSignature)));
}
...
CreateWithSrv(
_In_ const uint8_t threadGroupLog2,
_In_ const uint32_t stagingWriteBufferSize,
_In_ const uint32_t shaderResourceViewCount,
_In_ const uint32_t unorderedAccessViewCount,
_In_ const uint32_t stagingReadBufferCount)
{
...
// create & assign srv
DC12::CreateDescriptorHeap(
this->device.Get(),
1,
D3D12_DESCRIPTOR_HEAP_FLAG_NONE,
0,
this->srvDescriptor.GetAddressOf());
DC12::CreateShaderResourceView(
this->device.Get(),
this->srvDescriptor.Get(),
0,
shaderResourceViewCount,
this->srvBuffer.GetAddressOf());
// create & assign uav
DC12::CreateDescriptorHeap(
this->device.Get(),
1,
D3D12_DESCRIPTOR_HEAP_FLAG_NONE,
0,
this->uavDescriptor.GetAddressOf());
DC12::CreateUnorderedAccessView(
this->device.Get(),
this->uavDescriptor.Get(),
0,
unorderedAccessViewCount,
this->uavBuffer.GetAddressOf());
...
}
...
class ROOT_PARAMETER_SRV
: public D3D12_ROOT_PARAMETER
{
public:
ROOT_PARAMETER_SRV(
UINT shaderRegister)
{
this->ParameterType =
D3D12_ROOT_PARAMETER_TYPE_SRV;
this->Descriptor =
{
shaderRegister, // ShaderRegister
0, // RegisterSpace,
};
this->ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
}
};
...
Dc12HasherImpl::CreateWithSrv(
CryptoNightDcHelper::ThreadGroupLog2,
this->SrvSimdCount * sizeof(simd),
this->SrvSimdCount,
count,
MaxUAVReadSizeSimd);
D3D12_ROOT_PARAMETER rootParameters[] =
{
DC12::ROOT_PARAMETER_32BIT_CONSTANTS(0, 3),
DC12::ROOT_PARAMETER_CBV(1),
DC12::ROOT_PARAMETER_CBV(2),
DC12::ROOT_PARAMETER_SRV(3),
DC12::ROOT_PARAMETER_UAV(4),
};
DC12::CreateRootSignature(
this->device.Get(),
rootParameters,
_countof(rootParameters),
this->rootSignature.GetAddressOf());
D3D12_PIPELINE_STATE_FLAGS computePipelineStateFlags =
D3D12_PIPELINE_STATE_FLAG_NONE;
Dc12DxbcHelper::CreateComputePipelineState(
this->device.Get(),
this->rootSignature.Get(),
shaderBytecode,
shaderBytecodeLength,
0,
computePipelineStateFlags,
this->preKeccakShader.GetAddressOf());
顺便说一句,如果我注释掉所有特定于 SRV 的内容,这将毫无错误地运行。如果您需要我在此处发布其他内容以更好地诊断问题,我可以尝试提供。
编辑:着色器 DX Asm 的相关位:
...
dcl_constantbuffer cb0[1], immediateIndexed
dcl_constantbuffer cb1[13], immediateIndexed
dcl_constantbuffer cb2[1], immediateIndexed
dcl_resource_structured t0, 16
dcl_uav_structured u0, 16
...