2 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
7 // TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
8 // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
10 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
11 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
12 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
13 #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
14 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
15 #include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
16 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
17 #include "libGLESv2/renderer/d3d/d3d11/Image11.h"
18 #include "libGLESv2/renderer/d3d/MemoryBuffer.h"
19 #include "libGLESv2/renderer/d3d/TextureD3D.h"
20 #include "libGLESv2/main.h"
21 #include "libGLESv2/ImageIndex.h"
23 #include "common/utilities.h"
28 TextureStorage11::SwizzleCacheValue::SwizzleCacheValue()
29 : swizzleRed(GL_NONE), swizzleGreen(GL_NONE), swizzleBlue(GL_NONE), swizzleAlpha(GL_NONE)
33 TextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha)
34 : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha)
38 bool TextureStorage11::SwizzleCacheValue::operator==(const SwizzleCacheValue &other) const
40 return swizzleRed == other.swizzleRed &&
41 swizzleGreen == other.swizzleGreen &&
42 swizzleBlue == other.swizzleBlue &&
43 swizzleAlpha == other.swizzleAlpha;
46 bool TextureStorage11::SwizzleCacheValue::operator!=(const SwizzleCacheValue &other) const
48 return !(*this == other);
51 TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle)
52 : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle)
56 bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const
58 return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle);
61 TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
62 : mBindFlags(bindFlags),
65 mTextureFormat(DXGI_FORMAT_UNKNOWN),
66 mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
67 mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
68 mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
73 mRenderer = Renderer11::makeRenderer11(renderer);
75 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
81 TextureStorage11::~TextureStorage11()
83 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
85 SafeRelease(mLevelSRVs[level]);
88 for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++)
90 SafeRelease(i->second);
95 TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
97 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
98 return static_cast<TextureStorage11*>(storage);
101 DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTarget)
105 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
106 if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
108 bindFlags |= D3D11_BIND_SHADER_RESOURCE;
110 if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
112 bindFlags |= D3D11_BIND_DEPTH_STENCIL;
114 if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget)
116 bindFlags |= D3D11_BIND_RENDER_TARGET;
122 UINT TextureStorage11::getBindFlags() const
127 int TextureStorage11::getTopLevel() const
132 bool TextureStorage11::isRenderTarget() const
134 return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
137 bool TextureStorage11::isManaged() const
142 int TextureStorage11::getLevelCount() const
144 return mMipLevels - mTopLevel;
147 int TextureStorage11::getLevelWidth(int mipLevel) const
149 return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
152 int TextureStorage11::getLevelHeight(int mipLevel) const
154 return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
157 int TextureStorage11::getLevelDepth(int mipLevel) const
159 return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
162 UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const
164 UINT mipSlice = static_cast<UINT>(index.mipIndex + mTopLevel);
165 UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0);
166 UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
167 ASSERT(subresource != std::numeric_limits<UINT>::max());
171 gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV)
173 bool swizzleRequired = samplerState.swizzleRequired();
174 bool mipmapping = gl::IsMipmapFiltered(samplerState);
175 unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1;
177 // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0)
178 mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - samplerState.baseLevel);
182 verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
185 SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
186 SRVCache::const_iterator iter = mSrvCache.find(key);
187 if (iter != mSrvCache.end())
189 *outSRV = iter->second;
193 ID3D11Resource *texture = NULL;
196 gl::Error error = getSwizzleTexture(&texture);
204 gl::Error error = getResource(&texture);
211 ID3D11ShaderResourceView *srv = NULL;
212 DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
213 gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv);
219 mSrvCache.insert(std::make_pair(key, srv));
223 return gl::Error(GL_NO_ERROR);
226 gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV)
228 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
230 if (!mLevelSRVs[mipLevel])
232 ID3D11Resource *resource = NULL;
233 gl::Error error = getResource(&resource);
239 error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]);
246 *outSRV = mLevelSRVs[mipLevel];
248 return gl::Error(GL_NO_ERROR);
251 gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
253 SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
254 for (int level = 0; level < getLevelCount(); level++)
256 // Check if the swizzle for this level is out of date
257 if (mSwizzleCache[level] != swizzleTarget)
259 // Need to re-render the swizzle for this level
260 ID3D11ShaderResourceView *sourceSRV = NULL;
261 gl::Error error = getSRVLevel(level, &sourceSRV);
267 ID3D11RenderTargetView *destRTV = NULL;
268 error = getSwizzleRenderTarget(level, &destRTV);
274 gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
276 Blit11 *blitter = mRenderer->getBlitter();
278 error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
284 mSwizzleCache[level] = swizzleTarget;
288 return gl::Error(GL_NO_ERROR);
291 void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel)
293 if (mipLevel >= 0 && static_cast<unsigned int>(mipLevel) < ArraySize(mSwizzleCache))
295 // The default constructor of SwizzleCacheValue has GL_NONE for all channels which is not a
296 // valid swizzle combination
297 mSwizzleCache[mipLevel] = SwizzleCacheValue();
301 void TextureStorage11::invalidateSwizzleCache()
303 for (unsigned int mipLevel = 0; mipLevel < ArraySize(mSwizzleCache); mipLevel++)
305 invalidateSwizzleCacheLevel(mipLevel);
309 gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
310 const gl::ImageIndex &index, const gl::Box ©Area)
314 GLint level = index.mipIndex;
316 invalidateSwizzleCacheLevel(level);
318 gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
320 bool fullCopy = copyArea.x == 0 &&
323 copyArea.width == texSize.width &&
324 copyArea.height == texSize.height &&
325 copyArea.depth == texSize.depth;
327 ID3D11Resource *dstTexture = NULL;
328 gl::Error error = getResource(&dstTexture);
334 unsigned int dstSubresource = getSubresourceIndex(index);
338 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
339 if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
341 // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
342 Blit11 *blitter = mRenderer->getBlitter();
344 return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
345 dstTexture, dstSubresource, copyArea, texSize,
350 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
353 srcBox.left = copyArea.x;
354 srcBox.top = copyArea.y;
355 srcBox.right = copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatInfo.blockWidth);
356 srcBox.bottom = copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatInfo.blockHeight);
357 srcBox.front = copyArea.z;
358 srcBox.back = copyArea.z + copyArea.depth;
360 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
362 context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
363 srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
364 return gl::Error(GL_NO_ERROR);
368 gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
369 const gl::ImageIndex &index, const gl::Box ®ion)
373 ID3D11Resource *srcTexture = NULL;
374 gl::Error error = getResource(&srcTexture);
382 unsigned int srcSubresource = getSubresourceIndex(index);
384 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
385 context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z,
386 srcTexture, srcSubresource, NULL);
388 return gl::Error(GL_NO_ERROR);
391 gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
393 ASSERT(sourceIndex.layerIndex == destIndex.layerIndex);
395 invalidateSwizzleCacheLevel(destIndex.mipIndex);
397 RenderTarget *source = NULL;
398 gl::Error error = getRenderTarget(sourceIndex, &source);
404 RenderTarget *dest = NULL;
405 error = getRenderTarget(destIndex, &dest);
411 ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView();
412 ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView();
414 gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
415 gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
417 gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
418 gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
420 Blit11 *blitter = mRenderer->getBlitter();
421 return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
422 gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
425 void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
427 SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
428 for (unsigned int level = 0; level < mMipLevels; level++)
430 ASSERT(mSwizzleCache[level] == swizzleTarget);
434 gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
438 ID3D11Resource *sourceResouce = NULL;
439 gl::Error error = getResource(&sourceResouce);
445 TextureStorage11 *dest11 = TextureStorage11::makeTextureStorage11(destStorage);
446 ID3D11Resource *destResource = NULL;
447 error = dest11->getResource(&destResource);
453 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
454 immediateContext->CopyResource(destResource, sourceResouce);
456 dest11->invalidateSwizzleCache();
458 return gl::Error(GL_NO_ERROR);
461 gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
462 const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
464 ID3D11Resource *resource = NULL;
465 gl::Error error = getResource(&resource);
472 UINT destSubresource = getSubresourceIndex(index);
474 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat());
476 bool fullUpdate = (destBox == NULL || *destBox == gl::Box(0, 0, 0, mTextureWidth, mTextureHeight, mTextureDepth));
477 ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
479 // TODO(jmadill): Handle compressed formats
480 // Compressed formats have different load syntax, so we'll have to handle them with slightly
481 // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
482 // with compressed formats in the calling logic.
483 ASSERT(!internalFormatInfo.compressed);
485 int width = destBox ? destBox->width : static_cast<int>(image->getWidth());
486 int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
487 int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
488 UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment);
489 UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment);
491 const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat());
492 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
494 size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
496 UINT bufferRowPitch = outputPixelSize * width;
497 UINT bufferDepthPitch = bufferRowPitch * height;
499 MemoryBuffer conversionBuffer;
500 if (!conversionBuffer.resize(bufferDepthPitch * depth))
502 return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
506 LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
507 loadFunction(width, height, depth,
508 pixelData, srcRowPitch, srcDepthPitch,
509 conversionBuffer.data(), bufferRowPitch, bufferDepthPitch);
511 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
517 D3D11_BOX destD3DBox;
518 destD3DBox.left = destBox->x;
519 destD3DBox.right = destBox->x + destBox->width;
520 destD3DBox.top = destBox->y;
521 destD3DBox.bottom = destBox->y + destBox->height;
522 destD3DBox.front = 0;
525 immediateContext->UpdateSubresource(resource, destSubresource,
526 &destD3DBox, conversionBuffer.data(),
527 bufferRowPitch, bufferDepthPitch);
531 immediateContext->UpdateSubresource(resource, destSubresource,
532 NULL, conversionBuffer.data(),
533 bufferRowPitch, bufferDepthPitch);
536 return gl::Error(GL_NO_ERROR);
539 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
540 : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
541 mTexture(swapchain->getOffscreenTexture()),
542 mSwizzleTexture(NULL)
546 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
548 mAssociatedImages[i] = NULL;
549 mRenderTarget[i] = NULL;
550 mSwizzleRenderTargets[i] = NULL;
553 D3D11_TEXTURE2D_DESC texDesc;
554 mTexture->GetDesc(&texDesc);
555 mMipLevels = texDesc.MipLevels;
556 mTextureFormat = texDesc.Format;
557 mTextureWidth = texDesc.Width;
558 mTextureHeight = texDesc.Height;
561 ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
562 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
563 srv->GetDesc(&srvDesc);
564 mShaderResourceFormat = srvDesc.Format;
566 ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget();
567 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
568 offscreenRTV->GetDesc(&rtvDesc);
569 mRenderTargetFormat = rtvDesc.Format;
571 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
572 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat);
573 mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
574 mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
575 mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
577 mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
579 initializeSerials(1, 1);
582 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
583 : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)),
585 mSwizzleTexture(NULL)
587 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
589 mAssociatedImages[i] = NULL;
590 mRenderTarget[i] = NULL;
591 mSwizzleRenderTargets[i] = NULL;
594 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
595 mTextureFormat = formatInfo.texFormat;
596 mShaderResourceFormat = formatInfo.srvFormat;
597 mDepthStencilFormat = formatInfo.dsvFormat;
598 mRenderTargetFormat = formatInfo.rtvFormat;
599 mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
600 mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
601 mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
603 d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
604 mMipLevels = mTopLevel + levels;
605 mTextureWidth = width;
606 mTextureHeight = height;
609 initializeSerials(getLevelCount(), 1);
612 TextureStorage11_2D::~TextureStorage11_2D()
614 for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
616 if (mAssociatedImages[i] != NULL)
618 bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this);
619 ASSERT(imageAssociationCorrect);
621 if (imageAssociationCorrect)
623 // We must let the Images recover their data before we delete it from the TextureStorage.
624 gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage();
627 // TODO: Find a way to report this back to the context
633 SafeRelease(mTexture);
634 SafeRelease(mSwizzleTexture);
636 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
638 SafeDelete(mRenderTarget[i]);
639 SafeRelease(mSwizzleRenderTargets[i]);
643 TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
645 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
646 return static_cast<TextureStorage11_2D*>(storage);
649 void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index)
651 GLint level = index.mipIndex;
653 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
655 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
657 mAssociatedImages[level] = image;
661 bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
663 GLint level = index.mipIndex;
665 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
667 // This validation check should never return false. It means the Image/TextureStorage association is broken.
668 bool retValue = (mAssociatedImages[level] == expectedImage);
676 // disassociateImage allows an Image to end its association with a Storage.
677 void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
679 GLint level = index.mipIndex;
681 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
683 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
685 ASSERT(mAssociatedImages[level] == expectedImage);
687 if (mAssociatedImages[level] == expectedImage)
689 mAssociatedImages[level] = NULL;
694 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
695 gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
697 GLint level = index.mipIndex;
699 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
701 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
703 // No need to let the old Image recover its data, if it is also the incoming Image.
704 if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage)
706 // Ensure that the Image is still associated with this TextureStorage. This should be true.
707 bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this);
708 ASSERT(imageAssociationCorrect);
710 if (imageAssociationCorrect)
712 // Force the image to recover from storage before its data is overwritten.
713 // This will reset mAssociatedImages[level] to NULL too.
714 gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
723 return gl::Error(GL_NO_ERROR);
726 gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
728 // if the width or height is not positive this should be treated as an incomplete texture
729 // we handle that here by skipping the d3d texture creation
730 if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
732 ASSERT(mMipLevels > 0);
734 ID3D11Device *device = mRenderer->getDevice();
736 D3D11_TEXTURE2D_DESC desc;
737 desc.Width = mTextureWidth; // Compressed texture size constraints?
738 desc.Height = mTextureHeight;
739 desc.MipLevels = mMipLevels;
741 desc.Format = mTextureFormat;
742 desc.SampleDesc.Count = 1;
743 desc.SampleDesc.Quality = 0;
744 desc.Usage = D3D11_USAGE_DEFAULT;
745 desc.BindFlags = getBindFlags();
746 desc.CPUAccessFlags = 0;
749 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
751 // this can happen from windows TDR
752 if (d3d11::isDeviceLostError(result))
754 mRenderer->notifyDeviceLost();
755 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
757 else if (FAILED(result))
759 ASSERT(result == E_OUTOFMEMORY);
760 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
764 *outResource = mTexture;
765 return gl::Error(GL_NO_ERROR);
768 gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
770 ASSERT(!index.hasLayer());
772 int level = index.mipIndex;
773 ASSERT(level >= 0 && level < getLevelCount());
775 if (!mRenderTarget[level])
777 ID3D11Resource *texture = NULL;
778 gl::Error error = getResource(&texture);
784 ID3D11ShaderResourceView *srv = NULL;
785 error = getSRVLevel(level, &srv);
791 if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
793 ID3D11Device *device = mRenderer->getDevice();
795 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
796 rtvDesc.Format = mRenderTargetFormat;
797 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
798 rtvDesc.Texture2D.MipSlice = mTopLevel + level;
800 ID3D11RenderTargetView *rtv;
801 HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
803 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
806 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
809 mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1);
811 // RenderTarget will take ownership of these resources
814 else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
816 ID3D11Device *device = mRenderer->getDevice();
818 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
819 dsvDesc.Format = mDepthStencilFormat;
820 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
821 dsvDesc.Texture2D.MipSlice = mTopLevel + level;
824 ID3D11DepthStencilView *dsv;
825 HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
827 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
830 return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
833 mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1);
835 // RenderTarget will take ownership of these resources
845 *outRT = mRenderTarget[level];
846 return gl::Error(GL_NO_ERROR);
849 gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
850 ID3D11ShaderResourceView **outSRV) const
854 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
855 srvDesc.Format = format;
856 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
857 srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
858 srvDesc.Texture2D.MipLevels = mipLevels;
860 ID3D11Device *device = mRenderer->getDevice();
861 HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
863 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
866 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
869 return gl::Error(GL_NO_ERROR);
872 gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture)
876 if (!mSwizzleTexture)
878 ID3D11Device *device = mRenderer->getDevice();
880 D3D11_TEXTURE2D_DESC desc;
881 desc.Width = mTextureWidth;
882 desc.Height = mTextureHeight;
883 desc.MipLevels = mMipLevels;
885 desc.Format = mSwizzleTextureFormat;
886 desc.SampleDesc.Count = 1;
887 desc.SampleDesc.Quality = 0;
888 desc.Usage = D3D11_USAGE_DEFAULT;
889 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
890 desc.CPUAccessFlags = 0;
893 HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
895 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
898 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
902 *outTexture = mSwizzleTexture;
903 return gl::Error(GL_NO_ERROR);
906 gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
908 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
911 if (!mSwizzleRenderTargets[mipLevel])
913 ID3D11Resource *swizzleTexture = NULL;
914 gl::Error error = getSwizzleTexture(&swizzleTexture);
920 ID3D11Device *device = mRenderer->getDevice();
922 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
923 rtvDesc.Format = mSwizzleRenderTargetFormat;
924 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
925 rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
927 HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
929 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
932 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
936 *outRTV = mSwizzleRenderTargets[mipLevel];
937 return gl::Error(GL_NO_ERROR);
940 TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
941 : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
944 mSwizzleTexture = NULL;
946 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
948 mSwizzleRenderTargets[level] = NULL;
949 for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
951 mAssociatedImages[face][level] = NULL;
952 mRenderTarget[face][level] = NULL;
956 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
957 mTextureFormat = formatInfo.texFormat;
958 mShaderResourceFormat = formatInfo.srvFormat;
959 mDepthStencilFormat = formatInfo.dsvFormat;
960 mRenderTargetFormat = formatInfo.rtvFormat;
961 mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
962 mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
963 mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
965 // adjust size if needed for compressed textures
967 d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
969 mMipLevels = mTopLevel + levels;
970 mTextureWidth = size;
971 mTextureHeight = size;
974 initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
977 TextureStorage11_Cube::~TextureStorage11_Cube()
979 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
981 for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
983 if (mAssociatedImages[face][level] != NULL)
985 bool imageAssociationCorrect = mAssociatedImages[face][level]->isAssociatedStorageValid(this);
986 ASSERT(imageAssociationCorrect);
988 if (imageAssociationCorrect)
990 // We must let the Images recover their data before we delete it from the TextureStorage.
991 mAssociatedImages[face][level]->recoverFromAssociatedStorage();
997 SafeRelease(mTexture);
998 SafeRelease(mSwizzleTexture);
1000 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1002 SafeRelease(mSwizzleRenderTargets[level]);
1003 for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
1005 SafeDelete(mRenderTarget[face][level]);
1010 TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
1012 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
1013 return static_cast<TextureStorage11_Cube*>(storage);
1016 void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index)
1018 GLint level = index.mipIndex;
1019 GLint layerTarget = index.layerIndex;
1021 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1022 ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
1024 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1026 if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
1028 mAssociatedImages[layerTarget][level] = image;
1033 bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
1035 GLint level = index.mipIndex;
1036 GLint layerTarget = index.layerIndex;
1038 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1040 if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
1042 // This validation check should never return false. It means the Image/TextureStorage association is broken.
1043 bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage);
1052 // disassociateImage allows an Image to end its association with a Storage.
1053 void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
1055 GLint level = index.mipIndex;
1056 GLint layerTarget = index.layerIndex;
1058 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1059 ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
1061 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1063 if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
1065 ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
1067 if (mAssociatedImages[layerTarget][level] == expectedImage)
1069 mAssociatedImages[layerTarget][level] = NULL;
1075 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
1076 gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
1078 GLint level = index.mipIndex;
1079 GLint layerTarget = index.layerIndex;
1081 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1082 ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
1084 if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
1086 if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
1088 // No need to let the old Image recover its data, if it is also the incoming Image.
1089 if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage)
1091 // Ensure that the Image is still associated with this TextureStorage. This should be true.
1092 bool imageAssociationCorrect = mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this);
1093 ASSERT(imageAssociationCorrect);
1095 if (imageAssociationCorrect)
1097 // Force the image to recover from storage before its data is overwritten.
1098 // This will reset mAssociatedImages[level] to NULL too.
1099 gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
1100 if (error.isError())
1109 return gl::Error(GL_NO_ERROR);
1112 gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
1114 // if the size is not positive this should be treated as an incomplete texture
1115 // we handle that here by skipping the d3d texture creation
1116 if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
1118 ASSERT(mMipLevels > 0);
1120 ID3D11Device *device = mRenderer->getDevice();
1122 D3D11_TEXTURE2D_DESC desc;
1123 desc.Width = mTextureWidth;
1124 desc.Height = mTextureHeight;
1125 desc.MipLevels = mMipLevels;
1126 desc.ArraySize = CUBE_FACE_COUNT;
1127 desc.Format = mTextureFormat;
1128 desc.SampleDesc.Count = 1;
1129 desc.SampleDesc.Quality = 0;
1130 desc.Usage = D3D11_USAGE_DEFAULT;
1131 desc.BindFlags = getBindFlags();
1132 desc.CPUAccessFlags = 0;
1133 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
1135 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
1137 // this can happen from windows TDR
1138 if (d3d11::isDeviceLostError(result))
1140 mRenderer->notifyDeviceLost();
1141 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
1143 else if (FAILED(result))
1145 ASSERT(result == E_OUTOFMEMORY);
1146 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
1150 *outResource = mTexture;
1151 return gl::Error(GL_NO_ERROR);
1154 gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
1156 int faceIndex = index.layerIndex;
1157 int level = index.mipIndex;
1159 ASSERT(level >= 0 && level < getLevelCount());
1160 ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT);
1162 if (!mRenderTarget[faceIndex][level])
1164 ID3D11Device *device = mRenderer->getDevice();
1167 ID3D11Resource *texture = NULL;
1168 gl::Error error = getResource(&texture);
1169 if (error.isError())
1174 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1175 srvDesc.Format = mShaderResourceFormat;
1176 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
1177 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
1178 srvDesc.Texture2DArray.MipLevels = 1;
1179 srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
1180 srvDesc.Texture2DArray.ArraySize = 1;
1182 ID3D11ShaderResourceView *srv;
1183 result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
1185 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1188 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
1191 if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1193 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1194 rtvDesc.Format = mRenderTargetFormat;
1195 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1196 rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
1197 rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
1198 rtvDesc.Texture2DArray.ArraySize = 1;
1200 ID3D11RenderTargetView *rtv;
1201 result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
1203 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1207 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
1210 mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1);
1212 // RenderTarget will take ownership of these resources
1216 else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
1218 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
1219 dsvDesc.Format = mDepthStencilFormat;
1220 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
1222 dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
1223 dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
1224 dsvDesc.Texture2DArray.ArraySize = 1;
1226 ID3D11DepthStencilView *dsv;
1227 result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
1229 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1233 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
1236 mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1);
1238 // RenderTarget will take ownership of these resources
1249 *outRT = mRenderTarget[faceIndex][level];
1250 return gl::Error(GL_NO_ERROR);
1253 gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
1254 ID3D11ShaderResourceView **outSRV) const
1258 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1259 srvDesc.Format = format;
1261 // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures
1262 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
1263 if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT)
1265 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1266 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
1267 srvDesc.Texture2DArray.MipLevels = 1;
1268 srvDesc.Texture2DArray.FirstArraySlice = 0;
1269 srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
1273 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
1274 srvDesc.TextureCube.MipLevels = mipLevels;
1275 srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
1278 ID3D11Device *device = mRenderer->getDevice();
1279 HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
1281 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1284 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
1287 return gl::Error(GL_NO_ERROR);
1290 gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture)
1294 if (!mSwizzleTexture)
1296 ID3D11Device *device = mRenderer->getDevice();
1298 D3D11_TEXTURE2D_DESC desc;
1299 desc.Width = mTextureWidth;
1300 desc.Height = mTextureHeight;
1301 desc.MipLevels = mMipLevels;
1302 desc.ArraySize = CUBE_FACE_COUNT;
1303 desc.Format = mSwizzleTextureFormat;
1304 desc.SampleDesc.Count = 1;
1305 desc.SampleDesc.Quality = 0;
1306 desc.Usage = D3D11_USAGE_DEFAULT;
1307 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1308 desc.CPUAccessFlags = 0;
1309 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
1311 HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
1313 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1316 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
1320 *outTexture = mSwizzleTexture;
1321 return gl::Error(GL_NO_ERROR);
1324 gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
1326 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1329 if (!mSwizzleRenderTargets[mipLevel])
1331 ID3D11Resource *swizzleTexture = NULL;
1332 gl::Error error = getSwizzleTexture(&swizzleTexture);
1333 if (error.isError())
1338 ID3D11Device *device = mRenderer->getDevice();
1340 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1341 rtvDesc.Format = mSwizzleRenderTargetFormat;
1342 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1343 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
1344 rtvDesc.Texture2DArray.FirstArraySlice = 0;
1345 rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
1347 HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1349 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1352 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
1356 *outRTV = mSwizzleRenderTargets[mipLevel];
1357 return gl::Error(GL_NO_ERROR);
1360 TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
1361 GLsizei width, GLsizei height, GLsizei depth, int levels)
1362 : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
1365 mSwizzleTexture = NULL;
1367 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1369 mAssociatedImages[i] = NULL;
1370 mLevelRenderTargets[i] = NULL;
1371 mSwizzleRenderTargets[i] = NULL;
1374 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
1375 mTextureFormat = formatInfo.texFormat;
1376 mShaderResourceFormat = formatInfo.srvFormat;
1377 mDepthStencilFormat = formatInfo.dsvFormat;
1378 mRenderTargetFormat = formatInfo.rtvFormat;
1379 mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
1380 mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
1381 mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
1383 // adjust size if needed for compressed textures
1384 d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
1386 mMipLevels = mTopLevel + levels;
1387 mTextureWidth = width;
1388 mTextureHeight = height;
1389 mTextureDepth = depth;
1391 initializeSerials(getLevelCount() * depth, depth);
1394 TextureStorage11_3D::~TextureStorage11_3D()
1396 for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1398 if (mAssociatedImages[i] != NULL)
1400 bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this);
1401 ASSERT(imageAssociationCorrect);
1403 if (imageAssociationCorrect)
1405 // We must let the Images recover their data before we delete it from the TextureStorage.
1406 mAssociatedImages[i]->recoverFromAssociatedStorage();
1411 SafeRelease(mTexture);
1412 SafeRelease(mSwizzleTexture);
1414 for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++)
1416 SafeDelete(i->second);
1418 mLevelLayerRenderTargets.clear();
1420 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1422 SafeDelete(mLevelRenderTargets[i]);
1423 SafeRelease(mSwizzleRenderTargets[i]);
1427 TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage *storage)
1429 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_3D*, storage));
1430 return static_cast<TextureStorage11_3D*>(storage);
1433 void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index)
1435 GLint level = index.mipIndex;
1437 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1439 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1441 mAssociatedImages[level] = image;
1445 bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
1447 GLint level = index.mipIndex;
1449 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1451 // This validation check should never return false. It means the Image/TextureStorage association is broken.
1452 bool retValue = (mAssociatedImages[level] == expectedImage);
1460 // disassociateImage allows an Image to end its association with a Storage.
1461 void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
1463 GLint level = index.mipIndex;
1465 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1467 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1469 ASSERT(mAssociatedImages[level] == expectedImage);
1471 if (mAssociatedImages[level] == expectedImage)
1473 mAssociatedImages[level] = NULL;
1478 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
1479 gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
1481 GLint level = index.mipIndex;
1483 ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
1485 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1487 // No need to let the old Image recover its data, if it is also the incoming Image.
1488 if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage)
1490 // Ensure that the Image is still associated with this TextureStorage. This should be true.
1491 bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this);
1492 ASSERT(imageAssociationCorrect);
1494 if (imageAssociationCorrect)
1496 // Force the image to recover from storage before its data is overwritten.
1497 // This will reset mAssociatedImages[level] to NULL too.
1498 gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
1499 if (error.isError())
1507 return gl::Error(GL_NO_ERROR);
1510 gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource)
1512 // If the width, height or depth are not positive this should be treated as an incomplete texture
1513 // we handle that here by skipping the d3d texture creation
1514 if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
1516 ASSERT(mMipLevels > 0);
1518 ID3D11Device *device = mRenderer->getDevice();
1520 D3D11_TEXTURE3D_DESC desc;
1521 desc.Width = mTextureWidth;
1522 desc.Height = mTextureHeight;
1523 desc.Depth = mTextureDepth;
1524 desc.MipLevels = mMipLevels;
1525 desc.Format = mTextureFormat;
1526 desc.Usage = D3D11_USAGE_DEFAULT;
1527 desc.BindFlags = getBindFlags();
1528 desc.CPUAccessFlags = 0;
1531 HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
1533 // this can happen from windows TDR
1534 if (d3d11::isDeviceLostError(result))
1536 mRenderer->notifyDeviceLost();
1537 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
1539 else if (FAILED(result))
1541 ASSERT(result == E_OUTOFMEMORY);
1542 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
1546 *outResource = mTexture;
1547 return gl::Error(GL_NO_ERROR);
1550 gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
1551 ID3D11ShaderResourceView **outSRV) const
1555 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1556 srvDesc.Format = format;
1557 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
1558 srvDesc.Texture3D.MostDetailedMip = baseLevel;
1559 srvDesc.Texture3D.MipLevels = mipLevels;
1561 ID3D11Device *device = mRenderer->getDevice();
1562 HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
1564 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1567 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
1570 return gl::Error(GL_NO_ERROR);
1573 gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
1575 int mipLevel = index.mipIndex;
1576 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1578 ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
1580 if (!index.hasLayer())
1582 if (!mLevelRenderTargets[mipLevel])
1584 ID3D11Resource *texture = NULL;
1585 gl::Error error = getResource(&texture);
1586 if (error.isError())
1591 ID3D11ShaderResourceView *srv = NULL;
1592 error = getSRVLevel(mipLevel, &srv);
1593 if (error.isError())
1598 ID3D11Device *device = mRenderer->getDevice();
1600 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1601 rtvDesc.Format = mRenderTargetFormat;
1602 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1603 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1604 rtvDesc.Texture3D.FirstWSlice = 0;
1605 rtvDesc.Texture3D.WSize = -1;
1607 ID3D11RenderTargetView *rtv;
1608 HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
1610 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1614 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
1617 mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
1619 // RenderTarget will take ownership of these resources
1624 *outRT = mLevelRenderTargets[mipLevel];
1625 return gl::Error(GL_NO_ERROR);
1629 int layer = index.layerIndex;
1631 LevelLayerKey key(mipLevel, layer);
1632 if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
1634 ID3D11Device *device = mRenderer->getDevice();
1637 ID3D11Resource *texture = NULL;
1638 gl::Error error = getResource(&texture);
1639 if (error.isError())
1644 // TODO, what kind of SRV is expected here?
1645 ID3D11ShaderResourceView *srv = NULL;
1647 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1648 rtvDesc.Format = mRenderTargetFormat;
1649 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1650 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1651 rtvDesc.Texture3D.FirstWSlice = layer;
1652 rtvDesc.Texture3D.WSize = 1;
1654 ID3D11RenderTargetView *rtv;
1655 result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
1657 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1660 SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
1662 ASSERT(SUCCEEDED(result));
1664 mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
1666 // RenderTarget will take ownership of these resources
1671 *outRT = mLevelLayerRenderTargets[key];
1672 return gl::Error(GL_NO_ERROR);
1676 gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture)
1680 if (!mSwizzleTexture)
1682 ID3D11Device *device = mRenderer->getDevice();
1684 D3D11_TEXTURE3D_DESC desc;
1685 desc.Width = mTextureWidth;
1686 desc.Height = mTextureHeight;
1687 desc.Depth = mTextureDepth;
1688 desc.MipLevels = mMipLevels;
1689 desc.Format = mSwizzleTextureFormat;
1690 desc.Usage = D3D11_USAGE_DEFAULT;
1691 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1692 desc.CPUAccessFlags = 0;
1695 HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture);
1697 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1700 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
1704 *outTexture = mSwizzleTexture;
1705 return gl::Error(GL_NO_ERROR);
1708 gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
1710 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1713 if (!mSwizzleRenderTargets[mipLevel])
1715 ID3D11Resource *swizzleTexture = NULL;
1716 gl::Error error = getSwizzleTexture(&swizzleTexture);
1717 if (error.isError())
1722 ID3D11Device *device = mRenderer->getDevice();
1724 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1725 rtvDesc.Format = mSwizzleRenderTargetFormat;
1726 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1727 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1728 rtvDesc.Texture3D.FirstWSlice = 0;
1729 rtvDesc.Texture3D.WSize = -1;
1731 HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1733 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1736 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
1740 *outRTV = mSwizzleRenderTargets[mipLevel];
1741 return gl::Error(GL_NO_ERROR);
1744 TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
1745 GLsizei width, GLsizei height, GLsizei depth, int levels)
1746 : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
1749 mSwizzleTexture = NULL;
1751 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1753 mSwizzleRenderTargets[level] = NULL;
1756 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
1757 mTextureFormat = formatInfo.texFormat;
1758 mShaderResourceFormat = formatInfo.srvFormat;
1759 mDepthStencilFormat = formatInfo.dsvFormat;
1760 mRenderTargetFormat = formatInfo.rtvFormat;
1761 mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
1762 mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
1763 mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
1765 // adjust size if needed for compressed textures
1766 d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
1768 mMipLevels = mTopLevel + levels;
1769 mTextureWidth = width;
1770 mTextureHeight = height;
1771 mTextureDepth = depth;
1773 initializeSerials(getLevelCount() * depth, depth);
1776 TextureStorage11_2DArray::~TextureStorage11_2DArray()
1778 for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++)
1780 bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this);
1781 ASSERT(imageAssociationCorrect);
1783 if (imageAssociationCorrect)
1785 // We must let the Images recover their data before we delete it from the TextureStorage.
1786 i->second->recoverFromAssociatedStorage();
1789 mAssociatedImages.clear();
1791 SafeRelease(mTexture);
1792 SafeRelease(mSwizzleTexture);
1794 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1796 SafeRelease(mSwizzleRenderTargets[level]);
1799 for (RenderTargetMap::iterator i = mRenderTargets.begin(); i != mRenderTargets.end(); i++)
1801 SafeDelete(i->second);
1803 mRenderTargets.clear();
1806 TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray(TextureStorage *storage)
1808 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2DArray*, storage));
1809 return static_cast<TextureStorage11_2DArray*>(storage);
1812 void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index)
1814 GLint level = index.mipIndex;
1815 GLint layerTarget = index.layerIndex;
1817 ASSERT(0 <= level && level < getLevelCount());
1819 if (0 <= level && level < getLevelCount())
1821 LevelLayerKey key(level, layerTarget);
1822 mAssociatedImages[key] = image;
1826 bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
1828 GLint level = index.mipIndex;
1829 GLint layerTarget = index.layerIndex;
1831 LevelLayerKey key(level, layerTarget);
1833 // This validation check should never return false. It means the Image/TextureStorage association is broken.
1834 bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
1839 // disassociateImage allows an Image to end its association with a Storage.
1840 void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
1842 GLint level = index.mipIndex;
1843 GLint layerTarget = index.layerIndex;
1845 LevelLayerKey key(level, layerTarget);
1847 bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
1848 ASSERT(imageAssociationCorrect);
1850 if (imageAssociationCorrect)
1852 mAssociatedImages[key] = NULL;
1856 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
1857 gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
1859 GLint level = index.mipIndex;
1860 GLint layerTarget = index.layerIndex;
1862 LevelLayerKey key(level, layerTarget);
1864 ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
1866 if (mAssociatedImages.find(key) != mAssociatedImages.end())
1868 if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage)
1870 // Ensure that the Image is still associated with this TextureStorage. This should be true.
1871 bool imageAssociationCorrect = mAssociatedImages[key]->isAssociatedStorageValid(this);
1872 ASSERT(imageAssociationCorrect);
1874 if (imageAssociationCorrect)
1876 // Force the image to recover from storage before its data is overwritten.
1877 // This will reset mAssociatedImages[level] to NULL too.
1878 gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage();
1879 if (error.isError())
1887 return gl::Error(GL_NO_ERROR);
1890 gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource)
1892 // if the width, height or depth is not positive this should be treated as an incomplete texture
1893 // we handle that here by skipping the d3d texture creation
1894 if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
1896 ASSERT(mMipLevels > 0);
1898 ID3D11Device *device = mRenderer->getDevice();
1900 D3D11_TEXTURE2D_DESC desc;
1901 desc.Width = mTextureWidth;
1902 desc.Height = mTextureHeight;
1903 desc.MipLevels = mMipLevels;
1904 desc.ArraySize = mTextureDepth;
1905 desc.Format = mTextureFormat;
1906 desc.SampleDesc.Count = 1;
1907 desc.SampleDesc.Quality = 0;
1908 desc.Usage = D3D11_USAGE_DEFAULT;
1909 desc.BindFlags = getBindFlags();
1910 desc.CPUAccessFlags = 0;
1913 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
1915 // this can happen from windows TDR
1916 if (d3d11::isDeviceLostError(result))
1918 mRenderer->notifyDeviceLost();
1919 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
1921 else if (FAILED(result))
1923 ASSERT(result == E_OUTOFMEMORY);
1924 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
1928 *outResource = mTexture;
1929 return gl::Error(GL_NO_ERROR);
1932 gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
1933 ID3D11ShaderResourceView **outSRV) const
1935 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1936 srvDesc.Format = format;
1937 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1938 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
1939 srvDesc.Texture2DArray.MipLevels = mipLevels;
1940 srvDesc.Texture2DArray.FirstArraySlice = 0;
1941 srvDesc.Texture2DArray.ArraySize = mTextureDepth;
1943 ID3D11Device *device = mRenderer->getDevice();
1944 HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
1946 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1949 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
1952 return gl::Error(GL_NO_ERROR);
1955 gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
1957 ASSERT(index.hasLayer());
1959 int mipLevel = index.mipIndex;
1960 int layer = index.layerIndex;
1962 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1964 LevelLayerKey key(mipLevel, layer);
1965 if (mRenderTargets.find(key) == mRenderTargets.end())
1967 ID3D11Device *device = mRenderer->getDevice();
1970 ID3D11Resource *texture = NULL;
1971 gl::Error error = getResource(&texture);
1972 if (error.isError())
1977 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1978 srvDesc.Format = mShaderResourceFormat;
1979 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1980 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
1981 srvDesc.Texture2DArray.MipLevels = 1;
1982 srvDesc.Texture2DArray.FirstArraySlice = layer;
1983 srvDesc.Texture2DArray.ArraySize = 1;
1985 ID3D11ShaderResourceView *srv;
1986 result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
1988 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1991 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
1994 if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1996 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1997 rtvDesc.Format = mRenderTargetFormat;
1998 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1999 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
2000 rtvDesc.Texture2DArray.FirstArraySlice = layer;
2001 rtvDesc.Texture2DArray.ArraySize = 1;
2003 ID3D11RenderTargetView *rtv;
2004 result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
2006 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
2010 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
2013 mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
2015 // RenderTarget will take ownership of these resources
2026 *outRT = mRenderTargets[key];
2027 return gl::Error(GL_NO_ERROR);
2030 gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture)
2032 if (!mSwizzleTexture)
2034 ID3D11Device *device = mRenderer->getDevice();
2036 D3D11_TEXTURE2D_DESC desc;
2037 desc.Width = mTextureWidth;
2038 desc.Height = mTextureHeight;
2039 desc.MipLevels = mMipLevels;
2040 desc.ArraySize = mTextureDepth;
2041 desc.Format = mSwizzleTextureFormat;
2042 desc.SampleDesc.Count = 1;
2043 desc.SampleDesc.Quality = 0;
2044 desc.Usage = D3D11_USAGE_DEFAULT;
2045 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
2046 desc.CPUAccessFlags = 0;
2049 HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
2051 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
2054 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
2058 *outTexture = mSwizzleTexture;
2059 return gl::Error(GL_NO_ERROR);
2062 gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
2064 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
2067 if (!mSwizzleRenderTargets[mipLevel])
2069 ID3D11Resource *swizzleTexture = NULL;
2070 gl::Error error = getSwizzleTexture(&swizzleTexture);
2071 if (error.isError())
2076 ID3D11Device *device = mRenderer->getDevice();
2078 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
2079 rtvDesc.Format = mSwizzleRenderTargetFormat;
2080 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
2081 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
2082 rtvDesc.Texture2DArray.FirstArraySlice = 0;
2083 rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
2085 HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
2087 ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
2090 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
2094 *outRTV = mSwizzleRenderTargets[mipLevel];
2095 return gl::Error(GL_NO_ERROR);