X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Fgl_nir_linker.c;h=fb8b3e0c340967de9798aa65f86ced678cf73ba8;hb=37c88c670f79f4833856e9193d3b7696c8b5ad8a;hp=b6ad926bf582981dcd8bd21c6e6e157fbc1c357b;hpb=46f9f74c574abfdecea6a789380d7a00540e69d7;p=mesa.git diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index b6ad926bf58..fb8b3e0c340 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -26,12 +26,12 @@ #include "gl_nir_linker.h" #include "linker_util.h" #include "main/mtypes.h" +#include "main/shaderobj.h" #include "ir_uniform.h" /* for gl_uniform_storage */ -/* This file included general link methods, using NIR, instead of IR as +/** + * This file included general link methods, using NIR, instead of IR as * the counter-part glsl/linker.cpp - * - * Also note that this is tailored for ARB_gl_spirv needs and particularities */ /** @@ -396,10 +396,11 @@ add_interface_variables(const struct gl_context *ctx, */ void nir_build_program_resource_list(struct gl_context *ctx, - struct gl_shader_program *prog) + struct gl_shader_program *prog, + bool rebuild_resourse_list) { /* Rebuild resource list. */ - if (prog->data->ProgramResourceList) { + if (prog->data->ProgramResourceList && rebuild_resourse_list) { ralloc_free(prog->data->ProgramResourceList); prog->data->ProgramResourceList = NULL; prog->data->NumProgramResourceList = 0; @@ -475,9 +476,22 @@ nir_build_program_resource_list(struct gl_context *ctx, for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i]; - /* Do not add uniforms internally used by Mesa. */ - if (uniform->hidden) + if (uniform->hidden) { + for (int j = MESA_SHADER_VERTEX; j < MESA_SHADER_STAGES; j++) { + if (!uniform->opaque[j].active || + glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE) + continue; + + GLenum type = + _mesa_shader_stage_to_subroutine_uniform((gl_shader_stage)j); + /* add shader subroutines */ + if (!link_util_add_program_resource(prog, resource_set, + type, uniform, 0)) + return; + } + continue; + } if (!link_util_should_add_buffer_variable(prog, uniform, top_level_array_base_offset, @@ -533,12 +547,27 @@ nir_build_program_resource_list(struct gl_context *ctx, return; } + unsigned mask = prog->data->linked_stages; + while (mask) { + const int i = u_bit_scan(&mask); + struct gl_program *p = prog->_LinkedShaders[i]->Program; + + GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i); + for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) { + if (!link_util_add_program_resource(prog, resource_set, + type, + &p->sh.SubroutineFunctions[j], + 0)) + return; + } + } + _mesa_set_destroy(resource_set, NULL); } bool -gl_nir_link(struct gl_context *ctx, struct gl_shader_program *prog, - const struct gl_nir_linker_options *options) +gl_nir_link_spirv(struct gl_context *ctx, struct gl_shader_program *prog, + const struct gl_nir_linker_options *options) { if (!gl_nir_link_uniform_blocks(ctx, prog)) return false; @@ -551,3 +580,60 @@ gl_nir_link(struct gl_context *ctx, struct gl_shader_program *prog, return true; } + +/** + * Validate shader image resources. + */ +static void +check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog) +{ + unsigned total_image_units = 0; + unsigned fragment_outputs = 0; + unsigned total_shader_storage_blocks = 0; + + if (!ctx->Extensions.ARB_shader_image_load_store) + return; + + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + struct gl_linked_shader *sh = prog->_LinkedShaders[i]; + if (!sh) + continue; + + total_image_units += sh->Program->info.num_images; + total_shader_storage_blocks += sh->Program->info.num_ssbos; + } + + if (total_image_units > ctx->Const.MaxCombinedImageUniforms) + linker_error(prog, "Too many combined image uniforms\n"); + + struct gl_linked_shader *frag_sh = + prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; + if (frag_sh) { + uint64_t frag_outputs_written = frag_sh->Program->info.outputs_written; + fragment_outputs = util_bitcount64(frag_outputs_written); + } + + if (total_image_units + fragment_outputs + total_shader_storage_blocks > + ctx->Const.MaxCombinedShaderOutputResources) + linker_error(prog, "Too many combined image uniforms, shader storage " + " buffers and fragment outputs\n"); +} + +bool +gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) +{ + if (!gl_nir_link_uniforms(ctx, prog, true)) + return false; + + link_util_calculate_subroutine_compat(prog); + link_util_check_uniform_resources(ctx, prog); + link_util_check_subroutine_resources(prog); + check_image_resources(ctx, prog); + gl_nir_link_assign_atomic_counter_resources(ctx, prog); + gl_nir_link_check_atomic_counter_resources(ctx, prog); + + if (prog->data->LinkStatus == LINKING_FAILURE) + return false; + + return true; +}