mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 21:08:11 +02:00
ir3: Support min_lod tex source
Use the .clp modifier. In order to fix dEQP-VK.glsl.texture_functions.textureoffsetclamp.* we need to add a workaround for an empirically-discovered problem. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32671>
This commit is contained in:
parent
63959bb716
commit
e72fed3faa
3 changed files with 57 additions and 5 deletions
|
|
@ -3599,12 +3599,12 @@ static void
|
|||
emit_tex(struct ir3_context *ctx, nir_tex_instr *tex)
|
||||
{
|
||||
struct ir3_builder *b = &ctx->build;
|
||||
struct ir3_instruction **dst, *sam, *src0[12], *src1[4];
|
||||
struct ir3_instruction **dst, *sam, *src0[12], *src1[5];
|
||||
struct ir3_instruction *const *coord, *const *off, *const *ddx, *const *ddy;
|
||||
struct ir3_instruction *lod, *compare, *proj, *sample_index;
|
||||
struct ir3_instruction *lod, *compare, *proj, *sample_index, *min_lod;
|
||||
struct tex_src_info info = {0};
|
||||
bool has_bias = false, has_lod = false, has_proj = false, has_off = false;
|
||||
bool lod_zero = false;
|
||||
bool lod_zero = false, has_min_lod = false;
|
||||
unsigned i, coords, flags, ncomp;
|
||||
unsigned nsrc0 = 0, nsrc1 = 0;
|
||||
type_t type;
|
||||
|
|
@ -3613,7 +3613,7 @@ emit_tex(struct ir3_context *ctx, nir_tex_instr *tex)
|
|||
ncomp = tex->def.num_components;
|
||||
|
||||
coord = off = ddx = ddy = NULL;
|
||||
lod = proj = compare = sample_index = NULL;
|
||||
lod = proj = compare = sample_index = min_lod = NULL;
|
||||
|
||||
dst = ir3_get_def(ctx, &tex->def, ncomp);
|
||||
|
||||
|
|
@ -3658,6 +3658,10 @@ emit_tex(struct ir3_context *ctx, nir_tex_instr *tex)
|
|||
case nir_tex_src_ms_index:
|
||||
sample_index = ir3_get_src(ctx, &tex->src[i].src)[0];
|
||||
break;
|
||||
case nir_tex_src_min_lod:
|
||||
min_lod = ir3_get_src(ctx, &tex->src[i].src)[0];
|
||||
has_min_lod = true;
|
||||
break;
|
||||
case nir_tex_src_texture_offset:
|
||||
case nir_tex_src_sampler_offset:
|
||||
case nir_tex_src_texture_handle:
|
||||
|
|
@ -3831,7 +3835,7 @@ emit_tex(struct ir3_context *ctx, nir_tex_instr *tex)
|
|||
* - lod
|
||||
* - bias
|
||||
*/
|
||||
if (has_off | has_lod | has_bias) {
|
||||
if (has_off | has_lod | has_bias | has_min_lod) {
|
||||
if (has_off) {
|
||||
unsigned off_coords = coords;
|
||||
if (tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
|
||||
|
|
@ -3845,6 +3849,11 @@ emit_tex(struct ir3_context *ctx, nir_tex_instr *tex)
|
|||
|
||||
if (has_lod | has_bias)
|
||||
src1[nsrc1++] = lod;
|
||||
|
||||
if (has_min_lod) {
|
||||
src1[nsrc1++] = min_lod;
|
||||
flags |= IR3_INSTR_CLP;
|
||||
}
|
||||
}
|
||||
|
||||
type = get_tex_dest_type(tex);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#include "ir3_nir.h"
|
||||
#include "ir3_shader.h"
|
||||
|
||||
#include "nir_builtin_builder.h"
|
||||
|
||||
/* For use by binning_pass shaders, where const_state is const, but expected
|
||||
* to be already set up when we compiled the corresponding non-binning variant
|
||||
*/
|
||||
|
|
@ -626,6 +628,44 @@ ir3_nir_lower_sparse_residency(nir_shader *shader)
|
|||
nir_metadata_control_flow, NULL);
|
||||
}
|
||||
|
||||
/* The hardware implementiation of min LOD clamp is broken when the given LOD
|
||||
* clamp value (min_lod) is greater than levelCount - 1 (that is, when it would
|
||||
* be clamped by the hardware to avoid accessing an out-of-bounds level).
|
||||
* Instead of clamping the clamped LOD afterwards, it just returns zero. Because
|
||||
* the LOD would always be clamped to levelCount - 1 in this case, we can just
|
||||
* clamp min_lod to levelCount - 1 and get the same result while avoiding the
|
||||
* hardware bug.
|
||||
*/
|
||||
static bool
|
||||
ir3_nir_min_lod_workaround_cb(struct nir_builder *b, nir_tex_instr *tex, void *_data)
|
||||
{
|
||||
int src_idx = nir_tex_instr_src_index(tex, nir_tex_src_min_lod);
|
||||
if (src_idx < 0)
|
||||
return false;
|
||||
|
||||
b->cursor = nir_before_instr(&tex->instr);
|
||||
|
||||
nir_def *level_count = nir_build_texture_query(b, tex,
|
||||
nir_texop_query_levels, 1,
|
||||
nir_type_uint32,
|
||||
false, false);
|
||||
|
||||
nir_def *src = tex->src[src_idx].src.ssa;
|
||||
src = nir_fmin(b, src, nir_i2fN(b, nir_iadd_imm(b, level_count, -1),
|
||||
src->bit_size));
|
||||
nir_src_rewrite(&tex->src[src_idx].src, src);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ir3_nir_min_lod_workaround(nir_shader *shader)
|
||||
{
|
||||
return nir_shader_tex_pass(
|
||||
shader, ir3_nir_min_lod_workaround_cb,
|
||||
nir_metadata_control_flow, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ir3_finalize_nir(struct ir3_compiler *compiler,
|
||||
const struct ir3_shader_nir_options *options,
|
||||
|
|
@ -666,6 +706,7 @@ ir3_finalize_nir(struct ir3_compiler *compiler,
|
|||
OPT(s, nir_lower_load_const_to_scalar);
|
||||
|
||||
NIR_PASS(_, s, ir3_nir_lower_sparse_residency);
|
||||
NIR_PASS(_, s, ir3_nir_min_lod_workaround);
|
||||
|
||||
if (compiler->array_index_add_half)
|
||||
OPT(s, ir3_nir_lower_array_sampler);
|
||||
|
|
|
|||
|
|
@ -194,6 +194,8 @@ print_instr_name(struct log_stream *stream, struct ir3_instruction *instr,
|
|||
mesa_log_stream_printf(stream, ".u");
|
||||
if (instr->flags & IR3_INSTR_RCK)
|
||||
mesa_log_stream_printf(stream, ".rck");
|
||||
if (instr->flags & IR3_INSTR_CLP)
|
||||
mesa_log_stream_printf(stream, ".clp");
|
||||
if (instr->opc == OPC_LDC)
|
||||
mesa_log_stream_printf(stream, ".offset%d", instr->cat6.d);
|
||||
if (instr->opc == OPC_LDC_K)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue