Module: Mesa Branch: main Commit: e7f3112eb97952b5966089d8769cb53db8efe2a0 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e7f3112eb97952b5966089d8769cb53db8efe2a0
Author: Alyssa Rosenzweig <aly...@rosenzweig.io> Date: Sun Dec 10 17:05:55 2023 -0400 asahi: Implement lod queries Signed-off-by: Alyssa Rosenzweig <aly...@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26861> --- src/asahi/compiler/agx_compile.c | 12 ++++++++---- src/asahi/compiler/agx_compiler.h | 3 ++- src/asahi/compiler/agx_nir_lower_texture.c | 7 ++++++- src/asahi/compiler/agx_opcodes.py | 3 ++- src/asahi/compiler/agx_pack.c | 2 +- src/gallium/drivers/asahi/agx_pipe.c | 1 + 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/asahi/compiler/agx_compile.c b/src/asahi/compiler/agx_compile.c index 330454ffa43..d2ba4fb6d75 100644 --- a/src/asahi/compiler/agx_compile.c +++ b/src/asahi/compiler/agx_compile.c @@ -7,7 +7,6 @@ #include "agx_compile.h" #include "compiler/nir/nir_builder.h" -#include "glsl_types.h" #include "util/glheader.h" #include "util/macros.h" #include "util/u_debug.h" @@ -16,6 +15,7 @@ #include "agx_debug.h" #include "agx_internal_formats.h" #include "agx_nir.h" +#include "glsl_types.h" #include "nir.h" #include "nir_intrinsics.h" #include "nir_intrinsics_indices.h" @@ -1713,7 +1713,7 @@ agx_emit_alu(agx_builder *b, nir_alu_instr *instr) } static enum agx_lod_mode -agx_lod_mode_for_nir(nir_texop op) +agx_lod_mode_for_nir(nir_texop op, bool biased) { switch (op) { case nir_texop_tex: @@ -1721,6 +1721,8 @@ agx_lod_mode_for_nir(nir_texop op) return AGX_LOD_MODE_AUTO_LOD; case nir_texop_txb: return AGX_LOD_MODE_AUTO_LOD_BIAS; + case nir_texop_lod: + return biased ? AGX_LOD_MODE_AUTO_LOD_BIAS : AGX_LOD_MODE_AUTO_LOD; case nir_texop_txd: return AGX_LOD_MODE_LOD_GRAD; case nir_texop_txl: @@ -1847,8 +1849,10 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr) agx_instr *I = agx_texture_sample_to( b, tmp, coords, lod, bindless, texture, sampler, compare_offset, agx_tex_dim(instr->sampler_dim, instr->is_array), - agx_lod_mode_for_nir(instr->op), 0, 0, !agx_is_null(packed_offset), - !agx_is_null(compare), agx_gather_for_nir(instr)); + agx_lod_mode_for_nir( + instr->op, nir_tex_instr_src_index(instr, nir_tex_src_bias) >= 0), + 0, 0, !agx_is_null(packed_offset), !agx_is_null(compare), + instr->op == nir_texop_lod, agx_gather_for_nir(instr)); if (txf) I->op = AGX_OPCODE_TEXTURE_LOAD; diff --git a/src/asahi/compiler/agx_compiler.h b/src/asahi/compiler/agx_compiler.h index 235517babb0..af2e975c1b1 100644 --- a/src/asahi/compiler/agx_compiler.h +++ b/src/asahi/compiler/agx_compiler.h @@ -311,6 +311,7 @@ typedef struct { enum agx_dim dim : 4; bool offset : 1; bool shadow : 1; + bool query_lod : 1; enum agx_gather gather : 3; /* TODO: Handle iter ops more efficient */ @@ -330,7 +331,7 @@ typedef struct { bool saturate : 1; unsigned mask : 4; - unsigned padding : 9; + unsigned padding : 8; } agx_instr; static inline void diff --git a/src/asahi/compiler/agx_nir_lower_texture.c b/src/asahi/compiler/agx_nir_lower_texture.c index e2d4b87ebbd..9356ff51d2e 100644 --- a/src/asahi/compiler/agx_nir_lower_texture.c +++ b/src/asahi/compiler/agx_nir_lower_texture.c @@ -150,7 +150,7 @@ lower_regular_texture(nir_builder *b, nir_instr *instr, UNUSED void *data) nir_tex_instr *tex = nir_instr_as_tex(instr); b->cursor = nir_before_instr(instr); - if (nir_tex_instr_is_query(tex)) + if (nir_tex_instr_is_query(tex) && tex->op != nir_texop_lod) return false; if (tex->sampler_dim == GLSL_SAMPLER_DIM_BUF) @@ -306,6 +306,11 @@ lower_sampler_bias(nir_builder *b, nir_instr *instr, UNUSED void *data) return true; } + case nir_texop_lod: { + nir_tex_instr_add_src(tex, nir_tex_src_bias, bias_for_tex(b, tex)); + return true; + } + case nir_texop_txf: case nir_texop_txf_ms: case nir_texop_txs: diff --git a/src/asahi/compiler/agx_opcodes.py b/src/asahi/compiler/agx_opcodes.py index ac21c0ead91..40c039bdcdd 100644 --- a/src/asahi/compiler/agx_opcodes.py +++ b/src/asahi/compiler/agx_opcodes.py @@ -104,6 +104,7 @@ GATHER = enum("gather", { OFFSET = immediate("offset", "bool") SHADOW = immediate("shadow", "bool") +QUERY_LOD = immediate("query_lod", "bool") SCOREBOARD = immediate("scoreboard") ICOND = immediate("icond", "enum agx_icond") FCOND = immediate("fcond", "enum agx_fcond") @@ -276,7 +277,7 @@ op("fcmp", _, srcs = 2, imms = [FCOND, INVERT_COND]) op("texture_sample", encoding_32 = (0x31, 0x7F, 8, 10), # XXX WRONG SIZE srcs = 6, imms = [DIM, LOD_MODE, MASK, SCOREBOARD, OFFSET, SHADOW, - GATHER]) + QUERY_LOD, GATHER]) for memory, can_reorder in [("texture", True), ("image", False)]: op(f"{memory}_load", encoding_32 = (0x71, 0x7F, 8, 10), # XXX WRONG SIZE srcs = 6, imms = [DIM, LOD_MODE, MASK, SCOREBOARD, OFFSET], diff --git a/src/asahi/compiler/agx_pack.c b/src/asahi/compiler/agx_pack.c index ad136dcfb0c..27b6df3c442 100644 --- a/src/asahi/compiler/agx_pack.c +++ b/src/asahi/compiler/agx_pack.c @@ -794,7 +794,7 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups, unsigned D = agx_pack_lod(I->src[1], &lod_mode); unsigned q1 = I->shadow; - unsigned q2 = 0; // XXX + unsigned q2 = I->query_lod ? 2 : 0; unsigned q3 = 12; // XXX unsigned kill = 0; // helper invocation kill bit diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 2a81893b7f0..6c882da4d3f 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -1736,6 +1736,7 @@ agx_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 7; case PIPE_CAP_DRAW_INDIRECT: case PIPE_CAP_TEXTURE_QUERY_SAMPLES: + case PIPE_CAP_TEXTURE_QUERY_LOD: return true; case PIPE_CAP_MAX_VIEWPORTS: