좋아, 상수 버퍼가 파이프 라인 단계에 바인딩되고 업데이트되는 방법을 파악하는 데 어려움을 겪고 있습니다. DirectX11은 스테이지 당 최대 15 개의 쉐이더 상수 버퍼를 가질 수 있으며 각 버퍼는 최대 4096 개의 상수를 보유 할 수 있음을 이해합니다. 그러나 상수 버퍼와 상호 작용하는 데 사용되는 ID3D11Buffer COM이 이러한 버퍼 슬롯을 채우는 데 사용되는 메커니즘 (또는 핸들)인지 또는 객체가 실제로 앞뒤로 밀리는 특정 버퍼 데이터 인스턴스를 참조하는지 여부는 이해할 수 없습니다. GPU와 CPU 사이.
나는이 주제에 대한 혼란이 두 개의 다른 상수 버퍼를 사용하는 데있어 문제의 원인이라고 생각합니다.
다음은 셰이더 코드의 예입니다.
cbuffer PerFrame : register(b0) {
float4x4 view;
};
cbuffer PerObject : register(b1) {
float4x4 scale;
float4x4 rotation;
float4x4 translation;
};
내 코드가 구성되는 방식으로 카메라는 프레임 당 관련 데이터 업데이트를 처리하고 GameObjects는 객체 당 자체 데이터를 업데이트합니다. 두 클래스에는 모두이를 수행하는 데 사용되는 고유 ID3D11Buffer가 있습니다 (허브 아키텍처를 사용하므로 하나의 GameObject 클래스가 월드의 모든 인스턴스화 된 게임 오브젝트의 렌더링을 처리합니다).
문제는 슬롯에 따라 한 번에 하나만 업데이트 할 수 있으며 하나의 버퍼가 채워지고 다른 버퍼는 0이되는 업데이트 순서를 가정합니다.
이것은 본질적으로 내 코드입니다. 두 클래스 모두 동일한 업데이트 논리를 사용합니다.
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);
내 주요 질문은-
- UpdateSubresource 호출로 업데이트하려면 ShaderBuffer를 설정하거나 바인딩해야합니까? (이것은 파이프 라인에있을 때만 조작합니다) 아니면 VSSetConstantBuffer 호출과 함께 전송 될 데이터 덩어리입니까? (데이터 바인딩 및 업데이트 순서를 의미하는 것은 중요하지 않습니다. 파이프 라인이나 CPU에서 업데이트 할 수 있습니다)
- 버퍼를 설정하거나 바인딩 할 때 PerFrame 버퍼를 업데이트하려면 슬롯 0을, PerObject 버퍼를 업데이트하려면 슬롯 1을 참조해야합니까? 내 코드 에서이 호출과 혼동하여 모든 버퍼를 덮어 쓸 수 있습니까?
- D3D11은 업데이트하거나 매핑하려는 버퍼를 어떻게 알 수 있습니까? 사용 된 ID3D11Buffer COM에서 알고 있습니까?
편집하다 -
위 예제에서 상수 버퍼 레지스터 태그를 변경했습니다. (b #) 대신 (cb #)을 사용하면 어떤 이유로 버퍼가 올바르게 업데이트되지 않습니다. 원래 구문을 어디에서 가져 왔는지 또는 전혀 유효한지 확실하지 않지만 주요 문제인 것 같습니다.