[Mesa-dev] [PATCH] glsl: Implement MESA_shader_integer_mix extension.

Matt Turner mattst88 at gmail.com
Mon Sep 9 12:19:28 PDT 2013


Because why doesn't GLSL allow you to do this already?

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
---
 docs/specs/MESA_shader_integer_mix.spec | 135 ++++++++++++++++++++++++++++++++
 src/glsl/builtin_functions.cpp          |  39 +++++++--
 src/glsl/glcpp/glcpp-parse.y            |   3 +
 src/glsl/glsl_parser_extras.cpp         |   1 +
 src/glsl/glsl_parser_extras.h           |   2 +
 src/mesa/main/extensions.c              |   1 +
 src/mesa/main/mtypes.h                  |   3 +-
 7 files changed, 176 insertions(+), 8 deletions(-)
 create mode 100644 docs/specs/MESA_shader_integer_mix.spec

diff --git a/docs/specs/MESA_shader_integer_mix.spec b/docs/specs/MESA_shader_integer_mix.spec
new file mode 100644
index 0000000..d381ddd
--- /dev/null
+++ b/docs/specs/MESA_shader_integer_mix.spec
@@ -0,0 +1,135 @@
+Name
+
+    MESA_shader_integer_mix
+
+Name Strings
+
+    GL_MESA_shader_integer_mix
+
+Contact
+
+    Matt Turner (matt.turner 'at' intel.com)
+
+Contributors
+
+    Matt Turner, Intel
+    Ian Romanick, Intel
+
+Status
+
+    Shipping
+
+Version
+
+    Last Modified Date:         09/09/2013
+    Author Revision:            5
+
+Number
+
+    
+
+Dependencies
+
+    OpenGL 3.0 or OpenGL ES 3.0 is required. This extension interacts with
+    GL_ARB_ES3_compatibility.
+
+    This extension is written against the OpenGL 4.4 (core) specification
+    and the GLSL 4.40 specification.
+
+Overview
+
+    GLSL 1.30 (and GLSL ES 3.00) expanded the mix() built-in function to
+    operate on a boolean third argument that does not interpolate but
+    selects. This extension extends mix() to select between int, uint,
+    and bool components.
+
+New Procedures and Functions
+
+    None.
+
+New Tokens
+
+    None.
+
+Additions to Chapter 8 of the GLSL 4.40 Specification (Built-in Functions)
+
+    Modify Section 8.3, Common Functions
+
+    Additions to the table listing common built-in functions:
+
+      Syntax                       Description
+      ---------------------------  --------------------------------------------------
+      genIType mix(genIType x,     Selects which vector each returned component comes
+                   genIType y,     from. For a component of a that is false, the
+                   genBType a)     corresponding component of x is returned. For a
+      genUType mix(genUType x,     component of a that is true, the corresponding
+                   genUType y,     component of y is returned.
+                   genBType a)
+      genBType mix(genBType x,
+                   genBType y,
+                   genBType a)
+
+Additions to the AGL/GLX/WGL Specifications
+
+    None.
+
+Modifications to The OpenGL Shading Language Specification, Version 4.40
+
+    Including the following line in a shader can be used to control the
+    language features described in this extension:
+
+      #extension GL_MESA_shader_integer_mix : <behavior>
+
+    where <behavior> is as specified in section 3.3.
+
+    New preprocessor #defines are added to the OpenGL Shading Language:
+
+      #define GL_MESA_shader_integer_mix        1
+
+Interactions with ARB_ES3_compatibility
+
+    On desktop implementations that support ARB_ES3_compatibility,
+    GL_MESA_shader_integer_mix can be enabled (and the new functions
+    used) in shaders declared with '#version 300 es'.
+
+GLX Protocol
+
+    None.
+
+Errors
+
+    None.
+
+New State
+
+    None.
+
+New Implementation Dependent State
+
+    None.
+
+Issues
+
+    1) Should we allow linear interpolation of integers via a non-boolean
+       third component?
+
+    RESOLVED: No.
+
+    2) Should we allow mix() to select between boolean components?
+
+    RESOLVED: Yes. Implementing the same functionality using casts would be
+    possible but ugly.
+
+Revision History
+
+    Rev.    Date      Author    Changes
+    ----  --------    --------  ---------------------------------------------
+      5   09/09/2013  idr       Add ARB_ES3_compatibility interaction.
+
+      4   09/06/2013  mattst88  Allow extension on OpenGL ES 3.0.
+
+      3   08/28/2013  mattst88  Add #extension/#define changes.
+
+      2   08/26/2013  mattst88  Change vendor prefix to MESA. Add mix() that
+                                selects between boolean components.
+      1   08/26/2013  mattst88  Initial revision
diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp
index 7b7bae6..cc5e2a7 100644
--- a/src/glsl/builtin_functions.cpp
+++ b/src/glsl/builtin_functions.cpp
@@ -178,6 +178,12 @@ shader_bit_encoding(const _mesa_glsl_parse_state *state)
 }
 
 static bool
