[Mesa-dev] [PATCH 05/25] i965/vec4: Obtain atomic counter locations by recursing through the visitor.
Francisco Jerez
currojerez at riseup.net
Tue May 5 14:48:12 PDT 2015
Until now atomic counter built-ins were handled in a way that
prevented the GLSL visitor from encountering atomic counter IR
variables directly. This makes the handling of atomic counters
consistent with other kinds of GLSL variable dereferences.
---
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 124 +++++++++++++------------
1 file changed, 64 insertions(+), 60 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index f79d586..ab1b33a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1055,28 +1055,32 @@ vec4_visitor::visit(ir_variable *ir)
break;
case ir_var_uniform:
- reg = new(this->mem_ctx) dst_reg(UNIFORM, this->uniforms);
+ if (ir->type->contains_atomic()) {
+ reg = new(this->mem_ctx) dst_reg(ir->data.atomic.offset);
- /* Thanks to the lower_ubo_reference pass, we will see only
- * ir_binop_ubo_load expressions and not ir_dereference_variable for UBO
- * variables, so no need for them to be in variable_ht.
- *
- * Some uniforms, such as samplers and atomic counters, have no actual
- * storage, so we should ignore them.
- */
- if (ir->is_in_uniform_block() || type_size(ir->type) == 0)
+ } else if (ir->is_in_uniform_block() || type_size(ir->type) == 0) {
+ /* Thanks to the lower_ubo_reference pass, we will see only
+ * ir_binop_ubo_load expressions and not ir_dereference_variable for
+ * UBO variables, so no need for them to be in variable_ht.
+ *
+ * Some uniforms such as samplers have no actual storage, so we
+ * should ignore them.
+ */
return;
+ } else {
+ reg = new(this->mem_ctx) dst_reg(UNIFORM, this->uniforms);
- /* Track how big the whole uniform variable is, in case we need to put a
- * copy of its data into pull constants for array access.
- */
- assert(this->uniforms < uniform_array_size);
- this->uniform_size[this->uniforms] = type_size(ir->type);
+ /* Track how big the whole uniform variable is, in case we need to
+ * put a copy of its data into pull constants for array access.
+ */
+ assert(this->uniforms < uniform_array_size);
+ this->uniform_size[this->uniforms] = type_size(ir->type);
- if (!strncmp(ir->name, "gl_", 3)) {
- setup_builtin_uniform_values(ir);
- } else {
- setup_uniform_values(ir);
+ if (!strncmp(ir->name, "gl_", 3)) {
+ setup_builtin_uniform_values(ir);
+ } else {
+ setup_uniform_values(ir);
+ }
}
break;
@@ -2042,45 +2046,56 @@ vec4_visitor::visit(ir_dereference_array *ir)
ir->array->accept(this);
src = this->result;
- if (constant_index) {
- src.reg_offset += constant_index->value.i[0] * array_stride;
- } else {
- /* Variable index array dereference. It eats the "vec4" of the
- * base of the array and an index that offsets the Mesa register
- * index.
- */
- ir->array_index->accept(this);
+ if (ir->array->type->contains_atomic()) {
+ dst_reg tmp(this, glsl_type::uint_type);
- src_reg index_reg;
+ ir->array_index->accept(this);
+ emit(MUL(tmp, this->result, ATOMIC_COUNTER_SIZE));
+ emit(ADD(tmp, src_reg(tmp), src));
+ this->result = src_reg(tmp);
- if (array_stride == 1) {
- index_reg = this->result;
+ } else {
+ if (constant_index) {
+ src.reg_offset += constant_index->value.i[0] * array_stride;
} else {
- index_reg = src_reg(this, glsl_type::int_type);
+ /* Variable index array dereference. It eats the "vec4" of the
+ * base of the array and an index that offsets the Mesa register
+ * index.
+ */
+ ir->array_index->accept(this);
- emit(MUL(dst_reg(index_reg), this->result, src_reg(array_stride)));
- }
+ src_reg index_reg;
- if (src.reladdr) {
- src_reg temp = src_reg(this, glsl_type::int_type);
+ if (array_stride == 1) {
+ index_reg = this->result;
+ } else {
+ index_reg = src_reg(this, glsl_type::int_type);
- emit(ADD(dst_reg(temp), *src.reladdr, index_reg));
+ emit(MUL(dst_reg(index_reg), this->result, src_reg(array_stride)));
+ }
- index_reg = temp;
- }
+ if (src.reladdr) {
+ src_reg temp = src_reg(this, glsl_type::int_type);
- src.reladdr = ralloc(mem_ctx, src_reg);
- memcpy(src.reladdr, &index_reg, sizeof(index_reg));
- }
+ emit(ADD(dst_reg(temp), *src.reladdr, index_reg));
- /* If the type is smaller than a vec4, replicate the last channel out. */
- if (ir->type->is_scalar() || ir->type->is_vector() || ir->type->is_matrix())
- src.swizzle = brw_swizzle_for_size(ir->type->vector_elements);
- else
- src.swizzle = BRW_SWIZZLE_NOOP;
- src.type = brw_type_for_base_type(ir->type);
+ index_reg = temp;
+ }
+
+ src.reladdr = ralloc(mem_ctx, src_reg);
+ memcpy(src.reladdr, &index_reg, sizeof(index_reg));
+ }
+
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ if (ir->type->is_scalar() || ir->type->is_vector() ||
+ ir->type->is_matrix())
+ src.swizzle = brw_swizzle_for_size(ir->type->vector_elements);
+ else
+ src.swizzle = BRW_SWIZZLE_NOOP;
+ src.type = brw_type_for_base_type(ir->type);
- this->result = src;
+ this->result = src;
+ }
}
void
@@ -2410,19 +2425,8 @@ vec4_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
ir_variable *location = deref->variable_referenced();
unsigned surf_index = (prog_data->base.binding_table.abo_start +
location->data.binding);
-
- /* Calculate the surface offset */
- src_reg offset(this, glsl_type::uint_type);
- ir_dereference_array *deref_array = deref->as_dereference_array();
- if (deref_array) {
- deref_array->array_index->accept(this);
-
- src_reg tmp(this, glsl_type::uint_type);
- emit(MUL(dst_reg(tmp), this->result, ATOMIC_COUNTER_SIZE));
- emit(ADD(dst_reg(offset), tmp, location->data.atomic.offset));
- } else {
- offset = location->data.atomic.offset;
- }
+ deref->accept(this);
+ const src_reg offset = this->result;
/* Emit the appropriate machine instruction */
const char *callee = ir->callee->function_name();
--
2.3.5
More information about the mesa-dev
mailing list