[Mesa-dev] [PATCH 5/5] i965: Code generation uses complete_location now
Vincent Lejeune
vljn at ovi.com
Tue Jan 24 13:05:14 PST 2012
Linker generates location_tree * instead of single ints to store
varying locations, this patch makes i965 VS and FS code generator
able to produce output register access accordingly.
---
src/mesa/drivers/dri/i965/brw_fs.cpp | 14 +++-
src/mesa/drivers/dri/i965/brw_vec4.h | 3 +
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 106 +++++++++++++++++++++--
3 files changed, 111 insertions(+), 12 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 40327ac..a16e47a 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -444,7 +444,17 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
glsl_interp_qualifier interpolation_mode =
ir->determine_interpolation_mode(c->key.flat_shade);
+ unsigned delta = 0;
int location = ir->location;
+ if (ir->complete_location) {
+ unsigned size;
+ const struct register_info *tmp = get_register_info(ir->complete_location,ir->type,size);
+ location = tmp[0].index;
+ delta += tmp[0].writemask_offset;
+ ralloc_free((void *)tmp);
+ }
+
+
for (unsigned int i = 0; i < array_elements; i++) {
for (unsigned int j = 0; j < type->matrix_columns; j++) {
if (urb_setup[location] == -1) {
@@ -462,7 +472,7 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
* field of the setup reg.
*/
for (unsigned int k = 0; k < type->vector_elements; k++) {
- struct brw_reg interp = interp_reg(location, k);
+ struct brw_reg interp = interp_reg(location, k + delta);
interp = suboffset(interp, 3);
interp.type = reg->type;
emit(FS_OPCODE_CINTERP, attr, fs_reg(interp));
@@ -482,7 +492,7 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
k == 3 && !(c->key.proj_attrib_mask & (1 << location))) {
emit(BRW_OPCODE_MOV, attr, fs_reg(1.0f));
} else {
- struct brw_reg interp = interp_reg(location, k);
+ struct brw_reg interp = interp_reg(location, k + delta);
brw_wm_barycentric_interp_mode barycoord_mode;
if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
barycoord_mode = BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 2555fa7..602ccf6 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -354,6 +354,8 @@ public:
src_reg src_reg_for_float(float val);
+ bool handle_output_dereference(ir_dereference *ir);
+
/**
* \name Visit methods
*
@@ -387,6 +389,7 @@ public:
* for the ir->location's used.
*/
dst_reg output_reg[BRW_VERT_RESULT_MAX];
+ ir_variable *is_output_set[BRW_VERT_RESULT_MAX];
const char *output_reg_annotation[BRW_VERT_RESULT_MAX];
int uniform_size[MAX_UNIFORMS];
int uniform_vector_size[MAX_UNIFORMS];
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 06bde92..2af6008 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -850,17 +850,27 @@ vec4_visitor::visit(ir_variable *ir)
break;
case ir_var_out:
- reg = new(mem_ctx) dst_reg(this, ir->type);
+ {
+ const struct range_info &tmp = get_varying_range_info(ir->complete_location, ir->type);
+ if (is_output_set[tmp.index]) {
+ reg = variable_storage(is_output_set[tmp.index]);
+ } else {
+ reg = new(mem_ctx) dst_reg(this, ir->type);
+ is_output_set[tmp.index] = ir;
+ }
- for (int i = 0; i < type_size(ir->type); i++) {
- output_reg[ir->location + i] = *reg;
- output_reg[ir->location + i].reg_offset = i;
- output_reg[ir->location + i].type =
- brw_type_for_base_type(ir->type->get_scalar_type());
- output_reg_annotation[ir->location + i] = ir->name;
+ unsigned location = tmp.index;
+ unsigned count = tmp.involved_reg_counts;
+
+ for (unsigned i = 0; i < count; i++) {
+ output_reg[location + i] = *reg;
+ output_reg[location + i].reg_offset = i;
+ output_reg[location + i].type =
+ brw_type_for_base_type(ir->type->get_scalar_type());
+ output_reg_annotation[location + i] = ir->name;
}
break;
-
+ }
case ir_var_auto:
case ir_var_temporary:
reg = new(mem_ctx) dst_reg(this, ir->type);
@@ -1374,9 +1384,71 @@ vec4_visitor::visit(ir_swizzle *ir)
this->result = src;
}
+bool
+vec4_visitor::handle_output_dereference(ir_dereference *ir)
+{
+ ir_variable *inside_var = ir->variable_referenced();
+ if (!inside_var)
+ return false;
+
+ if (inside_var->mode != ir_var_out)
+ return false;
+
+ dst_reg *reg = variable_storage(inside_var);
+
+ location_tree_visitor v;
+ ir->accept(&v);
+ unsigned size;
+ const struct register_info *dst_regs = v.get_result_registers(ir->type, size);
+ // FINISHME : handle struct/array assignment
+
+ src_reg result_reg = src_reg (output_reg[dst_regs[0].index + v.static_offset]);
+
+ //result_reg.reg_offset = v.static_offset;
+
+ for (unsigned i = 0; i < v.indirect_strides_count; i++) {
+ /* Variable index array dereference. It eats the "vec4" of the
+ * base of the array and an index that offsets the Mesa register
+ * index.
+ */
+ v.indirections[i].rvalue->accept(this);
+ int element_size = v.indirections[i].stride;
+
+ src_reg index_reg;
+
+ if (element_size == 1) {
+ index_reg = this->result;
+ } else {
+ index_reg = src_reg(this, glsl_type::int_type);
+
+ emit(MUL(dst_reg(index_reg), this->result, src_reg(element_size)));
+ }
+
+ if (result_reg.reladdr) {
+ src_reg temp = src_reg(this, glsl_type::int_type);
+
+ emit(ADD(dst_reg(temp), *result_reg.reladdr, index_reg));
+
+ index_reg = temp;
+ }
+
+ result_reg.reladdr = ralloc(mem_ctx, src_reg);
+ memcpy(result_reg.reladdr, &index_reg, sizeof(index_reg));
+ }
+
+ this->result = result_reg;
+
+ if (ir->type->is_scalar() || ir->type->is_vector() || ir->type->is_matrix())
+ this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
+
+ return true;
+}
+
void
vec4_visitor::visit(ir_dereference_variable *ir)
{
+ if(handle_output_dereference(ir))
+ return;
const struct glsl_type *type = ir->type;
dst_reg *reg = variable_storage(ir->var);
@@ -1395,6 +1467,8 @@ vec4_visitor::visit(ir_dereference_variable *ir)
void
vec4_visitor::visit(ir_dereference_array *ir)
{
+ if(handle_output_dereference(ir))
+ return;
ir_constant *constant_index;
src_reg src;
int element_size = type_size(ir->type);
@@ -1448,6 +1522,8 @@ vec4_visitor::visit(ir_dereference_array *ir)
void
vec4_visitor::visit(ir_dereference_record *ir)
{
+ if(handle_output_dereference(ir))
+ return;
unsigned int i;
const glsl_type *struct_type = ir->record->type;
int offset = 0;
@@ -1641,6 +1717,13 @@ vec4_visitor::visit(ir_assignment *ir)
ir->lhs->type->is_scalar());
dst.writemask = ir->write_mask;
+ if (ir->lhs->variable_referenced()->complete_location ) {
+ unsigned size;
+ const struct register_info *tmp = get_register_info(ir->lhs->variable_referenced()->complete_location,ir->lhs->variable_referenced()->type,size);
+ dst.writemask = dst.writemask << tmp[0].writemask_offset;
+ ralloc_free((void *)tmp);
+ }
+
for (int i = 0; i < 4; i++) {
if (dst.writemask & (1 << i)) {
first_enabled_chan = BRW_GET_SWZ(src.swizzle, i);
@@ -2131,9 +2214,11 @@ vec4_visitor::emit_generic_urb_slot(dst_reg reg, int vert_result)
assert (vert_result < VERT_RESULT_MAX);
reg.type = output_reg[vert_result].type;
current_annotation = output_reg_annotation[vert_result];
+ src_reg res =src_reg(output_reg[vert_result]);
+ res.swizzle = BRW_SWIZZLE4(SWIZZLE_X,SWIZZLE_Y,SWIZZLE_Z,SWIZZLE_W);
/* Copy the register, saturating if necessary */
vec4_instruction *inst = emit(MOV(reg,
- src_reg(output_reg[vert_result])));
+ res));
if ((vert_result == VERT_RESULT_COL0 ||
vert_result == VERT_RESULT_COL1 ||
vert_result == VERT_RESULT_BFC0 ||
@@ -2246,7 +2331,7 @@ vec4_visitor::emit_urb_writes()
/* Set up the VUE data for the first URB write */
int slot;
- for (slot = 0; slot < c->vue_map.num_slots; ++slot) {
+ for (slot = 0; slot < c->vue_map.num_slots;++slot){//c->vue_map.num_slots; ++slot) {
emit_urb_slot(mrf++, c->vue_map.slot_to_vert_result[slot]);
/* If this was max_usable_mrf, we can't fit anything more into this URB
@@ -2596,6 +2681,7 @@ vec4_visitor::vec4_visitor(struct brw_vs_compile *c,
this->live_intervals_valid = false;
this->uniforms = 0;
+ memset(this->is_output_set, 0, sizeof(this->is_output_set));
}
vec4_visitor::~vec4_visitor()
--
1.7.7
More information about the mesa-dev
mailing list