D3D12엔진 – Descriptor Table구조 예시

개발중인 D3D12엔진에서 사용하는 Descriptor Table구조다.

예를 들어 두개의 텍스쳐를 사용하고 있는 오브젝트 한개가 있다.

두개의 텍스쳐-매터리얼을 가지고 있으므로 렌더링은 두번 나눠서 해야한다.

하지만 두개의 그룹-Facegroup이라 부르겠다-은 월드상에서 동일한 Transform Matrix를 사용해서 렌더링한다. 따라서 Transform Matrix와 같이 공통적으로 사용할 수 있는 리소스의 경우 한번만 설정하고 변경없이 두번 렌더링 하면 된다.

두개의 FaceGroup이 공통적으로 사용할 리소스는

Projection을 위한 matrix, Shadow map등이다.

각각의 FaceGroup이 다르게 사용할 리소스는 각자의 Texture,그밖의 매터리얼을 설정하는 constant이다.

이 Descriptor Table의 형식으로  RootSignature를 만드는 코드는 다음과 같다.

 

	CD3DX12_DESCRIPTOR_RANGE rangesPerObj[2];
	rangesPerObj[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0);	// b0 : default , b1 : bones
	rangesPerObj[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 2);	// t2 : toon table , t3:shadow

	CD3DX12_DESCRIPTOR_RANGE rangesPerFacegroup[2];
	rangesPerFacegroup[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 2);	// b2 : material
	rangesPerFacegroup[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0);	// t0 : diffuse , t1: mask
	
	D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags =
		D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
		D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
		D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
		D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
		D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;


	CD3DX12_ROOT_PARAMETER rootParameters[2];
	rootParameters[0].InitAsDescriptorTable(2, rangesPerObj, D3D12_SHADER_VISIBILITY_ALL);
	rootParameters[1].InitAsDescriptorTable(2, rangesPerFacegroup, D3D12_SHADER_VISIBILITY_ALL);

		
	CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
	rootSignatureDesc.Init(_countof(rootParameters), rootParameters, _countof(samplers), samplers, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

	ID3DBlob* pSignature = NULL;
	ID3DBlob* pError = NULL;
	
	if (FAILED(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &pSignature, &pError)))
	{
		const char*	szMsg = (const char*)pError->GetBufferPointer();
		__debugbreak();
	}

	if (FAILED(pResourceManager->CreateRootSignature(0, pSignature->GetBufferPointer(), pSignature->GetBufferSize(), &m_pRootSignature)))
		__debugbreak();

오브젝트 렌더링 초입부에서 pCommandList->SetGraphicsRootDescriptorTable(0, commonHeapHandle); 로 0번 파라미터를 설정해주고,

각각의 FaceGroup을 렌더링 할때마다 pCommandList->SetGraphicsRootDescriptorTable(1, commonHeapHandle);  로 1번 파라미티를 변경해서 렌더링하면 된다.

 

그림으로 보면 다음과 같다.

descritor_table_vlmesh

 

처음 보면 이게 뭥미..싶지만 역시 코드를 짜다보면 어떻게 사용하는지 감이 온다.


답글 남기기

댓글을 게시하려면 다음의 방법 중 하나를 사용하여 로그인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중