diff options
author | Paul Berry <[email protected]> | 2013-10-22 05:56:37 -0700 |
---|---|---|
committer | Paul Berry <[email protected]> | 2013-10-23 16:51:15 -0700 |
commit | 4df56177edba492c3aada4386a4f271c7849deb5 (patch) | |
tree | 285bd12ac80947d3da4367801c35328fc364a37e | |
parent | 8e15207c9d206e3698a240092afdf8cddb6f5c02 (diff) |
i965/fs: Only unroll high-accuracy dFdy() from SIMD16 to SIMD8 on gen4 and IVB.
In commit 800610f (i965/fs: Improve accuracy of dFdy() to match
dFdx()) I unrolled the high-accuracy dFdy() computation from a single
SIMD16 instruction to two SIMD8 instructions because of text I found
in the i965 (gen4) PRM saying that instruction compression could not
be used in align16 mode. I couldn't find similar text in later
hardware docs, and I observed problems trying to use instruction
compression on align16 mode on Ivy Bridge, so I assumed that the
restriction still applied and the associated documentation had simply
been lost.
After consultation with the hardware engineers, it turns out this is
not the case. In point of fact, the restriction was dropped in gen5,
re-introduced in Ivy Bridge, and dropped again in Haswell. The reason
I didn't notice this is that in the Ivy Bridge documentation, the
restriction was in a different section, and described using different
language.
Now that we know that the restriction only applies to Gen4 and Ivy
Bridge, we can limit the unrolling to those platforms.
Tested on gen5, gen6, and gen7 (both Ivy Bridge and Haswell).
Reviewed-by: Matt Turner <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index 0e6e8533c73..df72b989066 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -640,6 +640,30 @@ fs_generator::generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src bool negate_value) { if (c->key.high_quality_derivatives) { + /* From the Ivy Bridge PRM, volume 4 part 3, section 3.3.9 (Register + * Region Restrictions): + * + * In Align16 access mode, SIMD16 is not allowed for DW operations + * and SIMD8 is not allowed for DF operations. + * + * In this context, "DW operations" means "operations acting on 32-bit + * values", so it includes operations on floats. + * + * Gen4 has a similar restriction. From the i965 PRM, section 11.5.3 + * (Instruction Compression -> Rules and Restrictions): + * + * A compressed instruction must be in Align1 access mode. Align16 + * mode instructions cannot be compressed. + * + * Similar text exists in the g45 PRM. + * + * On these platforms, if we're building a SIMD16 shader, we need to + * manually unroll to a pair of SIMD8 instructions. + */ + bool unroll_to_simd8 = + (dispatch_width == 16 && + (brw->gen == 4 || (brw->gen == 7 && !brw->is_haswell))); + /* produce accurate derivatives */ struct brw_reg src0 = brw_reg(src.file, src.nr, 0, BRW_REGISTER_TYPE_F, @@ -655,20 +679,13 @@ fs_generator::generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src BRW_SWIZZLE_ZWZW, WRITEMASK_XYZW); brw_push_insn_state(p); brw_set_access_mode(p, BRW_ALIGN_16); - brw_set_compression_control(p, BRW_COMPRESSION_NONE); + if (unroll_to_simd8) + brw_set_compression_control(p, BRW_COMPRESSION_NONE); if (negate_value) brw_ADD(p, dst, src1, negate(src0)); else brw_ADD(p, dst, src0, negate(src1)); - if (dispatch_width == 16) { - /* From page 340 of the i965 PRM: - * - * "A compressed instruction must be in Align1 access - * mode. Align16 mode instructions cannot be compressed." - * - * Therefore, when doing a 16-wide dispatch, we need to manually - * unroll to two instructions. - */ + if (unroll_to_simd8) { brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); src0 = sechalf(src0); src1 = sechalf(src1); |