void ShaderCompiler::parseConstantBuffers(ID3D12ShaderReflection* reflect, const D3D12_SHADER_DESC& progDesc, std::weak_ptr<DX12DeviceContext> context) { for (uint_fast32_t i = 0; i < progDesc.ConstantBuffers; ++i) { auto cb = reflect->GetConstantBufferByIndex(i); D3D12_SHADER_BUFFER_DESC cbDesc; cb->GetDesc(&cbDesc); LOGS << "Constant buffer : " << cbDesc.Name; auto& cbuffer = context.lock()->CreateConstanBuffer(cbDesc.Name); for (uint_fast32_t j = 0; j < cbDesc.Variables; ++j) { auto var = cb->GetVariableByIndex(j); D3D12_SHADER_VARIABLE_DESC vardesc; var->GetDesc(&vardesc); auto fmt = boost::format("CB var : %1%, Offset: %2%, Size: %3%") % vardesc.Name % vardesc.StartOffset % vardesc.Size; LOGS << boost::str(fmt); cbuffer.addVariable(vardesc.Name, vardesc.StartOffset, vardesc.Size); } } }
bool GenereateShaderConstants( Shader* shader, ID3D11ShaderReflection* vsR, ID3D11ShaderReflection* psR, ID3D11ShaderReflection* gsR) { if(!shader) return false; HRESULT result; D3D11_SHADER_DESC vsD, psD, gsD; ZeroMemory(&vsD, sizeof(vsD)); ZeroMemory(&psD, sizeof(psD)); ZeroMemory(&gsD, sizeof(gsD)); if(vsR) { vsR->GetDesc(&vsD); if(vsD.ConstantBuffers) { //We construct the ConstantBuffer objects here as one big chunk. We'll still //have to populate them, but we won't be pushing them one by one. //In addition, this guarantees that at(buffer_number) will give us the right cbuf shader->vsConstants.resize(vsD.ConstantBuffers); } } if(psR) { psR->GetDesc(&psD); if(psD.ConstantBuffers) { shader->psConstants.resize(psD.ConstantBuffers); } } if(gsR) { gsR->GetDesc(&gsD); if(gsD.ConstantBuffers) { shader->gsConstants.resize(gsD.ConstantBuffers); } } D3D11_SHADER_BUFFER_DESC sbDesc; D3D11_BUFFER_DESC constDesc; constDesc.Usage = D3D11_USAGE_DEFAULT; constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constDesc.CPUAccessFlags = 0; constDesc.MiscFlags = 0; for(size_t i = 0; i < vsD.ConstantBuffers; ++i) { auto& Cbuf = shader->vsConstants.at(i); auto IndexedCBuf = vsR->GetConstantBufferByIndex(i); IndexedCBuf->GetDesc(&sbDesc); constDesc.ByteWidth = sbDesc.Size; result = device->CreateBuffer(&constDesc, NULL, &CBuf.constantBuf); if(FAILED(result)) { log_sxerror("Shader", "Error creating a buffer for VS.CBuffer %s", sbDesc.Name); return false; } CBuf.bufferData = new ubyte[sbDesc.Size]; CBuf.bufferSize = sbDesc.Size; for(size_t c = 0; c < sbDesc.Variables; ++c) { D3D11_SHADER_VARIABLE_DESC varDesc; IndexedCBuf->GetVariableByIndex(c)->GetDesc(&varDesc); auto placer = shader->constants.emplace(make_pair(varDesc.Name, Constant(varDesc.Name))); auto& constant = placer.first->second; constant.vsData = Cbuf.bufferData + varDesc.StartOffset; constant.vsBuffer = &CBuf; } Cbuf.dirty = false; } for(size_t i = 0; i < psD.ConstantBuffers; ++i) { auto& CBuf = shader->psConstants.at(i); auto IndexedCBuf = psR->GetConstantBufferByIndex(i); IndexedCBuf->GetDesc(sbDesc); constDesc.ByteWidth = sbDesc.Size; result = device->CreateBuffer(&constDesc, NULL, &Cbuf.constantBuf); if(FAILED(result)) { log_sxerror("Shader", "Error creating a buffer for PS.CBuffer %s", sbDesc.Name); return false; } CBuf.bufferData = new ubyte[sbDesc.Size]; CBuf.bufferSize = sbDesc.Size; for(size_t c = 0; c < sbDesc.Variables; ++c) { D3D11_SHADER_VARIABLE_DESC varDesc; IndexedCBuf->GetVariableByIndex(c)->GetDesc(&varDesc); auto finder = shader->constants.find(varDesc.Name); if(finder == shader->constants.end()) { finder = shader->constants.emplace(make_pair(varDesc.Name, Constant(varDesc.name))).first; } //or maybe finder.second auto& constant = finder->second; constant.psData = CBuf.bufferData + varDesc.StartOffset; constant.psBuffer = &CBuf; } CBuf.dirty = false; } for(size_t i = 0; i < gsD.ConstantBuffers; ++i) { auto& CBuf = shader->gsConstants.at(i); auto IndexedCBuf = gsR->GetConstantBufferByIndex(i); IndexedCBuf->GetDesc(sbDesc); constDesc.ByteWidth = sbDesc.Size; result = device->CreateBuffer(&constDesc, NULL, &Cbuf.constantBuf); if(FAILED(result)) { log_sxerror("Shader", "Error creating a buffer for PS.CBuffer %s", sbDesc.Name); return false; } CBuf.bufferData = new ubyte[sbDesc.Size]; CBuf.bufferSize = sbDesc.Size; for(size_t c = 0; c < sbDesc.Variables; ++c) { D3D11_SHADER_VARIABLE_DESC varDesc; IndexedCBuf->GetVariableByIndex(c)->GetDesc(&varDesc); auto finder = shader->constants.find(varDesc.Name); if(finder == shader->constants.end()) { finder = shader->constants.emplace(make_pair(varDesc.Name, Constant(varDesc.name))).first; } //or maybe finder.second auto& constant = finder->second; constant.gsData = CBuf.bufferData + varDesc.StartOffset; constant.gsBuffer = &CBuf; } CBuf.dirty = false; } return true; }