비타Cpp

CPU와 GPU의 상호작용 - 자원 상태 전이 본문

DirectX12/메모

CPU와 GPU의 상호작용 - 자원 상태 전이

멍C 2021. 10. 1. 14:02

흔히 쓰이는 렌더링 효과 중에는 한 단계에서 GPU가 자원 R에 자료를 기록하고, 다음 단계에서 그 자원 R의 자료를 읽어서 사용하는 식으로 구현하는 것들이 많다. 그런데 GPU가 자원에 자료를 다 기록하지 않았거나 기록을 아예 시작도 하지 않은 상태에서 자원의 자료를 읽으려 하면 문제가 생긴다. 이를 자원 위험 상황(Resurce Hazard)이라고 부른다.

이문제를 해결하기 위해 Direct3D는 자원들에 상태를 부여한다. 새로 생성된 자원은 기본 상태(Default State)로 시작한다. 임의의 상태 전이를 Direct3D에게 '보고'하는 것은 전적으로 응용 프로그램의 몫이다. 이 덕분에, GPU는 상태를 전이하고 자원 위험 상황을 방지하는 데 필요한 일들을 자유로이 진행할 수 있다. 예를 들어 텍스처 자원에 자료를 기록해야 할 때는 그 텍스처의 상태를 Render Target State로 변경한다. 응용 프로그램이 상태 전이를 Direct3D에게 보고함으로써, GPU는 자원 위험을 피하는 데 필요한 조치를 할 수 있다. 상태 전이를 보고하는 부담을 프로그램에게 부여한 것은 성능 때문이다. 응용 프로그램 개발자는 그러한 전이들이 언제 일어나는지 미리 알고 있다. 만일 그런 전이를 자동으로 추적하게 한다면 성능에 부담이 생긴다.

자원 상태 전이는 전이 자원 장벽(Transition Resource Barrier)들의 배열을 설정해서 지정한다. 배열을 사용하는 덕분에, 한 번의 API호출로 여러 개의 자원을 전이할 수 있다. 코드에서 자원 장벽은 D3D12_RESOURCE_BARRIER_DESC 구조체로 서술된다.

다음의 보조 함수는 주어진 자원과 이전, 이후 상태에 해당하는 전이 자원 장벽 서술 구조체를 리턴한다.

 

struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER
{
    //...
    
    static inline CD3DX12_RESOURCE_BARRIER Transition(
        _In_ ID3D12Resource* pResource,
        D3D12_RESOURCE_STATES stateBefore,
        D3D12_RESOURCE_STATES stateAfter,
        UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
        D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE)
    {
        CD3DX12_RESOURCE_BARRIER result;
        ZeroMemory(&result, sizeof(result));
        D3D12_RESOURCE_BARRIER &barrier = result;
        result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
        result.Flags = flags;
        barrier.Transition.pResource = pResource;
        barrier.Transition.StateBefore = stateBefore;
        barrier.Transition.StateAfter = stateAfter;
        barrier.Transition.Subresource = subresource;
        return result;
    }
    
   //...
};

 

다음은 이 함수의 호출의 예이다.

mCommandList->ResourceBarrier(1, 
		&CD3DX12_RESOURCE_BARRIER::Transition(
			CurrentBackBuffer(),
			D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_PRESENT,
			D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET));

 

이 코드는 화면에 표시할 이미지를 나타내는 텍스처 자원을 제시 상태(Presentation State)에서 렌더 대상 상태(Render Target State)로 전이한다. 자원 장벽이 CommandList에 추가됨을 주목해야 한다. 전이 자원 장벽이라는 것을 GPU에게 자원의 상태가 전이됨을 알려주는 하나의 명령이라고 생각하면 된다. 명령을 통해서 자원 상태 전이를 알려주는 덕분에, GPU는 이후의 명령들을 실행할 때 자원 위험 상황을 피하는 데 필요한 단계들을 밟을 수 있다. 

Comments