Tudo bem, estou tendo dificuldades para entender como os buffers constantes são vinculados a um estágio de pipeline e atualizados. Entendo que o DirectX11 pode ter até 15 buffers de shader-constante por estágio e cada buffer pode conter até 4096 constantes. No entanto, não entendo se o COM ID3D11Buffer usado para interagir com os buffers constantes é apenas um mecanismo (ou identificador) usado para preencher esses slots de buffer ou se o objeto realmente faz referência a uma instância específica de dados de buffer que é empurrada para frente e para trás entre a GPU e a CPU.
Acho que minha confusão sobre o assunto é a causa de um problema que estou tendo usando dois buffers constantes diferentes.
Aqui está um exemplo de código de sombreador.
cbuffer PerFrame : register(b0) {
float4x4 view;
};
cbuffer PerObject : register(b1) {
float4x4 scale;
float4x4 rotation;
float4x4 translation;
};
Da maneira como meu código é organizado, a câmera manipula a atualização dos dados relevantes por quadro e o GameObjects atualiza seus próprios dados por objeto. Ambas as classes têm seu próprio ID3D11Buffer usado para fazer isso (usando uma arquitetura de hub, uma classe GameObject manipulará a renderização de todos os GameObjects instanciados no mundo).
O problema é que eu só consigo atualizar uma por vez, dependendo do slot, e presumo que a ordem de atualização de um buffer seja preenchida enquanto o outro será zerado.
Este é essencialmente o meu código. Ambas as classes usam lógica de atualização idêntica.
static PerObjectShaderBuffer _updatedBuffer; // PerFrameShaderBuffer if Camera class
_updatedBuffer.scale = _rScale;
_updatedBuffer.rotation = _rRotation;
_updatedBuffer.translation = _rTranslation;
pDeviceContext->UpdateSubresource(pShaderBuffer, 0 , 0, &_updatedBuffer, 0, 0);
pDeviceContext->VSSetShader(pVShader->GetShaderPtr(), 0, 0);
pDeviceContext->PSSetShader(pPShader->GetShaderPtr(), 0, 0);
pDeviceContext->VSSetConstantBuffers(1, 1, &pShaderBuffer);
pDeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &vStride, &_offset );
pDeviceContext->IASetPrimitiveTopology(topologyType);
pDeviceContext->Draw(bufSize, 0);
Minhas principais perguntas são -
- Preciso definir ou vincular o ShaderBuffer para atualizá-lo com a chamada UpdateSubresource? (O que significa manipulá-lo apenas quando estiver no pipeline) Ou é um blob de dados que serão enviados com a chamada VSSetConstantBuffer? (Isso significa que a ordem dos dados de ligação e atualização não importa, posso atualizá-los no pipeline ou de alguma forma na CPU)
- Ao definir ou vincular o buffer, preciso fazer referência ao slot 0 para atualizar o buffer PerFrame e ao slot 1 para atualizar o buffer PerObject? Poderia algum tipo de confusão com essa chamada no meu código fazer com que todos os buffers fossem substituídos?
- Como o D3D11 sabe qual buffer eu quero atualizar ou mapear? Ele conhece o ID3D11Buffer COM usado?
Editar -
Alteradas as tags de registro do buffer constante no exemplo acima. O uso de (cb #) em vez de (b #) estava afetando a atualização correta dos buffers por algum motivo. Não sei onde peguei a sintaxe original ou se é válida, mas parece ter sido o meu principal problema.