I am building a C++ application that uses DirectX 12 as graphics api.
I want to define macros(for eg #define A_MACRO)
when compiling shader programs.
I looked on the internet but I didn't found where to put it. In terms of code I have this:
Root signature creation:
void Effect::createRootSignature(const D3D12_ROOT_PARAMETER* rootParams,
UINT nbParams,
const D3D12_STATIC_SAMPLER_DESC* samplers,
UINT numSamplers)
{
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init(nbParams,
rootParams,
numSamplers,
samplers,
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
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);
ID3DBlob* errorBuff;
ID3DBlob* signature;
HRESULT hr = D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &errorBuff);
if (FAILED(hr))
{
TRACE((char*)errorBuff->GetBufferPointer());
assert(false);
return;
}
hr = D3D12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature));
assert(SUCCEEDED(hr));
}
Shader deserialization:
ID3DBlob* Effect::readShader(const std::string& shaderName)
{
std::wstring shaderPath(shaderName.begin(), shaderName.end());
shaderPath = SHADER_PATH(shaderPath + L".cso");
ID3DBlob* shader = nullptr;
HRESULT hr = D3DReadFileToBlob(shaderPath.c_str(), &shader);
if (FAILED(hr))
{
return nullptr;
}
return shader;
}
PSO complilation:
void Effect::compilePipeline(PipelineStatePtr& pipelineStateDst,
ID3DBlob* vertexShader,
ID3DBlob* pixelShader,
const D3D12_INPUT_ELEMENT_DESC* inputLayoutElementDesc,
const UINT inputLayoutNumElements,
const D3D12_BLEND_DESC& blendDesc,
const D3D12_DEPTH_STENCIL_DESC& depthStencilDesc,
const D3D12_RASTERIZER_DESC& rasterizerDesc,
const std::vector<DXGI_FORMAT>& renderTargetFormats,
const D3D12_PRIMITIVE_TOPOLOGY_TYPE topologyType)
{
// Fill out a shader bytecode structure, which is basically just a pointer
// to the shader bytecode and the size of the shader bytecode.
D3D12_SHADER_BYTECODE vertexShaderBytecode = {};
vertexShaderBytecode.BytecodeLength = vertexShader->GetBufferSize();
vertexShaderBytecode.pShaderBytecode = vertexShader->GetBufferPointer();
// Fill out a pixel shader bytecode structure.
D3D12_SHADER_BYTECODE pixelShaderBytecode = {};
pixelShaderBytecode.BytecodeLength = pixelShader->GetBufferSize();
pixelShaderBytecode.pShaderBytecode = pixelShader->GetBufferPointer();
// Fill out an input layout description structure
D3D12_INPUT_LAYOUT_DESC inputLayoutDesc = {};
inputLayoutDesc.NumElements = inputLayoutNumElements;
inputLayoutDesc.pInputElementDescs = inputLayoutElementDesc;
// Fill out a PSO description
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.InputLayout = inputLayoutDesc;
psoDesc.pRootSignature = m_rootSignature;
psoDesc.VS = vertexShaderBytecode;
psoDesc.PS = pixelShaderBytecode;
psoDesc.PrimitiveTopologyType = topologyType;
assert(renderTargetFormats.size() <= 8);
const UINT numRenderTargets = std::min((UINT)renderTargetFormats.size(), 8u);
for (nbUint32 i = 0; i < numRenderTargets; ++i)
psoDesc.RTVFormats[i] = renderTargetFormats[i];
psoDesc.SampleDesc = m_sampleDesc;
psoDesc.SampleMask = 0xffffffff;
psoDesc.RasterizerState = rasterizerDesc;
psoDesc.BlendState = blendDesc;
psoDesc.NumRenderTargets = numRenderTargets;
psoDesc.DepthStencilState = depthStencilDesc;
psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT_S8X24_UINT7;
// Now create the PSO
HRESULT hr = D3D12Device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineStateDst));
assert(SUCCEEDED(hr));
}