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 */
32 /* This file included general link methods, using NIR, instead of IR as
33 * the counter-part glsl/linker.cpp
35 * Also note that this is tailored for ARB_gl_spirv needs and particularities
39 * Built-in / reserved GL variables names start with "gl_"
42 is_gl_identifier(const char *s
)
44 return s
&& s
[0] == 'g' && s
[1] == 'l' && s
[2] == '_';
48 inout_has_same_location(const nir_variable
*var
, unsigned stage
)
50 if (!var
->data
.patch
&&
51 ((var
->data
.mode
== nir_var_shader_out
&&
52 stage
== MESA_SHADER_TESS_CTRL
) ||
53 (var
->data
.mode
== nir_var_shader_in
&&
54 (stage
== MESA_SHADER_TESS_CTRL
|| stage
== MESA_SHADER_TESS_EVAL
||
55 stage
== MESA_SHADER_GEOMETRY
))))
62 * Create gl_shader_variable from nir_variable.
64 static struct gl_shader_variable
*
65 create_shader_variable(struct gl_shader_program
*shProg
,
66 const nir_variable
*in
,
67 const char *name
, const struct glsl_type
*type
,
68 const struct glsl_type
*interface_type
,
69 bool use_implicit_location
, int location
,
70 const struct glsl_type
*outermost_struct_type
)
72 /* Allocate zero-initialized memory to ensure that bitfield padding
75 struct gl_shader_variable
*out
= rzalloc(shProg
,
76 struct gl_shader_variable
);
80 /* Since gl_VertexID may be lowered to gl_VertexIDMESA, but applications
81 * expect to see gl_VertexID in the program resource list. Pretend.
83 if (in
->data
.mode
== nir_var_system_value
&&
84 in
->data
.location
== SYSTEM_VALUE_VERTEX_ID_ZERO_BASE
) {
85 out
->name
= ralloc_strdup(shProg
, "gl_VertexID");
86 } else if ((in
->data
.mode
== nir_var_shader_out
&&
87 in
->data
.location
== VARYING_SLOT_TESS_LEVEL_OUTER
) ||
88 (in
->data
.mode
== nir_var_system_value
&&
89 in
->data
.location
== SYSTEM_VALUE_TESS_LEVEL_OUTER
)) {
90 out
->name
= ralloc_strdup(shProg
, "gl_TessLevelOuter");
91 type
= glsl_array_type(glsl_float_type(), 4, 0);
92 } else if ((in
->data
.mode
== nir_var_shader_out
&&
93 in
->data
.location
== VARYING_SLOT_TESS_LEVEL_INNER
) ||
94 (in
->data
.mode
== nir_var_system_value
&&
95 in
->data
.location
== SYSTEM_VALUE_TESS_LEVEL_INNER
)) {
96 out
->name
= ralloc_strdup(shProg
, "gl_TessLevelInner");
97 type
= glsl_array_type(glsl_float_type(), 2, 0);
99 out
->name
= ralloc_strdup(shProg
, name
);
105 /* The ARB_program_interface_query spec says:
107 * "Not all active variables are assigned valid locations; the
108 * following variables will have an effective location of -1:
110 * * uniforms declared as atomic counters;
112 * * members of a uniform block;
114 * * built-in inputs, outputs, and uniforms (starting with "gl_"); and
116 * * inputs or outputs not declared with a "location" layout
117 * qualifier, except for vertex shader inputs and fragment shader
120 if (glsl_get_base_type(in
->type
) == GLSL_TYPE_ATOMIC_UINT
||
121 is_gl_identifier(in
->name
) ||
122 !(in
->data
.explicit_location
|| use_implicit_location
)) {
125 out
->location
= location
;
129 out
->outermost_struct_type
= outermost_struct_type
;
130 out
->interface_type
= interface_type
;
131 out
->component
= in
->data
.location_frac
;
132 out
->index
= in
->data
.index
;
133 out
->patch
= in
->data
.patch
;
134 out
->mode
= in
->data
.mode
;
135 out
->interpolation
= in
->data
.interpolation
;
136 out
->precision
= in
->data
.precision
;
137 out
->explicit_location
= in
->data
.explicit_location
;
143 add_shader_variable(const struct gl_context
*ctx
,
144 struct gl_shader_program
*shProg
,
145 struct set
*resource_set
,
147 GLenum programInterface
, nir_variable
*var
,
148 const char *name
, const struct glsl_type
*type
,
149 bool use_implicit_location
, int location
,
150 bool inouts_share_location
,
151 const struct glsl_type
*outermost_struct_type
)
153 const struct glsl_type
*interface_type
= var
->interface_type
;
155 if (outermost_struct_type
== NULL
) {
156 if (var
->data
.from_named_ifc_block
) {
157 const char *interface_name
= glsl_get_type_name(interface_type
);
159 if (glsl_type_is_array(interface_type
)) {
160 /* Issue #16 of the ARB_program_interface_query spec says:
162 * "* If a variable is a member of an interface block without an
163 * instance name, it is enumerated using just the variable name.
165 * * If a variable is a member of an interface block with an
166 * instance name, it is enumerated as "BlockName.Member", where
167 * "BlockName" is the name of the interface block (not the
168 * instance name) and "Member" is the name of the variable."
170 * In particular, it indicates that it should be "BlockName",
171 * not "BlockName[array length]". The conformance suite and
172 * dEQP both require this behavior.
174 * Here, we unwrap the extra array level added by named interface
175 * block array lowering so we have the correct variable type. We
176 * also unwrap the interface type when constructing the name.
178 * We leave interface_type the same so that ES 3.x SSO pipeline
179 * validation can enforce the rules requiring array length to
180 * match on interface blocks.
182 type
= glsl_get_array_element(type
);
185 glsl_get_type_name(glsl_get_array_element(interface_type
));
188 name
= ralloc_asprintf(shProg
, "%s.%s", interface_name
, name
);
192 switch (glsl_get_base_type(type
)) {
193 case GLSL_TYPE_STRUCT
: {
194 /* The ARB_program_interface_query spec says:
196 * "For an active variable declared as a structure, a separate entry
197 * will be generated for each active structure member. The name of
198 * each entry is formed by concatenating the name of the structure,
199 * the "." character, and the name of the structure member. If a
200 * structure member to enumerate is itself a structure or array,
201 * these enumeration rules are applied recursively."
203 if (outermost_struct_type
== NULL
)
204 outermost_struct_type
= type
;
206 unsigned field_location
= location
;
207 for (unsigned i
= 0; i
< glsl_get_length(type
); i
++) {
208 const struct glsl_type
*field_type
= glsl_get_struct_field(type
, i
);
209 const struct glsl_struct_field
*field
=
210 glsl_get_struct_field_data(type
, i
);
212 char *field_name
= ralloc_asprintf(shProg
, "%s.%s", name
, field
->name
);
213 if (!add_shader_variable(ctx
, shProg
, resource_set
,
214 stage_mask
, programInterface
,
215 var
, field_name
, field_type
,
216 use_implicit_location
, field_location
,
217 false, outermost_struct_type
))
220 field_location
+= glsl_count_attribute_slots(field_type
, false);
225 case GLSL_TYPE_ARRAY
: {
226 /* The ARB_program_interface_query spec says:
228 * "For an active variable declared as an array of basic types, a
229 * single entry will be generated, with its name string formed by
230 * concatenating the name of the array and the string "[0]"."
232 * "For an active variable declared as an array of an aggregate data
233 * type (structures or arrays), a separate entry will be generated
234 * for each active array element, unless noted immediately below.
235 * The name of each entry is formed by concatenating the name of
236 * the array, the "[" character, an integer identifying the element
237 * number, and the "]" character. These enumeration rules are
238 * applied recursively, treating each enumerated array element as a
239 * separate active variable."
241 const struct glsl_type
*array_type
= glsl_get_array_element(type
);
242 if (glsl_get_base_type(array_type
) == GLSL_TYPE_STRUCT
||
243 glsl_get_base_type(array_type
) == GLSL_TYPE_ARRAY
) {
244 unsigned elem_location
= location
;
245 unsigned stride
= inouts_share_location
? 0 :
246 glsl_count_attribute_slots(array_type
, false);
247 for (unsigned i
= 0; i
< glsl_get_length(type
); i
++) {
248 char *elem
= ralloc_asprintf(shProg
, "%s[%d]", name
, i
);
249 if (!add_shader_variable(ctx
, shProg
, resource_set
,
250 stage_mask
, programInterface
,
251 var
, elem
, array_type
,
252 use_implicit_location
, elem_location
,
253 false, outermost_struct_type
))
255 elem_location
+= stride
;
263 /* The ARB_program_interface_query spec says:
265 * "For an active variable declared as a single instance of a basic
266 * type, a single entry will be generated, using the variable name
267 * from the shader source."
269 struct gl_shader_variable
*sha_v
=
270 create_shader_variable(shProg
, var
, name
, type
, interface_type
,
271 use_implicit_location
, location
,
272 outermost_struct_type
);
276 return link_util_add_program_resource(shProg
, resource_set
,
277 programInterface
, sha_v
, stage_mask
);
283 add_vars_from_list(const struct gl_context
*ctx
,
284 struct gl_shader_program
*prog
, struct set
*resource_set
,
285 const struct exec_list
*var_list
, unsigned stage
,
286 GLenum programInterface
)
288 nir_foreach_variable(var
, var_list
) {
289 if (var
->data
.how_declared
== nir_var_hidden
)
293 switch(var
->data
.mode
) {
294 case nir_var_system_value
:
295 case nir_var_shader_in
:
296 if (programInterface
!= GL_PROGRAM_INPUT
)
298 loc_bias
= (stage
== MESA_SHADER_VERTEX
) ? VERT_ATTRIB_GENERIC0
301 case nir_var_shader_out
:
302 if (programInterface
!= GL_PROGRAM_OUTPUT
)
304 loc_bias
= (stage
== MESA_SHADER_FRAGMENT
) ? FRAG_RESULT_DATA0
312 loc_bias
= VARYING_SLOT_PATCH0
;
314 if (prog
->data
->spirv
) {
315 struct gl_shader_variable
*sh_var
=
316 rzalloc(prog
, struct gl_shader_variable
);
318 /* In the ARB_gl_spirv spec, names are considered optional debug info, so
319 * the linker needs to work without them. Returning them is optional.
320 * For simplicity, we ignore names.
323 sh_var
->type
= var
->type
;
324 sh_var
->location
= var
->data
.location
- loc_bias
;
325 sh_var
->index
= var
->data
.index
;
327 if (!link_util_add_program_resource(prog
, resource_set
,
329 sh_var
, 1 << stage
)) {
333 /* Skip packed varyings, packed varyings are handled separately
334 * by add_packed_varyings in the GLSL IR
335 * build_program_resource_list() call.
336 * TODO: handle packed varyings here instead. We likely want a NIR
337 * based packing pass first.
339 if (strncmp(var
->name
, "packed:", 7) == 0)
342 const bool vs_input_or_fs_output
=
343 (stage
== MESA_SHADER_VERTEX
&&
344 var
->data
.mode
== nir_var_shader_in
) ||
345 (stage
== MESA_SHADER_FRAGMENT
&&
346 var
->data
.mode
== nir_var_shader_out
);
348 if (!add_shader_variable(ctx
, prog
, resource_set
,
349 1 << stage
, programInterface
,
350 var
, var
->name
, var
->type
,
351 vs_input_or_fs_output
,
352 var
->data
.location
- loc_bias
,
353 inout_has_same_location(var
, stage
),
363 add_interface_variables(const struct gl_context
*ctx
,
364 struct gl_shader_program
*prog
,
365 struct set
*resource_set
,
366 unsigned stage
, GLenum programInterface
)
368 struct gl_linked_shader
*sh
= prog
->_LinkedShaders
[stage
];
372 nir_shader
*nir
= sh
->Program
->nir
;
375 switch (programInterface
) {
376 case GL_PROGRAM_INPUT
: {
377 bool result
= add_vars_from_list(ctx
, prog
, resource_set
,
378 &nir
->inputs
, stage
, programInterface
);
379 result
&= add_vars_from_list(ctx
, prog
, resource_set
, &nir
->system_values
,
380 stage
, programInterface
);
383 case GL_PROGRAM_OUTPUT
:
384 return add_vars_from_list(ctx
, prog
, resource_set
, &nir
->outputs
, stage
,
387 assert("!Should not get here");
394 /* TODO: as we keep adding features, this method is becoming more and more
395 * similar to its GLSL counterpart at linker.cpp. Eventually it would be good
396 * to check if they could be refactored, and reduce code duplication somehow
399 nir_build_program_resource_list(struct gl_context
*ctx
,
400 struct gl_shader_program
*prog
,
401 bool rebuild_resourse_list
)
403 /* Rebuild resource list. */
404 if (prog
->data
->ProgramResourceList
&& rebuild_resourse_list
) {
405 ralloc_free(prog
->data
->ProgramResourceList
);
406 prog
->data
->ProgramResourceList
= NULL
;
407 prog
->data
->NumProgramResourceList
= 0;
410 int input_stage
= MESA_SHADER_STAGES
, output_stage
= 0;
412 /* Determine first input and final output stage. These are used to
413 * detect which variables should be enumerated in the resource list
414 * for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.
416 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
417 if (!prog
->_LinkedShaders
[i
])
419 if (input_stage
== MESA_SHADER_STAGES
)
424 /* Empty shader, no resources. */
425 if (input_stage
== MESA_SHADER_STAGES
&& output_stage
== 0)
428 struct set
*resource_set
= _mesa_pointer_set_create(NULL
);
430 /* Add inputs and outputs to the resource list. */
431 if (!add_interface_variables(ctx
, prog
, resource_set
, input_stage
,
436 if (!add_interface_variables(ctx
, prog
, resource_set
, output_stage
,
437 GL_PROGRAM_OUTPUT
)) {
441 /* Add transform feedback varyings and buffers. */
442 if (prog
->last_vert_prog
) {
443 struct gl_transform_feedback_info
*linked_xfb
=
444 prog
->last_vert_prog
->sh
.LinkedTransformFeedback
;
447 if (linked_xfb
->NumVarying
> 0) {
448 for (int i
= 0; i
< linked_xfb
->NumVarying
; i
++) {
449 if (!link_util_add_program_resource(prog
, resource_set
,
450 GL_TRANSFORM_FEEDBACK_VARYING
,
451 &linked_xfb
->Varyings
[i
], 0))
457 for (unsigned i
= 0; i
< ctx
->Const
.MaxTransformFeedbackBuffers
; i
++) {
458 if ((linked_xfb
->ActiveBuffers
>> i
) & 1) {
459 linked_xfb
->Buffers
[i
].Binding
= i
;
460 if (!link_util_add_program_resource(prog
, resource_set
,
461 GL_TRANSFORM_FEEDBACK_BUFFER
,
462 &linked_xfb
->Buffers
[i
], 0))
470 * Here, it is expected that nir_link_uniforms() has already been
471 * called, so that UniformStorage table is already available.
473 int top_level_array_base_offset
= -1;
474 int top_level_array_size_in_bytes
= -1;
475 int second_element_offset
= -1;
476 int block_index
= -1;
477 for (unsigned i
= 0; i
< prog
->data
->NumUniformStorage
; i
++) {
478 struct gl_uniform_storage
*uniform
= &prog
->data
->UniformStorage
[i
];
480 if (uniform
->hidden
) {
481 for (int j
= MESA_SHADER_VERTEX
; j
< MESA_SHADER_STAGES
; j
++) {
482 if (!uniform
->opaque
[j
].active
||
483 glsl_get_base_type(uniform
->type
) != GLSL_TYPE_SUBROUTINE
)
487 _mesa_shader_stage_to_subroutine_uniform((gl_shader_stage
)j
);
488 /* add shader subroutines */
489 if (!link_util_add_program_resource(prog
, resource_set
,
497 if (!link_util_should_add_buffer_variable(prog
, uniform
,
498 top_level_array_base_offset
,
499 top_level_array_size_in_bytes
,
500 second_element_offset
, block_index
))
504 if (prog
->data
->UniformStorage
[i
].offset
>= second_element_offset
) {
505 top_level_array_base_offset
=
506 prog
->data
->UniformStorage
[i
].offset
;
508 top_level_array_size_in_bytes
=
509 prog
->data
->UniformStorage
[i
].top_level_array_size
*
510 prog
->data
->UniformStorage
[i
].top_level_array_stride
;
512 /* Set or reset the second element offset. For non arrays this
515 second_element_offset
= top_level_array_size_in_bytes
?
516 top_level_array_base_offset
+
517 prog
->data
->UniformStorage
[i
].top_level_array_stride
: -1;
519 block_index
= uniform
->block_index
;
522 GLenum interface
= uniform
->is_shader_storage
? GL_BUFFER_VARIABLE
: GL_UNIFORM
;
523 if (!link_util_add_program_resource(prog
, resource_set
, interface
, uniform
,
524 uniform
->active_shader_mask
)) {
530 for (unsigned i
= 0; i
< prog
->data
->NumUniformBlocks
; i
++) {
531 if (!link_util_add_program_resource(prog
, resource_set
, GL_UNIFORM_BLOCK
,
532 &prog
->data
->UniformBlocks
[i
],
533 prog
->data
->UniformBlocks
[i
].stageref
))
537 for (unsigned i
= 0; i
< prog
->data
->NumShaderStorageBlocks
; i
++) {
538 if (!link_util_add_program_resource(prog
, resource_set
, GL_SHADER_STORAGE_BLOCK
,
539 &prog
->data
->ShaderStorageBlocks
[i
],
540 prog
->data
->ShaderStorageBlocks
[i
].stageref
))
544 /* Add atomic counter buffers. */
545 for (unsigned i
= 0; i
< prog
->data
->NumAtomicBuffers
; i
++) {
546 if (!link_util_add_program_resource(prog
, resource_set
, GL_ATOMIC_COUNTER_BUFFER
,
547 &prog
->data
->AtomicBuffers
[i
], 0))
551 unsigned mask
= prog
->data
->linked_stages
;
553 const int i
= u_bit_scan(&mask
);
554 struct gl_program
*p
= prog
->_LinkedShaders
[i
]->Program
;
556 GLuint type
= _mesa_shader_stage_to_subroutine((gl_shader_stage
)i
);
557 for (unsigned j
= 0; j
< p
->sh
.NumSubroutineFunctions
; j
++) {
558 if (!link_util_add_program_resource(prog
, resource_set
,
560 &p
->sh
.SubroutineFunctions
[j
],
566 _mesa_set_destroy(resource_set
, NULL
);
570 gl_nir_link_spirv(struct gl_context
*ctx
, struct gl_shader_program
*prog
,
571 const struct gl_nir_linker_options
*options
)
573 if (!gl_nir_link_uniform_blocks(ctx
, prog
))
576 if (!gl_nir_link_uniforms(ctx
, prog
, options
->fill_parameters
))
579 gl_nir_link_assign_atomic_counter_resources(ctx
, prog
);
580 gl_nir_link_assign_xfb_resources(ctx
, prog
);
586 * Validate shader image resources.
589 check_image_resources(struct gl_context
*ctx
, struct gl_shader_program
*prog
)
591 unsigned total_image_units
= 0;
592 unsigned fragment_outputs
= 0;
593 unsigned total_shader_storage_blocks
= 0;
595 if (!ctx
->Extensions
.ARB_shader_image_load_store
)
598 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
599 struct gl_linked_shader
*sh
= prog
->_LinkedShaders
[i
];
603 total_image_units
+= sh
->Program
->info
.num_images
;
604 total_shader_storage_blocks
+= sh
->Program
->info
.num_ssbos
;
607 if (total_image_units
> ctx
->Const
.MaxCombinedImageUniforms
)
608 linker_error(prog
, "Too many combined image uniforms\n");
610 struct gl_linked_shader
*frag_sh
=
611 prog
->_LinkedShaders
[MESA_SHADER_FRAGMENT
];
613 uint64_t frag_outputs_written
= frag_sh
->Program
->info
.outputs_written
;
614 fragment_outputs
= util_bitcount64(frag_outputs_written
);
617 if (total_image_units
+ fragment_outputs
+ total_shader_storage_blocks
>
618 ctx
->Const
.MaxCombinedShaderOutputResources
)
619 linker_error(prog
, "Too many combined image uniforms, shader storage "
620 " buffers and fragment outputs\n");
624 gl_nir_link_glsl(struct gl_context
*ctx
, struct gl_shader_program
*prog
)
626 link_util_calculate_subroutine_compat(prog
);
627 link_util_check_uniform_resources(ctx
, prog
);
628 link_util_check_subroutine_resources(prog
);
629 check_image_resources(ctx
, prog
);
630 gl_nir_link_assign_atomic_counter_resources(ctx
, prog
);
631 gl_nir_link_check_atomic_counter_resources(ctx
, prog
);
633 if (prog
->data
->LinkStatus
== LINKING_FAILURE
)