diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/ir_clone.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_print_visitor.cpp | 3 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_set_program_inouts.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_variable.cpp | 25 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 8 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_tree_grafting.cpp | 39 |
6 files changed, 58 insertions, 21 deletions
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index c1befa95c..9adf47050 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -25,9 +25,7 @@ #include "main/compiler.h" #include "ir.h" #include "glsl_types.h" -extern "C" { #include "program/hash_table.h" -} /** * Duplicate an IR variable diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index ea7858224..b713bd03b 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -24,10 +24,7 @@ #include "ir_print_visitor.h" #include "glsl_types.h" #include "glsl_parser_extras.h" - -extern "C" { #include "program/hash_table.h" -} static void print_type(const glsl_type *t); diff --git a/mesalib/src/glsl/ir_set_program_inouts.cpp b/mesalib/src/glsl/ir_set_program_inouts.cpp index 3b10b9097..ae3ef74c7 100644 --- a/mesalib/src/glsl/ir_set_program_inouts.cpp +++ b/mesalib/src/glsl/ir_set_program_inouts.cpp @@ -34,10 +34,8 @@ * from the GLSL IR. */ -extern "C" { #include "main/core.h" /* for struct gl_program */ #include "program/hash_table.h" -} #include "ir.h" #include "ir_visitor.h" #include "glsl_types.h" diff --git a/mesalib/src/glsl/ir_variable.cpp b/mesalib/src/glsl/ir_variable.cpp index 58be64bfa..6ae3b1f9e 100644 --- a/mesalib/src/glsl/ir_variable.cpp +++ b/mesalib/src/glsl/ir_variable.cpp @@ -178,6 +178,14 @@ static struct gl_builtin_uniform_element gl_MESAFogParamsOptimized_elements[] = {NULL, {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED}, SWIZZLE_XYZW}, }; +static struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = { + {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB, 0}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = { + {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, 0}, SWIZZLE_XYZW}, +}; + #define MATRIX(name, statevar, modifier) \ static struct gl_builtin_uniform_element name ## _elements[] = { \ { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \ @@ -284,6 +292,8 @@ const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = { STATEVAR(gl_MESABumpRotMatrix0), STATEVAR(gl_MESABumpRotMatrix1), STATEVAR(gl_MESAFogParamsOptimized), + STATEVAR(gl_CurrentAttribVertMESA), + STATEVAR(gl_CurrentAttribFragMESA), {NULL, NULL, 0} }; @@ -355,7 +365,12 @@ add_uniform(exec_list *instructions, glsl_symbol_table *symtab, memcpy(slots->tokens, element->tokens, sizeof(element->tokens)); if (type->is_array()) { - slots->tokens[1] = a; + if (strcmp(name, "gl_CurrentAttribVertMESA") == 0 || + strcmp(name, "gl_CurrentAttribFragMESA") == 0) { + slots->tokens[2] = a; + } else { + slots->tokens[1] = a; + } } slots->swizzle = element->swizzle; @@ -518,6 +533,14 @@ generate_110_uniforms(exec_list *instructions, add_uniform(instructions, symtab, "gl_Fog", symtab->get_type("gl_FogParameters")); + + /* Mesa-internal current attrib state */ + const glsl_type *const vert_attribs = + glsl_type::get_array_instance(glsl_type::vec4_type, VERT_ATTRIB_MAX); + add_uniform(instructions, symtab, "gl_CurrentAttribVertMESA", vert_attribs); + const glsl_type *const frag_attribs = + glsl_type::get_array_instance(glsl_type::vec4_type, FRAG_ATTRIB_MAX); + add_uniform(instructions, symtab, "gl_CurrentAttribFragMESA", frag_attribs); } /* This function should only be called for ES, not desktop GL. */ diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 9463f5305..a7c38a342 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1342,7 +1342,10 @@ assign_attribute_or_color_locations(gl_shader_program *prog, } } - /* The location was explicitly assigned, nothing to do here. + /* If the variable is not a built-in and has a location statically + * assigned in the shader (presumably via a layout qualifier), make sure + * that it doesn't collide with other assigned locations. Otherwise, + * add it to the list of variables that need linker-assigned locations. */ const unsigned slots = count_attribute_slots(var->type); if (var->location != -1) { @@ -1802,7 +1805,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) * present in a linked program. By checking for use of shading language * version 1.00, we also catch the GL_ARB_ES2_compatibility case. */ - if (ctx->API == API_OPENGLES2 || prog->Version == 100) { + if (!prog->InternalSeparateShader && + (ctx->API == API_OPENGLES2 || prog->Version == 100)) { if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { linker_error(prog, "program lacks a vertex shader\n"); } else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) { diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp index 22a1749b9..d32d14e88 100644 --- a/mesalib/src/glsl/opt_tree_grafting.cpp +++ b/mesalib/src/glsl/opt_tree_grafting.cpp @@ -76,6 +76,8 @@ public: virtual ir_visitor_status visit_enter(class ir_swizzle *); virtual ir_visitor_status visit_enter(class ir_texture *); + ir_visitor_status check_graft(ir_instruction *ir, ir_variable *var); + bool do_graft(ir_rvalue **rvalue); bool progress; @@ -148,18 +150,17 @@ ir_tree_grafting_visitor::visit_enter(ir_loop *ir) return visit_stop; } +/** + * Check if we can continue grafting after writing to a variable. If the + * expression we're trying to graft references the variable, we must stop. + * + * \param ir An instruction that writes to a variable. + * \param var The variable being updated. + */ ir_visitor_status -ir_tree_grafting_visitor::visit_leave(ir_assignment *ir) +ir_tree_grafting_visitor::check_graft(ir_instruction *ir, ir_variable *var) { - if (do_graft(&ir->rhs) || - do_graft(&ir->condition)) - return visit_stop; - - /* If this assignment updates a variable used in the assignment - * we're trying to graft, then we're done. - */ - if (dereferences_variable(this->graft_assign->rhs, - ir->lhs->variable_referenced())) { + if (dereferences_variable(this->graft_assign->rhs, var)) { if (debug) { printf("graft killed by: "); ir->print(); @@ -172,6 +173,19 @@ ir_tree_grafting_visitor::visit_leave(ir_assignment *ir) } ir_visitor_status +ir_tree_grafting_visitor::visit_leave(ir_assignment *ir) +{ + if (do_graft(&ir->rhs) || + do_graft(&ir->condition)) + return visit_stop; + + /* If this assignment updates a variable used in the assignment + * we're trying to graft, then we're done. + */ + return check_graft(ir, ir->lhs->variable_referenced()); +} + +ir_visitor_status ir_tree_grafting_visitor::visit_enter(ir_function *ir) { (void) ir; @@ -195,8 +209,11 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir) ir_rvalue *ir = (ir_rvalue *)iter.get(); ir_rvalue *new_ir = ir; - if (sig_param->mode != ir_var_in && sig_param->mode != ir_var_const_in) + if (sig_param->mode != ir_var_in && sig_param->mode != ir_var_const_in) { + if (check_graft(ir, sig_param) == visit_stop) + return visit_stop; continue; + } if (do_graft(&new_ir)) { ir->replace_with(new_ir); |