diff --git a/src/imagination/common/device_info/axe-1-16m.h b/src/imagination/common/device_info/axe-1-16m.h index ddc09e5fd76..e9a607a7adf 100644 --- a/src/imagination/common/device_info/axe-1-16m.h +++ b/src/imagination/common/device_info/axe-1-16m.h @@ -108,6 +108,7 @@ static const struct pvr_device_enhancements pvr_device_enhancements_33_15_11_3 = static const struct pvr_device_quirks pvr_device_quirks_33_15_11_3 = { .has_brn70165 = true, + .has_brn74056 = true, }; static const struct pvr_device_info pvr_device_info_33_15_11_3 = { diff --git a/src/imagination/common/device_info/bxs-4-64.h b/src/imagination/common/device_info/bxs-4-64.h index fd8046e6016..a0833fa1410 100644 --- a/src/imagination/common/device_info/bxs-4-64.h +++ b/src/imagination/common/device_info/bxs-4-64.h @@ -125,6 +125,7 @@ static const struct pvr_device_quirks pvr_device_quirks_36_53_104_796 = { .has_brn70165 = true, .has_brn72168 = true, .has_brn72463 = true, + .has_brn74056 = true, }; static const struct pvr_device_info pvr_device_info_36_53_104_796 = { diff --git a/src/imagination/common/device_info/gx6250.h b/src/imagination/common/device_info/gx6250.h index c1de8b88819..60afd217fb6 100644 --- a/src/imagination/common/device_info/gx6250.h +++ b/src/imagination/common/device_info/gx6250.h @@ -124,6 +124,7 @@ static const struct pvr_device_quirks pvr_device_quirks_4_40_2_51 = { .has_brn62269 = true, .has_brn66011 = true, .has_brn70165 = true, + .has_brn74056 = true, }; static const struct pvr_device_info pvr_device_info_4_40_2_51 = { diff --git a/src/imagination/common/pvr_device_info.h b/src/imagination/common/pvr_device_info.h index 683e6cacaf8..d34082f188b 100644 --- a/src/imagination/common/pvr_device_info.h +++ b/src/imagination/common/pvr_device_info.h @@ -368,6 +368,7 @@ struct pvr_device_quirks { bool has_brn70165 : 1; bool has_brn72168 : 1; bool has_brn72463 : 1; + bool has_brn74056 : 1; }; struct pvr_device_info { diff --git a/src/imagination/pco/pco_internal.h b/src/imagination/pco/pco_internal.h index 2279cfb1408..713946f262e 100644 --- a/src/imagination/pco/pco_internal.h +++ b/src/imagination/pco/pco_internal.h @@ -1766,7 +1766,7 @@ bool pco_nir_lower_fs_intrinsics(nir_shader *shader); bool pco_nir_lower_images(nir_shader *shader, pco_data *data); bool pco_nir_lower_interpolation(nir_shader *shader, pco_fs_data *fs); bool pco_nir_lower_io(nir_shader *shader); -bool pco_nir_lower_tex(nir_shader *shader, pco_data *data); +bool pco_nir_lower_tex(nir_shader *shader, pco_data *data, pco_ctx *ctx); bool pco_nir_lower_variables(nir_shader *shader, bool inputs, bool outputs); bool pco_nir_lower_vk(nir_shader *shader, pco_data *data); bool pco_nir_pfo(nir_shader *shader, pco_fs_data *fs); diff --git a/src/imagination/pco/pco_nir.c b/src/imagination/pco/pco_nir.c index 640fafad867..5e113b7cde5 100644 --- a/src/imagination/pco/pco_nir.c +++ b/src/imagination/pco/pco_nir.c @@ -863,7 +863,7 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data) &(nir_lower_tex_options){ .lower_txd_cube_map = true, }); - NIR_PASS(_, nir, pco_nir_lower_tex, data); + NIR_PASS(_, nir, pco_nir_lower_tex, data, ctx); if (nir->info.stage == MESA_SHADER_FRAGMENT) { if (data->fs.uses.alpha_to_coverage) { diff --git a/src/imagination/pco/pco_nir_tex.c b/src/imagination/pco/pco_nir_tex.c index cfa8b55ec44..a07d4083b8c 100644 --- a/src/imagination/pco/pco_nir_tex.c +++ b/src/imagination/pco/pco_nir_tex.c @@ -25,6 +25,11 @@ #include #include +struct state { + pco_data *data; + pco_ctx *ctx; +}; + static inline nir_def *get_src_def(nir_tex_instr *tex, nir_tex_src_type src_type) { @@ -108,8 +113,12 @@ static inline enum pco_dim to_pco_dim(enum glsl_sampler_dim dim) UNREACHABLE(""); } -static nir_def * -lower_tex_query_lod(nir_builder *b, nir_def *coords, nir_def *smp_coeffs) +static nir_def *lower_tex_query_lod(nir_builder *b, + nir_def *coords, + nir_def *smp_coeffs, + pco_smp_params *params, + pco_data *data, + pco_ctx *ctx) { nir_def *lod_dval_post_clamp = nir_channel(b, smp_coeffs, ROGUE_SMP_COEFF_LOD_DVAL_POST_CLAMP); @@ -131,6 +140,17 @@ lower_tex_query_lod(nir_builder *b, nir_def *coords, nir_def *smp_coeffs) tfrac_post_clamp = nir_fdiv_imm(b, tfrac_post_clamp, 256.0f); tfrac_pre_clamp = nir_fdiv_imm(b, tfrac_pre_clamp, 256.0f); + if (PVR_HAS_QUIRK(ctx->dev_info, 74056)) { + lod_dval_post_clamp = + usclib_tex_lod_dval_post_clamp_resource_to_view_space( + b, + params->tex_state, + params->smp_state, + lod_dval_post_clamp); + + data->common.uses.usclib = true; + } + /* Calculate coord deltas. */ nir_def *coord_deltas = nir_imm_int(b, 0); for (unsigned c = 0; c < coords->num_components; ++c) { @@ -422,7 +442,9 @@ static nir_def *lower_tex_shadow(nir_builder *b, static nir_def *lower_tex(nir_builder *b, nir_instr *instr, void *cb_data) { nir_tex_instr *tex = nir_instr_as_tex(instr); - pco_data *data = cb_data; + struct state *state = cb_data; + pco_data *data = state->data; + pco_ctx *ctx = state->ctx; unsigned tex_desc_set; unsigned tex_binding; @@ -677,7 +699,8 @@ static nir_def *lower_tex(nir_builder *b, nir_instr *instr, void *cb_data) case nir_texop_lod: params.sample_coeffs = true; smp = pco_emit_nir_smp(b, ¶ms); - result = lower_tex_query_lod(b, float_coords, &smp->def); + result = + lower_tex_query_lod(b, float_coords, &smp->def, ¶ms, data, ctx); break; case nir_texop_txf: @@ -736,11 +759,17 @@ static bool is_tex(const nir_instr *instr, UNUSED const void *cb_data) * * \param[in,out] shader NIR shader. * \param[in,out] data Shader data. + * \param[in] ctx PCO compiler context. * \return True if the pass made progress. */ -bool pco_nir_lower_tex(nir_shader *shader, pco_data *data) +bool pco_nir_lower_tex(nir_shader *shader, pco_data *data, pco_ctx *ctx) { - return nir_shader_lower_instructions(shader, is_tex, lower_tex, data); + struct state state = { + .data = data, + .ctx = ctx, + }; + + return nir_shader_lower_instructions(shader, is_tex, lower_tex, &state); } static enum util_format_type nir_type_to_util_type(nir_alu_type nir_type) diff --git a/src/imagination/pco/usclib/tex.cl b/src/imagination/pco/usclib/tex.cl index 686058b0958..1ec58ff6a97 100644 --- a/src/imagination/pco/usclib/tex.cl +++ b/src/imagination/pco/usclib/tex.cl @@ -87,3 +87,35 @@ usclib_tex_state_size(uint4 tex_state, uint num_comps, bool is_1d, bool is_array return size_comps; } + +uint +usclib_tex_state_base_level(uint4 tex_state) +{ + uint32_t texstate_image_word1[] = {tex_state.z, tex_state.w}; + struct ROGUE_TEXSTATE_IMAGE_WORD1 texstate_image_struct; + + ROGUE_TEXSTATE_IMAGE_WORD1_unpack(texstate_image_word1, &texstate_image_struct); + + return texstate_image_struct.baselevel; +} + +bool +usclib_smp_state_mipfilter(uint4 smp_state) +{ + uint32_t texstate_sampler_word0[] = {smp_state.x, smp_state.y}; + struct ROGUE_TEXSTATE_SAMPLER_WORD0 texstate_sampler_struct; + + ROGUE_TEXSTATE_SAMPLER_WORD0_unpack(texstate_sampler_word0, &texstate_sampler_struct); + + return texstate_sampler_struct.mipfilter; +} + +float +usclib_tex_lod_dval_post_clamp_resource_to_view_space(uint4 tex_state, uint4 smp_state, float lod_dval_post_clamp) +{ + lod_dval_post_clamp -= (float)usclib_tex_state_base_level(tex_state); + if (!usclib_smp_state_mipfilter(smp_state)) + lod_dval_post_clamp = floor(lod_dval_post_clamp + 0.5f); + + return MAX2(lod_dval_post_clamp, 0.0f); +}