[6/6] panfrost: Add support for TXS instructions

Submitted by Boris Brezillon on June 17, 2019, 10:49 a.m.

Details

Message ID 20190617104928.24007-7-boris.brezillon@collabora.com
State New
Headers show
Series "panfrost: Add support for TXS instructions" ( rev: 2 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Boris Brezillon June 17, 2019, 10:49 a.m.
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@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(-)

Patch hide | download patch | download mbox

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);
                 }

Comments


On Mon, 17 Jun 2019 07:05:24 -0700
Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> wrote:

> > +        /*
> > +         * 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);  
> 
> Hmm, maybe we could just have a second indepedent lower_tex_options to
> do just the lower_txs_lod lowering? No progress loop needed, no complex
> explanation needed. It's a little strange, but it's okay :)

Okay, I'll do that.

Thanks,

Boris