CmD3D11GenericBuffer.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #include "CmD3D11GenericBuffer.h"
  2. #include "CmD3D11RenderSystem.h"
  3. #include "CmD3D11Device.h"
  4. #include "CmException.h"
  5. namespace CamelotEngine
  6. {
  7. D3D11GenericBuffer::D3D11GenericBuffer(UINT32 elementCount, UINT32 elementSize, GenericBufferType type, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
  8. : GenericBuffer(elementCount, elementSize, type, usage, randomGpuWrite, useCounter), mBuffer(nullptr)
  9. {
  10. D3D11_BUFFER_DESC desc;
  11. ZeroMemory(&desc, sizeof(desc));
  12. if(type == GBT_APPENDCONSUME && !randomGpuWrite)
  13. CM_EXCEPT(InvalidParametersException, "Append/Consume buffer must be created with randomGpuWrite enabled.");
  14. if(type != GBT_STRUCTURED && useCounter)
  15. CM_EXCEPT(InvalidParametersException, "Counter can only be used with a structured buffer.");
  16. if(useCounter && !randomGpuWrite)
  17. CM_EXCEPT(InvalidParametersException, "Counter can only be used with buffers that have randomGpuWrite enabled.");
  18. if(type == GBT_STRUCTURED || type == GBT_APPENDCONSUME)
  19. {
  20. desc.ByteWidth = elementCount * elementSize;
  21. desc.StructureByteStride = elementSize;
  22. desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
  23. }
  24. else if(type == GBT_RAW)
  25. {
  26. desc.ByteWidth = elementCount * elementSize;
  27. desc.StructureByteStride = 0;
  28. desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
  29. }
  30. else if(type == GBT_INDIRECTARGUMENT)
  31. {
  32. desc.ByteWidth = elementCount * elementSize;
  33. desc.StructureByteStride = 0;
  34. desc.MiscFlags = D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS;
  35. }
  36. if(!randomGpuWrite)
  37. {
  38. desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
  39. if(usage == GBU_STATIC)
  40. {
  41. desc.Usage = D3D11_USAGE_DEFAULT;
  42. desc.CPUAccessFlags = 0;
  43. }
  44. else if(usage == GBU_DYNAMIC)
  45. {
  46. desc.Usage = D3D11_USAGE_DYNAMIC;
  47. desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  48. }
  49. else
  50. CM_EXCEPT(InternalErrorException, "Invalid usage flag: " + toString(usage));
  51. }
  52. else
  53. {
  54. desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
  55. desc.Usage = D3D11_USAGE_DEFAULT;
  56. desc.CPUAccessFlags = 0;
  57. }
  58. D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
  59. HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateBuffer(&desc, nullptr, &mBuffer);
  60. if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
  61. {
  62. String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
  63. CM_EXCEPT(RenderingAPIException, "Cannot create D3D11 buffer: " + msg);
  64. }
  65. }
  66. D3D11GenericBuffer::~D3D11GenericBuffer()
  67. {
  68. SAFE_RELEASE(mBuffer);
  69. }
  70. ID3D11ShaderResourceView* D3D11GenericBuffer::createSRV(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements)
  71. {
  72. if(mType == GBT_APPENDCONSUME)
  73. CM_EXCEPT(InvalidParametersException, "Cannot create ShaderResourceView for an append/consume buffer.");
  74. D3D11_SHADER_RESOURCE_VIEW_DESC desc;
  75. ZeroMemory(&desc, sizeof(desc));
  76. if(mType == GBT_STRUCTURED)
  77. {
  78. desc.Format = DXGI_FORMAT_UNKNOWN;
  79. desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
  80. desc.Buffer.ElementOffset = firstElement * elementWidth;
  81. desc.Buffer.ElementWidth = elementWidth;
  82. }
  83. else if(mType == GBT_RAW)
  84. {
  85. desc.Format = DXGI_FORMAT_R32_TYPELESS;
  86. desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
  87. desc.BufferEx.Flags = D3D11_BUFFEREX_SRV_FLAG_RAW;
  88. desc.BufferEx.FirstElement = firstElement;
  89. desc.BufferEx.NumElements = numElements;
  90. }
  91. else if(mType == GBT_INDIRECTARGUMENT)
  92. {
  93. desc.Format = DXGI_FORMAT_R32_UINT;
  94. desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
  95. desc.Buffer.ElementOffset = firstElement * elementWidth;
  96. desc.Buffer.ElementWidth = elementWidth;
  97. }
  98. ID3D11ShaderResourceView* srv = nullptr;
  99. D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
  100. HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateShaderResourceView(mBuffer, &desc, &srv);
  101. if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
  102. {
  103. String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
  104. CM_EXCEPT(RenderingAPIException, "Cannot create ShaderResourceView: " + msg);
  105. }
  106. return srv;
  107. }
  108. ID3D11UnorderedAccessView* D3D11GenericBuffer::createUAV(UINT32 firstElement, UINT32 numElements)
  109. {
  110. D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
  111. ZeroMemory(&desc, sizeof(desc));
  112. desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
  113. if(mType == GBT_STRUCTURED)
  114. {
  115. desc.Format = DXGI_FORMAT_UNKNOWN;
  116. desc.Buffer.FirstElement = firstElement;
  117. desc.Buffer.NumElements = numElements;
  118. if(mUseCounter)
  119. desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_COUNTER;
  120. else
  121. desc.Buffer.Flags = 0;
  122. }
  123. else if(mType == GBT_RAW)
  124. {
  125. desc.Format = DXGI_FORMAT_R32_TYPELESS;
  126. desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
  127. desc.Buffer.FirstElement = firstElement;
  128. desc.Buffer.NumElements = numElements;
  129. }
  130. else if(mType == GBT_INDIRECTARGUMENT)
  131. {
  132. desc.Format = DXGI_FORMAT_R32_UINT;
  133. desc.Buffer.Flags = 0;
  134. desc.Buffer.FirstElement = firstElement;
  135. desc.Buffer.NumElements = numElements;
  136. }
  137. else if(mType == GBT_APPENDCONSUME)
  138. {
  139. desc.Format = DXGI_FORMAT_UNKNOWN;
  140. desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND;
  141. desc.Buffer.FirstElement = firstElement;
  142. desc.Buffer.NumElements = numElements;
  143. }
  144. ID3D11UnorderedAccessView* uav = nullptr;
  145. D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
  146. HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateUnorderedAccessView(mBuffer, &desc, &uav);
  147. if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
  148. {
  149. String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
  150. CM_EXCEPT(RenderingAPIException, "Cannot create UnorderedAccessView: " + msg);
  151. }
  152. return uav;
  153. }
  154. void* D3D11GenericBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
  155. {
  156. return nullptr;
  157. }
  158. void D3D11GenericBuffer::unlock()
  159. {
  160. }
  161. void D3D11GenericBuffer::readData(UINT32 offset, UINT32 length, void* pDest)
  162. {
  163. }
  164. void D3D11GenericBuffer::writeData(UINT32 offset, UINT32 length, const void* pSource, bool discardWholeBuffer)
  165. {
  166. }
  167. void D3D11GenericBuffer::copyData(GenericBuffer& srcBuffer, UINT32 srcOffset,
  168. UINT32 dstOffset, UINT32 length, bool discardWholeBuffer)
  169. {
  170. }
  171. }