W porządku, trudno mi zrozumieć, jak stałe bufory są powiązane z etapem potoku i aktualizowane. Rozumiem, że DirectX11 może mieć do 15 buforów stałych shaderów na stopień, a każdy bufor może pomieścić do 4096 stałych. Nie rozumiem jednak, czy ID3D11Buffer COM używany do interakcji ze stałymi buforami jest tylko mechanizmem (lub uchwytem) używanym do wypełniania tych miejsc buforowych, czy też obiekt faktycznie odwołuje się do konkretnej instancji danych bufora, które są wypychane w tę iz powrotem pomiędzy GPU a CPU.
Wydaje mi się, że moje zamieszanie na ten temat jest przyczyną problemu z używaniem dwóch różnych stałych buforów.
Oto przykładowy kod modułu cieniującego.
cbuffer PerFrame : register(b0) {
float4x4 view;
};
cbuffer PerObject : register(b1) {
float4x4 scale;
float4x4 rotation;
float4x4 translation;
};
Sposób, w jaki mój kod jest zorganizowany, kamera będzie aktualizować odpowiednie dane dla poszczególnych klatek, a GameObjects będzie aktualizować własne dane dla poszczególnych obiektów. Obie klasy mają własny ID3D11Buffer, który służy do tego celu (przy użyciu architektury koncentratora, więc jedna klasa GameObject obsłuży renderowanie wszystkich instancji GameObjects na świecie).
Problem polega na tym, że mogę aktualizować tylko jedną naraz, w zależności od miejsca i zakładam, że kolejność aktualizacji jednego bufora zostanie zapełniona, a drugiego zero.
To jest zasadniczo mój kod. Obie klasy używają identycznej logiki aktualizacji.
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);
Moje główne pytania to:
- Czy muszę ustawić lub powiązać ShaderBuffer, aby zaktualizować go za pomocą wywołania UpdateSubresource? (To znaczy manipuluj nim tylko wtedy, gdy jest w potoku) Czy może jest to kropla danych, która zostanie wysłana za pomocą wywołania VSSetConstantBuffer? (Oznacza to, że kolejność wiązania i aktualizacji danych nie ma znaczenia, mogę zaktualizować je w potoku lub w jakiś sposób na procesorze)
- Czy podczas ustawiania lub wiązania bufora muszę odwoływać się do gniazda 0, aby zaktualizować bufor PerFrame, i do gniazda 1, aby zaktualizować bufor PerObject? Czy jakieś zamieszanie związane z tym wywołaniem w moim kodzie może spowodować zastąpienie wszystkich buforów?
- Skąd D3D11 wie, który bufor chcę zaktualizować lub zmapować? Czy to wiadomo z zastosowanego ID3D11Buffer COM?
Edytować -
Zmieniono tagi rejestru stałego bufora w powyższym przykładzie. Użycie (cb #) zamiast (b #) wpłynęło na poprawność aktualizacji buforów z jakiegoś powodu. Nie jestem pewien, gdzie wybrałem oryginalną składnię lub czy w ogóle jest ona poprawna, ale wydaje się, że był to mój główny problem.