mesa/st: Always generate NIR from GLSL, and use nir_to_tgsi for TGSI drivers.

The NIR path through the frontend is effectively the only one maintained
for a quite a while now.  We can see that effect with !15540, where the
TGSI generation path was regressed to assertion fail on real-world
shaders, and nobody noticed until I came along trying to test the
NIR-to-TGSI transition.

We already have a nir_to_tgsi() call for translating NIR representation
for ARB programs into TGSI before handing them off to the driver.  This
change makes that path get taken for GLSL programs as well.

This is the minimum change to get all the drivers on NIR from GLSL, to
give a simple commit to bisect too.  The dead code removal comes next.

Now every driver benefits from shared NIR optimizations for GLSL, and we
can start retiring GLSL optimizations.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8044>
This commit is contained in:
Eric Anholt 2020-12-10 11:45:39 -08:00 committed by Marge Bot
parent 72dba615be
commit b167203cfe
3 changed files with 22 additions and 74 deletions

View file

@ -699,10 +699,7 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe,
ctx->Const.ShaderCompilerOptions[MESA_SHADER_TESS_EVAL].PositionAlwaysPrecise = options->vs_position_always_precise;
enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_PREFERRED_IR);
ctx->Const.UseNIRGLSLLinker = preferred_ir == PIPE_SHADER_IR_NIR;
ctx->Const.UseNIRGLSLLinker = true;
/* NIR drivers that support tess shaders and compact arrays need to use
* GLSLTessLevelsAsInputs / PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS. The NIR
@ -831,22 +828,11 @@ st_init_driver_functions(struct pipe_screen *screen,
st_init_flush_functions(screen, functions);
/* GL_ARB_get_program_binary */
enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_PREFERRED_IR);
if (preferred_ir == PIPE_SHADER_IR_NIR) {
functions->ShaderCacheSerializeDriverBlob = st_serialise_nir_program;
functions->ProgramBinarySerializeDriverBlob =
st_serialise_nir_program_binary;
functions->ProgramBinaryDeserializeDriverBlob =
st_deserialise_nir_program;
} else {
functions->ShaderCacheSerializeDriverBlob = st_serialise_tgsi_program;
functions->ProgramBinarySerializeDriverBlob =
st_serialise_tgsi_program_binary;
functions->ProgramBinaryDeserializeDriverBlob =
st_deserialise_tgsi_program;
}
functions->ShaderCacheSerializeDriverBlob = st_serialise_nir_program;
functions->ProgramBinarySerializeDriverBlob =
st_serialise_nir_program_binary;
functions->ProgramBinaryDeserializeDriverBlob =
st_deserialise_nir_program;
}

View file

