This patch adds support for nir_texop_txs instructions which are needed to support the OpenGL textureSize() function. This is also needed to support RECT texture sampling which is currently lowered to 2D sampling + a TXS() instruction by the nir_lower_tex() helper.
Signed-off-by: Boris Brezillon <[email protected]> --- .../panfrost/midgard/midgard_compile.c | 33 +++++++++++++++++++ .../panfrost/midgard/midgard_compile.h | 12 ++++++- src/gallium/drivers/panfrost/pan_context.c | 29 ++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c index 846a99187e1c..a887c4dcd911 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c +++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c @@ -288,6 +288,7 @@ static int sysval_for_instr(compiler_context *ctx, nir_instr *instr, { nir_intrinsic_instr *intr; nir_dest *dst = NULL; + nir_tex_instr *tex; int sysval = -1; switch (instr->type) { @@ -296,6 +297,18 @@ static int sysval_for_instr(compiler_context *ctx, nir_instr *instr, sysval = midgard_nir_sysval_for_intrinsic(intr); dst = &intr->dest; break; + case nir_instr_type_tex: + tex = nir_instr_as_tex(instr); + if (tex->op != nir_texop_txs) + break; + + sysval = PAN_SYSVAL(TEXTURE_SIZE, + PAN_TXS_SYSVAL_ID(tex->texture_index, + nir_tex_instr_dest_size(tex) - + (tex->is_array ? 1 : 0), + tex->is_array)); + dst = &tex->dest; + break; default: break; } @@ -388,9 +401,26 @@ optimise_nir(nir_shader *nir) nir_lower_tex_options lower_tex_options = { .lower_rect = true, + .lower_txs_lod = true, .lower_txp = ~0 }; + /* + * Note: the first call is here to lower RECT and TXP, the second one + * to lower the TXS(lod) instructions generated by the RECT lowering + * done in the first pass. + * + * FIXME: we should probably have a + * + * do nir_lower_tex() while (progress) + * + * loop here, but it looks like nir_lower_tex() is not ready for that + * (it keeps returning true and lowering the same instructions over and + * over again). + */ + NIR_PASS(progress, nir, nir_lower_tex, &lower_tex_options); + lower_tex_options.lower_rect = false; + lower_tex_options.lower_txp = 0; NIR_PASS(progress, nir, nir_lower_tex, &lower_tex_options); do { @@ -1351,6 +1381,9 @@ emit_tex(compiler_context *ctx, nir_tex_instr *instr) //assert (!instr->sampler); //assert (!instr->texture_array_size); switch (instr->op) { + case nir_texop_txs: + emit_sysval_read(ctx, &instr->instr); + return; case nir_texop_tex: case nir_texop_txb: case nir_texop_txl: diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.h b/src/gallium/drivers/panfrost/midgard/midgard_compile.h index b21f054c0318..44c3533b6de3 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard_compile.h +++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.h @@ -34,7 +34,9 @@ /* Allow 2D of sysval IDs, while allowing nonparametric sysvals to equal * their class for equal comparison */ -#define PAN_SYSVAL(type, no) ((no << 16) | PAN_SYSVAL_##type) +#define PAN_SYSVAL(type, no) (((no) << 16) | PAN_SYSVAL_##type) +#define PAN_SYSVAL_TYPE(sysval) ((sysval) & 0xffff) +#define PAN_SYSVAL_ID(sysval) ((sysval) >> 16) /* Define some common types. We start at one for easy indexing of hash * tables internal to the compiler */ @@ -42,8 +44,16 @@ enum { PAN_SYSVAL_VIEWPORT_SCALE = 1, PAN_SYSVAL_VIEWPORT_OFFSET = 2, + PAN_SYSVAL_TEXTURE_SIZE = 3, } pan_sysval; +#define PAN_TXS_SYSVAL_ID(texidx, dim, is_array) \ + ((texidx) | ((dim) << 7) | ((is_array) ? (1 << 9) : 0)) + +#define PAN_SYSVAL_ID_TO_TXS_TEX_IDX(id) ((id) & 0x7f) +#define PAN_SYSVAL_ID_TO_TXS_DIM(id) (((id) >> 7) & 0x3) +#define PAN_SYSVAL_ID_TO_TXS_IS_ARRAY(id) !!((id) & (1 << 9)) + typedef struct { int work_register_count; int uniform_count; diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 990f9fcb10c5..4eab6db4e234 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -1017,6 +1017,31 @@ static void panfrost_upload_viewport_offset_sysval(struct panfrost_context *ctx, uniform->f[2] = vp->translate[2]; } +static void panfrost_upload_txs_sysval(struct panfrost_context *ctx, + enum pipe_shader_type st, + unsigned int sysvalid, + struct sysval_uniform *uniform) +{ + unsigned texidx = PAN_SYSVAL_ID_TO_TXS_TEX_IDX(sysvalid); + unsigned dim = PAN_SYSVAL_ID_TO_TXS_DIM(sysvalid); + bool is_array = PAN_SYSVAL_ID_TO_TXS_IS_ARRAY(sysvalid); + struct pipe_sampler_view *tex = &ctx->sampler_views[st][texidx]->base; + + assert(dim); + uniform->i[0] = u_minify(tex->texture->width0, tex->u.tex.first_level); + + if (dim > 1) + uniform->i[1] = u_minify(tex->texture->height0, + tex->u.tex.first_level); + + if (dim > 2) + uniform->i[2] = u_minify(tex->texture->depth0, + tex->u.tex.first_level); + + if (is_array) + uniform->i[dim] = tex->texture->array_size; +} + static void panfrost_upload_sysvals(struct panfrost_context *ctx, void *buf, struct panfrost_shader_state *ss, enum pipe_shader_type st) @@ -1033,6 +1058,10 @@ static void panfrost_upload_sysvals(struct panfrost_context *ctx, void *buf, case PAN_SYSVAL_VIEWPORT_OFFSET: panfrost_upload_viewport_offset_sysval(ctx, &uniforms[i]); break; + case PAN_SYSVAL_TEXTURE_SIZE: + panfrost_upload_txs_sysval(ctx, st, PAN_SYSVAL_ID(sysval), + &uniforms[i]); + break; default: assert(0); } -- 2.20.1 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
