[Mesa-dev] [PATCH 1/3] mesa: restrict ES2 from 32-bit blending, add GL_EXT_float_blend
Ilia Mirkin
imirkin at alum.mit.edu
Mon Nov 2 16:50:58 PST 2015
GL_EXT_color_buffer_float adds support for float buffers in ES3.0+, but
explicitly disallows 32-bit blending. However this restriction was never
implemented in mesa.
Add the restriction, and also allow a driver to expose
GL_EXT_float_blend which re-enables the functionality.
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
Untested... looking for confirmation that this is the right thing to
do. Will write a piglit if it is.
src/mesa/main/api_validate.c | 46 ++++++++++++++++++++++++++++++++++++++++++--
src/mesa/main/extensions.c | 3 ++-
src/mesa/main/fbobject.c | 8 +++++++-
src/mesa/main/mtypes.h | 2 ++
4 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 06efe02..a44299d 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -46,10 +46,52 @@ check_valid_to_render(struct gl_context *ctx, const char *function)
}
switch (ctx->API) {
- case API_OPENGLES2:
+ case API_OPENGLES2: {
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ int i;
+
/* For ES2, we can draw if we have a vertex program/shader). */
- return ctx->VertexProgram._Current != NULL;
+ if (ctx->VertexProgram._Current == NULL)
+ return false;
+ /* From GL_EXT_color_buffer_float:
+ *
+ * "Blending applies only if the color buffer has a fixed-point or
+ * or floating-point format. If the color buffer has an integer
+ * format, proceed to the next operation. Furthermore, an
+ * INVALID_OPERATION error is generated by DrawArrays and the other
+ * drawing commands defined in section 2.8.3 (10.5 in ES 3.1) if
+ * blending is enabled (see below) and any draw buffer has 32-bit
+ * floating-point format components."
+ *
+ * However GL_EXT_float_blend removes this text.
+ */
+ if (fb->_Has32bitFloatColorBuffer &&
+ ctx->Color.BlendEnabled &&
+ !ctx->Extensions.EXT_float_blend) {
+ bool per_buffer =
+ ctx->Color._BlendFuncPerBuffer ||
+ ctx->Color._BlendEquationPerBuffer ||
+ (ctx->Color.BlendEnabled &&
+ (ctx->Color.BlendEnabled != ((1U << ctx->Const.MaxDrawBuffers) - 1)));
+ if (!per_buffer && !(ctx->Color.BlendEnabled & 1))
+ break;
+ for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
+ struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[i];
+ if (!rb)
+ continue;
+ if (!(ctx->Color.BlendEnabled & (1U << i)))
+ continue;
+ if (_mesa_get_format_datatype(rb->Format) == GL_FLOAT &&
+ _mesa_get_format_max_bits(rb->Format) > 16) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(32-bit float output + blending)", function);
+ return false;
+ }
+ }
+ }
+ break;
+ }
case API_OPENGLES:
/* For OpenGL ES, only draw if we have vertex positions
*/
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 64972fa..5b9e538 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -225,6 +225,7 @@ static const struct extension extension_table[] = {
{ "GL_EXT_discard_framebuffer", o(dummy_true), ES1 | ES2, 2009 },
{ "GL_EXT_blend_minmax", o(EXT_blend_minmax), GLL | ES1 | ES2, 1995 },
{ "GL_EXT_blend_subtract", o(dummy_true), GLL, 1995 },
+ { "GL_EXT_color_buffer_float", o(dummy_true), ES3, 2013 },
{ "GL_EXT_compiled_vertex_array", o(dummy_true), GLL, 1996 },
{ "GL_EXT_copy_texture", o(dummy_true), GLL, 1995 },
{ "GL_EXT_depth_bounds_test", o(EXT_depth_bounds_test), GL, 2002 },
@@ -232,6 +233,7 @@ static const struct extension extension_table[] = {
{ "GL_EXT_draw_buffers2", o(EXT_draw_buffers2), GL, 2006 },
{ "GL_EXT_draw_instanced", o(ARB_draw_instanced), GL, 2006 },
{ "GL_EXT_draw_range_elements", o(dummy_true), GLL, 1997 },
+ { "GL_EXT_float_blend", o(EXT_float_blend), ES3, 2015 },
{ "GL_EXT_fog_coord", o(dummy_true), GLL, 1999 },
{ "GL_EXT_framebuffer_blit", o(dummy_true), GL, 2005 },
{ "GL_EXT_framebuffer_multisample", o(EXT_framebuffer_multisample), GL, 2005 },
@@ -293,7 +295,6 @@ static const struct extension extension_table[] = {
{ "GL_EXT_unpack_subimage", o(dummy_true), ES2, 2011 },
{ "GL_EXT_vertex_array_bgra", o(EXT_vertex_array_bgra), GL, 2008 },
{ "GL_EXT_vertex_array", o(dummy_true), GLL, 1995 },
- { "GL_EXT_color_buffer_float", o(dummy_true), ES3, 2013 },
/* OES extensions */
{ "GL_OES_blend_equation_separate", o(EXT_blend_equation_separate), ES1, 2009 },
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index fe6bdc2..41ea4e1 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -957,6 +957,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
fb->Height = 0;
fb->_AllColorBuffersFixedPoint = GL_TRUE;
fb->_HasSNormOrFloatColorBuffer = GL_FALSE;
+ fb->_Has32bitFloatColorBuffer = GL_FALSE;
fb->_HasAttachments = true;
/* Start at -2 to more easily loop over all attachment points.
@@ -1081,7 +1082,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
/* check if integer color */
fb->_IntegerColor = _mesa_is_format_integer_color(attFormat);
- /* Update _AllColorBuffersFixedPoint and _HasSNormOrFloatColorBuffer. */
+ /* Update computed fb-global booleans. */
if (i >= 0) {
GLenum type = _mesa_get_format_datatype(attFormat);
@@ -1092,6 +1093,11 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
fb->_HasSNormOrFloatColorBuffer =
fb->_HasSNormOrFloatColorBuffer ||
type == GL_SIGNED_NORMALIZED || type == GL_FLOAT;
+
+ /* For EXT_color_buffer_float */
+ fb->_Has32bitFloatColorBuffer =
+ fb->_Has32bitFloatColorBuffer ||
+ (type == GL_FLOAT && _mesa_get_format_max_bits(attFormat) > 16);
}
/* Error-check width, height, format */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d6c1eb8..a129d02 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3171,6 +3171,7 @@ struct gl_framebuffer
/* ARB_color_buffer_float */
GLboolean _AllColorBuffersFixedPoint; /* no integer, no float */
GLboolean _HasSNormOrFloatColorBuffer;
+ GLboolean _Has32bitFloatColorBuffer;
/**
* The maximum number of layers in the framebuffer, or 0 if the framebuffer
@@ -3733,6 +3734,7 @@ struct gl_extensions
GLboolean EXT_blend_minmax;
GLboolean EXT_depth_bounds_test;
GLboolean EXT_draw_buffers2;
+ GLboolean EXT_float_blend;
GLboolean EXT_framebuffer_multisample;
GLboolean EXT_framebuffer_multisample_blit_scaled;
GLboolean EXT_framebuffer_sRGB;
--
2.4.10
More information about the mesa-dev
mailing list