2021년 3월 2일 화요일

DirectX - Indirect Drawing

1. 왜 씀

처음 봤을 때 뭔가 했던 기능.

 주 용도는 D3D11_BUFFER_UAV_FLAG_APPEND 또는 D3D11_BUFFER_UAV_FLAG_COUNTER 로 생성된 UAV 의 값으로 렌더링 하기위함. 이를 위해선 버퍼크기를 알아야하고 ComputerShader 에서 계산한 값들을 넣으면 버퍼 크기가 바뀜. 이때 CPU 에 버퍼크기를 넣는게 아니라 GPU 에 넣어서 속도를 빠르게 하는데 이를 위해서 그 크기를 넣는 버퍼를 따로 만들어야함.

 그 버퍼가 D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS 플래그로 만든 버퍼. 


2. 사용법

 2개의 buffer 를 만들어야함. 하나는 UAV 로 만들어서 ComputeShader 에서 Append 시켜서 업데이트 시킬 용도, 다른 하나는 그 버퍼의 크기를 를 복사할 용도.

 

D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Usage = m_cpu_writable ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = m_cpu_writable ? D3D11_CPU_ACCESS_WRITE : 0;;
desc.ByteWidth = sizeof(T) * num_item;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
desc.StructureByteStride = sizeof(T);

D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND;
desc.Buffer.NumElements = GetCount();
desc.Buffer.FirstElement = 0;

전자는 Append Flag 에 주의해서 만들면 됨. 

Counter 같은 다른 Flag 도 유효함.


D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.ByteWidth = sizeof(int) * 4;
desc.BindFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS;
desc.StructureByteStride = sizeof(T);

후자는 데이터 구성 요소가 정해져 있음.

d3d_context->DrawInstanced, DrawIndexedInstanced 의 인자가 4개인데 정확히 대응함.

https://docs.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-drawinstanced


d3d_context->CopyStructureCount() 

를 통해서 4개의 인자를 UAV 를 통해서 읽어온 후에

d3d_context->DrawInstancedIndirectted, DrawIndexedInstancedIndirected 를 실행하면 됨.



https://docs.microsoft.com/ko-kr/windows/win32/direct3d12/indirect-drawing

Direct12 에선 더 복잡해짐.




댓글 없음:

댓글 쓰기

List