101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2018 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include "nir.h" 257ec681f3Smrg#include "gl_nir.h" 2601e04c3fSmrg#include "gl_nir_linker.h" 2701e04c3fSmrg#include "linker_util.h" 2801e04c3fSmrg#include "main/mtypes.h" 297ec681f3Smrg#include "main/shaderobj.h" 3001e04c3fSmrg#include "ir_uniform.h" /* for gl_uniform_storage */ 3101e04c3fSmrg 327ec681f3Smrg/** 337ec681f3Smrg * This file included general link methods, using NIR, instead of IR as 3401e04c3fSmrg * the counter-part glsl/linker.cpp 3501e04c3fSmrg */ 3601e04c3fSmrg 377ec681f3Smrgstatic bool 387ec681f3Smrgcan_remove_uniform(nir_variable *var, UNUSED void *data) 397ec681f3Smrg{ 407ec681f3Smrg /* Section 2.11.6 (Uniform Variables) of the OpenGL ES 3.0.3 spec 417ec681f3Smrg * says: 427ec681f3Smrg * 437ec681f3Smrg * "All members of a named uniform block declared with a shared or 447ec681f3Smrg * std140 layout qualifier are considered active, even if they are not 457ec681f3Smrg * referenced in any shader in the program. The uniform block itself is 467ec681f3Smrg * also considered active, even if no member of the block is 477ec681f3Smrg * referenced." 487ec681f3Smrg * 497ec681f3Smrg * Although the spec doesn't state it std430 layouts are expect to behave 507ec681f3Smrg * the same way. If the variable is in a uniform block with one of those 517ec681f3Smrg * layouts, do not eliminate it. 527ec681f3Smrg */ 537ec681f3Smrg if (nir_variable_is_in_block(var) && 547ec681f3Smrg (glsl_get_ifc_packing(var->interface_type) != 557ec681f3Smrg GLSL_INTERFACE_PACKING_PACKED)) 567ec681f3Smrg return false; 577ec681f3Smrg 587ec681f3Smrg if (glsl_get_base_type(glsl_without_array(var->type)) == 597ec681f3Smrg GLSL_TYPE_SUBROUTINE) 607ec681f3Smrg return false; 617ec681f3Smrg 627ec681f3Smrg /* Uniform initializers could get used by another stage */ 637ec681f3Smrg if (var->constant_initializer) 647ec681f3Smrg return false; 657ec681f3Smrg 667ec681f3Smrg return true; 677ec681f3Smrg} 687ec681f3Smrg 697ec681f3Smrg/** 707ec681f3Smrg * Built-in / reserved GL variables names start with "gl_" 717ec681f3Smrg */ 727ec681f3Smrgstatic inline bool 737ec681f3Smrgis_gl_identifier(const char *s) 747ec681f3Smrg{ 757ec681f3Smrg return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_'; 767ec681f3Smrg} 777ec681f3Smrg 787ec681f3Smrgstatic bool 797ec681f3Smrginout_has_same_location(const nir_variable *var, unsigned stage) 807ec681f3Smrg{ 817ec681f3Smrg if (!var->data.patch && 827ec681f3Smrg ((var->data.mode == nir_var_shader_out && 837ec681f3Smrg stage == MESA_SHADER_TESS_CTRL) || 847ec681f3Smrg (var->data.mode == nir_var_shader_in && 857ec681f3Smrg (stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL || 867ec681f3Smrg stage == MESA_SHADER_GEOMETRY)))) 877ec681f3Smrg return true; 887ec681f3Smrg else 897ec681f3Smrg return false; 907ec681f3Smrg} 917ec681f3Smrg 927ec681f3Smrg/** 937ec681f3Smrg * Create gl_shader_variable from nir_variable. 947ec681f3Smrg */ 957ec681f3Smrgstatic struct gl_shader_variable * 967ec681f3Smrgcreate_shader_variable(struct gl_shader_program *shProg, 977ec681f3Smrg const nir_variable *in, 987ec681f3Smrg const char *name, const struct glsl_type *type, 997ec681f3Smrg const struct glsl_type *interface_type, 1007ec681f3Smrg bool use_implicit_location, int location, 1017ec681f3Smrg const struct glsl_type *outermost_struct_type) 1027ec681f3Smrg{ 1037ec681f3Smrg /* Allocate zero-initialized memory to ensure that bitfield padding 1047ec681f3Smrg * is zero. 1057ec681f3Smrg */ 1067ec681f3Smrg struct gl_shader_variable *out = rzalloc(shProg, 1077ec681f3Smrg struct gl_shader_variable); 1087ec681f3Smrg if (!out) 1097ec681f3Smrg return NULL; 1107ec681f3Smrg 1117ec681f3Smrg /* Since gl_VertexID may be lowered to gl_VertexIDMESA, but applications 1127ec681f3Smrg * expect to see gl_VertexID in the program resource list. Pretend. 1137ec681f3Smrg */ 1147ec681f3Smrg if (in->data.mode == nir_var_system_value && 1157ec681f3Smrg in->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) { 1167ec681f3Smrg out->name = ralloc_strdup(shProg, "gl_VertexID"); 1177ec681f3Smrg } else if ((in->data.mode == nir_var_shader_out && 1187ec681f3Smrg in->data.location == VARYING_SLOT_TESS_LEVEL_OUTER) || 1197ec681f3Smrg (in->data.mode == nir_var_system_value && 1207ec681f3Smrg in->data.location == SYSTEM_VALUE_TESS_LEVEL_OUTER)) { 1217ec681f3Smrg out->name = ralloc_strdup(shProg, "gl_TessLevelOuter"); 1227ec681f3Smrg type = glsl_array_type(glsl_float_type(), 4, 0); 1237ec681f3Smrg } else if ((in->data.mode == nir_var_shader_out && 1247ec681f3Smrg in->data.location == VARYING_SLOT_TESS_LEVEL_INNER) || 1257ec681f3Smrg (in->data.mode == nir_var_system_value && 1267ec681f3Smrg in->data.location == SYSTEM_VALUE_TESS_LEVEL_INNER)) { 1277ec681f3Smrg out->name = ralloc_strdup(shProg, "gl_TessLevelInner"); 1287ec681f3Smrg type = glsl_array_type(glsl_float_type(), 2, 0); 1297ec681f3Smrg } else { 1307ec681f3Smrg out->name = ralloc_strdup(shProg, name); 1317ec681f3Smrg } 1327ec681f3Smrg 1337ec681f3Smrg if (!out->name) 1347ec681f3Smrg return NULL; 1357ec681f3Smrg 1367ec681f3Smrg /* The ARB_program_interface_query spec says: 1377ec681f3Smrg * 1387ec681f3Smrg * "Not all active variables are assigned valid locations; the 1397ec681f3Smrg * following variables will have an effective location of -1: 1407ec681f3Smrg * 1417ec681f3Smrg * * uniforms declared as atomic counters; 1427ec681f3Smrg * 1437ec681f3Smrg * * members of a uniform block; 1447ec681f3Smrg * 1457ec681f3Smrg * * built-in inputs, outputs, and uniforms (starting with "gl_"); and 1467ec681f3Smrg * 1477ec681f3Smrg * * inputs or outputs not declared with a "location" layout 1487ec681f3Smrg * qualifier, except for vertex shader inputs and fragment shader 1497ec681f3Smrg * outputs." 1507ec681f3Smrg */ 1517ec681f3Smrg if (glsl_get_base_type(in->type) == GLSL_TYPE_ATOMIC_UINT || 1527ec681f3Smrg is_gl_identifier(in->name) || 1537ec681f3Smrg !(in->data.explicit_location || use_implicit_location)) { 1547ec681f3Smrg out->location = -1; 1557ec681f3Smrg } else { 1567ec681f3Smrg out->location = location; 1577ec681f3Smrg } 1587ec681f3Smrg 1597ec681f3Smrg out->type = type; 1607ec681f3Smrg out->outermost_struct_type = outermost_struct_type; 1617ec681f3Smrg out->interface_type = interface_type; 1627ec681f3Smrg out->component = in->data.location_frac; 1637ec681f3Smrg out->index = in->data.index; 1647ec681f3Smrg out->patch = in->data.patch; 1657ec681f3Smrg out->mode = in->data.mode; 1667ec681f3Smrg out->interpolation = in->data.interpolation; 1677ec681f3Smrg out->precision = in->data.precision; 1687ec681f3Smrg out->explicit_location = in->data.explicit_location; 1697ec681f3Smrg 1707ec681f3Smrg return out; 1717ec681f3Smrg} 1727ec681f3Smrg 1737ec681f3Smrgstatic bool 1747ec681f3Smrgadd_shader_variable(const struct gl_context *ctx, 1757ec681f3Smrg struct gl_shader_program *shProg, 1767ec681f3Smrg struct set *resource_set, 1777ec681f3Smrg unsigned stage_mask, 1787ec681f3Smrg GLenum programInterface, nir_variable *var, 1797ec681f3Smrg const char *name, const struct glsl_type *type, 1807ec681f3Smrg bool use_implicit_location, int location, 1817ec681f3Smrg bool inouts_share_location, 1827ec681f3Smrg const struct glsl_type *outermost_struct_type) 1837ec681f3Smrg{ 1847ec681f3Smrg const struct glsl_type *interface_type = var->interface_type; 1857ec681f3Smrg 1867ec681f3Smrg if (outermost_struct_type == NULL) { 1877ec681f3Smrg if (var->data.from_named_ifc_block) { 1887ec681f3Smrg const char *interface_name = glsl_get_type_name(interface_type); 1897ec681f3Smrg 1907ec681f3Smrg if (glsl_type_is_array(interface_type)) { 1917ec681f3Smrg /* Issue #16 of the ARB_program_interface_query spec says: 1927ec681f3Smrg * 1937ec681f3Smrg * "* If a variable is a member of an interface block without an 1947ec681f3Smrg * instance name, it is enumerated using just the variable name. 1957ec681f3Smrg * 1967ec681f3Smrg * * If a variable is a member of an interface block with an 1977ec681f3Smrg * instance name, it is enumerated as "BlockName.Member", where 1987ec681f3Smrg * "BlockName" is the name of the interface block (not the 1997ec681f3Smrg * instance name) and "Member" is the name of the variable." 2007ec681f3Smrg * 2017ec681f3Smrg * In particular, it indicates that it should be "BlockName", 2027ec681f3Smrg * not "BlockName[array length]". The conformance suite and 2037ec681f3Smrg * dEQP both require this behavior. 2047ec681f3Smrg * 2057ec681f3Smrg * Here, we unwrap the extra array level added by named interface 2067ec681f3Smrg * block array lowering so we have the correct variable type. We 2077ec681f3Smrg * also unwrap the interface type when constructing the name. 2087ec681f3Smrg * 2097ec681f3Smrg * We leave interface_type the same so that ES 3.x SSO pipeline 2107ec681f3Smrg * validation can enforce the rules requiring array length to 2117ec681f3Smrg * match on interface blocks. 2127ec681f3Smrg */ 2137ec681f3Smrg type = glsl_get_array_element(type); 2147ec681f3Smrg 2157ec681f3Smrg interface_name = 2167ec681f3Smrg glsl_get_type_name(glsl_get_array_element(interface_type)); 2177ec681f3Smrg } 2187ec681f3Smrg 2197ec681f3Smrg name = ralloc_asprintf(shProg, "%s.%s", interface_name, name); 2207ec681f3Smrg } 2217ec681f3Smrg } 2227ec681f3Smrg 2237ec681f3Smrg switch (glsl_get_base_type(type)) { 2247ec681f3Smrg case GLSL_TYPE_STRUCT: { 2257ec681f3Smrg /* The ARB_program_interface_query spec says: 2267ec681f3Smrg * 2277ec681f3Smrg * "For an active variable declared as a structure, a separate entry 2287ec681f3Smrg * will be generated for each active structure member. The name of 2297ec681f3Smrg * each entry is formed by concatenating the name of the structure, 2307ec681f3Smrg * the "." character, and the name of the structure member. If a 2317ec681f3Smrg * structure member to enumerate is itself a structure or array, 2327ec681f3Smrg * these enumeration rules are applied recursively." 2337ec681f3Smrg */ 2347ec681f3Smrg if (outermost_struct_type == NULL) 2357ec681f3Smrg outermost_struct_type = type; 2367ec681f3Smrg 2377ec681f3Smrg unsigned field_location = location; 2387ec681f3Smrg for (unsigned i = 0; i < glsl_get_length(type); i++) { 2397ec681f3Smrg const struct glsl_type *field_type = glsl_get_struct_field(type, i); 2407ec681f3Smrg const struct glsl_struct_field *field = 2417ec681f3Smrg glsl_get_struct_field_data(type, i); 2427ec681f3Smrg 2437ec681f3Smrg char *field_name = ralloc_asprintf(shProg, "%s.%s", name, field->name); 2447ec681f3Smrg if (!add_shader_variable(ctx, shProg, resource_set, 2457ec681f3Smrg stage_mask, programInterface, 2467ec681f3Smrg var, field_name, field_type, 2477ec681f3Smrg use_implicit_location, field_location, 2487ec681f3Smrg false, outermost_struct_type)) 2497ec681f3Smrg return false; 2507ec681f3Smrg 2517ec681f3Smrg field_location += glsl_count_attribute_slots(field_type, false); 2527ec681f3Smrg } 2537ec681f3Smrg return true; 2547ec681f3Smrg } 2557ec681f3Smrg 2567ec681f3Smrg case GLSL_TYPE_ARRAY: { 2577ec681f3Smrg /* The ARB_program_interface_query spec says: 2587ec681f3Smrg * 2597ec681f3Smrg * "For an active variable declared as an array of basic types, a 2607ec681f3Smrg * single entry will be generated, with its name string formed by 2617ec681f3Smrg * concatenating the name of the array and the string "[0]"." 2627ec681f3Smrg * 2637ec681f3Smrg * "For an active variable declared as an array of an aggregate data 2647ec681f3Smrg * type (structures or arrays), a separate entry will be generated 2657ec681f3Smrg * for each active array element, unless noted immediately below. 2667ec681f3Smrg * The name of each entry is formed by concatenating the name of 2677ec681f3Smrg * the array, the "[" character, an integer identifying the element 2687ec681f3Smrg * number, and the "]" character. These enumeration rules are 2697ec681f3Smrg * applied recursively, treating each enumerated array element as a 2707ec681f3Smrg * separate active variable." 2717ec681f3Smrg */ 2727ec681f3Smrg const struct glsl_type *array_type = glsl_get_array_element(type); 2737ec681f3Smrg if (glsl_get_base_type(array_type) == GLSL_TYPE_STRUCT || 2747ec681f3Smrg glsl_get_base_type(array_type) == GLSL_TYPE_ARRAY) { 2757ec681f3Smrg unsigned elem_location = location; 2767ec681f3Smrg unsigned stride = inouts_share_location ? 0 : 2777ec681f3Smrg glsl_count_attribute_slots(array_type, false); 2787ec681f3Smrg for (unsigned i = 0; i < glsl_get_length(type); i++) { 2797ec681f3Smrg char *elem = ralloc_asprintf(shProg, "%s[%d]", name, i); 2807ec681f3Smrg if (!add_shader_variable(ctx, shProg, resource_set, 2817ec681f3Smrg stage_mask, programInterface, 2827ec681f3Smrg var, elem, array_type, 2837ec681f3Smrg use_implicit_location, elem_location, 2847ec681f3Smrg false, outermost_struct_type)) 2857ec681f3Smrg return false; 2867ec681f3Smrg elem_location += stride; 2877ec681f3Smrg } 2887ec681f3Smrg return true; 2897ec681f3Smrg } 2907ec681f3Smrg } 2917ec681f3Smrg FALLTHROUGH; 2927ec681f3Smrg 2937ec681f3Smrg default: { 2947ec681f3Smrg /* The ARB_program_interface_query spec says: 2957ec681f3Smrg * 2967ec681f3Smrg * "For an active variable declared as a single instance of a basic 2977ec681f3Smrg * type, a single entry will be generated, using the variable name 2987ec681f3Smrg * from the shader source." 2997ec681f3Smrg */ 3007ec681f3Smrg struct gl_shader_variable *sha_v = 3017ec681f3Smrg create_shader_variable(shProg, var, name, type, interface_type, 3027ec681f3Smrg use_implicit_location, location, 3037ec681f3Smrg outermost_struct_type); 3047ec681f3Smrg if (!sha_v) 3057ec681f3Smrg return false; 3067ec681f3Smrg 3077ec681f3Smrg return link_util_add_program_resource(shProg, resource_set, 3087ec681f3Smrg programInterface, sha_v, stage_mask); 3097ec681f3Smrg } 3107ec681f3Smrg } 3117ec681f3Smrg} 3127ec681f3Smrg 3137ec681f3Smrgstatic bool 3147ec681f3Smrgadd_vars_with_modes(const struct gl_context *ctx, 3157ec681f3Smrg struct gl_shader_program *prog, struct set *resource_set, 3167ec681f3Smrg nir_shader *nir, nir_variable_mode modes, 3177ec681f3Smrg unsigned stage, GLenum programInterface) 3187ec681f3Smrg{ 3197ec681f3Smrg nir_foreach_variable_with_modes(var, nir, modes) { 3207ec681f3Smrg if (var->data.how_declared == nir_var_hidden) 3217ec681f3Smrg continue; 3227ec681f3Smrg 3237ec681f3Smrg int loc_bias = 0; 3247ec681f3Smrg switch(var->data.mode) { 3257ec681f3Smrg case nir_var_system_value: 3267ec681f3Smrg case nir_var_shader_in: 3277ec681f3Smrg if (programInterface != GL_PROGRAM_INPUT) 3287ec681f3Smrg continue; 3297ec681f3Smrg loc_bias = (stage == MESA_SHADER_VERTEX) ? VERT_ATTRIB_GENERIC0 3307ec681f3Smrg : VARYING_SLOT_VAR0; 3317ec681f3Smrg break; 3327ec681f3Smrg case nir_var_shader_out: 3337ec681f3Smrg if (programInterface != GL_PROGRAM_OUTPUT) 3347ec681f3Smrg continue; 3357ec681f3Smrg loc_bias = (stage == MESA_SHADER_FRAGMENT) ? FRAG_RESULT_DATA0 3367ec681f3Smrg : VARYING_SLOT_VAR0; 3377ec681f3Smrg break; 3387ec681f3Smrg default: 3397ec681f3Smrg continue; 3407ec681f3Smrg } 3417ec681f3Smrg 3427ec681f3Smrg if (var->data.patch) 3437ec681f3Smrg loc_bias = VARYING_SLOT_PATCH0; 3447ec681f3Smrg 3457ec681f3Smrg if (prog->data->spirv) { 3467ec681f3Smrg struct gl_shader_variable *sh_var = 3477ec681f3Smrg rzalloc(prog, struct gl_shader_variable); 3487ec681f3Smrg 3497ec681f3Smrg /* In the ARB_gl_spirv spec, names are considered optional debug info, so 3507ec681f3Smrg * the linker needs to work without them. Returning them is optional. 3517ec681f3Smrg * For simplicity, we ignore names. 3527ec681f3Smrg */ 3537ec681f3Smrg sh_var->name = NULL; 3547ec681f3Smrg sh_var->type = var->type; 3557ec681f3Smrg sh_var->location = var->data.location - loc_bias; 3567ec681f3Smrg sh_var->index = var->data.index; 3577ec681f3Smrg 3587ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, 3597ec681f3Smrg programInterface, 3607ec681f3Smrg sh_var, 1 << stage)) { 3617ec681f3Smrg return false; 3627ec681f3Smrg } 3637ec681f3Smrg } else { 3647ec681f3Smrg /* Skip packed varyings, packed varyings are handled separately 3657ec681f3Smrg * by add_packed_varyings in the GLSL IR 3667ec681f3Smrg * build_program_resource_list() call. 3677ec681f3Smrg * TODO: handle packed varyings here instead. We likely want a NIR 3687ec681f3Smrg * based packing pass first. 3697ec681f3Smrg */ 3707ec681f3Smrg if (strncmp(var->name, "packed:", 7) == 0) 3717ec681f3Smrg continue; 3727ec681f3Smrg 3737ec681f3Smrg const bool vs_input_or_fs_output = 3747ec681f3Smrg (stage == MESA_SHADER_VERTEX && 3757ec681f3Smrg var->data.mode == nir_var_shader_in) || 3767ec681f3Smrg (stage == MESA_SHADER_FRAGMENT && 3777ec681f3Smrg var->data.mode == nir_var_shader_out); 3787ec681f3Smrg 3797ec681f3Smrg if (!add_shader_variable(ctx, prog, resource_set, 3807ec681f3Smrg 1 << stage, programInterface, 3817ec681f3Smrg var, var->name, var->type, 3827ec681f3Smrg vs_input_or_fs_output, 3837ec681f3Smrg var->data.location - loc_bias, 3847ec681f3Smrg inout_has_same_location(var, stage), 3857ec681f3Smrg NULL)) 3867ec681f3Smrg return false; 3877ec681f3Smrg } 3887ec681f3Smrg } 3897ec681f3Smrg 3907ec681f3Smrg return true; 3917ec681f3Smrg} 3927ec681f3Smrg 3937ec681f3Smrgstatic bool 3947ec681f3Smrgadd_interface_variables(const struct gl_context *ctx, 3957ec681f3Smrg struct gl_shader_program *prog, 3967ec681f3Smrg struct set *resource_set, 3977ec681f3Smrg unsigned stage, GLenum programInterface) 3987ec681f3Smrg{ 3997ec681f3Smrg struct gl_linked_shader *sh = prog->_LinkedShaders[stage]; 4007ec681f3Smrg if (!sh) 4017ec681f3Smrg return true; 4027ec681f3Smrg 4037ec681f3Smrg nir_shader *nir = sh->Program->nir; 4047ec681f3Smrg assert(nir); 4057ec681f3Smrg 4067ec681f3Smrg switch (programInterface) { 4077ec681f3Smrg case GL_PROGRAM_INPUT: { 4087ec681f3Smrg return add_vars_with_modes(ctx, prog, resource_set, 4097ec681f3Smrg nir, nir_var_shader_in | nir_var_system_value, 4107ec681f3Smrg stage, programInterface); 4117ec681f3Smrg } 4127ec681f3Smrg case GL_PROGRAM_OUTPUT: 4137ec681f3Smrg return add_vars_with_modes(ctx, prog, resource_set, 4147ec681f3Smrg nir, nir_var_shader_out, 4157ec681f3Smrg stage, programInterface); 4167ec681f3Smrg default: 4177ec681f3Smrg assert("!Should not get here"); 4187ec681f3Smrg break; 4197ec681f3Smrg } 4207ec681f3Smrg 4217ec681f3Smrg return false; 4227ec681f3Smrg} 4237ec681f3Smrg 4247ec681f3Smrg/* TODO: as we keep adding features, this method is becoming more and more 4257ec681f3Smrg * similar to its GLSL counterpart at linker.cpp. Eventually it would be good 4267ec681f3Smrg * to check if they could be refactored, and reduce code duplication somehow 4277ec681f3Smrg */ 42801e04c3fSmrgvoid 42901e04c3fSmrgnir_build_program_resource_list(struct gl_context *ctx, 4307ec681f3Smrg struct gl_shader_program *prog, 4317ec681f3Smrg bool rebuild_resourse_list) 43201e04c3fSmrg{ 43301e04c3fSmrg /* Rebuild resource list. */ 4347ec681f3Smrg if (prog->data->ProgramResourceList && rebuild_resourse_list) { 43501e04c3fSmrg ralloc_free(prog->data->ProgramResourceList); 43601e04c3fSmrg prog->data->ProgramResourceList = NULL; 43701e04c3fSmrg prog->data->NumProgramResourceList = 0; 43801e04c3fSmrg } 43901e04c3fSmrg 4407ec681f3Smrg int input_stage = MESA_SHADER_STAGES, output_stage = 0; 4417ec681f3Smrg 4427ec681f3Smrg /* Determine first input and final output stage. These are used to 4437ec681f3Smrg * detect which variables should be enumerated in the resource list 4447ec681f3Smrg * for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT. 4457ec681f3Smrg */ 4467ec681f3Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 4477ec681f3Smrg if (!prog->_LinkedShaders[i]) 4487ec681f3Smrg continue; 4497ec681f3Smrg if (input_stage == MESA_SHADER_STAGES) 4507ec681f3Smrg input_stage = i; 4517ec681f3Smrg output_stage = i; 4527ec681f3Smrg } 4537ec681f3Smrg 4547ec681f3Smrg /* Empty shader, no resources. */ 4557ec681f3Smrg if (input_stage == MESA_SHADER_STAGES && output_stage == 0) 4567ec681f3Smrg return; 4577ec681f3Smrg 4587e102996Smaya struct set *resource_set = _mesa_pointer_set_create(NULL); 45901e04c3fSmrg 4607ec681f3Smrg /* Add inputs and outputs to the resource list. */ 4617ec681f3Smrg if (!add_interface_variables(ctx, prog, resource_set, input_stage, 4627ec681f3Smrg GL_PROGRAM_INPUT)) { 4637ec681f3Smrg return; 4647ec681f3Smrg } 4657ec681f3Smrg 4667ec681f3Smrg if (!add_interface_variables(ctx, prog, resource_set, output_stage, 4677ec681f3Smrg GL_PROGRAM_OUTPUT)) { 4687ec681f3Smrg return; 4697ec681f3Smrg } 4707ec681f3Smrg 4717ec681f3Smrg /* Add transform feedback varyings and buffers. */ 4727ec681f3Smrg if (prog->last_vert_prog) { 4737ec681f3Smrg struct gl_transform_feedback_info *linked_xfb = 4747ec681f3Smrg prog->last_vert_prog->sh.LinkedTransformFeedback; 4757ec681f3Smrg 4767ec681f3Smrg /* Add varyings. */ 4777ec681f3Smrg if (linked_xfb->NumVarying > 0) { 4787ec681f3Smrg for (int i = 0; i < linked_xfb->NumVarying; i++) { 4797ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, 4807ec681f3Smrg GL_TRANSFORM_FEEDBACK_VARYING, 4817ec681f3Smrg &linked_xfb->Varyings[i], 0)) 4827ec681f3Smrg return; 4837ec681f3Smrg } 4847ec681f3Smrg } 4857ec681f3Smrg 4867ec681f3Smrg /* Add buffers. */ 4877ec681f3Smrg for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) { 4887ec681f3Smrg if ((linked_xfb->ActiveBuffers >> i) & 1) { 4897ec681f3Smrg linked_xfb->Buffers[i].Binding = i; 4907ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, 4917ec681f3Smrg GL_TRANSFORM_FEEDBACK_BUFFER, 4927ec681f3Smrg &linked_xfb->Buffers[i], 0)) 4937ec681f3Smrg return; 4947ec681f3Smrg } 4957ec681f3Smrg } 4967ec681f3Smrg } 4977ec681f3Smrg 49801e04c3fSmrg /* Add uniforms 49901e04c3fSmrg * 50001e04c3fSmrg * Here, it is expected that nir_link_uniforms() has already been 50101e04c3fSmrg * called, so that UniformStorage table is already available. 50201e04c3fSmrg */ 5037ec681f3Smrg int top_level_array_base_offset = -1; 5047ec681f3Smrg int top_level_array_size_in_bytes = -1; 5057ec681f3Smrg int second_element_offset = -1; 5067ec681f3Smrg int block_index = -1; 50701e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 50801e04c3fSmrg struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i]; 50901e04c3fSmrg 5107ec681f3Smrg if (uniform->hidden) { 5117ec681f3Smrg for (int j = MESA_SHADER_VERTEX; j < MESA_SHADER_STAGES; j++) { 5127ec681f3Smrg if (!uniform->opaque[j].active || 5137ec681f3Smrg glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE) 5147ec681f3Smrg continue; 5157ec681f3Smrg 5167ec681f3Smrg GLenum type = 5177ec681f3Smrg _mesa_shader_stage_to_subroutine_uniform((gl_shader_stage)j); 5187ec681f3Smrg /* add shader subroutines */ 5197ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, 5207ec681f3Smrg type, uniform, 0)) 5217ec681f3Smrg return; 5227ec681f3Smrg } 5237ec681f3Smrg 5247ec681f3Smrg continue; 5257ec681f3Smrg } 5267ec681f3Smrg 5277ec681f3Smrg if (!link_util_should_add_buffer_variable(prog, uniform, 5287ec681f3Smrg top_level_array_base_offset, 5297ec681f3Smrg top_level_array_size_in_bytes, 5307ec681f3Smrg second_element_offset, block_index)) 53101e04c3fSmrg continue; 53201e04c3fSmrg 5337ec681f3Smrg 5347ec681f3Smrg if (prog->data->UniformStorage[i].offset >= second_element_offset) { 5357ec681f3Smrg top_level_array_base_offset = 5367ec681f3Smrg prog->data->UniformStorage[i].offset; 5377ec681f3Smrg 5387ec681f3Smrg top_level_array_size_in_bytes = 5397ec681f3Smrg prog->data->UniformStorage[i].top_level_array_size * 5407ec681f3Smrg prog->data->UniformStorage[i].top_level_array_stride; 5417ec681f3Smrg 5427ec681f3Smrg /* Set or reset the second element offset. For non arrays this 5437ec681f3Smrg * will be set to -1. 5447ec681f3Smrg */ 5457ec681f3Smrg second_element_offset = top_level_array_size_in_bytes ? 5467ec681f3Smrg top_level_array_base_offset + 5477ec681f3Smrg prog->data->UniformStorage[i].top_level_array_stride : -1; 5487ec681f3Smrg } 5497ec681f3Smrg block_index = uniform->block_index; 5507ec681f3Smrg 5517ec681f3Smrg 5527ec681f3Smrg GLenum interface = uniform->is_shader_storage ? GL_BUFFER_VARIABLE : GL_UNIFORM; 5537ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, interface, uniform, 55401e04c3fSmrg uniform->active_shader_mask)) { 55501e04c3fSmrg return; 55601e04c3fSmrg } 55701e04c3fSmrg } 55801e04c3fSmrg 55901e04c3fSmrg 5607ec681f3Smrg for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) { 5617ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, GL_UNIFORM_BLOCK, 5627ec681f3Smrg &prog->data->UniformBlocks[i], 5637ec681f3Smrg prog->data->UniformBlocks[i].stageref)) 5647ec681f3Smrg return; 5657ec681f3Smrg } 5667ec681f3Smrg 5677ec681f3Smrg for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) { 5687ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, GL_SHADER_STORAGE_BLOCK, 5697ec681f3Smrg &prog->data->ShaderStorageBlocks[i], 5707ec681f3Smrg prog->data->ShaderStorageBlocks[i].stageref)) 5717ec681f3Smrg return; 5727ec681f3Smrg } 5737ec681f3Smrg 5747ec681f3Smrg /* Add atomic counter buffers. */ 5757ec681f3Smrg for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) { 5767ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, GL_ATOMIC_COUNTER_BUFFER, 5777ec681f3Smrg &prog->data->AtomicBuffers[i], 0)) 5787ec681f3Smrg return; 5797ec681f3Smrg } 5807ec681f3Smrg 5817ec681f3Smrg unsigned mask = prog->data->linked_stages; 5827ec681f3Smrg while (mask) { 5837ec681f3Smrg const int i = u_bit_scan(&mask); 5847ec681f3Smrg struct gl_program *p = prog->_LinkedShaders[i]->Program; 5857ec681f3Smrg 5867ec681f3Smrg GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i); 5877ec681f3Smrg for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) { 5887ec681f3Smrg if (!link_util_add_program_resource(prog, resource_set, 5897ec681f3Smrg type, 5907ec681f3Smrg &p->sh.SubroutineFunctions[j], 5917ec681f3Smrg 0)) 5927ec681f3Smrg return; 5937ec681f3Smrg } 5947ec681f3Smrg } 5957ec681f3Smrg 59601e04c3fSmrg _mesa_set_destroy(resource_set, NULL); 59701e04c3fSmrg} 5987ec681f3Smrg 5997ec681f3Smrgbool 6007ec681f3Smrggl_nir_link_spirv(struct gl_context *ctx, struct gl_shader_program *prog, 6017ec681f3Smrg const struct gl_nir_linker_options *options) 6027ec681f3Smrg{ 6037ec681f3Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 6047ec681f3Smrg struct gl_linked_shader *shader = prog->_LinkedShaders[i]; 6057ec681f3Smrg if (shader) { 6067ec681f3Smrg const nir_remove_dead_variables_options opts = { 6077ec681f3Smrg .can_remove_var = can_remove_uniform, 6087ec681f3Smrg }; 6097ec681f3Smrg nir_remove_dead_variables(shader->Program->nir, nir_var_uniform, 6107ec681f3Smrg &opts); 6117ec681f3Smrg } 6127ec681f3Smrg } 6137ec681f3Smrg 6147ec681f3Smrg if (!gl_nir_link_uniform_blocks(ctx, prog)) 6157ec681f3Smrg return false; 6167ec681f3Smrg 6177ec681f3Smrg if (!gl_nir_link_uniforms(ctx, prog, options->fill_parameters)) 6187ec681f3Smrg return false; 6197ec681f3Smrg 6207ec681f3Smrg gl_nir_link_assign_atomic_counter_resources(ctx, prog); 6217ec681f3Smrg gl_nir_link_assign_xfb_resources(ctx, prog); 6227ec681f3Smrg 6237ec681f3Smrg return true; 6247ec681f3Smrg} 6257ec681f3Smrg 6267ec681f3Smrg/** 6277ec681f3Smrg * Validate shader image resources. 6287ec681f3Smrg */ 6297ec681f3Smrgstatic void 6307ec681f3Smrgcheck_image_resources(struct gl_context *ctx, struct gl_shader_program *prog) 6317ec681f3Smrg{ 6327ec681f3Smrg unsigned total_image_units = 0; 6337ec681f3Smrg unsigned fragment_outputs = 0; 6347ec681f3Smrg unsigned total_shader_storage_blocks = 0; 6357ec681f3Smrg 6367ec681f3Smrg if (!ctx->Extensions.ARB_shader_image_load_store) 6377ec681f3Smrg return; 6387ec681f3Smrg 6397ec681f3Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 6407ec681f3Smrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 6417ec681f3Smrg if (!sh) 6427ec681f3Smrg continue; 6437ec681f3Smrg 6447ec681f3Smrg total_image_units += sh->Program->info.num_images; 6457ec681f3Smrg total_shader_storage_blocks += sh->Program->info.num_ssbos; 6467ec681f3Smrg } 6477ec681f3Smrg 6487ec681f3Smrg if (total_image_units > ctx->Const.MaxCombinedImageUniforms) 6497ec681f3Smrg linker_error(prog, "Too many combined image uniforms\n"); 6507ec681f3Smrg 6517ec681f3Smrg struct gl_linked_shader *frag_sh = 6527ec681f3Smrg prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; 6537ec681f3Smrg if (frag_sh) { 6547ec681f3Smrg uint64_t frag_outputs_written = frag_sh->Program->info.outputs_written; 6557ec681f3Smrg fragment_outputs = util_bitcount64(frag_outputs_written); 6567ec681f3Smrg } 6577ec681f3Smrg 6587ec681f3Smrg if (total_image_units + fragment_outputs + total_shader_storage_blocks > 6597ec681f3Smrg ctx->Const.MaxCombinedShaderOutputResources) 6607ec681f3Smrg linker_error(prog, "Too many combined image uniforms, shader storage " 6617ec681f3Smrg " buffers and fragment outputs\n"); 6627ec681f3Smrg} 6637ec681f3Smrg 6647ec681f3Smrgbool 6657ec681f3Smrggl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog) 6667ec681f3Smrg{ 6677ec681f3Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 6687ec681f3Smrg struct gl_linked_shader *shader = prog->_LinkedShaders[i]; 6697ec681f3Smrg if (shader) { 6707ec681f3Smrg const nir_remove_dead_variables_options opts = { 6717ec681f3Smrg .can_remove_var = can_remove_uniform, 6727ec681f3Smrg }; 6737ec681f3Smrg nir_remove_dead_variables(shader->Program->nir, nir_var_uniform, 6747ec681f3Smrg &opts); 6757ec681f3Smrg } 6767ec681f3Smrg } 6777ec681f3Smrg 6787ec681f3Smrg if (!gl_nir_link_uniforms(ctx, prog, true)) 6797ec681f3Smrg return false; 6807ec681f3Smrg 6817ec681f3Smrg link_util_calculate_subroutine_compat(prog); 6827ec681f3Smrg link_util_check_uniform_resources(ctx, prog); 6837ec681f3Smrg link_util_check_subroutine_resources(prog); 6847ec681f3Smrg check_image_resources(ctx, prog); 6857ec681f3Smrg gl_nir_link_assign_atomic_counter_resources(ctx, prog); 6867ec681f3Smrg gl_nir_link_check_atomic_counter_resources(ctx, prog); 6877ec681f3Smrg 6887ec681f3Smrg if (prog->data->LinkStatus == LINKING_FAILURE) 6897ec681f3Smrg return false; 6907ec681f3Smrg 6917ec681f3Smrg return true; 6927ec681f3Smrg} 693