[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