From cbfc225e2bda2c8627a4580fa3a9b63bfb7133e0 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 5 Jun 2024 15:42:07 +1000 Subject: [PATCH] glsl: switch to a full nir based linker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit does 3 things at once (3 squashed commits) as required to make sure the commit doesn't break things. 1. convert to nir at compile time 2. enable full nir linking 3. switch standalone compiler to nir linker Acked-by: Marek Olšák Part-of: --- src/compiler/glsl/gl_nir_link_varyings.c | 2 +- src/compiler/glsl/gl_nir_linker.c | 191 ++++++++++++++++-- src/compiler/glsl/glsl_parser_extras.cpp | 49 ++++- src/compiler/glsl/glsl_to_nir.cpp | 10 +- src/compiler/glsl/meson.build | 2 +- src/compiler/glsl/program.h | 3 +- src/compiler/glsl/shader_cache.cpp | 3 +- src/compiler/glsl/standalone.cpp | 23 ++- src/compiler/glsl/standalone_scaffolding.cpp | 10 +- .../glsl/tests/test_gl_lower_mediump.cpp | 36 ++-- .../drivers/freedreno/ir3/ir3_cmdline.c | 16 +- src/mesa/main/shaderapi.c | 21 +- src/mesa/state_tracker/st_glsl_to_nir.cpp | 39 +--- 13 files changed, 272 insertions(+), 133 deletions(-) diff --git a/src/compiler/glsl/gl_nir_link_varyings.c b/src/compiler/glsl/gl_nir_link_varyings.c index 2f4e4fb2c6b..36e370a72ab 100644 --- a/src/compiler/glsl/gl_nir_link_varyings.c +++ b/src/compiler/glsl/gl_nir_link_varyings.c @@ -626,7 +626,7 @@ resize_tes_inputs(const struct gl_constants *consts, * known until draw time. */ const int num_vertices = tcs - ? tcs->Program->info.tess.tcs_vertices_out + ? tcs->Program->nir->info.tess.tcs_vertices_out : consts->MaxPatchVertices; resize_input_array(tes->Program->nir, prog, MESA_SHADER_TESS_EVAL, diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index d4e83107c64..4304fd421bf 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -332,7 +332,7 @@ validate_geometry_shader_emissions(const struct gl_constants *consts, * stream. */ if (sh->Program->nir->info.gs.active_stream_mask & ~(1 << 0) && - sh->Program->info.gs.output_primitive != MESA_PRIM_POINTS) { + sh->Program->nir->info.gs.output_primitive != MESA_PRIM_POINTS) { linker_error(prog, "EmitStreamVertex(n) and EndStreamPrimitive(n) " "with n>0 requires point output\n"); } @@ -1319,9 +1319,10 @@ preprocess_shader(const struct gl_constants *consts, assert(options); nir_shader *nir = prog->nir; + nir_shader_gather_info(prog->nir, nir_shader_get_entrypoint(prog->nir)); if (prog->info.stage == MESA_SHADER_FRAGMENT && consts->HasFBFetch) { - nir_shader_gather_info(prog->nir, nir_shader_get_entrypoint(prog->nir)); + NIR_PASS(_, prog->nir, gl_nir_lower_blend_equation_advanced, exts->KHR_blend_equation_advanced_coherent); nir_lower_global_vars_to_local(prog->nir); @@ -3678,6 +3679,140 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) MESA_TRACE_FUNC(); + void *mem_ctx = ralloc_context(NULL); /* temporary linker context */ + + /* Separate the shaders into groups based on their type. + */ + struct gl_shader **shader_list[MESA_SHADER_STAGES]; + unsigned num_shaders[MESA_SHADER_STAGES]; + + for (int i = 0; i < MESA_SHADER_STAGES; i++) { + shader_list[i] = (struct gl_shader **) + calloc(prog->NumShaders, sizeof(struct gl_shader *)); + num_shaders[i] = 0; + } + + unsigned min_version = UINT_MAX; + unsigned max_version = 0; + for (unsigned i = 0; i < prog->NumShaders; i++) { + min_version = MIN2(min_version, prog->Shaders[i]->Version); + max_version = MAX2(max_version, prog->Shaders[i]->Version); + + if (!consts->AllowGLSLRelaxedES && + prog->Shaders[i]->IsES != prog->Shaders[0]->IsES) { + linker_error(prog, "all shaders must use same shading " + "language version\n"); + goto done; + } + + gl_shader_stage shader_type = prog->Shaders[i]->Stage; + shader_list[shader_type][num_shaders[shader_type]] = prog->Shaders[i]; + num_shaders[shader_type]++; + } + + /* In desktop GLSL, different shader versions may be linked together. In + * GLSL ES, all shader versions must be the same. + */ + if (!consts->AllowGLSLRelaxedES && prog->Shaders[0]->IsES && + min_version != max_version) { + linker_error(prog, "all shaders must use same shading " + "language version\n"); + goto done; + } + + prog->GLSL_Version = max_version; + prog->IsES = prog->Shaders[0]->IsES; + + /* Some shaders have to be linked with some other shaders present. + */ + if (!prog->SeparateShader) { + if (num_shaders[MESA_SHADER_GEOMETRY] > 0 && + num_shaders[MESA_SHADER_VERTEX] == 0) { + linker_error(prog, "Geometry shader must be linked with " + "vertex shader\n"); + goto done; + } + if (num_shaders[MESA_SHADER_TESS_EVAL] > 0 && + num_shaders[MESA_SHADER_VERTEX] == 0) { + linker_error(prog, "Tessellation evaluation shader must be linked " + "with vertex shader\n"); + goto done; + } + if (num_shaders[MESA_SHADER_TESS_CTRL] > 0 && + num_shaders[MESA_SHADER_VERTEX] == 0) { + linker_error(prog, "Tessellation control shader must be linked with " + "vertex shader\n"); + goto done; + } + + /* Section 7.3 of the OpenGL ES 3.2 specification says: + * + * "Linking can fail for [...] any of the following reasons: + * + * * program contains an object to form a tessellation control + * shader [...] and [...] the program is not separable and + * contains no object to form a tessellation evaluation shader" + * + * The OpenGL spec is contradictory. It allows linking without a tess + * eval shader, but that can only be used with transform feedback and + * rasterization disabled. However, transform feedback isn't allowed + * with GL_PATCHES, so it can't be used. + * + * More investigation showed that the idea of transform feedback after + * a tess control shader was dropped, because some hw vendors couldn't + * support tessellation without a tess eval shader, but the linker + * section wasn't updated to reflect that. + * + * All specifications (ARB_tessellation_shader, GL 4.0-4.5) have this + * spec bug. + * + * Do what's reasonable and always require a tess eval shader if a tess + * control shader is present. + */ + if (num_shaders[MESA_SHADER_TESS_CTRL] > 0 && + num_shaders[MESA_SHADER_TESS_EVAL] == 0) { + linker_error(prog, "Tessellation control shader must be linked with " + "tessellation evaluation shader\n"); + goto done; + } + + if (prog->IsES) { + if (num_shaders[MESA_SHADER_TESS_EVAL] > 0 && + num_shaders[MESA_SHADER_TESS_CTRL] == 0) { + linker_error(prog, "GLSL ES requires non-separable programs " + "containing a tessellation evaluation shader to also " + "be linked with a tessellation control shader\n"); + goto done; + } + } + } + + /* Compute shaders have additional restrictions. */ + if (num_shaders[MESA_SHADER_COMPUTE] > 0 && + num_shaders[MESA_SHADER_COMPUTE] != prog->NumShaders) { + linker_error(prog, "Compute shaders may not be linked with any other " + "type of shader\n"); + } + + /* Link all shaders for a particular stage and validate the result. + */ + for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) { + if (num_shaders[stage] > 0) { + struct gl_linked_shader *const sh = + link_intrastage_shaders(mem_ctx, ctx, prog, shader_list[stage], + num_shaders[stage]); + + if (!prog->data->LinkStatus) { + if (sh) + _mesa_delete_linked_shader(ctx, sh); + goto done; + } + + prog->_LinkedShaders[stage] = sh; + prog->data->linked_stages |= 1 << stage; + } + } + /* Link all shaders for a particular stage and validate the result. */ for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) { @@ -3685,6 +3820,11 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) if (sh) { nir_shader *shader = sh->Program->nir; + /* Parameters will be filled during NIR linking. */ + sh->Program->Parameters = _mesa_new_parameter_list(); + sh->Program->shader_program = prog; + shader->info.separate_shader = prog->SeparateShader; + switch (stage) { case MESA_SHADER_VERTEX: validate_vertex_shader_executable(prog, shader, consts); @@ -3708,7 +3848,7 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) prog->_LinkedShaders[stage] = NULL; prog->data->linked_stages ^= 1 << stage; - return false; + goto done; } } } @@ -3719,14 +3859,14 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) */ cross_validate_uniforms(consts, prog); if (!prog->data->LinkStatus) - return false; + goto done; check_explicit_uniform_locations(exts, prog); link_assign_subroutine_types(prog); verify_subroutine_associated_funcs(prog); if (!prog->data->LinkStatus) - return false; + goto done; for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) @@ -3735,7 +3875,7 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) gl_nir_detect_recursion_linked(prog, prog->_LinkedShaders[i]->Program->nir); if (!prog->data->LinkStatus) - return false; + goto done; gl_nir_inline_functions(prog->_LinkedShaders[i]->Program->nir); } @@ -3759,7 +3899,7 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) gl_nir_validate_interstage_inout_blocks(prog, prog->_LinkedShaders[prev], prog->_LinkedShaders[i]); if (!prog->data->LinkStatus) - return false; + goto done; prev = i; } @@ -3767,13 +3907,13 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) /* Cross-validate uniform blocks between shader stages */ gl_nir_validate_interstage_uniform_blocks(prog, prog->_LinkedShaders); if (!prog->data->LinkStatus) - return false; + goto done; if (prog->IsES && prog->GLSL_Version == 100) if (!validate_invariant_builtins(consts, prog, prog->_LinkedShaders[MESA_SHADER_VERTEX], prog->_LinkedShaders[MESA_SHADER_FRAGMENT])) - return false; + goto done; /* Check and validate stream emissions in geometry shaders */ validate_geometry_shader_emissions(consts, prog); @@ -3822,7 +3962,7 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) prog->_LinkedShaders[prev], prog->_LinkedShaders[i]); if (!prog->data->LinkStatus) - return false; + goto done; prev = i; } @@ -3840,11 +3980,11 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) disable_varying_optimizations_for_sso(prog); struct gl_linked_shader *linked_shader[MESA_SHADER_STAGES]; - unsigned num_shaders = 0; + unsigned num_linked_shaders = 0; for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i]) { - linked_shader[num_shaders++] = prog->_LinkedShaders[i]; + linked_shader[num_linked_shaders++] = prog->_LinkedShaders[i]; /* Section 13.46 (Vertex Attribute Aliasing) of the OpenGL ES 3.2 * specification says: @@ -3866,13 +4006,13 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) } if (!gl_assign_attribute_or_color_locations(consts, prog)) - return false; + goto done; - if (!prelink_lowering(consts, exts, prog, linked_shader, num_shaders)) - return false; + if (!prelink_lowering(consts, exts, prog, linked_shader, num_linked_shaders)) + goto done; if (!gl_nir_link_varyings(consts, exts, api, prog)) - return false; + goto done; /* Validation for special cases where we allow sampler array indexing * with loop induction variable. This check emits a warning or error @@ -3881,11 +4021,11 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) if ((!prog->IsES && prog->GLSL_Version < 130) || (prog->IsES && prog->GLSL_Version < 300)) { if (!validate_sampler_array_indexing(consts, prog)) - return false; + goto done; } if (prog->data->LinkStatus == LINKING_FAILURE) - return false; + goto done; if (!linked_shader[0]->Program->nir->info.io_lowered) { /* Linking the stages in the opposite order (from fragment to vertex) @@ -3893,7 +4033,7 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) * are eliminated if they are (transitively) not used in a later * stage. */ - for (int i = num_shaders - 2; i >= 0; i--) { + for (int i = num_linked_shaders - 2; i >= 0; i--) { gl_nir_link_opts(linked_shader[i]->Program->nir, linked_shader[i + 1]->Program->nir); } @@ -3903,7 +4043,7 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) * For example varying arrays that get packed may have dead elements that * can be now be eliminated now that array access has been lowered. */ - if (num_shaders == 1) + if (num_linked_shaders == 1) gl_nir_opts(linked_shader[0]->Program->nir); for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { @@ -3943,10 +4083,10 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) } if (!gl_nir_link_uniform_blocks(consts, prog)) - return false; + goto done; if (!gl_nir_link_uniforms(consts, prog, true)) - return false; + goto done; link_util_calculate_subroutine_compat(prog); link_util_check_uniform_resources(consts, prog); @@ -3990,6 +4130,13 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) } } +done: + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + free(shader_list[i]); + } + + ralloc_free(mem_ctx); + if (prog->data->LinkStatus == LINKING_FAILURE) return false; diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index c5de8ae17c9..70383ce9aa1 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -37,6 +37,7 @@ #include "ast.h" #include "glsl_parser_extras.h" #include "glsl_parser.h" +#include "glsl_to_nir.h" #include "ir_optimization.h" #include "builtin_functions.h" @@ -2330,9 +2331,19 @@ can_skip_compile(struct gl_context *ctx, struct gl_shader *shader, return false; } +static void +log_compile_skip(struct gl_context *ctx, struct gl_shader *shader) +{ + if (ctx->_Shader->Flags & GLSL_DUMP) { + _mesa_log("No GLSL IR for shader %d (shader may be from cache)\n", + shader->Name); + } +} + void _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, - bool dump_ast, bool dump_hir, bool force_recompile) + FILE *dump_ir_file, bool dump_ast, bool dump_hir, + bool force_recompile) { const char *source; const uint8_t *source_blake3; @@ -2358,8 +2369,10 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, */ if (!source_has_shader_include && can_skip_compile(ctx, shader, source, source_blake3, force_recompile, - false)) + false)) { + log_compile_skip(ctx, shader); return; + } struct _mesa_glsl_parse_state *state = new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader); @@ -2379,8 +2392,10 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, */ if (source_has_shader_include && can_skip_compile(ctx, shader, source, source_blake3, force_recompile, - true)) + true)) { + log_compile_skip(ctx, shader); return; + } if (!state->error) { _mesa_glsl_lexer_ctor(state, source); @@ -2459,9 +2474,35 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, delete state->symbols; ralloc_free(state); - if (shader->CompileStatus == COMPILE_SUCCESS) + if (ctx->_Shader && ctx->_Shader->Flags & GLSL_DUMP) { + if (shader->CompileStatus) { + assert(shader->ir); + _mesa_log("GLSL IR for shader %d:\n", shader->Name); + _mesa_print_ir(mesa_log_get_file(), shader->ir, NULL); + _mesa_log("\n\n"); + } else { + _mesa_log("GLSL shader %d failed to compile.\n", shader->Name); + } + if (shader->InfoLog && shader->InfoLog[0] != 0) { + _mesa_log("GLSL shader %d info log:\n", shader->Name); + _mesa_log("%s\n", shader->InfoLog); + } + } + + if (dump_ir_file) { + if (shader->CompileStatus) { + assert(shader->ir); + _mesa_print_ir(dump_ir_file, shader->ir, NULL); + } + } + + if (shader->CompileStatus == COMPILE_SUCCESS) { memcpy(shader->compiled_source_blake3, source_blake3, BLAKE3_OUT_LEN); + shader->nir = glsl_to_nir(&ctx->Const, &shader->ir, NULL, shader->Stage, + options->NirOptions, source_blake3); + } + if (ctx->Cache && shader->CompileStatus == COMPILE_SUCCESS) { char sha1_buf[41]; disk_cache_put_key(ctx->Cache, shader->disk_cache_sha1); diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 78114e48a65..49db6d17e01 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -2839,7 +2839,8 @@ glsl_float64_funcs_to_nir(struct gl_context *ctx, struct gl_shader *sh = _mesa_new_shader(-1, MESA_SHADER_VERTEX); sh->Source = float64_source; sh->CompileStatus = COMPILE_FAILURE; - _mesa_glsl_compile_shader(ctx, sh, false, false, true); + _mesa_glsl_compile_shader(ctx, sh, NULL, false, false, true); + nir_shader *nir = nir_shader_clone(NULL, sh->nir); if (!sh->CompileStatus) { if (sh->InfoLog) { @@ -2850,13 +2851,6 @@ glsl_float64_funcs_to_nir(struct gl_context *ctx, return NULL; } - nir_shader *nir = nir_shader_create(NULL, MESA_SHADER_VERTEX, options, NULL); - - nir_visitor v1(&ctx->Const, nir, NULL); - nir_function_visitor v2(&v1); - v2.run(sh->ir); - visit_exec_list(sh->ir, &v1); - /* _mesa_delete_shader will try to free sh->Source but it's static const */ sh->Source = NULL; _mesa_delete_shader(ctx, sh); diff --git a/src/compiler/glsl/meson.build b/src/compiler/glsl/meson.build index d49273c7670..aad204887ec 100644 --- a/src/compiler/glsl/meson.build +++ b/src/compiler/glsl/meson.build @@ -247,7 +247,7 @@ libglsl_standalone = static_library( gnu_symbol_visibility : 'hidden', include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux], link_with : [libglsl, libglsl_util, libglcpp_standalone], - dependencies : [idep_mesautil, idep_getopt, idep_compiler], + dependencies : [idep_mesautil, idep_getopt, idep_compiler, idep_nir], build_by_default : false, ) diff --git a/src/compiler/glsl/program.h b/src/compiler/glsl/program.h index 8429d08e6f4..37c02eba37d 100644 --- a/src/compiler/glsl/program.h +++ b/src/compiler/glsl/program.h @@ -35,7 +35,8 @@ struct gl_shader_program; extern void _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, - bool dump_ast, bool dump_hir, bool force_recompile); + FILE *dump_ir_file, bool dump_ast, bool dump_hir, + bool force_recompile); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp index d45b148a63a..e3d60557967 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp @@ -71,7 +71,8 @@ extern "C" { static void compile_shaders(struct gl_context *ctx, struct gl_shader_program *prog) { for (unsigned i = 0; i < prog->NumShaders; i++) { - _mesa_glsl_compile_shader(ctx, prog->Shaders[i], false, false, true); + _mesa_glsl_compile_shader(ctx, prog->Shaders[i], NULL, + false, false, true); } } diff --git a/src/compiler/glsl/standalone.cpp b/src/compiler/glsl/standalone.cpp index e0f4566a5e1..783f77993dd 100644 --- a/src/compiler/glsl/standalone.cpp +++ b/src/compiler/glsl/standalone.cpp @@ -36,7 +36,7 @@ #include "standalone_scaffolding.h" #include "standalone.h" #include "util/set.h" -#include "linker.h" +#include "gl_nir_linker.h" #include "glsl_parser_extras.h" #include "builtin_functions.h" #include "main/mtypes.h" @@ -44,6 +44,9 @@ static const struct standalone_options *options; +static const struct nir_shader_compiler_options nir_vs_options = { 0 }; +static const struct nir_shader_compiler_options nir_fs_options = { 0 }; + static void initialize_context(struct gl_context *ctx, gl_api api) { @@ -51,6 +54,10 @@ initialize_context(struct gl_context *ctx, gl_api api) _mesa_glsl_builtin_functions_init_or_ref(); ctx->Version = 450; + ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].NirOptions = + &nir_fs_options; + ctx->Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT].NirOptions = + &nir_vs_options; /* The standalone compiler needs to claim support for almost * everything in order to compile the built-in functions. @@ -305,15 +312,11 @@ load_text_file(void *ctx, const char *file_name) static void compile_shader(struct gl_context *ctx, struct gl_shader *shader) { - _mesa_glsl_compile_shader(ctx, shader, options->dump_ast, + /* Print out the resulting IR if requested */ + FILE *print_file = options->dump_lir ? stdout : NULL; + + _mesa_glsl_compile_shader(ctx, shader, print_file, options->dump_ast, options->dump_hir, true); - - /* Print out the resulting IR */ - if (shader->CompileStatus == COMPILE_SUCCESS && options->dump_lir) { - _mesa_print_ir(stdout, shader->ir, NULL); - } - - return; } extern "C" struct gl_shader_program * @@ -423,7 +426,9 @@ standalone_compile_shader(const struct standalone_options *_options, if (status == EXIT_SUCCESS && options->do_link) { _mesa_clear_shader_program_data(ctx, whole_program); + whole_program->data->LinkStatus = LINKING_SUCCESS; link_shaders(ctx, whole_program); + gl_nir_link_glsl(ctx, whole_program); status = (whole_program->data->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/src/compiler/glsl/standalone_scaffolding.cpp b/src/compiler/glsl/standalone_scaffolding.cpp index 6f0d23bef44..13f24ff8e2d 100644 --- a/src/compiler/glsl/standalone_scaffolding.cpp +++ b/src/compiler/glsl/standalone_scaffolding.cpp @@ -141,6 +141,7 @@ void _mesa_delete_linked_shader(struct gl_context *, struct gl_linked_shader *sh) { + ralloc_free(sh->Program->nir); ralloc_free(sh->Program); ralloc_free(sh); } @@ -315,9 +316,16 @@ standalone_create_shader_program(void) void standalone_destroy_shader_program(struct gl_shader_program *whole_program) { + for (unsigned i = 0; i < whole_program->NumShaders; i++) { + ralloc_free(whole_program->Shaders[i]->nir); + } + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - if (whole_program->_LinkedShaders[i]) + if (whole_program->_LinkedShaders[i]) { + if (whole_program->_LinkedShaders[i]->Program->Parameters) + _mesa_free_parameter_list(whole_program->_LinkedShaders[i]->Program->Parameters); _mesa_delete_linked_shader(NULL, whole_program->_LinkedShaders[i]); + } } delete whole_program->AttributeBindings; diff --git a/src/compiler/glsl/tests/test_gl_lower_mediump.cpp b/src/compiler/glsl/tests/test_gl_lower_mediump.cpp index 1ec2056404f..5ac66667b65 100644 --- a/src/compiler/glsl/tests/test_gl_lower_mediump.cpp +++ b/src/compiler/glsl/tests/test_gl_lower_mediump.cpp @@ -136,11 +136,8 @@ namespace } } - ralloc_free(whole_program->_LinkedShaders[MESA_SHADER_VERTEX]->Program->nir); standalone_destroy_shader_program(whole_program); - ralloc_free(nir); - free(fs_ir); glsl_type_singleton_decref(); @@ -151,7 +148,18 @@ namespace { struct gl_shader *shader = standalone_add_shader_source(ctx, whole_program, type, source); - _mesa_glsl_compile_shader(ctx, shader, false, false, true); + /* Save off the GLSL IR, since the compile frees it. */ + char temp[4096]; + FILE *ftemp = NULL; + if (type == GL_FRAGMENT_SHADER) + ftemp = fmemopen(temp, sizeof(temp), "w"); + + _mesa_glsl_compile_shader(ctx, shader, ftemp, false, false, true); + + if (type == GL_FRAGMENT_SHADER) { + fclose(ftemp); + fs_ir = strdup(temp); + } return shader; } @@ -205,29 +213,13 @@ namespace } link_shaders(ctx, whole_program); - if (whole_program->data->LinkStatus != LINKING_SUCCESS) - fprintf(stderr, "Linker error: %s", whole_program->data->InfoLog); - EXPECT_EQ(whole_program->data->LinkStatus, LINKING_SUCCESS); - - /* Save off the GLSL IR now, since glsl_to_nir() frees it. */ - fs_ir = get_fs_ir(); - - struct gl_linked_shader *sh = whole_program->_LinkedShaders[MESA_SHADER_VERTEX]; - sh->Program->nir = glsl_to_nir(&ctx->Const, &sh->ir, &sh->Program->info, - MESA_SHADER_VERTEX, &compiler_options, - NULL); - - sh = whole_program->_LinkedShaders[MESA_SHADER_FRAGMENT]; - sh->Program->nir = glsl_to_nir(&ctx->Const, &sh->ir, &sh->Program->info, - MESA_SHADER_FRAGMENT, &compiler_options, - NULL); - nir = sh->Program->nir; - gl_nir_link_glsl(ctx, whole_program); if (whole_program->data->LinkStatus != LINKING_SUCCESS) fprintf(stderr, "Linker error: %s", whole_program->data->InfoLog); EXPECT_EQ(whole_program->data->LinkStatus, LINKING_SUCCESS); + nir = whole_program->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->nir; + /* Store the source for printing from later assertions. */ this->source = source; } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index 93fb1db713f..99d5b0576b8 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -103,21 +103,7 @@ load_glsl(unsigned num_files, char *const *files, gl_shader_stage stage) if (!prog) errx(1, "couldn't parse `%s'", files[0]); - nir_shader *nir = glsl_to_nir(&local_ctx.Const, - &prog->_LinkedShaders[stage]->ir, - &prog->_LinkedShaders[stage]->Program->info, - stage, nir_options, NULL); - - if (nir->info.stage == MESA_SHADER_FRAGMENT) { - nir->info.fs.pixel_center_integer = - prog->_LinkedShaders[stage]->Program->info.fs.pixel_center_integer; - nir->info.fs.origin_upper_left = - prog->_LinkedShaders[stage]->Program->info.fs.origin_upper_left; - nir->info.fs.advanced_blend_modes = - prog->_LinkedShaders[stage]->Program->info.fs.advanced_blend_modes; - } - - gl_nir_inline_functions(nir); + nir_shader *nir = prog->_LinkedShaders[stage]->Program->nir; /* required NIR passes: */ if (nir_options->lower_all_io_to_temps || diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 5ddf5a3ddbe..dc7a2ec2203 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -1232,30 +1232,11 @@ _mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh) /* this call will set the shader->CompileStatus field to indicate if * compilation was successful. */ - _mesa_glsl_compile_shader(ctx, sh, false, false, false); + _mesa_glsl_compile_shader(ctx, sh, NULL, false, false, false); if (ctx->_Shader->Flags & GLSL_LOG) { _mesa_write_shader_to_file(sh); } - - if (ctx->_Shader->Flags & GLSL_DUMP) { - if (sh->CompileStatus) { - if (sh->ir) { - _mesa_log("GLSL IR for shader %d:\n", sh->Name); - _mesa_print_ir(mesa_log_get_file(), sh->ir, NULL); - } else { - _mesa_log("No GLSL IR for shader %d (shader may be from " - "cache)\n", sh->Name); - } - _mesa_log("\n\n"); - } else { - _mesa_log("GLSL shader %d failed to compile.\n", sh->Name); - } - if (sh->InfoLog && sh->InfoLog[0] != 0) { - _mesa_log("GLSL shader %d info log:\n", sh->Name); - _mesa_log("%s\n", sh->InfoLog); - } - } } if (!sh->CompileStatus) { diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 91d602b5ac4..5ee521fb328 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -511,6 +511,11 @@ st_link_glsl_to_nir(struct gl_context *ctx, assert(shader_program->data->LinkStatus); + if (!shader_program->data->spirv) { + if (!gl_nir_link_glsl(ctx, shader_program)) + return GL_FALSE; + } + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (shader_program->_LinkedShaders[i]) linked_shader[num_shaders++] = shader_program->_LinkedShaders[i]; @@ -523,40 +528,21 @@ st_link_glsl_to_nir(struct gl_context *ctx, struct gl_program *prog = shader->Program; shader->Program->info.separate_shader = shader_program->SeparateShader; - - assert(!prog->nir); - prog->shader_program = shader_program; prog->state.type = PIPE_SHADER_IR_NIR; - /* Parameters will be filled during NIR linking. */ - prog->Parameters = _mesa_new_parameter_list(); - if (shader_program->data->spirv) { + /* Parameters will be filled during NIR linking. */ + prog->Parameters = _mesa_new_parameter_list(); + prog->shader_program = shader_program; + + assert(!prog->nir); prog->nir = _mesa_spirv_to_nir(ctx, shader_program, shader->Stage, options); } else { - if (ctx->_Shader->Flags & GLSL_DUMP) { - _mesa_log("\n"); - _mesa_log("GLSL IR for linked %s program %d:\n", - _mesa_shader_stage_to_string(shader->Stage), - shader_program->Name); - _mesa_print_ir(mesa_log_get_file(), shader->ir, NULL); - _mesa_log("\n\n"); - } - - prog->nir = glsl_to_nir(&st->ctx->Const, &shader->ir, - &shader->Program->info, shader->Stage, - options, NULL); - + assert(prog->nir); prog->nir->info.name = ralloc_asprintf(shader, "GLSL%d", shader_program->Name); if (shader_program->Label) prog->nir->info.label = ralloc_strdup(shader, shader_program->Label); - - if (prog->nir->info.stage == MESA_SHADER_FRAGMENT) { - prog->nir->info.fs.pixel_center_integer = prog->info.fs.pixel_center_integer; - prog->nir->info.fs.origin_upper_left = prog->info.fs.origin_upper_left; - prog->nir->info.fs.advanced_blend_modes = prog->info.fs.advanced_blend_modes; - } } memcpy(prog->nir->info.source_blake3, shader->linked_source_blake3, @@ -582,9 +568,6 @@ st_link_glsl_to_nir(struct gl_context *ctx, if (!gl_nir_link_spirv(&ctx->Const, &ctx->Extensions, shader_program, &opts)) return GL_FALSE; - } else { - if (!gl_nir_link_glsl(ctx, shader_program)) - return GL_FALSE; } for (unsigned i = 0; i < num_shaders; i++) {