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 <tapani.palli@intel.com> Reviewed-by: Paul Berry <stereotype441@gmail.com>tags/mesa-10.1-rc1
@@ -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'", |
@@ -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) { |
@@ -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); | |||
} | |||
} |
@@ -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"; |
@@ -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? |
@@ -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; |
@@ -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 " }; |
@@ -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) { |
@@ -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) { |
@@ -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; |
@@ -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); |
@@ -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; | |||
} |
@@ -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, |
@@ -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); |
@@ -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; |
@@ -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]); | |||
} | |||
@@ -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); | |||
} | |||
} | |||
@@ -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 |