[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