BsD3D11TextureView.cpp 13 KB

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