diff --git a/.pick_status.json b/.pick_status.json index 65a30010576..e6b4e7aa53b 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 7d7a20eeb4a..5ff17e4e28f 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -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 = diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index f1daa7e60a9..b12cf3dac1e 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -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)