summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-03-14 14:22:39 -0700
committerKenneth Graunke <[email protected]>2016-03-18 16:45:23 -0700
commit5b2d8c2273c6f48e764a1386240ec674cb4aa4ad (patch)
tree2ace95c5feedf99b548038334d82f89a5a4cb775
parent24298b7e2ffe0d69ef996ab2c279b380bcb4a269 (diff)
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: [email protected] Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94524 Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp16
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_tes.cpp12
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) {