i965/nir/vec4: Add setup of uniform variables
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vec4_nir.cpp
1 /*
2 * Copyright © 2015 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 "brw_nir.h"
25 #include "brw_vec4.h"
26 #include "glsl/ir_uniform.h"
27
28 namespace brw {
29
30 void
31 vec4_visitor::emit_nir_code()
32 {
33 nir_shader *nir = prog->nir;
34
35 if (nir->num_inputs > 0)
36 nir_setup_inputs(nir);
37
38 if (nir->num_uniforms > 0)
39 nir_setup_uniforms(nir);
40
41 nir_setup_system_values(nir);
42
43 /* get the main function and emit it */
44 nir_foreach_overload(nir, overload) {
45 assert(strcmp(overload->function->name, "main") == 0);
46 assert(overload->impl);
47 nir_emit_impl(overload->impl);
48 }
49 }
50
51 static bool
52 setup_system_values_block(nir_block *block, void *void_visitor)
53 {
54 /* @TODO: Not yet implemented */
55 return true;
56 }
57
58 void
59 vec4_visitor::nir_setup_system_values(nir_shader *shader)
60 {
61 nir_foreach_overload(shader, overload) {
62 assert(strcmp(overload->function->name, "main") == 0);
63 assert(overload->impl);
64 nir_foreach_block(overload->impl, setup_system_values_block, this);
65 }
66 }
67
68 void
69 vec4_visitor::nir_setup_inputs(nir_shader *shader)
70 {
71 nir_inputs = ralloc_array(mem_ctx, src_reg, shader->num_inputs);
72
73 foreach_list_typed(nir_variable, var, node, &shader->inputs) {
74 int offset = var->data.driver_location;
75 unsigned size = type_size(var->type);
76 for (unsigned i = 0; i < size; i++) {
77 src_reg src = src_reg(ATTR, var->data.location + i, var->type);
78 nir_inputs[offset + i] = src;
79 }
80 }
81 }
82
83 void
84 vec4_visitor::nir_setup_uniforms(nir_shader *shader)
85 {
86 uniforms = 0;
87
88 nir_uniform_driver_location =
89 rzalloc_array(mem_ctx, unsigned, this->uniform_array_size);
90
91 if (shader_prog) {
92 foreach_list_typed(nir_variable, var, node, &shader->uniforms) {
93 /* UBO's, atomics and samplers don't take up space in the
94 uniform file */
95 if (var->interface_type != NULL || var->type->contains_atomic() ||
96 type_size(var->type) == 0) {
97 continue;
98 }
99
100 assert(uniforms < uniform_array_size);
101 this->uniform_size[uniforms] = type_size(var->type);
102
103 if (strncmp(var->name, "gl_", 3) == 0)
104 nir_setup_builtin_uniform(var);
105 else
106 nir_setup_uniform(var);
107 }
108 } else {
109 /* ARB_vertex_program is not supported yet */
110 assert("Not implemented");
111 }
112 }
113
114 void
115 vec4_visitor::nir_setup_uniform(nir_variable *var)
116 {
117 int namelen = strlen(var->name);
118
119 /* The data for our (non-builtin) uniforms is stored in a series of
120 * gl_uniform_driver_storage structs for each subcomponent that
121 * glGetUniformLocation() could name. We know it's been set up in the same
122 * order we'd walk the type, so walk the list of storage and find anything
123 * with our name, or the prefix of a component that starts with our name.
124 */
125 for (unsigned u = 0; u < shader_prog->NumUniformStorage; u++) {
126 struct gl_uniform_storage *storage = &shader_prog->UniformStorage[u];
127
128 if (storage->builtin)
129 continue;
130
131 if (strncmp(var->name, storage->name, namelen) != 0 ||
132 (storage->name[namelen] != 0 &&
133 storage->name[namelen] != '.' &&
134 storage->name[namelen] != '[')) {
135 continue;
136 }
137
138 gl_constant_value *components = storage->storage;
139 unsigned vector_count = (MAX2(storage->array_elements, 1) *
140 storage->type->matrix_columns);
141
142 for (unsigned s = 0; s < vector_count; s++) {
143 assert(uniforms < uniform_array_size);
144 uniform_vector_size[uniforms] = storage->type->vector_elements;
145
146 int i;
147 for (i = 0; i < uniform_vector_size[uniforms]; i++) {
148 stage_prog_data->param[uniforms * 4 + i] = components;
149 components++;
150 }
151 for (; i < 4; i++) {
152 static const gl_constant_value zero = { 0.0 };
153 stage_prog_data->param[uniforms * 4 + i] = &zero;
154 }
155
156 nir_uniform_driver_location[uniforms] = var->data.driver_location;
157 uniforms++;
158 }
159 }
160 }
161
162 void
163 vec4_visitor::nir_setup_builtin_uniform(nir_variable *var)
164 {
165 const nir_state_slot *const slots = var->state_slots;
166 assert(var->state_slots != NULL);
167
168 for (unsigned int i = 0; i < var->num_state_slots; i++) {
169 /* This state reference has already been setup by ir_to_mesa,
170 * but we'll get the same index back here. We can reference
171 * ParameterValues directly, since unlike brw_fs.cpp, we never
172 * add new state references during compile.
173 */
174 int index = _mesa_add_state_reference(this->prog->Parameters,
175 (gl_state_index *)slots[i].tokens);
176 gl_constant_value *values =
177 &this->prog->Parameters->ParameterValues[index][0];
178
179 assert(uniforms < uniform_array_size);
180
181 for (unsigned j = 0; j < 4; j++)
182 stage_prog_data->param[uniforms * 4 + j] =
183 &values[GET_SWZ(slots[i].swizzle, j)];
184
185 this->uniform_vector_size[uniforms] =
186 (var->type->is_scalar() || var->type->is_vector() ||
187 var->type->is_matrix() ? var->type->vector_elements : 4);
188
189 nir_uniform_driver_location[uniforms] = var->data.driver_location;
190 uniforms++;
191 }
192 }
193
194 void
195 vec4_visitor::nir_emit_impl(nir_function_impl *impl)
196 {
197 /* @TODO: Not yet implemented */
198 }
199
200 void
201 vec4_visitor::nir_emit_cf_list(exec_list *list)
202 {
203 exec_list_validate(list);
204 foreach_list_typed(nir_cf_node, node, node, list) {
205 switch (node->type) {
206 case nir_cf_node_if:
207 nir_emit_if(nir_cf_node_as_if(node));
208 break;
209
210 case nir_cf_node_loop:
211 nir_emit_loop(nir_cf_node_as_loop(node));
212 break;
213
214 case nir_cf_node_block:
215 nir_emit_block(nir_cf_node_as_block(node));
216 break;
217
218 default:
219 unreachable("Invalid CFG node block");
220 }
221 }
222 }
223
224 void
225 vec4_visitor::nir_emit_if(nir_if *if_stmt)
226 {
227 /* @TODO: Not yet implemented */
228 }
229
230 void
231 vec4_visitor::nir_emit_loop(nir_loop *loop)
232 {
233 /* @TODO: Not yet implemented */
234 }
235
236 void
237 vec4_visitor::nir_emit_block(nir_block *block)
238 {
239 nir_foreach_instr(block, instr) {
240 nir_emit_instr(instr);
241 }
242 }
243
244 void
245 vec4_visitor::nir_emit_instr(nir_instr *instr)
246 {
247 this->base_ir = instr;
248
249 switch (instr->type) {
250 case nir_instr_type_load_const:
251 nir_emit_load_const(nir_instr_as_load_const(instr));
252 break;
253
254 case nir_instr_type_intrinsic:
255 nir_emit_intrinsic(nir_instr_as_intrinsic(instr));
256 break;
257
258 case nir_instr_type_alu:
259 nir_emit_alu(nir_instr_as_alu(instr));
260 break;
261
262 case nir_instr_type_jump:
263 nir_emit_jump(nir_instr_as_jump(instr));
264 break;
265
266 case nir_instr_type_tex:
267 nir_emit_texture(nir_instr_as_tex(instr));
268 break;
269
270 default:
271 fprintf(stderr, "VS instruction not yet implemented by NIR->vec4\n");
272 break;
273 }
274 }
275
276 void
277 vec4_visitor::nir_emit_load_const(nir_load_const_instr *instr)
278 {
279 /* @TODO: Not yet implemented */
280 }
281
282 void
283 vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
284 {
285 switch (instr->intrinsic) {
286
287 case nir_intrinsic_load_input_indirect:
288 /* fallthrough */
289 case nir_intrinsic_load_input:
290 /* @TODO: Not yet implemented */
291 break;
292
293 case nir_intrinsic_store_output_indirect:
294 /* fallthrough */
295 case nir_intrinsic_store_output:
296 /* @TODO: Not yet implemented */
297 break;
298
299 case nir_intrinsic_load_vertex_id:
300 unreachable("should be lowered by lower_vertex_id()");
301
302 case nir_intrinsic_load_vertex_id_zero_base:
303 /* @TODO: Not yet implemented */
304 break;
305
306 case nir_intrinsic_load_base_vertex:
307 /* @TODO: Not yet implemented */
308 break;
309
310 case nir_intrinsic_load_instance_id:
311 /* @TODO: Not yet implemented */
312 break;
313
314 case nir_intrinsic_load_uniform_indirect:
315 /* fallthrough */
316 case nir_intrinsic_load_uniform:
317 /* @TODO: Not yet implemented */
318 break;
319
320 case nir_intrinsic_atomic_counter_read:
321 case nir_intrinsic_atomic_counter_inc:
322 case nir_intrinsic_atomic_counter_dec:
323 /* @TODO: Not yet implemented */
324 break;
325
326 case nir_intrinsic_load_ubo_indirect:
327 /* fallthrough */
328 case nir_intrinsic_load_ubo:
329 /* @TODO: Not yet implemented */
330 break;
331
332 default:
333 unreachable("Unknown intrinsic");
334 }
335 }
336
337 void
338 vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
339 {
340 /* @TODO: Not yet implemented */
341 }
342
343 void
344 vec4_visitor::nir_emit_jump(nir_jump_instr *instr)
345 {
346 /* @TODO: Not yet implemented */
347 }
348
349 void
350 vec4_visitor::nir_emit_texture(nir_tex_instr *instr)
351 {
352 /* @TODO: Not yet implemented */
353 }
354
355 }