[DirectX11] 059 Raw Buffer
DirectX 11에서 Raw Buffer는 특정한 해석이나 형식 없이 바이트 시퀀스를 저장하는 데 사용되는 버퍼 객체의 유형을 가리킨다. 단순히 그래픽 처리 장치(GPU)가 유연한 방식으로 접근할 수 있는 메모리 블록이다. Raw Buffer를 사용하면 미리 정의된 형식으로 제한되지 않고 저장되는 데이터의 형식과 구조를 정의할 수 있다.
목차
Raw Buffer
DirectX 11에서 Raw Buffer는 특정한 해석이나 형식 없이 바이트 시퀀스를 저장하는 데 사용되는 버퍼 객체의 유형을 가리킨다. 단순히 그래픽 처리 장치(GPU)가 유연한 방식으로 접근할 수 있는 메모리 블록이다.
Raw Buffer는 일반적으로 CPU와 GPU 사이 또는 GPU 내의 서로 다른 셰이더 단계 사이에 전달되어야 하는 임의의 데이터를 저장하는 데 사용된다. 예를 들어 Raw Buffer는 정점 데이터, 텍스처 데이터 또는 다른 유형의 메타데이터를 저장하는 데 사용될 수 있다.
Raw Buffer를 사용하는 한 가지 이점은 프로그래머가 미리 정의된 형식으로 제한되지 않고 저장되는 데이터의 형식과 구조를 정의할 수 있다는 것이다. 이것은 사용자 정의 데이터 유형 또는 비표준 데이터 형식으로 작업할 때 특히 유용할 수 있습니다.
DirectX 11에서 Raw Buffer를 사용하려면 일반적으로 ID3D11Device 인터페이스를 사용하여 버퍼 개체를 만들고 버퍼 크기를 바이트 단위로 지정한다. 그런 다음 버퍼 개체를 사용하여 ID3D11DeviceContext 인터페이스를 사용하여 필요에 따라 데이터를 읽거나 쓸 수 있다.
Shader | |
Framework | |
Render | |
Buffer.h .cpp | |
UnitTest | |
DirectCompute | |
RawBufferDemo.h .cpp | |
Main.h .cpp |
Buffer
Buffers.h
#pragma once
class VertexBuffer
{
public:
VertexBuffer(void* data, UINT count, UINT stride, UINT slot = 0, bool bCpuWrite = false, bool bGpuWrite = false);
~VertexBuffer();
UINT Count() { return count; }
UINT Stride() { return stride; }
ID3D11Buffer* Buffer() { return buffer; }
void Render();
private:
ID3D11Buffer* buffer;
void* data;
UINT count;
UINT stride;
UINT slot;
bool bCpuWrite;
bool bGpuWrite;
};
class IndexBuffer
{
public:
IndexBuffer(void* data, UINT count);
~IndexBuffer();
UINT Count() { return count; }
ID3D11Buffer* Buffer() { return buffer; }
void Render();
private:
ID3D11Buffer* buffer;
void* data;
UINT count;
};
//
class ConstantBuffer
{
public:
ConstantBuffer(void* data, UINT dataSize);
~ConstantBuffer();
ID3D11Buffer* Buffer() { return buffer; }
void Render();
private:
ID3D11Buffer* buffer;
void* data;
UINT dataSize;
};
//
class CsResource
{
public:
CsResource();
virtual ~CsResource();
protected:
virtual void CreateInput() {}
virtual void CreateSRV() {}
virtual void CreateOutput() {}
virtual void CreateUAV() {}
virtual void CreateResult() {}
void CreateBuffer();
public:
ID3D11ShaderResourceView* SRV() { return srv; }
ID3D11UnorderedAccessView* UAV() { return uav; }
protected:
ID3D11Resource* input = NULL;
ID3D11ShaderResourceView* srv = NULL; //Input
ID3D11Resource* output = NULL;
ID3D11UnorderedAccessView* uav = NULL; //Output
ID3D11Resource* result = NULL;
};
//
class RawBuffer : public CsResource
{
public:
RawBuffer(void* inputData, UINT inputByte, UINT outputByte);
~RawBuffer();
private:
void CreateInput() override;
void CreateSRV() override;
void CreateOutput() override;
void CreateUAV() override;
void CreateResult() override;
public:
void CopyToInput(void* data); //input으로부터 데이터를 복사해올때
void CopyFromOuput(void* data); //output으로부터 데이터를 복사해올때
private:
void* inputData;
UINT inputByte; //입력으로 얼마나 Byte쓸지
UINT outputByte; //출력으로 얼마나 Byte쓸지
};
Buffers.cpp
#include "Framework.h"
#include "Buffers.h"
VertexBuffer::VertexBuffer(void * data, UINT count, UINT stride, UINT slot, bool bCpuWrite, bool bGpuWrite)
: data(data), count(count), stride(stride), slot(slot)
, bCpuWrite(bCpuWrite), bGpuWrite(bGpuWrite)
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = stride * count;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
if (bCpuWrite == false && bGpuWrite == false)
{
desc.Usage = D3D11_USAGE_IMMUTABLE; //GPU 읽기
}
else if (bCpuWrite == true && bGpuWrite == false)
{
desc.Usage = D3D11_USAGE_DYNAMIC; //CPU 쓰기, GPU 읽기
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
}
else if (bCpuWrite == false && bGpuWrite == true)
{
//CPU 쓰기 가능 - UpdateSubResource
desc.Usage = D3D11_USAGE_DEFAULT;
}
else
{
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
}
D3D11_SUBRESOURCE_DATA subResource = { 0 };
subResource.pSysMem = data;
Check(D3D::GetDevice()->CreateBuffer(&desc, &subResource, &buffer));
}
VertexBuffer::~VertexBuffer()
{
SafeRelease(buffer);
}
void VertexBuffer::Render()
{
UINT offset = 0;
D3D::GetDC()->IASetVertexBuffers(slot, 1, &buffer, &stride, &offset);
}
//
IndexBuffer::IndexBuffer(void * data, UINT count)
: data(data), count(count)
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = sizeof(UINT) * count;
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
desc.Usage = D3D11_USAGE_IMMUTABLE;
D3D11_SUBRESOURCE_DATA subResource = { 0 };
subResource.pSysMem = data;
Check(D3D::GetDevice()->CreateBuffer(&desc, &subResource, &buffer));
}
IndexBuffer::~IndexBuffer()
{
SafeRelease(buffer);
}
void IndexBuffer::Render()
{
D3D::GetDC()->IASetIndexBuffer(buffer, DXGI_FORMAT_R32_UINT, 0);
}
//
ConstantBuffer::ConstantBuffer(void * data, UINT dataSize)
: data(data), dataSize(dataSize)
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = dataSize;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
Check(D3D::GetDevice()->CreateBuffer(&desc, NULL, &buffer));
}
ConstantBuffer::~ConstantBuffer()
{
SafeRelease(buffer);
}
void ConstantBuffer::Render()
{
D3D11_MAPPED_SUBRESOURCE subResource;
D3D::GetDC()->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
{
memcpy(subResource.pData, data, dataSize);
}
D3D::GetDC()->Unmap(buffer, 0);
}
//
CsResource::CsResource()
{
}
CsResource::~CsResource()
{
SafeRelease(input);
SafeRelease(srv);
SafeRelease(output);
SafeRelease(uav);
SafeRelease(result);
}
void CsResource::CreateBuffer()
{
CreateInput();
CreateSRV();
CreateOutput();
CreateUAV();
CreateResult();
}
//
RawBuffer::RawBuffer(void * inputData, UINT inputByte, UINT outputByte)
: CsResource()
, inputData(inputData), inputByte(inputByte), outputByte(outputByte)
{
CreateBuffer();
}
RawBuffer::~RawBuffer()
{
}
void RawBuffer::CreateInput()
{
if (inputByte < 1) return; //inputByte가 1보다 작으면 버퍼를 생성할 수 없으니 패스.
ID3D11Buffer* buffer = NULL;
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = inputByte;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; //Buffer용도
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
D3D11_SUBRESOURCE_DATA subResource = { 0 };
subResource.pSysMem = inputData;
//inputData가 있으면 subResourse를 넣어주고 없으면 NULL.
Check(D3D::GetDevice()->CreateBuffer(&desc, inputData != NULL ? &subResource : NULL, &buffer));
//input에 buffer 저장
input = (ID3D11Resource *)buffer;
}
void RawBuffer::CreateSRV()
{
if (inputByte < 1) return;
ID3D11Buffer* buffer = (ID3D11Buffer *)input;
D3D11_BUFFER_DESC desc;
buffer->GetDesc(&desc);
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));//SHADER_RESOURCE_VIEW에 연결하겠다.
srvDesc.Format = DXGI_FORMAT_R32_TYPELESS; //32비트(=4바이트). buffer의 데이터 하나를 4바이트로 설정하는게 일반적이다.
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
srvDesc.BufferEx.Flags = D3D11_BUFFEREX_SRV_FLAG_RAW; //RawBuffer용 ByteAddress로 다루어라.
srvDesc.BufferEx.NumElements = desc.ByteWidth / 4; //전체 데이터의 개수 = 전체크기(ByteWidth)/ 설정한 기본 바이트 크기(4바이트)
Check(D3D::GetDevice()->CreateShaderResourceView(buffer, &srvDesc, &srv));
}
void RawBuffer::CreateOutput()
{
ID3D11Buffer* buffer = NULL;
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = outputByte;
desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
Check(D3D::GetDevice()->CreateBuffer(&desc, NULL, &buffer));
output = (ID3D11Resource *)buffer;
}
void RawBuffer::CreateUAV()
{
ID3D11Buffer* buffer = (ID3D11Buffer *)output;
D3D11_BUFFER_DESC desc;
buffer->GetDesc(&desc);
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
ZeroMemory(&uavDesc, sizeof(D3D11_UNORDERED_ACCESS_VIEW_DESC));
uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
uavDesc.Buffer.NumElements = desc.ByteWidth / 4;
Check(D3D::GetDevice()->CreateUnorderedAccessView(buffer, &uavDesc, &uav));
}
void RawBuffer::CreateResult()
{
ID3D11Buffer* buffer;
D3D11_BUFFER_DESC desc;
((ID3D11Buffer *)output)->GetDesc(&desc); //output이 만들어진 데이터를 가져온다.
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; //결과를 읽는다.
desc.BindFlags = D3D11_USAGE_DEFAULT; //D3D11_USAGE_DEFAULT = 0
desc.MiscFlags = 0;
Check(D3D::GetDevice()->CreateBuffer(&desc, NULL, &buffer));
result = (ID3D11Resource *)buffer;
}
void RawBuffer::CopyToInput(void * data)
{
D3D11_MAPPED_SUBRESOURCE subResource; //CPU에게 데이터를 써주거나 읽을때 MAPPED 사용.
D3D::GetDC()->Map(input, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
{
memcpy(subResource.pData, data, inputByte);
}
D3D::GetDC()->Unmap(input, 0);
}
void RawBuffer::CopyFromOuput(void * data)
{
//usage가 뭐든간에 ouput에 접근에서 리소스를 복사하여 result에 대입한다.
D3D::GetDC()->CopyResource(result, output);
D3D11_MAPPED_SUBRESOURCE subResource;
D3D::GetDC()->Map(result, 0, D3D11_MAP_READ, 0, &subResource);
{
memcpy(data, subResource.pData, outputByte);
}
D3D::GetDC()->Unmap(result, 0);
}
void RawBuffer::CreateInput()
Raw Buffer
RawBuffer.h
#pragma once
#include "Systems/IExecute.h"
class RawBufferDemo : public IExecute
{
public:
virtual void Initialize() override;
virtual void Ready() override {}
virtual void Destroy() override {}
virtual void Update() override;
virtual void PreRender() override {}
virtual void Render() override;
virtual void PostRender() override {}
virtual void ResizeScreen() override {}
private:
};
RawBuffer.cpp
#include "stdafx.h"
#include "RawBufferDemo.h"
void RawBufferDemo::Initialize()
{
}
void RawBufferDemo::Update()
{
}
void RawBufferDemo::Render()
{
}
실행화면
'⭐ DirectX > DirectX11 3D' 카테고리의 다른 글
[DirectX11] 061 Thread Group, SV_GroupID (0) | 2023.03.02 |
---|---|
[DirectX11] 060 Compute Shader (0) | 2023.02.28 |
[DirectX11] 058 Direct Compute (0) | 2023.02.27 |
[DirectX11] 057 경쟁 조건(Race Condition), 뮤텍스(Mutex), 세마포어(Semaphore) (0) | 2023.02.27 |
[DirectX11] 056 Thread (0) | 2023.02.22 |
댓글
이 글 공유하기
다른 글
-
[DirectX11] 061 Thread Group, SV_GroupID
[DirectX11] 061 Thread Group, SV_GroupID
2023.03.02 -
[DirectX11] 060 Compute Shader
[DirectX11] 060 Compute Shader
2023.02.28 -
[DirectX11] 058 Direct Compute
[DirectX11] 058 Direct Compute
2023.02.27 -
[DirectX11] 057 경쟁 조건(Race Condition), 뮤텍스(Mutex), 세마포어(Semaphore)
[DirectX11] 057 경쟁 조건(Race Condition), 뮤텍스(Mutex), 세마포어(Semaphore)
2023.02.27