Torque3D Documentation / _generateds / gfxD3D11Cubemap.cpp

gfxD3D11Cubemap.cpp

Engine/source/gfx/D3D11/gfxD3D11Cubemap.cpp

More...

Detailed Description

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