v2: less invasive changes --- src/mesa/drivers/dri/i965/brw_fs.cpp | 4 +- src/mesa/drivers/dri/i965/brw_vec4.h | 5 ++- src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 60 +++++++++++++++-------- 3 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index bf59da3..55cbf9e 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -462,7 +462,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 + ir->horizontal_location); interp = suboffset(interp, 3); interp.type = reg->type; emit(FS_OPCODE_CINTERP, attr, fs_reg(interp)); @@ -482,7 +482,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 + ir->horizontal_location); 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 bc8b392..c7b2665 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -387,7 +387,10 @@ public: /* Regs for vertex results. Generated at ir_variable visiting time * for the ir->location's used. */ - dst_reg output_reg[BRW_VERT_RESULT_MAX]; + dst_reg output_reg[4 * BRW_VERT_RESULT_MAX]; + unsigned horizontal_shift[4 * BRW_VERT_RESULT_MAX]; + unsigned components[4 * BRW_VERT_RESULT_MAX]; + unsigned output_per_ref[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 f9a08a0..776b93f 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -857,10 +857,14 @@ vec4_visitor::visit(ir_variable *ir) reg = new(mem_ctx) dst_reg(this, ir->type); 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 = + unsigned location_and_lateral_offset = 4 * ir->location + 4 * i + output_per_ref[ir->location + i]; + output_per_ref[ir->location + i] += 1; + output_reg[location_and_lateral_offset] = *reg; + output_reg[location_and_lateral_offset].reg_offset = i; + output_reg[location_and_lateral_offset].type = brw_type_for_base_type(ir->type->get_scalar_type()); + horizontal_shift[location_and_lateral_offset] = ir->horizontal_location; + components[location_and_lateral_offset] = (ir->type->is_array())?ir->type->fields.array->vector_elements:ir->type->vector_elements; output_reg_annotation[ir->location + i] = ir->name; } break; @@ -2020,11 +2024,11 @@ void vec4_visitor::emit_ndc_computation() { /* Get the position */ - src_reg pos = src_reg(output_reg[VERT_RESULT_HPOS]); + src_reg pos = src_reg(output_reg[4 * VERT_RESULT_HPOS]); /* Build ndc coords, which are (x/w, y/w, z/w, 1/w) */ dst_reg ndc = dst_reg(this, glsl_type::vec4_type); - output_reg[BRW_VERT_RESULT_NDC] = ndc; + output_reg[4 * BRW_VERT_RESULT_NDC] = ndc; current_annotation = "NDC"; dst_reg ndc_w = ndc; @@ -2053,7 +2057,7 @@ vec4_visitor::emit_psiz_and_flags(struct brw_reg reg) emit(MOV(header1, 0u)); if (c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_PSIZ)) { - src_reg psiz = src_reg(output_reg[VERT_RESULT_PSIZ]); + src_reg psiz = src_reg(output_reg[4 * VERT_RESULT_PSIZ]); current_annotation = "Point size"; emit(MUL(header1_w, psiz, src_reg((float)(1 << 11)))); @@ -2064,7 +2068,7 @@ vec4_visitor::emit_psiz_and_flags(struct brw_reg reg) for (i = 0; i < c->key.nr_userclip_plane_consts; i++) { vec4_instruction *inst; - inst = emit(DP4(dst_null_f(), src_reg(output_reg[VERT_RESULT_HPOS]), + inst = emit(DP4(dst_null_f(), src_reg(output_reg[4 * VERT_RESULT_HPOS]), src_reg(this->userplane[i]))); inst->conditional_mod = BRW_CONDITIONAL_L; @@ -2103,7 +2107,7 @@ vec4_visitor::emit_psiz_and_flags(struct brw_reg reg) emit(MOV(retype(reg, BRW_REGISTER_TYPE_D), src_reg(0))); if (c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_PSIZ)) { emit(MOV(brw_writemask(reg, WRITEMASK_W), - src_reg(output_reg[VERT_RESULT_PSIZ]))); + src_reg(output_reg[4 * VERT_RESULT_PSIZ]))); } } } @@ -2140,7 +2144,7 @@ vec4_visitor::emit_clip_distances(struct brw_reg reg, int offset) for (int i = 0; i + offset < c->key.nr_userclip_plane_consts && i < 4; ++i) { emit(DP4(dst_reg(brw_writemask(reg, 1 << i)), - src_reg(output_reg[clip_vertex]), + src_reg(output_reg[4 * clip_vertex]), src_reg(this->userplane[i + offset]))); } } @@ -2149,17 +2153,30 @@ void 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; + reg.type = output_reg[4 * vert_result].type; current_annotation = output_reg_annotation[vert_result]; - /* Copy the register, saturating if necessary */ - vec4_instruction *inst = emit(MOV(reg, - src_reg(output_reg[vert_result]))); - if ((vert_result == VERT_RESULT_COL0 || - vert_result == VERT_RESULT_COL1 || - vert_result == VERT_RESULT_BFC0 || - vert_result == VERT_RESULT_BFC1) && - c->key.clamp_vertex_color) { - inst->saturate = true; + for (unsigned i = 0; i < output_per_ref[vert_result]; i++) { + unsigned components_count = components[4 * vert_result + i], hs = horizontal_shift[4 * vert_result + i]; + reg.writemask = ((1 << components_count) - 1 ) << hs; + src_reg src_gpr = src_reg(output_reg[4 * vert_result + i]); + unsigned swz = src_gpr.swizzle; + src_gpr.swizzle = BRW_SWIZZLE4( + BRW_GET_SWZ(swz,(0 + hs) % 4), + BRW_GET_SWZ(swz,(1 + hs) % 4), + BRW_GET_SWZ(swz,(2 + hs) % 4), + BRW_GET_SWZ(swz,(3 + hs) % 4) + ); + + + /* Copy the register, saturating if necessary */ + vec4_instruction *inst = emit(MOV(reg, src_gpr)); + if ((vert_result == VERT_RESULT_COL0 || + vert_result == VERT_RESULT_COL1 || + vert_result == VERT_RESULT_BFC0 || + vert_result == VERT_RESULT_BFC1) && + c->key.clamp_vertex_color) { + inst->saturate = true; + } } } @@ -2178,12 +2195,12 @@ vec4_visitor::emit_urb_slot(int mrf, int vert_result) break; case BRW_VERT_RESULT_NDC: current_annotation = "NDC"; - emit(MOV(reg, src_reg(output_reg[BRW_VERT_RESULT_NDC]))); + emit(MOV(reg, src_reg(output_reg[4 *BRW_VERT_RESULT_NDC]))); break; case BRW_VERT_RESULT_HPOS_DUPLICATE: case VERT_RESULT_HPOS: current_annotation = "gl_Position"; - emit(MOV(reg, src_reg(output_reg[VERT_RESULT_HPOS]))); + emit(MOV(reg, src_reg(output_reg[4 * VERT_RESULT_HPOS]))); break; case VERT_RESULT_CLIP_DIST0: case VERT_RESULT_CLIP_DIST1: @@ -2615,6 +2632,7 @@ vec4_visitor::vec4_visitor(struct brw_vs_compile *c, this->max_grf = intel->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF; this->uniforms = 0; + memset(output_per_ref, 0, sizeof(output_per_ref)); } vec4_visitor::~vec4_visitor() -- 1.7.7 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev