diff options
-rw-r--r-- | src/intel/compiler/brw_fs.cpp | 64 | ||||
-rw-r--r-- | src/intel/compiler/brw_fs.h | 1 |
2 files changed, 64 insertions, 1 deletions
diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 00499e92759..9100b8d0a5e 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -7406,6 +7406,65 @@ fs_visitor::lower_barycentrics() return progress; } +/** + * Lower a derivative instruction as the floating-point difference of two + * swizzles of the source, specified as \p swz0 and \p swz1. + */ +static bool +lower_derivative(fs_visitor *v, bblock_t *block, fs_inst *inst, + unsigned swz0, unsigned swz1) +{ + const fs_builder ibld(v, block, inst); + const fs_reg tmp0 = ibld.vgrf(inst->src[0].type); + const fs_reg tmp1 = ibld.vgrf(inst->src[0].type); + + ibld.emit(SHADER_OPCODE_QUAD_SWIZZLE, tmp0, inst->src[0], brw_imm_ud(swz0)); + ibld.emit(SHADER_OPCODE_QUAD_SWIZZLE, tmp1, inst->src[0], brw_imm_ud(swz1)); + + inst->resize_sources(2); + inst->src[0] = negate(tmp0); + inst->src[1] = tmp1; + inst->opcode = BRW_OPCODE_ADD; + + return true; +} + +/** + * Lower derivative instructions on platforms where codegen cannot implement + * them efficiently (i.e. XeHP). + */ +bool +fs_visitor::lower_derivatives() +{ + bool progress = false; + + if (devinfo->verx10 < 125) + return false; + + foreach_block_and_inst(block, fs_inst, inst, cfg) { + if (inst->opcode == FS_OPCODE_DDX_COARSE) + progress |= lower_derivative(this, block, inst, + BRW_SWIZZLE_XXXX, BRW_SWIZZLE_YYYY); + + else if (inst->opcode == FS_OPCODE_DDX_FINE) + progress |= lower_derivative(this, block, inst, + BRW_SWIZZLE_XXZZ, BRW_SWIZZLE_YYWW); + + else if (inst->opcode == FS_OPCODE_DDY_COARSE) + progress |= lower_derivative(this, block, inst, + BRW_SWIZZLE_XXXX, BRW_SWIZZLE_ZZZZ); + + else if (inst->opcode == FS_OPCODE_DDY_FINE) + progress |= lower_derivative(this, block, inst, + BRW_SWIZZLE_XYXY, BRW_SWIZZLE_ZWZW); + } + + if (progress) + invalidate_analysis(DEPENDENCY_INSTRUCTIONS | DEPENDENCY_VARIABLES); + + return progress; +} + void fs_visitor::dump_instructions() const { @@ -7978,7 +8037,10 @@ fs_visitor::optimize() OPT(dead_code_eliminate); } - if (OPT(lower_regioning)) { + progress = false; + OPT(lower_derivatives); + OPT(lower_regioning); + if (progress) { OPT(opt_copy_propagation); OPT(dead_code_eliminate); OPT(lower_simd_width); diff --git a/src/intel/compiler/brw_fs.h b/src/intel/compiler/brw_fs.h index 1f286a0e593..413b225cfce 100644 --- a/src/intel/compiler/brw_fs.h +++ b/src/intel/compiler/brw_fs.h @@ -196,6 +196,7 @@ public: bool lower_minmax(); bool lower_simd_width(); bool lower_barycentrics(); + bool lower_derivatives(); bool lower_scoreboard(); bool lower_sub_sat(); bool opt_combine_constants(); |