mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
mesa/st: Add an optional GLSL link fail msg to finalize_nir.
GLES2 drivers are allowed to reject some GLSL constructs, like dynamic loop bounds (which neither i915g nor vc4 can fully support), but gallium hasn't had any way to trigger a link failure. Add a return msg to the finalize_nir hook, which is called at the end of GLSL linking, and use that. This means that some other callers of finalize need to do something with the msg, and we (for now) just throw it away. Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12218>
This commit is contained in:
parent
1b4b9a9eff
commit
17332ceb0f
17 changed files with 69 additions and 37 deletions
|
|
@ -414,12 +414,12 @@ dd_screen_memobj_destroy(struct pipe_screen *_screen,
|
|||
* screen
|
||||
*/
|
||||
|
||||
static void
|
||||
static char *
|
||||
dd_screen_finalize_nir(struct pipe_screen *_screen, void *nir)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
screen->finalize_nir(screen, nir);
|
||||
return screen->finalize_nir(screen, nir);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -599,11 +599,11 @@ static const void *noop_get_compiler_options(struct pipe_screen *pscreen,
|
|||
return screen->get_compiler_options(screen, ir, shader);
|
||||
}
|
||||
|
||||
static void noop_finalize_nir(struct pipe_screen *pscreen, void *nir)
|
||||
static char *noop_finalize_nir(struct pipe_screen *pscreen, void *nir)
|
||||
{
|
||||
struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen;
|
||||
|
||||
screen->finalize_nir(screen, nir);
|
||||
return screen->finalize_nir(screen, nir);
|
||||
}
|
||||
|
||||
static bool noop_check_resource_capability(struct pipe_screen *screen,
|
||||
|
|
|
|||
|
|
@ -410,12 +410,12 @@ rbug_screen_fence_get_fd(struct pipe_screen *_screen,
|
|||
return screen->fence_get_fd(screen, fence);
|
||||
}
|
||||
|
||||
static void
|
||||
static char *
|
||||
rbug_screen_finalize_nir(struct pipe_screen *_screen, void *nir)
|
||||
{
|
||||
struct pipe_screen *screen = rbug_screen(_screen)->screen;
|
||||
|
||||
screen->finalize_nir(screen, nir);
|
||||
return screen->finalize_nir(screen, nir);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -919,12 +919,12 @@ trace_screen_get_timestamp(struct pipe_screen *_screen)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
static char *
|
||||
trace_screen_finalize_nir(struct pipe_screen *_screen, void *nir)
|
||||
{
|
||||
struct pipe_screen *screen = trace_screen(_screen)->screen;
|
||||
|
||||
screen->finalize_nir(screen, nir);
|
||||
return screen->finalize_nir(screen, nir);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -2486,7 +2486,8 @@ ttn_finalize_nir(struct ttn_compile *c, struct pipe_screen *screen)
|
|||
NIR_PASS_V(nir, nir_lower_samplers);
|
||||
|
||||
if (screen->finalize_nir) {
|
||||
screen->finalize_nir(screen, nir);
|
||||
char *msg = screen->finalize_nir(screen, nir);
|
||||
free(msg);
|
||||
} else {
|
||||
ttn_optimize_nir(nir);
|
||||
nir_shader_gather_info(nir, c->build.impl);
|
||||
|
|
|
|||
|
|
@ -462,13 +462,15 @@ ir3_fixup_shader_state(struct pipe_context *pctx, struct ir3_shader_key *key)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static char *
|
||||
ir3_screen_finalize_nir(struct pipe_screen *pscreen, void *nir)
|
||||
{
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
|
||||
ir3_nir_lower_io_to_temporaries(nir);
|
||||
ir3_finalize_nir(screen->compiler, nir);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ i915_optimize_nir(struct nir_shader *s)
|
|||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
static char *
|
||||
i915_finalize_nir(struct pipe_screen *pscreen, void *nir)
|
||||
{
|
||||
nir_shader *s = nir;
|
||||
|
|
@ -237,6 +237,8 @@ i915_finalize_nir(struct pipe_screen *pscreen, void *nir)
|
|||
nir_validate_shader(s, "after uniform var removal");
|
||||
|
||||
nir_sweep(s);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -601,12 +601,13 @@ static const struct nir_shader_compiler_options gallivm_nir_options = {
|
|||
.lower_fisnormal = true,
|
||||
};
|
||||
|
||||
static void
|
||||
static char *
|
||||
llvmpipe_finalize_nir(struct pipe_screen *screen,
|
||||
void *nirptr)
|
||||
{
|
||||
struct nir_shader *nir = (struct nir_shader *)nirptr;
|
||||
lp_build_opt_nir(nir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline const void *
|
||||
|
|
|
|||
|
|
@ -887,7 +887,7 @@ struct si_shader *si_generate_gs_copy_shader(struct si_screen *sscreen,
|
|||
void si_nir_scan_shader(const struct nir_shader *nir, struct si_shader_info *info);
|
||||
void si_nir_opts(struct si_screen *sscreen, struct nir_shader *nir, bool first);
|
||||
void si_nir_late_opts(nir_shader *nir);
|
||||
void si_finalize_nir(struct pipe_screen *screen, void *nirptr);
|
||||
char *si_finalize_nir(struct pipe_screen *screen, void *nirptr);
|
||||
|
||||
/* si_state_shaders.c */
|
||||
void gfx9_get_gs_info(struct si_shader_selector *es, struct si_shader_selector *gs,
|
||||
|
|
|
|||
|
|
@ -903,7 +903,7 @@ static void si_lower_nir(struct si_screen *sscreen, struct nir_shader *nir)
|
|||
NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_function_temp, NULL);
|
||||
}
|
||||
|
||||
void si_finalize_nir(struct pipe_screen *screen, void *nirptr)
|
||||
char *si_finalize_nir(struct pipe_screen *screen, void *nirptr)
|
||||
{
|
||||
struct si_screen *sscreen = (struct si_screen *)screen;
|
||||
struct nir_shader *nir = (struct nir_shader *)nirptr;
|
||||
|
|
@ -914,4 +914,6 @@ void si_finalize_nir(struct pipe_screen *screen, void *nirptr)
|
|||
|
||||
if (sscreen->options.inline_uniforms)
|
||||
nir_find_inlinable_uniforms(nir);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1103,7 +1103,7 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
char *
|
||||
zink_shader_finalize(struct pipe_screen *pscreen, void *nirptr)
|
||||
{
|
||||
struct zink_screen *screen = zink_screen(pscreen);
|
||||
|
|
@ -1123,6 +1123,8 @@ zink_shader_finalize(struct pipe_screen *pscreen, void *nirptr)
|
|||
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
|
||||
if (screen->driconf.inline_uniforms)
|
||||
nir_find_inlinable_uniforms(nir);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ struct zink_shader *
|
|||
zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
|
||||
const struct pipe_stream_output_info *so_info);
|
||||
|
||||
void
|
||||
char *
|
||||
zink_shader_finalize(struct pipe_screen *pscreen, void *nirptr);
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -520,8 +520,11 @@ struct pipe_screen {
|
|||
*
|
||||
* gallium frontends should call this before passing shaders to drivers,
|
||||
* and ideally also before shader caching.
|
||||
*
|
||||
* The driver may return a non-NULL string to trigger GLSL link failure and
|
||||
* logging of that message in the GLSL linker log.
|
||||
*/
|
||||
void (*finalize_nir)(struct pipe_screen *screen, void *nir);
|
||||
char *(*finalize_nir)(struct pipe_screen *screen, void *nir);
|
||||
|
||||
/*Separated memory/resource allocations interfaces for Vulkan */
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "compiler/glsl/gl_nir_linker.h"
|
||||
#include "compiler/glsl/ir.h"
|
||||
#include "compiler/glsl/ir_optimization.h"
|
||||
#include "compiler/glsl/linker_util.h"
|
||||
#include "compiler/glsl/string_to_uint_map.h"
|
||||
|
||||
static int
|
||||
|
|
@ -468,7 +469,7 @@ filter_64_bit_instr(const nir_instr *const_instr, UNUSED const void *data)
|
|||
/* Second third of converting glsl_to_nir. This creates uniforms, gathers
|
||||
* info on varyings, etc after NIR link time opts have been applied.
|
||||
*/
|
||||
static void
|
||||
static char *
|
||||
st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog,
|
||||
struct gl_shader_program *shader_program)
|
||||
{
|
||||
|
|
@ -572,8 +573,9 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog,
|
|||
|
||||
st_finalize_nir_before_variants(nir);
|
||||
|
||||
char *msg = NULL;
|
||||
if (st->allow_st_finalize_nir_twice)
|
||||
st_finalize_nir(st, prog, shader_program, nir, true, true);
|
||||
msg = st_finalize_nir(st, prog, shader_program, nir, true, true);
|
||||
|
||||
if (st->ctx->_Shader->Flags & GLSL_DUMP) {
|
||||
_mesa_log("\n");
|
||||
|
|
@ -583,6 +585,8 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog,
|
|||
nir_print_shader(nir, _mesa_get_log_file());
|
||||
_mesa_log("\n\n");
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -890,7 +894,11 @@ st_link_nir(struct gl_context *ctx,
|
|||
struct gl_linked_shader *shader = linked_shader[i];
|
||||
struct shader_info *info = &shader->Program->nir->info;
|
||||
|
||||
st_glsl_to_nir_post_opts(st, shader->Program, shader_program);
|
||||
char *msg = st_glsl_to_nir_post_opts(st, shader->Program, shader_program);
|
||||
if (msg) {
|
||||
linker_error(shader_program, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (prev_info &&
|
||||
ctx->Const.ShaderCompilerOptions[shader->Stage].NirOptions->unify_interfaces) {
|
||||
|
|
@ -1032,7 +1040,7 @@ st_nir_lower_uniforms(struct st_context *st, nir_shader *nir)
|
|||
/* Last third of preparing nir from glsl, which happens after shader
|
||||
* variant lowering.
|
||||
*/
|
||||
void
|
||||
char *
|
||||
st_finalize_nir(struct st_context *st, struct gl_program *prog,
|
||||
struct gl_shader_program *shader_program,
|
||||
nir_shader *nir, bool finalize_by_driver,
|
||||
|
|
@ -1071,8 +1079,11 @@ st_finalize_nir(struct st_context *st, struct gl_program *prog,
|
|||
if (!screen->get_param(screen, PIPE_CAP_NIR_IMAGES_AS_DEREF))
|
||||
NIR_PASS_V(nir, gl_nir_lower_images, false);
|
||||
|
||||
char *msg = NULL;
|
||||
if (finalize_by_driver && screen->finalize_nir)
|
||||
screen->finalize_nir(screen, nir);
|
||||
msg = screen->finalize_nir(screen, nir);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@ void st_nir_lower_wpos_ytransform(struct nir_shader *nir,
|
|||
struct gl_program *prog,
|
||||
struct pipe_screen *pscreen);
|
||||
|
||||
void st_finalize_nir(struct st_context *st, struct gl_program *prog,
|
||||
struct gl_shader_program *shader_program,
|
||||
struct nir_shader *nir, bool finalize_by_driver,
|
||||
bool is_before_variants);
|
||||
char *st_finalize_nir(struct st_context *st, struct gl_program *prog,
|
||||
struct gl_shader_program *shader_program,
|
||||
struct nir_shader *nir, bool finalize_by_driver,
|
||||
bool is_before_variants);
|
||||
|
||||
void st_nir_opts(struct nir_shader *nir);
|
||||
|
||||
|
|
|
|||
|
|
@ -68,10 +68,12 @@ st_nir_finish_builtin_shader(struct st_context *st,
|
|||
if (!screen->get_param(screen, PIPE_CAP_NIR_IMAGES_AS_DEREF))
|
||||
NIR_PASS_V(nir, gl_nir_lower_images, false);
|
||||
|
||||
if (screen->finalize_nir)
|
||||
screen->finalize_nir(screen, nir);
|
||||
else
|
||||
if (screen->finalize_nir) {
|
||||
char *msg = screen->finalize_nir(screen, nir);
|
||||
free(msg);
|
||||
} else {
|
||||
st_nir_opts(nir);
|
||||
}
|
||||
|
||||
struct pipe_shader_state state = {
|
||||
.type = PIPE_SHADER_IR_NIR,
|
||||
|
|
|
|||
|
|
@ -390,8 +390,10 @@ st_prog_to_nir_postprocess(struct st_context *st, nir_shader *nir,
|
|||
st_nir_opts(nir);
|
||||
st_finalize_nir_before_variants(nir);
|
||||
|
||||
if (st->allow_st_finalize_nir_twice)
|
||||
st_finalize_nir(st, prog, NULL, nir, true, true);
|
||||
if (st->allow_st_finalize_nir_twice) {
|
||||
char *msg = st_finalize_nir(st, prog, NULL, nir, true, true);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
nir_validate_shader(nir, "after st/glsl finalize_nir");
|
||||
}
|
||||
|
|
@ -828,8 +830,9 @@ st_create_common_variant(struct st_context *st,
|
|||
}
|
||||
|
||||
if (finalize || !st->allow_st_finalize_nir_twice) {
|
||||
st_finalize_nir(st, &stp->Base, stp->shader_program, state.ir.nir,
|
||||
true, false);
|
||||
char *msg = st_finalize_nir(st, &stp->Base, stp->shader_program, state.ir.nir,
|
||||
true, false);
|
||||
free(msg);
|
||||
|
||||
/* Clip lowering and edgeflags may have introduced new varyings, so
|
||||
* update the inputs_read/outputs_written. However, with
|
||||
|
|
@ -1491,8 +1494,9 @@ st_create_fp_variant(struct st_context *st,
|
|||
}
|
||||
|
||||
if (finalize || !st->allow_st_finalize_nir_twice) {
|
||||
st_finalize_nir(st, &stfp->Base, stfp->shader_program, state.ir.nir,
|
||||
false, false);
|
||||
char *msg = st_finalize_nir(st, &stfp->Base, stfp->shader_program, state.ir.nir,
|
||||
false, false);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
/* This pass needs to happen *after* nir_lower_sampler */
|
||||
|
|
@ -1511,8 +1515,10 @@ st_create_fp_variant(struct st_context *st,
|
|||
nir_shader_get_entrypoint(state.ir.nir));
|
||||
|
||||
struct pipe_screen *screen = st->screen;
|
||||
if (screen->finalize_nir)
|
||||
screen->finalize_nir(screen, state.ir.nir);
|
||||
if (screen->finalize_nir) {
|
||||
char *msg = screen->finalize_nir(screen, state.ir.nir);
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
variant->base.driver_shader = st_create_nir_shader(st, &state);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue