[DX] 상수 버퍼(Constant Buffer)

김진우·2025년 7월 23일

DirectX

목록 보기
26/32
post-thumbnail

정의

GPU 셰이더에 일정한 데이터를 효율적으로 전달하기 위한 고정 크기의 메모리 블록이다.
즉, 한 번에 GPU에게 다양한 데이터를 전달할 수 있다.

주로 변하지 않는 변수들을 셰이더에 넘겨줄 때 사용한다.

특징

  • 성능 최적화 - CPU와 GPU 사이의 통신 오버헤드를 줄일 수 있어 효율적이다.
  • 메모리 정렬 - Constant Buffer는 16Byte 정렬 요구 조건이 있다.
  • 재사용 가능 - 동일한 데이터를 여러 셰이더에 동시에 바인딩 가능하다.

규칙

정렬 : 16Byte 단위로 정렬되어야 GPU가 제대로 읽을 수 있다.

예시 :

cbuffer ExampleBuffer
{
	float4 position; // 16Byte
    
    float3 direction; // 12Byte
    float padding; // 4Byte
} 

예시

1. 구조체 정의

C++와 HLSL 양쪽에서 동일한 메모리 정렬을 보장하기 위해 자료형 정렬 기준을 맞춰야 한다.

struct CB_Context
{
	FMatrix View;
    FMatrix ViewInverse;
    FMatrix Projection;
    FMatrix ViewProjection;

	float RunningTime;
    float Padding[3]; // 16Byte를 맞추기 위한 패딩
} FrameData;

2. 버퍼 생성

ID3D11Buffer* constantBuffer = nullptr;

D3D11_BUFFER_DESC cbDesc = {};
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.ByteWidth = sizeof(CB_Context);
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

device->CreateBuffer(&cbDesc, nullptr, &constantBuffer);

3. Constant Buffer 데이터 업데이트

CB_Context cbData = {};
cbData.View = XMMatrixTranspose(viewMatrix);
cbData.ViewInverse = XMMatrixTranspose(XMMatrixInverse(nullptr, viewMatrix));
cbData.Projection = XMMatrixTranspose(projMatrix);
cbData.ViewProjection = XMMatrixTranspose(viewMatrix * projMatrix);
cbData.RunningTime = totalTime;

D3D11_MAPPED_SUBRESOURCE mappedResource;
context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy(mappedResource.pData, &cbData, sizeof(CB_Context));
context->Unmap(constantBuffer, 0);

4. 셰이더에 Constant Buffer 바인딩

context->VSSetConstantBuffers(0, 1, &constantBuffer);
context->PSSetConstantBuffers(0, 1, &constantBuffer);

5. HLSL 셰이더 코드

cbuffer CB_Context
{
    matrix View;
    matrix ViewInverse;
    matrix Projection;
    matrix ViewProjection;

    float RunningTime;
};


VS_OUTPUT VS(VS_INPUT input)
{
    VS_OUTPUT output;
    float4 worldPos = float4(input.Position, 1.0f);
    output.Position = mul(worldPos, ViewProjection);
    return output;
}

0개의 댓글