[Mesa-dev] [PATCH 6/6] panfrost: Add support for TXS instructions
Boris Brezillon
boris.brezillon at collabora.com
Mon Jun 17 10:49:28 UTC 2019
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 <boris.brezillon at collabora.com>
---
.../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
More information about the mesa-dev
mailing list