Commit 74ed9b65 by James Darpinian Committed by Commit Bot

Support EXT_color_buffer_half_float on WebGL 2.0 contexts

EXT_color_buffer_half_float was recently updated to be valid for WebGL 2 contexts because iOS can't support EXT_color_buffer_float. Bug: angleproject:5038 Change-Id: Ib0d35c6b26a6cd215ff6725e92c47d1efd64e048 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2415187 Commit-Queue: James Darpinian <jdarpinian@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org>
parent e9813ba0
......@@ -3196,8 +3196,9 @@ Extensions Context::generateSupportedExtensions() const
// can be blit onto each other if the format is available.
// We require colorBufferFloat to be present in order to enable colorBufferHalfFloat, so
// that blitting is always allowed if the requested formats are exposed and have the correct
// feature capabilities
if (!supportedExtensions.colorBufferFloat)
// feature capabilities.
// WebGL 2 wants to support colorBufferHalfFloat without colorBufferFloat.
if (!supportedExtensions.colorBufferFloat && !mWebGLContext)
{
supportedExtensions.colorBufferHalfFloat = false;
}
......
......@@ -186,7 +186,9 @@ static bool SizedHalfFloatRGTextureAttachmentSupport(const Version &clientVersio
// HALF_FLOAT
if (clientVersion >= Version(3, 0))
{
return extensions.colorBufferFloat;
// WebGL 2 supports EXT_color_buffer_half_float.
return extensions.colorBufferFloat ||
(extensions.webglCompatibility && extensions.colorBufferHalfFloat);
}
// HALF_FLOAT_OES
else
......@@ -253,7 +255,8 @@ static bool SizedHalfFloatRGBTextureAttachmentSupport(const Version &clientVersi
// It is unclear how EXT_color_buffer_half_float applies to ES3.0 and above, however,
// dEQP GLES3 es3fFboColorbufferTests.cpp verifies that texture attachment of GL_RGB16F
// is possible, so assume that all GLES implementations support it.
return extensions.colorBufferHalfFloat;
// The WebGL version of the extension explicitly forbids RGB formats.
return extensions.colorBufferHalfFloat && !extensions.webglCompatibility;
}
// HALF_FLOAT_OES
else
......@@ -265,8 +268,9 @@ static bool SizedHalfFloatRGBTextureAttachmentSupport(const Version &clientVersi
static bool SizedHalfFloatRGBRenderbufferSupport(const Version &clientVersion,
const Extensions &extensions)
{
return (clientVersion >= Version(3, 0) || extensions.textureHalfFloat) &&
extensions.colorBufferHalfFloat;
return !extensions.webglCompatibility &&
((clientVersion >= Version(3, 0) || extensions.textureHalfFloat) &&
extensions.colorBufferHalfFloat);
}
static bool SizedHalfFloatRGBATextureAttachmentSupport(const Version &clientVersion,
......@@ -275,7 +279,9 @@ static bool SizedHalfFloatRGBATextureAttachmentSupport(const Version &clientVers
// HALF_FLOAT
if (clientVersion >= Version(3, 0))
{
return extensions.colorBufferFloat;
// WebGL 2 supports EXT_color_buffer_half_float.
return extensions.colorBufferFloat ||
(extensions.webglCompatibility && extensions.colorBufferHalfFloat);
}
// HALF_FLOAT_OES
else
......
......@@ -289,6 +289,18 @@ static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
textureCaps.blendable = textureCaps.renderbuffer || textureCaps.textureAttachment;
// Do extra renderability validation for some formats.
if (internalFormat == GL_R16F || internalFormat == GL_RG16F || internalFormat == GL_RGB16F)
{
// SupportRequirement can't currently express a condition of the form (version && extension)
// || other extensions, so do the (version && extension) part here.
if (functions->isAtLeastGLES(gl::Version(3, 0)) &&
functions->hasGLESExtension("GL_EXT_color_buffer_half_float"))
{
textureCaps.textureAttachment = true;
textureCaps.renderbuffer = true;
}
}
// We require GL_RGBA16F is renderable to expose EXT_color_buffer_half_float but we can't know
// if the format is supported unless we try to create a framebuffer.
if (internalFormat == GL_RGBA16F)
......
......@@ -318,6 +318,38 @@ bool IsValidStencilOp(GLenum op)
}
}
static inline bool Valid1to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
{
return (context->getExtensions().textureFloatOES &&
(format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F ||
format == GL_R32F)) ||
(context->getExtensions().textureHalfFloat &&
(format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F ||
format == GL_R16F));
}
static inline bool Valid2to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
{
return (context->getExtensions().textureFloatOES &&
(format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F)) ||
(context->getExtensions().textureHalfFloat &&
(format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F));
}
static inline bool Valid3to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
{
return (context->getExtensions().textureFloatOES &&
(format == GL_RGBA32F || format == GL_RGB32F)) ||
(context->getExtensions().textureHalfFloat &&
(format == GL_RGBA16F || format == GL_RGB16F));
}
static inline bool Valid4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
{
return (context->getExtensions().textureFloatOES && format == GL_RGBA32F) ||
(context->getExtensions().textureHalfFloat && format == GL_RGBA16F);
}
bool ValidateES2CopyTexImageParameters(const Context *context,
TextureTarget target,
GLint level,
......@@ -365,7 +397,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
case GL_ALPHA:
if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -376,7 +409,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -389,7 +423,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -401,7 +436,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid2to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -412,7 +448,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid3to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -422,7 +459,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
case GL_RGBA:
if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -466,29 +504,21 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
case GL_ALPHA:
if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
}
break;
case GL_LUMINANCE:
if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
}
break;
case GL_RED_EXT:
if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -498,7 +528,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid2to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -508,7 +539,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGR5_A1_ANGLEX &&
!Valid3to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -518,7 +550,8 @@ bool ValidateES2CopyTexImageParameters(const Context *context,
case GL_RGBA:
if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
colorbufferFormat != GL_BGR5_A1_ANGLEX && colorbufferFormat != GL_RGBA16F &&
!Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
{
context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
return false;
......@@ -1243,13 +1276,20 @@ bool ValidateES2TexImageParametersBase(const Context *context,
case GL_UNSIGNED_BYTE:
break;
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
if (!context->getExtensions().textureFloatOES)
{
context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
return false;
}
break;
case GL_HALF_FLOAT_OES:
if (!context->getExtensions().textureFloatOES &&
!context->getExtensions().textureHalfFloat)
{
context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
return false;
}
break;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
if (!context->getExtensions().textureNorm16)
......
......@@ -3619,7 +3619,8 @@ TEST_P(WebGLCompatibilityTest, R16FTextures)
// Sized R 16F
bool texture = true;
bool filter = true;
bool render = IsGLExtensionEnabled("GL_EXT_color_buffer_float");
bool render = IsGLExtensionEnabled("GL_EXT_color_buffer_float") ||
IsGLExtensionEnabled("GL_EXT_color_buffer_half_float");
TestFloatTextureFormat(GL_R16F, GL_RED, GL_HALF_FLOAT, texture, filter, render,
textureData, readPixelsData);
}
......@@ -3675,7 +3676,8 @@ TEST_P(WebGLCompatibilityTest, RG16FTextures)
// Sized RG 16F
bool texture = true;
bool filter = true;
bool render = IsGLExtensionEnabled("GL_EXT_color_buffer_float");
bool render = IsGLExtensionEnabled("GL_EXT_color_buffer_float") ||
IsGLExtensionEnabled("GL_EXT_color_buffer_half_float");
TestFloatTextureFormat(GL_RG16F, GL_RG, GL_HALF_FLOAT, texture, filter, render,
textureData, readPixelsData);
}
......@@ -3737,10 +3739,8 @@ TEST_P(WebGLCompatibilityTest, RGB16FTextures)
// Sized RGB 16F
bool texture = true;
bool filter = true;
// It is unclear how EXT_color_buffer_half_float applies to ES3.0 and above, however,
// dEQP GLES3 es3fFboColorbufferTests.cpp verifies that texture attachment of GL_RGB16F
// is possible, so assume that all GLES implementations support it.
bool render = IsGLExtensionEnabled("GL_EXT_color_buffer_half_float");
// Renderability of RGB is forbidden by GL_EXT_color_buffer_half_float in WebGL 2.
bool render = false;
TestFloatTextureFormat(GL_RGB16F, GL_RGB, GL_HALF_FLOAT, texture, filter, render,
textureData, readPixelsData);
}
......@@ -3796,7 +3796,8 @@ TEST_P(WebGLCompatibilityTest, RGBA16FTextures)
// Sized RGBA 16F
bool texture = true;
bool filter = true;
bool render = IsGLExtensionEnabled("GL_EXT_color_buffer_float");
bool render = IsGLExtensionEnabled("GL_EXT_color_buffer_float") ||
IsGLExtensionEnabled("GL_EXT_color_buffer_half_float");
TestFloatTextureFormat(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, texture, filter, render,
textureData, readPixelsData);
}
......
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