mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
glsl: add support for EXT_blend_func_extended builtins
gl_MaxDualSourceDrawBuffersEXT - Maximum dual-source draw buffers supported For ESSL 1.0, it provides two builtins since you can't have user-defined color output variables: gl_SecondaryFragColorEXT gl_SecondaryFragDataEXT[MaxDSDrawBuffers] Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
ceecb0876f
commit
1d1d02f2ac
2 changed files with 92 additions and 0 deletions
|
|
@ -7194,6 +7194,8 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
|
|||
{
|
||||
bool gl_FragColor_assigned = false;
|
||||
bool gl_FragData_assigned = false;
|
||||
bool gl_FragSecondaryColor_assigned = false;
|
||||
bool gl_FragSecondaryData_assigned = false;
|
||||
bool user_defined_fs_output_assigned = false;
|
||||
ir_variable *user_defined_fs_output = NULL;
|
||||
|
||||
|
|
@ -7211,6 +7213,10 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
|
|||
gl_FragColor_assigned = true;
|
||||
else if (strcmp(var->name, "gl_FragData") == 0)
|
||||
gl_FragData_assigned = true;
|
||||
else if (strcmp(var->name, "gl_SecondaryFragColorEXT") == 0)
|
||||
gl_FragSecondaryColor_assigned = true;
|
||||
else if (strcmp(var->name, "gl_SecondaryFragDataEXT") == 0)
|
||||
gl_FragSecondaryData_assigned = true;
|
||||
else if (!is_gl_identifier(var->name)) {
|
||||
if (state->stage == MESA_SHADER_FRAGMENT &&
|
||||
var->data.mode == ir_var_shader_out) {
|
||||
|
|
@ -7242,11 +7248,29 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
|
|||
_mesa_glsl_error(&loc, state, "fragment shader writes to both "
|
||||
"`gl_FragColor' and `%s'",
|
||||
user_defined_fs_output->name);
|
||||
} else if (gl_FragSecondaryColor_assigned && gl_FragSecondaryData_assigned) {
|
||||
_mesa_glsl_error(&loc, state, "fragment shader writes to both "
|
||||
"`gl_FragSecondaryColorEXT' and"
|
||||
" `gl_FragSecondaryDataEXT'");
|
||||
} else if (gl_FragColor_assigned && gl_FragSecondaryData_assigned) {
|
||||
_mesa_glsl_error(&loc, state, "fragment shader writes to both "
|
||||
"`gl_FragColor' and"
|
||||
" `gl_FragSecondaryDataEXT'");
|
||||
} else if (gl_FragData_assigned && gl_FragSecondaryColor_assigned) {
|
||||
_mesa_glsl_error(&loc, state, "fragment shader writes to both "
|
||||
"`gl_FragData' and"
|
||||
" `gl_FragSecondaryColorEXT'");
|
||||
} else if (gl_FragData_assigned && user_defined_fs_output_assigned) {
|
||||
_mesa_glsl_error(&loc, state, "fragment shader writes to both "
|
||||
"`gl_FragData' and `%s'",
|
||||
user_defined_fs_output->name);
|
||||
}
|
||||
|
||||
if ((gl_FragSecondaryColor_assigned || gl_FragSecondaryData_assigned) &&
|
||||
!state->EXT_blend_func_extended_enable) {
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"Dual source blending requires EXT_blend_func_extended");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -377,6 +377,11 @@ private:
|
|||
return add_variable(name, type, ir_var_shader_out, slot);
|
||||
}
|
||||
|
||||
ir_variable *add_index_output(int slot, int index, const glsl_type *type, const char *name)
|
||||
{
|
||||
return add_index_variable(name, type, ir_var_shader_out, slot, index);
|
||||
}
|
||||
|
||||
ir_variable *add_system_value(int slot, const glsl_type *type,
|
||||
const char *name)
|
||||
{
|
||||
|
|
@ -385,6 +390,8 @@ private:
|
|||
|
||||
ir_variable *add_variable(const char *name, const glsl_type *type,
|
||||
enum ir_variable_mode mode, int slot);
|
||||
ir_variable *add_index_variable(const char *name, const glsl_type *type,
|
||||
enum ir_variable_mode mode, int slot, int index);
|
||||
ir_variable *add_uniform(const glsl_type *type, const char *name);
|
||||
ir_variable *add_const(const char *name, int value);
|
||||
ir_variable *add_const_ivec3(const char *name, int x, int y, int z);
|
||||
|
|
@ -430,6 +437,46 @@ builtin_variable_generator::builtin_variable_generator(
|
|||
{
|
||||
}
|
||||
|
||||
ir_variable *
|
||||
builtin_variable_generator::add_index_variable(const char *name,
|
||||
const glsl_type *type,
|
||||
enum ir_variable_mode mode, int slot, int index)
|
||||
{
|
||||
ir_variable *var = new(symtab) ir_variable(type, name, mode);
|
||||
var->data.how_declared = ir_var_declared_implicitly;
|
||||
|
||||
switch (var->data.mode) {
|
||||
case ir_var_auto:
|
||||
case ir_var_shader_in:
|
||||
case ir_var_uniform:
|
||||
case ir_var_system_value:
|
||||
var->data.read_only = true;
|
||||
break;
|
||||
case ir_var_shader_out:
|
||||
case ir_var_shader_storage:
|
||||
break;
|
||||
default:
|
||||
/* The only variables that are added using this function should be
|
||||
* uniforms, shader storage, shader inputs, and shader outputs, constants
|
||||
* (which use ir_var_auto), and system values.
|
||||
*/
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
var->data.location = slot;
|
||||
var->data.explicit_location = (slot >= 0);
|
||||
var->data.explicit_index = 1;
|
||||
var->data.index = index;
|
||||
|
||||
/* Once the variable is created an initialized, add it to the symbol table
|
||||
* and add the declaration to the IR stream.
|
||||
*/
|
||||
instructions->push_tail(var);
|
||||
|
||||
symtab->add_variable(var);
|
||||
return var;
|
||||
}
|
||||
|
||||
ir_variable *
|
||||
builtin_variable_generator::add_variable(const char *name,
|
||||
|
|
@ -581,6 +628,14 @@ builtin_variable_generator::generate_constants()
|
|||
add_const("gl_MaxVaryingVectors",
|
||||
state->ctx->Const.MaxVarying);
|
||||
}
|
||||
|
||||
/* EXT_blend_func_extended brings a built in constant
|
||||
* for determining number of dual source draw buffers
|
||||
*/
|
||||
if (state->EXT_blend_func_extended_enable) {
|
||||
add_const("gl_MaxDualSourceDrawBuffersEXT",
|
||||
state->Const.MaxDualSourceDrawBuffers);
|
||||
}
|
||||
} else {
|
||||
add_const("gl_MaxVertexUniformComponents",
|
||||
state->Const.MaxVertexUniformComponents);
|
||||
|
|
@ -1017,6 +1072,19 @@ builtin_variable_generator::generate_fs_special_vars()
|
|||
array(vec4_t, state->Const.MaxDrawBuffers), "gl_FragData");
|
||||
}
|
||||
|
||||
if (state->es_shader && state->language_version == 100 && state->EXT_blend_func_extended_enable) {
|
||||
/* We make an assumption here that there will only ever be one dual-source draw buffer
|
||||
* In case this assumption is ever proven to be false, make sure to assert here
|
||||
* since we don't handle this case.
|
||||
* In practice, this issue will never arise since no hardware will support it.
|
||||
*/
|
||||
assert(state->Const.MaxDualSourceDrawBuffers <= 1);
|
||||
add_index_output(FRAG_RESULT_DATA0, 1, vec4_t, "gl_SecondaryFragColorEXT");
|
||||
add_index_output(FRAG_RESULT_DATA0, 1,
|
||||
array(vec4_t, state->Const.MaxDualSourceDrawBuffers),
|
||||
"gl_SecondaryFragDataEXT");
|
||||
}
|
||||
|
||||
/* gl_FragDepth has always been in desktop GLSL, but did not appear in GLSL
|
||||
* ES 1.00.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue