summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp1817
1 files changed, 996 insertions, 821 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
index 91e7147da6..74af27e8b3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -8,6 +8,9 @@
// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
+
+#include <tuple>
+
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
@@ -15,6 +18,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
+#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
#include "libGLESv2/main.h"
#include "libGLESv2/ImageIndex.h"
@@ -52,46 +56,16 @@ TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle)
{
}
-bool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const
-{
- return baseLevel == rhs.baseLevel &&
- mipLevels == rhs.mipLevels &&
- swizzle == rhs.swizzle;
-}
-
-TextureStorage11::SRVCache::~SRVCache()
+bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const
{
- for (size_t i = 0; i < cache.size(); i++)
- {
- SafeRelease(cache[i].srv);
- }
+ return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle);
}
-ID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const
-{
- for (size_t i = 0; i < cache.size(); i++)
- {
- if (cache[i].key == key)
- {
- return cache[i].srv;
- }
- }
-
- return NULL;
-}
-
-ID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv)
-{
- SRVPair pair = {key, srv};
- cache.push_back(pair);
-
- return srv;
-}
-
-TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
+TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags)
: mBindFlags(bindFlags),
mTopLevel(0),
mMipLevels(0),
+ mInternalFormat(GL_NONE),
mTextureFormat(DXGI_FORMAT_UNKNOWN),
mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
@@ -114,6 +88,12 @@ TextureStorage11::~TextureStorage11()
{
SafeRelease(mLevelSRVs[level]);
}
+
+ for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++)
+ {
+ SafeRelease(i->second);
+ }
+ mSrvCache.clear();
}
TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
@@ -183,17 +163,16 @@ int TextureStorage11::getLevelDepth(int mipLevel) const
return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
}
-UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const
+UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const
{
- UINT index = 0;
- if (getResource())
- {
- index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels);
- }
- return index;
+ UINT mipSlice = static_cast<UINT>(index.mipIndex + mTopLevel);
+ UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0);
+ UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
+ ASSERT(subresource != std::numeric_limits<UINT>::max());
+ return subresource;
}
-ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
+gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV)
{
bool swizzleRequired = samplerState.swizzleRequired();
bool mipmapping = gl::IsMipmapFiltered(samplerState);
@@ -206,38 +185,71 @@ ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &sampl
{
verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
}
-
- SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
- ID3D11ShaderResourceView *srv = srvCache.find(key);
- if(srv)
+ SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
+ SRVCache::const_iterator iter = mSrvCache.find(key);
+ if (iter != mSrvCache.end())
{
- return srv;
+ *outSRV = iter->second;
}
+ else
+ {
+ ID3D11Resource *texture = NULL;
+ if (swizzleRequired)
+ {
+ gl::Error error = getSwizzleTexture(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
- DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
- ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource();
+ ID3D11ShaderResourceView *srv = NULL;
+ DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
+ gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mSrvCache.insert(std::make_pair(key, srv));
+ *outSRV = srv;
+ }
- srv = createSRV(samplerState.baseLevel, mipLevels, format, texture);
-
- return srvCache.add(key, srv);
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel)
+gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ if (!mLevelSRVs[mipLevel])
{
- if (!mLevelSRVs[mipLevel])
+ ID3D11Resource *resource = NULL;
+ gl::Error error = getResource(&resource);
+ if (error.isError())
{
- mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource());
+ return error;
}
- return mLevelSRVs[mipLevel];
- }
- else
- {
- return NULL;
+ error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ *outSRV = mLevelSRVs[mipLevel];
+
+ return gl::Error(GL_NO_ERROR);
}
gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
@@ -249,14 +261,25 @@ gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGr
if (mSwizzleCache[level] != swizzleTarget)
{
// Need to re-render the swizzle for this level
- ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level);
- ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level);
+ ID3D11ShaderResourceView *sourceSRV = NULL;
+ gl::Error error = getSRVLevel(level, &sourceSRV);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11RenderTargetView *destRTV = NULL;
+ error = getSwizzleRenderTarget(level, &destRTV);
+ if (error.isError())
+ {
+ return error;
+ }
gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
Blit11 *blitter = mRenderer->getBlitter();
- gl::Error error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
+ error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
if (error.isError())
{
return error;
@@ -287,104 +310,120 @@ void TextureStorage11::invalidateSwizzleCache()
}
}
-bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
- int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
+ const gl::ImageIndex &index, const gl::Box &copyArea)
{
- if (srcTexture)
- {
- invalidateSwizzleCacheLevel(level);
+ ASSERT(srcTexture);
- gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
- gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth);
+ GLint level = index.mipIndex;
- bool fullCopy = copyArea.x == 0 &&
- copyArea.y == 0 &&
- copyArea.z == 0 &&
- copyArea.width == texSize.width &&
- copyArea.height == texSize.height &&
- copyArea.depth == texSize.depth;
+ invalidateSwizzleCacheLevel(level);
- ID3D11Resource *dstTexture = getResource();
- unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
+ gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
- ASSERT(dstTexture);
+ bool fullCopy = copyArea.x == 0 &&
+ copyArea.y == 0 &&
+ copyArea.z == 0 &&
+ copyArea.width == texSize.width &&
+ copyArea.height == texSize.height &&
+ copyArea.depth == texSize.depth;
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
- if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
- {
- // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
- Blit11 *blitter = mRenderer->getBlitter();
+ ID3D11Resource *dstTexture = NULL;
+ gl::Error error = getResource(&dstTexture);
+ if (error.isError())
+ {
+ return error;
+ }
- return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
- dstTexture, dstSubresource, copyArea, texSize,
- NULL);
- }
- else
- {
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+ unsigned int dstSubresource = getSubresourceIndex(index);
- D3D11_BOX srcBox;
- srcBox.left = copyArea.x;
- srcBox.top = copyArea.y;
- srcBox.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth);
- srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight);
- srcBox.front = copyArea.z;
- srcBox.back = copyArea.z + copyArea.depth;
+ ASSERT(dstTexture);
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+ if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
+ {
+ // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
+ Blit11 *blitter = mRenderer->getBlitter();
- context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
- srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
- return true;
- }
+ return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
+ dstTexture, dstSubresource, copyArea, texSize,
+ NULL);
}
+ else
+ {
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
- return false;
+ D3D11_BOX srcBox;
+ srcBox.left = copyArea.x;
+ srcBox.top = copyArea.y;
+ srcBox.right = copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatInfo.blockWidth);
+ srcBox.bottom = copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatInfo.blockHeight);
+ srcBox.front = copyArea.z;
+ srcBox.back = copyArea.z + copyArea.depth;
+
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
+ srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
+ return gl::Error(GL_NO_ERROR);
+ }
}
-bool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
- int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
+ const gl::ImageIndex &index, const gl::Box &region)
{
- if (dstTexture)
+ ASSERT(dstTexture);
+
+ ID3D11Resource *srcTexture = NULL;
+ gl::Error error = getResource(&srcTexture);
+ if (error.isError())
{
- ID3D11Resource *srcTexture = getResource();
- unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
+ return error;
+ }
- ASSERT(srcTexture);
+ ASSERT(srcTexture);
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ unsigned int srcSubresource = getSubresourceIndex(index);
- context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset,
- srcTexture, srcSubresource, NULL);
- return true;
- }
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z,
+ srcTexture, srcSubresource, NULL);
- return false;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
+gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- if (source && dest)
+ ASSERT(sourceIndex.layerIndex == destIndex.layerIndex);
+
+ invalidateSwizzleCacheLevel(destIndex.mipIndex);
+
+ RenderTarget *source = NULL;
+ gl::Error error = getRenderTarget(sourceIndex, &source);
+ if (error.isError())
{
- ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
- ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
+ return error;
+ }
- if (sourceSRV && destRTV)
- {
- gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
- gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
+ RenderTarget *dest = NULL;
+ error = getRenderTarget(destIndex, &dest);
+ if (error.isError())
+ {
+ return error;
+ }
- gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
- gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
+ ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView();
+ ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView();
- Blit11 *blitter = mRenderer->getBlitter();
+ gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
+ gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
- blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
- gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
- }
- }
+ gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
+ gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
+
+ Blit11 *blitter = mRenderer->getBlitter();
+ return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
+ gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
}
void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
@@ -396,7 +435,112 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree
}
}
-TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
+gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ ID3D11Resource *sourceResouce = NULL;
+ gl::Error error = getResource(&sourceResouce);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ TextureStorage11 *dest11 = TextureStorage11::makeTextureStorage11(destStorage);
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource, sourceResouce);
+
+ dest11->invalidateSwizzleCache();
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
+{
+ ID3D11Resource *resource = NULL;
+ gl::Error error = getResource(&resource);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(resource);
+
+ UINT destSubresource = getSubresourceIndex(index);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat());
+
+ bool fullUpdate = (destBox == NULL || *destBox == gl::Box(0, 0, 0, mTextureWidth, mTextureHeight, mTextureDepth));
+ ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
+
+ // TODO(jmadill): Handle compressed formats
+ // Compressed formats have different load syntax, so we'll have to handle them with slightly
+ // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
+ // with compressed formats in the calling logic.
+ ASSERT(!internalFormatInfo.compressed);
+
+ int width = destBox ? destBox->width : static_cast<int>(image->getWidth());
+ int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
+ int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
+ UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment);
+ UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment);
+
+ const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat());
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
+
+ size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
+
+ UINT bufferRowPitch = outputPixelSize * width;
+ UINT bufferDepthPitch = bufferRowPitch * height;
+
+ MemoryBuffer conversionBuffer;
+ if (!conversionBuffer.resize(bufferDepthPitch * depth))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
+ }
+
+ // TODO: fast path
+ LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
+ loadFunction(width, height, depth,
+ pixelData, srcRowPitch, srcDepthPitch,
+ conversionBuffer.data(), bufferRowPitch, bufferDepthPitch);
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+
+ if (!fullUpdate)
+ {
+ ASSERT(destBox);
+
+ D3D11_BOX destD3DBox;
+ destD3DBox.left = destBox->x;
+ destD3DBox.right = destBox->x + destBox->width;
+ destD3DBox.top = destBox->y;
+ destD3DBox.bottom = destBox->y + destBox->height;
+ destD3DBox.front = 0;
+ destD3DBox.back = 1;
+
+ immediateContext->UpdateSubresource(resource, destSubresource,
+ &destD3DBox, conversionBuffer.data(),
+ bufferRowPitch, bufferDepthPitch);
+ }
+ else
+ {
+ immediateContext->UpdateSubresource(resource, destSubresource,
+ NULL, conversionBuffer.data(),
+ bufferRowPitch, bufferDepthPitch);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain)
: TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
mTexture(swapchain->getOffscreenTexture()),
mSwizzleTexture(NULL)
@@ -418,6 +562,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
mTextureHeight = texDesc.Height;
mTextureDepth = 1;
+ mInternalFormat = swapchain->GetBackBufferInternalFormat();
+
ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srv->GetDesc(&srvDesc);
@@ -439,7 +585,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
initializeSerials(1, 1);
}
-TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)),
mTexture(NULL),
mSwizzleTexture(NULL)
@@ -451,6 +597,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform
mSwizzleRenderTargets[i] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -460,51 +608,11 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the width or height is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width; // Compressed texture size constraints?
- desc.Height = height;
- desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = 1;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = 1;
- }
- }
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = 1;
initializeSerials(getLevelCount(), 1);
}
@@ -521,7 +629,11 @@ TextureStorage11_2D::~TextureStorage11_2D()
if (imageAssociationCorrect)
{
// We must let the Images recover their data before we delete it from the TextureStorage.
- mAssociatedImages[i]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ // TODO: Find a way to report this back to the context
+ }
}
}
}
@@ -542,8 +654,10 @@ TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage
return static_cast<TextureStorage11_2D*>(storage);
}
-void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -552,8 +666,10 @@ void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTar
}
}
-bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -566,8 +682,10 @@ bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Ima
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -582,8 +700,10 @@ void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11*
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -599,137 +719,168 @@ void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Ima
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2D::getResource() const
+gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth; // Compressed texture size constraints?
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels;
+ desc.ArraySize = 1;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(!index.hasLayer());
int level = index.mipIndex;
+ ASSERT(level >= 0 && level < getLevelCount());
- if (level >= 0 && level < getLevelCount())
+ if (!mRenderTarget[level])
{
- if (!mRenderTarget[level])
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
{
- ID3D11ShaderResourceView *srv = getSRVLevel(level);
- if (!srv)
- {
- return NULL;
- }
-
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- ID3D11Device *device = mRenderer->getDevice();
+ return error;
+ }
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = mTopLevel + level;
+ ID3D11ShaderResourceView *srv = NULL;
+ error = getSRVLevel(level, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
- ID3D11RenderTargetView *rtv;
- HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + level;
- mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11RenderTargetView *rtv;
+ HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- }
- else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- ID3D11Device *device = mRenderer->getDevice();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
- D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
- dsvDesc.Format = mDepthStencilFormat;
- dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
- dsvDesc.Texture2D.MipSlice = mTopLevel + level;
- dsvDesc.Flags = 0;
+ mRenderTarget[level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
- ID3D11DepthStencilView *dsv;
- HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
+ else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mDepthStencilFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+ dsvDesc.Texture2D.MipSlice = mTopLevel + level;
+ dsvDesc.Flags = 0;
- mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11DepthStencilView *dsv;
+ HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
- // RenderTarget will take ownership of these resources
- SafeRelease(dsv);
- }
- else
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
}
- }
- return mRenderTarget[level];
- }
- else
- {
- return NULL;
+ mRenderTarget[level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
+
+ // RenderTarget will take ownership of these resources
+ SafeRelease(dsv);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget[level];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
- srvDesc.Texture2D.MipLevels = mipLevels;
-
- ID3D11ShaderResourceView *SRV = NULL;
+ srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels;
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11_2D::generateMipmaps()
+gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture)
{
- // Base level must already be defined
-
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
-
- gl::ImageIndex srcIndex = gl::ImageIndex::Make2D(level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::Make2D(level);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ ASSERT(outTexture);
- generateMipmapLayer(source, dest);
- }
-}
-
-ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
-{
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -749,52 +900,52 @@ ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
- }
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
+ }
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
mTexture = NULL;
@@ -803,13 +954,15 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
mSwizzleRenderTargets[level] = NULL;
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
mAssociatedImages[face][level] = NULL;
mRenderTarget[face][level] = NULL;
}
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -819,56 +972,23 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the size is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (size > 0)
- {
- // adjust size if needed for compressed textures
- int height = size;
- d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
+ // adjust size if needed for compressed textures
+ int height = size;
+ d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = size;
- desc.Height = size;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = 6;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = 1;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = size;
+ mTextureHeight = size;
+ mTextureDepth = 1;
- initializeSerials(getLevelCount() * 6, 6);
+ initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
}
-
TextureStorage11_Cube::~TextureStorage11_Cube()
{
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
if (mAssociatedImages[face][level] != NULL)
{
@@ -890,7 +1010,7 @@ TextureStorage11_Cube::~TextureStorage11_Cube()
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
SafeRelease(mSwizzleRenderTargets[level]);
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
SafeDelete(mRenderTarget[face][level]);
}
@@ -903,25 +1023,31 @@ TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureS
return static_cast<TextureStorage11_Cube*>(storage);
}
-void TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
mAssociatedImages[layerTarget][level] = image;
}
}
}
-bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage);
@@ -934,14 +1060,17 @@ bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, I
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
@@ -954,14 +1083,17 @@ void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image1
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
// No need to let the old Image recover its data, if it is also the incoming Image.
if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage)
@@ -974,114 +1106,165 @@ void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, I
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_Cube::getResource() const
+gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = CUBE_FACE_COUNT;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
int faceIndex = index.layerIndex;
int level = index.mipIndex;
- if (level >= 0 && level < getLevelCount())
- {
- if (!mRenderTarget[faceIndex][level])
- {
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
+ ASSERT(level >= 0 && level < getLevelCount());
+ ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT);
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
- srvDesc.Format = mShaderResourceFormat;
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
- srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
- srvDesc.Texture2DArray.MipLevels = 1;
- srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- srvDesc.Texture2DArray.ArraySize = 1;
+ if (!mRenderTarget[faceIndex][level])
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- ID3D11ShaderResourceView *srv;
- result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ srvDesc.Texture2DArray.ArraySize = 1;
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
- rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- rtvDesc.Texture2DArray.ArraySize = 1;
+ ID3D11ShaderResourceView *srv;
+ result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ rtvDesc.Texture2DArray.ArraySize = 1;
- mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
- else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
- dsvDesc.Format = mDepthStencilFormat;
- dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
- dsvDesc.Flags = 0;
- dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
- dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- dsvDesc.Texture2DArray.ArraySize = 1;
-
- ID3D11DepthStencilView *dsv;
- result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
- mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ mRenderTarget[faceIndex][level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
- // RenderTarget will take ownership of these resources
- SafeRelease(dsv);
- SafeRelease(srv);
- }
- else
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ SafeRelease(srv);
+ }
+ else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mDepthStencilFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ dsvDesc.Flags = 0;
+ dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ dsvDesc.Texture2DArray.ArraySize = 1;
+
+ ID3D11DepthStencilView *dsv;
+ result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
+
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
}
- }
- return mRenderTarget[faceIndex][level];
- }
- else
- {
- return NULL;
+ mRenderTarget[faceIndex][level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
+
+ // RenderTarget will take ownership of these resources
+ SafeRelease(dsv);
+ SafeRelease(srv);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget[faceIndex][level];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
@@ -1093,7 +1276,7 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi
srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.FirstArraySlice = 0;
- srvDesc.Texture2DArray.ArraySize = 6;
+ srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
}
else
{
@@ -1102,43 +1285,22 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi
srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
}
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11_Cube::generateMipmaps()
+gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture)
{
- // Base level must already be defined
-
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
- {
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
-
- gl::ImageIndex srcIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ ASSERT(outTexture);
- generateMipmapLayer(source, dest);
- }
- }
-}
-
-ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
-{
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -1147,7 +1309,7 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
desc.Width = mTextureWidth;
desc.Height = mTextureHeight;
desc.MipLevels = mMipLevels;
- desc.ArraySize = 6;
+ desc.ArraySize = CUBE_FACE_COUNT;
desc.Format = mSwizzleTextureFormat;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
@@ -1158,55 +1320,54 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = 0;
- rtvDesc.Texture2DArray.ArraySize = 6;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = 0;
+ rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
+TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
@@ -1220,6 +1381,8 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform
mSwizzleRenderTargets[i] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -1229,49 +1392,13 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // If the width, height or depth are not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0 && depth > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE3D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.Depth = depth;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.Format = mTextureFormat;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = desc.Depth;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
initializeSerials(getLevelCount() * depth, depth);
}
@@ -1315,8 +1442,10 @@ TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage
return static_cast<TextureStorage11_3D*>(storage);
}
-void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1325,8 +1454,10 @@ void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTar
}
}
-bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -1339,8 +1470,10 @@ bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Ima
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1355,8 +1488,10 @@ void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11*
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+
ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1372,148 +1507,188 @@ void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Ima
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_3D::getResource() const
+gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // If the width, height or depth are not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.Depth = mTextureDepth;
+ desc.MipLevels = mMipLevels;
+ desc.Format = mTextureFormat;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
srvDesc.Texture3D.MostDetailedMip = baseLevel;
srvDesc.Texture3D.MipLevels = mipLevels;
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
int mipLevel = index.mipIndex;
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
- if (mipLevel >= 0 && mipLevel < getLevelCount())
- {
- ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
+ ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
- if (!index.hasLayer())
+ if (!index.hasLayer())
+ {
+ if (!mLevelRenderTargets[mipLevel])
{
- if (!mLevelRenderTargets[mipLevel])
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
{
- ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel);
- if (!srv)
- {
- return NULL;
- }
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = 0;
- rtvDesc.Texture3D.WSize = -1;
-
- ID3D11RenderTargetView *rtv;
- HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ID3D11ShaderResourceView *srv = NULL;
+ error = getSRVLevel(mipLevel, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
- mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
+ ID3D11Device *device = mRenderer->getDevice();
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- }
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = 0;
+ rtvDesc.Texture3D.WSize = -1;
- return mLevelRenderTargets[mipLevel];
- }
- else
- {
- int layer = index.layerIndex;
+ ID3D11RenderTargetView *rtv;
+ HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- LevelLayerKey key(mipLevel, layer);
- if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
-
- // TODO, what kind of SRV is expected here?
- ID3D11ShaderResourceView *srv = NULL;
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = layer;
- rtvDesc.Texture3D.WSize = 1;
+ mLevelRenderTargets[mipLevel] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(outRT);
+ *outRT = mLevelRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
+ }
+ else
+ {
+ int layer = index.layerIndex;
- mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
+ LevelLayerKey key(mipLevel, layer);
+ if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- SafeRelease(srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
}
- return mLevelLayerRenderTargets[key];
- }
- }
+ // TODO, what kind of SRV is expected here?
+ ID3D11ShaderResourceView *srv = NULL;
- return NULL;
-}
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = layer;
+ rtvDesc.Texture3D.WSize = 1;
-void TextureStorage11_3D::generateMipmaps()
-{
- // Base level must already be defined
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
+ ASSERT(SUCCEEDED(result));
- gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level);
+ mLevelLayerRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0);
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
- generateMipmapLayer(source, dest);
+ ASSERT(outRT);
+ *outRT = mLevelLayerRenderTargets[key];
+ return gl::Error(GL_NO_ERROR);
}
}
-ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
+gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture)
{
+ ASSERT(outTexture);
+
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -1531,55 +1706,54 @@ ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture3D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = 0;
- rtvDesc.Texture3D.WSize = -1;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = 0;
+ rtvDesc.Texture3D.WSize = -1;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
+TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
@@ -1591,6 +1765,8 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in
mSwizzleRenderTargets[level] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -1600,51 +1776,13 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the width, height or depth is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0 && depth > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = depth;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = desc.ArraySize;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
initializeSerials(getLevelCount() * depth, depth);
}
@@ -1685,8 +1823,11 @@ TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray
return static_cast<TextureStorage11_2DArray*>(storage);
}
-void TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < getLevelCount());
if (0 <= level && level < getLevelCount())
@@ -1696,8 +1837,11 @@ void TextureStorage11_2DArray::associateImage(Image11* image, int level, int lay
}
}
-bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -1707,8 +1851,11 @@ bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
@@ -1721,8 +1868,11 @@ void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Ima
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
@@ -1739,18 +1889,62 @@ void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[key]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2DArray::getResource() const
+gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the width, height or depth is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = mTextureDepth;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
@@ -1760,112 +1954,94 @@ ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.ArraySize = mTextureDepth;
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(index.hasLayer());
int mipLevel = index.mipIndex;
int layer = index.layerIndex;
- if (mipLevel >= 0 && mipLevel < getLevelCount())
- {
- LevelLayerKey key(mipLevel, layer);
- if (mRenderTargets.find(key) == mRenderTargets.end())
- {
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
- srvDesc.Format = mShaderResourceFormat;
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
- srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
- srvDesc.Texture2DArray.MipLevels = 1;
- srvDesc.Texture2DArray.FirstArraySlice = layer;
- srvDesc.Texture2DArray.ArraySize = 1;
+ LevelLayerKey key(mipLevel, layer);
+ if (mRenderTargets.find(key) == mRenderTargets.end())
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- ID3D11ShaderResourceView *srv;
- result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = layer;
+ srvDesc.Texture2DArray.ArraySize = 1;
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = layer;
- rtvDesc.Texture2DArray.ArraySize = 1;
+ ID3D11ShaderResourceView *srv;
+ result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = layer;
+ rtvDesc.Texture2DArray.ArraySize = 1;
- mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- SafeRelease(srv);
- }
- else
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
- }
-
- return mRenderTargets[key];
- }
- else
- {
- return NULL;
- }
-}
-void TextureStorage11_2DArray::generateMipmaps()
-{
- // Base level must already be defined
+ mRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0);
- for (int level = 0; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
- for (unsigned int layer = 0; layer < mTextureDepth; layer++)
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ SafeRelease(srv);
+ }
+ else
{
- gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer);
- gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
-
- generateMipmapLayer(source, dest);
+ UNREACHABLE();
}
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets[key];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
+gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture)
{
if (!mSwizzleTexture)
{
@@ -1886,52 +2062,51 @@ ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = 0;
- rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = 0;
+ rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
}