Commit 8becd0cb by Geoff Lang

Updated Image11 to use gl::Errors for staging texture manipulation.

BUG=angle:520 Change-Id: I5792b139ddd69c2cabc3b901a7067438c1ee363b Reviewed-on: https://chromium-review.googlesource.com/221395Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 06ecf3dd
......@@ -57,18 +57,18 @@ gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src)
ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL);
D3D11_MAPPED_SUBRESOURCE destMapped;
HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped);
if (FAILED(destMapResult))
gl::Error error = dest->map(D3D11_MAP_WRITE, &destMapped);
if (error.isError())
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map destination image for mipmap generation, result: 0x%X", destMapResult);
return error;
}
D3D11_MAPPED_SUBRESOURCE srcMapped;
HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped);
if (FAILED(srcMapResult))
error = src->map(D3D11_MAP_READ, &srcMapped);
if (error.isError())
{
dest->unmap();
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map source image for mip map generation, result: 0x%X", srcMapResult);
return error;
}
const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData);
......@@ -120,8 +120,15 @@ gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex &
}
}
gl::Error error = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(),
index, region);
ID3D11Resource *stagingTexture = NULL;
unsigned int stagingSubresourceIndex = 0;
gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex);
if (error.isError())
{
return error;
}
error = storage11->updateSubresourceLevel(stagingTexture, stagingSubresourceIndex, index, region);
if (error.isError())
{
return error;
......@@ -149,7 +156,11 @@ gl::Error Image11::recoverFromAssociatedStorage()
{
if (mRecoverFromStorage)
{
createStagingTexture();
gl::Error error = createStagingTexture();
if (error.isError())
{
return error;
}
bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedImageIndex, this);
......@@ -161,7 +172,7 @@ gl::Error Image11::recoverFromAssociatedStorage()
{
// CopySubResource from the Storage to the Staging texture
gl::Box region(0, 0, 0, mWidth, mHeight, mDepth);
gl::Error error = mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region);
error = mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region);
if (error.isError())
{
return error;
......@@ -217,7 +228,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat,
mActualFormat = dxgiFormatInfo.internalFormat;
mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
SafeRelease(mStagingTexture);
releaseStagingTexture();
mDirty = (formatInfo.dataInitializerFunction != NULL);
return true;
......@@ -251,10 +262,10 @@ gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type);
D3D11_MAPPED_SUBRESOURCE mappedImage;
HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
if (FAILED(result))
gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
if (error.isError())
{
return gl::Error(GL_OUT_OF_MEMORY, "Could not map internal image for loading texture data, result: 0x%X.", result);
return error;
}
uint8_t* offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch));
......@@ -286,10 +297,10 @@ gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffse
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE);
D3D11_MAPPED_SUBRESOURCE mappedImage;
HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
if (FAILED(result))
gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
if (error.isError())
{
return gl::Error(GL_OUT_OF_MEMORY, "Could not map internal image for loading texture data, result: 0x%X.", result);
return error;
}
uint8_t* offsetMappedData = reinterpret_cast<uint8_t*>(mappedImage.pData) + ((yoffset / outputBlockHeight) * mappedImage.RowPitch +
......@@ -359,6 +370,14 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
if (textureDesc.Format == mDXGIFormat)
{
// No conversion needed-- use copyback fastpath
ID3D11Resource *stagingTexture = NULL;
unsigned int stagingSubresourceIndex = 0;
gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex);
if (error.isError())
{
return error;
}
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
......@@ -402,7 +421,7 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
srcBox.front = 0;
srcBox.back = 1;
deviceContext->CopySubresourceRegion(getStagingTexture(), 0, xoffset, yoffset, zoffset, srcTex, subresourceAfterResolve, &srcBox);
deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, xoffset, yoffset, zoffset, srcTex, subresourceAfterResolve, &srcBox);
if (textureDesc.SampleDesc.Count > 1)
{
......@@ -413,10 +432,10 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
{
// This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
D3D11_MAPPED_SUBRESOURCE mappedImage;
HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
if (FAILED(result))
gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
if (error.isError())
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map texture for Image11::copy, HRESULT: 0x%X.", result);
return error;
}
// determine the offset coordinate into the destination buffer
......@@ -425,7 +444,7 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
gl::Error error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
unmap();
......@@ -440,11 +459,17 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
return gl::Error(GL_NO_ERROR);
}
ID3D11Resource *Image11::getStagingTexture()
gl::Error Image11::getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex)
{
createStagingTexture();
gl::Error error = createStagingTexture();
if (error.isError())
{
return error;
}
return mStagingTexture;
*outStagingTexture = mStagingTexture;
*outSubresourceIndex = mStagingSubresource;
return gl::Error(GL_NO_ERROR);
}
void Image11::releaseStagingTexture()
......@@ -452,149 +477,149 @@ void Image11::releaseStagingTexture()
SafeRelease(mStagingTexture);
}
unsigned int Image11::getStagingSubresource()
{
createStagingTexture();
return mStagingSubresource;
}
void Image11::createStagingTexture()
gl::Error Image11::createStagingTexture()
{
if (mStagingTexture)
{
return;
return gl::Error(GL_NO_ERROR);
}
ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0);
const DXGI_FORMAT dxgiFormat = getDXGIFormat();
if (mWidth > 0 && mHeight > 0 && mDepth > 0)
{
ID3D11Device *device = mRenderer->getDevice();
HRESULT result;
ID3D11Device *device = mRenderer->getDevice();
HRESULT result;
int lodOffset = 1;
GLsizei width = mWidth;
GLsizei height = mHeight;
int lodOffset = 1;
GLsizei width = mWidth;
GLsizei height = mHeight;
// adjust size if needed for compressed textures
d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
// adjust size if needed for compressed textures
d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
if (mTarget == GL_TEXTURE_3D)
if (mTarget == GL_TEXTURE_3D)
{
ID3D11Texture3D *newTexture = NULL;
D3D11_TEXTURE3D_DESC desc;
desc.Width = width;
desc.Height = height;
desc.Depth = mDepth;
desc.MipLevels = lodOffset + 1;
desc.Format = dxgiFormat;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
{
ID3D11Texture3D *newTexture = NULL;
D3D11_TEXTURE3D_DESC desc;
desc.Width = width;
desc.Height = height;
desc.Depth = mDepth;
desc.MipLevels = lodOffset + 1;
desc.Format = dxgiFormat;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
std::vector< std::vector<BYTE> > textureData;
d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
lodOffset + 1, &initialData, &textureData);
result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
}
else
{
result = device->CreateTexture3D(&desc, NULL, &newTexture);
}
if (FAILED(result))
{
ASSERT(result == E_OUTOFMEMORY);
ERR("Creating image failed.");
return gl::error(GL_OUT_OF_MEMORY);
}
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
std::vector< std::vector<BYTE> > textureData;
d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
lodOffset + 1, &initialData, &textureData);
mStagingTexture = newTexture;
mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
}
else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
else
{
ID3D11Texture2D *newTexture = NULL;
D3D11_TEXTURE2D_DESC desc;
desc.Width = width;
desc.Height = height;
desc.MipLevels = lodOffset + 1;
desc.ArraySize = 1;
desc.Format = dxgiFormat;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
std::vector< std::vector<BYTE> > textureData;
d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
lodOffset + 1, &initialData, &textureData);
result = device->CreateTexture3D(&desc, NULL, &newTexture);
}
result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
}
else
{
result = device->CreateTexture2D(&desc, NULL, &newTexture);
}
if (FAILED(result))
{
ASSERT(result == E_OUTOFMEMORY);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result);
}
if (FAILED(result))
{
ASSERT(result == E_OUTOFMEMORY);
ERR("Creating image failed.");
return gl::error(GL_OUT_OF_MEMORY);
}
mStagingTexture = newTexture;
mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
}
else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
{
ID3D11Texture2D *newTexture = NULL;
D3D11_TEXTURE2D_DESC desc;
desc.Width = width;
desc.Height = height;
desc.MipLevels = lodOffset + 1;
desc.ArraySize = 1;
desc.Format = dxgiFormat;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
std::vector< std::vector<BYTE> > textureData;
d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
lodOffset + 1, &initialData, &textureData);
mStagingTexture = newTexture;
mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
}
else
{
UNREACHABLE();
result = device->CreateTexture2D(&desc, NULL, &newTexture);
}
if (FAILED(result))
{
ASSERT(result == E_OUTOFMEMORY);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result);
}
mStagingTexture = newTexture;
mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
}
else
{
UNREACHABLE();
}
mDirty = false;
return gl::Error(GL_NO_ERROR);
}
HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
gl::Error Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
{
createStagingTexture();
// We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
recoverFromAssociatedStorage();
HRESULT result = E_FAIL;
gl::Error error = recoverFromAssociatedStorage();
if (error.isError())
{
return error;
}
if (mStagingTexture)
ID3D11Resource *stagingTexture = NULL;
unsigned int subresourceIndex = 0;
error = getStagingTexture(&stagingTexture, &subresourceIndex);
if (error.isError())
{
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map);
return error;
}
// this can fail if the device is removed (from TDR)
if (d3d11::isDeviceLostError(result))
{
mRenderer->notifyDeviceLost();
}
else if (SUCCEEDED(result))
{
mDirty = true;
}
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ASSERT(mStagingTexture);
HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map);
// this can fail if the device is removed (from TDR)
if (d3d11::isDeviceLostError(result))
{
mRenderer->notifyDeviceLost();
}
else if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map staging texture, result: 0x%X.", result);
}
return result;
mDirty = true;
return gl::Error(GL_NO_ERROR);
}
void Image11::unmap()
......
......@@ -58,7 +58,7 @@ class Image11 : public ImageD3D
void disassociateStorage();
protected:
HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
gl::Error map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
void unmap();
private:
......@@ -67,9 +67,8 @@ class Image11 : public ImageD3D
gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box &region);
gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource);
ID3D11Resource *getStagingTexture();
unsigned int getStagingSubresource();
void createStagingTexture();
gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex);
gl::Error createStagingTexture();
void releaseStagingTexture();
Renderer11 *mRenderer;
......
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