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:
135
docs/specs/MESA_shader_integer_mix.spec
Normal file
135
docs/specs/MESA_shader_integer_mix.spec
Normal 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
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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. */
|
||||||
|
@@ -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 },
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user