2 * Copyright © 2018 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 #include "gl_nir_linker.h"
27 #include "linker_util.h"
28 #include "main/mtypes.h"
29 #include "main/shaderobj.h"
30 #include "ir_uniform.h" /* for gl_uniform_storage */
33 * This file included general link methods, using NIR, instead of IR as
34 * the counter-part glsl/linker.cpp
38 can_remove_uniform(nir_variable
*var
)
40 /* Section 2.11.6 (Uniform Variables) of the OpenGL ES 3.0.3 spec
43 * "All members of a named uniform block declared with a shared or
44 * std140 layout qualifier are considered active, even if they are not
45 * referenced in any shader in the program. The uniform block itself is
46 * also considered active, even if no member of the block is
49 * Although the spec doesn't state it std430 layouts are expect to behave
50 * the same way. If the variable is in a uniform block with one of those
51 * layouts, do not eliminate it.
53 if (nir_variable_is_in_block(var
) &&
54 (glsl_get_ifc_packing(var
->interface_type
) !=
55 GLSL_INTERFACE_PACKING_PACKED
))
58 if (glsl_get_base_type(glsl_without_array(var
->type
)) ==
62 /* Uniform initializers could get used by another stage */
63 if (var
->constant_initializer
)
70 * Built-in / reserved GL variables names start with "gl_"
73 is_gl_identifier(const char *s
)
75 return s
&& s
[0] == 'g' && s
[1] == 'l' && s
[2] == '_';
79 inout_has_same_location(const nir_variable
*var
, unsigned stage
)
81 if (!var
->data
.patch
&&
82 ((var
->data
.mode
== nir_var_shader_out
&&
83 stage
== MESA_SHADER_TESS_CTRL
) ||
84 (var
->data
.mode
== nir_var_shader_in
&&
85 (stage
== MESA_SHADER_TESS_CTRL
|| stage
== MESA_SHADER_TESS_EVAL
||
86 stage
== MESA_SHADER_GEOMETRY
))))
93 * Create gl_shader_variable from nir_variable.
95 static struct gl_shader_variable
*
96 create_shader_variable(struct gl_shader_program
*shProg
,
97 const nir_variable
*in
,
98 const char *name
, const struct glsl_type
*type
,
99 const struct glsl_type
*interface_type
,
100 bool use_implicit_location
, int location
,
101 const struct glsl_type
*outermost_struct_type
)
103 /* Allocate zero-initialized memory to ensure that bitfield padding
106 struct gl_shader_variable
*out
= rzalloc(shProg
,
107 struct gl_shader_variable
);
111 /* Since gl_VertexID may be lowered to gl_VertexIDMESA, but applications
112 * expect to see gl_VertexID in the program resource list. Pretend.
114 if (in
->data
.mode
== nir_var_system_value
&&
115 in
->data
.location
== SYSTEM_VALUE_VERTEX_ID_ZERO_BASE
) {
116 out
->name
= ralloc_strdup(shProg
, "gl_VertexID");
117 } else if ((in
->data
.mode
== nir_var_shader_out
&&
118 in
->data
.location
== VARYING_SLOT_TESS_LEVEL_OUTER
) ||
119 (in
->data
.mode
== nir_var_system_value
&&
120 in
->data
.location
== SYSTEM_VALUE_TESS_LEVEL_OUTER
)) {
121 out
->name
= ralloc_strdup(shProg
, "gl_TessLevelOuter");
122 type
= glsl_array_type(glsl_float_type(), 4, 0);
123 } else if ((in
->data
.mode
== nir_var_shader_out
&&
124 in
->data
.location
== VARYING_SLOT_TESS_LEVEL_INNER
) ||
125 (in
->data
.mode
== nir_var_system_value
&&
126 in
->data
.location
== SYSTEM_VALUE_TESS_LEVEL_INNER
)) {
127 out
->name
= ralloc_strdup(shProg
, "gl_TessLevelInner");
128 type
= glsl_array_type(glsl_float_type(), 2, 0);
130 out
->name
= ralloc_strdup(shProg
, name
);
136 /* The ARB_program_interface_query spec says:
138 * "Not all active variables are assigned valid locations; the
139 * following variables will have an effective location of -1:
141 * * uniforms declared as atomic counters;
143 * * members of a uniform block;
145 * * built-in inputs, outputs, and uniforms (starting with "gl_"); and
147 * * inputs or outputs not declared with a "location" layout
148 * qualifier, except for vertex shader inputs and fragment shader
151 if (glsl_get_base_type(in
->type
) == GLSL_TYPE_ATOMIC_UINT
||
152 is_gl_identifier(in
->name
) ||
153 !(in
->data
.explicit_location
|| use_implicit_location
)) {
156 out
->location
= location
;
160 out
->outermost_struct_type
= outermost_struct_type
;
161 out
->interface_type
= interface_type
;
162 out
->component
= in
->data
.location_frac
;
163 out
->index
= in
->data
.index
;
164 out
->patch
= in
->data
.patch
;
165 out
->mode
= in
->data
.mode
;
166 out
->interpolation
= in
->data
.interpolation
;
167 out
->precision
= in
->data
.precision
;
168 out
->explicit_location
= in
->data
.explicit_location
;
174 add_shader_variable(const struct gl_context
*ctx
,
175 struct gl_shader_program
*shProg
,
176 struct set
*resource_set
,
178 GLenum programInterface
, nir_variable
*var
,
179 const char *name
, const struct glsl_type
*type
,
180 bool use_implicit_location
, int location
,
181 bool inouts_share_location
,
182 const struct glsl_type
*outermost_struct_type
)
184 const struct glsl_type
*interface_type
= var
->interface_type
;
186 if (outermost_struct_type
== NULL
) {
187 if (var
->data
.from_named_ifc_block
) {
188 const char *interface_name
= glsl_get_type_name(interface_type
);
190 if (glsl_type_is_array(interface_type
)) {
191 /* Issue #16 of the ARB_program_interface_query spec says:
193 * "* If a variable is a member of an interface block without an
194 * instance name, it is enumerated using just the variable name.
196 * * If a variable is a member of an interface block with an
197 * instance name, it is enumerated as "BlockName.Member", where
198 * "BlockName" is the name of the interface block (not the
199 * instance name) and "Member" is the name of the variable."
201 * In particular, it indicates that it should be "BlockName",
202 * not "BlockName[array length]". The conformance suite and
203 * dEQP both require this behavior.
205 * Here, we unwrap the extra array level added by named interface
206 * block array lowering so we have the correct variable type. We
207 * also unwrap the interface type when constructing the name.
209 * We leave interface_type the same so that ES 3.x SSO pipeline
210 * validation can enforce the rules requiring array length to
211 * match on interface blocks.
213 type
= glsl_get_array_element(type
);
216 glsl_get_type_name(glsl_get_array_element(interface_type
));
219 name
= ralloc_asprintf(shProg
, "%s.%s", interface_name
, name
);
223 switch (glsl_get_base_type(type
)) {
224 case GLSL_TYPE_STRUCT
: {
225 /* The ARB_program_interface_query spec says:
227 * "For an active variable declared as a structure, a separate entry
228 * will be generated for each active structure member. The name of
229 * each entry is formed by concatenating the name of the structure,
230 * the "." character, and the name of the structure member. If a
231 * structure member to enumerate is itself a structure or array,
232 * these enumeration rules are applied recursively."
234 if (outermost_struct_type
== NULL
)
235 outermost_struct_type
= type
;
237 unsigned field_location
= location
;
238 for (unsigned i
= 0; i
< glsl_get_length(type
); i
++) {
239 const struct glsl_type
*field_type
= glsl_get_struct_field(type
, i
);
240 const struct glsl_struct_field
*field
=
241 glsl_get_struct_field_data(type
, i
);
243 char *field_name
= ralloc_asprintf(shProg
, "%s.%s", name
, field
->name
);
244 if (!add_shader_variable(ctx
, shProg
, resource_set
,
245 stage_mask
, programInterface
,
246 var
, field_name
, field_type
,
247 use_implicit_location
, field_location
,
248 false, outermost_struct_type
))
251 field_location
+= glsl_count_attribute_slots(field_type
, false);
256 case GLSL_TYPE_ARRAY
: {
257 /* The ARB_program_interface_query spec says:
259 * "For an active variable declared as an array of basic types, a
260 * single entry will be generated, with its name string formed by
261 * concatenating the name of the array and the string "[0]"."
263 * "For an active variable declared as an array of an aggregate data
264 * type (structures or arrays), a separate entry will be generated
265 * for each active array element, unless noted immediately below.
266 * The name of each entry is formed by concatenating the name of
267 * the array, the "[" character, an integer identifying the element
268 * number, and the "]" character. These enumeration rules are
269 * applied recursively, treating each enumerated array element as a
270 * separate active variable."
272 const struct glsl_type
*array_type
= glsl_get_array_element(type
);
273 if (glsl_get_base_type(array_type
) == GLSL_TYPE_STRUCT
||
274 glsl_get_base_type(array_type
) == GLSL_TYPE_ARRAY
) {
275 unsigned elem_location
= location
;
276 unsigned stride
= inouts_share_location
? 0 :
277 glsl_count_attribute_slots(array_type
, false);
278 for (unsigned i
= 0; i
< glsl_get_length(type
); i
++) {
279 char *elem
= ralloc_asprintf(shProg
, "%s[%d]", name
, i
);
280 if (!add_shader_variable(ctx
, shProg
, resource_set
,
281 stage_mask
, programInterface
,
282 var
, elem
, array_type
,
283 use_implicit_location
, elem_location
,
284 false, outermost_struct_type
))
286 elem_location
+= stride
;
294 /* The ARB_program_interface_query spec says:
296 * "For an active variable declared as a single instance of a basic
297 * type, a single entry will be generated, using the variable name
298 * from the shader source."
300 struct gl_shader_variable
*sha_v
=
301 create_shader_variable(shProg
, var
, name
, type
, interface_type
,
302 use_implicit_location
, location
,
303 outermost_struct_type
);
307 return link_util_add_program_resource(shProg
, resource_set
,
308 programInterface
, sha_v
, stage_mask
);
314 add_vars_from_list(const struct gl_context
*ctx
,
315 struct gl_shader_program
*prog
, struct set
*resource_set
,
316 const struct exec_list
*var_list
, unsigned stage
,
317 GLenum programInterface
)
319 nir_foreach_variable(var
, var_list
) {
320 if (var
->data
.how_declared
== nir_var_hidden
)
324 switch(var
->data
.mode
) {
325 case nir_var_system_value
:
326 case nir_var_shader_in
:
327 if (programInterface
!= GL_PROGRAM_INPUT
)
329 loc_bias
= (stage
== MESA_SHADER_VERTEX
) ? VERT_ATTRIB_GENERIC0
332 case nir_var_shader_out
:
333 if (programInterface
!= GL_PROGRAM_OUTPUT
)
335 loc_bias
= (stage
== MESA_SHADER_FRAGMENT
) ? FRAG_RESULT_DATA0
343 loc_bias
= VARYING_SLOT_PATCH0
;
345 if (prog
->data
->spirv
) {
346 struct gl_shader_variable
*sh_var
=
347 rzalloc(prog
, struct gl_shader_variable
);
349 /* In the ARB_gl_spirv spec, names are considered optional debug info, so
350 * the linker needs to work without them. Returning them is optional.
351 * For simplicity, we ignore names.
354 sh_var
->type
= var
->type
;
355 sh_var
->location
= var
->data
.location
- loc_bias
;
356 sh_var
->index
= var
->data
.index
;
358 if (!link_util_add_program_resource(prog
, resource_set
,
360 sh_var
, 1 << stage
)) {
364 /* Skip packed varyings, packed varyings are handled separately
365 * by add_packed_varyings in the GLSL IR
366 * build_program_resource_list() call.
367 * TODO: handle packed varyings here instead. We likely want a NIR
368 * based packing pass first.
370 if (strncmp(var
->name
, "packed:", 7) == 0)
373 const bool vs_input_or_fs_output
=
374 (stage
== MESA_SHADER_VERTEX
&&
375 var
->data
.mode
== nir_var_shader_in
) ||
376 (stage
== MESA_SHADER_FRAGMENT
&&
377 var
->data
.mode
== nir_var_shader_out
);
379 if (!add_shader_variable(ctx
, prog
, resource_set
,
380 1 << stage
, programInterface
,
381 var
, var
->name
, var
->type
,
382 vs_input_or_fs_output
,
383 var
->data
.location
- loc_bias
,
384 inout_has_same_location(var
, stage
),
394 add_interface_variables(const struct gl_context
*ctx
,
395 struct gl_shader_program
*prog
,
396 struct set
*resource_set
,
397 unsigned stage
, GLenum programInterface
)
399 struct gl_linked_shader
*sh
= prog
->_LinkedShaders
[stage
];
403 nir_shader
*nir
= sh
->Program
->nir
;
406 switch (programInterface
) {
407 case GL_PROGRAM_INPUT
: {
408 bool result
= add_vars_from_list(ctx
, prog
, resource_set
,
409 &nir
->inputs
, stage
, programInterface
);
410 result
&= add_vars_from_list(ctx
, prog
, resource_set
, &nir
->system_values
,
411 stage
, programInterface
);
414 case GL_PROGRAM_OUTPUT
:
415 return add_vars_from_list(ctx
, prog
, resource_set
, &nir
->outputs
, stage
,
418 assert("!Should not get here");
425 /* TODO: as we keep adding features, this method is becoming more and more
426 * similar to its GLSL counterpart at linker.cpp. Eventually it would be good
427 * to check if they could be refactored, and reduce code duplication somehow
430 nir_build_program_resource_list(struct gl_context
*ctx
,
431 struct gl_shader_program
*prog
,
432 bool rebuild_resourse_list
)
434 /* Rebuild resource list. */
435 if (prog
->data
->ProgramResourceList
&& rebuild_resourse_list
) {
436 ralloc_free(prog
->data
->ProgramResourceList
);
437 prog
->data
->ProgramResourceList
= NULL
;
438 prog
->data
->NumProgramResourceList
= 0;
441 int input_stage
= MESA_SHADER_STAGES
, output_stage
= 0;
443 /* Determine first input and final output stage. These are used to
444 * detect which variables should be enumerated in the resource list
445 * for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.
447 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
448 if (!prog
->_LinkedShaders
[i
])
450 if (input_stage
== MESA_SHADER_STAGES
)
455 /* Empty shader, no resources. */
456 if (input_stage
== MESA_SHADER_STAGES
&& output_stage
== 0)
459 struct set
*resource_set
= _mesa_pointer_set_create(NULL
);
461 /* Add inputs and outputs to the resource list. */
462 if (!add_interface_variables(ctx
, prog
, resource_set
, input_stage
,
467 if (!add_interface_variables(ctx
, prog
, resource_set
, output_stage
,
468 GL_PROGRAM_OUTPUT
)) {
472 /* Add transform feedback varyings and buffers. */
473 if (prog
->last_vert_prog
) {
474 struct gl_transform_feedback_info
*linked_xfb
=
475 prog
->last_vert_prog
->sh
.LinkedTransformFeedback
;
478 if (linked_xfb
->NumVarying
> 0) {
479 for (int i
= 0; i
< linked_xfb
->NumVarying
; i
++) {
480 if (!link_util_add_program_resource(prog
, resource_set
,
481 GL_TRANSFORM_FEEDBACK_VARYING
,
482 &linked_xfb
->Varyings
[i
], 0))
488 for (unsigned i
= 0; i
< ctx
->Const
.MaxTransformFeedbackBuffers
; i
++) {
489 if ((linked_xfb
->ActiveBuffers
>> i
) & 1) {
490 linked_xfb
->Buffers
[i
].Binding
= i
;
491 if (!link_util_add_program_resource(prog
, resource_set
,
492 GL_TRANSFORM_FEEDBACK_BUFFER
,
493 &linked_xfb
->Buffers
[i
], 0))
501 * Here, it is expected that nir_link_uniforms() has already been
502 * called, so that UniformStorage table is already available.
504 int top_level_array_base_offset
= -1;
505 int top_level_array_size_in_bytes
= -1;
506 int second_element_offset
= -1;
507 int block_index
= -1;
508 for (unsigned i
= 0; i
< prog
->data
->NumUniformStorage
; i
++) {
509 struct gl_uniform_storage
*uniform
= &prog
->data
->UniformStorage
[i
];
511 if (uniform
->hidden
) {
512 for (int j
= MESA_SHADER_VERTEX
; j
< MESA_SHADER_STAGES
; j
++) {
513 if (!uniform
->opaque
[j
].active
||
514 glsl_get_base_type(uniform
->type
) != GLSL_TYPE_SUBROUTINE
)
518 _mesa_shader_stage_to_subroutine_uniform((gl_shader_stage
)j
);
519 /* add shader subroutines */
520 if (!link_util_add_program_resource(prog
, resource_set
,
528 if (!link_util_should_add_buffer_variable(prog
, uniform
,
529 top_level_array_base_offset
,
530 top_level_array_size_in_bytes
,
531 second_element_offset
, block_index
))
535 if (prog
->data
->UniformStorage
[i
].offset
>= second_element_offset
) {
536 top_level_array_base_offset
=
537 prog
->data
->UniformStorage
[i
].offset
;
539 top_level_array_size_in_bytes
=
540 prog
->data
->UniformStorage
[i
].top_level_array_size
*
541 prog
->data
->UniformStorage
[i
].top_level_array_stride
;
543 /* Set or reset the second element offset. For non arrays this
546 second_element_offset
= top_level_array_size_in_bytes
?
547 top_level_array_base_offset
+
548 prog
->data
->UniformStorage
[i
].top_level_array_stride
: -1;
550 block_index
= uniform
->block_index
;
553 GLenum interface
= uniform
->is_shader_storage
? GL_BUFFER_VARIABLE
: GL_UNIFORM
;
554 if (!link_util_add_program_resource(prog
, resource_set
, interface
, uniform
,
555 uniform
->active_shader_mask
)) {
561 for (unsigned i
= 0; i
< prog
->data
->NumUniformBlocks
; i
++) {
562 if (!link_util_add_program_resource(prog
, resource_set
, GL_UNIFORM_BLOCK
,
563 &prog
->data
->UniformBlocks
[i
],
564 prog
->data
->UniformBlocks
[i
].stageref
))
568 for (unsigned i
= 0; i
< prog
->data
->NumShaderStorageBlocks
; i
++) {
569 if (!link_util_add_program_resource(prog
, resource_set
, GL_SHADER_STORAGE_BLOCK
,
570 &prog
->data
->ShaderStorageBlocks
[i
],
571 prog
->data
->ShaderStorageBlocks
[i
].stageref
))
575 /* Add atomic counter buffers. */
576 for (unsigned i
= 0; i
< prog
->data
->NumAtomicBuffers
; i
++) {
577 if (!link_util_add_program_resource(prog
, resource_set
, GL_ATOMIC_COUNTER_BUFFER
,
578 &prog
->data
->AtomicBuffers
[i
], 0))
582 unsigned mask
= prog
->data
->linked_stages
;
584 const int i
= u_bit_scan(&mask
);
585 struct gl_program
*p
= prog
->_LinkedShaders
[i
]->Program
;
587 GLuint type
= _mesa_shader_stage_to_subroutine((gl_shader_stage
)i
);
588 for (unsigned j
= 0; j
< p
->sh
.NumSubroutineFunctions
; j
++) {
589 if (!link_util_add_program_resource(prog
, resource_set
,
591 &p
->sh
.SubroutineFunctions
[j
],
597 _mesa_set_destroy(resource_set
, NULL
);
601 gl_nir_link_spirv(struct gl_context
*ctx
, struct gl_shader_program
*prog
,
602 const struct gl_nir_linker_options
*options
)
604 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
605 struct gl_linked_shader
*shader
= prog
->_LinkedShaders
[i
];
607 nir_remove_dead_variables(shader
->Program
->nir
, nir_var_uniform
,
608 &can_remove_uniform
);
612 if (!gl_nir_link_uniform_blocks(ctx
, prog
))
615 if (!gl_nir_link_uniforms(ctx
, prog
, options
->fill_parameters
))
618 gl_nir_link_assign_atomic_counter_resources(ctx
, prog
);
619 gl_nir_link_assign_xfb_resources(ctx
, prog
);
625 * Validate shader image resources.
628 check_image_resources(struct gl_context
*ctx
, struct gl_shader_program
*prog
)
630 unsigned total_image_units
= 0;
631 unsigned fragment_outputs
= 0;
632 unsigned total_shader_storage_blocks
= 0;
634 if (!ctx
->Extensions
.ARB_shader_image_load_store
)
637 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
638 struct gl_linked_shader
*sh
= prog
->_LinkedShaders
[i
];
642 total_image_units
+= sh
->Program
->info
.num_images
;
643 total_shader_storage_blocks
+= sh
->Program
->info
.num_ssbos
;
646 if (total_image_units
> ctx
->Const
.MaxCombinedImageUniforms
)
647 linker_error(prog
, "Too many combined image uniforms\n");
649 struct gl_linked_shader
*frag_sh
=
650 prog
->_LinkedShaders
[MESA_SHADER_FRAGMENT
];
652 uint64_t frag_outputs_written
= frag_sh
->Program
->info
.outputs_written
;
653 fragment_outputs
= util_bitcount64(frag_outputs_written
);
656 if (total_image_units
+ fragment_outputs
+ total_shader_storage_blocks
>
657 ctx
->Const
.MaxCombinedShaderOutputResources
)
658 linker_error(prog
, "Too many combined image uniforms, shader storage "
659 " buffers and fragment outputs\n");
663 gl_nir_link_glsl(struct gl_context
*ctx
, struct gl_shader_program
*prog
)
665 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
666 struct gl_linked_shader
*shader
= prog
->_LinkedShaders
[i
];
668 nir_remove_dead_variables(shader
->Program
->nir
, nir_var_uniform
,
669 &can_remove_uniform
);
673 if (!gl_nir_link_uniforms(ctx
, prog
, true))
676 link_util_calculate_subroutine_compat(prog
);
677 link_util_check_uniform_resources(ctx
, prog
);
678 link_util_check_subroutine_resources(prog
);
679 check_image_resources(ctx
, prog
);
680 gl_nir_link_assign_atomic_counter_resources(ctx
, prog
);
681 gl_nir_link_check_atomic_counter_resources(ctx
, prog
);
683 if (prog
->data
->LinkStatus
== LINKING_FAILURE
)