Commit 651378b2 by Kenneth Russell Committed by Commit Bot

Support OES_texture_{half_}float on ES 3.0 without these extensions.

Emulate the LUMINANCE, ALPHA and LUMINANCE_ALPHA formats with GL_RED/GL_RG textures on platforms that don't support the OES_texture_{half_}float extensions. Fix a preexisting bug in TextureGL's luminance/alpha emulation where it would use desktop GL functionality on GLES. This change makes WebKit on iOS pass WebGL's conformance/extensions/oes-texture-{half-}float tests per https://bugs.webkit.org/show_bug.cgi?id=210524 . Bug: angleproject:4636 Change-Id: I6c158058e4b170b16ece578a3930c230de16a9ca Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2203283Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Commit-Queue: Kenneth Russell <kbr@chromium.org>
parent 29fedbac
...@@ -1607,9 +1607,23 @@ angle::Result TextureGL::setSwizzle(const gl::Context *context, GLint swizzle[4] ...@@ -1607,9 +1607,23 @@ angle::Result TextureGL::setSwizzle(const gl::Context *context, GLint swizzle[4]
onStateChange(angle::SubjectMessage::DirtyBitsFlagged); onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
stateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
if (functions->standard == STANDARD_GL_ES)
{
ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()),
GL_TEXTURE_SWIZZLE_R, swizzle[0]));
ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()),
GL_TEXTURE_SWIZZLE_G, swizzle[1]));
ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()),
GL_TEXTURE_SWIZZLE_B, swizzle[2]));
ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()),
GL_TEXTURE_SWIZZLE_A, swizzle[3]));
}
else
{
ANGLE_GL_TRY(context, functions->texParameteriv(ToGLenum(getType()), ANGLE_GL_TRY(context, functions->texParameteriv(ToGLenum(getType()),
GL_TEXTURE_SWIZZLE_RGBA, swizzle)); GL_TEXTURE_SWIZZLE_RGBA, swizzle));
} }
}
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -279,12 +279,12 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() ...@@ -279,12 +279,12 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
InsertFormatMapping(&map, GL_ALPHA8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), AlwaysSupported(), AlwaysSupported(), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_ALPHA8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), AlwaysSupported(), AlwaysSupported(), NeverSupported(), NeverSupported() );
InsertFormatMapping(&map, GL_LUMINANCE8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), AlwaysSupported(), AlwaysSupported(), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_LUMINANCE8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), AlwaysSupported(), AlwaysSupported(), NeverSupported(), NeverSupported() );
InsertFormatMapping(&map, GL_LUMINANCE8_ALPHA8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), AlwaysSupported(), AlwaysSupported(), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_LUMINANCE8_ALPHA8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), AlwaysSupported(), AlwaysSupported(), NeverSupported(), NeverSupported() );
InsertFormatMapping(&map, GL_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(), NeverSupported() );
InsertFormatMapping(&map, GL_LUMINANCE16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_LUMINANCE16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(), NeverSupported() );
InsertFormatMapping(&map, GL_LUMINANCE_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_LUMINANCE_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(), NeverSupported() );
InsertFormatMapping(&map, GL_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_float"), ExtsOnly("GL_OES_texture_float_linear"), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_float"), ExtsOnly("GL_OES_texture_float_linear"), NeverSupported(), NeverSupported() );
InsertFormatMapping(&map, GL_LUMINANCE32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_float"), ExtsOnly("GL_OES_texture_float_linear"), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_LUMINANCE32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_float"), ExtsOnly("GL_OES_texture_float_linear"), NeverSupported(), NeverSupported() );
InsertFormatMapping(&map, GL_LUMINANCE_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_float"), ExtsOnly("GL_OES_texture_float_linear"), NeverSupported(), NeverSupported() ); InsertFormatMapping(&map, GL_LUMINANCE_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_float"), ExtsOnly("GL_OES_texture_float_linear"), NeverSupported(), NeverSupported() );
// EXT_texture_compression_rgtc formats // EXT_texture_compression_rgtc formats
// | Format | OpenGL texture support | Filter | Render | OpenGL ES texture support | Filter | OpenGL ES texture attachment support | OpenGL ES renderbuffer support | // | Format | OpenGL texture support | Filter | Render | OpenGL ES texture support | Filter | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
...@@ -434,6 +434,33 @@ const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL st ...@@ -434,6 +434,33 @@ const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL st
return *defaultInternalFormat; return *defaultInternalFormat;
} }
static bool IsLUMAFormat(GLenum format)
{
return (format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA);
}
static GLenum EmulateLUMAFormat(const GLenum format)
{
// This is needed separately from EmulateLUMA because some format/type combinations that come in
// to GetNativeFormat don't have entries in the internal format map.
ASSERT(IsLUMAFormat(format));
if (format == GL_LUMINANCE || format == GL_ALPHA)
return GL_RED;
return GL_RG;
}
static const gl::InternalFormat &EmulateLUMA(const gl::InternalFormat &internalFormat)
{
ASSERT(IsLUMAFormat(internalFormat.format));
// Work around deprecated luminance/alpha formats in the OpenGL core profile, and OpenGL ES 3.0
// and greater, by backing them with R or RG textures.
return gl::GetInternalFormatInfo(EmulateLUMAFormat(internalFormat.format), internalFormat.type);
}
static GLenum GetNativeInternalFormat(const FunctionsGL *functions, static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
const angle::FeaturesGL &features, const angle::FeaturesGL &features,
const gl::InternalFormat &internalFormat) const gl::InternalFormat &internalFormat)
...@@ -479,27 +506,35 @@ static GLenum GetNativeInternalFormat(const FunctionsGL *functions, ...@@ -479,27 +506,35 @@ static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0) if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
{ {
// Work around deprecated luminance alpha formats in the OpenGL core profile by backing if (IsLUMAFormat(internalFormat.format))
// them with R or RG textures.
if (internalFormat.format == GL_LUMINANCE || internalFormat.format == GL_ALPHA)
{
result = gl::GetInternalFormatInfo(GL_RED, internalFormat.type).sizedInternalFormat;
}
if (internalFormat.format == GL_LUMINANCE_ALPHA)
{ {
result = gl::GetInternalFormatInfo(GL_RG, internalFormat.type).sizedInternalFormat; result = EmulateLUMA(internalFormat).sizedInternalFormat;
} }
} }
} }
else if (functions->isAtLeastGLES(gl::Version(3, 0))) else if (functions->isAtLeastGLES(gl::Version(3, 0)))
{ {
if (internalFormat.componentType == GL_FLOAT && !internalFormat.isLUMA()) if (internalFormat.componentType == GL_FLOAT)
{
if (!internalFormat.isLUMA())
{ {
// Use sized internal formats for floating point textures. Extensions such as // Use sized internal formats for floating point textures. Extensions such as
// EXT_color_buffer_float require the sized formats to be renderable. // EXT_color_buffer_float require the sized formats to be renderable.
result = internalFormat.sizedInternalFormat; result = internalFormat.sizedInternalFormat;
} }
else if ((internalFormat.type == GL_FLOAT &&
!functions->hasGLESExtension("GL_OES_texture_float")) ||
(internalFormat.type == GL_HALF_FLOAT_OES &&
!functions->hasGLESExtension("GL_OES_texture_half_float")))
{
// The legacy luminance/alpha formats from OES_texture_float are emulated with R/RG
// textures.
if (IsLUMAFormat(internalFormat.format))
{
result = EmulateLUMA(internalFormat).sizedInternalFormat;
}
}
}
else if (internalFormat.format == GL_RED_EXT || internalFormat.format == GL_RG_EXT) else if (internalFormat.format == GL_RED_EXT || internalFormat.format == GL_RG_EXT)
{ {
// Workaround Adreno driver not supporting unsized EXT_texture_rg formats // Workaround Adreno driver not supporting unsized EXT_texture_rg formats
...@@ -519,7 +554,8 @@ static GLenum GetNativeInternalFormat(const FunctionsGL *functions, ...@@ -519,7 +554,8 @@ static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
static GLenum GetNativeFormat(const FunctionsGL *functions, static GLenum GetNativeFormat(const FunctionsGL *functions,
const angle::FeaturesGL &features, const angle::FeaturesGL &features,
GLenum format) GLenum format,
GLenum type)
{ {
GLenum result = format; GLenum result = format;
...@@ -541,14 +577,9 @@ static GLenum GetNativeFormat(const FunctionsGL *functions, ...@@ -541,14 +577,9 @@ static GLenum GetNativeFormat(const FunctionsGL *functions,
{ {
// Work around deprecated luminance alpha formats in the OpenGL core profile by backing // Work around deprecated luminance alpha formats in the OpenGL core profile by backing
// them with R or RG textures. // them with R or RG textures.
if (format == GL_LUMINANCE || format == GL_ALPHA) if (IsLUMAFormat(format))
{
result = GL_RED;
}
if (format == GL_LUMINANCE_ALPHA)
{ {
result = GL_RG; result = EmulateLUMAFormat(format);
} }
} }
} }
...@@ -566,6 +597,18 @@ static GLenum GetNativeFormat(const FunctionsGL *functions, ...@@ -566,6 +597,18 @@ static GLenum GetNativeFormat(const FunctionsGL *functions,
result = GL_RGBA; result = GL_RGBA;
} }
} }
if ((type == GL_FLOAT && !functions->hasGLESExtension("GL_OES_texture_float")) ||
(type == GL_HALF_FLOAT_OES &&
!functions->hasGLESExtension("GL_OES_texture_half_float")))
{
// On ES 3.0 systems that don't have GL_OES_texture_float or OES_texture_half_float, the
// LUMINANCE/ALPHA formats from those extensions must be emulated with R/RG textures.
if (IsLUMAFormat(format))
{
result = EmulateLUMAFormat(format);
}
}
} }
return result; return result;
...@@ -629,18 +672,12 @@ static GLenum GetNativeType(const FunctionsGL *functions, ...@@ -629,18 +672,12 @@ static GLenum GetNativeType(const FunctionsGL *functions,
{ {
if (type == GL_HALF_FLOAT_OES) if (type == GL_HALF_FLOAT_OES)
{ {
switch (format) if (!IsLUMAFormat(format) || !functions->hasGLESExtension("GL_OES_texture_half_float"))
{ {
case GL_LUMINANCE_ALPHA: // In ES3, the luminance formats come from OES_texture_half_float, which uses
case GL_LUMINANCE:
case GL_ALPHA:
// In ES3, these formats come from EXT_texture_storage, which uses
// HALF_FLOAT_OES. Other formats (like RGBA) use HALF_FLOAT (non-OES) in ES3. // HALF_FLOAT_OES. Other formats (like RGBA) use HALF_FLOAT (non-OES) in ES3.
break; // If they're emulated (see above), use HALF_FLOAT.
default:
result = GL_HALF_FLOAT; result = GL_HALF_FLOAT;
break;
} }
} }
} }
...@@ -701,7 +738,7 @@ TexImageFormat GetTexImageFormat(const FunctionsGL *functions, ...@@ -701,7 +738,7 @@ TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
TexImageFormat result; TexImageFormat result;
result.internalFormat = GetNativeInternalFormat( result.internalFormat = GetNativeInternalFormat(
functions, features, gl::GetInternalFormatInfo(internalFormat, type)); functions, features, gl::GetInternalFormatInfo(internalFormat, type));
result.format = GetNativeFormat(functions, features, format); result.format = GetNativeFormat(functions, features, format, type);
result.type = GetNativeType(functions, features, format, type); result.type = GetNativeType(functions, features, format, type);
return result; return result;
} }
...@@ -712,7 +749,7 @@ TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions, ...@@ -712,7 +749,7 @@ TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
GLenum type) GLenum type)
{ {
TexSubImageFormat result; TexSubImageFormat result;
result.format = GetNativeFormat(functions, features, format); result.format = GetNativeFormat(functions, features, format, type);
result.type = GetNativeType(functions, features, format, type); result.type = GetNativeType(functions, features, format, type);
return result; return result;
} }
......
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