From 875ca9ec11417d1bcd56b0568ce8164082322cc8 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 10 Apr 2024 09:53:15 +1000 Subject: [PATCH] glsl: move validate_{stage}_shader_executable() to the nir linker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Alejandro Piñeiro Reviewed-by: Marek Olšák Part-of: --- src/compiler/glsl/gl_nir_linker.c | 348 ++++++++++++++++++- src/compiler/glsl/gl_nir_linker.h | 5 +- src/compiler/glsl/linker.cpp | 385 ---------------------- src/mesa/state_tracker/st_glsl_to_nir.cpp | 3 +- 4 files changed, 346 insertions(+), 395 deletions(-) diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index 668fae2bad3..73772ea8009 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -31,6 +31,7 @@ #include "string_to_uint_map.h" #include "main/shader_types.h" #include "main/consts_exts.h" +#include "main/context.h" #include "main/shaderobj.h" #include "ir_uniform.h" /* for gl_uniform_storage */ #include "util/glheader.h" @@ -302,6 +303,40 @@ gl_nir_mode_string(const nir_variable *var) return "invalid variable"; } +static void +remove_dead_functions(nir_shader *shader) +{ + struct set *fn_set = + _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); + + /* Find all function prototypes adding them to a list then removing them + * if they are ever called. + */ + nir_foreach_function_impl(impl, shader) { + _mesa_set_add(fn_set, impl->function); + } + + nir_foreach_function_impl(impl, shader) { + nir_foreach_block(block, impl) { + nir_foreach_instr(instr, block) { + if (instr->type == nir_instr_type_call) { + nir_call_instr *call = nir_instr_as_call(instr); + _mesa_set_remove_key(fn_set, call->callee); + } + } + } + } + + /* Any functions remaining in the list must be unused so remove them. */ + set_foreach(fn_set, entry) { + nir_function *func = (nir_function *) entry->key; + if (!func->is_entrypoint) + exec_node_remove(&func->node); + } + + _mesa_set_destroy(fn_set, NULL); +} + bool gl_nir_can_add_pointsize_to_program(const struct gl_constants *consts, struct gl_program *prog) @@ -2396,17 +2431,320 @@ validate_invariant_builtins(const struct gl_constants *consts, return true; } -bool -gl_nir_link_glsl(const struct gl_constants *consts, - const struct gl_extensions *exts, - gl_api api, - struct gl_shader_program *prog) +static void +find_assignments(nir_shader *shader, nir_variable *var1, nir_variable *var2, + nir_variable *var3, bool *var1_written, bool *var2_written, + bool *var3_written) { + nir_foreach_function_impl(impl, shader) { + nir_foreach_block(block, impl) { + nir_foreach_instr(instr, block) { + if (instr->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + if (intrin->intrinsic == nir_intrinsic_store_deref || + intrin->intrinsic == nir_intrinsic_copy_deref) { + nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); + nir_variable *var = nir_deref_instr_get_variable(deref); + if (!var) + continue; + + if (var == var1) + *var1_written = true; + else if (var == var2) + *var2_written = true; + else if (var == var3) + *var3_written = true; + } + } + } + } + } +} + +/** + * Set clip_distance_array_size based and cull_distance_array_size on the given + * shader. + * + * Also check for errors based on incorrect usage of gl_ClipVertex and + * gl_ClipDistance and gl_CullDistance. + * Additionally test whether the arrays gl_ClipDistance and gl_CullDistance + * exceed the maximum size defined by gl_MaxCombinedClipAndCullDistances. + */ +static void +analyze_clip_cull_usage(struct gl_shader_program *prog, nir_shader *shader, + const struct gl_constants *consts, + struct shader_info *info) +{ + if (consts->DoDCEBeforeClipCullAnalysis) { + /* Remove dead functions to avoid raising an error (eg: dead function + * writes to gl_ClipVertex, and main() writes to gl_ClipDistance). + */ + remove_dead_functions(shader); + } + + info->clip_distance_array_size = 0; + info->cull_distance_array_size = 0; + + if (prog->GLSL_Version >= (prog->IsES ? 300 : 130)) { + /* From section 7.1 (Vertex Shader Special Variables) of the + * GLSL 1.30 spec: + * + * "It is an error for a shader to statically write both + * gl_ClipVertex and gl_ClipDistance." + * + * This does not apply to GLSL ES shaders, since GLSL ES defines neither + * gl_ClipVertex nor gl_ClipDistance. However with + * GL_EXT_clip_cull_distance, this functionality is exposed in ES 3.0. + */ + nir_variable *clip_dist = + nir_find_variable_with_location(shader, + nir_var_shader_out, + VARYING_SLOT_CLIP_DIST0); + nir_variable *cull_dist = + nir_find_variable_with_location(shader, + nir_var_shader_out, + VARYING_SLOT_CULL_DIST0); + nir_variable *clip_vert = + nir_find_variable_with_location(shader, + nir_var_shader_out, + VARYING_SLOT_CLIP_VERTEX); + + bool clip_dist_written = false; + bool cull_dist_written = false; + bool clip_vert_written = false; + find_assignments(shader, clip_dist, cull_dist, clip_vert, + &clip_dist_written, &cull_dist_written, + &clip_vert_written); + + /* From the ARB_cull_distance spec: + * + * It is a compile-time or link-time error for the set of shaders forming + * a program to statically read or write both gl_ClipVertex and either + * gl_ClipDistance or gl_CullDistance. + * + * This does not apply to GLSL ES shaders, since GLSL ES doesn't define + * gl_ClipVertex. + */ + if (!prog->IsES) { + if (clip_vert_written && clip_dist_written) { + linker_error(prog, "%s shader writes to both `gl_ClipVertex' " + "and `gl_ClipDistance'\n", + _mesa_shader_stage_to_string(info->stage)); + return; + } + if (clip_vert_written && cull_dist_written) { + linker_error(prog, "%s shader writes to both `gl_ClipVertex' " + "and `gl_CullDistance'\n", + _mesa_shader_stage_to_string(info->stage)); + return; + } + } + + if (clip_dist_written) + info->clip_distance_array_size = glsl_get_length(clip_dist->type); + + if (cull_dist_written) + info->cull_distance_array_size = glsl_get_length(cull_dist->type); + + /* From the ARB_cull_distance spec: + * + * It is a compile-time or link-time error for the set of shaders forming + * a program to have the sum of the sizes of the gl_ClipDistance and + * gl_CullDistance arrays to be larger than + * gl_MaxCombinedClipAndCullDistances. + */ + if ((uint32_t)(info->clip_distance_array_size + info->cull_distance_array_size) > + consts->MaxClipPlanes) { + linker_error(prog, "%s shader: the combined size of " + "'gl_ClipDistance' and 'gl_CullDistance' size cannot " + "be larger than " + "gl_MaxCombinedClipAndCullDistances (%u)", + _mesa_shader_stage_to_string(info->stage), + consts->MaxClipPlanes); + } + } +} + +/** + * Verify that a vertex shader executable meets all semantic requirements. + * + * Also sets info.clip_distance_array_size and + * info.cull_distance_array_size as a side effect. + * + * \param shader Vertex shader executable to be verified + */ +static void +validate_vertex_shader_executable(struct gl_shader_program *prog, + nir_shader *shader, + const struct gl_constants *consts) +{ + if (shader == NULL) + return; + + /* From the GLSL 1.10 spec, page 48: + * + * "The variable gl_Position is available only in the vertex + * language and is intended for writing the homogeneous vertex + * position. All executions of a well-formed vertex shader + * executable must write a value into this variable. [...] The + * variable gl_Position is available only in the vertex + * language and is intended for writing the homogeneous vertex + * position. All executions of a well-formed vertex shader + * executable must write a value into this variable." + * + * while in GLSL 1.40 this text is changed to: + * + * "The variable gl_Position is available only in the vertex + * language and is intended for writing the homogeneous vertex + * position. It can be written at any time during shader + * execution. It may also be read back by a vertex shader + * after being written. This value will be used by primitive + * assembly, clipping, culling, and other fixed functionality + * operations, if present, that operate on primitives after + * vertex processing has occurred. Its value is undefined if + * the vertex shader executable does not write gl_Position." + * + * All GLSL ES Versions are similar to GLSL 1.40--failing to write to + * gl_Position is not an error. + */ + if (prog->GLSL_Version < (prog->IsES ? 300 : 140)) { + nir_variable *gl_position = + nir_find_variable_with_location(shader, + nir_var_shader_out, + VARYING_SLOT_POS); + + bool gl_position_written = false; + find_assignments(shader, gl_position, NULL, NULL, &gl_position_written, + NULL, NULL); + if (!gl_position_written) { + if (prog->IsES) { + linker_warning(prog, + "vertex shader does not write to `gl_Position'. " + "Its value is undefined. \n"); + } else { + linker_error(prog, + "vertex shader does not write to `gl_Position'. \n"); + } + return; + } + } + + analyze_clip_cull_usage(prog, shader, consts, &shader->info); +} + +static void +validate_tess_eval_shader_executable(struct gl_shader_program *prog, + nir_shader *shader, + const struct gl_constants *consts) +{ + if (shader == NULL) + return; + + analyze_clip_cull_usage(prog, shader, consts, &shader->info); +} + +/** + * Verify that a fragment shader executable meets all semantic requirements + * + * \param shader Fragment shader executable to be verified + */ +static void +validate_fragment_shader_executable(struct gl_shader_program *prog, + nir_shader *shader) +{ + if (shader == NULL) + return; + + nir_variable *gl_frag_color = + nir_find_variable_with_location(shader, + nir_var_shader_out, + FRAG_RESULT_COLOR); + nir_variable *gl_frag_data = + nir_find_variable_with_location(shader, + nir_var_shader_out, + FRAG_RESULT_DATA0); + + bool gl_frag_color_written = false; + bool gl_frag_data_written = false; + find_assignments(shader, gl_frag_color, gl_frag_data, NULL, + &gl_frag_color_written, &gl_frag_data_written, NULL); + + if (gl_frag_color_written && gl_frag_data_written) { + linker_error(prog, "fragment shader writes to both " + "`gl_FragColor' and `gl_FragData'\n"); + } +} + +/** + * Verify that a geometry shader executable meets all semantic requirements + * + * Also sets prog->Geom.VerticesIn, and info.clip_distance_array_sizeand + * info.cull_distance_array_size as a side effect. + * + * \param shader Geometry shader executable to be verified + */ +static void +validate_geometry_shader_executable(struct gl_shader_program *prog, + nir_shader *shader, + const struct gl_constants *consts) +{ + if (shader == NULL) + return; + + unsigned num_vertices = + mesa_vertices_per_prim(shader->info.gs.input_primitive); + shader->info.gs.vertices_in = num_vertices; + + analyze_clip_cull_usage(prog, shader, consts, &shader->info); +} + +bool +gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) +{ + const struct gl_constants *consts = &ctx->Const; + const struct gl_extensions *exts = &ctx->Extensions; + gl_api api = ctx->API; + if (prog->NumShaders == 0) return true; MESA_TRACE_FUNC(); + /* Link all shaders for a particular stage and validate the result. + */ + for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) { + struct gl_linked_shader *sh = prog->_LinkedShaders[stage]; + if (sh) { + nir_shader *shader = sh->Program->nir; + + switch (stage) { + case MESA_SHADER_VERTEX: + validate_vertex_shader_executable(prog, shader, consts); + break; + case MESA_SHADER_TESS_CTRL: + /* nothing to be done */ + break; + case MESA_SHADER_TESS_EVAL: + validate_tess_eval_shader_executable(prog, shader, consts); + break; + case MESA_SHADER_GEOMETRY: + validate_geometry_shader_executable(prog, shader, consts); + break; + case MESA_SHADER_FRAGMENT: + validate_fragment_shader_executable(prog, shader); + break; + } + if (!prog->data->LinkStatus) { + _mesa_delete_linked_shader(ctx, sh); + + prog->_LinkedShaders[stage] = NULL; + prog->data->linked_stages ^= 1 << stage; + + return false; + } + } + } + /* Here begins the inter-stage linking phase. Some initial validation is * performed, then locations are assigned for uniforms, attributes, and * varyings. diff --git a/src/compiler/glsl/gl_nir_linker.h b/src/compiler/glsl/gl_nir_linker.h index 701e00f1241..b63fa4d1a77 100644 --- a/src/compiler/glsl/gl_nir_linker.h +++ b/src/compiler/glsl/gl_nir_linker.h @@ -35,6 +35,7 @@ extern "C" { #endif struct gl_constants; +struct gl_context; struct gl_extensions; struct gl_linked_shader; struct gl_shader_program; @@ -63,9 +64,7 @@ bool gl_nir_link_spirv(const struct gl_constants *consts, struct gl_shader_program *prog, const struct gl_nir_linker_options *options); -bool gl_nir_link_glsl(const struct gl_constants *consts, - const struct gl_extensions *exts, - gl_api api, +bool gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog); bool gl_nir_link_uniforms(const struct gl_constants *consts, diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index fba5e6617c6..94a1b0366b4 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -95,143 +95,6 @@ namespace { -struct find_variable { - const char *name; - bool found; - - find_variable(const char *name) : name(name), found(false) {} -}; - -/** - * Visitor that determines whether or not a variable is ever written. - * Note: this is only considering if the variable is statically written - * (= regardless of the runtime flow of control) - * - * Use \ref find_assignments for convenience. - */ -class find_assignment_visitor : public ir_hierarchical_visitor { -public: - find_assignment_visitor(unsigned num_vars, - find_variable * const *vars) - : num_variables(num_vars), num_found(0), variables(vars) - { - } - - virtual ir_visitor_status visit_enter(ir_assignment *ir) - { - ir_variable *const var = ir->lhs->variable_referenced(); - - return check_variable_name(var->name); - } - - virtual ir_visitor_status visit_enter(ir_call *ir) - { - foreach_two_lists(formal_node, &ir->callee->parameters, - actual_node, &ir->actual_parameters) { - ir_rvalue *param_rval = (ir_rvalue *) actual_node; - ir_variable *sig_param = (ir_variable *) formal_node; - - if (sig_param->data.mode == ir_var_function_out || - sig_param->data.mode == ir_var_function_inout) { - ir_variable *var = param_rval->variable_referenced(); - if (var && check_variable_name(var->name) == visit_stop) - return visit_stop; - } - } - - if (ir->return_deref != NULL) { - ir_variable *const var = ir->return_deref->variable_referenced(); - - if (check_variable_name(var->name) == visit_stop) - return visit_stop; - } - - return visit_continue_with_parent; - } - -private: - ir_visitor_status check_variable_name(const char *name) - { - for (unsigned i = 0; i < num_variables; ++i) { - if (strcmp(variables[i]->name, name) == 0) { - if (!variables[i]->found) { - variables[i]->found = true; - - assert(num_found < num_variables); - if (++num_found == num_variables) - return visit_stop; - } - break; - } - } - - return visit_continue_with_parent; - } - -private: - unsigned num_variables; /**< Number of variables to find */ - unsigned num_found; /**< Number of variables already found */ - find_variable * const *variables; /**< Variables to find */ -}; - -/** - * Determine whether or not any of NULL-terminated list of variables is ever - * written to. - */ -static void -find_assignments(exec_list *ir, find_variable * const *vars) -{ - unsigned num_variables = 0; - - for (find_variable * const *v = vars; *v; ++v) - num_variables++; - - find_assignment_visitor visitor(num_variables, vars); - visitor.run(ir); -} - -/** - * Determine whether or not the given variable is ever written to. - */ -static void -find_assignments(exec_list *ir, find_variable *var) -{ - find_assignment_visitor visitor(1, &var); - visitor.run(ir); -} - -/** - * Visitor that determines whether or not a variable is ever read. - */ -class find_deref_visitor : public ir_hierarchical_visitor { -public: - find_deref_visitor(const char *name) - : name(name), found(false) - { - /* empty */ - } - - virtual ir_visitor_status visit(ir_dereference_variable *ir) - { - if (strcmp(this->name, ir->var->name) == 0) { - this->found = true; - return visit_stop; - } - - return visit_continue; - } - - bool variable_found() const - { - return this->found; - } - -private: - const char *name; /**< Find writes to a variable with this name. */ - bool found; /**< Was a write to the variable found? */ -}; - - /** * A visitor helper that provides methods for updating the types of * ir_dereferences. Classes that update variable types (say, updating @@ -385,231 +248,6 @@ linker_warning(gl_shader_program *prog, const char *fmt, ...) } - -/** - * Set clip_distance_array_size based and cull_distance_array_size on the given - * shader. - * - * Also check for errors based on incorrect usage of gl_ClipVertex and - * gl_ClipDistance and gl_CullDistance. - * Additionally test whether the arrays gl_ClipDistance and gl_CullDistance - * exceed the maximum size defined by gl_MaxCombinedClipAndCullDistances. - * - * Return false if an error was reported. - */ -static void -analyze_clip_cull_usage(struct gl_shader_program *prog, - struct gl_linked_shader *shader, - const struct gl_constants *consts, - struct shader_info *info) -{ - if (consts->DoDCEBeforeClipCullAnalysis) { - /* Remove dead functions to avoid raising an error (eg: dead function - * writes to gl_ClipVertex, and main() writes to gl_ClipDistance). - */ - do_dead_functions(shader->ir); - } - - info->clip_distance_array_size = 0; - info->cull_distance_array_size = 0; - - if (prog->GLSL_Version >= (prog->IsES ? 300 : 130)) { - /* From section 7.1 (Vertex Shader Special Variables) of the - * GLSL 1.30 spec: - * - * "It is an error for a shader to statically write both - * gl_ClipVertex and gl_ClipDistance." - * - * This does not apply to GLSL ES shaders, since GLSL ES defines neither - * gl_ClipVertex nor gl_ClipDistance. However with - * GL_EXT_clip_cull_distance, this functionality is exposed in ES 3.0. - */ - find_variable gl_ClipDistance("gl_ClipDistance"); - find_variable gl_CullDistance("gl_CullDistance"); - find_variable gl_ClipVertex("gl_ClipVertex"); - find_variable * const variables[] = { - &gl_ClipDistance, - &gl_CullDistance, - !prog->IsES ? &gl_ClipVertex : NULL, - NULL - }; - find_assignments(shader->ir, variables); - - /* From the ARB_cull_distance spec: - * - * It is a compile-time or link-time error for the set of shaders forming - * a program to statically read or write both gl_ClipVertex and either - * gl_ClipDistance or gl_CullDistance. - * - * This does not apply to GLSL ES shaders, since GLSL ES doesn't define - * gl_ClipVertex. - */ - if (!prog->IsES) { - if (gl_ClipVertex.found && gl_ClipDistance.found) { - linker_error(prog, "%s shader writes to both `gl_ClipVertex' " - "and `gl_ClipDistance'\n", - _mesa_shader_stage_to_string(shader->Stage)); - return; - } - if (gl_ClipVertex.found && gl_CullDistance.found) { - linker_error(prog, "%s shader writes to both `gl_ClipVertex' " - "and `gl_CullDistance'\n", - _mesa_shader_stage_to_string(shader->Stage)); - return; - } - } - - if (gl_ClipDistance.found) { - ir_variable *clip_distance_var = - shader->symbols->get_variable("gl_ClipDistance"); - assert(clip_distance_var); - info->clip_distance_array_size = clip_distance_var->type->length; - } - if (gl_CullDistance.found) { - ir_variable *cull_distance_var = - shader->symbols->get_variable("gl_CullDistance"); - assert(cull_distance_var); - info->cull_distance_array_size = cull_distance_var->type->length; - } - /* From the ARB_cull_distance spec: - * - * It is a compile-time or link-time error for the set of shaders forming - * a program to have the sum of the sizes of the gl_ClipDistance and - * gl_CullDistance arrays to be larger than - * gl_MaxCombinedClipAndCullDistances. - */ - if ((uint32_t)(info->clip_distance_array_size + info->cull_distance_array_size) > - consts->MaxClipPlanes) { - linker_error(prog, "%s shader: the combined size of " - "'gl_ClipDistance' and 'gl_CullDistance' size cannot " - "be larger than " - "gl_MaxCombinedClipAndCullDistances (%u)", - _mesa_shader_stage_to_string(shader->Stage), - consts->MaxClipPlanes); - } - } -} - - -/** - * Verify that a vertex shader executable meets all semantic requirements. - * - * Also sets info.clip_distance_array_size and - * info.cull_distance_array_size as a side effect. - * - * \param shader Vertex shader executable to be verified - */ -static void -validate_vertex_shader_executable(struct gl_shader_program *prog, - struct gl_linked_shader *shader, - const struct gl_constants *consts) -{ - if (shader == NULL) - return; - - /* From the GLSL 1.10 spec, page 48: - * - * "The variable gl_Position is available only in the vertex - * language and is intended for writing the homogeneous vertex - * position. All executions of a well-formed vertex shader - * executable must write a value into this variable. [...] The - * variable gl_Position is available only in the vertex - * language and is intended for writing the homogeneous vertex - * position. All executions of a well-formed vertex shader - * executable must write a value into this variable." - * - * while in GLSL 1.40 this text is changed to: - * - * "The variable gl_Position is available only in the vertex - * language and is intended for writing the homogeneous vertex - * position. It can be written at any time during shader - * execution. It may also be read back by a vertex shader - * after being written. This value will be used by primitive - * assembly, clipping, culling, and other fixed functionality - * operations, if present, that operate on primitives after - * vertex processing has occurred. Its value is undefined if - * the vertex shader executable does not write gl_Position." - * - * All GLSL ES Versions are similar to GLSL 1.40--failing to write to - * gl_Position is not an error. - */ - if (prog->GLSL_Version < (prog->IsES ? 300 : 140)) { - find_variable gl_Position("gl_Position"); - find_assignments(shader->ir, &gl_Position); - if (!gl_Position.found) { - if (prog->IsES) { - linker_warning(prog, - "vertex shader does not write to `gl_Position'. " - "Its value is undefined. \n"); - } else { - linker_error(prog, - "vertex shader does not write to `gl_Position'. \n"); - } - return; - } - } - - analyze_clip_cull_usage(prog, shader, consts, &shader->Program->info); -} - -static void -validate_tess_eval_shader_executable(struct gl_shader_program *prog, - struct gl_linked_shader *shader, - const struct gl_constants *consts) -{ - if (shader == NULL) - return; - - analyze_clip_cull_usage(prog, shader, consts, &shader->Program->info); -} - - -/** - * Verify that a fragment shader executable meets all semantic requirements - * - * \param shader Fragment shader executable to be verified - */ -static void -validate_fragment_shader_executable(struct gl_shader_program *prog, - struct gl_linked_shader *shader) -{ - if (shader == NULL) - return; - - find_variable gl_FragColor("gl_FragColor"); - find_variable gl_FragData("gl_FragData"); - find_variable * const variables[] = { &gl_FragColor, &gl_FragData, NULL }; - find_assignments(shader->ir, variables); - - if (gl_FragColor.found && gl_FragData.found) { - linker_error(prog, "fragment shader writes to both " - "`gl_FragColor' and `gl_FragData'\n"); - } -} - -/** - * Verify that a geometry shader executable meets all semantic requirements - * - * Also sets prog->Geom.VerticesIn, and info.clip_distance_array_sizeand - * info.cull_distance_array_size as a side effect. - * - * \param shader Geometry shader executable to be verified - */ -static void -validate_geometry_shader_executable(struct gl_shader_program *prog, - struct gl_linked_shader *shader, - const struct gl_constants *consts) -{ - if (shader == NULL) - return; - - unsigned num_vertices = - mesa_vertices_per_prim(shader->Program->info.gs.input_primitive); - shader->Program->info.gs.vertices_in = num_vertices; - - analyze_clip_cull_usage(prog, shader, consts, &shader->Program->info); -} - bool validate_intrastage_arrays(struct gl_shader_program *prog, ir_variable *const var, @@ -2332,29 +1970,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) goto done; } - switch (stage) { - case MESA_SHADER_VERTEX: - validate_vertex_shader_executable(prog, sh, consts); - break; - case MESA_SHADER_TESS_CTRL: - /* nothing to be done */ - break; - case MESA_SHADER_TESS_EVAL: - validate_tess_eval_shader_executable(prog, sh, consts); - break; - case MESA_SHADER_GEOMETRY: - validate_geometry_shader_executable(prog, sh, consts); - break; - case MESA_SHADER_FRAGMENT: - validate_fragment_shader_executable(prog, sh); - break; - } - if (!prog->data->LinkStatus) { - if (sh) - _mesa_delete_linked_shader(ctx, sh); - goto done; - } - prog->_LinkedShaders[stage] = sh; prog->data->linked_stages |= 1 << stage; } diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 548bcb8976f..70f6df8787d 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -568,8 +568,7 @@ st_link_glsl_to_nir(struct gl_context *ctx, &opts)) return GL_FALSE; } else { - if (!gl_nir_link_glsl(&ctx->Const, &ctx->Extensions, ctx->API, - shader_program)) + if (!gl_nir_link_glsl(ctx, shader_program)) return GL_FALSE; }