상수 버퍼(Constant buffer)는 정점 및 픽셀 셰이더에서 사용될 상수를 모아 놓은 버퍼이다. 상수 버퍼 사용을 위해 cpp 코드 영역에 상수 버퍼 타입의 구조체를 정의하고 셰이더에도 동일한 포맷으로 상수 버퍼 구조체를 정의해야 한다. 그리고 시스템 메모리에서 구조체 변수 생성 및 값 설정 후 정점 혹은 픽셀 셰이더에 Set 시킨다. 값 설정 및 set은 보통 매 프레임 실행되는 Render() 함수에 적용한다. 그러면 이 Set 시킨 데이터를 설정한 셰이더에서 사용할 수 있다.
상수 버퍼를 사용하는 이유는 셰이더에서 매번 사용되는 상수, 하지만 cpp 파일에서 전달해주어야 한다고 가정할 때, 개별적으로 하나하나 값을 전달해 주는 것은 대역폭(bandwidth)이 크고 부담이 많이 된다고 한다. 따라서 하나의 구조체로 묶어 보내도록 하기 위해 constant buffer라는 개념을 사용한다고 한다.
Constant buffers reduce the bandwidth required to update shader constants by allowing shader constants to be grouped together and committed at the same time, rather than making individual calls to commit each constant separately.
그렇다고 하나의 상수 버퍼 구조체에 모든 데이터를 몰아 넣는 것이 아니라, 업데이트 주기에 따라 상수 버퍼를 구성하는 것이 좋다고 한다. 예를 들어 절대 변경되지 않는 고정 데이터, 무엇이 변하면 따라서 변하는 데이터, 매 프레임마다 항상 변하는 데이터와 같은 방식으로 나누는 것이 효율적이라 한다.
But the best way to efficiently use constant buffers is to organize shader variables into constant buffers based on their frequency of update. This allows an application to minimize the bandwidth required for updating shader constants.
읽어보면 이해가 되는 말이다. 변하지 않는 데이터가 포함된 구조체를 매 프레임마다 업데이트하면 그 변하지 않는 데이터까지 셰이더에 매번 보내야 하기 때문이다.
상수 버퍼는 업데이트 및 전송이 빈번하기 때문에 처리하기에 효율적인 메모리 정렬이 되어 있어야 한다. 따라서 상수 버퍼를 구성하는 구조체는 16바이트 정렬되어 있어야 한다. 따라서 전체 크기는 16의 배수가 되며, 최대 4096 x 16바이트 가질 수 있다.
컴파일러가 패딩 데이터를 알아서 붙여주지 않으므로 float3 타입의 변수 2개를 연속으로 선언하면 잘못된 결과가 나온다. 이와 관련하여 다음 포스팅 참고~!
https://woo-dev.tistory.com/271
'게임 공부 > DirectX' 카테고리의 다른 글
[DX11] UpdateSubresource 와 map은 각각 언제? (0) | 2021.04.18 |
---|---|
Blend state (0) | 2021.04.03 |
atan2(arctan)을 이용하여 pitch, yaw 구하기 (0) | 2021.03.25 |
XMVECTOR 타입 구조 - SSE (0) | 2021.03.20 |
깊이스텐실 Desc 중 깊이 func 값 관련 - D3D11_COMPARISON_FUNC (0) | 2021.03.18 |
댓글