diff options
author | Emma Anholt <emma@anholt.net> | 2021-12-08 14:56:54 -0800 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-02-16 17:22:40 +0000 |
commit | ca1ec7272685bdadd4e339cb989ac503db0abd18 (patch) | |
tree | fca0d1f8ffa2279991034ae361c132721548ee0d | |
parent | 80716b6f7e9fe0c93e6a244d23689b0ff81c2927 (diff) |
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>
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_debug.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv30/nv30_fragprog.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv30/nv30_screen.c | 53 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv30/nv30_screen.h | 3 | ||||
-rw-r--r-- | 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; } |