Mesa (main): nv30/40: Switch to using NIR-to-TGSI by default.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Feb 16 18:02:58 UTC 2022


Module: Mesa
Branch: main
Commit: ca1ec7272685bdadd4e339cb989ac503db0abd18
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ca1ec7272685bdadd4e339cb989ac503db0abd18

Author: Emma Anholt <emma at anholt.net>
Date:   Wed Dec  8 14:56:54 2021 -0800

nv30/40: Switch to using NIR-to-TGSI by default.

shader-db results (note that we expect many more loops unrolled, so instr
count is probably understating the win):

nv30:
total instructions in shared programs: 16535069 -> 14299105 (-13.52%)
instructions in affected programs: 16377286 -> 14141322 (-13.65%)
total gpr in shared programs: 81255 -> 67268 (-17.21%)
gpr in affected programs: 56714 -> 42727 (-24.66%)
LOST:   0
GAINED: 824

nv40:
total instructions in shared programs: 20907673 -> 18428749 (-11.86%)
instructions in affected programs: 20755510 -> 18276586 (-11.94%)
total gpr in shared programs: 104200 -> 82831 (-20.51%)
gpr in affected programs: 80278 -> 58909 (-26.62%)

14130

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14130>

---

 src/gallium/drivers/nouveau/nouveau_debug.h      |  1 +
 src/gallium/drivers/nouveau/nv30/nv30_fragprog.c | 10 ++++-
 src/gallium/drivers/nouveau/nv30/nv30_screen.c   | 53 ++++++++++++++++++++++--
 src/gallium/drivers/nouveau/nv30/nv30_screen.h   |  3 ++
 src/gallium/drivers/nouveau/nv30/nv30_vertprog.c | 10 ++++-
 5 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nouveau_debug.h b/src/gallium/drivers/nouveau/nouveau_debug.h
index 546a4ad0af3..5e7c5b70b42 100644
--- a/src/gallium/drivers/nouveau/nouveau_debug.h
+++ b/src/gallium/drivers/nouveau/nouveau_debug.h
@@ -7,6 +7,7 @@
 #include "util/u_debug.h"
 
 #define NOUVEAU_DEBUG_MISC       0x0001
+#define NOUVEAU_DEBUG_USE_TGSI   0x0002
 #define NOUVEAU_DEBUG_SHADER     0x0100
 #define NOUVEAU_DEBUG_PROG_IR    0x0200
 #define NOUVEAU_DEBUG_PROG_RA    0x0400
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
index 74134bb2f0c..55857781f5f 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
@@ -25,6 +25,7 @@
 
 #include "draw/draw_context.h"
 #include "tgsi/tgsi_parse.h"
+#include "nir/nir_to_tgsi.h"
 
 #include "nv_object.xml.h"
 #include "nv30/nv30-40_3d.xml.h"
@@ -140,7 +141,14 @@ nv30_fp_state_create(struct pipe_context *pipe,
    if (!fp)
       return NULL;
 
-   fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+   if (cso->type == PIPE_SHADER_IR_NIR) {
+      fp->pipe.tokens = nir_to_tgsi(cso->ir.nir, pipe->screen);
+   } else {
+      assert(cso->type == PIPE_SHADER_IR_TGSI);
+      /* we need to keep a local copy of the tokens */
+      fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+   }
+
    tgsi_scan_shader(fp->pipe.tokens, &fp->info);
    return fp;
 }
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index 8b43357a375..c3167aa9832 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -349,7 +349,7 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen,
       case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
          return 32;
       case PIPE_SHADER_CAP_PREFERRED_IR:
-         return PIPE_SHADER_IR_TGSI;
+         return (NOUVEAU_DEBUG & NOUVEAU_DEBUG_USE_TGSI) ? PIPE_SHADER_IR_TGSI : PIPE_SHADER_IR_NIR;
       case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
       case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
          return 0;
@@ -380,7 +380,7 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen,
       case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
          return 0;
       case PIPE_SHADER_CAP_SUPPORTED_IRS:
-         return 1 << PIPE_SHADER_IR_TGSI;
+         return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
       default:
          debug_printf("unknown vertex shader param %d\n", param);
          return 0;
@@ -411,7 +411,7 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen,
       case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
          return 32;
       case PIPE_SHADER_CAP_PREFERRED_IR:
-         return PIPE_SHADER_IR_TGSI;
+         return (NOUVEAU_DEBUG & NOUVEAU_DEBUG_USE_TGSI) ? PIPE_SHADER_IR_TGSI : PIPE_SHADER_IR_NIR;
       case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
       case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
       case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
@@ -438,7 +438,7 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen,
       case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
          return 0;
       case PIPE_SHADER_CAP_SUPPORTED_IRS:
-         return 1 << PIPE_SHADER_IR_TGSI;
+         return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
       default:
          debug_printf("unknown fragment shader param %d\n", param);
          return 0;
@@ -486,6 +486,45 @@ nv30_screen_is_format_supported(struct pipe_screen *pscreen,
    return (nv30_format_info(pscreen, format)->bindings & bindings) == bindings;
 }
 
+static const nir_shader_compiler_options nv30_base_compiler_options = {
+   .fuse_ffma32 = true,
+   .fuse_ffma64 = true,
+   .lower_bitops = true,
+   .lower_extract_byte = true,
+   .lower_extract_word = true,
+   .lower_fdiv = true,
+   .lower_insert_byte = true,
+   .lower_insert_word = true,
+   .lower_fdph = true,
+   .lower_flrp32 = true,
+   .lower_flrp64 = true,
+   .lower_fmod = true,
+   .lower_fpow = true, /* In hardware as of nv40 FS */
+   .lower_rotate = true,
+   .lower_uniforms_to_ubo = true,
+   .lower_vector_cmp = true,
+   .max_unroll_iterations = 32,
+
+   .use_interpolated_input_intrinsics = true,
+};
+
+static const void *
+nv30_screen_get_compiler_options(struct pipe_screen *pscreen,
+                                 enum pipe_shader_ir ir,
+                                 enum pipe_shader_type shader)
+{
+   struct nv30_screen *screen = nv30_screen(pscreen);
+   assert(ir == PIPE_SHADER_IR_NIR);
+
+   /* The FS compiler options are different between nv30 and nv40, and are set
+    * up at screen creation time.
+    */
+   if (shader == PIPE_SHADER_FRAGMENT)
+      return &screen->fs_compiler_options;
+
+   return &nv30_base_compiler_options;
+}
+
 static void
 nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)
 {
@@ -617,6 +656,8 @@ nv30_screen_create(struct nouveau_device *dev)
    pscreen->get_shader_param = nv30_screen_get_shader_param;
    pscreen->context_create = nv30_context_create;
    pscreen->is_format_supported = nv30_screen_is_format_supported;
+   pscreen->get_compiler_options = nv30_screen_get_compiler_options;
+
    nv30_resource_screen_init(pscreen);
    nouveau_screen_init_vdec(&screen->base);
 
@@ -634,6 +675,10 @@ nv30_screen_create(struct nouveau_device *dev)
       screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER;
    }
 
+   screen->fs_compiler_options = nv30_base_compiler_options;
+   if (oclass >= NV40_3D_CLASS)
+      screen->fs_compiler_options.lower_fpow = false;
+
    fifo = screen->base.channel->data;
    push = screen->base.pushbuf;
    push->rsvd_kick = 16;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.h b/src/gallium/drivers/nouveau/nv30/nv30_screen.h
index df11233d07a..c61a1ece54b 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.h
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.h
@@ -11,6 +11,7 @@
 #include "nouveau_heap.h"
 #include "nv30/nv30_winsys.h"
 #include "nv30/nv30_resource.h"
+#include "compiler/nir/nir.h"
 
 struct nv30_context;
 
@@ -39,6 +40,8 @@ struct nv30_screen {
    struct nouveau_heap *vp_exec_heap;
    struct nouveau_heap *vp_data_heap;
 
+   nir_shader_compiler_options fs_compiler_options;
+
    unsigned max_sample_count;
 };
 
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c b/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c
index ee0a6280d7a..3866709c138 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c
@@ -26,6 +26,7 @@
 #include "draw/draw_context.h"
 #include "util/u_dynarray.h"
 #include "tgsi/tgsi_parse.h"
+#include "nir/nir_to_tgsi.h"
 
 #include "nv_object.xml.h"
 #include "nv30/nv30-40_3d.xml.h"
@@ -226,7 +227,14 @@ nv30_vp_state_create(struct pipe_context *pipe,
    if (!vp)
       return NULL;
 
-   vp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+   if (cso->type == PIPE_SHADER_IR_NIR) {
+      vp->pipe.tokens = nir_to_tgsi(cso->ir.nir, pipe->screen);
+   } else {
+      assert(cso->type == PIPE_SHADER_IR_TGSI);
+      /* we need to keep a local copy of the tokens */
+      vp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+   }
+
    tgsi_scan_shader(vp->pipe.tokens, &vp->info);
    return vp;
 }



More information about the mesa-commit mailing list