#include "DXBuffer.h" #include #ifdef WIN32 #include #include #include #endif using namespace Framework; // Inhalt der DXBuffer Klasse // Konstruktor // bind: Der verwendungszweck des Buffers. Beispiel: D3D11_BIND_INDEX_BUFFER, D3D11_BIND_VERTEX_BUFFER. // eLän: Länge eines einzelnen Elements in Bytes DXBuffer::DXBuffer( int eLen ) { data = 0; changed = 0; len = 0; elLen = eLen; ref = 1; } // Destruktor DXBuffer::~DXBuffer() {} // Setzt den geändert fläg, so das beim nächsten auruf von 'kopieren' die daten neu kopiert werden void DXBuffer::setChanged() { changed = 1; } // Ändert die länge des Buffers beim nächsten aufruf von 'kopieren' // län: Die Länge in Bytes void DXBuffer::setLength( int len ) { this->len = len; } // Legt fest, was beim nächsten aufruf von 'kopieren' kopiert wird // data: Ein zeiger auf die Daten void DXBuffer::setData( void *data ) { this->data = data; changed = 1; } // Gibt die Länge eines Elementes in bytes zurück int DXBuffer::getElementLength() const { return elLen; } // Gibt die Anzahl der Elemente im Buffer zurück int DXBuffer::getElementAnzahl() const { return len / elLen; } // Erhöht den Reference Counting Zähler. // return: this. DXBuffer *DXBuffer::getThis() { ref++; return this; } // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht. // return: 0. DXBuffer *DXBuffer::release() { ref--; if( !ref ) delete this; return 0; } #ifdef WIN32 // Inhalt der DX11Buffer Klasse // Konstruktor // eSize: Die Länge eines Elementes 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; } // Destruktor DX11Buffer::~DX11Buffer() { if( buffer ) buffer->Release(); delete description; } // Kopiert die Daten in den Buffer, fals sie sich verändert haben // zRObj: Das Objekt, mit dem die Grafikkarte angesprochen wird 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 ) { D3D11_MAPPED_SUBRESOURCE map; if( ( description->Usage | D3D11_USAGE_DYNAMIC ) == description->Usage ) context->Map( buffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &map ); else context->Map( buffer, 0, D3D11_MAP::D3D11_MAP_WRITE, 0, &map ); memcpy( map.pData, data, byteCount ); context->Unmap( buffer, 0 ); changed = 0; } } // Gibt den Buffer zurück ID3D11Buffer * DX11Buffer::zBuffer() const { return buffer; } // Inhalt der DXStructuredBuffer Klasse // Konstruktor // eSize: Die Länge eines Elementes 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; } // Destruktor DX11StructuredBuffer::~DX11StructuredBuffer() { if( view ) view->Release(); } // Kopiert die Daten in den Buffer, fals sie sich verändert haben // zRObj: Das Objekt, mit dem die Grafikkarte angesprochen wird 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 ); } } // Gibt die verwendtete Shader Resource View zurück DX11StructuredBuffer::operator ID3D11ShaderResourceView *( ) const { return view; } // Konstruktor // eSize: Die Länge eines Elementes in Bytes DX12Buffer::DX12Buffer( int eSize, ID3D12Device2 * device, ID3D12GraphicsCommandList2 * list, int flags ) : DXBuffer( eSize ), buffer( 0 ), intermediate( 0 ), device( device ), list( list ) { description = new D3D12_RESOURCE_DESC(); ZeroMemory( description, sizeof( D3D12_RESOURCE_DESC ) ); description->Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; description->Height = 1; description->DepthOrArraySize = 1; description->MipLevels = 1; description->Format = DXGI_FORMAT_UNKNOWN; description->SampleDesc.Count = 1; description->Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; description->Flags = (D3D12_RESOURCE_FLAGS)flags; } // Destruktor DX12Buffer::~DX12Buffer() { if( intermediate ) intermediate->Release(); if( buffer ) buffer->Release(); delete description; } // Kopiert die Daten in den Buffer, fals sie sich verändert haben void DX12Buffer::copieren( int byteCount ) { if( !len ) return; if( byteCount < 0 ) byteCount = len; if( description->Width < len ) { if( intermediate ) intermediate->Release(); if( buffer ) buffer->Release(); buffer = 0; description->Width = len; } if( !buffer ) { D3D12_HEAP_PROPERTIES hprop; hprop.Type = D3D12_HEAP_TYPE_DEFAULT; hprop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; hprop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; hprop.CreationNodeMask = 1; hprop.VisibleNodeMask = 1; device->CreateCommittedResource( &hprop, D3D12_HEAP_FLAG_NONE, description, D3D12_RESOURCE_STATE_COPY_DEST, 0, __uuidof( ID3D12Resource ), (void **)& buffer ); hprop.Type = D3D12_HEAP_TYPE_UPLOAD; device->CreateCommittedResource( &hprop, D3D12_HEAP_FLAG_NONE, description, D3D12_RESOURCE_STATE_GENERIC_READ, 0, __uuidof( ID3D12Resource ), (void **)& intermediate ); if( data ) changed = 1; } if( changed && data ) { BYTE *pData; intermediate->Map( 0, nullptr, reinterpret_cast( &pData ) ); memcpy( pData, data, byteCount ); intermediate->Unmap( 0, nullptr ); list->CopyBufferRegion( buffer, 0, intermediate, 0, byteCount ); changed = 0; } } // Gibt den Buffer zurück ID3D12Resource *DX12Buffer::zBuffer() const { return buffer; } #endif