Commit 553c6bee by Geoff Lang

Defer the creation of textures in TextureStorage11.

BUG=angle:520 Change-Id: If1c1f7519a84900f594701b6298b64ebf8798073 Reviewed-on: https://chromium-review.googlesource.com/219333Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 5ca41055
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment