nir: make nir_const_value scalar
[mesa.git] / src / compiler / glsl / gl_nir_link_uniform_initializers.c
1 /*
2 * Copyright © 2018 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 */
23
24 #include "nir.h"
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"
29
30 struct set_opaque_binding_closure {
31 struct gl_shader_program *shader_prog;
32 struct gl_program *prog;
33 const nir_variable *var;
34 int binding;
35 int location;
36 };
37
38 static void
39 set_opaque_binding(struct set_opaque_binding_closure *data,
40 const struct glsl_type *type)
41 {
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);
45
46 for (unsigned int i = 0; i < glsl_get_length(type); i++)
47 set_opaque_binding(data, element_type);
48
49 return;
50 }
51
52 if (data->location < 0 ||
53 data->location >= data->prog->sh.data->NumUniformStorage)
54 return;
55
56 struct gl_uniform_storage *storage =
57 data->prog->sh.data->UniformStorage + data->location++;
58
59 const unsigned elements = MAX2(storage->array_elements, 1);
60
61 for (unsigned int i = 0; i < elements; i++)
62 storage->storage[i].i = data->binding++;
63
64 for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
65 struct gl_linked_shader *shader = data->shader_prog->_LinkedShaders[sh];
66
67 if (!shader)
68 continue;
69 if (!storage->opaque[sh].active)
70 continue;
71
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;
75
76 if (storage->is_bindless) {
77 if (index >= shader->Program->sh.NumBindlessSamplers)
78 break;
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;
83 } else {
84 if (index >= ARRAY_SIZE(shader->Program->SamplerUnits))
85 break;
86 shader->Program->SamplerUnits[index] =
87 storage->storage[i].i;
88 }
89 }
90 } else if (glsl_type_is_image(type)) {
91 for (unsigned i = 0; i < elements; i++) {
92 const unsigned index = storage->opaque[sh].index + i;
93
94 if (storage->is_bindless) {
95 if (index >= shader->Program->sh.NumBindlessImages)
96 break;
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;
101 } else {
102 if (index >= ARRAY_SIZE(shader->Program->sh.ImageUnits))
103 break;
104 shader->Program->sh.ImageUnits[index] =
105 storage->storage[i].i;
106 }
107 }
108 }
109 }
110 }
111
112 static void
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)
117 {
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 int i = 0;
122
123 for (unsigned int column = 0; column < n_columns; column++) {
124 for (unsigned int row = 0; row < n_rows; row++) {
125 switch (base_type) {
126 case GLSL_TYPE_UINT:
127 storage[i].u = val->values[column][row].u32;
128 break;
129 case GLSL_TYPE_INT:
130 case GLSL_TYPE_SAMPLER:
131 storage[i].i = val->values[column][row].i32;
132 break;
133 case GLSL_TYPE_FLOAT:
134 storage[i].f = val->values[column][row].f32;
135 break;
136 case GLSL_TYPE_DOUBLE:
137 case GLSL_TYPE_UINT64:
138 case GLSL_TYPE_INT64:
139 /* XXX need to check on big-endian */
140 memcpy(&storage[i * 2].u,
141 &val->values[column][row].f64,
142 sizeof(double));
143 break;
144 case GLSL_TYPE_BOOL:
145 storage[i].b = val->values[column][row].u32 ? boolean_true : 0;
146 break;
147 case GLSL_TYPE_ARRAY:
148 case GLSL_TYPE_STRUCT:
149 case GLSL_TYPE_IMAGE:
150 case GLSL_TYPE_ATOMIC_UINT:
151 case GLSL_TYPE_INTERFACE:
152 case GLSL_TYPE_VOID:
153 case GLSL_TYPE_SUBROUTINE:
154 case GLSL_TYPE_FUNCTION:
155 case GLSL_TYPE_ERROR:
156 case GLSL_TYPE_UINT16:
157 case GLSL_TYPE_INT16:
158 case GLSL_TYPE_UINT8:
159 case GLSL_TYPE_INT8:
160 case GLSL_TYPE_FLOAT16:
161 /* All other types should have already been filtered by other
162 * paths in the caller.
163 */
164 assert(!"Should not get here.");
165 break;
166 }
167 i++;
168 }
169 }
170 }
171
172 struct set_uniform_initializer_closure {
173 struct gl_shader_program *shader_prog;
174 struct gl_program *prog;
175 const nir_variable *var;
176 int location;
177 unsigned int boolean_true;
178 };
179
180 static void
181 set_uniform_initializer(struct set_uniform_initializer_closure *data,
182 const struct glsl_type *type,
183 const nir_constant *val)
184 {
185 const struct glsl_type *t_without_array = glsl_without_array(type);
186
187 if (glsl_type_is_struct_or_ifc(type)) {
188 for (unsigned int i = 0; i < glsl_get_length(type); i++) {
189 const struct glsl_type *field_type = glsl_get_struct_field(type, i);
190 set_uniform_initializer(data, field_type, val->elements[i]);
191 }
192 return;
193 }
194
195 if (glsl_type_is_struct_or_ifc(t_without_array) ||
196 (glsl_type_is_array(type) &&
197 glsl_type_is_array(glsl_get_array_element(type)))) {
198 const struct glsl_type *element_type = glsl_get_array_element(type);
199
200 for (unsigned int i = 0; i < glsl_get_length(type); i++)
201 set_uniform_initializer(data, element_type, val->elements[i]);
202
203 return;
204 }
205
206 if (data->location < 0 ||
207 data->location >= data->prog->sh.data->NumUniformStorage)
208 return;
209
210 struct gl_uniform_storage *storage =
211 data->prog->sh.data->UniformStorage + data->location++;
212
213 if (glsl_type_is_array(type)) {
214 const struct glsl_type *element_type = glsl_get_array_element(type);
215 const enum glsl_base_type base_type = glsl_get_base_type(element_type);
216 const unsigned int elements = glsl_get_components(element_type);
217 unsigned int idx = 0;
218 unsigned dmul = glsl_base_type_is_64bit(base_type) ? 2 : 1;
219
220 assert(glsl_get_length(type) >= storage->array_elements);
221 for (unsigned int i = 0; i < storage->array_elements; i++) {
222 copy_constant_to_storage(&storage->storage[idx],
223 val->elements[i],
224 element_type,
225 data->boolean_true);
226
227 idx += elements * dmul;
228 }
229 } else {
230 copy_constant_to_storage(storage->storage,
231 val,
232 type,
233 data->boolean_true);
234
235 if (glsl_type_is_sampler(storage->type)) {
236 for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
237 struct gl_linked_shader *shader =
238 data->shader_prog->_LinkedShaders[sh];
239
240 if (shader && storage->opaque[sh].active) {
241 unsigned index = storage->opaque[sh].index;
242
243 shader->Program->SamplerUnits[index] = storage->storage[0].i;
244 }
245 }
246 }
247 }
248 }
249
250 void
251 gl_nir_set_uniform_initializers(struct gl_context *ctx,
252 struct gl_shader_program *prog)
253 {
254 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
255 struct gl_linked_shader *sh = prog->_LinkedShaders[i];
256 if (!sh)
257 continue;
258
259 nir_shader *nir = sh->Program->nir;
260 assert(nir);
261
262 nir_foreach_variable(var, &nir->uniforms) {
263 if (var->constant_initializer) {
264 struct set_uniform_initializer_closure data = {
265 .shader_prog = prog,
266 .prog = sh->Program,
267 .var = var,
268 .location = var->data.location,
269 .boolean_true = ctx->Const.UniformBooleanTrue
270 };
271 set_uniform_initializer(&data,
272 var->type,
273 var->constant_initializer);
274 } else if (var->data.explicit_binding) {
275 const struct glsl_type *without_array =
276 glsl_without_array(var->type);
277
278 if (glsl_type_is_sampler(without_array) ||
279 glsl_type_is_image(without_array)) {
280 struct set_opaque_binding_closure data = {
281 .shader_prog = prog,
282 .prog = sh->Program,
283 .var = var,
284 .binding = var->data.binding,
285 .location = var->data.location
286 };
287 set_opaque_binding(&data, var->type);
288 }
289 }
290 }
291 }
292 }