DirectX

6.6 루트 서명과 서술자 테이블

Awesome Red Tomato 2021. 12. 31. 01:29

셰이더 프로그램들은 특정 종류의 자원들이 렌더링 파이프라인에 묶인 상태에서 그리기 호출이 실행되었다고 기대한다. 자원들은 특정 레지스터 슬롯에 묶이며, 셰이더 프로그램들은 그 슬롯들을 통해서 자원에 접근한다. 

 

루트서명(root signature)은 그리기 호출 전에 응용 프로그램이 반드시 렌더링 파이프라인에 묶어야 하는 자원들이 무엇이고 그 자원들이 셰이더 입력 레지스터들에 어떻게 대응되는지를 정의한다. 루트 서명은 반드시 그리기 호출에 쓰이는 셰이더들과 호환되어야 한다. 루트 서명의 유효성은 파이프라인 상태 객체(PSO, Pipeline State Object 나중에 나옴)를 생성할 때 검증된다.

 

루트 서명은 ID3D12RootSignature 인터페이스를 사용한다. 루트 서명은 자원들을 서술하는 매개변수들의 배열이다. 여기서 루트 매개변수(root parameter)는 루트 상수(root constant), 루트 서술자(root descriptor), 서술자 테이블(descriptor table) 중 하나가 될 수 있다.

 

이번 예제는 서술자 테이블만 사용한다. 서술자 테이블은 서술자 힙 안에 있는 연속된 서술자들의 구간을 지정한다. 루트 매개변수 하나로 된 루트 서명을 생성하는 코드이다. 그 루트 매개변수는 CBV(상수 버퍼 뷰) 하나를 담기에 충분한 크기의 서술자 테이블이다.

void BoxApp::BuildRootSignature()
{
	// 루트 파라미터
	CD3DX12_ROOT_PARAMETER rootParam[1];

	// cbv 서술자 테이블
	CD3DX12_DESCRIPTOR_RANGE cbvTable = {};
	cbvTable.Init(
    	D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 
		1,  // 테이블의 서술자 개수
		0); // 루트 매개변수에 묶일 셰이더 인수들의 기준 레지스터 번호

	rootParam[0].InitAsDescriptorTable(
		1,          // 구간(range) 개수
		&cbvTable); // 구간들의 배열을 가리키는 포인터

	// 루트 서명 서술자
	CD3DX12_ROOT_SIGNATURE_DESC rootSigDesc(
		1, 
		rootParam, 
		0, 
		nullptr,
		D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

	// CreateRootSignature 멤버로 사용될 변수
	ComPtr<ID3D10Blob> serializedRootSig = nullptr;
	ComPtr<ID3DBlob> errBlob = nullptr;
	HRESULT hrr = D3D12SerializeRootSignature(
		&rootSigDesc,
		D3D_ROOT_SIGNATURE_VERSION_1,
		serializedRootSig.GetAddressOf(),
		errBlob.GetAddressOf());

	if (errBlob != nullptr)
	{
		::OutputDebugStringA((char*)errBlob->GetBufferPointer());
	}
	ThrowIfFailed(hrr);

	ThrowIfFailed(mDevice->CreateRootSignature(
		0, 
		serializedRootSig->GetBufferPointer(),
		serializedRootSig->GetBufferSize(),
		IID_PPV_ARGS(mRootSignature.GetAddressOf())));
}

 

 

생성한 루트 서명은 ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable을 호출해서 서술자 테이블을 파이프라인에 묶는다.

mCommandList->SetGraphicsRootSignature(mRootSignature.Get());
ID3D12DescriptorHeap* descriptorHeaps[] = { mCbvHeap.Get() };
mCommandList->SetDescritproHeaps(_countof(descriptorHeaps), descriptorHeaps);

// 이번 그리기 호출에서 사용할 CBV의 오프셋
CD3DX12_GPU_DESCRIPTOR_HANDLE cbv(mCbvHeap->GetGPUDescriptorHandleForHeapStart());
cbv.Offset(cbvIndex, mCbvSrvUavDescriptorSize);

mCommandList->SetGraphicsRootDescriptorTable(0, cbv);

'DirectX' 카테고리의 다른 글

6.8 래스터화기 상태  (0) 2022.01.03
6.7 셰이더의 컴파일  (0) 2021.12.31
6.5 상수 버퍼(Constant buffer)  (0) 2021.12.26
6.4 픽셀 셰이더(Pixel Shader)  (0) 2021.12.26
6.3 정점 셰이더(Vertex Shader)  (0) 2021.12.26