On Fri, Nov 6, 2015 at 1:10 PM, Ian Romanick <i...@freedesktop.org> wrote: > On 11/05/2015 06:47 PM, Ryan Houdek wrote: >> gl_MaxDualSourceDrawBuffersEXT - Maximum DS draw buffers supported >> >> Only for ESSL 1.0 it provides two builtins since you can't have user-defined >> color output variables >> gl_SecondaryFragColorEXT and gl_SecondaryFragDataEXT[MaxDSDrawBuffers] >> --- >> src/glsl/ast_to_hir.cpp | 16 +++++++++++ >> src/glsl/builtin_variables.cpp | 62 >> ++++++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 78 insertions(+) >> >> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp >> index 0306530..9ac7d80 100644 >> --- a/src/glsl/ast_to_hir.cpp >> +++ b/src/glsl/ast_to_hir.cpp >> @@ -6973,6 +6973,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; >> >> @@ -6990,6 +6992,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) { >> @@ -7021,11 +7027,21 @@ 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_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"); >> + } > > The spec doesn't seem to provide any guidance about a shader like: > > #extension GL_EXT_blend_func_extended: require > void main() { > gl_FragData[0] = vec4(0); > glSecondaryFragColorEXT = vec4(0); > } > > What does NVIDIA's implementation do? We should mimic that behavior,
It says "GL_EXT_blend_func_extended not supported" :) Why would the above be problematic though? > and have a comment here justifying it. Something like > > /* The EXT_blend_func_extended spec doesn't say what to do if > * gl_FragData and glSecondaryFragColorEXT (or gl_FragColor and > * glSecondaryFragDataEXT) are written together. NVIDIA's XXX.YY > * driver [say what it does], so we mimic that. > */ > > We should also have piglit tests that exercise it. > >> } >> >> >> diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp >> index c30fb92..4933c8a 100644 >> --- a/src/glsl/builtin_variables.cpp >> +++ b/src/glsl/builtin_variables.cpp >> @@ -376,6 +376,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) >> { >> @@ -384,6 +389,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); >> @@ -429,6 +436,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, >> @@ -580,6 +627,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); >> @@ -1016,6 +1071,13 @@ 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) { >> + 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. >> */ >> > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev