#include "DXBuffer.h" #include #include "Logging.h" #ifdef WIN32 # include # include # include "d3dx12.h" #endif using namespace Framework; // Contents of the DXBuffer class // Constructor // bind: The usage purpose of the buffer. Example: D3D11_BIND_INDEX_BUFFER, // D3D11_BIND_VERTEX_BUFFER. eLaen: Length of a single element in bytes DXBuffer::DXBuffer(int eLen) : ReferenceCounter() { data = 0; changed = 0; len = 0; elLen = eLen; } // Destructor DXBuffer::~DXBuffer() {} // Sets the changed flag so that data is re-copied on the next call to // 'copieren' void DXBuffer::setChanged() { changed = 1; } // Changes the length of the buffer on the next call to 'copieren' // laen: The length in bytes void DXBuffer::setLength(int len) { this->len = len; } // Sets what will be copied on the next call to 'copieren' // data: A pointer to the data void DXBuffer::setData(void* data) { this->data = data; changed = 1; } // Returns the length of an element in bytes int DXBuffer::getElementLength() const { return elLen; } // Returns the number of elements in the buffer int DXBuffer::getElementAnzahl() const { return len / elLen; } #ifdef WIN32 // Contents of the DX11Buffer class // Constructor // eSize: The length of an element in bytes DX11Buffer::DX11Buffer(int eSize, ID3D11Device* device, ID3D11DeviceContext* context, int bindFlags) : DXBuffer(eSize) { buffer = 0; description = new D3D11_BUFFER_DESC(); memset(description, 0, sizeof(description)); description->Usage = D3D11_USAGE_DYNAMIC; description->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; description->BindFlags = bindFlags; this->device = device; this->context = context; } // Destructor DX11Buffer::~DX11Buffer() { if (buffer) buffer->Release(); delete description; } // Copies the data into the buffer if it has changed // zRObj: The object used to communicate with the graphics card void DX11Buffer::copieren(int byteCount) { if (!len) return; if (byteCount < 0) byteCount = len; if (description->ByteWidth < (unsigned)len) { if (buffer) buffer->Release(); buffer = 0; } if (!buffer) { description->ByteWidth = len; device->CreateBuffer(description, 0, &buffer); if (data) changed = 1; } if (changed) { HRESULT res; D3D11_MAPPED_SUBRESOURCE map; if ((description->Usage | D3D11_USAGE_DYNAMIC) == description->Usage) res = context->Map( buffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &map); else res = context->Map(buffer, 0, D3D11_MAP::D3D11_MAP_WRITE, 0, &map); if (res == S_OK) { memcpy(map.pData, data, byteCount); context->Unmap(buffer, 0); changed = 0; } else { Logging::error() << "Could not update buffer: " << std::hex << res << std::endl; } } } // Returns the buffer ID3D11Buffer* DX11Buffer::zBuffer() const { return buffer; } // Contents of the DXStructuredBuffer class // Constructor // eSize: The length of an element in bytes DX11StructuredBuffer::DX11StructuredBuffer( int eSize, ID3D11Device* device, ID3D11DeviceContext* context) : DX11Buffer(eSize, device, context, D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE) { description->MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; description->StructureByteStride = eSize; description->Usage = D3D11_USAGE_DEFAULT; view = 0; } // Destructor DX11StructuredBuffer::~DX11StructuredBuffer() { if (view) view->Release(); } // Copies the data into the buffer if it has changed // zRObj: The object used to communicate with the graphics card void DX11StructuredBuffer::copieren(int byteCount) { ID3D11Buffer* old = buffer; DX11Buffer::copieren(byteCount); if (buffer != old) { if (view) view->Release(); D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX; desc.BufferEx.FirstElement = 0; desc.Format = DXGI_FORMAT_UNKNOWN; desc.BufferEx.NumElements = description->ByteWidth / description->StructureByteStride; device->CreateShaderResourceView(buffer, &desc, &view); } } // Returns the used shader resource view DX11StructuredBuffer::operator ID3D11ShaderResourceView*() const { return view; } #endif