Gathering all the checks into a single place makes it easier to add new workarounds.
Signed-off-by: Kenneth Graunke <kenn...@whitecape.org> Cc: Neil Roberts <n...@linux.intel.com> Cc: Matt Turner <matts...@gmail.com> --- src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 28 +++++---------- src/mesa/drivers/dri/i965/brw_shader.cpp | 48 ++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_shader.h | 1 + 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index cbe6191..8a5ad9b 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -1613,6 +1613,9 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) unreachable(!"Invalid instruction width"); } + bool must_break_down_simd16_to_simd8 = dispatch_width == 16 && + !brw_instruction_supports_simd16(brw, inst->opcode); + switch (inst->opcode) { case BRW_OPCODE_MOV: brw_MOV(p, dst, src[0]); @@ -1637,7 +1640,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) case BRW_OPCODE_MAD: assert(brw->gen >= 6); brw_set_default_access_mode(p, BRW_ALIGN_16); - if (dispatch_width == 16 && brw->gen < 8 && !brw->is_haswell) { + if (must_break_down_simd16_to_simd8) { brw_set_default_compression_control(p, BRW_COMPRESSION_NONE); brw_inst *f = brw_MAD(p, firsthalf(dst), firsthalf(src[0]), firsthalf(src[1]), firsthalf(src[2])); brw_set_default_compression_control(p, BRW_COMPRESSION_2NDHALF); @@ -1658,7 +1661,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) case BRW_OPCODE_LRP: assert(brw->gen >= 6); brw_set_default_access_mode(p, BRW_ALIGN_16); - if (dispatch_width == 16 && brw->gen < 8 && !brw->is_haswell) { + if (must_break_down_simd16_to_simd8) { brw_set_default_compression_control(p, BRW_COMPRESSION_NONE); brw_inst *f = brw_LRP(p, firsthalf(dst), firsthalf(src[0]), firsthalf(src[1]), firsthalf(src[2])); brw_set_default_compression_control(p, BRW_COMPRESSION_2NDHALF); @@ -1730,7 +1733,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) * coissuing would affect CMP instructions not otherwise affected by * the errata. */ - if (dispatch_width == 16 && brw->gen == 7 && !brw->is_haswell) { + if (must_break_down_simd16_to_simd8) { if (dst.file == BRW_GENERAL_REGISTER_FILE) { brw_set_default_compression_control(p, BRW_COMPRESSION_NONE); brw_CMP(p, firsthalf(dst), inst->conditional_mod, @@ -1795,7 +1798,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) case BRW_OPCODE_BFE: assert(brw->gen >= 7); brw_set_default_access_mode(p, BRW_ALIGN_16); - if (dispatch_width == 16 && brw->gen < 8 && !brw->is_haswell) { + if (must_break_down_simd16_to_simd8) { brw_set_default_compression_control(p, BRW_COMPRESSION_NONE); brw_BFE(p, firsthalf(dst), firsthalf(src[0]), firsthalf(src[1]), firsthalf(src[2])); brw_set_default_compression_control(p, BRW_COMPRESSION_2NDHALF); @@ -1809,12 +1812,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) case BRW_OPCODE_BFI1: assert(brw->gen >= 7); - /* The Haswell WaForceSIMD8ForBFIInstruction workaround says that we - * should - * - * "Force BFI instructions to be executed always in SIMD8." - */ - if (dispatch_width == 16 && brw->is_haswell) { + if (must_break_down_simd16_to_simd8) { brw_set_default_compression_control(p, BRW_COMPRESSION_NONE); brw_BFI1(p, firsthalf(dst), firsthalf(src[0]), firsthalf(src[1])); brw_set_default_compression_control(p, BRW_COMPRESSION_2NDHALF); @@ -1827,15 +1825,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) case BRW_OPCODE_BFI2: assert(brw->gen >= 7); brw_set_default_access_mode(p, BRW_ALIGN_16); - /* The Haswell WaForceSIMD8ForBFIInstruction workaround says that we - * should - * - * "Force BFI instructions to be executed always in SIMD8." - * - * Otherwise we would be able to emit compressed instructions like we - * do for the other three-source instructions. - */ - if (dispatch_width == 16 && brw->gen < 8) { + if (must_break_down_simd16_to_simd8) { brw_set_default_compression_control(p, BRW_COMPRESSION_NONE); brw_BFI2(p, firsthalf(dst), firsthalf(src[0]), firsthalf(src[1]), firsthalf(src[2])); brw_set_default_compression_control(p, BRW_COMPRESSION_2NDHALF); diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index ec3cfcb..fed4ba3 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -392,6 +392,54 @@ brw_texture_offset(struct gl_context *ctx, int *offsets, return offset_bits; } +/** + * Some instructions aren't always natively supported in SIMD16 mode + * and need to be broken down into a pair of SIMD8 instructions. + */ +bool +brw_instruction_supports_simd16(const struct brw_context *brw, enum opcode op) +{ + bool supports_3src = brw->is_haswell || brw->gen >= 8; + + switch (op) { + case BRW_OPCODE_MAD: + case BRW_OPCODE_LRP: + return supports_3src; + case BRW_OPCODE_BFI2: + /* The Haswell WaForceSIMD8ForBFIInstruction workaround says that we + * should + * + * "Force BFI instructions to be executed always in SIMD8." + * + * Otherwise we would be able to emit compressed instructions like we + * do for the other three-source instructions. + */ + return supports_3src && !brw->is_haswell; + case BRW_OPCODE_BFI1: + /* The Haswell WaForceSIMD8ForBFIInstruction workarounds says that we + * should + * + * "Force BFI instructions to be executed always in SIMD8." + */ + return !brw->is_haswell; + case BRW_OPCODE_CMP: + /* The Ivybridge/BayTrail WaCMPInstFlagDepClearedEarly workaround says + * that when the destination is a GRF that the dependency-clear bit on + * the flag register is cleared early. + * + * Suggested workarounds are to disable coissuing CMP instructions + * or to split CMP(16) instructions into two CMP(8) instructions. + * + * We choose to split into CMP(8) instructions since disabling + * coissuing would affect CMP instructions not otherwise affected by + * the errata. + */ + return brw->gen != 7 || brw->is_haswell; + default: + return true; + } +} + const char * brw_instruction_name(enum opcode op) { diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h index 5c95355..a9c9565 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.h +++ b/src/mesa/drivers/dri/i965/brw_shader.h @@ -212,6 +212,7 @@ uint32_t brw_texture_offset(struct gl_context *ctx, int *offsets, enum brw_reg_type brw_type_for_base_type(const struct glsl_type *type); enum brw_conditional_mod brw_conditional_for_comparison(unsigned int op); uint32_t brw_math_function(enum opcode op); +bool brw_instruction_supports_simd16(const struct brw_context *brw, enum opcode); const char *brw_instruction_name(enum opcode op); bool brw_saturate_immediate(enum brw_reg_type type, struct brw_reg *reg); bool brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg); -- 2.2.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev