I'm trying to create an ID3D12PipelineState but CreateGraphicsPipelineState() is throwing an error
D3D12 ERROR: ID3D12Device::CreateGraphicsPipelineState: Root Signature doesn't match Vertex Shader: Shader CBV descriptor range (BaseShaderRegister=0, NumDescriptors=1, RegisterSpace=0) is not fully bound in root signature
[ STATE_CREATION ERROR #688: CREATEGRAPHICSPIPELINESTATE_VS_ROOT_SIGNATURE_MISMATCH]
ID3D12PipelineState creation code:
D3D12_DESCRIPTOR_RANGE descrioptorRange[1];
descrioptorRange->RangeType=D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
descrioptorRange->NumDescriptors=1;
descrioptorRange->BaseShaderRegister=0;
descrioptorRange->RegisterSpace = 0; // space 0. can usually be zero
descrioptorRange->OffsetInDescriptorsFromTableStart=D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND ;
D3D12_ROOT_DESCRIPTOR_TABLE descriptorTable;
descriptorTable.NumDescriptorRanges=_countof(descrioptorRange);
descriptorTable.pDescriptorRanges=descrioptorRange;
D3D12_ROOT_PARAMETER rootParameters[1]={};
D3D12_ROOT_PARAMETER& vertexConstantParameter = rootParameters[0];
vertexConstantParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
vertexConstantParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
vertexConstantParameter.Descriptor.RegisterSpace = 0; // Пространство регистрации
vertexConstantParameter.Descriptor.ShaderRegister = 0; // Регистр шейдера для константного буфера
vertexConstantParameter.DescriptorTable=descriptorTable;
D3D12_ROOT_SIGNATURE_DESC desc;
desc.NumParameters=_countof(rootParameters);
desc.pParameters=rootParameters;
desc.NumStaticSamplers=0;
desc.pStaticSamplers=nullptr;
desc.Flags=D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | // we can deny shader stages here for better performance
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;
ThrowF(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &DX12.PipeLine.serializedRootSignature, nullptr), ERROR_CREATEPIPELINE);
ThrowFEX(DX12.d3dDevice->CreateRootSignature(0, DX12.PipeLine.serializedRootSignature->GetBufferPointer(),DX12.PipeLine.serializedRootSignature->GetBufferSize(), IID_PPV_ARGS(&DX12.PipeLine.rootSignature)), ERROR_CREATEPIPELINE, DX12.d3dDevice);
// Формат вершины
D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(vertex,position), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(vertex,color), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
};
D3D12_SHADER_BYTECODE vShader={};
vShader.BytecodeLength=DX12.vShader->GetBufferSize();
vShader.pShaderBytecode=DX12.vShader->GetBufferPointer();
D3D12_SHADER_BYTECODE cShader={};
cShader.BytecodeLength=DX12.cShader->GetBufferSize();
cShader.pShaderBytecode=DX12.cShader->GetBufferPointer();
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeLineDesc={};
pipeLineDesc.InputLayout={inputElementDescs,_countof(inputElementDescs)};
pipeLineDesc.pRootSignature=DX12.PipeLine.rootSignature;
pipeLineDesc.VS=vShader;
pipeLineDesc.PS=cShader;
pipeLineDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
pipeLineDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
pipeLineDesc.PrimitiveTopologyType=D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
pipeLineDesc.NumRenderTargets = 1;
pipeLineDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
pipeLineDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
pipeLineDesc.SampleDesc.Count = 1;
pipeLineDesc.SampleDesc.Quality = 0;
pipeLineDesc.SampleMask=0xffffffff;
pipeLineDesc.BlendState=CD3DX12_BLEND_DESC(D3D12_DEFAULT);
pipeLineDesc.DepthStencilState.DepthEnable = false;
pipeLineDesc.DepthStencilState.StencilEnable = false;
pipeLineDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
ThrowF(DX12.d3dDevice->CreateGraphicsPipelineState(&pipeLineDesc, IID_PPV_ARGS(&DX12.PipeLine.pPipelineState)), ERROR_CREATEPIPELINE);
I checked all the parameters several times. I tried to disable the creation of the representation of constant buffers of the vertex shader. I tried to use instead of D3D12_RESOURCE_DESC
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
I handle all exceptions, no method before CreateGraphicsPipelineState throws an error. I don't understand what constant buffer CreateGraphicsPipelineState expects and why.
Usage D3D12_ROOT_PARAMETER_TYPE::D3D12_ROOT_PARAMETER_TYPE_CBV
cannot be used with D3D12_ROOT_PARAMETER::DescriptorTable
. This inevitably results in an error because it assumes that you are using a single representation of a constant buffer.
If you need to define multiple constant buffers, you should use D3D12_ROOT_PARAMETER_TYPE::D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE
and write the representation of the buffers to ID3D12DescriptorHeap. Then use SetGraphicsRootDescriptorTable()
. Alternatively, create multiple D3D12_ROOT_PARAMETER structures and use SetGraphicsRootConstantBufferView()
(although I haven't tested this).