Va bene, sto facendo fatica a capire come i buffer costanti sono legati a uno stadio della pipeline e aggiornati. Comprendo che DirectX11 può avere fino a 15 buffer di shader costanti per fase e ogni buffer può contenere fino a 4096 costanti. Tuttavia, non capisco se la COM ID3D11Buffer utilizzata per interagire con i buffer costanti sia solo un meccanismo (o handle) utilizzato per riempire questi slot del buffer o se l'oggetto fa effettivamente riferimento a una particolare istanza di dati buffer che viene spinta avanti e indietro tra GPU e CPU.
Penso che la mia confusione sull'argomento sia la causa di un problema che sto avendo usando due diversi buffer costanti.
Ecco alcuni esempi di codice shader.
cbuffer PerFrame : register(b0) {
float4x4 view;
};
cbuffer PerObject : register(b1) {
float4x4 scale;
float4x4 rotation;
float4x4 translation;
};
Il modo in cui è organizzato il mio codice, la telecamera gestirà l'aggiornamento dei dati rilevanti per frame e GameObjects aggiornerà i propri dati per oggetto. Entrambe le classi hanno il proprio ID3D11Buffer che viene utilizzato per fare ciò (utilizzando un'architettura hub, quindi una classe GameObject gestirà il rendering di tutti gli GameObject istanziati nel mondo).
Il problema è che posso aggiornarne solo uno alla volta, a seconda dello slot e presumo che l'ordine di aggiornamento venga riempito da un buffer mentre l'altro venga azzerato.
Questo è essenzialmente il mio codice. Entrambe le classi usano la stessa logica di aggiornamento.
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);
Le mie domande principali sono:
- Devo impostare o associare ShaderBuffer per aggiornarlo con la chiamata UpdateSubresource? (Il significato lo manipola solo quando è nella pipeline) O è un blocco di dati che verrà inviato con la chiamata VSSetConstantBuffer? (Significa che l'ordine di associazione e aggiornamento dei dati non ha importanza, posso aggiornarlo nella pipeline o in qualche modo sulla CPU)
- Quando si imposta o si associa il buffer, è necessario fare riferimento allo slot 0 per aggiornare il buffer PerFrame e lo slot 1 per aggiornare il buffer PerObject? Una sorta di confusione con questa chiamata nel mio codice potrebbe causare la sovrascrittura di tutti i buffer?
- Come fa D3D11 a sapere quale buffer voglio aggiornare o mappare? Lo sa dal COM ID3D11Buffer utilizzato?
Modificare -
Modificati i tag del registro buffer costante nell'esempio sopra. L'uso di (cb #) invece di (b #) ha influito negativamente sull'aggiornamento corretto dei buffer per qualche motivo. Non sono sicuro di dove abbia preso la sintassi originale o se sia valida, ma sembra essere stato il mio problema principale.