Commit 06ecf3dd by Geoff Lang

Updated mipmap generation to return Error objects.

BUG=angle:520 Change-Id: Ic4e57148d031d6c452b3054efad98f6e730c7691 Reviewed-on: https://chromium-review.googlesource.com/221394Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 2a517272
......@@ -131,9 +131,9 @@ GLenum Texture::getActualFormat(const ImageIndex &index) const
return image->getActualFormat();
}
void Texture::generateMipmaps()
Error Texture::generateMipmaps()
{
getImplementation()->generateMipmaps();
return getImplementation()->generateMipmaps();
}
Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
......@@ -361,11 +361,11 @@ bool Texture2D::isDepth(GLint level) const
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
void Texture2D::generateMipmaps()
Error Texture2D::generateMipmaps()
{
releaseTexImage();
mTexture->generateMipmaps();
return mTexture->generateMipmaps();
}
// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
......
......@@ -68,7 +68,8 @@ class Texture : public RefCountObject
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0;
virtual void generateMipmaps();
virtual Error generateMipmaps();
virtual Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
// Texture serials provide a unique way of identifying a Texture that isn't a raw pointer.
......@@ -129,7 +130,7 @@ class Texture2D : public Texture
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps();
virtual Error generateMipmaps();
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
......
......@@ -1766,7 +1766,12 @@ void GL_APIENTRY glGenerateMipmap(GLenum target)
}
}
texture->generateMipmaps();
gl::Error error = texture->generateMipmaps();
if (error.isError())
{
context->recordError(error);
return;
}
}
}
......
......@@ -208,7 +208,7 @@ class Renderer
// Image operations
virtual Image *createImage() = 0;
virtual void generateMipmap(Image *dest, Image *source) = 0;
virtual gl::Error generateMipmap(Image *dest, Image *source) = 0;
virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0;
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0;
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0;
......
......@@ -55,7 +55,7 @@ class TextureImpl
virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0;
virtual void generateMipmaps() = 0;
virtual gl::Error generateMipmaps() = 0;
virtual void bindTexImage(egl::Surface *surface) = 0;
virtual void releaseTexImage() = 0;
......
......@@ -337,13 +337,13 @@ Image *TextureD3D::getBaseLevelImage() const
return getImage(getImageIndex(0, 0));
}
void TextureD3D::generateMipmaps()
gl::Error TextureD3D::generateMipmaps()
{
GLint mipCount = mipLevels();
if (mipCount == 1)
{
return; // no-op
return gl::Error(GL_NO_ERROR); // no-op
}
// Set up proper mipmap chain in our Image array.
......@@ -366,12 +366,20 @@ void TextureD3D::generateMipmaps()
Image *image = getImage(srcIndex);
gl::Rectangle area(0, 0, image->getWidth(), image->getHeight());
image->copy(0, 0, 0, area, srcIndex, mTexStorage);
gl::Error error = image->copy(0, 0, 0, area, srcIndex, mTexStorage);
if (error.isError())
{
return error;
}
}
}
else
{
updateStorage();
gl::Error error = updateStorage();
if (error.isError())
{
return error;
}
}
}
......@@ -389,15 +397,25 @@ void TextureD3D::generateMipmaps()
if (renderableStorage)
{
// GPU-side mipmapping
mTexStorage->generateMipmap(sourceIndex, destIndex);
gl::Error error = mTexStorage->generateMipmap(sourceIndex, destIndex);
if (error.isError())
{
return error;
}
}
else
{
// CPU-side mipmapping
mRenderer->generateMipmap(getImage(destIndex), getImage(sourceIndex));
gl::Error error = mRenderer->generateMipmap(getImage(destIndex), getImage(sourceIndex));
if (error.isError())
{
return error;
}
}
}
}
return gl::Error(GL_NO_ERROR);
}
bool TextureD3D::isBaseImageZeroSize() const
......
......@@ -59,7 +59,7 @@ class TextureD3D : public TextureImpl
virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0;
virtual bool isValidIndex(const gl::ImageIndex &index) const = 0;
virtual void generateMipmaps();
virtual gl::Error generateMipmaps();
TextureStorage *getStorage();
Image *getBaseLevelImage() const;
......
......@@ -43,7 +43,7 @@ class TextureStorage
virtual int getLevelCount() const = 0;
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0;
virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
......
......@@ -47,7 +47,7 @@ Image11 *Image11::makeImage11(Image *img)
return static_cast<rx::Image11*>(img);
}
void Image11::generateMipmap(Image11 *dest, Image11 *src)
gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src)
{
ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
......@@ -60,18 +60,15 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src)
HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped);
if (FAILED(destMapResult))
{
ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult);
return;
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map destination image for mipmap generation, result: 0x%X", destMapResult);
}
D3D11_MAPPED_SUBRESOURCE srcMapped;
HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped);
if (FAILED(srcMapResult))
{
ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult);
dest->unmap();
return;
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map source image for mip map generation, result: 0x%X", srcMapResult);
}
const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData);
......@@ -85,6 +82,8 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src)
src->unmap();
dest->markDirty();
return gl::Error(GL_NO_ERROR);
}
bool Image11::isDirty() const
......
......@@ -34,7 +34,7 @@ class Image11 : public ImageD3D
static Image11 *makeImage11(Image *img);
static void generateMipmap(Image11 *dest, Image11 *src);
static gl::Error generateMipmap(Image11 *dest, Image11 *src);
virtual bool isDirty() const;
......
......@@ -2659,11 +2659,11 @@ Image *Renderer11::createImage()
return new Image11();
}
void Renderer11::generateMipmap(Image *dest, Image *src)
gl::Error Renderer11::generateMipmap(Image *dest, Image *src)
{
Image11 *dest11 = Image11::makeImage11(dest);
Image11 *src11 = Image11::makeImage11(src);
Image11::generateMipmap(dest11, src11);
return Image11::generateMipmap(dest11, src11);
}
TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
......
......@@ -152,7 +152,7 @@ class Renderer11 : public Renderer
// Image operations
virtual Image *createImage();
virtual void generateMipmap(Image *dest, Image *source);
virtual gl::Error generateMipmap(Image *dest, Image *source);
virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels);
......
......@@ -388,7 +388,7 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, uns
return gl::Error(GL_NO_ERROR);
}
void TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
ASSERT(sourceIndex.layerIndex == destIndex.layerIndex);
......@@ -398,14 +398,14 @@ void TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const g
gl::Error error = getRenderTarget(sourceIndex, &source);
if (error.isError())
{
return;
return error;
}
RenderTarget *dest = NULL;
error = getRenderTarget(destIndex, &dest);
if (error.isError())
{
return;
return error;
}
ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView();
......@@ -418,8 +418,8 @@ void TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const g
gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
Blit11 *blitter = mRenderer->getBlitter();
blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
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)
......
......@@ -45,7 +45,7 @@ class TextureStorage11 : public TextureStorage
virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV);
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
......
......@@ -36,15 +36,23 @@ Image9::~Image9()
SafeRelease(mSurface);
}
void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
{
D3DSURFACE_DESC destDesc;
HRESULT result = destSurface->GetDesc(&destDesc);
ASSERT(SUCCEEDED(result));
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the source surface description for mipmap generation, result: 0x%X.", result);
}
D3DSURFACE_DESC sourceDesc;
result = sourceSurface->GetDesc(&sourceDesc);
ASSERT(SUCCEEDED(result));
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the destination surface description for mipmap generation, result: 0x%X.", result);
}
ASSERT(sourceDesc.Format == destDesc.Format);
ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
......@@ -56,22 +64,32 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour
D3DLOCKED_RECT sourceLocked = {0};
result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
ASSERT(SUCCEEDED(result));
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface for mipmap generation, result: 0x%X.", result);
}
D3DLOCKED_RECT destLocked = {0};
result = destSurface->LockRect(&destLocked, NULL, 0);
ASSERT(SUCCEEDED(result));
if (FAILED(result))
{
sourceSurface->UnlockRect();
return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the destination surface for mipmap generation, result: 0x%X.", result);
}
const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(sourceLocked.pBits);
uint8_t *destData = reinterpret_cast<uint8_t*>(destLocked.pBits);
if (sourceData && destData)
{
d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
destData, destLocked.Pitch, 0);
}
ASSERT(sourceData && destData);
d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
destData, destLocked.Pitch, 0);
destSurface->UnlockRect();
sourceSurface->UnlockRect();
return gl::Error(GL_NO_ERROR);
}
Image9 *Image9::makeImage9(Image *img)
......@@ -80,16 +98,21 @@ Image9 *Image9::makeImage9(Image *img)
return static_cast<rx::Image9*>(img);
}
void Image9::generateMipmap(Image9 *dest, Image9 *source)
gl::Error Image9::generateMipmap(Image9 *dest, Image9 *source)
{
IDirect3DSurface9 *sourceSurface = source->getSurface();
if (sourceSurface == NULL)
return gl::error(GL_OUT_OF_MEMORY);
ASSERT(sourceSurface);
IDirect3DSurface9 *destSurface = dest->getSurface();
generateMip(destSurface, sourceSurface);
gl::Error error = generateMip(destSurface, sourceSurface);
if (error.isError())
{
return error;
}
dest->markDirty();
return gl::Error(GL_NO_ERROR);
}
gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
......
......@@ -31,8 +31,8 @@ class Image9 : public ImageD3D
static Image9 *makeImage9(Image *img);
static void generateMipmap(Image9 *dest, Image9 *source);
static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
static gl::Error generateMipmap(Image9 *dest, Image9 *source);
static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease);
......
......@@ -3037,11 +3037,11 @@ Image *Renderer9::createImage()
return new Image9();
}
void Renderer9::generateMipmap(Image *dest, Image *src)
gl::Error Renderer9::generateMipmap(Image *dest, Image *src)
{
Image9 *src9 = Image9::makeImage9(src);
Image9 *dst9 = Image9::makeImage9(dest);
Image9::generateMipmap(dst9, src9);
return Image9::generateMipmap(dst9, src9);
}
TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain)
......
......@@ -154,7 +154,7 @@ class Renderer9 : public Renderer
// Image operations
virtual Image *createImage();
virtual void generateMipmap(Image *dest, Image *source);
virtual gl::Error generateMipmap(Image *dest, Image *source);
virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels);
......
......@@ -194,13 +194,13 @@ gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, R
return gl::Error(GL_NO_ERROR);
}
void TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
IDirect3DSurface9 *upper = NULL;
gl::Error error = getSurfaceLevel(sourceIndex.mipIndex, false, &upper);
if (error.isError())
{
return;
return error;
}
IDirect3DSurface9 *lower = NULL;
......@@ -208,14 +208,16 @@ void TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const
if (error.isError())
{
SafeRelease(upper);
return;
return error;
}
ASSERT(upper && lower);
mRenderer->boxFilter(upper, lower);
error = mRenderer->boxFilter(upper, lower);
SafeRelease(upper);
SafeRelease(lower);
return error;
}
gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture)
......@@ -369,13 +371,13 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren
return gl::Error(GL_NO_ERROR);
}
void TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
IDirect3DSurface9 *upper = NULL;
gl::Error error = getCubeMapSurface(sourceIndex.type, sourceIndex.mipIndex, false, &upper);
if (error.isError())
{
return;
return error;
}
IDirect3DSurface9 *lower = NULL;
......@@ -383,14 +385,16 @@ void TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, con
if (error.isError())
{
SafeRelease(upper);
return;
return error;
}
ASSERT(upper && lower);
mRenderer->boxFilter(upper, lower);
error = mRenderer->boxFilter(upper, lower);
SafeRelease(upper);
SafeRelease(lower);
return error;
}
gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTexture)
......
......@@ -35,7 +35,6 @@ class TextureStorage9 : public TextureStorage
virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0;
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
......@@ -75,7 +74,7 @@ class TextureStorage9_2D : public TextureStorage9
gl::Error getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface);
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture);
virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual gl::Error copyToStorage(TextureStorage *destStorage);
private:
......@@ -96,7 +95,7 @@ class TextureStorage9_Cube : public TextureStorage9
gl::Error getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface);
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture);
virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual gl::Error copyToStorage(TextureStorage *destStorage);
private:
......
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