Commit ef7b016a by Geoff Lang

Refactor Texture::copy*Image methods to use gl::Error objects.

BUG=angle:520 Change-Id: I8b6bf5d50ee0d1f796eff52919ee65823fdee6cb Reviewed-on: https://chromium-review.googlesource.com/216647Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 4119ed3d
...@@ -148,9 +148,10 @@ void Texture::generateMipmaps() ...@@ -148,9 +148,10 @@ void Texture::generateMipmaps()
getImplementation()->generateMipmaps(); getImplementation()->generateMipmaps();
} }
void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{ {
getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source); return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
} }
unsigned int Texture::getTextureSerial() unsigned int Texture::getTextureSerial()
...@@ -273,11 +274,12 @@ Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, G ...@@ -273,11 +274,12 @@ Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, G
return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels); return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
} }
void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
Framebuffer *source)
{ {
releaseTexImage(); releaseTexImage();
mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source); return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
} }
void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
...@@ -529,9 +531,10 @@ bool TextureCubeMap::isDepth(GLenum target, GLint level) const ...@@ -529,9 +531,10 @@ bool TextureCubeMap::isDepth(GLenum target, GLint level) const
return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0; return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
} }
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
GLsizei width, GLsizei height, Framebuffer *source)
{ {
mTexture->copyImage(target, level, format, x, y, width, height, source); return mTexture->copyImage(target, level, format, x, y, width, height, source);
} }
void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size) void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
......
...@@ -72,7 +72,7 @@ class Texture : public RefCountObject ...@@ -72,7 +72,7 @@ class Texture : public RefCountObject
rx::TextureStorage *getNativeTexture(); rx::TextureStorage *getNativeTexture();
virtual void generateMipmaps(); virtual void generateMipmaps();
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); virtual Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
unsigned int getTextureSerial(); unsigned int getTextureSerial();
...@@ -120,7 +120,7 @@ class Texture2D : public Texture ...@@ -120,7 +120,7 @@ class Texture2D : public Texture
Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
Error subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); Error subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); Error copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
...@@ -156,7 +156,7 @@ class TextureCubeMap : public Texture ...@@ -156,7 +156,7 @@ class TextureCubeMap : public Texture
Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei size); void storage(GLsizei levels, GLenum internalformat, GLsizei size);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
......
...@@ -899,7 +899,12 @@ void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalfor ...@@ -899,7 +899,12 @@ void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalfor
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
{ {
gl::Texture2D *texture = context->getTexture2D(); gl::Texture2D *texture = context->getTexture2D();
texture->copyImage(level, internalformat, x, y, width, height, framebuffer); gl::Error error = texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
if (error.isError())
{
context->recordError(error);
return;
}
} }
break; break;
...@@ -911,7 +916,12 @@ void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalfor ...@@ -911,7 +916,12 @@ void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalfor
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{ {
gl::TextureCubeMap *texture = context->getTextureCubeMap(); gl::TextureCubeMap *texture = context->getTextureCubeMap();
texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); gl::Error error = texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
if (error.isError())
{
context->recordError(error);
return;
}
} }
break; break;
...@@ -952,7 +962,12 @@ void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, ...@@ -952,7 +962,12 @@ void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
{ {
gl::Texture2D *texture = context->getTexture2D(); gl::Texture2D *texture = context->getTexture2D();
texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
if (error.isError())
{
context->recordError(error);
return;
}
} }
break; break;
...@@ -964,7 +979,12 @@ void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, ...@@ -964,7 +979,12 @@ void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{ {
gl::TextureCubeMap *texture = context->getTextureCubeMap(); gl::TextureCubeMap *texture = context->getTextureCubeMap();
texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
if (error.isError())
{
context->recordError(error);
return;
}
} }
break; break;
...@@ -5194,7 +5214,12 @@ void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, ...@@ -5194,7 +5214,12 @@ void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset,
return; return;
} }
texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer); gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
if (error.isError())
{
context->recordError(error);
return;
}
} }
} }
......
...@@ -27,18 +27,14 @@ Image::Image() ...@@ -27,18 +27,14 @@ Image::Image()
mDirty = false; mDirty = false;
} }
void Image::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, gl::Framebuffer *source) gl::Error Image::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, gl::Framebuffer *source)
{ {
gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer(); gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
ASSERT(colorbuffer);
if (!colorbuffer)
{
return gl::error(GL_OUT_OF_MEMORY);
}
RenderTarget *renderTarget = GetAttachmentRenderTarget(colorbuffer); RenderTarget *renderTarget = GetAttachmentRenderTarget(colorbuffer);
ASSERT(renderTarget); ASSERT(renderTarget);
copy(xoffset, yoffset, zoffset, area, renderTarget); return copy(xoffset, yoffset, zoffset, area, renderTarget);
} }
} }
...@@ -54,10 +54,10 @@ class Image ...@@ -54,10 +54,10 @@ class Image
virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
const void *input) = 0; const void *input) = 0;
void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, gl::Framebuffer *source); gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, gl::Framebuffer *source);
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) = 0; virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) = 0;
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0; const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0;
protected: protected:
GLsizei mWidth; GLsizei mWidth;
......
...@@ -56,8 +56,8 @@ class TextureImpl ...@@ -56,8 +56,8 @@ class TextureImpl
virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0; virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0;
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0; virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0;
virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
virtual void 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 copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0; virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0;
virtual void generateMipmaps() = 0; virtual void generateMipmaps() = 0;
......
...@@ -35,10 +35,10 @@ class ImageD3D : public Image ...@@ -35,10 +35,10 @@ class ImageD3D : public Image
virtual bool isDirty() const = 0; virtual bool isDirty() const = 0;
virtual void setManagedSurface2D(TextureStorage *storage, int level) {}; virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level) {}; virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level) { return gl::Error(GL_NO_ERROR); };
virtual void setManagedSurface3D(TextureStorage *storage, int level) {}; virtual gl::Error setManagedSurface3D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
virtual void setManagedSurface2DArray(TextureStorage *storage, int layer, int level) {}; virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); };
virtual gl::Error copyToStorage2D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0; virtual gl::Error copyToStorage2D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
virtual gl::Error copyToStorageCube(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0; virtual gl::Error copyToStorageCube(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
virtual gl::Error copyToStorage3D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0; virtual gl::Error copyToStorage3D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
......
...@@ -378,28 +378,43 @@ bool TextureD3D::isBaseImageZeroSize() const ...@@ -378,28 +378,43 @@ bool TextureD3D::isBaseImageZeroSize() const
return false; return false;
} }
bool TextureD3D::ensureRenderTarget() gl::Error TextureD3D::ensureRenderTarget()
{ {
initializeStorage(true); gl::Error error = initializeStorage(true);
if (error.isError())
{
return error;
}
if (!isBaseImageZeroSize()) if (!isBaseImageZeroSize())
{ {
ASSERT(mTexStorage); ASSERT(mTexStorage);
if (!mTexStorage->isRenderTarget()) if (!mTexStorage->isRenderTarget())
{ {
TextureStorage *newRenderTargetStorage = createCompleteStorage(true); TextureStorage *newRenderTargetStorage = NULL;
error = createCompleteStorage(true, &newRenderTargetStorage);
if (error.isError())
{
return error;
}
if (mTexStorage->copyToStorage(newRenderTargetStorage).isError()) error = mTexStorage->copyToStorage(newRenderTargetStorage);
if (error.isError())
{ {
delete newRenderTargetStorage; SafeDelete(newRenderTargetStorage);
return gl::error(GL_OUT_OF_MEMORY, false); return error;
} }
setCompleteTexStorage(newRenderTargetStorage); error = setCompleteTexStorage(newRenderTargetStorage);
if (error.isError())
{
SafeDelete(newRenderTargetStorage);
return error;
}
} }
} }
return (mTexStorage && mTexStorage->isRenderTarget()); return gl::Error(GL_NO_ERROR);
} }
TextureD3D_2D::TextureD3D_2D(Renderer *renderer) TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
...@@ -597,7 +612,8 @@ gl::Error TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xo ...@@ -597,7 +612,8 @@ gl::Error TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xo
return commitRegion(index, region); return commitRegion(index, region);
} }
void TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) gl::Error TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
gl::Framebuffer *source)
{ {
ASSERT(target == GL_TEXTURE_2D); ASSERT(target == GL_TEXTURE_2D);
...@@ -608,22 +624,39 @@ void TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x ...@@ -608,22 +624,39 @@ void TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x
if (!mImageArray[level]->isRenderableFormat()) if (!mImageArray[level]->isRenderableFormat())
{ {
mImageArray[level]->copy(0, 0, 0, sourceRect, source); gl::Error error = mImageArray[level]->copy(0, 0, 0, sourceRect, source);
if (error.isError())
{
return error;
}
mDirtyImages = true; mDirtyImages = true;
} }
else else
{ {
ensureRenderTarget(); gl::Error error = ensureRenderTarget();
if (error.isError())
{
return error;
}
mImageArray[level]->markClean(); mImageArray[level]->markClean();
if (width != 0 && height != 0 && isValidLevel(level)) if (width != 0 && height != 0 && isValidLevel(level))
{ {
mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level); gl::Error error = mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) gl::Error TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{ {
ASSERT(target == GL_TEXTURE_2D && zoffset == 0); ASSERT(target == GL_TEXTURE_2D && zoffset == 0);
...@@ -635,22 +668,41 @@ void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLin ...@@ -635,22 +668,41 @@ void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLin
if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
{ {
mImageArray[level]->copy(xoffset, yoffset, 0, sourceRect, source); gl::Error error = mImageArray[level]->copy(xoffset, yoffset, 0, sourceRect, source);
if (error.isError())
{
return error;
}
mDirtyImages = true; mDirtyImages = true;
} }
else else
{ {
ensureRenderTarget(); gl::Error error = ensureRenderTarget();
if (error.isError())
{
return error;
}
if (isValidLevel(level)) if (isValidLevel(level))
{ {
updateStorageLevel(level); error = updateStorageLevel(level);
if (error.isError())
{
return error;
}
mRenderer->copyImage2D(source, sourceRect, error = mRenderer->copyImage2D(source, sourceRect,
gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
xoffset, yoffset, mTexStorage, level); xoffset, yoffset, mTexStorage, level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
...@@ -720,7 +772,7 @@ void TextureD3D_2D::initMipmapsImages() ...@@ -720,7 +772,7 @@ void TextureD3D_2D::initMipmapsImages()
unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index) unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index)
{ {
ASSERT(!index.hasLayer()); ASSERT(!index.hasLayer());
return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
} }
RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index) RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index)
...@@ -728,12 +780,18 @@ RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index) ...@@ -728,12 +780,18 @@ RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index)
ASSERT(!index.hasLayer()); ASSERT(!index.hasLayer());
// ensure the underlying texture is created // ensure the underlying texture is created
if (!ensureRenderTarget()) gl::Error error = ensureRenderTarget();
if (error.isError())
{
return NULL;
}
error = updateStorageLevel(index.mipIndex);
if (error.isError())
{ {
return NULL; return NULL;
} }
updateStorageLevel(index.mipIndex);
return mTexStorage->getRenderTarget(index); return mTexStorage->getRenderTarget(index);
} }
...@@ -787,30 +845,49 @@ bool TextureD3D_2D::isLevelComplete(int level) const ...@@ -787,30 +845,49 @@ bool TextureD3D_2D::isLevelComplete(int level) const
} }
// Constructs a native texture resource from the texture images // Constructs a native texture resource from the texture images
void TextureD3D_2D::initializeStorage(bool renderTarget) gl::Error TextureD3D_2D::initializeStorage(bool renderTarget)
{ {
// Only initialize the first time this texture is used as a render target or shader resource // Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage) if (mTexStorage)
{ {
return; return gl::Error(GL_NO_ERROR);
} }
// do not attempt to create storage for nonexistant data // do not attempt to create storage for nonexistant data
if (!isLevelComplete(0)) if (!isLevelComplete(0))
{ {
return; return gl::Error(GL_NO_ERROR);
} }
bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
setCompleteTexStorage(createCompleteStorage(createRenderTarget)); TextureStorage *storage = NULL;
gl::Error error = createCompleteStorage(createRenderTarget, &storage);
if (error.isError())
{
return error;
}
error = setCompleteTexStorage(storage);
if (error.isError())
{
SafeDelete(storage);
return error;
}
ASSERT(mTexStorage); ASSERT(mTexStorage);
// flush image data to the storage // flush image data to the storage
updateStorage(); error = updateStorage();
if (error.isError())
{
return error;
}
return gl::Error(GL_NO_ERROR);
} }
TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const
{ {
GLsizei width = getBaseLevelWidth(); GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight(); GLsizei height = getBaseLevelHeight();
...@@ -821,26 +898,35 @@ TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const ...@@ -821,26 +898,35 @@ TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D // use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
return mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels); // TODO(geofflang): Determine if the texture creation succeeded
*outTexStorage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels);
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) gl::Error TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{ {
SafeDelete(mTexStorage); if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
mTexStorage = newCompleteTexStorage;
if (mTexStorage && mTexStorage->isManaged())
{ {
for (int level = 0; level < mTexStorage->getLevelCount(); level++) for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
{ {
mImageArray[level]->setManagedSurface2D(mTexStorage, level); gl::Error error = mImageArray[level]->setManagedSurface2D(newCompleteTexStorage, level);
if (error.isError())
{
return error;
}
} }
} }
SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage;
mDirtyImages = true; mDirtyImages = true;
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2D::updateStorage() gl::Error TextureD3D_2D::updateStorage()
{ {
ASSERT(mTexStorage != NULL); ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount(); GLint storageLevels = mTexStorage->getLevelCount();
...@@ -848,12 +934,18 @@ void TextureD3D_2D::updateStorage() ...@@ -848,12 +934,18 @@ void TextureD3D_2D::updateStorage()
{ {
if (mImageArray[level]->isDirty() && isLevelComplete(level)) if (mImageArray[level]->isDirty() && isLevelComplete(level))
{ {
updateStorageLevel(level); gl::Error error = updateStorageLevel(level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2D::updateStorageLevel(int level) gl::Error TextureD3D_2D::updateStorageLevel(int level)
{ {
ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL); ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
ASSERT(isLevelComplete(level)); ASSERT(isLevelComplete(level));
...@@ -862,8 +954,14 @@ void TextureD3D_2D::updateStorageLevel(int level) ...@@ -862,8 +954,14 @@ void TextureD3D_2D::updateStorageLevel(int level)
{ {
gl::ImageIndex index = gl::ImageIndex::Make2D(level); gl::ImageIndex index = gl::ImageIndex::Make2D(level);
gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1); gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
commitRegion(index, region); gl::Error error = commitRegion(index, region);
if (error.isError())
{
return error;
}
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height) void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height)
...@@ -1042,7 +1140,8 @@ gl::Error TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint ...@@ -1042,7 +1140,8 @@ gl::Error TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint
return commitRegion(index, region); return commitRegion(index, region);
} }
void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) gl::Error TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
GLsizei width, GLsizei height, gl::Framebuffer *source)
{ {
int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
...@@ -1053,24 +1152,41 @@ void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint ...@@ -1053,24 +1152,41 @@ void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint
if (!mImageArray[faceIndex][level]->isRenderableFormat()) if (!mImageArray[faceIndex][level]->isRenderableFormat())
{ {
mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source); gl::Error error = mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
if (error.isError())
{
return error;
}
mDirtyImages = true; mDirtyImages = true;
} }
else else
{ {
ensureRenderTarget(); gl::Error error = ensureRenderTarget();
if (error.isError())
{
return error;
}
mImageArray[faceIndex][level]->markClean(); mImageArray[faceIndex][level]->markClean();
ASSERT(width == height); ASSERT(width == height);
if (width > 0 && isValidFaceLevel(faceIndex, level)) if (width > 0 && isValidFaceLevel(faceIndex, level))
{ {
mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level); error = mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) gl::Error TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{ {
int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
...@@ -1083,21 +1199,40 @@ void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GL ...@@ -1083,21 +1199,40 @@ void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GL
if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
{ {
mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source); gl::Error error =mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
if (error.isError())
{
return error;
}
mDirtyImages = true; mDirtyImages = true;
} }
else else
{ {
ensureRenderTarget(); gl::Error error = ensureRenderTarget();
if (error.isError())
{
return error;
}
if (isValidFaceLevel(faceIndex, level)) if (isValidFaceLevel(faceIndex, level))
{ {
updateStorageFaceLevel(faceIndex, level); error = updateStorageFaceLevel(faceIndex, level);
if (error.isError())
{
return error;
}
mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, error = mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
xoffset, yoffset, mTexStorage, target, level); xoffset, yoffset, mTexStorage, target, level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
...@@ -1183,7 +1318,7 @@ void TextureD3D_Cube::initMipmapsImages() ...@@ -1183,7 +1318,7 @@ void TextureD3D_Cube::initMipmapsImages()
unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index) unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index)
{ {
return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); return (ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
} }
RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index) RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index)
...@@ -1191,39 +1326,64 @@ RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index) ...@@ -1191,39 +1326,64 @@ RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index)
ASSERT(gl::IsCubemapTextureTarget(index.type)); ASSERT(gl::IsCubemapTextureTarget(index.type));
// ensure the underlying texture is created // ensure the underlying texture is created
if (!ensureRenderTarget()) gl::Error error = ensureRenderTarget();
if (error.isError())
{
return NULL;
}
error = updateStorageFaceLevel(index.layerIndex, index.mipIndex);
if (error.isError())
{ {
return NULL; return NULL;
} }
updateStorageFaceLevel(index.layerIndex, index.mipIndex);
return mTexStorage->getRenderTarget(index); return mTexStorage->getRenderTarget(index);
} }
void TextureD3D_Cube::initializeStorage(bool renderTarget) gl::Error TextureD3D_Cube::initializeStorage(bool renderTarget)
{ {
// Only initialize the first time this texture is used as a render target or shader resource // Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage) if (mTexStorage)
{ {
return; return gl::Error(GL_NO_ERROR);
} }
// do not attempt to create storage for nonexistant data // do not attempt to create storage for nonexistant data
if (!isFaceLevelComplete(0, 0)) if (!isFaceLevelComplete(0, 0))
{ {
return; return gl::Error(GL_NO_ERROR);
} }
bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
setCompleteTexStorage(createCompleteStorage(createRenderTarget)); TextureStorage *storage = NULL;
gl::Error error = createCompleteStorage(createRenderTarget, &storage);
if (error.isError())
{
return error;
}
error = setCompleteTexStorage(storage);
if (error.isError())
{
SafeDelete(storage);
return error;
}
ASSERT(mTexStorage); ASSERT(mTexStorage);
// flush image data to the storage // flush image data to the storage
updateStorage(); error = updateStorage();
if (error.isError())
{
return error;
}
return gl::Error(GL_NO_ERROR);
} }
TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const gl::Error TextureD3D_Cube::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const
{ {
GLsizei size = getBaseLevelWidth(); GLsizei size = getBaseLevelWidth();
...@@ -1232,29 +1392,37 @@ TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const ...@@ -1232,29 +1392,37 @@ TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D // use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1)); GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
return mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels); // TODO (geofflang): detect if storage creation succeeded
*outTexStorage = mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels);
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) gl::Error TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{ {
SafeDelete(mTexStorage); if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
mTexStorage = newCompleteTexStorage;
if (mTexStorage && mTexStorage->isManaged())
{ {
for (int faceIndex = 0; faceIndex < 6; faceIndex++) for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{ {
for (int level = 0; level < mTexStorage->getLevelCount(); level++) for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
{ {
mImageArray[faceIndex][level]->setManagedSurfaceCube(mTexStorage, faceIndex, level); gl::Error error = mImageArray[faceIndex][level]->setManagedSurfaceCube(newCompleteTexStorage, faceIndex, level);
if (error.isError())
{
return error;
}
} }
} }
} }
SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage;
mDirtyImages = true; mDirtyImages = true;
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_Cube::updateStorage() gl::Error TextureD3D_Cube::updateStorage()
{ {
ASSERT(mTexStorage != NULL); ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount(); GLint storageLevels = mTexStorage->getLevelCount();
...@@ -1264,10 +1432,16 @@ void TextureD3D_Cube::updateStorage() ...@@ -1264,10 +1432,16 @@ void TextureD3D_Cube::updateStorage()
{ {
if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level)) if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
{ {
updateStorageFaceLevel(face, level); gl::Error error = updateStorageFaceLevel(face, level);
if (error.isError())
{
return error;
}
} }
} }
} }
return gl::Error(GL_NO_ERROR);
} }
bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
...@@ -1315,7 +1489,7 @@ bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const ...@@ -1315,7 +1489,7 @@ bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
return true; return true;
} }
void TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level) gl::Error TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
{ {
ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL); ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
ImageD3D *image = mImageArray[faceIndex][level]; ImageD3D *image = mImageArray[faceIndex][level];
...@@ -1325,8 +1499,14 @@ void TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level) ...@@ -1325,8 +1499,14 @@ void TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
GLenum faceTarget = gl::TextureCubeMap::layerIndexToTarget(faceIndex); GLenum faceTarget = gl::TextureCubeMap::layerIndexToTarget(faceIndex);
gl::ImageIndex index = gl::ImageIndex::MakeCube(faceTarget, level); gl::ImageIndex index = gl::ImageIndex::MakeCube(faceTarget, level);
gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1); gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1);
commitRegion(index, region); gl::Error error = commitRegion(index, region);
if (error.isError())
{
return error;
}
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height) void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height)
...@@ -1592,12 +1772,15 @@ gl::Error TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xo ...@@ -1592,12 +1772,15 @@ gl::Error TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xo
return commitRegion(index, region); return commitRegion(index, region);
} }
void TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) gl::Error TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
GLsizei width, GLsizei height, gl::Framebuffer *source)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION, "Copying 3D textures is unimplemented.");
} }
void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) gl::Error TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{ {
ASSERT(target == GL_TEXTURE_3D); ASSERT(target == GL_TEXTURE_3D);
...@@ -1609,22 +1792,41 @@ void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLin ...@@ -1609,22 +1792,41 @@ void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLin
if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
{ {
mImageArray[level]->copy(xoffset, yoffset, zoffset, sourceRect, source); gl::Error error = mImageArray[level]->copy(xoffset, yoffset, zoffset, sourceRect, source);
if (error.isError())
{
return error;
}
mDirtyImages = true; mDirtyImages = true;
} }
else else
{ {
ensureRenderTarget(); gl::Error error = ensureRenderTarget();
if (error.isError())
{
return error;
}
if (isValidLevel(level)) if (isValidLevel(level))
{ {
updateStorageLevel(level); error = updateStorageLevel(level);
if (error.isError())
{
return error;
}
mRenderer->copyImage3D(source, sourceRect, error = mRenderer->copyImage3D(source, sourceRect,
gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
xoffset, yoffset, zoffset, mTexStorage, level); xoffset, yoffset, zoffset, mTexStorage, level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
...@@ -1677,53 +1879,81 @@ void TextureD3D_3D::initMipmapsImages() ...@@ -1677,53 +1879,81 @@ void TextureD3D_3D::initMipmapsImages()
unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index) unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index)
{ {
return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
} }
RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index) RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index)
{ {
// ensure the underlying texture is created // ensure the underlying texture is created
if (!ensureRenderTarget()) gl::Error error = ensureRenderTarget();
if (error.isError())
{ {
return NULL; return NULL;
} }
if (index.hasLayer()) if (index.hasLayer())
{ {
updateStorage(); error = updateStorage();
if (error.isError())
{
return NULL;
}
} }
else else
{ {
updateStorageLevel(index.mipIndex); error = updateStorageLevel(index.mipIndex);
if (error.isError())
{
return NULL;
}
} }
return mTexStorage->getRenderTarget(index); return mTexStorage->getRenderTarget(index);
} }
void TextureD3D_3D::initializeStorage(bool renderTarget) gl::Error TextureD3D_3D::initializeStorage(bool renderTarget)
{ {
// Only initialize the first time this texture is used as a render target or shader resource // Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage) if (mTexStorage)
{ {
return; return gl::Error(GL_NO_ERROR);
} }
// do not attempt to create storage for nonexistant data // do not attempt to create storage for nonexistant data
if (!isLevelComplete(0)) if (!isLevelComplete(0))
{ {
return; return gl::Error(GL_NO_ERROR);
} }
bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
setCompleteTexStorage(createCompleteStorage(createRenderTarget)); rx::TextureStorage *storage = NULL;
gl::Error error = createCompleteStorage(createRenderTarget, &storage);
if (error.isError())
{
return error;
}
error = setCompleteTexStorage(storage);
if (error.isError())
{
SafeDelete(storage);
return error;
}
ASSERT(mTexStorage); ASSERT(mTexStorage);
// flush image data to the storage // flush image data to the storage
updateStorage(); error = updateStorage();
if (error.isError())
{
return error;
}
return gl::Error(GL_NO_ERROR);
} }
TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const gl::Error TextureD3D_3D::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const
{ {
GLsizei width = getBaseLevelWidth(); GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight(); GLsizei height = getBaseLevelHeight();
...@@ -1735,10 +1965,13 @@ TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const ...@@ -1735,10 +1965,13 @@ TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D // use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth)); GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth));
return mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels); // TODO: Verify creation of the storage succeeded
*outStorage = mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels);
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) gl::Error TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{ {
SafeDelete(mTexStorage); SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage; mTexStorage = newCompleteTexStorage;
...@@ -1746,9 +1979,11 @@ void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) ...@@ -1746,9 +1979,11 @@ void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
// We do not support managed 3D storage, as that is D3D9/ES2-only // We do not support managed 3D storage, as that is D3D9/ES2-only
ASSERT(!mTexStorage->isManaged()); ASSERT(!mTexStorage->isManaged());
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_3D::updateStorage() gl::Error TextureD3D_3D::updateStorage()
{ {
ASSERT(mTexStorage != NULL); ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount(); GLint storageLevels = mTexStorage->getLevelCount();
...@@ -1756,9 +1991,15 @@ void TextureD3D_3D::updateStorage() ...@@ -1756,9 +1991,15 @@ void TextureD3D_3D::updateStorage()
{ {
if (mImageArray[level]->isDirty() && isLevelComplete(level)) if (mImageArray[level]->isDirty() && isLevelComplete(level))
{ {
updateStorageLevel(level); gl::Error error = updateStorageLevel(level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
bool TextureD3D_3D::isValidLevel(int level) const bool TextureD3D_3D::isValidLevel(int level) const
...@@ -1814,7 +2055,7 @@ bool TextureD3D_3D::isLevelComplete(int level) const ...@@ -1814,7 +2055,7 @@ bool TextureD3D_3D::isLevelComplete(int level) const
return true; return true;
} }
void TextureD3D_3D::updateStorageLevel(int level) gl::Error TextureD3D_3D::updateStorageLevel(int level)
{ {
ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL); ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
ASSERT(isLevelComplete(level)); ASSERT(isLevelComplete(level));
...@@ -1823,8 +2064,14 @@ void TextureD3D_3D::updateStorageLevel(int level) ...@@ -1823,8 +2064,14 @@ void TextureD3D_3D::updateStorageLevel(int level)
{ {
gl::ImageIndex index = gl::ImageIndex::Make3D(level); gl::ImageIndex index = gl::ImageIndex::Make3D(level);
gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
commitRegion(index, region); gl::Error error = commitRegion(index, region);
if (error.isError())
{
return error;
}
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
...@@ -2060,12 +2307,13 @@ gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLi ...@@ -2060,12 +2307,13 @@ gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLi
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) gl::Error TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION, "Copying 2D array textures is unimplemented.");
} }
void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{ {
ASSERT(target == GL_TEXTURE_2D_ARRAY); ASSERT(target == GL_TEXTURE_2D_ARRAY);
...@@ -2077,21 +2325,39 @@ void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, ...@@ -2077,21 +2325,39 @@ void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset,
if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
{ {
mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, sourceRect, source); gl::Error error = mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, sourceRect, source);
if (error.isError())
{
return error;
}
mDirtyImages = true; mDirtyImages = true;
} }
else else
{ {
ensureRenderTarget(); gl::Error error = ensureRenderTarget();
if (error.isError())
{
return error;
}
if (isValidLevel(level)) if (isValidLevel(level))
{ {
updateStorageLevel(level); error = updateStorageLevel(level);
if (error.isError())
{
return error;
}
mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format, error = mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
xoffset, yoffset, zoffset, mTexStorage, level); xoffset, yoffset, zoffset, mTexStorage, level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
...@@ -2156,45 +2422,70 @@ void TextureD3D_2DArray::initMipmapsImages() ...@@ -2156,45 +2422,70 @@ void TextureD3D_2DArray::initMipmapsImages()
unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index) unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index)
{ {
return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
} }
RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index) RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index)
{ {
// ensure the underlying texture is created // ensure the underlying texture is created
if (!ensureRenderTarget()) gl::Error error = ensureRenderTarget();
if (error.isError())
{
return NULL;
}
error = updateStorageLevel(index.mipIndex);
if (error.isError())
{ {
return NULL; return NULL;
} }
updateStorageLevel(index.mipIndex);
return mTexStorage->getRenderTarget(index); return mTexStorage->getRenderTarget(index);
} }
void TextureD3D_2DArray::initializeStorage(bool renderTarget) gl::Error TextureD3D_2DArray::initializeStorage(bool renderTarget)
{ {
// Only initialize the first time this texture is used as a render target or shader resource // Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage) if (mTexStorage)
{ {
return; return gl::Error(GL_NO_ERROR);
} }
// do not attempt to create storage for nonexistant data // do not attempt to create storage for nonexistant data
if (!isLevelComplete(0)) if (!isLevelComplete(0))
{ {
return; return gl::Error(GL_NO_ERROR);
} }
bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
setCompleteTexStorage(createCompleteStorage(createRenderTarget)); TextureStorage *storage = NULL;
gl::Error error = createCompleteStorage(createRenderTarget, &storage);
if (error.isError())
{
return error;
}
error = setCompleteTexStorage(storage);
if (error.isError())
{
SafeDelete(storage);
return error;
}
ASSERT(mTexStorage); ASSERT(mTexStorage);
// flush image data to the storage // flush image data to the storage
updateStorage(); error = updateStorage();
if (error.isError())
{
return error;
}
return gl::Error(GL_NO_ERROR);
} }
TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) const gl::Error TextureD3D_2DArray::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const
{ {
GLsizei width = getBaseLevelWidth(); GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight(); GLsizei height = getBaseLevelHeight();
...@@ -2206,10 +2497,13 @@ TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) con ...@@ -2206,10 +2497,13 @@ TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) con
// use existing storage level count, when previously specified by TexStorage*D // use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
return mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels); // TODO(geofflang): Verify storage creation succeeds
*outStorage = mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels);
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) gl::Error TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{ {
SafeDelete(mTexStorage); SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage; mTexStorage = newCompleteTexStorage;
...@@ -2217,9 +2511,11 @@ void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexSto ...@@ -2217,9 +2511,11 @@ void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexSto
// We do not support managed 2D array storage, as managed storage is ES2/D3D9 only // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
ASSERT(!mTexStorage->isManaged()); ASSERT(!mTexStorage->isManaged());
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2DArray::updateStorage() gl::Error TextureD3D_2DArray::updateStorage()
{ {
ASSERT(mTexStorage != NULL); ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount(); GLint storageLevels = mTexStorage->getLevelCount();
...@@ -2227,9 +2523,15 @@ void TextureD3D_2DArray::updateStorage() ...@@ -2227,9 +2523,15 @@ void TextureD3D_2DArray::updateStorage()
{ {
if (isLevelComplete(level)) if (isLevelComplete(level))
{ {
updateStorageLevel(level); gl::Error error = updateStorageLevel(level);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
bool TextureD3D_2DArray::isValidLevel(int level) const bool TextureD3D_2DArray::isValidLevel(int level) const
...@@ -2283,7 +2585,7 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const ...@@ -2283,7 +2585,7 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const
return true; return true;
} }
void TextureD3D_2DArray::updateStorageLevel(int level) gl::Error TextureD3D_2DArray::updateStorageLevel(int level)
{ {
ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts)); ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts));
ASSERT(isLevelComplete(level)); ASSERT(isLevelComplete(level));
...@@ -2295,9 +2597,15 @@ void TextureD3D_2DArray::updateStorageLevel(int level) ...@@ -2295,9 +2597,15 @@ void TextureD3D_2DArray::updateStorageLevel(int level)
{ {
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1); gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
commitRegion(index, region); gl::Error error = commitRegion(index, region);
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
void TextureD3D_2DArray::deleteImages() void TextureD3D_2DArray::deleteImages()
......
...@@ -78,10 +78,10 @@ class TextureD3D : public TextureImpl ...@@ -78,10 +78,10 @@ class TextureD3D : public TextureImpl
virtual void initMipmapsImages() = 0; virtual void initMipmapsImages() = 0;
bool isBaseImageZeroSize() const; bool isBaseImageZeroSize() const;
virtual bool ensureRenderTarget(); virtual gl::Error ensureRenderTarget();
virtual TextureStorage *createCompleteStorage(bool renderTarget) const = 0; virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const = 0;
virtual void setCompleteTexStorage(TextureStorage *newCompleteTexStorage) = 0; virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage) = 0;
virtual gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region) = 0; virtual gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region) = 0;
Renderer *mRenderer; Renderer *mRenderer;
...@@ -96,9 +96,9 @@ class TextureD3D : public TextureImpl ...@@ -96,9 +96,9 @@ class TextureD3D : public TextureImpl
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D); DISALLOW_COPY_AND_ASSIGN(TextureD3D);
virtual void initializeStorage(bool renderTarget) = 0; virtual gl::Error initializeStorage(bool renderTarget) = 0;
virtual void updateStorage() = 0; virtual gl::Error updateStorage() = 0;
}; };
class TextureD3D_2D : public TextureD3D class TextureD3D_2D : public TextureD3D
...@@ -121,8 +121,8 @@ class TextureD3D_2D : public TextureD3D ...@@ -121,8 +121,8 @@ class TextureD3D_2D : public TextureD3D
virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); 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);
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface); virtual void bindTexImage(egl::Surface *surface);
...@@ -137,18 +137,18 @@ class TextureD3D_2D : public TextureD3D ...@@ -137,18 +137,18 @@ class TextureD3D_2D : public TextureD3D
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D); DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
virtual void initializeStorage(bool renderTarget); virtual gl::Error initializeStorage(bool renderTarget);
virtual TextureStorage *createCompleteStorage(bool renderTarget) const; gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const;
virtual void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region); gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region);
virtual void updateStorage(); virtual gl::Error updateStorage();
virtual void initMipmapsImages(); virtual void initMipmapsImages();
bool isValidLevel(int level) const; bool isValidLevel(int level) const;
bool isLevelComplete(int level) const; bool isLevelComplete(int level) const;
void updateStorageLevel(int level); gl::Error updateStorageLevel(int level);
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height); void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
...@@ -176,8 +176,8 @@ class TextureD3D_Cube : public TextureD3D ...@@ -176,8 +176,8 @@ class TextureD3D_Cube : public TextureD3D
virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); 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);
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface); virtual void bindTexImage(egl::Surface *surface);
...@@ -192,18 +192,18 @@ class TextureD3D_Cube : public TextureD3D ...@@ -192,18 +192,18 @@ class TextureD3D_Cube : public TextureD3D
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube); DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
virtual void initializeStorage(bool renderTarget); virtual gl::Error initializeStorage(bool renderTarget);
virtual TextureStorage *createCompleteStorage(bool renderTarget) const; gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const;
virtual void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
virtual gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region); virtual gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region);
virtual void updateStorage(); virtual gl::Error updateStorage();
virtual void initMipmapsImages(); virtual void initMipmapsImages();
bool isValidFaceLevel(int faceIndex, int level) const; bool isValidFaceLevel(int faceIndex, int level) const;
bool isFaceLevelComplete(int faceIndex, int level) const; bool isFaceLevelComplete(int faceIndex, int level) const;
bool isCubeComplete() const; bool isCubeComplete() const;
void updateStorageFaceLevel(int faceIndex, int level); gl::Error updateStorageFaceLevel(int faceIndex, int level);
void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height); void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
...@@ -230,8 +230,8 @@ class TextureD3D_3D : public TextureD3D ...@@ -230,8 +230,8 @@ class TextureD3D_3D : public TextureD3D
virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); 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);
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface); virtual void bindTexImage(egl::Surface *surface);
...@@ -246,17 +246,17 @@ class TextureD3D_3D : public TextureD3D ...@@ -246,17 +246,17 @@ class TextureD3D_3D : public TextureD3D
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D); DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D);
virtual void initializeStorage(bool renderTarget); virtual gl::Error initializeStorage(bool renderTarget);
virtual TextureStorage *createCompleteStorage(bool renderTarget) const; gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const;
virtual void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
virtual gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region); virtual gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region);
virtual void updateStorage(); virtual gl::Error updateStorage();
virtual void initMipmapsImages(); virtual void initMipmapsImages();
bool isValidLevel(int level) const; bool isValidLevel(int level) const;
bool isLevelComplete(int level) const; bool isLevelComplete(int level) const;
void updateStorageLevel(int level); gl::Error updateStorageLevel(int level);
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
...@@ -282,8 +282,8 @@ class TextureD3D_2DArray : public TextureD3D ...@@ -282,8 +282,8 @@ class TextureD3D_2DArray : public TextureD3D
virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); 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);
virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface); virtual void bindTexImage(egl::Surface *surface);
...@@ -298,17 +298,17 @@ class TextureD3D_2DArray : public TextureD3D ...@@ -298,17 +298,17 @@ class TextureD3D_2DArray : public TextureD3D
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray); DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray);
virtual void initializeStorage(bool renderTarget); virtual gl::Error initializeStorage(bool renderTarget);
virtual TextureStorage *createCompleteStorage(bool renderTarget) const; gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const;
virtual void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
virtual gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region); virtual gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region);
virtual void updateStorage(); virtual gl::Error updateStorage();
virtual void initMipmapsImages(); virtual void initMipmapsImages();
bool isValidLevel(int level) const; bool isValidLevel(int level) const;
bool isLevelComplete(int level) const; bool isLevelComplete(int level) const;
void updateStorageLevel(int level); gl::Error updateStorageLevel(int level);
void deleteImages(); void deleteImages();
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
......
...@@ -321,7 +321,7 @@ gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffse ...@@ -321,7 +321,7 @@ gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffse
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source)
{ {
RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(source); RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(source);
ASSERT(sourceRenderTarget->getTexture()); ASSERT(sourceRenderTarget->getTexture());
...@@ -331,16 +331,17 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan ...@@ -331,16 +331,17 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan
if (!sourceTexture2D) if (!sourceTexture2D)
{ {
// Error already generated return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source RenderTarget.");
return;
} }
copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex); gl::Error error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex);
SafeRelease(sourceTexture2D); SafeRelease(sourceTexture2D);
return error;
} }
void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source) gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source)
{ {
TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source); TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source);
...@@ -349,16 +350,17 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan ...@@ -349,16 +350,17 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan
if (!sourceTexture2D) if (!sourceTexture2D)
{ {
// Error already generated return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source TextureStorage.");
return;
} }
copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex); gl::Error error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex);
SafeRelease(sourceTexture2D); SafeRelease(sourceTexture2D);
return error;
} }
void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource) gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource)
{ {
D3D11_TEXTURE2D_DESC textureDesc; D3D11_TEXTURE2D_DESC textureDesc;
source->GetDesc(&textureDesc); source->GetDesc(&textureDesc);
...@@ -390,8 +392,7 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan ...@@ -390,8 +392,7 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan
HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
return;
} }
deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, textureDesc.Format); deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, textureDesc.Format);
...@@ -424,8 +425,7 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan ...@@ -424,8 +425,7 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan
HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result); return gl::Error(GL_OUT_OF_MEMORY, "Failed to map texture for Image11::copy, HRESULT: 0x%X.", result);
return;
} }
// determine the offset coordinate into the destination buffer // determine the offset coordinate into the destination buffer
...@@ -434,12 +434,19 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan ...@@ -434,12 +434,19 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectan
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); gl::Error error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
unmap(); unmap();
if (error.isError())
{
return error;
}
} }
mDirty = true; mDirty = true;
return gl::Error(GL_NO_ERROR);
} }
ID3D11Resource *Image11::getStagingTexture() ID3D11Resource *Image11::getStagingTexture()
......
...@@ -52,9 +52,9 @@ class Image11 : public ImageD3D ...@@ -52,9 +52,9 @@ class Image11 : public ImageD3D
virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
const void *input); const void *input);
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source); virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source);
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
const gl::ImageIndex &sourceIndex, TextureStorage *source); const gl::ImageIndex &sourceIndex, TextureStorage *source);
bool recoverFromAssociatedStorage(); bool recoverFromAssociatedStorage();
bool isAssociatedStorageValid(TextureStorage11* textureStorage) const; bool isAssociatedStorageValid(TextureStorage11* textureStorage) const;
...@@ -68,7 +68,7 @@ class Image11 : public ImageD3D ...@@ -68,7 +68,7 @@ class Image11 : public ImageD3D
DISALLOW_COPY_AND_ASSIGN(Image11); DISALLOW_COPY_AND_ASSIGN(Image11);
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);
void 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(); ID3D11Resource *getStagingTexture();
unsigned int getStagingSubresource(); unsigned int getStagingSubresource();
......
...@@ -92,35 +92,47 @@ void Image9::generateMipmap(Image9 *dest, Image9 *source) ...@@ -92,35 +92,47 @@ void Image9::generateMipmap(Image9 *dest, Image9 *source)
dest->markDirty(); dest->markDirty();
} }
void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source) gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
{ {
D3DLOCKED_RECT sourceLock = {0}; D3DLOCKED_RECT sourceLock = {0};
D3DLOCKED_RECT destLock = {0}; D3DLOCKED_RECT destLock = {0};
source->LockRect(&sourceLock, NULL, 0); HRESULT result;
dest->LockRect(&destLock, NULL, 0);
if (sourceLock.pBits && destLock.pBits) result = source->LockRect(&sourceLock, NULL, 0);
if (FAILED(result))
{ {
D3DSURFACE_DESC desc; return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result);
source->GetDesc(&desc); }
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); result = dest->LockRect(&destLock, NULL, 0);
unsigned int rows = desc.Height / d3dFormatInfo.blockHeight; if (FAILED(result))
{
source->UnlockRect();
return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result);
}
unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight); ASSERT(sourceLock.pBits && destLock.pBits);
ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
bytes <= static_cast<unsigned int>(destLock.Pitch));
for(unsigned int i = 0; i < rows; i++) D3DSURFACE_DESC desc;
{ source->GetDesc(&desc);
memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
}
source->UnlockRect(); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
dest->UnlockRect(); unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
bytes <= static_cast<unsigned int>(destLock.Pitch));
for(unsigned int i = 0; i < rows; i++)
{
memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
} }
else UNREACHABLE();
source->UnlockRect();
dest->UnlockRect();
return gl::Error(GL_NO_ERROR);
} }
bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
...@@ -270,19 +282,19 @@ IDirect3DSurface9 *Image9::getSurface() ...@@ -270,19 +282,19 @@ IDirect3DSurface9 *Image9::getSurface()
return mSurface; return mSurface;
} }
void Image9::setManagedSurface2D(TextureStorage *storage, int level) gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level)
{ {
TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
setManagedSurface(storage9->getSurfaceLevel(level, false)); return setManagedSurface(storage9->getSurfaceLevel(level, false));
} }
void Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) gl::Error Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level)
{ {
TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false)); return setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
} }
void Image9::setManagedSurface(IDirect3DSurface9 *surface) gl::Error Image9::setManagedSurface(IDirect3DSurface9 *surface)
{ {
D3DSURFACE_DESC desc; D3DSURFACE_DESC desc;
surface->GetDesc(&desc); surface->GetDesc(&desc);
...@@ -292,13 +304,19 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface) ...@@ -292,13 +304,19 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface)
{ {
if (mSurface) if (mSurface)
{ {
copyLockableSurfaces(surface, mSurface); gl::Error error = copyLockableSurfaces(surface, mSurface);
SafeRelease(mSurface); SafeRelease(mSurface);
if (error.isError())
{
return error;
}
} }
mSurface = surface; mSurface = surface;
mD3DPool = desc.Pool; mD3DPool = desc.Pool;
} }
return gl::Error(GL_NO_ERROR);
} }
gl::Error Image9::copyToStorage2D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) gl::Error Image9::copyToStorage2D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region)
...@@ -466,7 +484,7 @@ gl::Error Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset ...@@ -466,7 +484,7 @@ gl::Error Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset
} }
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source)
{ {
ASSERT(source); ASSERT(source);
...@@ -483,8 +501,7 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang ...@@ -483,8 +501,7 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang
if (!surface) if (!surface)
{ {
ERR("Failed to retrieve the render target."); return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal render target.");
return gl::error(GL_OUT_OF_MEMORY);
} }
IDirect3DDevice9 *device = mRenderer->getDevice(); IDirect3DDevice9 *device = mRenderer->getDevice();
...@@ -497,19 +514,17 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang ...@@ -497,19 +514,17 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Could not create matching destination surface.");
SafeRelease(surface); SafeRelease(surface);
return gl::error(GL_OUT_OF_MEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Could not create matching destination surface, result: 0x%X.", result);
} }
result = device->GetRenderTargetData(surface, renderTargetData); result = device->GetRenderTargetData(surface, renderTargetData);
if (FAILED(result)) if (FAILED(result))
{ {
ERR("GetRenderTargetData unexpectedly failed.");
SafeRelease(renderTargetData); SafeRelease(renderTargetData);
SafeRelease(surface); SafeRelease(surface);
return gl::error(GL_OUT_OF_MEMORY); return gl::Error(GL_OUT_OF_MEMORY, "GetRenderTargetData unexpectedly failed, result: 0x%X.", result);
} }
int width = sourceArea.width; int width = sourceArea.width;
...@@ -523,10 +538,9 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang ...@@ -523,10 +538,9 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Failed to lock the source surface (rectangle might be invalid).");
SafeRelease(renderTargetData); SafeRelease(renderTargetData);
SafeRelease(surface); SafeRelease(surface);
return gl::error(GL_OUT_OF_MEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface (rectangle might be invalid), result: 0x%X.", result);
} }
D3DLOCKED_RECT destLock = {0}; D3DLOCKED_RECT destLock = {0};
...@@ -534,178 +548,167 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang ...@@ -534,178 +548,167 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Failed to lock the destination surface (rectangle might be invalid).");
renderTargetData->UnlockRect(); renderTargetData->UnlockRect();
SafeRelease(renderTargetData); SafeRelease(renderTargetData);
SafeRelease(surface); SafeRelease(surface);
return gl::error(GL_OUT_OF_MEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the destination surface (rectangle might be invalid), result: 0x%X.", result);
} }
if (destLock.pBits && sourceLock.pBits) ASSERT(destLock.pBits && sourceLock.pBits);
{
unsigned char *source = (unsigned char*)sourceLock.pBits; unsigned char *sourcePixels = (unsigned char*)sourceLock.pBits;
unsigned char *dest = (unsigned char*)destLock.pBits; unsigned char *destPixels = (unsigned char*)destLock.pBits;
switch (description.Format) switch (description.Format)
{
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
switch (getD3DFormat())
{ {
case D3DFMT_X8R8G8B8: case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8: case D3DFMT_A8R8G8B8:
switch(getD3DFormat()) for (int y = 0; y < height; y++)
{ {
case D3DFMT_X8R8G8B8: memcpy(destPixels, sourcePixels, 4 * width);
case D3DFMT_A8R8G8B8: sourcePixels += sourceLock.Pitch;
for (int y = 0; y < height; y++) destPixels += destLock.Pitch;
{ }
memcpy(dest, source, 4 * width); break;
case D3DFMT_L8:
source += sourceLock.Pitch; for (int y = 0; y < height; y++)
dest += destLock.Pitch; {
} for (int x = 0; x < width; x++)
break;
case D3DFMT_L8:
for (int y = 0; y < height; y++)
{ {
for (int x = 0; x < width; x++) destPixels[x] = sourcePixels[x * 4 + 2];
{
dest[x] = source[x * 4 + 2];
}
source += sourceLock.Pitch;
dest += destLock.Pitch;
} }
break; sourcePixels += sourceLock.Pitch;
case D3DFMT_A8L8: destPixels += destLock.Pitch;
for (int y = 0; y < height; y++) }
break;
case D3DFMT_A8L8:
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{ {
for (int x = 0; x < width; x++) destPixels[x * 2 + 0] = sourcePixels[x * 4 + 2];
{ destPixels[x * 2 + 1] = sourcePixels[x * 4 + 3];
dest[x * 2 + 0] = source[x * 4 + 2];
dest[x * 2 + 1] = source[x * 4 + 3];
}
source += sourceLock.Pitch;
dest += destLock.Pitch;
} }
break; sourcePixels += sourceLock.Pitch;
default: destPixels += destLock.Pitch;
UNREACHABLE();
} }
break; break;
case D3DFMT_R5G6B5: default:
switch(getD3DFormat()) UNREACHABLE();
}
break;
case D3DFMT_R5G6B5:
switch (getD3DFormat())
{
case D3DFMT_X8R8G8B8:
for (int y = 0; y < height; y++)
{ {
case D3DFMT_X8R8G8B8: for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
{ {
for (int x = 0; x < width; x++) unsigned short rgb = ((unsigned short*)sourcePixels)[x];
{ unsigned char red = (rgb & 0xF800) >> 8;
unsigned short rgb = ((unsigned short*)source)[x]; unsigned char green = (rgb & 0x07E0) >> 3;
unsigned char red = (rgb & 0xF800) >> 8; unsigned char blue = (rgb & 0x001F) << 3;
unsigned char green = (rgb & 0x07E0) >> 3; destPixels[x + 0] = blue | (blue >> 5);
unsigned char blue = (rgb & 0x001F) << 3; destPixels[x + 1] = green | (green >> 6);
dest[x + 0] = blue | (blue >> 5); destPixels[x + 2] = red | (red >> 5);
dest[x + 1] = green | (green >> 6); destPixels[x + 3] = 0xFF;
dest[x + 2] = red | (red >> 5);
dest[x + 3] = 0xFF;
}
source += sourceLock.Pitch;
dest += destLock.Pitch;
} }
break; sourcePixels += sourceLock.Pitch;
case D3DFMT_L8: destPixels += destLock.Pitch;
for (int y = 0; y < height; y++) }
break;
case D3DFMT_L8:
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{ {
for (int x = 0; x < width; x++) unsigned char red = sourcePixels[x * 2 + 1] & 0xF8;
{ destPixels[x] = red | (red >> 5);
unsigned char red = source[x * 2 + 1] & 0xF8;
dest[x] = red | (red >> 5);
}
source += sourceLock.Pitch;
dest += destLock.Pitch;
} }
break; sourcePixels += sourceLock.Pitch;
default: destPixels += destLock.Pitch;
UNREACHABLE();
} }
break; break;
case D3DFMT_A1R5G5B5: default:
switch (getD3DFormat()) UNREACHABLE();
}
break;
case D3DFMT_A1R5G5B5:
switch (getD3DFormat())
{
case D3DFMT_X8R8G8B8:
for (int y = 0; y < height; y++)
{ {
case D3DFMT_X8R8G8B8: for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
{ {
for (int x = 0; x < width; x++) unsigned short argb = ((unsigned short*)sourcePixels)[x];
{ unsigned char red = (argb & 0x7C00) >> 7;
unsigned short argb = ((unsigned short*)source)[x]; unsigned char green = (argb & 0x03E0) >> 2;
unsigned char red = (argb & 0x7C00) >> 7; unsigned char blue = (argb & 0x001F) << 3;
unsigned char green = (argb & 0x03E0) >> 2; destPixels[x + 0] = blue | (blue >> 5);
unsigned char blue = (argb & 0x001F) << 3; destPixels[x + 1] = green | (green >> 5);
dest[x + 0] = blue | (blue >> 5); destPixels[x + 2] = red | (red >> 5);
dest[x + 1] = green | (green >> 5); destPixels[x + 3] = 0xFF;
dest[x + 2] = red | (red >> 5);
dest[x + 3] = 0xFF;
}
source += sourceLock.Pitch;
dest += destLock.Pitch;
} }
break; sourcePixels += sourceLock.Pitch;
case D3DFMT_A8R8G8B8: destPixels += destLock.Pitch;
for (int y = 0; y < height; y++) }
break;
case D3DFMT_A8R8G8B8:
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{ {
for (int x = 0; x < width; x++) unsigned short argb = ((unsigned short*)sourcePixels)[x];
{ unsigned char red = (argb & 0x7C00) >> 7;
unsigned short argb = ((unsigned short*)source)[x]; unsigned char green = (argb & 0x03E0) >> 2;
unsigned char red = (argb & 0x7C00) >> 7; unsigned char blue = (argb & 0x001F) << 3;
unsigned char green = (argb & 0x03E0) >> 2; unsigned char alpha = (signed short)argb >> 15;
unsigned char blue = (argb & 0x001F) << 3; destPixels[x + 0] = blue | (blue >> 5);
unsigned char alpha = (signed short)argb >> 15; destPixels[x + 1] = green | (green >> 5);
dest[x + 0] = blue | (blue >> 5); destPixels[x + 2] = red | (red >> 5);
dest[x + 1] = green | (green >> 5); destPixels[x + 3] = alpha;
dest[x + 2] = red | (red >> 5);
dest[x + 3] = alpha;
}
source += sourceLock.Pitch;
dest += destLock.Pitch;
} }
break; sourcePixels += sourceLock.Pitch;
case D3DFMT_L8: destPixels += destLock.Pitch;
for (int y = 0; y < height; y++) }
break;
case D3DFMT_L8:
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{ {
for (int x = 0; x < width; x++) unsigned char red = sourcePixels[x * 2 + 1] & 0x7C;
{ destPixels[x] = (red << 1) | (red >> 4);
unsigned char red = source[x * 2 + 1] & 0x7C;
dest[x] = (red << 1) | (red >> 4);
}
source += sourceLock.Pitch;
dest += destLock.Pitch;
} }
break; sourcePixels += sourceLock.Pitch;
case D3DFMT_A8L8: destPixels += destLock.Pitch;
for (int y = 0; y < height; y++) }
break;
case D3DFMT_A8L8:
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{ {
for (int x = 0; x < width; x++) unsigned char red = sourcePixels[x * 2 + 1] & 0x7C;
{ destPixels[x * 2 + 0] = (red << 1) | (red >> 4);
unsigned char red = source[x * 2 + 1] & 0x7C; destPixels[x * 2 + 1] = (signed char)sourcePixels[x * 2 + 1] >> 7;
dest[x * 2 + 0] = (red << 1) | (red >> 4);
dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
}
source += sourceLock.Pitch;
dest += destLock.Pitch;
} }
break; sourcePixels += sourceLock.Pitch;
default: destPixels += destLock.Pitch;
UNREACHABLE();
} }
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
break;
default:
UNREACHABLE();
} }
unlock(); unlock();
...@@ -715,12 +718,14 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang ...@@ -715,12 +718,14 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectang
SafeRelease(surface); SafeRelease(surface);
mDirty = true; mDirty = true;
return gl::Error(GL_NO_ERROR);
} }
void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage) gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage)
{ {
// Currently unreachable, due to only being used in a D3D11-only workaround // Currently unreachable, due to only being used in a D3D11-only workaround
UNIMPLEMENTED(); UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION);
} }
} }
...@@ -33,7 +33,7 @@ class Image9 : public ImageD3D ...@@ -33,7 +33,7 @@ class Image9 : public ImageD3D
static void generateMipmap(Image9 *dest, Image9 *source); static void generateMipmap(Image9 *dest, Image9 *source);
static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); 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); virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease);
...@@ -42,8 +42,8 @@ class Image9 : public ImageD3D ...@@ -42,8 +42,8 @@ class Image9 : public ImageD3D
virtual bool isDirty() const; virtual bool isDirty() const;
IDirect3DSurface9 *getSurface(); IDirect3DSurface9 *getSurface();
virtual void setManagedSurface2D(TextureStorage *storage, int level); virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level);
virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level); virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level);
virtual gl::Error copyToStorage2D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region); virtual gl::Error copyToStorage2D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
virtual gl::Error copyToStorageCube(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region); virtual gl::Error copyToStorageCube(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
virtual gl::Error copyToStorage3D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region); virtual gl::Error copyToStorage3D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
...@@ -54,15 +54,15 @@ class Image9 : public ImageD3D ...@@ -54,15 +54,15 @@ class Image9 : public ImageD3D
virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
const void *input); const void *input);
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source); virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source);
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
const gl::ImageIndex &sourceIndex, TextureStorage *source); const gl::ImageIndex &sourceIndex, TextureStorage *source);
private: private:
DISALLOW_COPY_AND_ASSIGN(Image9); DISALLOW_COPY_AND_ASSIGN(Image9);
void createSurface(); void createSurface();
void setManagedSurface(IDirect3DSurface9 *surface); gl::Error setManagedSurface(IDirect3DSurface9 *surface);
gl::Error copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); gl::Error copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
......
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