Commit 88318b44 by Geoff Lang Committed by Commit Bot

Fall back to CPU copies for srgb textures in copy_texture_CHROMIUM.

The copied data is not supposed to have sRGB conversions applied to it when written to the destination texture but an sRGB SRV is used by Blit11. Instead of creating multiple sRGB and non-sRGB SRVs for textures, simply fall back to the CPU copy path for this format for now. Clip color channels that should not exist in the destination texture formats in Image11::CopyImage. This works around issues with texture formats with emulated channels. TEST=conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte TEST=conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte BUG=angleproject:1932 Change-Id: Ieeda3569f80d016fda781e7eb498acd3b97568d0 Reviewed-on: https://chromium-review.googlesource.com/559857Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent ea39a223
......@@ -920,6 +920,11 @@ bool TextureD3D_2D::isDepth(GLint level) const
return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
bool TextureD3D_2D::isSRGB(GLint level) const
{
return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB;
}
gl::Error TextureD3D_2D::setImage(const gl::Context *context,
GLenum target,
size_t imageLevel,
......@@ -1179,7 +1184,7 @@ gl::Error TextureD3D_2D::copyTexture(const gl::Context *context,
gl::Rectangle sourceRect(0, 0, size.width, size.height);
gl::Offset destOffset(0, 0, 0);
if (canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel)))
if (!isSRGB(destLevel) && canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel)))
{
ANGLE_TRY(ensureRenderTarget(context));
ASSERT(isValidLevel(destLevel));
......@@ -1223,7 +1228,7 @@ gl::Error TextureD3D_2D::copySubTexture(const gl::Context *context,
GLint destLevel = static_cast<GLint>(level);
if (canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel)))
if (!isSRGB(destLevel) && canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel)))
{
ANGLE_TRY(ensureRenderTarget(context));
ASSERT(isValidLevel(destLevel));
......@@ -1714,6 +1719,11 @@ bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const
return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0;
}
bool TextureD3D_Cube::isSRGB(GLint level, GLint layer) const
{
return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).colorEncoding == GL_SRGB;
}
gl::Error TextureD3D_Cube::setEGLImageTarget(const gl::Context *context,
GLenum target,
egl::Image *image)
......@@ -1910,7 +1920,8 @@ gl::Error TextureD3D_Cube::copyTexture(const gl::Context *context,
gl::Rectangle sourceRect(0, 0, size.width, size.height);
gl::Offset destOffset(0, 0, 0);
if (canCreateRenderTargetForImage(gl::ImageIndex::MakeCube(target, destLevel)))
if (!isSRGB(destLevel, faceIndex) &&
canCreateRenderTargetForImage(gl::ImageIndex::MakeCube(target, destLevel)))
{
ANGLE_TRY(ensureRenderTarget(context));
ASSERT(isValidFaceLevel(faceIndex, destLevel));
......@@ -1956,7 +1967,8 @@ gl::Error TextureD3D_Cube::copySubTexture(const gl::Context *context,
GLint destLevel = static_cast<GLint>(level);
int faceIndex = static_cast<int>(gl::CubeMapTextureTargetToLayerIndex(target));
if (canCreateRenderTargetForImage(gl::ImageIndex::MakeCube(target, destLevel)))
if (!isSRGB(destLevel, faceIndex) &&
canCreateRenderTargetForImage(gl::ImageIndex::MakeCube(target, destLevel)))
{
ANGLE_TRY(ensureRenderTarget(context));
ASSERT(isValidFaceLevel(faceIndex, destLevel));
......
......@@ -194,6 +194,7 @@ class TextureD3D_2D : public TextureD3D
GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
bool isSRGB(GLint level) const;
gl::Error setImage(const gl::Context *context,
GLenum target,
......@@ -336,6 +337,7 @@ class TextureD3D_Cube : public TextureD3D
GLenum getInternalFormat(GLint level, GLint layer) const;
bool isDepth(GLint level, GLint layer) const;
bool isSRGB(GLint level, GLint layer) const;
gl::Error setImage(const gl::Context *context,
GLenum target,
......
......@@ -48,6 +48,40 @@ void UnmultiplyAlpha(gl::ColorF *color)
}
}
void ClipChannelsR(gl::ColorF *color)
{
color->green = 0.0f;
color->blue = 0.0f;
color->alpha = 1.0f;
}
void ClipChannelsRG(gl::ColorF *color)
{
color->blue = 0.0f;
color->alpha = 1.0f;
}
void ClipChannelsRGB(gl::ColorF *color)
{
color->alpha = 1.0f;
}
void ClipChannelsLuminance(gl::ColorF *color)
{
color->alpha = 1.0f;
}
void ClipChannelsAlpha(gl::ColorF *color)
{
color->red = 0.0f;
color->green = 0.0f;
color->blue = 0.0f;
}
void ClipChannelsNoOp(gl::ColorF *color)
{
}
void WriteUintColor(const gl::ColorF &color,
ColorWriteFunction colorWriteFunction,
uint8_t *destPixelData)
......@@ -150,6 +184,7 @@ gl::Error Image11::CopyImage(const gl::Context *context,
GLuint sourcePixelBytes =
gl::GetSizedInternalFormatInfo(sourceFormat.fboImplementationInternalFormat).pixelBytes;
GLenum destUnsizedFormat = gl::GetUnsizedFormat(dest->getInternalFormat());
const auto &destFormat = d3d11::Format::Get(dest->getInternalFormat(), rendererCaps).format();
const auto &destFormatInfo =
gl::GetSizedInternalFormatInfo(destFormat.fboImplementationInternalFormat);
......@@ -172,6 +207,26 @@ gl::Error Image11::CopyImage(const gl::Context *context,
}
}
auto clipChannelsFunction = ClipChannelsNoOp;
switch (destUnsizedFormat)
{
case GL_RED:
clipChannelsFunction = ClipChannelsR;
break;
case GL_RG:
clipChannelsFunction = ClipChannelsRG;
break;
case GL_RGB:
clipChannelsFunction = ClipChannelsRGB;
break;
case GL_LUMINANCE:
clipChannelsFunction = ClipChannelsLuminance;
break;
case GL_ALPHA:
clipChannelsFunction = ClipChannelsAlpha;
break;
}
auto writeFunction =
(destFormatInfo.componentType == GL_UNSIGNED_INT) ? WriteUintColor : WriteFloatColor;
......@@ -189,6 +244,7 @@ gl::Error Image11::CopyImage(const gl::Context *context,
reinterpret_cast<uint8_t *>(&sourceColor));
conversionFunction(&sourceColor);
clipChannelsFunction(&sourceColor);
int destX = destOffset.x + x;
int destY = destOffset.y;
......
......@@ -811,7 +811,7 @@ TEST_P(CopyTextureTestES3, ES3UnormFormats)
GL_UNSIGNED_BYTE, false, true, false, GLColor(0, 0, 0, 128));
// New sRGB dest formats
if (IsOpenGLES())
if (IsOpenGLES() || IsOpenGL())
{
std::cout << "Skipping GL_SRGB and GL_SRGB_ALPHA because it is not implemented yet."
<< std::endl;
......@@ -819,12 +819,12 @@ TEST_P(CopyTextureTestES3, ES3UnormFormats)
else
{
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
GL_UNSIGNED_BYTE, false, false, false, GLColor(128, 64, 32, 255));
GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 255));
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
GL_UNSIGNED_BYTE, false, true, false, GLColor(64, 32, 16, 255));
GL_UNSIGNED_BYTE, false, true, false, GLColor(13, 4, 1, 255));
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
GLColor(128, 64, 32, 128));
GLColor(55, 13, 4, 128));
}
}
......
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