루트 서술자들을 받는 루트 서명은 서술자 힙을 거치지 않고 자원의 가상 주소를 루트 인수로서 직접 전달할 수 있는데 이 방법은 텍스처가 아니라 버퍼 자원에 대한 SRV와 UAV에만 가능하다.
13.3.5 계산 셰이더의 결과를 시스템 메모리에 복사
계산 셰이더에서 UAV 버퍼 자원에 결과값을 저장하고 메모리에 복사하기 위해서는 힙 속성이 READBACK인 자원(UAV 버퍼와 자료 형식과 크기가 동일) 을 만든 뒤에 cmdlist->CopyResource 메서드를 이용해 자원을 READBACK 버퍼에 복사한다. 이후 Map 함수로 자료를 매핑하여 CPU에서 읽을 수 있도록 한다.
13.4 스레드 식별 시스템 값
그룹 ID (SV_GroupID) : 그룹 ID
그룹 스레드 ID (SV_GroupThreadID) : 그룹 내에서 각 스레드의 ID
배분 스레드 ID : SV_DispatchThreadID
3가지 식별 값 모두 int3의 자료형을 가진다.
13.5 추가 버퍼와 소비 버퍼
자료를 계산하는 순서가 중요하지 않은 경우 추가 버퍼와 소비 버퍼라고 불리는 종류의 구조적 버퍼를 사용하는 것이 좋다.
ConsumeStructuredBuffer<Particle> gInput;
AppendStructuredBuffer<Particle> gOutput;
Particle p = gInput.Consume();
gOutput.Append(p);
13.6 공유 메모리와 동기화
groupshared float gCache[256]; // 스레드 그룹마다 하나씩 존재
공유 메모리의 흔한 용도는 텍스처 값을 저장하는 것이다. 동일한 텍스처를 여러 번 추출하는 것은 느리기 때문에
스레드 그룹 내 각 스레드가 gCache (공유 메모리)에 값을 저장을 완료하기 전에 gCache 내용을 사용하려 하면 안되기 때문에, GroupMemoryBarrierWithGroupSync() 함수를 사용해 스레드가 모두 공유 메모리에 값을 기록하기 전까지 대기하도록 만들어야 한다.
13.7.2 텍스처 대상 렌더링 기법
원래 후면버퍼를 화면에 출력하는 방법
후면버퍼 = 텍스처
텍스처에 대한 rtv 서술자를 출력 병합기 단계에 묶고(OMSetRenderTargets) Present 함수 호출하여 화면에 후면 버퍼 용 출력
또 다른 텍스처를 생성하고 그에 대한 rtv 를 만들어서 똑같이 진행해도 가능함 (화면 밖 텍스처 대상 렌더링 방법)
텍스처 대상 렌더링 기법의 용도
1. 그림자 매핑
2. 화면 공간 주변광 차폐 (SSAO)
3. 입방체 맵을 이용한 동적 반사
연습문제
1. 2. 3.
1번 2번 문제는 해결했으나 3번 문제는 해결하지 못했다.
DX11에서는 버퍼에 대한 UAV를 만들 때 D3D11_BUFFER_UAV_FLAG_APPEND를 지정하면 해당 버퍼를 셰이더에서 추가 버퍼 혹은 소비 버퍼로 인식하게 만들 수 있는 거 같은데 책과 인터넷을 찾아봐도 DX12에서 추가 소비 버퍼의 사용 예제가 보이질 않는다. FLAG_NONE을 대체하여 사용해봤는데 계산 셰이더가 제대로 작동하지 않는다. 책에서도 이에 대한 설명이 부실하여 일단은 넘어가도록 해야겠다.
UAV_FLAG_NONE으로 설정하고 셰이더 파일에서 추가 소비 버퍼를 사용하는 대신에 구조적 버퍼(RWStructuredBuffer)로 바꿔주기만 해도 정상적으로 결과가 나온다.
5.
예제가 이미 만들어져 있어서 성능 비교만 했다. 격자 크기 512x512 시뮬레이션 대신에 256x256으로 진행하였다.(512로 하면 CPU 버전에서 파도가 렌더링되지 않음)
GPU에서 계산을 수행하는 것이 CPU에서 수행하는 것보다 처리가 확연하게 빠름을 알 수 있었다.
CPU를 사용한 프로그램은 괜찮았는데 계산 셰이더를 사용한 프로그램을 돌리니 GPU에서 평소에 듣지 못하던 소음이 발생했다.
동작 과정:
Disturb가 발생할 때 mCurrsolUav 서술자가 가리키는 버퍼에 계산 셰이더를 이용해서 파도를 일으키면 (계산 셰이더1)
Update마다 mCurrsolUav와 mPrevSolUav를 이용해 mNextSolUav에 다음 정점 위치를 계산하여 기록한다 (계산 셰이더2)
Update가 끝나면 srv, uav, 자원을 서로바꿔준다. (prev를 next로 curr을 prev로 next를 curr로)