CmD3D11Texture.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. #include "CmD3D11Texture.h"
  2. #include "CmD3D11Mappings.h"
  3. #include "CmD3D11Device.h"
  4. #include "CmD3D11RenderSystem.h"
  5. #include "CmException.h"
  6. #include "CmAsyncOp.h"
  7. #if CM_DEBUG_MODE
  8. #define THROW_IF_NOT_RENDER_THREAD throwIfNotRenderThread();
  9. #else
  10. #define THROW_IF_NOT_RENDER_THREAD
  11. #endif
  12. namespace CamelotEngine
  13. {
  14. D3D11Texture::D3D11Texture()
  15. : m1DTex(nullptr)
  16. , m2DTex(nullptr)
  17. , m3DTex(nullptr)
  18. , mTex(nullptr)
  19. , mShaderResourceView(nullptr)
  20. , mStagingBuffer(nullptr)
  21. , mLockedSubresourceIdx(-1)
  22. , mLockedForReading(false)
  23. , mStaticBuffer(nullptr)
  24. {
  25. }
  26. D3D11Texture::~D3D11Texture()
  27. {
  28. THROW_IF_NOT_RENDER_THREAD;
  29. freeInternalResources();
  30. }
  31. void D3D11Texture::copyImpl(TexturePtr& target)
  32. {
  33. D3D11Texture* other = static_cast<D3D11Texture*>(target.get());
  34. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  35. D3D11Device& device = rs->getPrimaryDevice();
  36. device.getImmediateContext()->CopyResource(other->getDX11Resource(), mTex);
  37. if (device.hasError())
  38. {
  39. String errorDescription = device.getErrorDescription();
  40. CM_EXCEPT(RenderingAPIException, "D3D11 device cannot copy resource\nError Description:" + errorDescription);
  41. }
  42. }
  43. PixelData D3D11Texture::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
  44. {
  45. UINT32 mipWidth = mWidth >> mipLevel;
  46. UINT32 mipHeight = mHeight >> mipLevel;
  47. UINT32 mipDepth = mDepth >> mipLevel;
  48. PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
  49. D3D11_MAP flags = D3D11Mappings::getLockOptions(options);
  50. if(flags == D3D11_MAP_READ || flags == D3D11_MAP_READ_WRITE)
  51. {
  52. lockedArea.data = _mapstagingbuffer(flags, face, mipLevel);
  53. mLockedForReading = true;
  54. }
  55. else
  56. {
  57. if(mUsage == TU_DYNAMIC)
  58. lockedArea.data = _map(mTex, flags, face, mipLevel);
  59. else
  60. lockedArea.data = _mapstaticbuffer(lockedArea, mipLevel, face);
  61. mLockedForReading = false;
  62. }
  63. return lockedArea;
  64. }
  65. void D3D11Texture::unlockImpl()
  66. {
  67. if(mLockedForReading)
  68. _unmapstagingbuffer();
  69. else
  70. {
  71. if(mUsage == TU_DYNAMIC)
  72. _unmap(mTex);
  73. else
  74. _unmapstaticbuffer();
  75. }
  76. }
  77. void D3D11Texture::initialize_internal()
  78. {
  79. THROW_IF_NOT_RENDER_THREAD
  80. createInternalResources();
  81. Resource::initialize_internal();
  82. }
  83. void D3D11Texture::createInternalResourcesImpl()
  84. {
  85. // load based on tex.type
  86. switch (getTextureType())
  87. {
  88. case TEX_TYPE_1D:
  89. _create1DTex();
  90. break;
  91. case TEX_TYPE_2D:
  92. case TEX_TYPE_CUBE_MAP:
  93. _create2DTex();
  94. break;
  95. case TEX_TYPE_3D:
  96. _create3DTex();
  97. break;
  98. default:
  99. freeInternalResources();
  100. CM_EXCEPT(RenderingAPIException, "Unknown texture type");
  101. }
  102. }
  103. void D3D11Texture::freeInternalResourcesImpl()
  104. {
  105. SAFE_RELEASE(mTex);
  106. SAFE_RELEASE(mShaderResourceView);
  107. SAFE_RELEASE(m1DTex);
  108. SAFE_RELEASE(m2DTex);
  109. SAFE_RELEASE(m3DTex);
  110. SAFE_RELEASE(mStagingBuffer);
  111. }
  112. void D3D11Texture::_create1DTex()
  113. {
  114. // We must have those defined here
  115. assert(mWidth > 0);
  116. // Determine which D3D11 pixel format we'll use
  117. HRESULT hr;
  118. DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
  119. D3D11_TEXTURE1D_DESC desc;
  120. desc.Width = static_cast<UINT32>(mWidth);
  121. desc.ArraySize = 1;
  122. desc.Format = d3dPF;
  123. desc.MiscFlags = 0;
  124. if((mUsage & TU_RENDERTARGET) != 0)
  125. {
  126. desc.Usage = D3D11_USAGE_DEFAULT;
  127. desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
  128. desc.CPUAccessFlags = (mUsage & TU_RENDERTARGET) != 0 ? 0 : D3D11Mappings::_getAccessFlags(mUsage);
  129. desc.MipLevels = 1;
  130. }
  131. else
  132. {
  133. desc.Usage = D3D11Mappings::_getUsage(mUsage);
  134. desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
  135. desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage);
  136. // Determine total number of mipmaps including main one (d3d11 convention)
  137. UINT32 numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > mWidth) ? 0 : mNumMipmaps + 1;
  138. desc.MipLevels = numMips;
  139. }
  140. // Create the texture
  141. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  142. D3D11Device& device = rs->getPrimaryDevice();
  143. hr = device.getD3D11Device()->CreateTexture1D(&desc, nullptr, &m1DTex);
  144. // Check result and except if failed
  145. if (FAILED(hr) || device.hasError())
  146. {
  147. freeInternalResources();
  148. String errorDescription = device.getErrorDescription();
  149. CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
  150. }
  151. hr = m1DTex->QueryInterface(__uuidof(ID3D11Resource), (void **)&mTex);
  152. if(FAILED(hr) || device.hasError())
  153. {
  154. freeInternalResources();
  155. String errorDescription = device.getErrorDescription();
  156. CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
  157. }
  158. m1DTex->GetDesc(&desc);
  159. mNumMipmaps = desc.MipLevels - 1;
  160. // Create texture view
  161. ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
  162. mSRVDesc.Format = desc.Format;
  163. mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
  164. mSRVDesc.Texture1D.MipLevels = desc.MipLevels;
  165. hr = device.getD3D11Device()->CreateShaderResourceView(m1DTex, &mSRVDesc, &mShaderResourceView);
  166. if (FAILED(hr) || device.hasError())
  167. {
  168. String errorDescription = device.getErrorDescription();
  169. CM_EXCEPT(RenderingAPIException, "D3D11 device can't create shader resource view.\nError Description:" + errorDescription);
  170. }
  171. }
  172. void D3D11Texture::_create2DTex()
  173. {
  174. // We must have those defined here
  175. assert(mWidth > 0 || mHeight > 0);
  176. // Determine which D3D11 pixel format we'll use
  177. HRESULT hr;
  178. DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
  179. D3D11_TEXTURE2D_DESC desc;
  180. desc.Width = static_cast<UINT32>(mWidth);
  181. desc.Height = static_cast<UINT32>(mHeight);
  182. desc.ArraySize = 1;
  183. desc.Format = d3dPF;
  184. desc.MiscFlags = 0;
  185. if((mUsage & TU_RENDERTARGET) != 0)
  186. {
  187. desc.Usage = D3D11_USAGE_DEFAULT;
  188. desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
  189. desc.CPUAccessFlags = (mUsage & TU_RENDERTARGET) != 0 ? 0 : D3D11Mappings::_getAccessFlags(mUsage);
  190. desc.MipLevels = 1;
  191. DXGI_SAMPLE_DESC sampleDesc;
  192. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  193. rs->determineFSAASettings(mFSAA, mFSAAHint, d3dPF, &sampleDesc);
  194. desc.SampleDesc = sampleDesc;
  195. if(getTextureType() == TEX_TYPE_CUBE_MAP)
  196. {
  197. CM_EXCEPT(NotImplementedException, "Cube map not yet supported as a render target."); // TODO: Will be once I add proper texture array support
  198. }
  199. }
  200. else
  201. {
  202. desc.Usage = D3D11Mappings::_getUsage(mUsage);
  203. desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
  204. desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage);
  205. // Determine total number of mipmaps including main one (d3d11 convention)
  206. UINT32 numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > mWidth) ? 0 : mNumMipmaps + 1;
  207. desc.MipLevels = numMips;
  208. DXGI_SAMPLE_DESC sampleDesc;
  209. sampleDesc.Count = 1;
  210. sampleDesc.Quality = 0;
  211. desc.SampleDesc = sampleDesc;
  212. }
  213. if (getTextureType() == TEX_TYPE_CUBE_MAP)
  214. {
  215. desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
  216. desc.ArraySize = 6;
  217. }
  218. // Create the texture
  219. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  220. D3D11Device& device = rs->getPrimaryDevice();
  221. hr = device.getD3D11Device()->CreateTexture2D(&desc, nullptr, &m2DTex);
  222. // Check result and except if failed
  223. if (FAILED(hr) || device.hasError())
  224. {
  225. freeInternalResources();
  226. String errorDescription = device.getErrorDescription();
  227. CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
  228. }
  229. hr = m2DTex->QueryInterface(__uuidof(ID3D11Resource), (void **)&mTex);
  230. if(FAILED(hr) || device.hasError())
  231. {
  232. freeInternalResources();
  233. String errorDescription = device.getErrorDescription();
  234. CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
  235. }
  236. m2DTex->GetDesc(&desc);
  237. mNumMipmaps = desc.MipLevels - 1;
  238. // Create shader texture view
  239. ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
  240. mSRVDesc.Format = desc.Format;
  241. if((mUsage & TU_RENDERTARGET) != 0)
  242. {
  243. if(mFSAA > 0)
  244. {
  245. mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
  246. mSRVDesc.Texture2D.MostDetailedMip = 0;
  247. mSRVDesc.Texture2D.MipLevels = desc.MipLevels;
  248. }
  249. else
  250. {
  251. mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
  252. mSRVDesc.Texture2D.MostDetailedMip = 0;
  253. mSRVDesc.Texture2D.MipLevels = desc.MipLevels;
  254. }
  255. }
  256. else
  257. {
  258. switch(getTextureType())
  259. {
  260. case TEX_TYPE_CUBE_MAP:
  261. mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
  262. mSRVDesc.TextureCube.MipLevels = desc.MipLevels;
  263. mSRVDesc.TextureCube.MostDetailedMip = 0;
  264. break;
  265. case TEX_TYPE_2D:
  266. mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
  267. mSRVDesc.Texture2D.MostDetailedMip = 0;
  268. mSRVDesc.Texture2D.MipLevels = desc.MipLevels;
  269. break;
  270. }
  271. }
  272. hr = device.getD3D11Device()->CreateShaderResourceView(m2DTex, &mSRVDesc, &mShaderResourceView);
  273. if (FAILED(hr) || device.hasError())
  274. {
  275. String errorDescription = device.getErrorDescription();
  276. CM_EXCEPT(RenderingAPIException, "D3D11 device can't create shader resource view.\nError Description:" + errorDescription);
  277. }
  278. }
  279. void D3D11Texture::_create3DTex()
  280. {
  281. // We must have those defined here
  282. assert(mWidth > 0 && mHeight > 0 && mDepth > 0);
  283. // Determine which D3D11 pixel format we'll use
  284. HRESULT hr;
  285. DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
  286. D3D11_TEXTURE3D_DESC desc;
  287. desc.Width = static_cast<UINT32>(mWidth);
  288. desc.Height = static_cast<UINT32>(mHeight);
  289. desc.Depth = static_cast<UINT32>(mDepth);
  290. desc.Format = d3dPF;
  291. desc.MiscFlags = 0;
  292. if((mUsage & TU_RENDERTARGET) != 0)
  293. {
  294. desc.Usage = D3D11_USAGE_DEFAULT;
  295. desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
  296. desc.CPUAccessFlags = (mUsage & TU_RENDERTARGET) != 0 ? 0 : D3D11Mappings::_getAccessFlags(mUsage);
  297. desc.MipLevels = 1;
  298. }
  299. else
  300. {
  301. desc.Usage = D3D11Mappings::_getUsage(mUsage);
  302. desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
  303. desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage);
  304. // Determine total number of mipmaps including main one (d3d11 convention)
  305. UINT numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > std::max(std::max(mWidth, mHeight), mDepth)) ? 0 : mNumMipmaps + 1;
  306. desc.MipLevels = numMips;
  307. }
  308. // Create the texture
  309. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  310. D3D11Device& device = rs->getPrimaryDevice();
  311. hr = device.getD3D11Device()->CreateTexture3D(&desc, nullptr, &m3DTex);
  312. // Check result and except if failed
  313. if (FAILED(hr) || device.hasError())
  314. {
  315. freeInternalResources();
  316. String errorDescription = device.getErrorDescription();
  317. CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
  318. }
  319. hr = m3DTex->QueryInterface(__uuidof(ID3D11Resource), (void **)&mTex);
  320. if(FAILED(hr) || device.hasError())
  321. {
  322. freeInternalResources();
  323. String errorDescription = device.getErrorDescription();
  324. CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
  325. }
  326. // Create texture view
  327. m3DTex->GetDesc(&desc);
  328. mNumMipmaps = desc.MipLevels - 1;
  329. ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
  330. mSRVDesc.Format = desc.Format;
  331. mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
  332. mSRVDesc.Texture3D.MostDetailedMip = 0;
  333. mSRVDesc.Texture3D.MipLevels = desc.MipLevels;
  334. hr = device.getD3D11Device()->CreateShaderResourceView(m2DTex, &mSRVDesc, &mShaderResourceView);
  335. if (FAILED(hr) || device.hasError())
  336. {
  337. String errorDescription = device.getErrorDescription();
  338. CM_EXCEPT(RenderingAPIException, "D3D11 device can't create shader resource view.\nError Description:" + errorDescription);
  339. }
  340. }
  341. void* D3D11Texture::_map(ID3D11Resource* res, D3D11_MAP flags, UINT32 mipLevel, UINT32 face)
  342. {
  343. D3D11_MAPPED_SUBRESOURCE pMappedResource;
  344. pMappedResource.pData = nullptr;
  345. mipLevel = Math::Clamp(mipLevel, (UINT32)mipLevel, getNumMipmaps());
  346. face = Math::Clamp(face, (UINT32)0, mDepth - 1);
  347. if(getTextureType() == TEX_TYPE_3D)
  348. face = 0;
  349. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  350. D3D11Device& device = rs->getPrimaryDevice();
  351. mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, getNumMipmaps()+1);
  352. device.getImmediateContext()->Map(res, mLockedSubresourceIdx, flags, 0, &pMappedResource);
  353. if (device.hasError())
  354. {
  355. String errorDescription = device.getErrorDescription();
  356. CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription);
  357. }
  358. return pMappedResource.pData;
  359. }
  360. void D3D11Texture::_unmap(ID3D11Resource* res)
  361. {
  362. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  363. D3D11Device& device = rs->getPrimaryDevice();
  364. device.getImmediateContext()->Unmap(res, mLockedSubresourceIdx);
  365. if (device.hasError())
  366. {
  367. String errorDescription = device.getErrorDescription();
  368. CM_EXCEPT(RenderingAPIException, "D3D11 device unmap resource\nError Description:" + errorDescription);
  369. }
  370. }
  371. void* D3D11Texture::_mapstagingbuffer(D3D11_MAP flags, UINT32 mipLevel, UINT32 face)
  372. {
  373. if(!mStagingBuffer)
  374. _createStagingBuffer();
  375. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  376. D3D11Device& device = rs->getPrimaryDevice();
  377. device.getImmediateContext()->CopyResource(mStagingBuffer, mTex);
  378. return _map(mStagingBuffer, flags, face, mipLevel);
  379. }
  380. void D3D11Texture::_unmapstagingbuffer()
  381. {
  382. _unmap(mStagingBuffer);
  383. }
  384. void* D3D11Texture::_mapstaticbuffer(PixelData lock, UINT32 mipLevel, UINT32 face)
  385. {
  386. UINT32 sizeOfImage = lock.getConsecutiveSize();
  387. mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, getNumMipmaps()+1);
  388. UINT8* bufferData = new UINT8[sizeOfImage];
  389. mStaticBuffer = new PixelData(lock.getWidth(), lock.getHeight(), lock.getDepth(), lock.getFormat(), bufferData, true);
  390. return bufferData;
  391. }
  392. void D3D11Texture::_unmapstaticbuffer()
  393. {
  394. UINT32 rowWidth = D3D11Mappings::_getSizeInBytes(mStaticBuffer->getFormat(), mStaticBuffer->getWidth());
  395. UINT32 sliceWidth = D3D11Mappings::_getSizeInBytes(mStaticBuffer->getFormat(), mStaticBuffer->getWidth(), mStaticBuffer->getHeight());
  396. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  397. D3D11Device& device = rs->getPrimaryDevice();
  398. device.getImmediateContext()->UpdateSubresource(mTex, mLockedSubresourceIdx, nullptr, mStaticBuffer->data, rowWidth, sliceWidth);
  399. if (device.hasError())
  400. {
  401. String errorDescription = device.getErrorDescription();
  402. CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription);
  403. }
  404. SAFE_DELETE(mStaticBuffer);
  405. }
  406. void D3D11Texture::_createStagingBuffer()
  407. {
  408. D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
  409. D3D11Device& device = rs->getPrimaryDevice();
  410. switch (getTextureType())
  411. {
  412. case TEX_TYPE_1D:
  413. {
  414. D3D11_TEXTURE1D_DESC desc;
  415. m1DTex->GetDesc(&desc);
  416. desc.BindFlags = 0;
  417. desc.MiscFlags = 0;
  418. desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
  419. desc.Usage = D3D11_USAGE_STAGING;
  420. device.getD3D11Device()->CreateTexture1D(&desc, NULL, (ID3D11Texture1D**)(&mStagingBuffer));
  421. }
  422. break;
  423. case TEX_TYPE_2D:
  424. case TEX_TYPE_CUBE_MAP:
  425. {
  426. D3D11_TEXTURE2D_DESC desc;
  427. m2DTex->GetDesc(&desc);
  428. desc.BindFlags = 0;
  429. desc.MiscFlags = 0;
  430. desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
  431. desc.Usage = D3D11_USAGE_STAGING;
  432. device.getD3D11Device()->CreateTexture2D(&desc, NULL, (ID3D11Texture2D**)(&mStagingBuffer));
  433. }
  434. break;
  435. case TEX_TYPE_3D:
  436. {
  437. D3D11_TEXTURE3D_DESC desc;
  438. m3DTex->GetDesc(&desc);
  439. desc.BindFlags = 0;
  440. desc.MiscFlags = 0;
  441. desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
  442. desc.Usage = D3D11_USAGE_STAGING;
  443. device.getD3D11Device()->CreateTexture3D(&desc, NULL, (ID3D11Texture3D**)(&mStagingBuffer));
  444. }
  445. break;
  446. }
  447. }
  448. }
  449. #undef THROW_IF_NOT_RENDER_THREAD