From a297061524c7b7caaaaebfc589f550bb9d6a353a Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Thu, 29 Oct 2020 15:19:30 +0200 Subject: [PATCH] intel/compiler: add support for fragment shading rate variable v2: Drop old register type initializers (Jason) Simplify instruction snippet (Jason) Signed-off-by: Lionel Landwerlin Reviewed-by: Kenneth Graunke Part-of: --- src/intel/compiler/brw_fs.cpp | 41 +++++++++++++++++++++++++++++++++++++++ src/intel/compiler/brw_fs.h | 1 + src/intel/compiler/brw_fs_nir.cpp | 9 ++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 5e9a4a5..957f5a2 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -1545,6 +1545,47 @@ fs_visitor::emit_samplemaskin_setup() return reg; } +fs_reg * +fs_visitor::emit_shading_rate_setup() +{ + assert(devinfo->ver >= 11); + + const fs_builder abld = bld.annotate("compute fragment shading rate"); + + fs_reg *reg = new(this->mem_ctx) fs_reg(bld.vgrf(BRW_REGISTER_TYPE_UD)); + + struct brw_wm_prog_data *wm_prog_data = + brw_wm_prog_data(bld.shader->stage_prog_data); + + /* Coarse pixel shading size fields overlap with other fields of not in + * coarse pixel dispatch mode, so report 0 when that's not the case. + */ + if (wm_prog_data->per_coarse_pixel_dispatch) { + /* The shading rates provided in the shader are the actual 2D shading + * rate while the SPIR-V built-in is the enum value that has the shading + * rate encoded as a bitfield. Fortunately, the bitfield value is just + * the shading rate divided by two and shifted. + */ + + /* r1.0 - 0:7 ActualCoarsePixelShadingSize.X */ + fs_reg actual_x = fs_reg(retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UB)); + /* r1.0 - 15:8 ActualCoarsePixelShadingSize.Y */ + fs_reg actual_y = byte_offset(actual_x, 1); + + fs_reg int_rate_x = bld.vgrf(BRW_REGISTER_TYPE_UD); + fs_reg int_rate_y = bld.vgrf(BRW_REGISTER_TYPE_UD); + + abld.SHR(int_rate_y, actual_y, brw_imm_ud(1)); + abld.SHR(int_rate_x, actual_x, brw_imm_ud(1)); + abld.SHL(int_rate_x, int_rate_x, brw_imm_ud(2)); + abld.OR(*reg, int_rate_x, int_rate_y); + } else { + abld.MOV(*reg, brw_imm_ud(0)); + } + + return reg; +} + fs_reg fs_visitor::resolve_source_modifiers(const fs_reg &src) { diff --git a/src/intel/compiler/brw_fs.h b/src/intel/compiler/brw_fs.h index 96ef092..3b13e55 100644 --- a/src/intel/compiler/brw_fs.h +++ b/src/intel/compiler/brw_fs.h @@ -208,6 +208,7 @@ public: fs_reg *emit_samplepos_setup(); fs_reg *emit_sampleid_setup(); fs_reg *emit_samplemaskin_setup(); + fs_reg *emit_shading_rate_setup(); void emit_interpolation_setup_gfx4(); void emit_interpolation_setup_gfx6(); void compute_sample_position(fs_reg dst, fs_reg int_sample_pos); diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp index c84609d..f052fa7 100644 --- a/src/intel/compiler/brw_fs_nir.cpp +++ b/src/intel/compiler/brw_fs_nir.cpp @@ -254,6 +254,12 @@ emit_system_values_block(nir_block *block, fs_visitor *v) } break; + case nir_intrinsic_load_frag_shading_rate: + reg = &v->nir_system_values[SYSTEM_VALUE_FRAG_SHADING_RATE]; + if (reg->file == BAD_FILE) + *reg = *v->emit_shading_rate_setup(); + break; + default: break; } @@ -3320,7 +3326,8 @@ fs_visitor::nir_emit_fs_intrinsic(const fs_builder &bld, case nir_intrinsic_load_helper_invocation: case nir_intrinsic_load_sample_mask_in: - case nir_intrinsic_load_sample_id: { + case nir_intrinsic_load_sample_id: + case nir_intrinsic_load_frag_shading_rate: { gl_system_value sv = nir_system_value_from_intrinsic(instr->intrinsic); fs_reg val = nir_system_values[sv]; assert(val.file != BAD_FILE); -- 2.7.4