[Mesa-dev] [PATCH 3/5] i965/fs: Support fine/coarse derivative opcodes

Chris Forbes chrisf at ijw.co.nz
Thu Aug 14 02:19:13 PDT 2014


The quality level (fine/coarse/dont-care) is plumbed through to the
generator as a constant in src1.

Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
---
 src/mesa/drivers/dri/i965/brw_defines.h            |  6 ++++++
 src/mesa/drivers/dri/i965/brw_fs.h                 |  4 ++--
 .../dri/i965/brw_fs_channel_expressions.cpp        |  4 ++++
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp     | 24 ++++++++++++++++------
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp       | 16 +++++++++++++--
 5 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 3564041..1322ed2 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -1004,6 +1004,12 @@ enum opcode {
    GS_OPCODE_GET_INSTANCE_ID,
 };
 
+enum brw_derivative_quality {
+   BRW_DERIVATIVE_BY_HINT = 0,
+   BRW_DERIVATIVE_FINE = 1,
+   BRW_DERIVATIVE_COARSE = 2,
+};
+
 enum brw_urb_write_flags {
    BRW_URB_WRITE_NO_FLAGS = 0,
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 5cad504..a838e74 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -604,9 +604,9 @@ private:
    void generate_math_g45(fs_inst *inst,
 			  struct brw_reg dst,
 			  struct brw_reg src);
-   void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
+   void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src, struct brw_reg quality);
    void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src,
-                     bool negate_value);
+                     struct brw_reg quality, bool negate_value);
    void generate_scratch_write(fs_inst *inst, struct brw_reg src);
    void generate_scratch_read(fs_inst *inst, struct brw_reg dst);
    void generate_scratch_read_gen7(fs_inst *inst, struct brw_reg dst);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
index 4113f47..d98b7eb 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
@@ -237,7 +237,11 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_unop_sin_reduced:
    case ir_unop_cos_reduced:
    case ir_unop_dFdx:
+   case ir_unop_dFdx_coarse:
+   case ir_unop_dFdx_fine:
    case ir_unop_dFdy:
+   case ir_unop_dFdy_coarse:
+   case ir_unop_dFdy_fine:
    case ir_unop_bitfield_reverse:
    case ir_unop_bit_count:
    case ir_unop_find_msb:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index 1190f1f..6efd41c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -644,11 +644,17 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src
  * appropriate swizzling.
  */
 void
-fs_generator::generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
+fs_generator::generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src,
+                           struct brw_reg quality)
 {
    unsigned vstride, width;
+   assert(quality.file == BRW_IMMEDIATE_VALUE);
+   assert(quality.type == BRW_REGISTER_TYPE_D);
 
-   if (key->high_quality_derivatives) {
+   int quality_value = quality.dw1.d;
+
+   if (quality_value == BRW_DERIVATIVE_FINE ||
+      (key->high_quality_derivatives && quality_value != BRW_DERIVATIVE_COARSE)) {
       /* produce accurate derivatives */
       vstride = BRW_VERTICAL_STRIDE_2;
       width = BRW_WIDTH_2;
@@ -680,9 +686,15 @@ fs_generator::generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src
  */
 void
 fs_generator::generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src,
-                         bool negate_value)
+                         struct brw_reg quality, bool negate_value)
 {
-   if (key->high_quality_derivatives) {
+   assert(quality.file == BRW_IMMEDIATE_VALUE);
+   assert(quality.type == BRW_REGISTER_TYPE_D);
+
+   int quality_value = quality.dw1.d;
+
+   if (quality_value == BRW_DERIVATIVE_FINE ||
+      (key->high_quality_derivatives && quality_value != BRW_DERIVATIVE_COARSE)) {
       /* From the Ivy Bridge PRM, volume 4 part 3, section 3.3.9 (Register
        * Region Restrictions):
        *
@@ -1655,14 +1667,14 @@ fs_generator::generate_code(exec_list *instructions)
 	 generate_tex(inst, dst, src[0], src[1]);
 	 break;
       case FS_OPCODE_DDX:
-	 generate_ddx(inst, dst, src[0]);
+	 generate_ddx(inst, dst, src[0], src[1]);
 	 break;
       case FS_OPCODE_DDY:
          /* Make sure fp->UsesDFdy flag got set (otherwise there's no
           * guarantee that key->render_to_fbo is set).
           */
          assert(fp->UsesDFdy);
-	 generate_ddy(inst, dst, src[0], key->render_to_fbo);
+	 generate_ddy(inst, dst, src[0], src[1], key->render_to_fbo);
 	 break;
 
       case SHADER_OPCODE_GEN4_SCRATCH_WRITE:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index c16401b..f719345 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -593,10 +593,22 @@ fs_visitor::visit(ir_expression *ir)
       break;
 
    case ir_unop_dFdx:
-      emit(FS_OPCODE_DDX, this->result, op[0]);
+      emit(FS_OPCODE_DDX, this->result, op[0], fs_reg(BRW_DERIVATIVE_BY_HINT));
+      break;
+   case ir_unop_dFdx_coarse:
+      emit(FS_OPCODE_DDX, this->result, op[0], fs_reg(BRW_DERIVATIVE_COARSE));
+      break;
+   case ir_unop_dFdx_fine:
+      emit(FS_OPCODE_DDX, this->result, op[0], fs_reg(BRW_DERIVATIVE_FINE));
       break;
    case ir_unop_dFdy:
-      emit(FS_OPCODE_DDY, this->result, op[0]);
+      emit(FS_OPCODE_DDY, this->result, op[0], fs_reg(BRW_DERIVATIVE_BY_HINT));
+      break;
+   case ir_unop_dFdy_coarse:
+      emit(FS_OPCODE_DDY, this->result, op[0], fs_reg(BRW_DERIVATIVE_COARSE));
+      break;
+   case ir_unop_dFdy_fine:
+      emit(FS_OPCODE_DDY, this->result, op[0], fs_reg(BRW_DERIVATIVE_FINE));
       break;
 
    case ir_binop_add:
-- 
2.0.4



More information about the mesa-dev mailing list