i915: rework shader compile failures reporting

Report compile errors from create_fs_state instead of finalize_nir.
The current way is broken, since nir_to_tgsi is called in finalize_nir,
however it can't handle lowered IO.

Fixes: dae57e184a
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/12373
Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33341>
(cherry picked from commit 4d4a3a6d6b)
This commit is contained in:
Pavel Ondračka 2025-01-28 20:00:33 +01:00 committed by Eric Engestrom
parent ef741dad68
commit 90c4d44969
3 changed files with 48 additions and 72 deletions

View file

@ -74,7 +74,7 @@
"description": "i915: rework shader compile failures reporting",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "dae57e184aafdd7da562cb3120d530504a2426fc",
"notes": null

View file

@ -227,31 +227,6 @@ i915_optimize_nir(struct nir_shader *s)
NIR_PASS_V(s, nir_group_loads, nir_group_all, ~0);
}
static char *
i915_check_control_flow(nir_shader *s)
{
if (s->info.stage == MESA_SHADER_FRAGMENT) {
nir_function_impl *impl = nir_shader_get_entrypoint(s);
nir_block *first = nir_start_block(impl);
nir_cf_node *next = nir_cf_node_next(&first->cf_node);
if (next) {
switch (next->type) {
case nir_cf_node_if:
return "if/then statements not supported by i915 fragment shaders, "
"should have been flattened by peephole_select.";
case nir_cf_node_loop:
return "looping not supported i915 fragment shaders, all loops "
"must be statically unrollable.";
default:
return "Unknown control flow type";
}
}
}
return NULL;
}
static char *
i915_finalize_nir(struct pipe_screen *pscreen, struct nir_shader *s)
{
@ -275,20 +250,7 @@ i915_finalize_nir(struct pipe_screen *pscreen, struct nir_shader *s)
nir_validate_shader(s, "after uniform var removal");
nir_sweep(s);
char *msg = i915_check_control_flow(s);
if (msg) {
if (I915_DBG_ON(DBG_FS) && (!s->info.internal || NIR_DEBUG(PRINT_INTERNAL))) {
mesa_logi("failing shader:");
nir_log_shaderi(s);
}
return strdup(msg);
}
if (s->info.stage == MESA_SHADER_FRAGMENT)
return i915_test_fragment_shader_compile(pscreen, s);
else
return NULL;
return NULL;
}
static int
@ -412,7 +374,6 @@ i915_init_screen_caps(struct i915_screen *is)
caps->user_vertex_buffers = true;
caps->mixed_color_depth_bits = true;
caps->tgsi_texcoord = true;
caps->call_finalize_nir_in_linker = true;
caps->texture_transfer_modes =
caps->pci_group =

View file

@ -40,12 +40,15 @@
#include "nir.h"
#include "i915_context.h"
#include "i915_debug.h"
#include "i915_fpc.h"
#include "i915_reg.h"
#include "i915_resource.h"
#include "i915_state.h"
#include "i915_state_inlines.h"
static void i915_delete_fs_state(struct pipe_context *pipe, void *shader);
/* The i915 (and related graphics cores) do not support GL_CLAMP. The
* Intel drivers for "other operating systems" implement GL_CLAMP as
* GL_CLAMP_TO_EDGE, so the same is done here.
@ -538,6 +541,29 @@ static const struct nir_to_tgsi_options ntt_options = {
.lower_fabs = true,
};
static char *
i915_check_control_flow(nir_shader *s)
{
nir_function_impl *impl = nir_shader_get_entrypoint(s);
nir_block *first = nir_start_block(impl);
nir_cf_node *next = nir_cf_node_next(&first->cf_node);
if (next) {
switch (next->type) {
case nir_cf_node_if:
return "if/then statements not supported by i915 fragment shaders, "
"should have been flattened by peephole_select.";
case nir_cf_node_loop:
return "looping not supported i915 fragment shaders, all loops "
"must be statically unrollable.";
default:
return "Unknown control flow type";
}
}
return NULL;
}
static void *
i915_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
@ -553,6 +579,21 @@ i915_create_fs_state(struct pipe_context *pipe,
nir_shader *s = templ->ir.nir;
ifs->internal = s->info.internal;
char *msg = i915_check_control_flow(s);
if (msg) {
if (I915_DBG_ON(DBG_FS) &&
(!s->info.internal || NIR_DEBUG(PRINT_INTERNAL))) {
mesa_logi("failing shader:");
nir_log_shaderi(s);
}
if (templ->report_compile_error) {
((struct pipe_shader_state *)templ)->error_message = strdup(msg);
ralloc_free(s);
i915_delete_fs_state(NULL, ifs);
return NULL;
}
}
ifs->state.tokens = nir_to_tgsi_options(s, pipe->screen, &ntt_options);
} else {
assert(templ->type == PIPE_SHADER_IR_TGSI);
@ -567,6 +608,11 @@ i915_create_fs_state(struct pipe_context *pipe,
/* The shader's compiled to i915 instructions here */
i915_translate_fragment_program(i915, ifs);
if (ifs->error && templ->report_compile_error) {
((struct pipe_shader_state *)templ)->error_message = strdup(ifs->error);
i915_delete_fs_state(NULL, ifs);
return NULL;
}
return ifs;
}
@ -607,37 +653,6 @@ i915_delete_fs_state(struct pipe_context *pipe, void *shader)
FREE(ifs);
}
/* Does a test compile at link time to see if we'll be able to run this shader
* at runtime. Return a string to the GLSL compiler for anything we should
* report as link failure.
*/
char *
i915_test_fragment_shader_compile(struct pipe_screen *screen, nir_shader *s)
{
struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader);
if (!ifs)
return NULL;
/* NTT takes ownership of the shader, give it a clone. */
s = nir_shader_clone(NULL, s);
ifs->internal = s->info.internal;
ifs->state.tokens = nir_to_tgsi_options(s, screen, &ntt_options);
ifs->state.type = PIPE_SHADER_IR_TGSI;
tgsi_scan_shader(ifs->state.tokens, &ifs->info);
i915_translate_fragment_program(NULL, ifs);
char *msg = NULL;
if (ifs->error)
msg = strdup(ifs->error);
i915_delete_fs_state(NULL, ifs);
return msg;
}
static void *
i915_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)