gfxD3D11Cubemap.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2015 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "gfx/D3D11/gfxD3D11Cubemap.h"
  23. #include "gfx/gfxCardProfile.h"
  24. #include "gfx/gfxTextureManager.h"
  25. #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
  26. #include "gfx/bitmap/imageUtils.h"
  27. GFXD3D11Cubemap::GFXD3D11Cubemap() : mTexture(NULL), mSRView(NULL), mDSView(NULL), mTexSize(0)
  28. {
  29. mDynamic = false;
  30. mAutoGenMips = false;
  31. mFaceFormat = GFXFormatR8G8B8A8;
  32. for (U32 i = 0; i < CubeFaces; i++)
  33. {
  34. for(U32 j=0; j < MaxMipMaps; j++)
  35. mRTView[i][j] = NULL;
  36. }
  37. }
  38. GFXD3D11Cubemap::~GFXD3D11Cubemap()
  39. {
  40. releaseSurfaces();
  41. }
  42. void GFXD3D11Cubemap::releaseSurfaces()
  43. {
  44. if (mDynamic)
  45. GFXTextureManager::removeEventDelegate(this, &GFXD3D11Cubemap::_onTextureEvent);
  46. for (U32 i = 0; i < CubeFaces; i++)
  47. {
  48. for (U32 j = 0; j < MaxMipMaps; j++)
  49. SAFE_RELEASE(mRTView[i][j]);
  50. }
  51. SAFE_RELEASE(mDSView);
  52. SAFE_RELEASE(mSRView);
  53. SAFE_RELEASE(mTexture);
  54. }
  55. void GFXD3D11Cubemap::_onTextureEvent(GFXTexCallbackCode code)
  56. {
  57. if (code == GFXZombify)
  58. releaseSurfaces();
  59. else if (code == GFXResurrect)
  60. initDynamic(mTexSize);
  61. }
  62. void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
  63. {
  64. AssertFatal( faces, "GFXD3D11Cubemap::initStatic - Got null GFXTexHandle!" );
  65. AssertFatal( *faces, "empty texture passed to CubeMap::create" );
  66. // NOTE - check tex sizes on all faces - they MUST be all same size
  67. mTexSize = faces->getWidth();
  68. mFaceFormat = faces->getFormat();
  69. bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
  70. UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
  71. UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
  72. if (!compressed)
  73. {
  74. bindFlags |= D3D11_BIND_RENDER_TARGET;
  75. miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
  76. }
  77. mMipMapLevels = faces->getPointer()->getMipLevels();
  78. if (mMipMapLevels < 1 && !compressed)
  79. mAutoGenMips = true;
  80. D3D11_TEXTURE2D_DESC desc;
  81. ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
  82. desc.Width = mTexSize;
  83. desc.Height = mTexSize;
  84. desc.MipLevels = mAutoGenMips ? 0 : mMipMapLevels;
  85. desc.ArraySize = CubeFaces;
  86. desc.Format = GFXD3D11TextureFormat[mFaceFormat];
  87. desc.SampleDesc.Count = 1;
  88. desc.SampleDesc.Quality = 0;
  89. desc.Usage = D3D11_USAGE_DEFAULT;
  90. desc.BindFlags = bindFlags;
  91. desc.MiscFlags = miscFlags;
  92. desc.CPUAccessFlags = 0;
  93. HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
  94. if (FAILED(hr))
  95. {
  96. AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - CreateTexture2D failure");
  97. }
  98. for (U32 i = 0; i < CubeFaces; i++)
  99. {
  100. GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]);
  101. for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
  102. {
  103. U32 subResource = D3D11CalcSubresource(currentMip, i, mMipMapLevels);
  104. D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), currentMip, NULL);
  105. }
  106. }
  107. D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
  108. SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
  109. SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
  110. SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mMipMapLevels;
  111. SMViewDesc.TextureCube.MostDetailedMip = 0;
  112. hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
  113. if (FAILED(hr))
  114. {
  115. AssertFatal(false, "GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) - texcube shader resource view creation failure");
  116. }
  117. //Generate mips
  118. if (mAutoGenMips && !compressed)
  119. {
  120. D3D11DEVICECONTEXT->GenerateMips(mSRView);
  121. //get mip level count
  122. D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
  123. mSRView->GetDesc(&viewDesc);
  124. mMipMapLevels = viewDesc.TextureCube.MipLevels;
  125. }
  126. }
  127. void GFXD3D11Cubemap::initStatic(DDSFile *dds)
  128. {
  129. AssertFatal(dds, "GFXD3D11Cubemap::initStatic - Got null DDS file!");
  130. AssertFatal(dds->isCubemap(), "GFXD3D11Cubemap::initStatic - Got non-cubemap DDS file!");
  131. AssertFatal(dds->mSurfaces.size() == 6, "GFXD3D11Cubemap::initStatic - DDS has less than 6 surfaces!");
  132. // NOTE - check tex sizes on all faces - they MUST be all same size
  133. mTexSize = dds->getWidth();
  134. mFaceFormat = dds->getFormat();
  135. mMipMapLevels = dds->getMipLevels();
  136. D3D11_TEXTURE2D_DESC desc;
  137. desc.Width = mTexSize;
  138. desc.Height = mTexSize;
  139. desc.MipLevels = mMipMapLevels;
  140. desc.ArraySize = CubeFaces;
  141. desc.Format = GFXD3D11TextureFormat[mFaceFormat];
  142. desc.SampleDesc.Count = 1;
  143. desc.SampleDesc.Quality = 0;
  144. desc.Usage = D3D11_USAGE_IMMUTABLE;
  145. desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
  146. desc.CPUAccessFlags = 0;
  147. desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
  148. D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[CubeFaces * mMipMapLevels];
  149. for (U32 currentFace = 0; currentFace < CubeFaces; currentFace++)
  150. {
  151. if (!dds->mSurfaces[currentFace])
  152. continue;
  153. // convert to Z up
  154. const U32 faceIndex = zUpFaceIndex(currentFace);
  155. for(U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
  156. {
  157. const U32 dataIndex = faceIndex * mMipMapLevels + currentMip;
  158. pData[dataIndex].pSysMem = dds->mSurfaces[currentFace]->mMips[currentMip];
  159. pData[dataIndex].SysMemPitch = dds->getSurfacePitch(currentMip);
  160. pData[dataIndex].SysMemSlicePitch = 0;
  161. }
  162. }
  163. HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
  164. if (FAILED(hr))
  165. {
  166. AssertFatal(false, "GFXD3D11Cubemap::initStatic(DDSFile *dds) - CreateTexture2D failure");
  167. }
  168. delete [] pData;
  169. D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
  170. SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
  171. SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
  172. SMViewDesc.TextureCube.MipLevels = mMipMapLevels;
  173. SMViewDesc.TextureCube.MostDetailedMip = 0;
  174. hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
  175. if(FAILED(hr))
  176. {
  177. AssertFatal(false, "GFXD3D11Cubemap::initStatic(DDSFile *dds) - CreateTexture2D call failure");
  178. }
  179. }
  180. void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat, U32 mipLevels)
  181. {
  182. if(!mDynamic)
  183. GFXTextureManager::addEventDelegate(this, &GFXD3D11Cubemap::_onTextureEvent);
  184. mDynamic = true;
  185. mTexSize = texSize;
  186. mFaceFormat = faceFormat;
  187. if (!mipLevels)
  188. mAutoGenMips = true;
  189. mMipMapLevels = mipLevels;
  190. bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
  191. UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
  192. UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
  193. if (!compressed)
  194. {
  195. bindFlags |= D3D11_BIND_RENDER_TARGET;
  196. miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
  197. }
  198. D3D11_TEXTURE2D_DESC desc;
  199. desc.Width = mTexSize;
  200. desc.Height = mTexSize;
  201. desc.MipLevels = mMipMapLevels;
  202. desc.ArraySize = 6;
  203. desc.Format = GFXD3D11TextureFormat[mFaceFormat];
  204. desc.SampleDesc.Count = 1;
  205. desc.SampleDesc.Quality = 0;
  206. desc.Usage = D3D11_USAGE_DEFAULT;
  207. desc.BindFlags = bindFlags;
  208. desc.CPUAccessFlags = 0;
  209. desc.MiscFlags = miscFlags;
  210. HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
  211. D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
  212. SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
  213. SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
  214. SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mMipMapLevels;
  215. SMViewDesc.TextureCube.MostDetailedMip = 0;
  216. hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
  217. if(FAILED(hr))
  218. {
  219. AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D call failure");
  220. }
  221. //Generate mips
  222. if (mAutoGenMips && !compressed)
  223. {
  224. D3D11DEVICECONTEXT->GenerateMips(mSRView);
  225. //get mip level count
  226. D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
  227. mSRView->GetDesc(&viewDesc);
  228. mMipMapLevels = viewDesc.TextureCube.MipLevels;
  229. }
  230. D3D11_RENDER_TARGET_VIEW_DESC viewDesc;
  231. viewDesc.Format = desc.Format;
  232. viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
  233. viewDesc.Texture2DArray.ArraySize = 1;
  234. for (U32 i = 0; i < CubeFaces; i++)
  235. {
  236. viewDesc.Texture2DArray.FirstArraySlice = i;
  237. for (U32 j = 0; j < mMipMapLevels; j++)
  238. {
  239. viewDesc.Texture2DArray.MipSlice = j;
  240. hr = D3D11DEVICE->CreateRenderTargetView(mTexture, &viewDesc, &mRTView[i][j]);
  241. if (FAILED(hr))
  242. {
  243. AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateRenderTargetView call failure");
  244. }
  245. }
  246. }
  247. D3D11_TEXTURE2D_DESC depthTexDesc;
  248. depthTexDesc.Width = mTexSize;
  249. depthTexDesc.Height = mTexSize;
  250. depthTexDesc.MipLevels = 1;
  251. depthTexDesc.ArraySize = 1;
  252. depthTexDesc.SampleDesc.Count = 1;
  253. depthTexDesc.SampleDesc.Quality = 0;
  254. depthTexDesc.Format = DXGI_FORMAT_D32_FLOAT;
  255. depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
  256. depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  257. depthTexDesc.CPUAccessFlags = 0;
  258. depthTexDesc.MiscFlags = 0;
  259. ID3D11Texture2D* depthTex = 0;
  260. hr = D3D11DEVICE->CreateTexture2D(&depthTexDesc, 0, &depthTex);
  261. if(FAILED(hr))
  262. {
  263. AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D for depth stencil call failure");
  264. }
  265. // Create the depth stencil view for the entire cube
  266. D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
  267. dsvDesc.Format = depthTexDesc.Format; //The format must match the depth texture we created above
  268. dsvDesc.Flags = 0;
  269. dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
  270. dsvDesc.Texture2D.MipSlice = 0;
  271. hr = D3D11DEVICE->CreateDepthStencilView(depthTex, &dsvDesc, &mDSView);
  272. if(FAILED(hr))
  273. {
  274. AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateDepthStencilView call failure");
  275. }
  276. SAFE_RELEASE(depthTex);
  277. }
  278. //-----------------------------------------------------------------------------
  279. // Set the cubemap to the specified texture unit num
  280. //-----------------------------------------------------------------------------
  281. void GFXD3D11Cubemap::setToTexUnit(U32 tuNum)
  282. {
  283. D3D11DEVICECONTEXT->PSSetShaderResources(tuNum, 1, &mSRView);
  284. }
  285. void GFXD3D11Cubemap::zombify()
  286. {
  287. // Static cubemaps are handled by D3D
  288. if( mDynamic )
  289. releaseSurfaces();
  290. }
  291. void GFXD3D11Cubemap::resurrect()
  292. {
  293. // Static cubemaps are handled by D3D
  294. if( mDynamic )
  295. initDynamic( mTexSize, mFaceFormat );
  296. }
  297. ID3D11ShaderResourceView* GFXD3D11Cubemap::getSRView()
  298. {
  299. return mSRView;
  300. }
  301. ID3D11RenderTargetView* GFXD3D11Cubemap::getRTView(U32 faceIdx, U32 mipIndex)
  302. {
  303. AssertFatal(faceIdx < CubeFaces, "GFXD3D11Cubemap::getRTView - face index out of bounds");
  304. return mRTView[faceIdx][mipIndex];
  305. }
  306. ID3D11DepthStencilView* GFXD3D11Cubemap::getDSView()
  307. {
  308. return mDSView;
  309. }
  310. ID3D11Texture2D* GFXD3D11Cubemap::get2DTex()
  311. {
  312. return mTexture;
  313. }
  314. //-----------------------------------------------------------------------------
  315. // Cubemap Array
  316. //-----------------------------------------------------------------------------
  317. GFXD3D11CubemapArray::GFXD3D11CubemapArray() : mTexture(NULL), mSRView(NULL)
  318. {
  319. }
  320. GFXD3D11CubemapArray::~GFXD3D11CubemapArray()
  321. {
  322. SAFE_RELEASE(mSRView);
  323. SAFE_RELEASE(mTexture);
  324. }
  325. //TODO: really need a common private 'init' function to avoid code double up with these init* functions
  326. void GFXD3D11CubemapArray::init(GFXCubemapHandle *cubemaps, const U32 cubemapCount)
  327. {
  328. AssertFatal(cubemaps, "GFXD3D11CubemapArray::initStatic - Got null GFXCubemapHandle!");
  329. AssertFatal(*cubemaps, "GFXD3D11CubemapArray::initStatic - Got empty cubemap!");
  330. setCubeTexSize(cubemaps);
  331. mFormat = cubemaps[0]->getFormat();
  332. mNumCubemaps = cubemapCount;
  333. //create texture object
  334. UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
  335. UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
  336. D3D11_TEXTURE2D_DESC desc;
  337. ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
  338. desc.Width = mSize;
  339. desc.Height = mSize;
  340. desc.MipLevels = mMipMapLevels;
  341. desc.ArraySize = CubeFaces * cubemapCount;
  342. desc.Format = GFXD3D11TextureFormat[mFormat];
  343. desc.SampleDesc.Count = 1;
  344. desc.SampleDesc.Quality = 0;
  345. desc.Usage = D3D11_USAGE_DEFAULT;
  346. desc.BindFlags = bindFlags;
  347. desc.MiscFlags = miscFlags;
  348. desc.CPUAccessFlags = 0;
  349. HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
  350. if (FAILED(hr))
  351. AssertFatal(false, "GFXD3D11CubemapArray::initStatic - CreateTexture2D failure");
  352. for (U32 i = 0; i < cubemapCount; i++)
  353. {
  354. GFXD3D11Cubemap *cubeObj = static_cast<GFXD3D11Cubemap*>((GFXCubemap*)cubemaps[i]);
  355. //yes checking the first one(cubemap at index 0) is pointless but saves a further if statement
  356. if (cubemaps[i]->getSize() != mSize || cubemaps[i]->getFormat() != mFormat || cubemaps[i]->getMipMapLevels() != mMipMapLevels)
  357. {
  358. Con::printf("Trying to add an invalid Cubemap to a CubemapArray");
  359. //destroy array here first
  360. AssertFatal(false, "GFXD3D11CubemapArray::initStatic - invalid cubemap");
  361. }
  362. for (U32 face = 0; face < CubeFaces; face++)
  363. {
  364. const U32 arraySlice = face + CubeFaces * i;
  365. for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
  366. {
  367. const U32 srcSubResource = D3D11CalcSubresource(currentMip, face, mMipMapLevels);
  368. const U32 dstSubResource = D3D11CalcSubresource(currentMip, arraySlice, mMipMapLevels);
  369. D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, dstSubResource, 0, 0, 0, cubeObj->get2DTex(), srcSubResource, NULL);
  370. }
  371. }
  372. }
  373. //create shader resource view
  374. D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
  375. SMViewDesc.Format = GFXD3D11TextureFormat[mFormat];
  376. SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
  377. SMViewDesc.TextureCubeArray.MipLevels = mMipMapLevels;
  378. SMViewDesc.TextureCubeArray.MostDetailedMip = 0;
  379. SMViewDesc.TextureCubeArray.NumCubes = mNumCubemaps;
  380. SMViewDesc.TextureCubeArray.First2DArrayFace = 0;
  381. hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
  382. if (FAILED(hr))
  383. AssertFatal(false, "GFXD3D11CubemapArray::initStatic - shader resource view creation failure");
  384. }
  385. //Just allocate the cubemap array but we don't upload any data
  386. void GFXD3D11CubemapArray::init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format)
  387. {
  388. setCubeTexSize(cubemapFaceSize);
  389. mNumCubemaps = cubemapCount;
  390. mFormat = format;
  391. //create texture object
  392. UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
  393. UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
  394. D3D11_TEXTURE2D_DESC desc;
  395. ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
  396. desc.Width = mSize;
  397. desc.Height = mSize;
  398. desc.MipLevels = mMipMapLevels;
  399. desc.ArraySize = CubeFaces * cubemapCount;
  400. desc.Format = GFXD3D11TextureFormat[mFormat];
  401. desc.SampleDesc.Count = 1;
  402. desc.SampleDesc.Quality = 0;
  403. desc.Usage = D3D11_USAGE_DEFAULT;
  404. desc.BindFlags = bindFlags;
  405. desc.MiscFlags = miscFlags;
  406. desc.CPUAccessFlags = 0;
  407. HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
  408. if (FAILED(hr))
  409. AssertFatal(false, "GFXD3D11CubemapArray::initStatic - CreateTexture2D failure");
  410. //create shader resource view
  411. D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
  412. SMViewDesc.Format = GFXD3D11TextureFormat[mFormat];
  413. SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
  414. SMViewDesc.TextureCubeArray.MipLevels = mMipMapLevels;
  415. SMViewDesc.TextureCubeArray.MostDetailedMip = 0;
  416. SMViewDesc.TextureCubeArray.NumCubes = mNumCubemaps;
  417. SMViewDesc.TextureCubeArray.First2DArrayFace = 0;
  418. hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
  419. if (FAILED(hr))
  420. AssertFatal(false, "GFXD3D11CubemapArray::initStatic - shader resource view creation failure");
  421. }
  422. void GFXD3D11CubemapArray::updateTexture(const GFXCubemapHandle &cubemap, const U32 slot)
  423. {
  424. AssertFatal(slot <= mNumCubemaps, "GFXD3D11CubemapArray::updateTexture - trying to update a cubemap texture that is out of bounds!");
  425. AssertFatal(mFormat == cubemap->getFormat(), "GFXD3D11CubemapArray::updateTexture - Destination format doesn't match");
  426. AssertFatal(mSize == cubemap->getSize(), "GFXD3D11CubemapArray::updateTexture - Destination size doesn't match");
  427. AssertFatal(mMipMapLevels == cubemap->getMipMapLevels(), "GFXD3D11CubemapArray::updateTexture - Destination mip levels doesn't match");
  428. GFXD3D11Cubemap *pCubeObj = static_cast<GFXD3D11Cubemap*>((GFXCubemap*)cubemap);
  429. ID3D11Resource *pDstRes = pCubeObj->get2DTex();
  430. for (U32 face = 0; face < CubeFaces; face++)
  431. {
  432. const U32 arraySlice = face + CubeFaces * slot;
  433. for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
  434. {
  435. const U32 srcSubResource = D3D11CalcSubresource(currentMip, face, mMipMapLevels);
  436. const U32 dstSubResource = D3D11CalcSubresource(currentMip, arraySlice, mMipMapLevels);
  437. D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, dstSubResource, 0, 0, 0, pDstRes, srcSubResource, NULL);
  438. }
  439. }
  440. }
  441. void GFXD3D11CubemapArray::copyTo(GFXCubemapArray *pDstCubemap)
  442. {
  443. AssertFatal(pDstCubemap, "GFXD3D11CubemapArray::copyTo - Got null GFXCubemapArray");
  444. AssertFatal(pDstCubemap->getNumCubemaps() > mNumCubemaps, "GFXD3D11CubemapArray::copyTo - Destination too small");
  445. AssertFatal(pDstCubemap->getFormat() == mFormat, "GFXD3D11CubemapArray::copyTo - Destination format doesn't match");
  446. AssertFatal(pDstCubemap->getSize() == mSize, "GFXD3D11CubemapArray::copyTo - Destination size doesn't match");
  447. AssertFatal(pDstCubemap->getMipMapLevels() == mMipMapLevels, "GFXD3D11CubemapArray::copyTo - Destination mip levels doesn't match");
  448. GFXD3D11CubemapArray *pDstCube = static_cast<GFXD3D11CubemapArray*>(pDstCubemap);
  449. ID3D11Resource *pDstRes = pDstCube->get2DTex();
  450. for (U32 cubeMap = 0; cubeMap < mNumCubemaps; cubeMap++)
  451. {
  452. for (U32 face = 0; face < CubeFaces; face++)
  453. {
  454. const U32 arraySlice = face + CubeFaces * cubeMap;
  455. for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
  456. {
  457. const U32 subResource = D3D11CalcSubresource(currentMip, arraySlice, mMipMapLevels);
  458. D3D11DEVICECONTEXT->CopySubresourceRegion(pDstRes, subResource, 0, 0, 0, mTexture, subResource, NULL);
  459. }
  460. }
  461. }
  462. }
  463. void GFXD3D11CubemapArray::setToTexUnit(U32 tuNum)
  464. {
  465. D3D11DEVICECONTEXT->PSSetShaderResources(tuNum, 1, &mSRView);
  466. }
  467. void GFXD3D11CubemapArray::zombify()
  468. {
  469. // Static cubemaps are handled by D3D
  470. }
  471. void GFXD3D11CubemapArray::resurrect()
  472. {
  473. // Static cubemaps are handled by D3D
  474. }