glsl: Implement MESA_shader_integer_mix extension.

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

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
Matt Turner
2013-08-28 18:01:39 -07:00
parent fd183fa02c
commit 56fff7063d
7 changed files with 176 additions and 8 deletions

View File

@@ -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

View File

@@ -187,6 +187,12 @@ shader_bit_encoding(const _mesa_glsl_parse_state *state)
state->ARB_gpu_shader5_enable; state->ARB_gpu_shader5_enable;
} }
static bool
shader_integer_mix(const _mesa_glsl_parse_state *state)
{
return v130(state) && state->MESA_shader_integer_mix_enable;
}
static bool static bool
shader_packing(const _mesa_glsl_parse_state *state) shader_packing(const _mesa_glsl_parse_state *state)
{ {
@@ -415,7 +421,9 @@ private:
BA2(max) BA2(max)
BA2(clamp) BA2(clamp)
B2(mix_lrp) 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(step)
B2(smoothstep) B2(smoothstep)
B1(isnan) B1(isnan)
@@ -773,10 +781,25 @@ builtin_builder::create_builtins()
_mix_lrp(glsl_type::vec3_type, glsl_type::vec3_type), _mix_lrp(glsl_type::vec3_type, glsl_type::vec3_type),
_mix_lrp(glsl_type::vec4_type, glsl_type::vec4_type), _mix_lrp(glsl_type::vec4_type, glsl_type::vec4_type),
_mix_sel(glsl_type::float_type, glsl_type::bool_type), _mix_sel(v130, glsl_type::float_type, glsl_type::bool_type),
_mix_sel(glsl_type::vec2_type, glsl_type::bvec2_type), _mix_sel(v130, glsl_type::vec2_type, glsl_type::bvec2_type),
_mix_sel(glsl_type::vec3_type, glsl_type::bvec3_type), _mix_sel(v130, glsl_type::vec3_type, glsl_type::bvec3_type),
_mix_sel(glsl_type::vec4_type, glsl_type::bvec4_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); NULL);
add_function("step", add_function("step",
@@ -2255,12 +2278,14 @@ builtin_builder::_mix_lrp(const glsl_type *val_type, const glsl_type *blend_type
} }
ir_function_signature * 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 *x = in_var(val_type, "x");
ir_variable *y = in_var(val_type, "y"); ir_variable *y = in_var(val_type, "y");
ir_variable *a = in_var(blend_type, "a"); 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);
/* csel matches the ternary operator in that a selector of true choses the /* csel matches the ternary operator in that a selector of true choses the
* first argument. This differs from mix(x, y, false) which choses the * first argument. This differs from mix(x, y, false) which choses the

View File

@@ -1245,6 +1245,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
if (extensions->ARB_shading_language_420pack) if (extensions->ARB_shading_language_420pack)
add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1); 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);
} }
} }

View File

@@ -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_texture_query_lod, true, false, ARB_texture_query_lod),
EXT(ARB_gpu_shader5, true, false, ARB_gpu_shader5), EXT(ARB_gpu_shader5, true, false, ARB_gpu_shader5),
EXT(AMD_vertex_shader_layer, true, false, AMD_vertex_shader_layer), EXT(AMD_vertex_shader_layer, true, false, AMD_vertex_shader_layer),
EXT(MESA_shader_integer_mix, true, true, MESA_shader_integer_mix),
}; };
#undef EXT #undef EXT

View File

@@ -315,6 +315,8 @@ struct _mesa_glsl_parse_state {
bool AMD_vertex_shader_layer_warn; bool AMD_vertex_shader_layer_warn;
bool ARB_shading_language_420pack_enable; bool ARB_shading_language_420pack_enable;
bool ARB_shading_language_420pack_warn; bool ARB_shading_language_420pack_warn;
bool MESA_shader_integer_mix_enable;
bool MESA_shader_integer_mix_warn;
/*@}*/ /*@}*/
/** Extensions supported by the OpenGL implementation. */ /** Extensions supported by the OpenGL implementation. */

View File

@@ -311,6 +311,7 @@ static const struct extension extension_table[] = {
{ "GL_IBM_texture_mirrored_repeat", o(dummy_true), GLL, 1998 }, { "GL_IBM_texture_mirrored_repeat", o(dummy_true), GLL, 1998 },
{ "GL_INGR_blend_func_separate", o(EXT_blend_func_separate), GLL, 1999 }, { "GL_INGR_blend_func_separate", o(EXT_blend_func_separate), GLL, 1999 },
{ "GL_MESA_pack_invert", o(MESA_pack_invert), GL, 2002 }, { "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_array", o(MESA_texture_array), GLL, 2007 },
{ "GL_MESA_texture_signed_rgba", o(EXT_texture_snorm), GL, 2009 }, { "GL_MESA_texture_signed_rgba", o(EXT_texture_snorm), GL, 2009 },
{ "GL_MESA_window_pos", o(dummy_true), GLL, 2000 }, { "GL_MESA_window_pos", o(dummy_true), GLL, 2000 },

View File

@@ -3154,8 +3154,9 @@ struct gl_extensions
GLboolean ATI_fragment_shader; GLboolean ATI_fragment_shader;
GLboolean ATI_separate_stencil; GLboolean ATI_separate_stencil;
GLboolean MESA_pack_invert; GLboolean MESA_pack_invert;
GLboolean MESA_ycbcr_texture; GLboolean MESA_shader_integer_mix;
GLboolean MESA_texture_array; GLboolean MESA_texture_array;
GLboolean MESA_ycbcr_texture;
GLboolean NV_conditional_render; GLboolean NV_conditional_render;
GLboolean NV_fog_distance; GLboolean NV_fog_distance;
GLboolean NV_fragment_program_option; GLboolean NV_fragment_program_option;