softpipe: Switch to using NIR as the shader format from mesa/st.

This causes our TGSI to use far more temps, since NTT is currently not
releasing temps from registers.  On the other hand, this interpreter is
already spectacularly slow, and if we wanted to go fast we should probably
write a scalar NIR intrepeter.

For now, using NTT means that we test that codepath in preparation for
switching TGSI-consuming HW drivers over, so that we can eventually
garbage collect st_glsl_to_tgsi.

As this is a major restructuring, there are some impacts on piglit:

- Several tests start assert failing about 64-bit NIR registers for temp
  arrays not getting split to vec2s:
  - fs-frexp-dvec4-variable-index.shader_test
  - arb_gpu_shader_fp64/uniform_buffers/{vs,fs,gs}-array-copy.shader_test
  - arb_gpu_shader_int64/execution/indirect-array-two-accesses.shader_test
- dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_geometry_fragment.fbo_bbox_larger
  starts crashing depending on various bits of state (previous tests run
  before it, presence of valgrind, presence of glib's memcheck).  Doesn't
  seem really NTT-specific, added to flakes list with other GS flakes.
- Almost 200 fp64/int64-related tests start passing, mostly around i/o loayout.

shader-db:
total instructions in shared programs: 3492656 -> 3081674 (-11.77%)
total loops in shared programs: 1418 -> 1387 (-2.19%)
total temps in shared programs: 340041 -> 615527 (81.02%)
total const in shared programs: 3158970 -> 1528630 (-51.61%)
total imm in shared programs: 117586 -> 101349 (-13.81%)
Total CPU time (seconds): 430.36 -> 900.94 (109.35%)

FPS results:
glmark2 texture               +7.32484% +/- 3.76528% (n=10)
glmark2 desktop:effect=shadow +20%      +/- 0% (n=10)
glmark2 shadow                +6.49351% +/- 3.65335% (n=7)
glmark2 conditionals          +18.75%   +/- 2.74658% (n=9)

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3395>
This commit is contained in:
Eric Anholt 2019-12-31 16:20:52 -08:00
parent 6444f5702d
commit d0f8fe5909
8 changed files with 91 additions and 20 deletions

View File

@ -19,6 +19,7 @@ dEQP-GLES31.functional.shaders.linkage.es31.geometry.uniform.types.uvec4
dEQP-GLES31.functional.shaders.linkage.es31.geometry.varying.types.uvec4
dEQP-GLES31.functional.shaders.opaque_type_indexing.sampler.const_expression.geometry.usampler3d
dEQP-GLES31.functional.shaders.opaque_type_indexing.sampler.dynamically_uniform.geometry.sampler2darray
dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_geometry_fragment.fbo_bbox_larger
# This one is really slow and can time out (~56 seconds locally)
KHR-GL33.texture_swizzle.smoke

View File

@ -451,6 +451,9 @@ Softpipe driver environment variables
``use_llvm``
the softpipe driver will try to use LLVM JIT for vertex
shading processing.
``use_tgsi``
if set, the softpipe driver will ask to directly consume TGSI, instead
of NIR.
LLVMpipe driver environment variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -105,6 +105,8 @@ C_SOURCES := \
indices/u_indices_priv.h \
indices/u_primconvert.c \
indices/u_primconvert.h \
nir/nir_to_tgsi.c \
nir/nir_to_tgsi.h \
os/os_mman.h \
os/os_process.c \
os/os_process.h \

View File

@ -2,6 +2,10 @@ Import('*')
env = env.Clone()
env.Prepend(CPPPATH = [
'../../../compiler/nir',
])
env.MSVC2013Compat()
softpipe = env.ConvenienceLibrary(

View File

@ -82,6 +82,7 @@ libsoftpipe = static_library(
include_directories : [inc_gallium_aux, inc_gallium, inc_include, inc_src],
c_args : [c_msvc_compat_args],
gnu_symbol_visibility : 'hidden',
dependencies : idep_nir,
)
driver_swrast = declare_dependency(

View File

@ -26,6 +26,7 @@
**************************************************************************/
#include "compiler/nir/nir.h"
#include "util/u_memory.h"
#include "util/format/u_format.h"
#include "util/format/u_format_s3tc.h"
@ -53,6 +54,7 @@ static const struct debug_named_value sp_debug_options[] = {
{"cs", SP_DBG_CS, "dump compute shader assembly to stderr"},
{"no_rast", SP_DBG_NO_RAST, "no-ops rasterization, for profiling purposes"},
{"use_llvm", SP_DBG_USE_LLVM, "Use LLVM if available for shaders"},
{"use_tgsi", SP_DBG_USE_TGSI, "Request TGSI from the API instead of NIR"},
};
int sp_debug;
@ -71,6 +73,27 @@ softpipe_get_name(struct pipe_screen *screen)
return "softpipe";
}
static const nir_shader_compiler_options sp_compiler_options = {
.fuse_ffma32 = true,
.fuse_ffma64 = true,
.lower_extract_byte = true,
.lower_extract_word = true,
.lower_fdph = true,
.lower_flrp64 = true,
.lower_fmod = true,
.lower_rotate = true,
.lower_sub = true,
.lower_vector_cmp = true,
.use_interpolated_input_intrinsics = true,
};
static const void *
softpipe_get_compiler_options(struct pipe_screen *pscreen,
enum pipe_shader_ir ir, unsigned shader)
{
assert(ir == PIPE_SHADER_IR_NIR);
return &sp_compiler_options;
}
static int
softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
@ -219,6 +242,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
return 1;
case PIPE_CAP_QUERY_SO_OVERFLOW:
return 1;
case PIPE_CAP_NIR_IMAGES_AS_DEREF:
return 0;
case PIPE_CAP_VENDOR_ID:
return 0xFFFFFFFF;
@ -264,7 +289,6 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_PCI_BUS:
case PIPE_CAP_PCI_DEVICE:
case PIPE_CAP_PCI_FUNCTION:
case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
return 0;
case PIPE_CAP_MAX_GS_INVOCATIONS:
return 32;
@ -283,6 +307,16 @@ softpipe_get_shader_param(struct pipe_screen *screen,
enum pipe_shader_cap param)
{
struct softpipe_screen *sp_screen = softpipe_screen(screen);
switch (param) {
case PIPE_SHADER_CAP_PREFERRED_IR:
return (sp_debug & SP_DBG_USE_TGSI) ? PIPE_SHADER_IR_TGSI : PIPE_SHADER_IR_NIR;
case PIPE_SHADER_CAP_SUPPORTED_IRS:
return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
default:
break;
}
switch(shader)
{
case PIPE_SHADER_FRAGMENT:
@ -548,6 +582,7 @@ softpipe_create_screen(struct sw_winsys *winsys)
screen->base.context_create = softpipe_create_context;
screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
screen->base.get_compute_param = softpipe_get_compute_param;
screen->base.get_compiler_options = softpipe_get_compiler_options;
screen->use_llvm = sp_debug & SP_DBG_USE_LLVM;
softpipe_init_screen_texture_funcs(&screen->base);

View File

@ -64,6 +64,7 @@ enum sp_debug_flag {
SP_DBG_CS = BITFIELD_BIT(5),
SP_DBG_USE_LLVM = BITFIELD_BIT(6),
SP_DBG_NO_RAST = BITFIELD_BIT(7),
SP_DBG_USE_TGSI = BITFIELD_BIT(8),
};
extern int sp_debug;

View File

@ -31,7 +31,10 @@
#include "sp_fs.h"
#include "sp_texture.h"
#include "nir.h"
#include "nir/nir_to_tgsi.h"
#include "pipe/p_defines.h"
#include "util/ralloc.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_pstipple.h"
@ -139,10 +142,23 @@ softpipe_create_shader_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ,
bool debug)
{
assert(templ->type == PIPE_SHADER_IR_TGSI);
if (templ->type == PIPE_SHADER_IR_NIR) {
shader->tokens = nir_to_tgsi(templ->ir.nir, pipe->screen);
/* Note: Printing the final NIR after nir-to-tgsi transformed and
* optimized it
*/
if (debug)
nir_print_shader(templ->ir.nir, stderr);
ralloc_free(templ->ir.nir);
} else {
assert(templ->type == PIPE_SHADER_IR_TGSI);
/* we need to keep a local copy of the tokens */
shader->tokens = tgsi_dup_tokens(templ->tokens);
}
shader->type = PIPE_SHADER_IR_TGSI;
/* we need to keep a local copy of the tokens */
shader->tokens = tgsi_dup_tokens(templ->tokens);
shader->stream_output = templ->stream_output;
@ -308,8 +324,9 @@ softpipe_create_gs_state(struct pipe_context *pipe,
softpipe_create_shader_state(pipe, &state->shader, templ,
sp_debug & SP_DBG_GS);
if (templ->tokens) {
state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
if (state->shader.tokens) {
state->draw_data = draw_create_geometry_shader(softpipe->draw,
&state->shader);
if (state->draw_data == NULL)
goto fail;
@ -405,22 +422,29 @@ static void *
softpipe_create_compute_state(struct pipe_context *pipe,
const struct pipe_compute_state *templ)
{
const struct tgsi_token *tokens;
struct sp_compute_shader *state;
if (templ->ir_type != PIPE_SHADER_IR_TGSI)
return NULL;
tokens = templ->prog;
/* debug */
if (sp_debug & SP_DBG_CS)
tgsi_dump(tokens, 0);
softpipe_shader_db(pipe, tokens);
state = CALLOC_STRUCT(sp_compute_shader);
struct sp_compute_shader *state = CALLOC_STRUCT(sp_compute_shader);
state->shader = *templ;
state->tokens = tgsi_dup_tokens(tokens);
if (templ->ir_type == PIPE_SHADER_IR_NIR) {
nir_shader *s = (void *)templ->prog;
if (sp_debug & SP_DBG_CS)
nir_print_shader(s, stderr);
state->tokens = (void *)nir_to_tgsi(s, pipe->screen);
ralloc_free(s);
} else {
assert(templ->ir_type == PIPE_SHADER_IR_TGSI);
/* we need to keep a local copy of the tokens */
state->tokens = tgsi_dup_tokens(templ->prog);
}
if (sp_debug & SP_DBG_CS)
tgsi_dump(state->tokens, 0);
softpipe_shader_db(pipe, state->tokens);
tgsi_scan_shader(state->tokens, &state->info);
state->max_sampler = state->info.file_max[TGSI_FILE_SAMPLER];