D'accord, j'ai du mal à comprendre comment les tampons constants sont liés à une étape de pipeline et mis à jour. Je comprends que DirectX11 peut avoir jusqu'à 15 tampons constants de shader par étape et chaque tampon peut contenir jusqu'à 4096 constantes. Cependant, je ne comprends pas si le COM ID3D11Buffer utilisé pour interagir avec les tampons constants n'est qu'un mécanisme (ou poignée) utilisé pour remplir ces emplacements de tampon ou si l'objet fait réellement référence à une instance particulière de données de tampon qui est poussée d'avant en arrière entre le GPU et le CPU.
Je pense que ma confusion sur le sujet est la cause d'un problème que j'utilise avec deux tampons constants différents.
Voici un exemple de code de shader.
cbuffer PerFrame : register(b0) {
float4x4 view;
};
cbuffer PerObject : register(b1) {
float4x4 scale;
float4x4 rotation;
float4x4 translation;
};
La façon dont mon code est organisé, la caméra gérera la mise à jour des données pertinentes par image et GameObjects mettra à jour leurs propres données par objet. Les deux classes ont leur propre ID3D11Buffer qui est utilisé pour ce faire (en utilisant une architecture concentrateur, donc une classe GameObject gérera le rendu de tous les GameObjects instanciés dans le monde).
Le problème est que je ne peux obtenir qu'une mise à jour à la fois, en fonction de l'emplacement et je suppose que l'ordre de mise à jour un tampon est rempli tandis que l'autre est mis à zéro.
C'est essentiellement mon code. Les deux classes utilisent une logique de mise à jour identique.
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);
Mes principales questions sont -
- Dois-je définir ou lier le ShaderBuffer afin de le mettre à jour avec l'appel UpdateSubresource? (Cela signifie que vous ne devez le manipuler que lorsqu'il est dans le pipeline). Ou s'agit-il d'un blob de données qui sera envoyé avec l'appel VSSetConstantBuffer? (Cela signifie que l'ordre de liaison et de mise à jour des données n'a pas d'importance, je peux le mettre à jour dans le pipeline ou d'une manière ou d'une autre sur le processeur)
- Lors de la définition ou de la liaison du tampon, dois-je faire référence à l'emplacement 0 pour mettre à jour le tampon PerFrame et à l'emplacement 1 pour mettre à jour le tampon PerObject? Une sorte de confusion avec cet appel dans mon code pourrait-elle entraîner l'écrasement de tous les tampons?
- Comment le D3D11 sait-il quel tampon je souhaite mettre à jour ou mapper? Sait-il du COM ID3D11Buffer utilisé?
Éditer -
Modification des balises de registre de tampon constant dans l'exemple ci-dessus. L'utilisation de (cb #) au lieu de (b #) empêchait les tampons de se mettre à jour correctement pour une raison quelconque. Je ne sais pas où j'ai récupéré la syntaxe d'origine ou si elle est valide, mais cela semble avoir été mon principal problème.