diff options
author | Geoff Lang <geofflang@chromium.org> | 2014-09-22 15:21:39 -0400 |
---|---|---|
committer | Geoff Lang <geofflang@chromium.org> | 2014-10-24 16:56:18 +0000 |
commit | 553c6bee81fa41e2c36512023f06c049fba98979 (patch) | |
tree | 3688019d642f451e947379dfc925a06a76aa4f97 | |
parent | 5ca41055d838a0bb16a698076a7b7df6730fefde (diff) | |
download | angle-553c6bee81fa41e2c36512023f06c049fba98979.tar.gz |
Defer the creation of textures in TextureStorage11.
BUG=angle:520
Change-Id: If1c1f7519a84900f594701b6298b64ebf8798073
Reviewed-on: https://chromium-review.googlesource.com/219333
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Image11.cpp | 11 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp | 493 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h | 10 |
3 files changed, 296 insertions, 218 deletions
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp index c9f538b4..a8196f64 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp +++ b/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp @@ -331,14 +331,21 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source); UINT subresourceIndex = sourceStorage11->getSubresourceIndex(sourceIndex); - ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(sourceStorage11->getResource()); + ID3D11Resource *resource = NULL; + gl::Error error = sourceStorage11->getResource(&resource); + if (error.isError()) + { + return error; + } + + ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource); if (!sourceTexture2D) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source TextureStorage."); } - gl::Error error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex); + error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex); SafeRelease(sourceTexture2D); diff --git a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp index e5a5dfed..07bd7dd8 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp @@ -161,14 +161,10 @@ int TextureStorage11::getLevelDepth(int mipLevel) const UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const { - UINT subresource = 0; - if (getResource()) - { - UINT mipSlice = static_cast<UINT>(index.mipIndex + mTopLevel); - UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0); - subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); - ASSERT(subresource != std::numeric_limits<UINT>::max()); - } + 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; } @@ -205,7 +201,11 @@ gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11S } else { - texture = getResource(); + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } } ID3D11ShaderResourceView *srv = NULL; @@ -229,7 +229,14 @@ gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView * if (!mLevelSRVs[mipLevel]) { - gl::Error error = createSRV(mipLevel, 1, mShaderResourceFormat, getResource(), &mLevelSRVs[mipLevel]); + ID3D11Resource *resource = NULL; + gl::Error error = getResource(&resource); + if (error.isError()) + { + return error; + } + + error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]); if (error.isError()) { return error; @@ -317,7 +324,13 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, u copyArea.height == texSize.height && copyArea.depth == texSize.depth; - ID3D11Resource *dstTexture = getResource(); + ID3D11Resource *dstTexture = NULL; + gl::Error error = getResource(&dstTexture); + if (error.isError()) + { + return error; + } + unsigned int dstSubresource = getSubresourceIndex(index); ASSERT(dstTexture); @@ -357,7 +370,13 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, uns { ASSERT(dstTexture); - ID3D11Resource *srcTexture = getResource(); + ID3D11Resource *srcTexture = NULL; + gl::Error error = getResource(&srcTexture); + if (error.isError()) + { + return error; + } + ASSERT(srcTexture); unsigned int srcSubresource = getSubresourceIndex(index); @@ -416,10 +435,23 @@ 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(dest11->getResource(), getResource()); + immediateContext->CopyResource(destResource, sourceResouce); dest11->invalidateSwizzleCache(); @@ -429,7 +461,12 @@ gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage) 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 = getResource(); + ID3D11Resource *resource = NULL; + gl::Error error = getResource(&resource); + if (error.isError()) + { + return error; + } ASSERT(resource); UINT destSubresource = getSubresourceIndex(index); @@ -563,51 +600,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 = ((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); } @@ -726,9 +723,46 @@ gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &inde 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 = 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); } gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) @@ -740,8 +774,15 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend if (!mRenderTarget[level]) { + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } + ID3D11ShaderResourceView *srv = NULL; - gl::Error error = getSRVLevel(level, &srv); + error = getSRVLevel(level, &srv); if (error.isError()) { return error; @@ -757,7 +798,7 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend rtvDesc.Texture2D.MipSlice = mTopLevel + level; ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -765,7 +806,7 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); } - mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1); // RenderTarget will take ownership of these resources SafeRelease(rtv); @@ -781,7 +822,7 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend dsvDesc.Flags = 0; ID3D11DepthStencilView *dsv; - HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); + HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -789,7 +830,7 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); } - mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1); // RenderTarget will take ownership of these resources SafeRelease(dsv); @@ -921,51 +962,18 @@ 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(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = size; - desc.Height = size; - desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); - 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; + // adjust size if needed for compressed textures + int height = size; + d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel); - 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() * CUBE_FACE_COUNT, CUBE_FACE_COUNT); } - TextureStorage11_Cube::~TextureStorage11_Cube() { for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) @@ -1101,9 +1109,46 @@ gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &in 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); } gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) @@ -1119,6 +1164,13 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re ID3D11Device *device = mRenderer->getDevice(); HRESULT result; + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = mShaderResourceFormat; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube @@ -1128,7 +1180,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re srvDesc.Texture2DArray.ArraySize = 1; ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + result = device->CreateShaderResourceView(texture, &srvDesc, &srv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -1146,7 +1198,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re rtvDesc.Texture2DArray.ArraySize = 1; ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -1155,7 +1207,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); } - mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1); // RenderTarget will take ownership of these resources SafeRelease(rtv); @@ -1172,7 +1224,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re dsvDesc.Texture2DArray.ArraySize = 1; ID3D11DepthStencilView *dsv; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); + result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -1181,7 +1233,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); } - mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1); // RenderTarget will take ownership of these resources SafeRelease(dsv); @@ -1328,49 +1380,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; + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - HRESULT result = device->CreateTexture3D(&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.Depth; - } - } + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; initializeSerials(getLevelCount() * depth, depth); } @@ -1491,9 +1507,44 @@ gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &inde 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); } gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, @@ -1530,8 +1581,15 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend { if (!mLevelRenderTargets[mipLevel]) { + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } + ID3D11ShaderResourceView *srv = NULL; - gl::Error error = getSRVLevel(mipLevel, &srv); + error = getSRVLevel(mipLevel, &srv); if (error.isError()) { return error; @@ -1547,7 +1605,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend rtvDesc.Texture3D.WSize = -1; ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -1556,7 +1614,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); } - mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel)); + mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel)); // RenderTarget will take ownership of these resources SafeRelease(rtv); @@ -1576,6 +1634,13 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend ID3D11Device *device = mRenderer->getDevice(); HRESULT result; + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } + // TODO, what kind of SRV is expected here? ID3D11ShaderResourceView *srv = NULL; @@ -1587,7 +1652,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend rtvDesc.Texture3D.WSize = 1; ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -1596,7 +1661,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend } ASSERT(SUCCEEDED(result)); - mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); + mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); // RenderTarget will take ownership of these resources SafeRelease(rtv); @@ -1697,51 +1762,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); - - 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); + // 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.ArraySize; - } - } + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; initializeSerials(getLevelCount() * depth, depth); } @@ -1860,9 +1887,46 @@ gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex 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); } gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, @@ -1903,6 +1967,13 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, ID3D11Device *device = mRenderer->getDevice(); HRESULT result; + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = mShaderResourceFormat; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; @@ -1912,7 +1983,7 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, srvDesc.Texture2DArray.ArraySize = 1; ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + result = device->CreateShaderResourceView(texture, &srvDesc, &srv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -1930,7 +2001,7 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, rtvDesc.Texture2DArray.ArraySize = 1; ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) @@ -1939,7 +2010,7 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); } - mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); + mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); // RenderTarget will take ownership of these resources SafeRelease(rtv); diff --git a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h index 0355536b..3ec2be67 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h +++ b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h @@ -41,7 +41,7 @@ class TextureStorage11 : public TextureStorage UINT getBindFlags() const; - virtual ID3D11Resource *getResource() const = 0; + virtual gl::Error getResource(ID3D11Resource **outResource) = 0; virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV); virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0; @@ -147,7 +147,7 @@ class TextureStorage11_2D : public TextureStorage11 static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; + virtual gl::Error getResource(ID3D11Resource **outResource); virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); virtual void associateImage(Image11* image, const gl::ImageIndex &index); @@ -182,7 +182,7 @@ class TextureStorage11_Cube : public TextureStorage11 static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; + virtual gl::Error getResource(ID3D11Resource **outResource); virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); virtual void associateImage(Image11* image, const gl::ImageIndex &index); @@ -220,7 +220,7 @@ class TextureStorage11_3D : public TextureStorage11 static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; + virtual gl::Error getResource(ID3D11Resource **outResource); // Handles both layer and non-layer RTs virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); @@ -262,7 +262,7 @@ class TextureStorage11_2DArray : public TextureStorage11 static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; + virtual gl::Error getResource(ID3D11Resource **outResource); virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); virtual void associateImage(Image11* image, const gl::ImageIndex &index); |