From c1d3080ee86cd3d914712ffe0bb533c5d6a6b271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tapani=20P=C3=A4lli?= Date: Thu, 12 Dec 2013 12:57:57 +0200 Subject: [PATCH] glsl: introduce data section to ir_variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Data section helps serialization and cloning of a ir_variable. This patch includes the helper bits used for read only ir_variables. Signed-off-by: Tapani Pälli Reviewed-by: Paul Berry --- src/glsl/ast_function.cpp | 2 +- src/glsl/ast_to_hir.cpp | 30 +++++++++++------------ src/glsl/builtin_variables.cpp | 6 ++--- src/glsl/ir.cpp | 17 +++++++------ src/glsl/ir.h | 24 ++++++++++-------- src/glsl/ir_clone.cpp | 8 +++--- src/glsl/ir_print_visitor.cpp | 6 ++--- src/glsl/ir_reader.cpp | 6 ++--- src/glsl/ir_set_program_inouts.cpp | 4 +-- src/glsl/link_varyings.cpp | 28 ++++++++++----------- src/glsl/linker.cpp | 6 ++--- src/glsl/loop_analysis.h | 3 ++- src/glsl/lower_named_interface_blocks.cpp | 4 +-- src/glsl/lower_packed_varyings.cpp | 4 +-- src/glsl/opt_cse.cpp | 2 +- src/glsl/opt_function_inlining.cpp | 2 +- src/glsl/tests/builtin_variable_test.cpp | 2 +- src/mesa/drivers/dri/i965/brw_fs.cpp | 4 +-- 18 files changed, 83 insertions(+), 75 deletions(-) diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 64237594e13..8202116324f 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -157,7 +157,7 @@ verify_parameter_modes(_mesa_glsl_parse_state *state, if (var) var->assigned = true; - if (var && var->read_only) { + if (var && var->data.read_only) { _mesa_glsl_error(&loc, state, "function parameter '%s %s' references the " "read-only variable '%s'", diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index f35d8679e70..0278f97cb17 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -776,7 +776,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, non_lvalue_description); error_emitted = true; } else if (lhs->variable_referenced() != NULL - && lhs->variable_referenced()->read_only) { + && lhs->variable_referenced()->data.read_only) { _mesa_glsl_error(&lhs_loc, state, "assignment to read-only variable '%s'", lhs->variable_referenced()->name); @@ -2168,20 +2168,20 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, "`invariant' after being used", var->name); } else { - var->invariant = 1; + var->data.invariant = 1; } } if (qual->flags.q.constant || qual->flags.q.attribute || qual->flags.q.uniform || (qual->flags.q.varying && (state->target == fragment_shader))) - var->read_only = 1; + var->data.read_only = 1; if (qual->flags.q.centroid) - var->centroid = 1; + var->data.centroid = 1; if (qual->flags.q.sample) - var->sample = 1; + var->data.sample = 1; if (qual->flags.q.attribute && state->target != vertex_shader) { var->type = glsl_type::error_type; @@ -2275,16 +2275,16 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, switch (state->target) { case vertex_shader: if (var->mode == ir_var_shader_out) - var->invariant = true; + var->data.invariant = true; break; case geometry_shader: if ((var->mode == ir_var_shader_in) || (var->mode == ir_var_shader_out)) - var->invariant = true; + var->data.invariant = true; break; case fragment_shader: if (var->mode == ir_var_shader_in) - var->invariant = true; + var->data.invariant = true; break; } } @@ -2650,9 +2650,9 @@ process_initializer(ir_variable *var, ast_declaration *decl, } if (rhs && !rhs->type->is_error()) { - bool temp = var->read_only; + bool temp = var->data.read_only; if (type->qualifier.flags.q.constant) - var->read_only = false; + var->data.read_only = false; /* Never emit code to initialize a uniform. */ @@ -2691,7 +2691,7 @@ process_initializer(ir_variable *var, ast_declaration *decl, */ var->type = initializer_type; - var->read_only = temp; + var->data.read_only = temp; } return result; @@ -2859,7 +2859,7 @@ ast_declarator_list::hir(exec_list *instructions, "`invariant' after being used", earlier->name); } else { - earlier->invariant = true; + earlier->data.invariant = true; } } @@ -3077,7 +3077,7 @@ ast_declarator_list::hir(exec_list *instructions, mode, var->name, extra); } } else if (var->mode == ir_var_shader_in) { - var->read_only = true; + var->data.read_only = true; if (state->target == vertex_shader) { bool error_emitted = false; @@ -5097,8 +5097,8 @@ ast_interface_block::hir(exec_list *instructions, ralloc_strdup(state, fields[i].name), var_mode); var->interpolation = fields[i].interpolation; - var->centroid = fields[i].centroid; - var->sample = fields[i].sample; + var->data.centroid = fields[i].centroid; + var->data.sample = fields[i].sample; var->init_interface_type(block_type); if (redeclaring_per_vertex) { diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp index d0e76e3a402..9cc11b77c85 100644 --- a/src/glsl/builtin_variables.cpp +++ b/src/glsl/builtin_variables.cpp @@ -442,7 +442,7 @@ builtin_variable_generator::add_variable(const char *name, case ir_var_shader_in: case ir_var_uniform: case ir_var_system_value: - var->read_only = true; + var->data.read_only = true; break; case ir_var_shader_out: break; @@ -937,8 +937,8 @@ builtin_variable_generator::generate_varyings() add_variable(fields[i].name, fields[i].type, ir_var_shader_out, fields[i].location); var->interpolation = fields[i].interpolation; - var->centroid = fields[i].centroid; - var->sample = fields[i].sample; + var->data.centroid = fields[i].centroid; + var->data.sample = fields[i].sample; var->init_interface_type(per_vertex_out_type); } } diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index 623bc1bb2e9..a3ca4ef7fd4 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -1359,7 +1359,7 @@ ir_dereference::is_lvalue() const /* Every l-value derference chain eventually ends in a variable. */ - if ((var == NULL) || var->read_only) + if ((var == NULL) || var->data.read_only) return false; /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: @@ -1580,7 +1580,6 @@ ir_swizzle::variable_referenced() const ir_variable::ir_variable(const struct glsl_type *type, const char *name, ir_variable_mode mode) : max_array_access(0), max_ifc_array_access(NULL), - read_only(false), centroid(false), sample(false), invariant(false), how_declared(ir_var_declared_normally), mode(mode), interpolation(INTERP_QUALIFIER_NONE), atomic() { @@ -1598,10 +1597,14 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, this->pixel_center_integer = false; this->depth_layout = ir_depth_layout_none; this->used = false; + this->data.read_only = false; + this->data.centroid = false; + this->data.sample = false; + this->data.invariant = false; if (type != NULL) { if (type->base_type == GLSL_TYPE_SAMPLER) - this->read_only = true; + this->data.read_only = true; if (type->is_interface()) this->init_interface_type(type); @@ -1701,11 +1704,11 @@ ir_function_signature::qualifiers_match(exec_list *params) ir_variable *a = (ir_variable *)iter_a.get(); ir_variable *b = (ir_variable *)iter_b.get(); - if (a->read_only != b->read_only || + if (a->data.read_only != b->data.read_only || !modes_match(a->mode, b->mode) || a->interpolation != b->interpolation || - a->centroid != b->centroid || - a->sample != b->sample) { + a->data.centroid != b->data.centroid || + a->data.sample != b->data.sample) { /* parameter a's qualifiers don't match */ return a->name; @@ -1891,7 +1894,7 @@ mode_string(const ir_variable *var) { switch (var->mode) { case ir_var_auto: - return (var->read_only) ? "global constant" : "global variable"; + return (var->data.read_only) ? "global constant" : "global variable"; case ir_var_uniform: return "uniform"; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 7a939a236b8..cdede59d864 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -522,16 +522,20 @@ public: */ unsigned *max_ifc_array_access; - /** - * Is the variable read-only? - * - * This is set for variables declared as \c const, shader inputs, - * and uniforms. - */ - unsigned read_only:1; - unsigned centroid:1; - unsigned sample:1; - unsigned invariant:1; + struct ir_variable_data { + + /** + * Is the variable read-only? + * + * This is set for variables declared as \c const, shader inputs, + * and uniforms. + */ + unsigned read_only:1; + unsigned centroid:1; + unsigned sample:1; + unsigned invariant:1; + + } data; /** * Has this variable been used for reading or writing? diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index df6e971f41a..a781cf0d24d 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -50,10 +50,10 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const memcpy(var->max_ifc_array_access, this->max_ifc_array_access, this->interface_type->length * sizeof(unsigned)); } - var->read_only = this->read_only; - var->centroid = this->centroid; - var->sample = this->sample; - var->invariant = this->invariant; + var->data.read_only = this->data.read_only; + var->data.centroid = this->data.centroid; + var->data.sample = this->data.sample; + var->data.invariant = this->data.invariant; var->interpolation = this->interpolation; var->location = this->location; var->index = this->index; diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index 2beefedf16e..ae5074ba9a2 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/src/glsl/ir_print_visitor.cpp @@ -148,9 +148,9 @@ void ir_print_visitor::visit(ir_variable *ir) { printf("(declare "); - const char *const cent = (ir->centroid) ? "centroid " : ""; - const char *const samp = (ir->sample) ? "sample " : ""; - const char *const inv = (ir->invariant) ? "invariant " : ""; + const char *const cent = (ir->data.centroid) ? "centroid " : ""; + const char *const samp = (ir->data.sample) ? "sample " : ""; + const char *const inv = (ir->data.invariant) ? "invariant " : ""; const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ", "in ", "out ", "inout ", "const_in ", "sys ", "temporary " }; diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index 4afe2810139..127358cf6df 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -412,11 +412,11 @@ ir_reader::read_declaration(s_expression *expr) // FINISHME: Check for duplicate/conflicting qualifiers. if (strcmp(qualifier->value(), "centroid") == 0) { - var->centroid = 1; + var->data.centroid = 1; } else if (strcmp(qualifier->value(), "sample") == 0) { - var->sample = 1; + var->data.sample = 1; } else if (strcmp(qualifier->value(), "invariant") == 0) { - var->invariant = 1; + var->data.invariant = 1; } else if (strcmp(qualifier->value(), "uniform") == 0) { var->mode = ir_var_uniform; } else if (strcmp(qualifier->value(), "auto") == 0) { diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp index 1a36527397e..2d824395c74 100644 --- a/src/glsl/ir_set_program_inouts.cpp +++ b/src/glsl/ir_set_program_inouts.cpp @@ -100,9 +100,9 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len, gl_fragment_program *fprog = (gl_fragment_program *) prog; fprog->InterpQualifier[var->location + var->index + offset + i] = (glsl_interp_qualifier) var->interpolation; - if (var->centroid) + if (var->data.centroid) fprog->IsCentroid |= bitfield; - if (var->sample) + if (var->data.sample) fprog->IsSample |= bitfield; } } else if (var->mode == ir_var_system_value) { diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp index 097cee5e4cb..53a9d75e3cd 100644 --- a/src/glsl/link_varyings.cpp +++ b/src/glsl/link_varyings.cpp @@ -93,39 +93,39 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, /* Check that all of the qualifiers match between stages. */ - if (input->centroid != output->centroid) { + if (input->data.centroid != output->data.centroid) { linker_error(prog, "%s shader output `%s' %s centroid qualifier, " "but %s shader input %s centroid qualifier\n", _mesa_glsl_shader_target_name(producer_type), output->name, - (output->centroid) ? "has" : "lacks", + (output->data.centroid) ? "has" : "lacks", _mesa_glsl_shader_target_name(consumer_type), - (input->centroid) ? "has" : "lacks"); + (input->data.centroid) ? "has" : "lacks"); return; } - if (input->sample != output->sample) { + if (input->data.sample != output->data.sample) { linker_error(prog, "%s shader output `%s' %s sample qualifier, " "but %s shader input %s sample qualifier\n", _mesa_glsl_shader_target_name(producer_type), output->name, - (output->sample) ? "has" : "lacks", + (output->data.sample) ? "has" : "lacks", _mesa_glsl_shader_target_name(consumer_type), - (input->sample) ? "has" : "lacks"); + (input->data.sample) ? "has" : "lacks"); return; } - if (input->invariant != output->invariant) { + if (input->data.invariant != output->data.invariant) { linker_error(prog, "%s shader output `%s' %s invariant qualifier, " "but %s shader input %s invariant qualifier\n", _mesa_glsl_shader_target_name(producer_type), output->name, - (output->invariant) ? "has" : "lacks", + (output->data.invariant) ? "has" : "lacks", _mesa_glsl_shader_target_name(consumer_type), - (input->invariant) ? "has" : "lacks"); + (input->data.invariant) ? "has" : "lacks"); return; } @@ -764,13 +764,13 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var) * regardless of where they appear. We can trivially satisfy that * requirement by changing the interpolation type to flat here. */ - producer_var->centroid = false; - producer_var->sample = false; + producer_var->data.centroid = false; + producer_var->data.sample = false; producer_var->interpolation = INTERP_QUALIFIER_FLAT; if (consumer_var) { - consumer_var->centroid = false; - consumer_var->sample = false; + consumer_var->data.centroid = false; + consumer_var->data.sample = false; consumer_var->interpolation = INTERP_QUALIFIER_FLAT; } } @@ -887,7 +887,7 @@ varying_matches::compute_packing_class(ir_variable *var) * * Therefore, the packing class depends only on the interpolation type. */ - unsigned packing_class = var->centroid | (var->sample << 1); + unsigned packing_class = var->data.centroid | (var->data.sample << 1); packing_class *= 4; packing_class += var->interpolation; return packing_class; diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 9e8eca5cc9e..38bf579805f 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -753,19 +753,19 @@ cross_validate_globals(struct gl_shader_program *prog, existing->has_initializer = true; } - if (existing->invariant != var->invariant) { + if (existing->data.invariant != var->data.invariant) { linker_error(prog, "declarations for %s `%s' have " "mismatching invariant qualifiers\n", mode_string(var), var->name); return; } - if (existing->centroid != var->centroid) { + if (existing->data.centroid != var->data.centroid) { linker_error(prog, "declarations for %s `%s' have " "mismatching centroid qualifiers\n", mode_string(var), var->name); return; } - if (existing->sample != var->sample) { + if (existing->data.sample != var->data.sample) { linker_error(prog, "declarations for %s `%s` have " "mismatching sample qualifiers\n", mode_string(var), var->name); diff --git a/src/glsl/loop_analysis.h b/src/glsl/loop_analysis.h index 6799f876cd7..f841042f026 100644 --- a/src/glsl/loop_analysis.h +++ b/src/glsl/loop_analysis.h @@ -217,7 +217,8 @@ public: /* Variables that are marked read-only *MUST* be loop constant. */ - assert(!this->var->read_only || (this->var->read_only && is_const)); + assert(!this->var->data.read_only + || (this->var->data.read_only && is_const)); return is_const; } diff --git a/src/glsl/lower_named_interface_blocks.cpp b/src/glsl/lower_named_interface_blocks.cpp index aa4c11070e5..0775375f614 100644 --- a/src/glsl/lower_named_interface_blocks.cpp +++ b/src/glsl/lower_named_interface_blocks.cpp @@ -156,8 +156,8 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) new_var->explicit_location = (new_var->location >= 0); new_var->interpolation = iface_t->fields.structure[i].interpolation; - new_var->centroid = iface_t->fields.structure[i].centroid; - new_var->sample = iface_t->fields.structure[i].sample; + new_var->data.centroid = iface_t->fields.structure[i].centroid; + new_var->data.sample = iface_t->fields.structure[i].sample; new_var->init_interface_type(iface_t); hash_table_insert(interface_namespace, new_var, diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp index e097e81f1b3..498914e312d 100644 --- a/src/glsl/lower_packed_varyings.cpp +++ b/src/glsl/lower_packed_varyings.cpp @@ -564,8 +564,8 @@ lower_packed_varyings_visitor::get_packed_varying_deref( */ packed_var->max_array_access = this->gs_input_vertices - 1; } - packed_var->centroid = unpacked_var->centroid; - packed_var->sample = unpacked_var->sample; + packed_var->data.centroid = unpacked_var->data.centroid; + packed_var->data.sample = unpacked_var->data.sample; packed_var->interpolation = unpacked_var->interpolation; packed_var->location = location; unpacked_var->insert_before(packed_var); diff --git a/src/glsl/opt_cse.cpp b/src/glsl/opt_cse.cpp index 8f73940d854..a2b63ee99ba 100644 --- a/src/glsl/opt_cse.cpp +++ b/src/glsl/opt_cse.cpp @@ -193,7 +193,7 @@ is_cse_candidate_visitor::visit(ir_dereference_variable *ir) /* Currently, since we don't handle kills of the ae based on variables * getting assigned, we can only handle constant variables. */ - if (ir->var->read_only) { + if (ir->var->data.read_only) { return visit_continue; } else { ok = false; diff --git a/src/glsl/opt_function_inlining.cpp b/src/glsl/opt_function_inlining.cpp index f8033a095d8..86d0fa3618a 100644 --- a/src/glsl/opt_function_inlining.cpp +++ b/src/glsl/opt_function_inlining.cpp @@ -139,7 +139,7 @@ ir_call::generate_inline(ir_instruction *next_ir) * read-only and the inlined function is inside a loop, the loop * analysis code will get confused. */ - parameters[i]->read_only = false; + parameters[i]->data.read_only = false; next_ir->insert_before(parameters[i]); } diff --git a/src/glsl/tests/builtin_variable_test.cpp b/src/glsl/tests/builtin_variable_test.cpp index 366fbce018a..accdd9155e4 100644 --- a/src/glsl/tests/builtin_variable_test.cpp +++ b/src/glsl/tests/builtin_variable_test.cpp @@ -129,7 +129,7 @@ common_builtin::constants_are_constant() EXPECT_FALSE(var->explicit_location); EXPECT_EQ(-1, var->location); - EXPECT_TRUE(var->read_only); + EXPECT_TRUE(var->data.read_only); } } diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index dbd93e7abca..374801fab20 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1084,8 +1084,8 @@ fs_visitor::emit_general_interpolation(ir_variable *ir) */ struct brw_reg interp = interp_reg(location, k); emit_linterp(attr, fs_reg(interp), interpolation_mode, - ir->centroid); - if (brw->needs_unlit_centroid_workaround && ir->centroid) { + ir->data.centroid); + if (brw->needs_unlit_centroid_workaround && ir->data.centroid) { /* Get the pixel/sample mask into f0 so that we know * which pixels are lit. Then, for each channel that is * unlit, replace the centroid data with non-centroid