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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev