DXBuffer.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #include "DXBuffer.h"
  2. #include "DXCommandQueue.h"
  3. #include <iostream>
  4. #ifdef WIN32
  5. #include <d3d11.h>
  6. #include <d3d12.h>
  7. #include <d3dx12.h>
  8. #endif
  9. using namespace Framework;
  10. // Inhalt der DXBuffer Klasse
  11. // Konstruktor
  12. // bind: Der verwendungszweck des Buffers. Beispiel: D3D11_BIND_INDEX_BUFFER, D3D11_BIND_VERTEX_BUFFER.
  13. // eLän: Länge eines einzelnen Elements in Bytes
  14. DXBuffer::DXBuffer( int eLen )
  15. {
  16. data = 0;
  17. changed = 0;
  18. len = 0;
  19. elLen = eLen;
  20. ref = 1;
  21. }
  22. // Destruktor
  23. DXBuffer::~DXBuffer()
  24. {}
  25. // Setzt den geändert fläg, so das beim nächsten auruf von 'kopieren' die daten neu kopiert werden
  26. void DXBuffer::setChanged()
  27. {
  28. changed = 1;
  29. }
  30. // Ändert die länge des Buffers beim nächsten aufruf von 'kopieren'
  31. // län: Die Länge in Bytes
  32. void DXBuffer::setLength( int len )
  33. {
  34. this->len = len;
  35. }
  36. // Legt fest, was beim nächsten aufruf von 'kopieren' kopiert wird
  37. // data: Ein zeiger auf die Daten
  38. void DXBuffer::setData( void *data )
  39. {
  40. this->data = data;
  41. changed = 1;
  42. }
  43. // Gibt die Länge eines Elementes in bytes zurück
  44. int DXBuffer::getElementLength() const
  45. {
  46. return elLen;
  47. }
  48. // Gibt die Anzahl der Elemente im Buffer zurück
  49. int DXBuffer::getElementAnzahl() const
  50. {
  51. return len / elLen;
  52. }
  53. // Erhöht den Reference Counting Zähler.
  54. // return: this.
  55. DXBuffer *DXBuffer::getThis()
  56. {
  57. ref++;
  58. return this;
  59. }
  60. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  61. // return: 0.
  62. DXBuffer *DXBuffer::release()
  63. {
  64. ref--;
  65. if( !ref )
  66. delete this;
  67. return 0;
  68. }
  69. #ifdef WIN32
  70. // Inhalt der DX11Buffer Klasse
  71. // Konstruktor
  72. // eSize: Die Länge eines Elementes in Bytes
  73. DX11Buffer::DX11Buffer( int eSize, ID3D11Device * device, ID3D11DeviceContext * context, int bindFlags )
  74. : DXBuffer( eSize )
  75. {
  76. buffer = 0;
  77. description = new D3D11_BUFFER_DESC();
  78. memset( description, 0, sizeof( description ) );
  79. description->Usage = D3D11_USAGE_DYNAMIC;
  80. description->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  81. description->BindFlags = bindFlags;
  82. this->device = device;
  83. this->context = context;
  84. }
  85. // Destruktor
  86. DX11Buffer::~DX11Buffer()
  87. {
  88. if( buffer )
  89. buffer->Release();
  90. delete description;
  91. }
  92. // Kopiert die Daten in den Buffer, fals sie sich verändert haben
  93. // zRObj: Das Objekt, mit dem die Grafikkarte angesprochen wird
  94. void DX11Buffer::copieren( int byteCount )
  95. {
  96. if( !len )
  97. return;
  98. if( byteCount < 0 )
  99. byteCount = len;
  100. if( description->ByteWidth < (unsigned)len )
  101. {
  102. if( buffer )
  103. buffer->Release();
  104. buffer = 0;
  105. }
  106. if( !buffer )
  107. {
  108. description->ByteWidth = len;
  109. device->CreateBuffer( description, 0, &buffer );
  110. if( data )
  111. changed = 1;
  112. }
  113. if( changed )
  114. {
  115. D3D11_MAPPED_SUBRESOURCE map;
  116. if( ( description->Usage | D3D11_USAGE_DYNAMIC ) == description->Usage )
  117. context->Map( buffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &map );
  118. else
  119. context->Map( buffer, 0, D3D11_MAP::D3D11_MAP_WRITE, 0, &map );
  120. memcpy( map.pData, data, byteCount );
  121. context->Unmap( buffer, 0 );
  122. changed = 0;
  123. }
  124. }
  125. // Gibt den Buffer zurück
  126. ID3D11Buffer * DX11Buffer::zBuffer() const
  127. {
  128. return buffer;
  129. }
  130. // Inhalt der DXStructuredBuffer Klasse
  131. // Konstruktor
  132. // eSize: Die Länge eines Elementes in Bytes
  133. DX11StructuredBuffer::DX11StructuredBuffer( int eSize, ID3D11Device * device, ID3D11DeviceContext * context )
  134. : DX11Buffer( eSize, device, context, D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE )
  135. {
  136. description->MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
  137. description->StructureByteStride = eSize;
  138. description->Usage = D3D11_USAGE_DEFAULT;
  139. view = 0;
  140. }
  141. // Destruktor
  142. DX11StructuredBuffer::~DX11StructuredBuffer()
  143. {
  144. if( view )
  145. view->Release();
  146. }
  147. // Kopiert die Daten in den Buffer, fals sie sich verändert haben
  148. // zRObj: Das Objekt, mit dem die Grafikkarte angesprochen wird
  149. void DX11StructuredBuffer::copieren( int byteCount )
  150. {
  151. ID3D11Buffer *old = buffer;
  152. DX11Buffer::copieren( byteCount );
  153. if( buffer != old )
  154. {
  155. if( view )
  156. view->Release();
  157. D3D11_SHADER_RESOURCE_VIEW_DESC desc = {};
  158. desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
  159. desc.BufferEx.FirstElement = 0;
  160. desc.Format = DXGI_FORMAT_UNKNOWN;
  161. desc.BufferEx.NumElements = description->ByteWidth / description->StructureByteStride;
  162. device->CreateShaderResourceView( buffer, &desc, &view );
  163. }
  164. }
  165. // Gibt die verwendtete Shader Resource View zurück
  166. DX11StructuredBuffer::operator ID3D11ShaderResourceView *( ) const
  167. {
  168. return view;
  169. }
  170. // Konstruktor
  171. // eSize: Die Länge eines Elementes in Bytes
  172. DX12Buffer::DX12Buffer( int eSize, ID3D12Device2 * device, ID3D12GraphicsCommandList2 * list, int flags )
  173. : DXBuffer( eSize ),
  174. buffer( 0 ),
  175. intermediate( 0 ),
  176. device( device ),
  177. list( list )
  178. {
  179. description = new D3D12_RESOURCE_DESC();
  180. ZeroMemory( description, sizeof( D3D12_RESOURCE_DESC ) );
  181. description->Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
  182. description->Height = 1;
  183. description->DepthOrArraySize = 1;
  184. description->MipLevels = 1;
  185. description->Format = DXGI_FORMAT_UNKNOWN;
  186. description->SampleDesc.Count = 1;
  187. description->Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
  188. description->Flags = (D3D12_RESOURCE_FLAGS)flags;
  189. }
  190. // Destruktor
  191. DX12Buffer::~DX12Buffer()
  192. {
  193. if( intermediate )
  194. intermediate->Release();
  195. if( buffer )
  196. buffer->Release();
  197. delete description;
  198. }
  199. // Kopiert die Daten in den Buffer, fals sie sich verändert haben
  200. void DX12Buffer::copieren( int byteCount )
  201. {
  202. if( !len )
  203. return;
  204. if( byteCount < 0 )
  205. byteCount = len;
  206. if( description->Width < len )
  207. {
  208. if( intermediate )
  209. intermediate->Release();
  210. if( buffer )
  211. buffer->Release();
  212. buffer = 0;
  213. description->Width = len;
  214. }
  215. if( !buffer )
  216. {
  217. D3D12_HEAP_PROPERTIES hprop;
  218. hprop.Type = D3D12_HEAP_TYPE_UPLOAD;
  219. hprop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
  220. hprop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
  221. hprop.CreationNodeMask = 1;
  222. hprop.VisibleNodeMask = 1;
  223. device->CreateCommittedResource( &hprop, D3D12_HEAP_FLAG_NONE, description, D3D12_RESOURCE_STATE_GENERIC_READ, 0, __uuidof( ID3D12Resource ), (void **)& buffer );
  224. hprop.Type = D3D12_HEAP_TYPE_UPLOAD;
  225. device->CreateCommittedResource( &hprop, D3D12_HEAP_FLAG_NONE, description, D3D12_RESOURCE_STATE_GENERIC_READ, 0, __uuidof( ID3D12Resource ), (void **)& intermediate );
  226. if( data )
  227. changed = 1;
  228. }
  229. if( changed && data )
  230. {
  231. BYTE *pData;
  232. D3D12_RANGE r;
  233. r.Begin = 0;
  234. r.End = 0;
  235. buffer->Map( 0, &r, (void **)&pData );
  236. memcpy( pData, data, byteCount );
  237. r.End = byteCount;
  238. buffer->Unmap( 0, &r );
  239. //list->CopyBufferRegion( buffer, 0, intermediate, 0, len );
  240. changed = 0;
  241. }
  242. }
  243. // Gibt den Buffer zurück
  244. ID3D12Resource *DX12Buffer::zBuffer() const
  245. {
  246. return buffer;
  247. }
  248. DX12IndexBuffer::DX12IndexBuffer( int eSize, ID3D12Device2 *device, DX12CopyCommandQueue *copy, DX12DirectCommandQueue *direct )
  249. : DX12Buffer( eSize, device, copy->getCommandList(), D3D12_RESOURCE_FLAG_NONE ),
  250. copy( copy ),
  251. direct( direct )
  252. {
  253. ibs = 0;
  254. }
  255. DX12IndexBuffer::~DX12IndexBuffer()
  256. {}
  257. // Kopiert die Daten in den Buffer, fals sie sich verändert haben
  258. void DX12IndexBuffer::copieren( int byteCount )
  259. {
  260. /*if( ibs )
  261. {
  262. D3D12_RESOURCE_BARRIER barrier;
  263. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  264. barrier.Transition.pResource = buffer;
  265. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_INDEX_BUFFER;
  266. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
  267. barrier.Transition.Subresource = 0;
  268. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  269. direct->getCommandList()->ResourceBarrier( 1, &barrier );
  270. direct->execute();
  271. ibs = 0;
  272. }*/
  273. DX12Buffer::copieren( byteCount );
  274. //copy->execute();
  275. /*D3D12_RESOURCE_BARRIER barrier;
  276. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  277. barrier.Transition.pResource = buffer;
  278. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
  279. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_INDEX_BUFFER;
  280. barrier.Transition.Subresource = 0;
  281. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  282. direct->getCommandList()->ResourceBarrier( 1, &barrier );
  283. direct->execute();
  284. ibs = 1;*/
  285. }
  286. DX12VertexBuffer::DX12VertexBuffer( int eSize, ID3D12Device2 *device, DX12CopyCommandQueue *copy, DX12DirectCommandQueue *direct )
  287. : DX12Buffer( eSize, device, copy->getCommandList(), D3D12_RESOURCE_FLAG_NONE ),
  288. copy( copy ),
  289. direct( direct )
  290. {
  291. vbs = 0;
  292. }
  293. DX12VertexBuffer::~DX12VertexBuffer()
  294. {}
  295. // Kopiert die Daten in den Buffer, fals sie sich verändert haben
  296. void DX12VertexBuffer::copieren( int byteCount )
  297. {
  298. /*if( vbs )
  299. {
  300. D3D12_RESOURCE_BARRIER barrier;
  301. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  302. barrier.Transition.pResource = buffer;
  303. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
  304. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
  305. barrier.Transition.Subresource = 0;
  306. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  307. direct->getCommandList()->ResourceBarrier( 1, &barrier );
  308. direct->execute();
  309. vbs = 0;
  310. }*/
  311. DX12Buffer::copieren( byteCount );
  312. //copy->execute();
  313. /*D3D12_RESOURCE_BARRIER barrier;
  314. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  315. barrier.Transition.pResource = buffer;
  316. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
  317. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
  318. barrier.Transition.Subresource = 0;
  319. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  320. direct->getCommandList()->ResourceBarrier( 1, &barrier );
  321. direct->execute();
  322. vbs = 1;*/
  323. }
  324. #endif