From 84e19322d3a24f7d90bdea09298f1ad55c5e0f04 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 13 Dec 2016 23:47:05 -0800 Subject: [PATCH] i965/vec4: Fix TCS output reads with non-zero component qualifiers. We want to perform the URB read to a vec4 temporary, with no writemask, then issue a MOV to swizzle the data and store it to the actual destination, using the final writemask. We were doing this wrong. For example, let's say we wanted to read a vec2 stored in components 2-3 of a vec4. We would generate a URB read message of: SEND .XY
MOV .XY .ZW This doesn't work, because the URB message reads the .XY components of the vec4, rather than the ZW. It writes to the right place, but with the wrong data. Then the MOV comes along and overwrites it with data that didn't even come from the URB at all. Instead we want to do: SEND
MOV .XY .ZW Signed-off-by: Kenneth Graunke Reviewed-by: Jason Ekstrand --- src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp b/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp index c7278e4a787..b6ff4fda974 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp @@ -209,19 +209,19 @@ vec4_tcs_visitor::emit_output_urb_read(const dst_reg &dst, /* Set up the message header to reference the proper parts of the URB */ dst_reg header = dst_reg(this, glsl_type::uvec4_type); inst = emit(TCS_OPCODE_SET_OUTPUT_URB_OFFSETS, header, - brw_imm_ud(dst.writemask), indirect_offset); + brw_imm_ud(dst.writemask << first_component), indirect_offset); inst->force_writemask_all = true; - /* Read into a temporary, ignoring writemasking. */ vec4_instruction *read = emit(VEC4_OPCODE_URB_READ, dst, src_reg(header)); read->offset = base_offset; read->mlen = 1; read->base_mrf = -1; if (first_component) { - src_reg src = src_reg(dst); - src.swizzle = BRW_SWZ_COMP_INPUT(first_component); - emit(MOV(dst, src)); + /* Read into a temporary and copy with a swizzle and writemask. */ + read->dst = retype(dst_reg(this, glsl_type::ivec4_type), dst.type); + emit(MOV(dst, swizzle(src_reg(read->dst), + BRW_SWZ_COMP_INPUT(first_component)))); } } -- 2.30.2