[Mesa-dev] [PATCH v3 35/44] i965/fs/generator: add support to set floating points modes in control register

Samuel Iglesias Gonsálvez siglesias at igalia.com
Wed Feb 6 10:45:04 UTC 2019


v2:
- Fix bug in defining BRW_CR0_FP_MODE_MASK.

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
---
 src/intel/compiler/brw_eu.h             |  4 ++++
 src/intel/compiler/brw_eu_defines.h     | 10 ++++++++++
 src/intel/compiler/brw_eu_emit.c        | 26 +++++++++++++++++++++++++
 src/intel/compiler/brw_fs_generator.cpp |  8 +++++++-
 src/intel/compiler/brw_shader.cpp       |  3 +++
 5 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/src/intel/compiler/brw_eu.h b/src/intel/compiler/brw_eu.h
index 9f1ca769bd3..2309d3b10d8 100644
--- a/src/intel/compiler/brw_eu.h
+++ b/src/intel/compiler/brw_eu.h
@@ -677,6 +677,10 @@ void
 brw_rounding_mode(struct brw_codegen *p,
                   enum brw_rnd_mode mode);
 
+void
+brw_float_controls_mode(struct brw_codegen *p,
+                        unsigned mode, unsigned mask);
+
 /***********************************************************************
  * brw_eu_util.c:
  */
diff --git a/src/intel/compiler/brw_eu_defines.h b/src/intel/compiler/brw_eu_defines.h
index b7bd104be59..e256ca6d5c6 100644
--- a/src/intel/compiler/brw_eu_defines.h
+++ b/src/intel/compiler/brw_eu_defines.h
@@ -412,6 +412,7 @@ enum opcode {
    SHADER_OPCODE_TYPED_SURFACE_WRITE_LOGICAL,
 
    SHADER_OPCODE_RND_MODE,
+   SHADER_OPCODE_FLOAT_CONTROL_MODE,
 
    /**
     * Byte scattered write/read opcodes.
@@ -1312,6 +1313,15 @@ enum PACKED brw_rnd_mode {
    BRW_RND_MODE_UNSPECIFIED,  /* Unspecified rounding mode */
 };
 
+#define BRW_CR0_FP64_DENORM_PRESERVE (1 << 6)
+#define BRW_CR0_FP32_DENORM_PRESERVE (1 << 7)
+#define BRW_CR0_FP16_DENORM_PRESERVE (1 << 10)
+
+#define BRW_CR0_FP_MODE_MASK (BRW_CR0_FP64_DENORM_PRESERVE | \
+                              BRW_CR0_FP32_DENORM_PRESERVE | \
+                              BRW_CR0_FP16_DENORM_PRESERVE | \
+                              BRW_CR0_RND_MODE_MASK)
+
 /* MDC_DS - Data Size Message Descriptor Control Field
  * Skylake PRM, Volume 2d, page 129
  *
diff --git a/src/intel/compiler/brw_eu_emit.c b/src/intel/compiler/brw_eu_emit.c
index 54aa09ea652..9de829e85f0 100644
--- a/src/intel/compiler/brw_eu_emit.c
+++ b/src/intel/compiler/brw_eu_emit.c
@@ -3699,3 +3699,29 @@ brw_rounding_mode(struct brw_codegen *p,
       brw_inst_set_thread_control(p->devinfo, inst, BRW_THREAD_SWITCH);
    }
 }
+
+/* TODO: Refactor brw_rounding_mode() to use this. */
+void
+brw_float_controls_mode(struct brw_codegen *p,
+                        unsigned mode, unsigned mask)
+{
+   brw_inst *inst = brw_AND(p, brw_cr0_reg(0), brw_cr0_reg(0),
+                            brw_imm_ud(~mask));
+   brw_inst_set_exec_size(p->devinfo, inst, BRW_EXECUTE_1);
+
+   /* From the Skylake PRM, Volume 7, page 760:
+    *  "Implementation Restriction on Register Access: When the control
+    *   register is used as an explicit source and/or destination, hardware
+    *   does not ensure execution pipeline coherency. Software must set the
+    *   thread control field to ‘switch’ for an instruction that uses
+    *   control register as an explicit operand."
+    */
+   brw_inst_set_thread_control(p->devinfo, inst, BRW_THREAD_SWITCH);
+
+   if (mode) {
+      brw_inst *inst_or = brw_OR(p, brw_cr0_reg(0), brw_cr0_reg(0),
+                                 brw_imm_ud(mode));
+      brw_inst_set_exec_size(p->devinfo, inst_or, BRW_EXECUTE_1);
+      brw_inst_set_thread_control(p->devinfo, inst_or, BRW_THREAD_SWITCH);
+   }
+}
diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp
index 37f8730f326..fd6201f2220 100644
--- a/src/intel/compiler/brw_fs_generator.cpp
+++ b/src/intel/compiler/brw_fs_generator.cpp
@@ -2437,7 +2437,13 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
 
       case SHADER_OPCODE_RND_MODE:
          assert(src[0].file == BRW_IMMEDIATE_VALUE);
-         brw_rounding_mode(p, (brw_rnd_mode) src[0].d);
+         brw_rounding_mode(p, (enum brw_rnd_mode) src[0].d);
+         break;
+
+      case SHADER_OPCODE_FLOAT_CONTROL_MODE:
+         assert(src[0].file == BRW_IMMEDIATE_VALUE);
+         assert(src[1].file == BRW_IMMEDIATE_VALUE);
+         brw_float_controls_mode(p, src[0].d, src[1].d);
          break;
 
       default:
diff --git a/src/intel/compiler/brw_shader.cpp b/src/intel/compiler/brw_shader.cpp
index 3c636c9d3a4..61abccfbcbe 100644
--- a/src/intel/compiler/brw_shader.cpp
+++ b/src/intel/compiler/brw_shader.cpp
@@ -505,6 +505,8 @@ brw_instruction_name(const struct gen_device_info *devinfo, enum opcode op)
 
    case SHADER_OPCODE_RND_MODE:
       return "rnd_mode";
+   case SHADER_OPCODE_FLOAT_CONTROL_MODE:
+      return "float_control_mode";
    }
 
    unreachable("not reached");
@@ -1049,6 +1051,7 @@ backend_instruction::has_side_effects() const
    case TCS_OPCODE_URB_WRITE:
    case TCS_OPCODE_RELEASE_INPUT:
    case SHADER_OPCODE_RND_MODE:
+   case SHADER_OPCODE_FLOAT_CONTROL_MODE:
       return true;
    default:
       return eot;
-- 
2.19.1



More information about the mesa-dev mailing list