[Mesa-dev] [PATCH 1/2] i965: Refactor SIMD16-to-2xSIMD8 checks.
Kenneth Graunke
kenneth at whitecape.org
Wed Mar 4 12:53:44 PST 2015
Gathering all the checks into a single place makes it easier to add new
workarounds.
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
Cc: Neil Roberts <neil at linux.intel.com>
Cc: Matt Turner <mattst88 at 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
More information about the mesa-dev
mailing list