X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Flinker.cpp;h=8761c16e2fefca58acdf7871810b1a281c844ee8;hb=d70fff99c5bc3a721e20869e7f0be8024ffe5ecd;hp=ef77389add4ec377af3544ca4ddcea6a44296503;hpb=726e8f24c6eefe5b2d77fe0dbfd9d7c89fc224f4;p=mesa.git diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index ef77389add4..8761c16e2fe 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -86,7 +86,7 @@ #include "util/u_string.h" #include "util/u_math.h" -#include "main/imports.h" + #include "main/shaderobj.h" #include "main/enums.h" #include "main/mtypes.h" @@ -260,6 +260,8 @@ public: class array_resize_visitor : public deref_type_updater { public: + using deref_type_updater::visit; + unsigned num_vertices; gl_shader_program *prog; gl_shader_stage stage; @@ -1062,9 +1064,13 @@ cross_validate_globals(struct gl_context *ctx, struct gl_shader_program *prog, * no vendor actually implemented that behavior. The 4.20 * behavior matches the implemented behavior of at least one other * vendor, so we'll implement that for all GLSL versions. + * If (at least) one of these constant expressions is implicit, + * because it was added by glsl_zero_init, we skip the verification. */ if (var->constant_initializer != NULL) { - if (existing->constant_initializer != NULL) { + if (existing->constant_initializer != NULL && + !existing->data.is_implicit_initializer && + !var->data.is_implicit_initializer) { if (!var->constant_initializer->has_value(existing->constant_initializer)) { linker_error(prog, "initializers for %s " "`%s' have differing values\n", @@ -1076,7 +1082,8 @@ cross_validate_globals(struct gl_context *ctx, struct gl_shader_program *prog, * not have an initializer but a later instance does, * replace the former with the later. */ - variables->replace_variable(existing->name, var); + if (!var->data.is_implicit_initializer) + variables->replace_variable(existing->name, var); } } @@ -1506,6 +1513,8 @@ move_non_declarations(exec_list *instructions, exec_node *last, */ class array_sizing_visitor : public deref_type_updater { public: + using deref_type_updater::visit; + array_sizing_visitor() : mem_ctx(ralloc_context(NULL)), unnamed_interfaces(_mesa_pointer_hash_table_create(NULL)) @@ -1812,6 +1821,40 @@ link_bindless_layout_qualifiers(struct gl_shader_program *prog, } } +/** + * Check for conflicting viewport_relative settings across shaders, and sets + * the value for the linked shader. + */ +static void +link_layer_viewport_relative_qualifier(struct gl_shader_program *prog, + struct gl_program *gl_prog, + struct gl_shader **shader_list, + unsigned num_shaders) +{ + unsigned i; + + /* Find first shader with explicit layer declaration */ + for (i = 0; i < num_shaders; i++) { + if (shader_list[i]->redeclares_gl_layer) { + gl_prog->info.layer_viewport_relative = + shader_list[i]->layer_viewport_relative; + break; + } + } + + /* Now make sure that each subsequent shader's explicit layer declaration + * matches the first one's. + */ + for (; i < num_shaders; i++) { + if (shader_list[i]->redeclares_gl_layer && + shader_list[i]->layer_viewport_relative != + gl_prog->info.layer_viewport_relative) { + linker_error(prog, "all gl_Layer redeclarations must have identical " + "viewport_relative settings"); + } + } +} + /** * Performs the cross-validation of tessellation control shader vertices and * layout qualifiers for the attached tessellation control shaders, @@ -2429,9 +2472,7 @@ link_intrastage_shaders(void *mem_ctx, /* Create program and attach it to the linked shader */ struct gl_program *gl_prog = - ctx->Driver.NewProgram(ctx, - _mesa_shader_stage_to_program(shader_list[0]->Stage), - prog->Name, false); + ctx->Driver.NewProgram(ctx, shader_list[0]->Stage, prog->Name, false); if (!gl_prog) { prog->data->LinkStatus = LINKING_FAILURE; _mesa_delete_linked_shader(ctx, linked); @@ -2457,6 +2498,8 @@ link_intrastage_shaders(void *mem_ctx, link_bindless_layout_qualifiers(prog, shader_list, num_shaders); + link_layer_viewport_relative_qualifier(prog, gl_prog, shader_list, num_shaders); + populate_symbol_table(linked, shader_list[0]->symbols); /* The pointer to the main function in the final linked shader (i.e., the @@ -2530,6 +2573,7 @@ link_intrastage_shaders(void *mem_ctx, for (unsigned i = 0; i < num_ubo_blocks; i++) { linked->Program->sh.UniformBlocks[i] = &ubo_blocks[i]; } + linked->Program->sh.NumUniformBlocks = num_ubo_blocks; linked->Program->info.num_ubos = num_ubo_blocks; /* Copy ssbo blocks to linked shader list */ @@ -4036,8 +4080,10 @@ build_program_resource_list(struct gl_context *ctx, return; } - if (add_packed_varyings_only) + if (add_packed_varyings_only) { + _mesa_set_destroy(resource_set, NULL); return; + } if (!add_fragdata_arrays(ctx, shProg, resource_set)) return; @@ -4398,6 +4444,8 @@ static void link_and_validate_uniforms(struct gl_context *ctx, struct gl_shader_program *prog) { + assert(!ctx->Const.UseNIRGLSLLinker); + update_array_sizes(prog); link_assign_uniform_locations(prog, ctx); @@ -4405,14 +4453,11 @@ link_and_validate_uniforms(struct gl_context *ctx, return; link_util_calculate_subroutine_compat(prog); - - if (!ctx->Const.UseNIRGLSLLinker) { - link_util_check_uniform_resources(ctx, prog); - link_util_check_subroutine_resources(prog); - check_image_resources(ctx, prog); - link_assign_atomic_counter_resources(ctx, prog); - link_check_atomic_counter_resources(ctx, prog); - } + link_util_check_uniform_resources(ctx, prog); + link_util_check_subroutine_resources(prog); + check_image_resources(ctx, prog); + link_assign_atomic_counter_resources(ctx, prog); + link_check_atomic_counter_resources(ctx, prog); } static bool @@ -4459,7 +4504,8 @@ link_varyings_and_uniforms(unsigned first, unsigned last, if (!link_varyings(prog, first, last, ctx, mem_ctx)) return false; - link_and_validate_uniforms(ctx, prog); + if (!ctx->Const.UseNIRGLSLLinker) + link_and_validate_uniforms(ctx, prog); if (!prog->data->LinkStatus) return false;