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) ...@@ -57,18 +57,18 @@ gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src)
ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL); ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL);
D3D11_MAPPED_SUBRESOURCE destMapped; D3D11_MAPPED_SUBRESOURCE destMapped;
HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped); gl::Error error = dest->map(D3D11_MAP_WRITE, &destMapped);
if (FAILED(destMapResult)) 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; D3D11_MAPPED_SUBRESOURCE srcMapped;
HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped); error = src->map(D3D11_MAP_READ, &srcMapped);
if (FAILED(srcMapResult)) if (error.isError())
{ {
dest->unmap(); 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); const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData);
...@@ -120,8 +120,15 @@ gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex & ...@@ -120,8 +120,15 @@ gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex &
} }
} }
gl::Error error = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), ID3D11Resource *stagingTexture = NULL;
index, region); 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()) if (error.isError())
{ {
return error; return error;
...@@ -149,7 +156,11 @@ gl::Error Image11::recoverFromAssociatedStorage() ...@@ -149,7 +156,11 @@ gl::Error Image11::recoverFromAssociatedStorage()
{ {
if (mRecoverFromStorage) if (mRecoverFromStorage)
{ {
createStagingTexture(); gl::Error error = createStagingTexture();
if (error.isError())
{
return error;
}
bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedImageIndex, this); bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedImageIndex, this);
...@@ -161,7 +172,7 @@ gl::Error Image11::recoverFromAssociatedStorage() ...@@ -161,7 +172,7 @@ gl::Error Image11::recoverFromAssociatedStorage()
{ {
// CopySubResource from the Storage to the Staging texture // CopySubResource from the Storage to the Staging texture
gl::Box region(0, 0, 0, mWidth, mHeight, mDepth); 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()) if (error.isError())
{ {
return error; return error;
...@@ -217,7 +228,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, ...@@ -217,7 +228,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat,
mActualFormat = dxgiFormatInfo.internalFormat; mActualFormat = dxgiFormatInfo.internalFormat;
mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
SafeRelease(mStagingTexture); releaseStagingTexture();
mDirty = (formatInfo.dataInitializerFunction != NULL); mDirty = (formatInfo.dataInitializerFunction != NULL);
return true; return true;
...@@ -251,10 +262,10 @@ gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei ...@@ -251,10 +262,10 @@ gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type); LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type);
D3D11_MAPPED_SUBRESOURCE mappedImage; D3D11_MAPPED_SUBRESOURCE mappedImage;
HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
if (FAILED(result)) 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)); 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 ...@@ -286,10 +297,10 @@ gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffse
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE); LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE);
D3D11_MAPPED_SUBRESOURCE mappedImage; D3D11_MAPPED_SUBRESOURCE mappedImage;
HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
if (FAILED(result)) 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 + 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 ...@@ -359,6 +370,14 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
if (textureDesc.Format == mDXGIFormat) if (textureDesc.Format == mDXGIFormat)
{ {
// No conversion needed-- use copyback fastpath // 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(); ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
...@@ -402,7 +421,7 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R ...@@ -402,7 +421,7 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
srcBox.front = 0; srcBox.front = 0;
srcBox.back = 1; 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) if (textureDesc.SampleDesc.Count > 1)
{ {
...@@ -413,10 +432,10 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R ...@@ -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 // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
D3D11_MAPPED_SUBRESOURCE mappedImage; D3D11_MAPPED_SUBRESOURCE mappedImage;
HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
if (FAILED(result)) 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 // 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 ...@@ -425,7 +444,7 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); 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(); unmap();
...@@ -440,11 +459,17 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R ...@@ -440,11 +459,17 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
return gl::Error(GL_NO_ERROR); 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() void Image11::releaseStagingTexture()
...@@ -452,24 +477,17 @@ void Image11::releaseStagingTexture() ...@@ -452,24 +477,17 @@ void Image11::releaseStagingTexture()
SafeRelease(mStagingTexture); SafeRelease(mStagingTexture);
} }
unsigned int Image11::getStagingSubresource() gl::Error Image11::createStagingTexture()
{
createStagingTexture();
return mStagingSubresource;
}
void Image11::createStagingTexture()
{ {
if (mStagingTexture) if (mStagingTexture)
{ {
return; return gl::Error(GL_NO_ERROR);
} }
ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0);
const DXGI_FORMAT dxgiFormat = getDXGIFormat(); const DXGI_FORMAT dxgiFormat = getDXGIFormat();
if (mWidth > 0 && mHeight > 0 && mDepth > 0)
{
ID3D11Device *device = mRenderer->getDevice(); ID3D11Device *device = mRenderer->getDevice();
HRESULT result; HRESULT result;
...@@ -512,8 +530,7 @@ void Image11::createStagingTexture() ...@@ -512,8 +530,7 @@ void Image11::createStagingTexture()
if (FAILED(result)) if (FAILED(result))
{ {
ASSERT(result == E_OUTOFMEMORY); ASSERT(result == E_OUTOFMEMORY);
ERR("Creating image failed."); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result);
return gl::error(GL_OUT_OF_MEMORY);
} }
mStagingTexture = newTexture; mStagingTexture = newTexture;
...@@ -553,8 +570,7 @@ void Image11::createStagingTexture() ...@@ -553,8 +570,7 @@ void Image11::createStagingTexture()
if (FAILED(result)) if (FAILED(result))
{ {
ASSERT(result == E_OUTOFMEMORY); ASSERT(result == E_OUTOFMEMORY);
ERR("Creating image failed."); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result);
return gl::error(GL_OUT_OF_MEMORY);
} }
mStagingTexture = newTexture; mStagingTexture = newTexture;
...@@ -564,37 +580,46 @@ void Image11::createStagingTexture() ...@@ -564,37 +580,46 @@ void Image11::createStagingTexture()
{ {
UNREACHABLE(); UNREACHABLE();
} }
}
mDirty = false; 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. // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
recoverFromAssociatedStorage(); gl::Error error = recoverFromAssociatedStorage();
if (error.isError())
HRESULT result = E_FAIL; {
return error;
}
if (mStagingTexture) ID3D11Resource *stagingTexture = NULL;
unsigned int subresourceIndex = 0;
error = getStagingTexture(&stagingTexture, &subresourceIndex);
if (error.isError())
{ {
return error;
}
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map);
ASSERT(mStagingTexture);
HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map);
// this can fail if the device is removed (from TDR) // this can fail if the device is removed (from TDR)
if (d3d11::isDeviceLostError(result)) if (d3d11::isDeviceLostError(result))
{ {
mRenderer->notifyDeviceLost(); mRenderer->notifyDeviceLost();
} }
else if (SUCCEEDED(result)) else if (FAILED(result))
{ {
mDirty = true; 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() void Image11::unmap()
......
...@@ -58,7 +58,7 @@ class Image11 : public ImageD3D ...@@ -58,7 +58,7 @@ class Image11 : public ImageD3D
void disassociateStorage(); void disassociateStorage();
protected: protected:
HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); gl::Error map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
void unmap(); void unmap();
private: private:
...@@ -67,9 +67,8 @@ class Image11 : public ImageD3D ...@@ -67,9 +67,8 @@ class Image11 : public ImageD3D
gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box &region); 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); gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource);
ID3D11Resource *getStagingTexture(); gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex);
unsigned int getStagingSubresource(); gl::Error createStagingTexture();
void createStagingTexture();
void releaseStagingTexture(); void releaseStagingTexture();
Renderer11 *mRenderer; 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