зеркало из https://github.com/AvaloniaUI/angle.git
GL: Work around Qualcomm sRGB ReadPixels driver bug.
When calling glReadPixels on unsized sRGB textures, the data returned is not linearized. Using sized sRGB formats works around this problem. Fix SRGBTextureTest assuming that unsized SRGB formats work in ES3. BUG=angleproject:2977 Change-Id: I413c888ca0c3564ecdc364f3ea693e75ed4f8d6d Reviewed-on: https://chromium-review.googlesource.com/c/1343138 Reviewed-by: Tobin Ehlis <tobine@google.com> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Родитель
617103ed0e
Коммит
7198ebc48c
|
@ -3231,6 +3231,12 @@ Extensions Context::generateSupportedExtensions() const
|
||||||
supportedExtensions.maxViews = 1u;
|
supportedExtensions.maxViews = 1u;
|
||||||
supportedExtensions.copyTexture3d = false;
|
supportedExtensions.copyTexture3d = false;
|
||||||
supportedExtensions.textureMultisample = false;
|
supportedExtensions.textureMultisample = false;
|
||||||
|
|
||||||
|
// Don't expose GL_EXT_texture_sRGB_decode without sRGB texture support
|
||||||
|
if (!supportedExtensions.sRGB)
|
||||||
|
{
|
||||||
|
supportedExtensions.textureSRGBDecode = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getClientVersion() < ES_3_1)
|
if (getClientVersion() < ES_3_1)
|
||||||
|
|
|
@ -158,6 +158,11 @@ struct WorkaroundsGL
|
||||||
// instead of disabling the functionality entirely. The AMD bug looked like incorrect blending,
|
// instead of disabling the functionality entirely. The AMD bug looked like incorrect blending,
|
||||||
// not sure if a workaround is feasible. http://anglebug.com/1085
|
// not sure if a workaround is feasible. http://anglebug.com/1085
|
||||||
bool disableBlendFuncExtended = false;
|
bool disableBlendFuncExtended = false;
|
||||||
|
|
||||||
|
// Qualcomm drivers returns raw sRGB values instead of linearized values when calling
|
||||||
|
// glReadPixels on unsized sRGB texture formats. http://crbug.com/550292 and
|
||||||
|
// http://crbug.com/565179
|
||||||
|
bool unsizedsRGBReadPixelsDoesntTransform = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline WorkaroundsGL::WorkaroundsGL() = default;
|
inline WorkaroundsGL::WorkaroundsGL() = default;
|
||||||
|
|
|
@ -414,6 +414,13 @@ static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
|
||||||
// Workaround Adreno driver not supporting unsized EXT_texture_rg formats
|
// Workaround Adreno driver not supporting unsized EXT_texture_rg formats
|
||||||
result = internalFormat.sizedInternalFormat;
|
result = internalFormat.sizedInternalFormat;
|
||||||
}
|
}
|
||||||
|
else if (workarounds.unsizedsRGBReadPixelsDoesntTransform &&
|
||||||
|
internalFormat.colorEncoding == GL_SRGB)
|
||||||
|
{
|
||||||
|
// Work around some Adreno driver bugs that don't read back SRGB data correctly when
|
||||||
|
// it's in unsized SRGB texture formats.
|
||||||
|
result = internalFormat.sizedInternalFormat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -454,6 +461,21 @@ static GLenum GetNativeFormat(const FunctionsGL *functions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (functions->isAtLeastGLES(gl::Version(3, 0)))
|
||||||
|
{
|
||||||
|
if (workarounds.unsizedsRGBReadPixelsDoesntTransform)
|
||||||
|
{
|
||||||
|
if (format == GL_SRGB)
|
||||||
|
{
|
||||||
|
result = GL_RGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == GL_SRGB_ALPHA)
|
||||||
|
{
|
||||||
|
result = GL_RGBA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1201,6 +1201,14 @@ void GenerateCaps(const FunctionsGL *functions,
|
||||||
// ES driver.
|
// ES driver.
|
||||||
extensions->compressedTextureETC = functions->standard == STANDARD_GL_ES &&
|
extensions->compressedTextureETC = functions->standard == STANDARD_GL_ES &&
|
||||||
gl::DetermineCompressedTextureETCSupport(*textureCapsMap);
|
gl::DetermineCompressedTextureETCSupport(*textureCapsMap);
|
||||||
|
|
||||||
|
// To work around broken unsized sRGB textures, sized sRGB textures are used. Disable EXT_sRGB
|
||||||
|
// if those formats are not available.
|
||||||
|
if (workarounds.unsizedsRGBReadPixelsDoesntTransform &&
|
||||||
|
!functions->isAtLeastGLES(gl::Version(3, 0)))
|
||||||
|
{
|
||||||
|
extensions->sRGB = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds)
|
void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds)
|
||||||
|
@ -1295,6 +1303,13 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
workarounds->disableBlendFuncExtended = IsAMD(vendor) || IsIntel(vendor);
|
workarounds->disableBlendFuncExtended = IsAMD(vendor) || IsIntel(vendor);
|
||||||
|
|
||||||
|
#if defined(ANGLE_PLATFORM_ANDROID)
|
||||||
|
if (IsQualcomm(vendor))
|
||||||
|
{
|
||||||
|
workarounds->unsizedsRGBReadPixelsDoesntTransform = true;
|
||||||
|
}
|
||||||
|
#endif // defined(ANGLE_PLATFORM_ANDROID)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyWorkarounds(const FunctionsGL *functions, gl::Workarounds *workarounds)
|
void ApplyWorkarounds(const FunctionsGL *functions, gl::Workarounds *workarounds)
|
||||||
|
|
|
@ -1331,6 +1331,8 @@ TEST_P(CopyTextureTestES3, ES3UnormFormats)
|
||||||
GL_UNSIGNED_BYTE, false, true, false, GLColor(0, 0, 0, 128));
|
GL_UNSIGNED_BYTE, false, true, false, GLColor(0, 0, 0, 128));
|
||||||
|
|
||||||
// New sRGB dest formats
|
// New sRGB dest formats
|
||||||
|
if (extensionEnabled("GL_EXT_sRGB"))
|
||||||
|
{
|
||||||
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
|
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
|
||||||
GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 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,
|
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
|
||||||
|
@ -1339,14 +1341,17 @@ TEST_P(CopyTextureTestES3, ES3UnormFormats)
|
||||||
GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
|
GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
|
||||||
GLColor(55, 13, 4, 128));
|
GLColor(55, 13, 4, 128));
|
||||||
|
|
||||||
testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
|
testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
|
||||||
GL_SRGB, GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 255));
|
GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, false, false,
|
||||||
testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
|
GLColor(55, 13, 4, 255));
|
||||||
GL_SRGB, GL_UNSIGNED_BYTE, false, true, false, GLColor(13, 4, 1, 255));
|
testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
|
||||||
|
GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, true, false,
|
||||||
|
GLColor(13, 4, 1, 255));
|
||||||
testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
|
testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
|
||||||
GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false,
|
GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false,
|
||||||
false, GLColor(55, 13, 4, 128));
|
false, GLColor(55, 13, 4, 128));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test the newly added ES3 float formats
|
// Test the newly added ES3 float formats
|
||||||
TEST_P(CopyTextureTestES3, ES3FloatFormats)
|
TEST_P(CopyTextureTestES3, ES3FloatFormats)
|
||||||
|
|
|
@ -62,6 +62,26 @@ class SRGBTextureTest : public ANGLETest
|
||||||
ANGLETest::TearDown();
|
ANGLETest::TearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLenum getSRGBA8TextureInternalFormat() const
|
||||||
|
{
|
||||||
|
return getClientMajorVersion() >= 3 ? GL_SRGB8_ALPHA8 : GL_SRGB_ALPHA_EXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum getSRGBA8TextureFormat() const
|
||||||
|
{
|
||||||
|
return getClientMajorVersion() >= 3 ? GL_RGBA : GL_SRGB_ALPHA_EXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum getSRGB8TextureInternalFormat() const
|
||||||
|
{
|
||||||
|
return getClientMajorVersion() >= 3 ? GL_SRGB8 : GL_SRGB_EXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum getSRGB8TextureFormat() const
|
||||||
|
{
|
||||||
|
return getClientMajorVersion() >= 3 ? GL_RGB : GL_SRGB_EXT;
|
||||||
|
}
|
||||||
|
|
||||||
GLuint mProgram = 0;
|
GLuint mProgram = 0;
|
||||||
GLint mTextureLocation = -1;
|
GLint mTextureLocation = -1;
|
||||||
};
|
};
|
||||||
|
@ -80,25 +100,21 @@ TEST_P(SRGBTextureTest, SRGBValidation)
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
|
|
||||||
GLubyte pixel[3] = { 0 };
|
GLubyte pixel[3] = { 0 };
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, 1, 1, 0, GL_SRGB, GL_UNSIGNED_BYTE, pixel);
|
glTexImage2D(GL_TEXTURE_2D, 0, getSRGB8TextureInternalFormat(), 1, 1, 0,
|
||||||
|
getSRGB8TextureFormat(), GL_UNSIGNED_BYTE, pixel);
|
||||||
if (supported)
|
if (supported)
|
||||||
{
|
{
|
||||||
EXPECT_GL_NO_ERROR();
|
EXPECT_GL_NO_ERROR();
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB, GL_UNSIGNED_BYTE, pixel);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSRGB8TextureFormat(), GL_UNSIGNED_BYTE,
|
||||||
|
pixel);
|
||||||
EXPECT_GL_NO_ERROR();
|
EXPECT_GL_NO_ERROR();
|
||||||
|
|
||||||
|
// Mipmap generation always generates errors for SRGB unsized in ES2 or SRGB8 sized in ES3.
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
if (getClientMajorVersion() < 3)
|
|
||||||
{
|
|
||||||
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
|
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
EXPECT_GL_NO_ERROR();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
EXPECT_GL_ERROR(GL_INVALID_ENUM);
|
EXPECT_GL_ERROR(GL_INVALID_ENUM);
|
||||||
}
|
}
|
||||||
|
@ -118,12 +134,14 @@ TEST_P(SRGBTextureTest, SRGBAValidation)
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
|
|
||||||
GLubyte pixel[4] = { 0 };
|
GLubyte pixel[4] = { 0 };
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel);
|
glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
|
||||||
|
getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, pixel);
|
||||||
if (supported)
|
if (supported)
|
||||||
{
|
{
|
||||||
EXPECT_GL_NO_ERROR();
|
EXPECT_GL_NO_ERROR();
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE,
|
||||||
|
pixel);
|
||||||
EXPECT_GL_NO_ERROR();
|
EXPECT_GL_NO_ERROR();
|
||||||
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
@ -157,7 +175,8 @@ TEST_P(SRGBTextureTest, SRGBASizedValidation)
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
|
|
||||||
GLubyte pixel[4] = {0};
|
GLubyte pixel[4] = {0};
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
|
glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
|
||||||
|
getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, pixel);
|
||||||
|
|
||||||
EXPECT_GL_NO_ERROR();
|
EXPECT_GL_NO_ERROR();
|
||||||
|
|
||||||
|
@ -237,8 +256,8 @@ TEST_P(SRGBTextureTest, SRGBDecodeTextureParameter)
|
||||||
|
|
||||||
GLTexture tex;
|
GLTexture tex;
|
||||||
glBindTexture(GL_TEXTURE_2D, tex.get());
|
glBindTexture(GL_TEXTURE_2D, tex.get());
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE,
|
glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
|
||||||
&linearColor);
|
getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, &linearColor);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
|
||||||
ASSERT_GL_NO_ERROR();
|
ASSERT_GL_NO_ERROR();
|
||||||
|
|
||||||
|
@ -267,8 +286,8 @@ TEST_P(SRGBTextureTest, SRGBDecodeSamplerParameter)
|
||||||
|
|
||||||
GLTexture tex;
|
GLTexture tex;
|
||||||
glBindTexture(GL_TEXTURE_2D, tex.get());
|
glBindTexture(GL_TEXTURE_2D, tex.get());
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE,
|
glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
|
||||||
&linearColor);
|
getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, &linearColor);
|
||||||
ASSERT_GL_NO_ERROR();
|
ASSERT_GL_NO_ERROR();
|
||||||
|
|
||||||
GLSampler sampler;
|
GLSampler sampler;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче