
CPU와 GPU 메모리 계층도이다. Core와 FP에 가까이 있는 메모리일수록 처리 속도가 빠르고 용량이 작다. 그래서 중요한 정보는 레지스터에서 처리하고 우선순위에서 떨어지는 데이터는 램부분에서 처리한다. 레지스터에서 데이터를 처리할 경우 중요한 데이터인만큼 미리 이 공간을 활용하겠다는 Root Signature을 필요로 한다.

Root Signature에는 그림과 같이 여러가지 값, 테이블, CBV(Constant Buffer View) 등을 넣을 수 있다.
CD3DX12_ROOT_PARAMETER param[2];
param[0].InitAsConstantBufferView(0); // 0번 -> b0 -> CBV
param[1].InitAsConstantBufferView(1); // 1번 -> b1 -> CBV
D3D12_ROOT_SIGNATURE_DESC sigDesc = CD3DX12_ROOT_SIGNATURE_DESC(2, param);
_cmdList->SetGraphicsRootSignature(ROOT_SIGNATURE.Get());
Root Signature에 CBV 2개를 넣고 RenderBegin에서 서명을 완료한다. 그러면 레지스터의 공간 예약이 된 것이고 실제로 데이터를 밀어넣는 작업이 필요하다. 그러기 위해서는 먼저 램 공간에 버퍼를 만들어 데이터를 넣고 레지스터까지 올려야 한다.
DEVICE->CreateCommittedResource(
&heapProperty,
D3D12_HEAP_FLAG_NONE,
&desc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&_cbvBuffer));
_cbvBuffer->Map(0, nullptr, reinterpret_cast<void**>(&_mappedBuffer));
// TODO
// 1) Buffer에다가 데이터 세팅
// 2) Buffer의 주소를 register에다가 전송
GEngine->GetCB()->PushData(0, &_transform, sizeof(_transform));
GEngine->GetCB()->PushData(1, &_transform, sizeof(_transform));
D3D12_CPU_DESCRIPTOR_HANDLE ConstantBuffer::PushData(int32 rootParamIndex, void* buffer, uint32 size)
{
assert(_currentIndex < _elementSize);
::memcpy(&_mappedBuffer[_currentIndex * _elementSize], buffer, size);
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle = GetCpuHandle(_currentIndex);
_currentIndex++;
return cpuHandle;
}
먼저 Buffer를 만들 공간을 생성해야 하는데 Mesh를 만들때와 마찬가지로 CreateCommittedResource를 이용해서 생성하고 memcpy를 통해 데이터를 복사한다. 그리고 주소를 레지스터에 전송해서 필요할 때마다 레지스터가 Buffer의 주소를 찾아 사용할 수 있도록 한다.
그런데 버퍼의 데이터를 복사하고 레지스터로 주소를 전송하는 과정이 지연되기 때문에 문제가 발생한다. 한 정점을 출력하고 다음 정점을 출력하려고 할 때 이전 버퍼의 데이터가 복사되는 과정이 일어나지 않았다면 다음 정점의 데이터를 덮어 씌워버린다.
void ConstantBuffer::Init(uint32 size, uint32 count)
{
// 상수 버퍼는 256 바이트 배수로 만들어야 한다
// 0 256 512 768
_elementSize = (size + 255) & ~255;
_elementCount = count;
CreateBuffer();
}
그래서 ConstantBuffer을 만들 때 미리 몇개를 만드는지 count로 받는다. 그래서 각 버퍼를 순서에 맞게 데이터를 관리해서 다음 데이터가 이전 데이터를 덮어 씌우지 않게 한다. 그리고 index를 만들어 매프레임마다 index를 0으로 설정해 처음부터 과정을 반복한다.
'그래픽스' 카테고리의 다른 글
| [DX12] Index Buffer (0) | 2022.07.22 |
|---|---|
| [DX12] Root Signature (0) | 2022.07.22 |
| [DX12] Frustum Culling (0) | 2022.02.28 |
| [DX12] Normal Mapping (0) | 2022.02.28 |
| [DX12] Projection, Screen 변환 행렬 (0) | 2022.02.26 |