서의 공간
[T18] Constant buffer 본문
핵심 개념
Constant buffer: 상수버퍼에는 [파이프라인(셰이더)로부터 적은 레이턴시로 액세스], [CPU로 인한 빈번한 갱신]같은 성능이 요구된다. 이로 인해 상수버퍼의 메모리 구조에는 [4바이트 얼리어너먼트]로 [각 요소는 16바이트를 경계를 사이에 걸친 형태로는 할 수 없으며 전체 사이즈는 16의 배수(최대 4096 x 16 바이트)] 라는 조건이 붙어있다. 즉 버퍼사이즈는 16의 배수이어야 한다.
상수버퍼에 값을 쓰는 것은 버퍼의 Usage가 D3D11_USAGE_DEFAULT일 때의 서브리소스에 쓰는 방식과 D3D11_USAGE_DYNAMIC일 때에 ID3D11Device::Map~ UnMap을 사용하는 방식이 있다.
Graphics.cpp
더보기
void Graphics::DrawTestTriangle( float angle )
{
HRESULT hr;
struct Vertex
{
struct {
float x;
float y;
} pos;
struct {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} color;
};
// create vertex buffer (1 2d triangle at center of screen)
Vertex vertices[] =
{
{ 0.0f,0.5f,255,0,0,0 },
{ 0.5f,-0.5f,0,255,0,0 },
{ -0.5f,-0.5f,0,0,255,0 },
{ -0.3f,0.3f,0,255,0,0 },
{ 0.3f,0.3f,0,0,255,0 },
{ 0.0f,-1.0f,255,0,0,0 },
};
vertices[0].color.g = 255;
wrl::ComPtr<ID3D11Buffer> pVertexBuffer;
D3D11_BUFFER_DESC bd = {};
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.Usage = D3D11_USAGE_DEFAULT;
bd.CPUAccessFlags = 0u;
bd.MiscFlags = 0u;
bd.ByteWidth = sizeof( vertices );
bd.StructureByteStride = sizeof( Vertex );
D3D11_SUBRESOURCE_DATA sd = {};
sd.pSysMem = vertices;
GFX_THROW_INFO( pDevice->CreateBuffer( &bd,&sd,&pVertexBuffer ) );
// Bind vertex buffer to pipeline
const UINT stride = sizeof( Vertex );
const UINT offset = 0u;
pContext->IASetVertexBuffers( 0u,1u,pVertexBuffer.GetAddressOf(),&stride,&offset );
// create index buffer
const unsigned short indices[] =
{
0,1,2,
0,2,3,
0,4,1,
2,1,5,
};
wrl::ComPtr<ID3D11Buffer> pIndexBuffer;
D3D11_BUFFER_DESC ibd = {};
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.Usage = D3D11_USAGE_DEFAULT;
ibd.CPUAccessFlags = 0u;
ibd.MiscFlags = 0u;
ibd.ByteWidth = sizeof( indices );
ibd.StructureByteStride = sizeof( unsigned short );
D3D11_SUBRESOURCE_DATA isd = {};
isd.pSysMem = indices;
GFX_THROW_INFO( pDevice->CreateBuffer( &ibd,&isd,&pIndexBuffer ) );
// bind index buffer
pContext->IASetIndexBuffer( pIndexBuffer.Get(),DXGI_FORMAT_R16_UINT,0u );
// create constant buffer for transformation matrix
struct ConstantBuffer
{
struct
{
float element[4][4];
} transformation;
};
const ConstantBuffer cb =
{
{
(3.0f / 4.0f) * std::cos( angle ), std::sin( angle ), 0.0f, 0.0f,
(3.0f / 4.0f) * -std::sin( angle ), std::cos( angle ), 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f,
}
};
wrl::ComPtr<ID3D11Buffer> pConstantBuffer;
D3D11_BUFFER_DESC cbd;
cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd.Usage = D3D11_USAGE_DYNAMIC;
cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbd.MiscFlags = 0u;
cbd.ByteWidth = sizeof( cb );
cbd.StructureByteStride = 0u;
D3D11_SUBRESOURCE_DATA csd = {};
csd.pSysMem = &cb;
GFX_THROW_INFO( pDevice->CreateBuffer( &cbd,&csd,&pConstantBuffer ) );
// bind constant buffer to vertex shader
pContext->VSSetConstantBuffers( 0u,1u,pConstantBuffer.GetAddressOf() );
// create pixel shader
wrl::ComPtr<ID3D11PixelShader> pPixelShader;
wrl::ComPtr<ID3DBlob> pBlob;
GFX_THROW_INFO( D3DReadFileToBlob( L"PixelShader.cso",&pBlob ) );
GFX_THROW_INFO( pDevice->CreatePixelShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(),nullptr,&pPixelShader ) );
// bind pixel shader
pContext->PSSetShader( pPixelShader.Get(),nullptr,0u );
// create vertex shader
wrl::ComPtr<ID3D11VertexShader> pVertexShader;
GFX_THROW_INFO( D3DReadFileToBlob( L"VertexShader.cso",&pBlob ) );
GFX_THROW_INFO( pDevice->CreateVertexShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(),nullptr,&pVertexShader ) );
// bind vertex shader
pContext->VSSetShader( pVertexShader.Get(),nullptr,0u );
// input (vertex) layout (2d position only)
wrl::ComPtr<ID3D11InputLayout> pInputLayout;
const D3D11_INPUT_ELEMENT_DESC ied[] =
{
{ "Position",0,DXGI_FORMAT_R32G32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0 },
{ "Color",0,DXGI_FORMAT_R8G8B8A8_UNORM,0,8u,D3D11_INPUT_PER_VERTEX_DATA,0 },
};
GFX_THROW_INFO( pDevice->CreateInputLayout(
ied,(UINT)std::size( ied ),
pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
&pInputLayout
) );
// bind vertex layout
pContext->IASetInputLayout( pInputLayout.Get() );
// bind render target
pContext->OMSetRenderTargets( 1u,pTarget.GetAddressOf(),nullptr );
// Set primitive topology to triangle list (groups of 3 vertices)
pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
// configure viewport
D3D11_VIEWPORT vp;
vp.Width = 800;
vp.Height = 600;
vp.MinDepth = 0;
vp.MaxDepth = 1;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
pContext->RSSetViewports( 1u,&vp );
GFX_THROW_INFO_ONLY( pContext->DrawIndexed( (UINT)std::size( indices ),0u,0u ) );
}
VertexShader.hlsl
더보기
struct VSOut
{
float3 color : Color;
float4 pos : SV_Position;
};
cbuffer CBuf
{
row_major matrix transform;
};
VSOut main( float2 pos : Position,float3 color : Color )
{
VSOut vso;
vso.pos = mul( float4(pos.x,pos.y,0.0f,1.0f),transform );
vso.color = color;
return vso;
}
'Graphics API > DirectX 11 - Chili' 카테고리의 다른 글
[T21.1] Bindable System (0) | 2020.11.29 |
---|---|
[T20] Solid cube, Depth and stencil (0) | 2020.11.29 |
[T17] Draw Indexed Triangle (0) | 2020.11.29 |
[T16.2] Draw Triangle (0) | 2020.11.28 |
[T16.1] Draw Triangle (0) | 2020.11.28 |
Comments