[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
댓글을 사용할 수 없습니다.