BsD3D11TextureView.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsD3D11TextureView.h"
  4. #include "BsD3D11RenderAPI.h"
  5. #include "BsD3D11Device.h"
  6. #include "BsD3D11Texture.h"
  7. #include "BsRenderStats.h"
  8. #include "BsD3D11Mappings.h"
  9. #include "BsException.h"
  10. namespace BansheeEngine
  11. {
  12. D3D11TextureView::D3D11TextureView(const SPtr<TextureCore>& texture, const TEXTURE_VIEW_DESC& desc)
  13. :TextureView(texture, desc), mSRV(nullptr), mUAV(nullptr), mDSV(nullptr), mRTV(nullptr), mRODSV(nullptr)
  14. {
  15. D3D11TextureCore* d3d11Texture = static_cast<D3D11TextureCore*>(mOwnerTexture.get());
  16. if ((mDesc.usage & GVU_RANDOMWRITE) != 0)
  17. mUAV = createUAV(d3d11Texture, mDesc.mostDetailMip, mDesc.firstArraySlice, mDesc.numArraySlices);
  18. else if ((mDesc.usage & GVU_RENDERTARGET) != 0)
  19. mRTV = createRTV(d3d11Texture, mDesc.mostDetailMip, mDesc.firstArraySlice, mDesc.numArraySlices);
  20. else if ((mDesc.usage & GVU_DEPTHSTENCIL) != 0)
  21. {
  22. mDSV = createDSV(d3d11Texture, mDesc.mostDetailMip, mDesc.firstArraySlice, mDesc.numArraySlices, false);
  23. mRODSV = createDSV(d3d11Texture, mDesc.mostDetailMip, mDesc.firstArraySlice, mDesc.numArraySlices, true);
  24. }
  25. else
  26. mSRV = createSRV(d3d11Texture, mDesc.mostDetailMip, mDesc.numMips, mDesc.firstArraySlice, mDesc.numArraySlices);
  27. }
  28. D3D11TextureView::~D3D11TextureView()
  29. {
  30. SAFE_RELEASE(mSRV);
  31. SAFE_RELEASE(mUAV);
  32. SAFE_RELEASE(mDSV);
  33. SAFE_RELEASE(mRODSV);
  34. SAFE_RELEASE(mRTV);
  35. }
  36. ID3D11ShaderResourceView* D3D11TextureView::createSRV(D3D11TextureCore* texture,
  37. UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices)
  38. {
  39. D3D11_SHADER_RESOURCE_VIEW_DESC desc;
  40. ZeroMemory(&desc, sizeof(desc));
  41. const TextureProperties& texProps = texture->getProperties();
  42. UINT32 numFaces = texProps.getNumFaces();
  43. switch (texProps.getTextureType())
  44. {
  45. case TEX_TYPE_1D:
  46. if (numFaces <= 1)
  47. {
  48. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
  49. desc.Texture1D.MipLevels = numMips;
  50. desc.Texture1D.MostDetailedMip = mostDetailMip;
  51. }
  52. else
  53. {
  54. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
  55. desc.Texture1DArray.MipLevels = numMips;
  56. desc.Texture1DArray.MostDetailedMip = mostDetailMip;
  57. desc.Texture1DArray.FirstArraySlice = firstArraySlice;
  58. desc.Texture1DArray.ArraySize = numArraySlices;
  59. }
  60. break;
  61. case TEX_TYPE_2D:
  62. if (texProps.getMultisampleCount() > 1)
  63. {
  64. if (numFaces <= 1)
  65. {
  66. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
  67. }
  68. else
  69. {
  70. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
  71. desc.Texture2DMSArray.FirstArraySlice = firstArraySlice;
  72. desc.Texture2DMSArray.ArraySize = numArraySlices;
  73. }
  74. }
  75. else
  76. {
  77. if (numFaces <= 1)
  78. {
  79. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
  80. desc.Texture2D.MipLevels = numMips;
  81. desc.Texture2D.MostDetailedMip = mostDetailMip;
  82. }
  83. else
  84. {
  85. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
  86. desc.Texture2DArray.MipLevels = numMips;
  87. desc.Texture2DArray.MostDetailedMip = mostDetailMip;
  88. desc.Texture2DArray.FirstArraySlice = firstArraySlice;
  89. desc.Texture2DArray.ArraySize = numArraySlices;
  90. }
  91. }
  92. break;
  93. case TEX_TYPE_3D:
  94. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
  95. desc.Texture3D.MipLevels = numMips;
  96. desc.Texture3D.MostDetailedMip = mostDetailMip;
  97. break;
  98. case TEX_TYPE_CUBE_MAP:
  99. if (numFaces <= 6)
  100. {
  101. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
  102. desc.TextureCube.MipLevels = numMips;
  103. desc.TextureCube.MostDetailedMip = mostDetailMip;
  104. }
  105. else
  106. {
  107. desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
  108. desc.TextureCubeArray.MipLevels = numMips;
  109. desc.TextureCubeArray.MostDetailedMip = mostDetailMip;
  110. desc.TextureCubeArray.First2DArrayFace = firstArraySlice;
  111. desc.TextureCubeArray.NumCubes = numArraySlices / 6;
  112. }
  113. break;
  114. default:
  115. BS_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");
  116. }
  117. desc.Format = texture->getColorFormat();
  118. ID3D11ShaderResourceView* srv = nullptr;
  119. D3D11RenderAPI* d3d11rs = static_cast<D3D11RenderAPI*>(D3D11RenderAPI::instancePtr());
  120. HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateShaderResourceView(texture->getDX11Resource(), &desc, &srv);
  121. if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
  122. {
  123. String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
  124. BS_EXCEPT(RenderingAPIException, "Cannot create ShaderResourceView: " + msg);
  125. }
  126. return srv;
  127. }
  128. ID3D11RenderTargetView* D3D11TextureView::createRTV(D3D11TextureCore* texture,
  129. UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices)
  130. {
  131. D3D11_RENDER_TARGET_VIEW_DESC desc;
  132. ZeroMemory(&desc, sizeof(desc));
  133. const TextureProperties& texProps = texture->getProperties();
  134. UINT32 numFaces = texProps.getNumFaces();
  135. switch (texProps.getTextureType())
  136. {
  137. case TEX_TYPE_1D:
  138. if (numFaces <= 1)
  139. {
  140. desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
  141. desc.Texture1D.MipSlice = mipSlice;
  142. }
  143. else
  144. {
  145. desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
  146. desc.Texture1DArray.MipSlice = mipSlice;
  147. desc.Texture1DArray.FirstArraySlice = firstArraySlice;
  148. desc.Texture1DArray.ArraySize = numArraySlices;
  149. }
  150. break;
  151. case TEX_TYPE_2D:
  152. if (texProps.getMultisampleCount() > 1)
  153. {
  154. if (numFaces <= 1)
  155. {
  156. desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
  157. }
  158. else
  159. {
  160. desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
  161. desc.Texture2DMSArray.FirstArraySlice = firstArraySlice;
  162. desc.Texture2DMSArray.ArraySize = numArraySlices;
  163. }
  164. }
  165. else
  166. {
  167. if (numFaces <= 1)
  168. {
  169. desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
  170. desc.Texture2D.MipSlice = mipSlice;
  171. }
  172. else
  173. {
  174. desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
  175. desc.Texture2DArray.MipSlice = mipSlice;
  176. desc.Texture2DArray.FirstArraySlice = firstArraySlice;
  177. desc.Texture2DArray.ArraySize = numArraySlices;
  178. }
  179. }
  180. break;
  181. case TEX_TYPE_3D:
  182. desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
  183. desc.Texture3D.MipSlice = mipSlice;
  184. desc.Texture3D.FirstWSlice = firstArraySlice;
  185. desc.Texture3D.WSize = numArraySlices;
  186. break;
  187. case TEX_TYPE_CUBE_MAP:
  188. desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
  189. desc.Texture2DArray.FirstArraySlice = firstArraySlice;
  190. desc.Texture2DArray.ArraySize = numArraySlices;
  191. desc.Texture2DArray.MipSlice = mipSlice;
  192. break;
  193. default:
  194. BS_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");
  195. }
  196. desc.Format = texture->getColorFormat();
  197. ID3D11RenderTargetView* rtv = nullptr;
  198. D3D11RenderAPI* d3d11rs = static_cast<D3D11RenderAPI*>(D3D11RenderAPI::instancePtr());
  199. HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateRenderTargetView(texture->getDX11Resource(), &desc, &rtv);
  200. if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
  201. {
  202. String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
  203. BS_EXCEPT(RenderingAPIException, "Cannot create RenderTargetView: " + msg);
  204. }
  205. return rtv;
  206. }
  207. ID3D11UnorderedAccessView* D3D11TextureView::createUAV(D3D11TextureCore* texture,
  208. UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices)
  209. {
  210. D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
  211. ZeroMemory(&desc, sizeof(desc));
  212. const TextureProperties& texProps = texture->getProperties();
  213. UINT32 numFaces = texProps.getNumFaces();
  214. switch (texProps.getTextureType())
  215. {
  216. case TEX_TYPE_1D:
  217. if (numFaces <= 1)
  218. {
  219. desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D;
  220. desc.Texture1D.MipSlice = mipSlice;
  221. }
  222. else
  223. {
  224. desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY;
  225. desc.Texture1DArray.MipSlice = mipSlice;
  226. desc.Texture1DArray.FirstArraySlice = firstArraySlice;
  227. desc.Texture1DArray.ArraySize = numArraySlices;
  228. }
  229. break;
  230. case TEX_TYPE_2D:
  231. if (numFaces <= 1)
  232. {
  233. desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
  234. desc.Texture2D.MipSlice = mipSlice;
  235. }
  236. else
  237. {
  238. desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
  239. desc.Texture2DArray.MipSlice = mipSlice;
  240. desc.Texture2DArray.FirstArraySlice = firstArraySlice;
  241. desc.Texture2DArray.ArraySize = numArraySlices;
  242. }
  243. break;
  244. case TEX_TYPE_3D:
  245. desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
  246. desc.Texture3D.MipSlice = mipSlice;
  247. desc.Texture3D.FirstWSlice = firstArraySlice;
  248. desc.Texture3D.WSize = numArraySlices;
  249. break;
  250. case TEX_TYPE_CUBE_MAP:
  251. desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
  252. desc.Texture2DArray.FirstArraySlice = firstArraySlice;
  253. desc.Texture2DArray.ArraySize = numArraySlices;
  254. desc.Texture2DArray.MipSlice = mipSlice;
  255. break;
  256. default:
  257. BS_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");
  258. }
  259. desc.Format = texture->getDXGIFormat();
  260. ID3D11UnorderedAccessView* uav = nullptr;
  261. D3D11RenderAPI* d3d11rs = static_cast<D3D11RenderAPI*>(D3D11RenderAPI::instancePtr());
  262. HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateUnorderedAccessView(texture->getDX11Resource(), &desc, &uav);
  263. if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
  264. {
  265. String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
  266. BS_EXCEPT(RenderingAPIException, "Cannot create UnorderedAccessView: " + msg);
  267. }
  268. return uav;
  269. }
  270. ID3D11DepthStencilView* D3D11TextureView::createDSV(D3D11TextureCore* texture,
  271. UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices, bool readOnly)
  272. {
  273. D3D11_DEPTH_STENCIL_VIEW_DESC desc;
  274. ZeroMemory(&desc, sizeof(desc));
  275. const TextureProperties& texProps = texture->getProperties();
  276. UINT32 numFaces = texProps.getNumFaces();
  277. switch (texProps.getTextureType())
  278. {
  279. case TEX_TYPE_1D:
  280. if (numFaces <= 1)
  281. {
  282. desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
  283. desc.Texture1D.MipSlice = mipSlice;
  284. }
  285. else
  286. {
  287. desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY;
  288. desc.Texture1DArray.MipSlice = mipSlice;
  289. desc.Texture1DArray.FirstArraySlice = firstArraySlice;
  290. desc.Texture1DArray.ArraySize = numArraySlices;
  291. }
  292. break;
  293. case TEX_TYPE_2D:
  294. if (texProps.getMultisampleCount() > 1)
  295. {
  296. if (numFaces <= 1)
  297. {
  298. desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
  299. }
  300. else
  301. {
  302. desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
  303. desc.Texture2DMSArray.FirstArraySlice = firstArraySlice;
  304. desc.Texture2DMSArray.ArraySize = numArraySlices;
  305. }
  306. }
  307. else
  308. {
  309. if (numFaces <= 1)
  310. {
  311. desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
  312. desc.Texture2D.MipSlice = mipSlice;
  313. }
  314. else
  315. {
  316. desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
  317. desc.Texture2DArray.MipSlice = mipSlice;
  318. desc.Texture2DArray.FirstArraySlice = firstArraySlice;
  319. desc.Texture2DArray.ArraySize = numArraySlices;
  320. }
  321. }
  322. break;
  323. case TEX_TYPE_3D:
  324. case TEX_TYPE_CUBE_MAP:
  325. desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
  326. desc.Texture2DArray.FirstArraySlice = firstArraySlice;
  327. desc.Texture2DArray.ArraySize = numArraySlices;
  328. desc.Texture2DArray.MipSlice = mipSlice;
  329. break;
  330. default:
  331. BS_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");
  332. }
  333. if (readOnly)
  334. desc.Flags = D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL;
  335. desc.Format = texture->getDepthStencilFormat();
  336. ID3D11DepthStencilView* dsv = nullptr;
  337. D3D11RenderAPI* d3d11rs = static_cast<D3D11RenderAPI*>(D3D11RenderAPI::instancePtr());
  338. HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateDepthStencilView(texture->getDX11Resource(), &desc, &dsv);
  339. if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
  340. {
  341. String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
  342. BS_EXCEPT(RenderingAPIException, "Cannot create DepthStencilView: " + msg);
  343. }
  344. return dsv;
  345. }
  346. }