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,
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);
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:
* 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;
*/
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):
*
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:
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: