Commit 447bb902 authored by Tapani Pälli's avatar Tapani Pälli

glsl: move variables in to ir_variable::data, part II

This patch moves following bitfields and variables to the data
structure:

explicit_location, explicit_index, explicit_binding, has_initializer,
is_unmatched_generic_inout, location_frac, from_named_ifc_block_nonarray,
from_named_ifc_block_array, depth_layout, location, index, binding,
max_array_access, atomic
Signed-off-by: default avatarTapani Pälli <tapani.palli@intel.com>
Reviewed-by: default avatarPaul Berry <stereotype441@gmail.com>
parent 33ee2c67
......@@ -41,8 +41,8 @@ update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc,
{
if (ir_dereference_variable *deref_var = ir->as_dereference_variable()) {
ir_variable *var = deref_var->var;
if (idx > var->max_array_access) {
var->max_array_access = idx;
if (idx > var->data.max_array_access) {
var->data.max_array_access = idx;
/* Check whether this access will, as a side effect, implicitly cause
* the size of a built-in array to be too large.
......@@ -184,7 +184,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
*/
ir_variable *v = array->whole_variable_referenced();
if (v != NULL)
v->max_array_access = array->type->array_size() - 1;
v->data.max_array_access = array->type->array_size() - 1;
}
/* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
......
......@@ -728,7 +728,7 @@ mark_whole_array_access(ir_rvalue *access)
ir_dereference_variable *deref = access->as_dereference_variable();
if (deref && deref->var) {
deref->var->max_array_access = deref->type->length - 1;
deref->var->data.max_array_access = deref->type->length - 1;
}
}
......@@ -819,11 +819,11 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
assert(var != NULL);
if (var->max_array_access >= unsigned(rhs->type->array_size())) {
if (var->data.max_array_access >= unsigned(rhs->type->array_size())) {
/* FINISHME: This should actually log the location of the RHS. */
_mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
"previous access",
var->max_array_access);
var->data.max_array_access);
}
var->type = glsl_type::get_array_instance(lhs->type->element_type(),
......@@ -2112,7 +2112,7 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
mode_string(var),
_mesa_glsl_shader_target_name(state->target));
} else {
var->explicit_location = true;
var->data.explicit_location = true;
/* This bit of silliness is needed because invalid explicit locations
* are supposed to be flagged during linking. Small negative values
......@@ -2122,11 +2122,11 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
* ensures that negative values stay negative.
*/
if (qual->location >= 0) {
var->location = (state->target == vertex_shader)
var->data.location = (state->target == vertex_shader)
? (qual->location + VERT_ATTRIB_GENERIC0)
: (qual->location + FRAG_RESULT_DATA0);
} else {
var->location = qual->location;
var->data.location = qual->location;
}
if (qual->flags.q.explicit_index) {
......@@ -2143,8 +2143,8 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
_mesa_glsl_error(loc, state,
"explicit index may only be 0 or 1");
} else {
var->explicit_index = true;
var->index = qual->index;
var->data.explicit_index = true;
var->data.index = qual->index;
}
}
}
......@@ -2315,20 +2315,21 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
if (qual->flags.q.explicit_binding &&
validate_binding_qualifier(state, loc, var, qual)) {
var->explicit_binding = true;
var->binding = qual->binding;
var->data.explicit_binding = true;
var->data.binding = qual->binding;
}
if (var->type->contains_atomic()) {
if (var->data.mode == ir_var_uniform) {
if (var->explicit_binding) {
unsigned *offset = &state->atomic_counter_offsets[var->binding];
if (var->data.explicit_binding) {
unsigned *offset =
&state->atomic_counter_offsets[var->data.binding];
if (*offset % ATOMIC_COUNTER_SIZE)
_mesa_glsl_error(loc, state,
"misaligned atomic counter offset");
var->atomic.offset = *offset;
var->data.atomic.offset = *offset;
*offset += var->type->atomic_size();
} else {
......@@ -2409,15 +2410,15 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
"gl_FragDepth");
}
if (qual->flags.q.depth_any)
var->depth_layout = ir_depth_layout_any;
var->data.depth_layout = ir_depth_layout_any;
else if (qual->flags.q.depth_greater)
var->depth_layout = ir_depth_layout_greater;
var->data.depth_layout = ir_depth_layout_greater;
else if (qual->flags.q.depth_less)
var->depth_layout = ir_depth_layout_less;
var->data.depth_layout = ir_depth_layout_less;
else if (qual->flags.q.depth_unchanged)
var->depth_layout = ir_depth_layout_unchanged;
var->data.depth_layout = ir_depth_layout_unchanged;
else
var->depth_layout = ir_depth_layout_none;
var->data.depth_layout = ir_depth_layout_none;
if (qual->flags.q.std140 ||
qual->flags.q.packed ||
......@@ -2478,10 +2479,10 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
const unsigned size = unsigned(var->type->array_size());
check_builtin_array_max_size(var->name, size, loc, state);
if ((size > 0) && (size <= earlier->max_array_access)) {
if ((size > 0) && (size <= earlier->data.max_array_access)) {
_mesa_glsl_error(& loc, state, "array size must be > %u due to "
"previous access",
earlier->max_array_access);
earlier->data.max_array_access);
}
earlier->type = var->type;
......@@ -2537,17 +2538,17 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
}
/* Prevent inconsistent redeclaration of depth layout qualifier. */
if (earlier->depth_layout != ir_depth_layout_none
&& earlier->depth_layout != var->depth_layout) {
if (earlier->data.depth_layout != ir_depth_layout_none
&& earlier->data.depth_layout != var->data.depth_layout) {
_mesa_glsl_error(&loc, state,
"gl_FragDepth: depth layout is declared here "
"as '%s, but it was previously declared as "
"'%s'",
depth_layout_string(var->depth_layout),
depth_layout_string(earlier->depth_layout));
depth_layout_string(var->data.depth_layout),
depth_layout_string(earlier->data.depth_layout));
}
earlier->depth_layout = var->depth_layout;
earlier->data.depth_layout = var->data.depth_layout;
} else if (allow_all_redeclarations) {
if (earlier->data.mode != var->data.mode) {
......@@ -2667,7 +2668,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
initializer_type = rhs->type;
var->constant_initializer = rhs->constant_expression_value();
var->has_initializer = true;
var->data.has_initializer = true;
/* If the declared variable is an unsized array, it must inherrit
* its full type from the initializer. A declaration such as
......@@ -5126,8 +5127,8 @@ ast_interface_block::hir(exec_list *instructions,
* the UBO declaration itself doesn't get an ir_variable unless it
* has an instance name. This is ugly.
*/
var->explicit_binding = this->layout.flags.q.explicit_binding;
var->binding = this->layout.binding;
var->data.explicit_binding = this->layout.flags.q.explicit_binding;
var->data.binding = this->layout.binding;
state->symbols->add_variable(var);
instructions->push_tail(var);
......@@ -5223,12 +5224,12 @@ ast_gs_input_layout::hir(exec_list *instructions,
*/
if (var->type->is_unsized_array()) {
if (var->max_array_access >= num_vertices) {
if (var->data.max_array_access >= num_vertices) {
_mesa_glsl_error(&loc, state,
"this geometry shader input layout implies %u"
" vertices, but an access to element %u of input"
" `%s' already exists", num_vertices,
var->max_array_access, var->name);
var->data.max_array_access, var->name);
} else {
var->type = glsl_type::get_array_instance(var->type->fields.array,
num_vertices);
......
......@@ -455,9 +455,9 @@ builtin_variable_generator::add_variable(const char *name,
break;
}
var->location = slot;
var->explicit_location = (slot >= 0);
var->explicit_index = 0;
var->data.location = slot;
var->data.explicit_location = (slot >= 0);
var->data.explicit_index = 0;
/* Once the variable is created an initialized, add it to the symbol table
* and add the declaration to the IR stream.
......@@ -524,7 +524,7 @@ builtin_variable_generator::add_const(const char *name, int value)
ir_var_auto, -1);
var->constant_value = new(var) ir_constant(value);
var->constant_initializer = new(var) ir_constant(value);
var->has_initializer = true;
var->data.has_initializer = true;
return var;
}
......
......@@ -1579,21 +1579,21 @@ 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), atomic()
: max_ifc_array_access(NULL)
{
this->ir_type = ir_type_variable;
this->type = type;
this->name = ralloc_strdup(this, name);
this->explicit_location = false;
this->has_initializer = false;
this->location = -1;
this->location_frac = 0;
this->data.explicit_location = false;
this->data.has_initializer = false;
this->data.location = -1;
this->data.location_frac = 0;
this->warn_extension = NULL;
this->constant_value = NULL;
this->constant_initializer = NULL;
this->data.origin_upper_left = false;
this->data.pixel_center_integer = false;
this->depth_layout = ir_depth_layout_none;
this->data.depth_layout = ir_depth_layout_none;
this->data.used = false;
this->data.read_only = false;
this->data.centroid = false;
......@@ -1602,6 +1602,9 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
this->data.how_declared = ir_var_declared_normally;
this->data.mode = mode;
this->data.interpolation = INTERP_QUALIFIER_NONE;
this->data.max_array_access = 0;
this->data.atomic.buffer_index = 0;
this->data.atomic.offset = 0;
if (type != NULL) {
if (type->base_type == GLSL_TYPE_SAMPLER)
......@@ -1635,7 +1638,7 @@ ir_variable::determine_interpolation_mode(bool flat_shade)
{
if (this->data.interpolation != INTERP_QUALIFIER_NONE)
return (glsl_interp_qualifier) this->data.interpolation;
int location = this->location;
int location = this->data.location;
bool is_gl_Color =
location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1;
if (flat_shade && is_gl_Color)
......
......@@ -502,13 +502,6 @@ public:
*/
const char *name;
/**
* Highest element accessed with a constant expression array index
*
* Not used for non-array variables.
*/
unsigned max_array_access;
/**
* For variables which satisfy the is_interface_instance() predicate, this
* points to an array of integers such that if the ith member of the
......@@ -587,117 +580,124 @@ public:
unsigned pixel_center_integer:1;
/*@}*/
} data;
/**
* Was the location explicitly set in the shader?
*
* If the location is explicitly set in the shader, it \b cannot be changed
* by the linker or by the API (e.g., calls to \c glBindAttribLocation have
* no effect).
*/
unsigned explicit_location:1;
unsigned explicit_index:1;
/**
* Was the location explicitly set in the shader?
*
* If the location is explicitly set in the shader, it \b cannot be changed
* by the linker or by the API (e.g., calls to \c glBindAttribLocation have
* no effect).
*/
unsigned explicit_location:1;
unsigned explicit_index:1;
/**
* Was an initial binding explicitly set in the shader?
*
* If so, constant_value contains an integer ir_constant representing the
* initial binding point.
*/
unsigned explicit_binding:1;
/**
* Was an initial binding explicitly set in the shader?
*
* If so, constant_value contains an integer ir_constant representing the
* initial binding point.
*/
unsigned explicit_binding:1;
/**
* Does this variable have an initializer?
*
* This is used by the linker to cross-validiate initializers of global
* variables.
*/
unsigned has_initializer:1;
/**
* Does this variable have an initializer?
*
* This is used by the linker to cross-validiate initializers of global
* variables.
*/
unsigned has_initializer:1;
/**
* Is this variable a generic output or input that has not yet been matched
* up to a variable in another stage of the pipeline?
*
* This is used by the linker as scratch storage while assigning locations
* to generic inputs and outputs.
*/
unsigned is_unmatched_generic_inout:1;
/**
* Is this variable a generic output or input that has not yet been matched
* up to a variable in another stage of the pipeline?
*
* This is used by the linker as scratch storage while assigning locations
* to generic inputs and outputs.
*/
unsigned is_unmatched_generic_inout:1;
/**
* If non-zero, then this variable may be packed along with other variables
* into a single varying slot, so this offset should be applied when
* accessing components. For example, an offset of 1 means that the x
* component of this variable is actually stored in component y of the
* location specified by \c location.
*/
unsigned location_frac:2;
/**
* If non-zero, then this variable may be packed along with other variables
* into a single varying slot, so this offset should be applied when
* accessing components. For example, an offset of 1 means that the x
* component of this variable is actually stored in component y of the
* location specified by \c location.
*/
unsigned location_frac:2;
/**
* Non-zero if this variable was created by lowering a named interface
* block which was not an array.
*
* Note that this variable and \c from_named_ifc_block_array will never
* both be non-zero.
*/
unsigned from_named_ifc_block_nonarray:1;
/**
* Non-zero if this variable was created by lowering a named interface
* block which was not an array.
*
* Note that this variable and \c from_named_ifc_block_array will never
* both be non-zero.
*/
unsigned from_named_ifc_block_nonarray:1;
/**
* Non-zero if this variable was created by lowering a named interface
* block which was an array.
*
* Note that this variable and \c from_named_ifc_block_nonarray will never
* both be non-zero.
*/
unsigned from_named_ifc_block_array:1;
/**
* Non-zero if this variable was created by lowering a named interface
* block which was an array.
*
* Note that this variable and \c from_named_ifc_block_nonarray will never
* both be non-zero.
*/
unsigned from_named_ifc_block_array:1;
/**
* \brief Layout qualifier for gl_FragDepth.
*
* This is not equal to \c ir_depth_layout_none if and only if this
* variable is \c gl_FragDepth and a layout qualifier is specified.
*/
ir_depth_layout depth_layout;
/**
* \brief Layout qualifier for gl_FragDepth.
*
* This is not equal to \c ir_depth_layout_none if and only if this
* variable is \c gl_FragDepth and a layout qualifier is specified.
*/
ir_depth_layout depth_layout;
/**
* Storage location of the base of this variable
*
* The precise meaning of this field depends on the nature of the variable.
*
* - Vertex shader input: one of the values from \c gl_vert_attrib.
* - Vertex shader output: one of the values from \c gl_varying_slot.
* - Geometry shader input: one of the values from \c gl_varying_slot.
* - Geometry shader output: one of the values from \c gl_varying_slot.
* - Fragment shader input: one of the values from \c gl_varying_slot.
* - Fragment shader output: one of the values from \c gl_frag_result.
* - Uniforms: Per-stage uniform slot number for default uniform block.
* - Uniforms: Index within the uniform block definition for UBO members.
* - Other: This field is not currently used.
*
* If the variable is a uniform, shader input, or shader output, and the
* slot has not been assigned, the value will be -1.
*/
int location;
/**
* Storage location of the base of this variable
*
* The precise meaning of this field depends on the nature of the variable.
*
* - Vertex shader input: one of the values from \c gl_vert_attrib.
* - Vertex shader output: one of the values from \c gl_varying_slot.
* - Geometry shader input: one of the values from \c gl_varying_slot.
* - Geometry shader output: one of the values from \c gl_varying_slot.
* - Fragment shader input: one of the values from \c gl_varying_slot.
* - Fragment shader output: one of the values from \c gl_frag_result.
* - Uniforms: Per-stage uniform slot number for default uniform block.
* - Uniforms: Index within the uniform block definition for UBO members.
* - Other: This field is not currently used.
*
* If the variable is a uniform, shader input, or shader output, and the
* slot has not been assigned, the value will be -1.
*/
int location;
/**
* output index for dual source blending.
*/
int index;
/**
* output index for dual source blending.
*/
int index;
/**
* Initial binding point for a sampler or UBO.
*
* For array types, this represents the binding point for the first element.
*/
int binding;
/**
* Initial binding point for a sampler or UBO.
*
* For array types, this represents the binding point for the first element.
*/
int binding;
/**
* Location an atomic counter is stored at.
*/
struct {
unsigned buffer_index;
unsigned offset;
} atomic;
/**
* Location an atomic counter is stored at.
*/
struct {
unsigned buffer_index;
unsigned offset;
} atomic;
/**
* Highest element accessed with a constant expression array index
*
* Not used for non-array variables.
*/
unsigned max_array_access;
} data;
/**
* Built-in state that backs this uniform
......
......@@ -43,7 +43,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
ir_variable *var = new(mem_ctx) ir_variable(this->type, this->name,
(ir_variable_mode) this->data.mode);
var->max_array_access = this->max_array_access;
var->data.max_array_access = this->data.max_array_access;
if (this->is_interface_instance()) {
var->max_ifc_array_access =
rzalloc_array(var, unsigned, this->interface_type->length);
......@@ -55,19 +55,19 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
var->data.sample = this->data.sample;
var->data.invariant = this->data.invariant;
var->data.interpolation = this->data.interpolation;
var->location = this->location;
var->index = this->index;
var->binding = this->binding;
var->atomic.buffer_index = this->atomic.buffer_index;
var->atomic.offset = this->atomic.offset;
var->data.location = this->data.location;
var->data.index = this->data.index;
var->data.binding = this->data.binding;
var->data.atomic.buffer_index = this->data.atomic.buffer_index;
var->data.atomic.offset = this->data.atomic.offset;
var->warn_extension = this->warn_extension;
var->data.origin_upper_left = this->data.origin_upper_left;
var->data.pixel_center_integer = this->data.pixel_center_integer;
var->explicit_location = this->explicit_location;
var->explicit_index = this->explicit_index;
var->explicit_binding = this->explicit_binding;
var->has_initializer = this->has_initializer;
var->depth_layout = this->depth_layout;
var->data.explicit_location = this->data.explicit_location;
var->data.explicit_index = this->data.explicit_index;
var->data.explicit_binding = this->data.explicit_binding;
var->data.has_initializer = this->data.has_initializer;
var->data.depth_layout = this->data.depth_layout;
var->data.assigned = this->data.assigned;
var->data.how_declared = this->data.how_declared;
var->data.used = this->data.used;
......
......@@ -93,12 +93,14 @@ 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 + var->index + offset + i);
GLbitfield64 bitfield =
BITFIELD64_BIT(var->data.location + var->data.index + offset + i);
if (var->data.mode == ir_var_shader_in) {
prog->InputsRead |= bitfield;
if (is_fragment_shader) {
gl_fragment_program *fprog = (gl_fragment_program *) prog;
fprog->InterpQualifier[var->location + var->index + offset + i] =
fprog->InterpQualifier[var->data.location +
var->data.index + offset + i] =
(glsl_interp_qualifier) var->data.interpolation;
if (var->data.centroid)
fprog->IsCentroid |= bitfield;
......
......@@ -642,9 +642,9 @@ ir_validate::visit(ir_variable *ir)
* to be out of bounds.
*/
if (ir->type->array_size() > 0) {
if (ir->max_array_access >= ir->type->length) {
if (ir->data.max_array_access >= ir->type->length) {
printf("ir_variable has maximum access out of bounds (%d vs %d)\n",
ir->max_array_access, ir->type->length - 1);
ir->data.max_array_access, ir->type->length - 1);
ir->print();
abort();
}
......@@ -670,7 +670,7 @@ ir_validate::visit(ir_variable *ir)
}
}
if (ir->constant_initializer != NULL && !ir->has_initializer) {
if (ir->constant_initializer != NULL && !ir->data.has_initializer) {
printf("ir_variable didn't have an initializer, but has a constant "
"initializer value.\n");
ir->print();
......
......@@ -73,16 +73,16 @@ namespace {
const active_atomic_counter *const first = (active_atomic_counter *) a;
const active_atomic_counter *const second = (active_atomic_counter *) b;
return int(first->var->atomic.offset) - int(second->var->atomic.offset);
return int(first->var->data.atomic.offset) - int(second->var->data.atomic.offset);
}
bool
check_atomic_counters_overlap(const ir_variable *x, const ir_variable *y)
{
return ((x->atomic.offset >= y->atomic.offset &&
x->atomic.offset < y->atomic.offset + y->type->atomic_size()) ||
(y->atomic.offset >= x->atomic.offset &&
y->atomic.offset < x->atomic.offset + x->type->atomic_size()));
return ((x->data.atomic.offset >= y->data.atomic.offset &&
x->data.atomic.offset < y->data.atomic.offset + y->type->atomic_size()) ||
(y->data.atomic.offset >= x->data.atomic.offset &&
y->data.atomic.offset < x->data.atomic.offset + x->type->atomic_size()));
}
active_atomic_buffer *
......@@ -107,7 +107,7 @@ namespace {
unsigned id;
bool found = prog->UniformHash->get(id, var->name);
assert(found);
active_atomic_buffer *buf = &buffers[var->binding];
active_atomic_buffer *buf = &buffers[var->data.binding];
/* If this is the first time the buffer is used, increment
* the counter of buffers used.
......@@ -118,7 +118,7 @@ namespace {
buf->push_back(id, var);
buf->stage_references[i]++;
buf->size = MAX2(buf->size, var->atomic.offset +
buf->size = MAX2(buf->size, var->data.atomic.offset +
var->type->atomic_size());
}
}
......@@ -143,7 +143,7 @@ namespace {
linker_error(prog, "Atomic counter %s declared at offset %d "
"which is already in use.",
buffers[i].counters[j].var->name,
buffers[i].counters[j].var->atomic.offset);
buffers[i].counters[j].var->data.atomic.offset);
}
}
}
......@@ -190,9 +190,9 @@ link_assign_atomic_counter_resources(struct gl_context *ctx,
gl_uniform_storage *const storage = &prog->UniformStorage[id];
mab.Uniforms[j] = id;
var->atomic.buffer_index = i;