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>
This commit is contained in:
Emma Anholt 2021-12-08 14:56:54 -08:00 committed by Marge Bot
parent 80716b6f7e
commit ca1ec72726
5 changed files with 71 additions and 6 deletions

View file

@ -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

View file

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

View file

@ -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;

View file

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

View file

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