From 5b2d8c2273c6f48e764a1386240ec674cb4aa4ad Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 14 Mar 2016 14:22:39 -0700 Subject: [PATCH] i965: Fix gl_TessLevelOuter[] for isolines. Thanks to James Legg for finding this! From the ARB_tessellation_shader spec: "The number of isolines generated is derived from the first outer tessellation level; the number of segments in each isoline is derived from the second outer tessellation level." According to the PRM, "TF.LineDensity determines # lines" while "TF.LineDetail determines # segments". Line Density is stored at DWord 6, while Line Detail is at DWord 7. So, they're not reversed like they are for triangles and quads. Fixes Piglit's spec/arb_tessellation_shader/execution/isoline, and about 24 dEQP isoline tests (with GL_EXT_tessellation_shader hacked on - it's not normally enabled). Cc: mesa-stable@lists.freedesktop.org Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94524 Signed-off-by: Kenneth Graunke Reviewed-by: Jordan Justen --- src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp | 16 +++++++++++++--- src/mesa/drivers/dri/i965/brw_vec4_tes.cpp | 12 +++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp b/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp index cb345157f81..2046b94bca1 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp @@ -402,6 +402,7 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) } } else if (imm_offset == 1 && indirect_offset.file == BAD_FILE) { dst.type = BRW_REGISTER_TYPE_F; + unsigned swiz = BRW_SWIZZLE_WZYX; /* This is a read of gl_TessLevelOuter[], which lives in the * high 4 DWords of the Patch URB header, in reverse order. @@ -414,6 +415,8 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) dst.writemask = WRITEMASK_XYZ; break; case GL_ISOLINES: + /* Isolines are not reversed; swizzle .zw -> .xy */ + swiz = BRW_SWIZZLE_ZWZW; dst.writemask = WRITEMASK_XY; return; default: @@ -422,7 +425,7 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) dst_reg tmp(this, glsl_type::vec4_type); emit_output_urb_read(tmp, 1, src_reg()); - emit(MOV(dst, swizzle(src_reg(tmp), BRW_SWIZZLE_WZYX))); + emit(MOV(dst, swizzle(src_reg(tmp), swiz))); } else { emit_output_urb_read(dst, imm_offset, indirect_offset); } @@ -475,8 +478,15 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) * Patch URB Header at DWords 4-7. However, it's reversed, so * instead of .xyzw we have .wzyx. */ - swiz = BRW_SWIZZLE_WZYX; - mask = writemask_for_backwards_vector(mask); + if (key->tes_primitive_mode == GL_ISOLINES) { + /* Isolines .xy should be stored in .zw, in order. */ + swiz = BRW_SWIZZLE4(0, 0, 0, 1); + mask <<= 2; + } else { + /* Other domains are reversed; store .wzyx instead of .xyzw. */ + swiz = BRW_SWIZZLE_WZYX; + mask = writemask_for_backwards_vector(mask); + } } emit_urb_write(swizzle(value, swiz), mask, diff --git a/src/mesa/drivers/dri/i965/brw_vec4_tes.cpp b/src/mesa/drivers/dri/i965/brw_vec4_tes.cpp index e3c23f1a52f..7ba494fbffc 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_tes.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_tes.cpp @@ -149,9 +149,15 @@ vec4_tes_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) src_reg(brw_vec8_grf(1, 0)))); break; case nir_intrinsic_load_tess_level_outer: - emit(MOV(get_nir_dest(instr->dest, BRW_REGISTER_TYPE_F), - swizzle(src_reg(ATTR, 1, glsl_type::vec4_type), - BRW_SWIZZLE_WZYX))); + if (tes_prog_data->domain == BRW_TESS_DOMAIN_ISOLINE) { + emit(MOV(get_nir_dest(instr->dest, BRW_REGISTER_TYPE_F), + swizzle(src_reg(ATTR, 1, glsl_type::vec4_type), + BRW_SWIZZLE_ZWZW))); + } else { + emit(MOV(get_nir_dest(instr->dest, BRW_REGISTER_TYPE_F), + swizzle(src_reg(ATTR, 1, glsl_type::vec4_type), + BRW_SWIZZLE_WZYX))); + } break; case nir_intrinsic_load_tess_level_inner: if (tes_prog_data->domain == BRW_TESS_DOMAIN_QUAD) { -- 2.30.2