@ -33,6 +33,7 @@
#include "main/macros.h"
#include "main/spirv_extensions.h"
#include "main/version.h"
#include "nir/nir_to_tgsi.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@ -167,23 +168,21 @@ void st_init_limits(struct pipe_screen *screen,
}
for (sh = 0; sh < PIPE_SHADER_TYPES; ++sh) {
struct gl_shader_compiler_options *options;
struct gl_program_constants *pc;
const nir_shader_compiler_options *nir_options = NULL;
const gl_shader_stage stage = tgsi_processor_to_shader_stage(sh);
struct gl_shader_compiler_options *options =
&c->ShaderCompilerOptions[stage];
struct gl_program_constants *pc = &c->Program[stage];
bool prefer_nir = PIPE_SHADER_IR_NIR ==
screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_PREFERRED_IR);
if (screen->get_compiler_options)
options->NirOptions = screen->get_compiler_options(screen, PIPE_SHADER_IR_NIR, sh);
if (screen->get_compiler_options && prefer_nir) {
nir_options = (const nir_shader_compiler_options *)
screen->get_compiler_options(screen, PIPE_SHADER_IR_NIR, sh);
if (!options->NirOptions) {
options->NirOptions =
nir_to_tgsi_get_compiler_options(screen, PIPE_SHADER_IR_NIR, sh);
}
const gl_shader_stage stage = tgsi_processor_to_shader_stage(sh);
pc = &c->Program[stage];
options = &c->ShaderCompilerOptions[stage];
c->ShaderCompilerOptions[stage].NirOptions = nir_options;
if (sh == PIPE_SHADER_COMPUTE) {
if (!screen->get_param(screen, PIPE_CAP_COMPUTE))
continue;
@ -325,15 +324,6 @@ void st_init_limits(struct pipe_screen *screen,
screen->get_shader_param(screen, sh,
PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
/* If we're using NIR, then leave GLSL loop handling to NIR. If we set
* this flag, then GLSL jump lowering will turn the breaks into something
* that GLSL loop unrolling can't handle, and then you get linker failures
* about samplers with non-const indexes in loops that should be unrollable.
*/
options->EmitNoLoops = !prefer_nir &&
!screen->get_shader_param(screen, sh,
PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
options->EmitNoMainReturn =
!screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
@ -372,11 +362,6 @@ void st_init_limits(struct pipe_screen *screen,
if (!screen->get_param(screen, PIPE_CAP_NIR_COMPACT_ARRAYS))
options->LowerCombinedClipCullDistance = true;
/* NIR can do the lowering on our behalf and we'll get better results
* because it can actually optimize SSBO access.
*/
options->LowerBufferInterfaceBlocks = !prefer_nir;
if (sh == PIPE_SHADER_VERTEX || sh == PIPE_SHADER_GEOMETRY) {
if (screen->get_param(screen, PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED))
options->LowerBuiltinVariablesXfb |= VARYING_BIT_POS;
@ -384,6 +369,9 @@ void st_init_limits(struct pipe_screen *screen,
options->LowerBuiltinVariablesXfb |= VARYING_BIT_PSIZ;
}
/* Note: If the driver doesn't prefer NIR, then st_create_nir_shader()
* will call nir_to_tgsi, and TGSI doesn't support 16-bit ops.
*/
if (prefer_nir) {
options->LowerPrecisionFloat16 =
screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_FP16);

View file

@ -30,7 +30,6 @@
#include "st_nir.h"
#include "st_shader_cache.h"
#include "st_glsl_to_tgsi.h"
#include "st_program.h"
#include "tgsi/tgsi_from_mesa.h"
@ -42,13 +41,8 @@ link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
struct st_context *sctx = st_context(ctx);
struct pipe_screen *pscreen = sctx->screen;
enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_PREFERRED_IR);
bool use_nir = preferred_ir == PIPE_SHADER_IR_NIR;
/* Return early if we are loading the shader from on-disk cache */
if (st_load_ir_from_disk_cache(ctx, prog, use_nir)) {
if (st_load_ir_from_disk_cache(ctx, prog, true)) {
return GL_TRUE;
}
@ -56,7 +50,6 @@ link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
/* Skip the GLSL steps when using SPIR-V. */
if (prog->data->spirv) {
assert(use_nir);
return st_link_nir(ctx, prog);
}
@ -70,19 +63,6 @@ link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
const struct gl_shader_compiler_options *options =
&ctx->Const.ShaderCompilerOptions[stage];
/* If there are forms of indirect addressing that the driver
* cannot handle, perform the lowering pass.
*/
if (!use_nir &&
(options->EmitNoIndirectInput || options->EmitNoIndirectOutput ||
options->EmitNoIndirectTemp || options->EmitNoIndirectUniform)) {
lower_variable_index_to_cond_assign(stage, ir,
options->EmitNoIndirectInput,
options->EmitNoIndirectOutput,
options->EmitNoIndirectTemp,
options->EmitNoIndirectUniform);
}
enum pipe_shader_type ptarget = pipe_shader_type_from_mesa(stage);
bool have_dround = pscreen->get_shader_param(pscreen, ptarget,
PIPE_SHADER_CAP_DROUND_SUPPORTED);
@ -123,7 +103,6 @@ link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
shader, ctx->Extensions.KHR_blend_equation_advanced_coherent);
lower_instructions(ir,
(use_nir ? 0 : MOD_TO_FLOOR) |
FDIV_TO_MUL_RCP |
EXP_TO_EXP2 |
LOG_TO_LOG2 |
@ -161,12 +140,9 @@ link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
validate_ir_tree(ir);
}
build_program_resource_list(&ctx->Const, prog, use_nir);
build_program_resource_list(&ctx->Const, prog, true);
if (use_nir)
ret = st_link_nir(ctx, prog);
else
ret = st_link_tgsi(ctx, prog);
ret = st_link_nir(ctx, prog);
return ret;
}
@ -176,8 +152,6 @@ extern "C" {
/**
* Link a shader.
* Called via ctx->Driver.LinkShader()
* This is a shared function that branches off to either GLSL IR -> TGSI or
* GLSL IR -> NIR
*/
GLboolean
st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)