BsD3D11RenderUtility.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #include "BsD3D11RenderUtility.h"
  2. #include "BsD3D11Device.h"
  3. #include "BsVector3.h"
  4. #include "BsColor.h"
  5. #include "BsRect2I.h"
  6. #include "BsD3D11BlendState.h"
  7. #include "BsD3D11RasterizerState.h"
  8. #include "BsD3D11DepthStencilState.h"
  9. #include "BsRenderStateManager.h"
  10. namespace BansheeEngine
  11. {
  12. struct ClearVertex
  13. {
  14. Vector3 pos;
  15. UINT32 col;
  16. };
  17. D3D11RenderUtility::D3D11RenderUtility(D3D11Device* device)
  18. :mDevice(device), mClearQuadIB(nullptr), mClearQuadVB(nullptr),
  19. mClearQuadIL(nullptr), mClearQuadVS(nullptr), mClearQuadPS(nullptr)
  20. {
  21. initClearQuadResources();
  22. }
  23. D3D11RenderUtility::~D3D11RenderUtility()
  24. {
  25. SAFE_RELEASE(mClearQuadPS);
  26. SAFE_RELEASE(mClearQuadVS);
  27. SAFE_RELEASE(mClearQuadIL);
  28. SAFE_RELEASE(mClearQuadIB);
  29. SAFE_RELEASE(mClearQuadVB);
  30. }
  31. void D3D11RenderUtility::drawClearQuad(UINT32 clearBuffers, const Color& color, float depth, UINT16 stencil)
  32. {
  33. // Set states
  34. if((clearBuffers & FBT_COLOR) != 0)
  35. {
  36. D3D11BlendStateCore* d3d11BlendState = static_cast<D3D11BlendStateCore*>(const_cast<BlendStateCore*>(mClearQuadBlendStateYesC.get()));
  37. mDevice->getImmediateContext()->OMSetBlendState(d3d11BlendState->getInternal(), nullptr, 0xFFFFFFFF);
  38. }
  39. else
  40. {
  41. D3D11BlendStateCore* d3d11BlendState = static_cast<D3D11BlendStateCore*>(const_cast<BlendStateCore*>(mClearQuadBlendStateNoC.get()));
  42. mDevice->getImmediateContext()->OMSetBlendState(d3d11BlendState->getInternal(), nullptr, 0xFFFFFFFF);
  43. }
  44. D3D11RasterizerStateCore* d3d11RasterizerState = static_cast<D3D11RasterizerStateCore*>(const_cast<RasterizerStateCore*>(mClearQuadRasterizerState.get()));
  45. mDevice->getImmediateContext()->RSSetState(d3d11RasterizerState->getInternal());
  46. if((clearBuffers & FBT_DEPTH) != 0)
  47. {
  48. if((clearBuffers & FBT_STENCIL) != 0)
  49. {
  50. D3D11DepthStencilStateCore* d3d11RasterizerState = static_cast<D3D11DepthStencilStateCore*>(const_cast<DepthStencilStateCore*>(mClearQuadDSStateYesD_YesS.get()));
  51. mDevice->getImmediateContext()->OMSetDepthStencilState(d3d11RasterizerState->getInternal(), stencil);
  52. }
  53. else
  54. {
  55. D3D11DepthStencilStateCore* d3d11RasterizerState = static_cast<D3D11DepthStencilStateCore*>(const_cast<DepthStencilStateCore*>(mClearQuadDSStateYesD_NoS.get()));
  56. mDevice->getImmediateContext()->OMSetDepthStencilState(d3d11RasterizerState->getInternal(), stencil);
  57. }
  58. }
  59. else
  60. {
  61. if((clearBuffers & FBT_STENCIL) != 0)
  62. {
  63. D3D11DepthStencilStateCore* d3d11RasterizerState = static_cast<D3D11DepthStencilStateCore*>(const_cast<DepthStencilStateCore*>(mClearQuadDSStateNoD_YesS.get()));
  64. mDevice->getImmediateContext()->OMSetDepthStencilState(d3d11RasterizerState->getInternal(), stencil);
  65. }
  66. else
  67. {
  68. D3D11DepthStencilStateCore* d3d11RasterizerState = static_cast<D3D11DepthStencilStateCore*>(const_cast<DepthStencilStateCore*>(mClearQuadDSStateNoD_NoS.get()));
  69. mDevice->getImmediateContext()->OMSetDepthStencilState(d3d11RasterizerState->getInternal(), stencil);
  70. }
  71. }
  72. // TODO - How smart it is to update buffer right before drawing it!? (cache the clip area)
  73. ClearVertex vertexData[4];
  74. vertexData[0].pos = Vector3(-1.0f, 1.0f, depth);
  75. vertexData[1].pos = Vector3(1.0f, 1.0f, depth);
  76. vertexData[2].pos = Vector3(-1.0f, -1.0f, depth);
  77. vertexData[3].pos = Vector3(1.0f, -1.0f, depth);
  78. vertexData[0].col = color.getAsRGBA();
  79. vertexData[1].col = color.getAsRGBA();
  80. vertexData[2].col = color.getAsRGBA();
  81. vertexData[3].col = color.getAsRGBA();
  82. mDevice->getImmediateContext()->UpdateSubresource(mClearQuadVB, 0, nullptr, vertexData, 0, sizeof(ClearVertex) * 4);
  83. mDevice->getImmediateContext()->VSSetShader(mClearQuadVS, nullptr, 0);
  84. mDevice->getImmediateContext()->PSSetShader(mClearQuadPS, nullptr, 0);
  85. ID3D11Buffer* buffers[1];
  86. buffers[0] = mClearQuadVB;
  87. UINT32 strides[1] = { sizeof(ClearVertex) };
  88. UINT32 offsets[1] = { 0 };
  89. mDevice->getImmediateContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  90. mDevice->getImmediateContext()->IASetIndexBuffer(mClearQuadIB, DXGI_FORMAT_R16_UINT, 0);
  91. mDevice->getImmediateContext()->IASetVertexBuffers(0, 1, buffers, strides, offsets);
  92. mDevice->getImmediateContext()->IASetInputLayout(mClearQuadIL);
  93. mDevice->getImmediateContext()->DrawIndexed(6, 0, 0);
  94. }
  95. void D3D11RenderUtility::initClearQuadResources()
  96. {
  97. BLEND_STATE_DESC blendStateDescYesC;
  98. mClearQuadBlendStateYesC = RenderStateCoreManager::instance().createBlendState(blendStateDescYesC);
  99. BLEND_STATE_DESC blendStateDescNoC;
  100. for(int i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++)
  101. blendStateDescNoC.renderTargetDesc[i].renderTargetWriteMask = 0;
  102. mClearQuadBlendStateNoC = RenderStateCoreManager::instance().createBlendState(blendStateDescNoC);
  103. DEPTH_STENCIL_STATE_DESC depthStateDescNoD_NoS;
  104. depthStateDescNoD_NoS.depthReadEnable = false;
  105. depthStateDescNoD_NoS.depthWriteEnable = false;
  106. depthStateDescNoD_NoS.depthComparisonFunc = CMPF_ALWAYS_PASS;
  107. mClearQuadDSStateNoD_NoS = RenderStateCoreManager::instance().createDepthStencilState(depthStateDescNoD_NoS);
  108. DEPTH_STENCIL_STATE_DESC depthStateDescYesD_NoS;
  109. depthStateDescYesD_NoS.depthReadEnable = false;
  110. depthStateDescYesD_NoS.depthWriteEnable = false; // TODO - Set to true
  111. //depthStateDescYesD_NoS.depthComparisonFunc = CMPF_ALWAYS_PASS;
  112. mClearQuadDSStateYesD_NoS = RenderStateCoreManager::instance().createDepthStencilState(depthStateDescYesD_NoS);
  113. DEPTH_STENCIL_STATE_DESC depthStateDescYesD_YesS;
  114. depthStateDescYesD_YesS.depthReadEnable = false;
  115. depthStateDescYesD_YesS.depthWriteEnable = true;
  116. depthStateDescYesD_YesS.depthComparisonFunc = CMPF_ALWAYS_PASS;
  117. depthStateDescYesD_YesS.stencilEnable = true;
  118. depthStateDescYesD_YesS.frontStencilComparisonFunc = CMPF_ALWAYS_PASS;
  119. depthStateDescYesD_YesS.frontStencilPassOp = SOP_REPLACE;
  120. mClearQuadDSStateYesD_YesS = RenderStateCoreManager::instance().createDepthStencilState(depthStateDescYesD_YesS);
  121. DEPTH_STENCIL_STATE_DESC depthStateDescNoD_YesS;
  122. depthStateDescNoD_YesS.depthReadEnable = false;
  123. depthStateDescNoD_YesS.depthWriteEnable = false;
  124. depthStateDescNoD_YesS.depthComparisonFunc = CMPF_ALWAYS_PASS;
  125. depthStateDescNoD_YesS.stencilEnable = true;
  126. depthStateDescNoD_YesS.frontStencilComparisonFunc = CMPF_ALWAYS_PASS;
  127. mClearQuadDSStateNoD_YesS = RenderStateCoreManager::instance().createDepthStencilState(depthStateDescNoD_YesS);
  128. RASTERIZER_STATE_DESC rasterizerStateDesc;
  129. mClearQuadRasterizerState = RenderStateCoreManager::instance().createRasterizerState(rasterizerStateDesc);
  130. String vsShaderCode = " \
  131. void main( \
  132. in float3 inPos : POSITION, \
  133. in float4 color : COLOR0, \
  134. out float4 oPosition : SV_Position, \
  135. out float4 oColor : COLOR0) \
  136. { \
  137. oPosition = float4(inPos.xyz, 1); \
  138. oColor = color; \
  139. } \
  140. ";
  141. String psShaderCode = "float4 main(in float4 inPos : SV_Position, float4 color : COLOR0) : SV_Target \
  142. { return color; }";
  143. HRESULT hr;
  144. ID3DBlob* microcode = nullptr;
  145. ID3DBlob* errors = nullptr;
  146. // Compile pixel shader
  147. hr = D3DCompile(psShaderCode.c_str(), psShaderCode.size(), nullptr, nullptr, nullptr, "main", "ps_4_0",
  148. D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR, 0, &microcode, &errors);
  149. if (FAILED(hr))
  150. {
  151. String message = "Cannot assemble D3D11 high-level shader. Errors:\n" +
  152. String(static_cast<const char*>(errors->GetBufferPointer()));
  153. SAFE_RELEASE(errors);
  154. BS_EXCEPT(RenderingAPIException, message);
  155. }
  156. SAFE_RELEASE(errors);
  157. hr = mDevice->getD3D11Device()->CreatePixelShader(static_cast<DWORD*>(microcode->GetBufferPointer()),
  158. microcode->GetBufferSize(), mDevice->getClassLinkage(), &mClearQuadPS);
  159. if (FAILED(hr))
  160. {
  161. SAFE_RELEASE(microcode);
  162. BS_EXCEPT(RenderingAPIException, "Cannot create D3D11 high-level shader.");
  163. }
  164. // Compile vertex shader
  165. hr = D3DCompile(vsShaderCode.c_str(), vsShaderCode.size(), nullptr, nullptr, nullptr, "main", "vs_4_0",
  166. D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR, 0, &microcode, &errors);
  167. if (FAILED(hr))
  168. {
  169. String message = "Cannot assemble D3D11 high-level shader. Errors:\n" +
  170. String(static_cast<const char*>(errors->GetBufferPointer()));
  171. SAFE_RELEASE(errors);
  172. BS_EXCEPT(RenderingAPIException, message);
  173. }
  174. SAFE_RELEASE(errors);
  175. hr = mDevice->getD3D11Device()->CreateVertexShader(static_cast<DWORD*>(microcode->GetBufferPointer()),
  176. microcode->GetBufferSize(), mDevice->getClassLinkage(), &mClearQuadVS);
  177. if (FAILED(hr))
  178. {
  179. SAFE_RELEASE(microcode);
  180. BS_EXCEPT(RenderingAPIException, "Cannot create D3D11 high-level shader.");
  181. }
  182. // Create input layout
  183. D3D11_INPUT_ELEMENT_DESC* declElements = bs_newN<D3D11_INPUT_ELEMENT_DESC>(2);
  184. ZeroMemory(declElements, sizeof(D3D11_INPUT_ELEMENT_DESC) * 2);
  185. declElements[0].SemanticName = "POSITION";
  186. declElements[0].SemanticIndex = 0;
  187. declElements[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
  188. declElements[0].InputSlot = 0;
  189. declElements[0].AlignedByteOffset = 0;
  190. declElements[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  191. declElements[0].InstanceDataStepRate = 0;
  192. declElements[1].SemanticName = "COLOR";
  193. declElements[1].SemanticIndex = 0;
  194. declElements[1].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  195. declElements[1].InputSlot = 0;
  196. declElements[1].AlignedByteOffset = sizeof(float) * 3;
  197. declElements[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  198. declElements[1].InstanceDataStepRate = 0;
  199. hr = mDevice->getD3D11Device()->CreateInputLayout(declElements, 2, microcode->GetBufferPointer(),
  200. microcode->GetBufferSize(), &mClearQuadIL);
  201. bs_deleteN(declElements, 2);
  202. if (FAILED(hr))
  203. {
  204. BS_EXCEPT(RenderingAPIException, "Cannot create D3D11 input layout.");
  205. }
  206. // Create vertex buffer
  207. D3D11_BUFFER_DESC mVBDesc;
  208. mVBDesc.ByteWidth = sizeof(ClearVertex) * 4;
  209. mVBDesc.MiscFlags = 0;
  210. mVBDesc.StructureByteStride = 0;
  211. mVBDesc.Usage = D3D11_USAGE_DEFAULT;
  212. mVBDesc.CPUAccessFlags = 0;
  213. mVBDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  214. ClearVertex vertexData[4];
  215. vertexData[0].pos = Vector3(0, 0, 0);
  216. vertexData[1].pos = Vector3(0, 0, 0);
  217. vertexData[2].pos = Vector3(0, 0, 0);
  218. vertexData[3].pos = Vector3(0, 0, 0);
  219. vertexData[0].col = Color::White.getAsBGRA();
  220. vertexData[1].col = Color::White.getAsBGRA();
  221. vertexData[2].col = Color::White.getAsBGRA();
  222. vertexData[3].col = Color::White.getAsBGRA();
  223. D3D11_SUBRESOURCE_DATA vertexSubresourceData;
  224. vertexSubresourceData.pSysMem = vertexData;
  225. hr = mDevice->getD3D11Device()->CreateBuffer(&mVBDesc, &vertexSubresourceData, &mClearQuadVB);
  226. if (FAILED(hr) || mDevice->hasError())
  227. {
  228. String msg = mDevice->getErrorDescription();
  229. BS_EXCEPT(RenderingAPIException, "Cannot create D3D11 buffer: " + msg);
  230. }
  231. // Create index buffer
  232. D3D11_BUFFER_DESC mIBDesc;
  233. mIBDesc.ByteWidth = sizeof(UINT16) * 6;
  234. mIBDesc.MiscFlags = 0;
  235. mIBDesc.StructureByteStride = 0;
  236. mIBDesc.Usage = D3D11_USAGE_DEFAULT;
  237. mIBDesc.CPUAccessFlags = 0;
  238. mIBDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
  239. UINT16 indexData[6];
  240. indexData[0] = 0;
  241. indexData[1] = 1;
  242. indexData[2] = 2;
  243. indexData[3] = 1;
  244. indexData[4] = 3;
  245. indexData[5] = 2;
  246. D3D11_SUBRESOURCE_DATA indexSubresourceData;
  247. indexSubresourceData.pSysMem = indexData;
  248. hr = mDevice->getD3D11Device()->CreateBuffer(&mIBDesc, &indexSubresourceData, &mClearQuadIB);
  249. if (FAILED(hr) || mDevice->hasError())
  250. {
  251. String msg = mDevice->getErrorDescription();
  252. BS_EXCEPT(RenderingAPIException, "Cannot create D3D11 buffer: " + msg);
  253. }
  254. }
  255. }