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