X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fir_set_program_inouts.cpp;h=91a8b452683a81d1872bdd43eaadf799b4bdacca;hb=15085b477b092ba4315d13b96112a8d714de8e27;hp=8c2bc30d614a96f3192d571717b14b30e746f257;hpb=cf45949d6a896651a5f3864d3b195e26d59eee74;p=mesa.git diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp index 8c2bc30d614..91a8b452683 100644 --- a/src/glsl/ir_set_program_inouts.cpp +++ b/src/glsl/ir_set_program_inouts.cpp @@ -26,7 +26,8 @@ * * Sets the InputsRead and OutputsWritten of Mesa programs. * - * Additionally, for fragment shaders, sets the InterpQualifier array. + * Additionally, for fragment shaders, sets the InterpQualifier array, the + * IsCentroid bitfield, and the UsesDFdy flag. * * Mesa programs (gl_program, not gl_shader_program) have a set of * flags indicating which varyings are read and written. Computing @@ -37,7 +38,6 @@ */ #include "main/core.h" /* for struct gl_program */ -#include "program/hash_table.h" #include "ir.h" #include "ir_visitor.h" #include "glsl_types.h" @@ -49,25 +49,29 @@ public: { this->prog = prog; this->is_fragment_shader = is_fragment_shader; - this->ht = hash_table_ctor(0, - hash_table_pointer_hash, - hash_table_pointer_compare); } ~ir_set_program_inouts_visitor() { - hash_table_dtor(this->ht); } virtual ir_visitor_status visit_enter(ir_dereference_array *); virtual ir_visitor_status visit_enter(ir_function_signature *); + virtual ir_visitor_status visit_enter(ir_expression *); + virtual ir_visitor_status visit_enter(ir_discard *); virtual ir_visitor_status visit(ir_dereference_variable *); - virtual ir_visitor_status visit(ir_variable *); struct gl_program *prog; - struct hash_table *ht; bool is_fragment_shader; }; +static inline bool +is_shader_inout(ir_variable *var) +{ + return var->mode == ir_var_shader_in || + var->mode == ir_var_shader_out || + var->mode == ir_var_system_value; +} + static void mark(struct gl_program *prog, ir_variable *var, int offset, int len, bool is_fragment_shader) @@ -81,17 +85,20 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len, */ for (int i = 0; i < len; i++) { - GLbitfield64 bitfield = BITFIELD64_BIT(var->location + offset + i); - if (var->mode == ir_var_in) { + GLbitfield64 bitfield = BITFIELD64_BIT(var->location + var->index + offset + i); + if (var->mode == ir_var_shader_in) { prog->InputsRead |= bitfield; if (is_fragment_shader) { gl_fragment_program *fprog = (gl_fragment_program *) prog; - fprog->InterpQualifier[var->location + offset + i] = + fprog->InterpQualifier[var->location + var->index + offset + i] = (glsl_interp_qualifier) var->interpolation; + if (var->centroid) + fprog->IsCentroid |= bitfield; } } else if (var->mode == ir_var_system_value) { prog->SystemValuesRead |= bitfield; } else { + assert(var->mode == ir_var_shader_out); prog->OutputsWritten |= bitfield; } } @@ -101,7 +108,7 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len, ir_visitor_status ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir) { - if (hash_table_find(this->ht, ir->var) == NULL) + if (!is_shader_inout(ir->var)) return visit_continue; if (ir->type->is_array()) { @@ -122,13 +129,13 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) ir_dereference_variable *deref_var; ir_constant *index = ir->array_index->as_constant(); deref_var = ir->array->as_dereference_variable(); - ir_variable *var = NULL; + ir_variable *var = deref_var ? deref_var->var : NULL; /* Check that we're dereferencing a shader in or out */ - if (deref_var) - var = (ir_variable *)hash_table_find(this->ht, deref_var->var); + if (!var || !is_shader_inout(var)) + return visit_continue; - if (index && var) { + if (index) { int width = 1; if (deref_var->type->is_array() && @@ -144,18 +151,6 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) return visit_continue; } -ir_visitor_status -ir_set_program_inouts_visitor::visit(ir_variable *ir) -{ - if (ir->mode == ir_var_in || - ir->mode == ir_var_out || - ir->mode == ir_var_system_value) { - hash_table_insert(this->ht, ir, ir); - } - - return visit_continue; -} - ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir) { @@ -166,6 +161,28 @@ ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir) return visit_continue_with_parent; } +ir_visitor_status +ir_set_program_inouts_visitor::visit_enter(ir_expression *ir) +{ + if (is_fragment_shader && ir->operation == ir_unop_dFdy) { + gl_fragment_program *fprog = (gl_fragment_program *) prog; + fprog->UsesDFdy = true; + } + return visit_continue; +} + +ir_visitor_status +ir_set_program_inouts_visitor::visit_enter(ir_discard *) +{ + /* discards are only allowed in fragment shaders. */ + assert(is_fragment_shader); + + gl_fragment_program *fprog = (gl_fragment_program *) prog; + fprog->UsesKill = true; + + return visit_continue; +} + void do_set_program_inouts(exec_list *instructions, struct gl_program *prog, bool is_fragment_shader) @@ -176,8 +193,11 @@ do_set_program_inouts(exec_list *instructions, struct gl_program *prog, prog->OutputsWritten = 0; prog->SystemValuesRead = 0; if (is_fragment_shader) { - memset(((gl_fragment_program *) prog)->InterpQualifier, 0, - sizeof(((gl_fragment_program *) prog)->InterpQualifier)); + gl_fragment_program *fprog = (gl_fragment_program *) prog; + memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier)); + fprog->IsCentroid = 0; + fprog->UsesDFdy = false; + fprog->UsesKill = false; } visit_list_elements(&v, instructions); }