Path: blob/21.2-virgl/src/compiler/glsl/gl_nir_linker.c
4545 views
/*1* Copyright © 2018 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "nir.h"24#include "gl_nir.h"25#include "gl_nir_linker.h"26#include "linker_util.h"27#include "main/mtypes.h"28#include "main/shaderobj.h"29#include "ir_uniform.h" /* for gl_uniform_storage */3031/**32* This file included general link methods, using NIR, instead of IR as33* the counter-part glsl/linker.cpp34*/3536static bool37can_remove_uniform(nir_variable *var, UNUSED void *data)38{39/* Section 2.11.6 (Uniform Variables) of the OpenGL ES 3.0.3 spec40* says:41*42* "All members of a named uniform block declared with a shared or43* std140 layout qualifier are considered active, even if they are not44* referenced in any shader in the program. The uniform block itself is45* also considered active, even if no member of the block is46* referenced."47*48* Although the spec doesn't state it std430 layouts are expect to behave49* the same way. If the variable is in a uniform block with one of those50* layouts, do not eliminate it.51*/52if (nir_variable_is_in_block(var) &&53(glsl_get_ifc_packing(var->interface_type) !=54GLSL_INTERFACE_PACKING_PACKED))55return false;5657if (glsl_get_base_type(glsl_without_array(var->type)) ==58GLSL_TYPE_SUBROUTINE)59return false;6061/* Uniform initializers could get used by another stage */62if (var->constant_initializer)63return false;6465return true;66}6768/**69* Built-in / reserved GL variables names start with "gl_"70*/71static inline bool72is_gl_identifier(const char *s)73{74return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_';75}7677static bool78inout_has_same_location(const nir_variable *var, unsigned stage)79{80if (!var->data.patch &&81((var->data.mode == nir_var_shader_out &&82stage == MESA_SHADER_TESS_CTRL) ||83(var->data.mode == nir_var_shader_in &&84(stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL ||85stage == MESA_SHADER_GEOMETRY))))86return true;87else88return false;89}9091/**92* Create gl_shader_variable from nir_variable.93*/94static struct gl_shader_variable *95create_shader_variable(struct gl_shader_program *shProg,96const nir_variable *in,97const char *name, const struct glsl_type *type,98const struct glsl_type *interface_type,99bool use_implicit_location, int location,100const struct glsl_type *outermost_struct_type)101{102/* Allocate zero-initialized memory to ensure that bitfield padding103* is zero.104*/105struct gl_shader_variable *out = rzalloc(shProg,106struct gl_shader_variable);107if (!out)108return NULL;109110/* Since gl_VertexID may be lowered to gl_VertexIDMESA, but applications111* expect to see gl_VertexID in the program resource list. Pretend.112*/113if (in->data.mode == nir_var_system_value &&114in->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {115out->name = ralloc_strdup(shProg, "gl_VertexID");116} else if ((in->data.mode == nir_var_shader_out &&117in->data.location == VARYING_SLOT_TESS_LEVEL_OUTER) ||118(in->data.mode == nir_var_system_value &&119in->data.location == SYSTEM_VALUE_TESS_LEVEL_OUTER)) {120out->name = ralloc_strdup(shProg, "gl_TessLevelOuter");121type = glsl_array_type(glsl_float_type(), 4, 0);122} else if ((in->data.mode == nir_var_shader_out &&123in->data.location == VARYING_SLOT_TESS_LEVEL_INNER) ||124(in->data.mode == nir_var_system_value &&125in->data.location == SYSTEM_VALUE_TESS_LEVEL_INNER)) {126out->name = ralloc_strdup(shProg, "gl_TessLevelInner");127type = glsl_array_type(glsl_float_type(), 2, 0);128} else {129out->name = ralloc_strdup(shProg, name);130}131132if (!out->name)133return NULL;134135/* The ARB_program_interface_query spec says:136*137* "Not all active variables are assigned valid locations; the138* following variables will have an effective location of -1:139*140* * uniforms declared as atomic counters;141*142* * members of a uniform block;143*144* * built-in inputs, outputs, and uniforms (starting with "gl_"); and145*146* * inputs or outputs not declared with a "location" layout147* qualifier, except for vertex shader inputs and fragment shader148* outputs."149*/150if (glsl_get_base_type(in->type) == GLSL_TYPE_ATOMIC_UINT ||151is_gl_identifier(in->name) ||152!(in->data.explicit_location || use_implicit_location)) {153out->location = -1;154} else {155out->location = location;156}157158out->type = type;159out->outermost_struct_type = outermost_struct_type;160out->interface_type = interface_type;161out->component = in->data.location_frac;162out->index = in->data.index;163out->patch = in->data.patch;164out->mode = in->data.mode;165out->interpolation = in->data.interpolation;166out->precision = in->data.precision;167out->explicit_location = in->data.explicit_location;168169return out;170}171172static bool173add_shader_variable(const struct gl_context *ctx,174struct gl_shader_program *shProg,175struct set *resource_set,176unsigned stage_mask,177GLenum programInterface, nir_variable *var,178const char *name, const struct glsl_type *type,179bool use_implicit_location, int location,180bool inouts_share_location,181const struct glsl_type *outermost_struct_type)182{183const struct glsl_type *interface_type = var->interface_type;184185if (outermost_struct_type == NULL) {186if (var->data.from_named_ifc_block) {187const char *interface_name = glsl_get_type_name(interface_type);188189if (glsl_type_is_array(interface_type)) {190/* Issue #16 of the ARB_program_interface_query spec says:191*192* "* If a variable is a member of an interface block without an193* instance name, it is enumerated using just the variable name.194*195* * If a variable is a member of an interface block with an196* instance name, it is enumerated as "BlockName.Member", where197* "BlockName" is the name of the interface block (not the198* instance name) and "Member" is the name of the variable."199*200* In particular, it indicates that it should be "BlockName",201* not "BlockName[array length]". The conformance suite and202* dEQP both require this behavior.203*204* Here, we unwrap the extra array level added by named interface205* block array lowering so we have the correct variable type. We206* also unwrap the interface type when constructing the name.207*208* We leave interface_type the same so that ES 3.x SSO pipeline209* validation can enforce the rules requiring array length to210* match on interface blocks.211*/212type = glsl_get_array_element(type);213214interface_name =215glsl_get_type_name(glsl_get_array_element(interface_type));216}217218name = ralloc_asprintf(shProg, "%s.%s", interface_name, name);219}220}221222switch (glsl_get_base_type(type)) {223case GLSL_TYPE_STRUCT: {224/* The ARB_program_interface_query spec says:225*226* "For an active variable declared as a structure, a separate entry227* will be generated for each active structure member. The name of228* each entry is formed by concatenating the name of the structure,229* the "." character, and the name of the structure member. If a230* structure member to enumerate is itself a structure or array,231* these enumeration rules are applied recursively."232*/233if (outermost_struct_type == NULL)234outermost_struct_type = type;235236unsigned field_location = location;237for (unsigned i = 0; i < glsl_get_length(type); i++) {238const struct glsl_type *field_type = glsl_get_struct_field(type, i);239const struct glsl_struct_field *field =240glsl_get_struct_field_data(type, i);241242char *field_name = ralloc_asprintf(shProg, "%s.%s", name, field->name);243if (!add_shader_variable(ctx, shProg, resource_set,244stage_mask, programInterface,245var, field_name, field_type,246use_implicit_location, field_location,247false, outermost_struct_type))248return false;249250field_location += glsl_count_attribute_slots(field_type, false);251}252return true;253}254255case GLSL_TYPE_ARRAY: {256/* The ARB_program_interface_query spec says:257*258* "For an active variable declared as an array of basic types, a259* single entry will be generated, with its name string formed by260* concatenating the name of the array and the string "[0]"."261*262* "For an active variable declared as an array of an aggregate data263* type (structures or arrays), a separate entry will be generated264* for each active array element, unless noted immediately below.265* The name of each entry is formed by concatenating the name of266* the array, the "[" character, an integer identifying the element267* number, and the "]" character. These enumeration rules are268* applied recursively, treating each enumerated array element as a269* separate active variable."270*/271const struct glsl_type *array_type = glsl_get_array_element(type);272if (glsl_get_base_type(array_type) == GLSL_TYPE_STRUCT ||273glsl_get_base_type(array_type) == GLSL_TYPE_ARRAY) {274unsigned elem_location = location;275unsigned stride = inouts_share_location ? 0 :276glsl_count_attribute_slots(array_type, false);277for (unsigned i = 0; i < glsl_get_length(type); i++) {278char *elem = ralloc_asprintf(shProg, "%s[%d]", name, i);279if (!add_shader_variable(ctx, shProg, resource_set,280stage_mask, programInterface,281var, elem, array_type,282use_implicit_location, elem_location,283false, outermost_struct_type))284return false;285elem_location += stride;286}287return true;288}289}290FALLTHROUGH;291292default: {293/* The ARB_program_interface_query spec says:294*295* "For an active variable declared as a single instance of a basic296* type, a single entry will be generated, using the variable name297* from the shader source."298*/299struct gl_shader_variable *sha_v =300create_shader_variable(shProg, var, name, type, interface_type,301use_implicit_location, location,302outermost_struct_type);303if (!sha_v)304return false;305306return link_util_add_program_resource(shProg, resource_set,307programInterface, sha_v, stage_mask);308}309}310}311312static bool313add_vars_with_modes(const struct gl_context *ctx,314struct gl_shader_program *prog, struct set *resource_set,315nir_shader *nir, nir_variable_mode modes,316unsigned stage, GLenum programInterface)317{318nir_foreach_variable_with_modes(var, nir, modes) {319if (var->data.how_declared == nir_var_hidden)320continue;321322int loc_bias = 0;323switch(var->data.mode) {324case nir_var_system_value:325case nir_var_shader_in:326if (programInterface != GL_PROGRAM_INPUT)327continue;328loc_bias = (stage == MESA_SHADER_VERTEX) ? VERT_ATTRIB_GENERIC0329: VARYING_SLOT_VAR0;330break;331case nir_var_shader_out:332if (programInterface != GL_PROGRAM_OUTPUT)333continue;334loc_bias = (stage == MESA_SHADER_FRAGMENT) ? FRAG_RESULT_DATA0335: VARYING_SLOT_VAR0;336break;337default:338continue;339}340341if (var->data.patch)342loc_bias = VARYING_SLOT_PATCH0;343344if (prog->data->spirv) {345struct gl_shader_variable *sh_var =346rzalloc(prog, struct gl_shader_variable);347348/* In the ARB_gl_spirv spec, names are considered optional debug info, so349* the linker needs to work without them. Returning them is optional.350* For simplicity, we ignore names.351*/352sh_var->name = NULL;353sh_var->type = var->type;354sh_var->location = var->data.location - loc_bias;355sh_var->index = var->data.index;356357if (!link_util_add_program_resource(prog, resource_set,358programInterface,359sh_var, 1 << stage)) {360return false;361}362} else {363/* Skip packed varyings, packed varyings are handled separately364* by add_packed_varyings in the GLSL IR365* build_program_resource_list() call.366* TODO: handle packed varyings here instead. We likely want a NIR367* based packing pass first.368*/369if (strncmp(var->name, "packed:", 7) == 0)370continue;371372const bool vs_input_or_fs_output =373(stage == MESA_SHADER_VERTEX &&374var->data.mode == nir_var_shader_in) ||375(stage == MESA_SHADER_FRAGMENT &&376var->data.mode == nir_var_shader_out);377378if (!add_shader_variable(ctx, prog, resource_set,3791 << stage, programInterface,380var, var->name, var->type,381vs_input_or_fs_output,382var->data.location - loc_bias,383inout_has_same_location(var, stage),384NULL))385return false;386}387}388389return true;390}391392static bool393add_interface_variables(const struct gl_context *ctx,394struct gl_shader_program *prog,395struct set *resource_set,396unsigned stage, GLenum programInterface)397{398struct gl_linked_shader *sh = prog->_LinkedShaders[stage];399if (!sh)400return true;401402nir_shader *nir = sh->Program->nir;403assert(nir);404405switch (programInterface) {406case GL_PROGRAM_INPUT: {407return add_vars_with_modes(ctx, prog, resource_set,408nir, nir_var_shader_in | nir_var_system_value,409stage, programInterface);410}411case GL_PROGRAM_OUTPUT:412return add_vars_with_modes(ctx, prog, resource_set,413nir, nir_var_shader_out,414stage, programInterface);415default:416assert("!Should not get here");417break;418}419420return false;421}422423/* TODO: as we keep adding features, this method is becoming more and more424* similar to its GLSL counterpart at linker.cpp. Eventually it would be good425* to check if they could be refactored, and reduce code duplication somehow426*/427void428nir_build_program_resource_list(struct gl_context *ctx,429struct gl_shader_program *prog,430bool rebuild_resourse_list)431{432/* Rebuild resource list. */433if (prog->data->ProgramResourceList && rebuild_resourse_list) {434ralloc_free(prog->data->ProgramResourceList);435prog->data->ProgramResourceList = NULL;436prog->data->NumProgramResourceList = 0;437}438439int input_stage = MESA_SHADER_STAGES, output_stage = 0;440441/* Determine first input and final output stage. These are used to442* detect which variables should be enumerated in the resource list443* for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.444*/445for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {446if (!prog->_LinkedShaders[i])447continue;448if (input_stage == MESA_SHADER_STAGES)449input_stage = i;450output_stage = i;451}452453/* Empty shader, no resources. */454if (input_stage == MESA_SHADER_STAGES && output_stage == 0)455return;456457struct set *resource_set = _mesa_pointer_set_create(NULL);458459/* Add inputs and outputs to the resource list. */460if (!add_interface_variables(ctx, prog, resource_set, input_stage,461GL_PROGRAM_INPUT)) {462return;463}464465if (!add_interface_variables(ctx, prog, resource_set, output_stage,466GL_PROGRAM_OUTPUT)) {467return;468}469470/* Add transform feedback varyings and buffers. */471if (prog->last_vert_prog) {472struct gl_transform_feedback_info *linked_xfb =473prog->last_vert_prog->sh.LinkedTransformFeedback;474475/* Add varyings. */476if (linked_xfb->NumVarying > 0) {477for (int i = 0; i < linked_xfb->NumVarying; i++) {478if (!link_util_add_program_resource(prog, resource_set,479GL_TRANSFORM_FEEDBACK_VARYING,480&linked_xfb->Varyings[i], 0))481return;482}483}484485/* Add buffers. */486for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {487if ((linked_xfb->ActiveBuffers >> i) & 1) {488linked_xfb->Buffers[i].Binding = i;489if (!link_util_add_program_resource(prog, resource_set,490GL_TRANSFORM_FEEDBACK_BUFFER,491&linked_xfb->Buffers[i], 0))492return;493}494}495}496497/* Add uniforms498*499* Here, it is expected that nir_link_uniforms() has already been500* called, so that UniformStorage table is already available.501*/502int top_level_array_base_offset = -1;503int top_level_array_size_in_bytes = -1;504int second_element_offset = -1;505int block_index = -1;506for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {507struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];508509if (uniform->hidden) {510for (int j = MESA_SHADER_VERTEX; j < MESA_SHADER_STAGES; j++) {511if (!uniform->opaque[j].active ||512glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE)513continue;514515GLenum type =516_mesa_shader_stage_to_subroutine_uniform((gl_shader_stage)j);517/* add shader subroutines */518if (!link_util_add_program_resource(prog, resource_set,519type, uniform, 0))520return;521}522523continue;524}525526if (!link_util_should_add_buffer_variable(prog, uniform,527top_level_array_base_offset,528top_level_array_size_in_bytes,529second_element_offset, block_index))530continue;531532533if (prog->data->UniformStorage[i].offset >= second_element_offset) {534top_level_array_base_offset =535prog->data->UniformStorage[i].offset;536537top_level_array_size_in_bytes =538prog->data->UniformStorage[i].top_level_array_size *539prog->data->UniformStorage[i].top_level_array_stride;540541/* Set or reset the second element offset. For non arrays this542* will be set to -1.543*/544second_element_offset = top_level_array_size_in_bytes ?545top_level_array_base_offset +546prog->data->UniformStorage[i].top_level_array_stride : -1;547}548block_index = uniform->block_index;549550551GLenum interface = uniform->is_shader_storage ? GL_BUFFER_VARIABLE : GL_UNIFORM;552if (!link_util_add_program_resource(prog, resource_set, interface, uniform,553uniform->active_shader_mask)) {554return;555}556}557558559for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {560if (!link_util_add_program_resource(prog, resource_set, GL_UNIFORM_BLOCK,561&prog->data->UniformBlocks[i],562prog->data->UniformBlocks[i].stageref))563return;564}565566for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {567if (!link_util_add_program_resource(prog, resource_set, GL_SHADER_STORAGE_BLOCK,568&prog->data->ShaderStorageBlocks[i],569prog->data->ShaderStorageBlocks[i].stageref))570return;571}572573/* Add atomic counter buffers. */574for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) {575if (!link_util_add_program_resource(prog, resource_set, GL_ATOMIC_COUNTER_BUFFER,576&prog->data->AtomicBuffers[i], 0))577return;578}579580unsigned mask = prog->data->linked_stages;581while (mask) {582const int i = u_bit_scan(&mask);583struct gl_program *p = prog->_LinkedShaders[i]->Program;584585GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i);586for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {587if (!link_util_add_program_resource(prog, resource_set,588type,589&p->sh.SubroutineFunctions[j],5900))591return;592}593}594595_mesa_set_destroy(resource_set, NULL);596}597598bool599gl_nir_link_spirv(struct gl_context *ctx, struct gl_shader_program *prog,600const struct gl_nir_linker_options *options)601{602for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {603struct gl_linked_shader *shader = prog->_LinkedShaders[i];604if (shader) {605const nir_remove_dead_variables_options opts = {606.can_remove_var = can_remove_uniform,607};608nir_remove_dead_variables(shader->Program->nir, nir_var_uniform,609&opts);610}611}612613if (!gl_nir_link_uniform_blocks(ctx, prog))614return false;615616if (!gl_nir_link_uniforms(ctx, prog, options->fill_parameters))617return false;618619gl_nir_link_assign_atomic_counter_resources(ctx, prog);620gl_nir_link_assign_xfb_resources(ctx, prog);621622return true;623}624625/**626* Validate shader image resources.627*/628static void629check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)630{631unsigned total_image_units = 0;632unsigned fragment_outputs = 0;633unsigned total_shader_storage_blocks = 0;634635if (!ctx->Extensions.ARB_shader_image_load_store)636return;637638for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {639struct gl_linked_shader *sh = prog->_LinkedShaders[i];640if (!sh)641continue;642643total_image_units += sh->Program->info.num_images;644total_shader_storage_blocks += sh->Program->info.num_ssbos;645}646647if (total_image_units > ctx->Const.MaxCombinedImageUniforms)648linker_error(prog, "Too many combined image uniforms\n");649650struct gl_linked_shader *frag_sh =651prog->_LinkedShaders[MESA_SHADER_FRAGMENT];652if (frag_sh) {653uint64_t frag_outputs_written = frag_sh->Program->info.outputs_written;654fragment_outputs = util_bitcount64(frag_outputs_written);655}656657if (total_image_units + fragment_outputs + total_shader_storage_blocks >658ctx->Const.MaxCombinedShaderOutputResources)659linker_error(prog, "Too many combined image uniforms, shader storage "660" buffers and fragment outputs\n");661}662663bool664gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog)665{666for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {667struct gl_linked_shader *shader = prog->_LinkedShaders[i];668if (shader) {669const nir_remove_dead_variables_options opts = {670.can_remove_var = can_remove_uniform,671};672nir_remove_dead_variables(shader->Program->nir, nir_var_uniform,673&opts);674}675}676677if (!gl_nir_link_uniforms(ctx, prog, true))678return false;679680link_util_calculate_subroutine_compat(prog);681link_util_check_uniform_resources(ctx, prog);682link_util_check_subroutine_resources(prog);683check_image_resources(ctx, prog);684gl_nir_link_assign_atomic_counter_resources(ctx, prog);685gl_nir_link_check_atomic_counter_resources(ctx, prog);686687if (prog->data->LinkStatus == LINKING_FAILURE)688return false;689690return true;691}692693694