+shader_integer_mix(const _mesa_glsl_parse_state *state)
+{
+   return v130(state) && state->MESA_shader_integer_mix_enable;
+}
+
+static bool
 shader_packing(const _mesa_glsl_parse_state *state)
 {
    return state->ARB_shading_language_packing_enable ||
@@ -391,7 +397,9 @@ private:
    B2(max)
    B2(clamp)
    B2(mix_lrp)
-   B2(mix_sel)
+   ir_function_signature *_mix_sel(builtin_available_predicate avail,
+                                   const glsl_type *val_type,
+                                   const glsl_type *blend_type);
    B2(step)
    B2(smoothstep)
    B1(isnan)
@@ -743,10 +751,25 @@ builtin_builder::create_builtins()
                 _mix_lrp(glsl_type::vec3_type,  glsl_type::vec3_type),
                 _mix_lrp(glsl_type::vec4_type,  glsl_type::vec4_type),
 
-                _mix_sel(glsl_type::float_type, glsl_type::bool_type),
-                _mix_sel(glsl_type::vec2_type,  glsl_type::bvec2_type),
-                _mix_sel(glsl_type::vec3_type,  glsl_type::bvec3_type),
-                _mix_sel(glsl_type::vec4_type,  glsl_type::bvec4_type),
+                _mix_sel(v130, glsl_type::float_type, glsl_type::bool_type),
+                _mix_sel(v130, glsl_type::vec2_type,  glsl_type::bvec2_type),
+                _mix_sel(v130, glsl_type::vec3_type,  glsl_type::bvec3_type),
+                _mix_sel(v130, glsl_type::vec4_type,  glsl_type::bvec4_type),
+
+                _mix_sel(shader_integer_mix, glsl_type::int_type,   glsl_type::bool_type),
+                _mix_sel(shader_integer_mix, glsl_type::ivec2_type, glsl_type::bvec2_type),
+                _mix_sel(shader_integer_mix, glsl_type::ivec3_type, glsl_type::bvec3_type),
+                _mix_sel(shader_integer_mix, glsl_type::ivec4_type, glsl_type::bvec4_type),
+
+                _mix_sel(shader_integer_mix, glsl_type::uint_type,  glsl_type::bool_type),
+                _mix_sel(shader_integer_mix, glsl_type::uvec2_type, glsl_type::bvec2_type),
+                _mix_sel(shader_integer_mix, glsl_type::uvec3_type, glsl_type::bvec3_type),
+                _mix_sel(shader_integer_mix, glsl_type::uvec4_type, glsl_type::bvec4_type),
+
+                _mix_sel(shader_integer_mix, glsl_type::bool_type,  glsl_type::bool_type),
+                _mix_sel(shader_integer_mix, glsl_type::bvec2_type, glsl_type::bvec2_type),
+                _mix_sel(shader_integer_mix, glsl_type::bvec3_type, glsl_type::bvec3_type),
+                _mix_sel(shader_integer_mix, glsl_type::bvec4_type, glsl_type::bvec4_type),
                 NULL);
 
    add_function("step",
@@ -2216,12 +2239,14 @@ builtin_builder::_mix_lrp(const glsl_type *val_type, const glsl_type *blend_type
 }
 
 ir_function_signature *
-builtin_builder::_mix_sel(const glsl_type *val_type, const glsl_type *blend_type)
+builtin_builder::_mix_sel(builtin_available_predicate avail,
+                          const glsl_type *val_type,
+                          const glsl_type *blend_type)
 {
    ir_variable *x = in_var(val_type, "x");
    ir_variable *y = in_var(val_type, "y");
    ir_variable *a = in_var(blend_type, "a");
-   MAKE_SIG(val_type, v130, 3, x, y, a);
+   MAKE_SIG(val_type, avail, 3, x, y, a);
 
    /* cond_sel matches the ternary operator in that a selector of true choses
     * the first argument. This differs from mix(x, y, false) which choses the
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index ff5bdfe..fb1c1d0 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -1245,6 +1245,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
 
 	      if (extensions->ARB_shading_language_420pack)
 	         add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
+
+	      if (extensions->MESA_shader_integer_mix)
+	         add_builtin_define(parser, "GL_MESA_shader_integer_mix", 1);
 	   }
 	}
 
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index cd3907a..1e4d7c7 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -517,6 +517,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
    EXT(ARB_texture_query_lod,          true,  false,     ARB_texture_query_lod),
    EXT(ARB_gpu_shader5,                true,  false,     ARB_gpu_shader5),
    EXT(AMD_vertex_shader_layer,        true,  false,     AMD_vertex_shader_layer),
+   EXT(MESA_shader_integer_mix,        true,   true,     MESA_shader_integer_mix),
 };
 
 #undef EXT
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index c4443ac..15abbbc 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -315,6 +315,8 @@ struct _mesa_glsl_parse_state {
    bool AMD_vertex_shader_layer_warn;
    bool ARB_shading_language_420pack_enable;
    bool ARB_shading_language_420pack_warn;
+   bool MESA_shader_integer_mix_enable;
+   bool MESA_shader_integer_mix_warn;
    /*@}*/
 
    /** Extensions supported by the OpenGL implementation. */
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index f60157f..88fcde3 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -311,6 +311,7 @@ static const struct extension extension_table[] = {
    { "GL_IBM_texture_mirrored_repeat",             o(dummy_true),                              GLL,            1998 },
    { "GL_INGR_blend_func_separate",                o(EXT_blend_func_separate),                 GLL,            1999 },
    { "GL_MESA_pack_invert",                        o(MESA_pack_invert),                        GL,             2002 },
+   { "GL_MESA_shader_integer_mix",                 o(MESA_shader_integer_mix),                 GL       | ES3, 2013 },
    { "GL_MESA_texture_array",                      o(MESA_texture_array),                      GLL,            2007 },
    { "GL_MESA_texture_signed_rgba",                o(EXT_texture_snorm),                       GL,             2009 },
    { "GL_MESA_window_pos",                         o(dummy_true),                              GLL,            2000 },
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index ef16c59..ca7111e 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3154,8 +3154,9 @@ struct gl_extensions
    GLboolean ATI_fragment_shader;
    GLboolean ATI_separate_stencil;
    GLboolean MESA_pack_invert;
-   GLboolean MESA_ycbcr_texture;
+   GLboolean MESA_shader_integer_mix;
    GLboolean MESA_texture_array;
+   GLboolean MESA_ycbcr_texture;
    GLboolean NV_conditional_render;
    GLboolean NV_fog_distance;
    GLboolean NV_fragment_program_option;
-- 
1.8.3.2



More information about the mesa-dev mailing list