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
25 #include "gl_nir_linker.h"
26 #include "compiler/glsl/ir_uniform.h" /* for gl_uniform_storage */
27 #include "main/context.h"
28 #include "main/mtypes.h"
30 struct set_opaque_binding_closure
{
31 struct gl_shader_program
*shader_prog
;
32 struct gl_program
*prog
;
33 const nir_variable
*var
;
39 set_opaque_binding(struct set_opaque_binding_closure
*data
,
40 const struct glsl_type
*type
)
42 if (glsl_type_is_array(type
) &&
43 glsl_type_is_array(glsl_get_array_element(type
))) {
44 const struct glsl_type
*element_type
= glsl_get_array_element(type
);
46 for (unsigned int i
= 0; i
< glsl_get_length(type
); i
++)
47 set_opaque_binding(data
, element_type
);
52 if (data
->location
< 0 ||
53 data
->location
>= data
->prog
->sh
.data
->NumUniformStorage
)
56 struct gl_uniform_storage
*storage
=
57 data
->prog
->sh
.data
->UniformStorage
+ data
->location
++;
59 const unsigned elements
= MAX2(storage
->array_elements
, 1);
61 for (unsigned int i
= 0; i
< elements
; i
++)
62 storage
->storage
[i
].i
= data
->binding
++;
64 for (int sh
= 0; sh
< MESA_SHADER_STAGES
; sh
++) {
65 struct gl_linked_shader
*shader
= data
->shader_prog
->_LinkedShaders
[sh
];
69 if (!storage
->opaque
[sh
].active
)
72 if (glsl_type_is_sampler(storage
->type
)) {
73 for (unsigned i
= 0; i
< elements
; i
++) {
74 const unsigned index
= storage
->opaque
[sh
].index
+ i
;
76 if (storage
->is_bindless
) {
77 if (index
>= shader
->Program
->sh
.NumBindlessSamplers
)
79 shader
->Program
->sh
.BindlessSamplers
[index
].unit
=
80 storage
->storage
[i
].i
;
81 shader
->Program
->sh
.BindlessSamplers
[index
].bound
= true;
82 shader
->Program
->sh
.HasBoundBindlessSampler
= true;
84 if (index
>= ARRAY_SIZE(shader
->Program
->SamplerUnits
))
86 shader
->Program
->SamplerUnits
[index
] =
87 storage
->storage
[i
].i
;
90 } else if (glsl_type_is_image(storage
->type
)) {
91 for (unsigned i
= 0; i
< elements
; i
++) {
92 const unsigned index
= storage
->opaque
[sh
].index
+ i
;
94 if (storage
->is_bindless
) {
95 if (index
>= shader
->Program
->sh
.NumBindlessImages
)
97 shader
->Program
->sh
.BindlessImages
[index
].unit
=
98 storage
->storage
[i
].i
;
99 shader
->Program
->sh
.BindlessImages
[index
].bound
= true;
100 shader
->Program
->sh
.HasBoundBindlessImage
= true;
102 if (index
>= ARRAY_SIZE(shader
->Program
->sh
.ImageUnits
))
104 shader
->Program
->sh
.ImageUnits
[index
] =
105 storage
->storage
[i
].i
;
113 copy_constant_to_storage(union gl_constant_value
*storage
,
114 const nir_constant
*val
,
115 const struct glsl_type
*type
,
116 unsigned int boolean_true
)
118 const enum glsl_base_type base_type
= glsl_get_base_type(type
);
119 const unsigned n_columns
= glsl_get_matrix_columns(type
);
120 const unsigned n_rows
= glsl_get_vector_elements(type
);
121 unsigned dmul
= glsl_base_type_is_64bit(base_type
) ? 2 : 1;
125 const struct glsl_type
*column_type
= glsl_get_column_type(type
);
126 for (unsigned int column
= 0; column
< n_columns
; column
++) {
127 copy_constant_to_storage(&storage
[i
], val
->elements
[column
],
128 column_type
, boolean_true
);
132 for (unsigned int row
= 0; row
< n_rows
; row
++) {
135 storage
[i
].u
= val
->values
[row
].u32
;
138 case GLSL_TYPE_SAMPLER
:
139 storage
[i
].i
= val
->values
[row
].i32
;
141 case GLSL_TYPE_FLOAT
:
142 storage
[i
].f
= val
->values
[row
].f32
;
144 case GLSL_TYPE_DOUBLE
:
145 case GLSL_TYPE_UINT64
:
146 case GLSL_TYPE_INT64
:
147 /* XXX need to check on big-endian */
148 memcpy(&storage
[i
].u
, &val
->values
[row
].f64
, sizeof(double));
151 storage
[i
].b
= val
->values
[row
].u32
? boolean_true
: 0;
153 case GLSL_TYPE_ARRAY
:
154 case GLSL_TYPE_STRUCT
:
155 case GLSL_TYPE_IMAGE
:
156 case GLSL_TYPE_ATOMIC_UINT
:
157 case GLSL_TYPE_INTERFACE
:
159 case GLSL_TYPE_SUBROUTINE
:
160 case GLSL_TYPE_FUNCTION
:
161 case GLSL_TYPE_ERROR
:
162 case GLSL_TYPE_UINT16
:
163 case GLSL_TYPE_INT16
:
164 case GLSL_TYPE_UINT8
:
166 case GLSL_TYPE_FLOAT16
:
167 /* All other types should have already been filtered by other
168 * paths in the caller.
170 assert(!"Should not get here.");
178 struct set_uniform_initializer_closure
{
179 struct gl_shader_program
*shader_prog
;
180 struct gl_program
*prog
;
181 const nir_variable
*var
;
183 unsigned int boolean_true
;
187 set_uniform_initializer(struct set_uniform_initializer_closure
*data
,
188 const struct glsl_type
*type
,
189 const nir_constant
*val
)
191 const struct glsl_type
*t_without_array
= glsl_without_array(type
);
193 if (glsl_type_is_struct_or_ifc(type
)) {
194 for (unsigned int i
= 0; i
< glsl_get_length(type
); i
++) {
195 const struct glsl_type
*field_type
= glsl_get_struct_field(type
, i
);
196 set_uniform_initializer(data
, field_type
, val
->elements
[i
]);
201 if (glsl_type_is_struct_or_ifc(t_without_array
) ||
202 (glsl_type_is_array(type
) &&
203 glsl_type_is_array(glsl_get_array_element(type
)))) {
204 const struct glsl_type
*element_type
= glsl_get_array_element(type
);
206 for (unsigned int i
= 0; i
< glsl_get_length(type
); i
++)
207 set_uniform_initializer(data
, element_type
, val
->elements
[i
]);
212 if (data
->location
< 0 ||
213 data
->location
>= data
->prog
->sh
.data
->NumUniformStorage
)
216 struct gl_uniform_storage
*storage
=
217 data
->prog
->sh
.data
->UniformStorage
+ data
->location
++;
219 if (glsl_type_is_array(type
)) {
220 const struct glsl_type
*element_type
= glsl_get_array_element(type
);
221 const enum glsl_base_type base_type
= glsl_get_base_type(element_type
);
222 const unsigned int elements
= glsl_get_components(element_type
);
223 unsigned int idx
= 0;
224 unsigned dmul
= glsl_base_type_is_64bit(base_type
) ? 2 : 1;
226 assert(glsl_get_length(type
) >= storage
->array_elements
);
227 for (unsigned int i
= 0; i
< storage
->array_elements
; i
++) {
228 copy_constant_to_storage(&storage
->storage
[idx
],
233 idx
+= elements
* dmul
;
236 copy_constant_to_storage(storage
->storage
,
241 if (glsl_type_is_sampler(storage
->type
)) {
242 for (int sh
= 0; sh
< MESA_SHADER_STAGES
; sh
++) {
243 struct gl_linked_shader
*shader
=
244 data
->shader_prog
->_LinkedShaders
[sh
];
246 if (shader
&& storage
->opaque
[sh
].active
) {
247 unsigned index
= storage
->opaque
[sh
].index
;
249 shader
->Program
->SamplerUnits
[index
] = storage
->storage
[0].i
;
257 gl_nir_set_uniform_initializers(struct gl_context
*ctx
,
258 struct gl_shader_program
*prog
)
260 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
261 struct gl_linked_shader
*sh
= prog
->_LinkedShaders
[i
];
265 nir_shader
*nir
= sh
->Program
->nir
;
268 nir_foreach_gl_uniform_variable(var
, nir
) {
269 if (var
->constant_initializer
) {
270 struct set_uniform_initializer_closure data
= {
274 .location
= var
->data
.location
,
275 .boolean_true
= ctx
->Const
.UniformBooleanTrue
277 set_uniform_initializer(&data
,
279 var
->constant_initializer
);
280 } else if (var
->data
.explicit_binding
) {
282 if (nir_variable_is_in_block(var
)) {
283 /* This case is handled by link_uniform_blocks */
287 const struct glsl_type
*without_array
=
288 glsl_without_array(var
->type
);
290 if (glsl_type_is_sampler(without_array
) ||
291 glsl_type_is_image(without_array
)) {
292 struct set_opaque_binding_closure data
= {
296 .binding
= var
->data
.binding
,
297 .location
= var
->data
.location
299 set_opaque_binding(&data
, var
->type
);
304 memcpy(prog
->data
->UniformDataDefaults
, prog
->data
->UniformDataSlots
,
305 sizeof(union gl_constant_value
) * prog
->data
->NumUniformDataSlots
);