Merge remote-tracking branch 'mesa-public/master' into vulkan
[mesa.git] / src / gallium / auxiliary / nir / tgsi_to_nir.c
1 /*
2 * Copyright © 2014-2015 Broadcom
3 * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 #include "util/ralloc.h"
26 #include "glsl/nir/nir.h"
27 #include "glsl/nir/nir_control_flow.h"
28 #include "glsl/nir/nir_builder.h"
29 #include "glsl/list.h"
30 #include "glsl/shader_enums.h"
31
32 #include "nir/tgsi_to_nir.h"
33 #include "tgsi/tgsi_parse.h"
34 #include "tgsi/tgsi_dump.h"
35 #include "tgsi/tgsi_info.h"
36 #include "tgsi/tgsi_scan.h"
37
38 #define SWIZ(X, Y, Z, W) (unsigned[4]){ \
39 TGSI_SWIZZLE_##X, \
40 TGSI_SWIZZLE_##Y, \
41 TGSI_SWIZZLE_##Z, \
42 TGSI_SWIZZLE_##W, \
43 }
44
45 struct ttn_reg_info {
46 /** nir register containing this TGSI index. */
47 nir_register *reg;
48 nir_variable *var;
49 /** Offset (in vec4s) from the start of var for this TGSI index. */
50 int offset;
51 };
52
53 struct ttn_compile {
54 union tgsi_full_token *token;
55 nir_builder build;
56 struct tgsi_shader_info *scan;
57
58 struct ttn_reg_info *output_regs;
59 struct ttn_reg_info *temp_regs;
60 nir_ssa_def **imm_defs;
61
62 unsigned num_samp_types;
63 nir_alu_type *samp_types;
64
65 nir_register *addr_reg;
66
67 /**
68 * Stack of nir_cursors where instructions should be pushed as we pop
69 * back out of the control flow stack.
70 *
71 * For each IF/ELSE/ENDIF block, if_stack[if_stack_pos] has where the else
72 * instructions should be placed, and if_stack[if_stack_pos - 1] has where
73 * the next instructions outside of the if/then/else block go.
74 */
75 nir_cursor *if_stack;
76 unsigned if_stack_pos;
77
78 /**
79 * Stack of nir_cursors where instructions should be pushed as we pop
80 * back out of the control flow stack.
81 *
82 * loop_stack[loop_stack_pos - 1] contains the cf_node_list for the outside
83 * of the loop.
84 */
85 nir_cursor *loop_stack;
86 unsigned loop_stack_pos;
87
88 /* How many TGSI_FILE_IMMEDIATE vec4s have been parsed so far. */
89 unsigned next_imm;
90 };
91
92 #define ttn_swizzle(b, src, x, y, z, w) \
93 nir_swizzle(b, src, SWIZ(x, y, z, w), 4, false)
94 #define ttn_channel(b, src, swiz) \
95 nir_swizzle(b, src, SWIZ(swiz, swiz, swiz, swiz), 1, false)
96
97 static nir_ssa_def *
98 ttn_src_for_dest(nir_builder *b, nir_alu_dest *dest)
99 {
100 nir_alu_src src;
101 memset(&src, 0, sizeof(src));
102
103 if (dest->dest.is_ssa)
104 src.src = nir_src_for_ssa(&dest->dest.ssa);
105 else {
106 assert(!dest->dest.reg.indirect);
107 src.src = nir_src_for_reg(dest->dest.reg.reg);
108 src.src.reg.base_offset = dest->dest.reg.base_offset;
109 }
110
111 for (int i = 0; i < 4; i++)
112 src.swizzle[i] = i;
113
114 return nir_fmov_alu(b, src, 4);
115 }
116
117 static void
118 ttn_emit_declaration(struct ttn_compile *c)
119 {
120 nir_builder *b = &c->build;
121 struct tgsi_full_declaration *decl = &c->token->FullDeclaration;
122 unsigned array_size = decl->Range.Last - decl->Range.First + 1;
123 unsigned file = decl->Declaration.File;
124 unsigned i;
125
126 if (file == TGSI_FILE_TEMPORARY) {
127 if (decl->Declaration.Array) {
128 /* for arrays, we create variables instead of registers: */
129 nir_variable *var = rzalloc(b->shader, nir_variable);
130
131 var->type = glsl_array_type(glsl_vec4_type(), array_size);
132 var->data.mode = nir_var_global;
133 var->name = ralloc_asprintf(var, "arr_%d", decl->Array.ArrayID);
134
135 exec_list_push_tail(&b->shader->globals, &var->node);
136
137 for (i = 0; i < array_size; i++) {
138 /* point all the matching slots to the same var,
139 * with appropriate offset set, mostly just so
140 * we know what to do when tgsi does a non-indirect
141 * access
142 */
143 c->temp_regs[decl->Range.First + i].reg = NULL;
144 c->temp_regs[decl->Range.First + i].var = var;
145 c->temp_regs[decl->Range.First + i].offset = i;
146 }
147 } else {
148 for (i = 0; i < array_size; i++) {
149 nir_register *reg = nir_local_reg_create(b->impl);
150 reg->num_components = 4;
151 c->temp_regs[decl->Range.First + i].reg = reg;
152 c->temp_regs[decl->Range.First + i].var = NULL;
153 c->temp_regs[decl->Range.First + i].offset = 0;
154 }
155 }
156 } else if (file == TGSI_FILE_ADDRESS) {
157 c->addr_reg = nir_local_reg_create(b->impl);
158 c->addr_reg->num_components = 4;
159 } else if (file == TGSI_FILE_SYSTEM_VALUE) {
160 /* Nothing to record for system values. */
161 } else if (file == TGSI_FILE_SAMPLER) {
162 /* Nothing to record for samplers. */
163 } else if (file == TGSI_FILE_SAMPLER_VIEW) {
164 struct tgsi_declaration_sampler_view *sview = &decl->SamplerView;
165 nir_alu_type type;
166
167 assert((sview->ReturnTypeX == sview->ReturnTypeY) &&
168 (sview->ReturnTypeX == sview->ReturnTypeZ) &&
169 (sview->ReturnTypeX == sview->ReturnTypeW));
170
171 switch (sview->ReturnTypeX) {
172 case TGSI_RETURN_TYPE_SINT:
173 type = nir_type_int;
174 break;
175 case TGSI_RETURN_TYPE_UINT:
176 type = nir_type_unsigned;
177 break;
178 case TGSI_RETURN_TYPE_FLOAT:
179 default:
180 type = nir_type_float;
181 break;
182 }
183
184 for (i = 0; i < array_size; i++) {
185 c->samp_types[decl->Range.First + i] = type;
186 }
187 } else {
188 bool is_array = (array_size > 1);
189
190 assert(file == TGSI_FILE_INPUT ||
191 file == TGSI_FILE_OUTPUT ||
192 file == TGSI_FILE_CONSTANT);
193
194 /* nothing to do for UBOs: */
195 if ((file == TGSI_FILE_CONSTANT) && decl->Declaration.Dimension)
196 return;
197
198 if ((file == TGSI_FILE_INPUT) || (file == TGSI_FILE_OUTPUT)) {
199 is_array = (is_array && decl->Declaration.Array &&
200 (decl->Array.ArrayID != 0));
201 }
202
203 for (i = 0; i < array_size; i++) {
204 unsigned idx = decl->Range.First + i;
205 nir_variable *var = rzalloc(b->shader, nir_variable);
206
207 var->data.driver_location = idx;
208
209 var->type = glsl_vec4_type();
210 if (is_array)
211 var->type = glsl_array_type(var->type, array_size);
212
213 switch (file) {
214 case TGSI_FILE_INPUT:
215 var->data.read_only = true;
216 var->data.mode = nir_var_shader_in;
217 var->name = ralloc_asprintf(var, "in_%d", idx);
218
219 /* We should probably translate to a VERT_ATTRIB_* or VARYING_SLOT_*
220 * instead, but nothing in NIR core is looking at the value
221 * currently, and this is less change to drivers.
222 */
223 var->data.location = decl->Semantic.Name;
224 var->data.index = decl->Semantic.Index;
225
226 /* We definitely need to translate the interpolation field, because
227 * nir_print will decode it.
228 */
229 switch (decl->Interp.Interpolate) {
230 case TGSI_INTERPOLATE_CONSTANT:
231 var->data.interpolation = INTERP_QUALIFIER_FLAT;
232 break;
233 case TGSI_INTERPOLATE_LINEAR:
234 var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
235 break;
236 case TGSI_INTERPOLATE_PERSPECTIVE:
237 var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
238 break;
239 }
240
241 exec_list_push_tail(&b->shader->inputs, &var->node);
242 break;
243 case TGSI_FILE_OUTPUT: {
244 /* Since we can't load from outputs in the IR, we make temporaries
245 * for the outputs and emit stores to the real outputs at the end of
246 * the shader.
247 */
248 nir_register *reg = nir_local_reg_create(b->impl);
249 reg->num_components = 4;
250 if (is_array)
251 reg->num_array_elems = array_size;
252
253 var->data.mode = nir_var_shader_out;
254 var->name = ralloc_asprintf(var, "out_%d", idx);
255
256 var->data.location = decl->Semantic.Name;
257 if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
258 decl->Semantic.Index == 0 &&
259 c->scan->properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
260 var->data.index = -1;
261 else
262 var->data.index = decl->Semantic.Index;
263
264 if (is_array) {
265 unsigned j;
266 for (j = 0; j < array_size; j++) {
267 c->output_regs[idx + j].offset = i + j;
268 c->output_regs[idx + j].reg = reg;
269 }
270 } else {
271 c->output_regs[idx].offset = i;
272 c->output_regs[idx].reg = reg;
273 }
274
275 exec_list_push_tail(&b->shader->outputs, &var->node);
276 }
277 break;
278 case TGSI_FILE_CONSTANT:
279 var->data.mode = nir_var_uniform;
280 var->name = ralloc_asprintf(var, "uniform_%d", idx);
281
282 exec_list_push_tail(&b->shader->uniforms, &var->node);
283 break;
284 default:
285 unreachable("bad declaration file");
286 return;
287 }
288
289 if (is_array)
290 break;
291 }
292
293 }
294 }
295
296 static void
297 ttn_emit_immediate(struct ttn_compile *c)
298 {
299 nir_builder *b = &c->build;
300 struct tgsi_full_immediate *tgsi_imm = &c->token->FullImmediate;
301 nir_load_const_instr *load_const;
302 int i;
303
304 load_const = nir_load_const_instr_create(b->shader, 4);
305 c->imm_defs[c->next_imm] = &load_const->def;
306 c->next_imm++;
307
308 for (i = 0; i < 4; i++)
309 load_const->value.u[i] = tgsi_imm->u[i].Uint;
310
311 nir_builder_instr_insert(b, &load_const->instr);
312 }
313
314 static nir_src
315 ttn_src_for_indirect(struct ttn_compile *c, struct tgsi_ind_register *indirect);
316
317 /* generate either a constant or indirect deref chain for accessing an
318 * array variable.
319 */
320 static nir_deref_var *
321 ttn_array_deref(struct ttn_compile *c, nir_intrinsic_instr *instr,
322 nir_variable *var, unsigned offset,
323 struct tgsi_ind_register *indirect)
324 {
325 nir_deref_var *deref = nir_deref_var_create(instr, var);
326 nir_deref_array *arr = nir_deref_array_create(deref);
327
328 arr->base_offset = offset;
329 arr->deref.type = glsl_get_array_element(var->type);
330
331 if (indirect) {
332 arr->deref_array_type = nir_deref_array_type_indirect;
333 arr->indirect = ttn_src_for_indirect(c, indirect);
334 } else {
335 arr->deref_array_type = nir_deref_array_type_direct;
336 }
337
338 deref->deref.child = &arr->deref;
339
340 return deref;
341 }
342
343 static nir_src
344 ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
345 struct tgsi_ind_register *indirect,
346 struct tgsi_dimension *dim,
347 struct tgsi_ind_register *dimind)
348 {
349 nir_builder *b = &c->build;
350 nir_src src;
351
352 memset(&src, 0, sizeof(src));
353
354 switch (file) {
355 case TGSI_FILE_TEMPORARY:
356 if (c->temp_regs[index].var) {
357 unsigned offset = c->temp_regs[index].offset;
358 nir_variable *var = c->temp_regs[index].var;
359 nir_intrinsic_instr *load;
360
361 load = nir_intrinsic_instr_create(b->shader,
362 nir_intrinsic_load_var);
363 load->num_components = 4;
364 load->variables[0] = ttn_array_deref(c, load, var, offset, indirect);
365
366 nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
367 nir_builder_instr_insert(b, &load->instr);
368
369 src = nir_src_for_ssa(&load->dest.ssa);
370
371 } else {
372 assert(!indirect);
373 src.reg.reg = c->temp_regs[index].reg;
374 }
375 assert(!dim);
376 break;
377
378 case TGSI_FILE_ADDRESS:
379 src.reg.reg = c->addr_reg;
380 assert(!dim);
381 break;
382
383 case TGSI_FILE_IMMEDIATE:
384 src = nir_src_for_ssa(c->imm_defs[index]);
385 assert(!indirect);
386 assert(!dim);
387 break;
388
389 case TGSI_FILE_SYSTEM_VALUE: {
390 nir_intrinsic_instr *load;
391 nir_intrinsic_op op;
392 unsigned ncomp = 1;
393
394 assert(!indirect);
395 assert(!dim);
396
397 switch (c->scan->system_value_semantic_name[index]) {
398 case TGSI_SEMANTIC_VERTEXID_NOBASE:
399 op = nir_intrinsic_load_vertex_id_zero_base;
400 break;
401 case TGSI_SEMANTIC_VERTEXID:
402 op = nir_intrinsic_load_vertex_id;
403 break;
404 case TGSI_SEMANTIC_BASEVERTEX:
405 op = nir_intrinsic_load_base_vertex;
406 break;
407 case TGSI_SEMANTIC_INSTANCEID:
408 op = nir_intrinsic_load_instance_id;
409 break;
410 default:
411 unreachable("bad system value");
412 }
413
414 load = nir_intrinsic_instr_create(b->shader, op);
415 load->num_components = ncomp;
416
417 nir_ssa_dest_init(&load->instr, &load->dest, ncomp, NULL);
418 nir_builder_instr_insert(b, &load->instr);
419
420 src = nir_src_for_ssa(&load->dest.ssa);
421 break;
422 }
423
424 case TGSI_FILE_INPUT:
425 case TGSI_FILE_CONSTANT: {
426 nir_intrinsic_instr *load;
427 nir_intrinsic_op op;
428 unsigned srcn = 0;
429
430 switch (file) {
431 case TGSI_FILE_INPUT:
432 op = indirect ? nir_intrinsic_load_input_indirect :
433 nir_intrinsic_load_input;
434 assert(!dim);
435 break;
436 case TGSI_FILE_CONSTANT:
437 if (dim) {
438 op = indirect ? nir_intrinsic_load_ubo_indirect :
439 nir_intrinsic_load_ubo;
440 /* convert index from vec4 to byte: */
441 index *= 16;
442 } else {
443 op = indirect ? nir_intrinsic_load_uniform_indirect :
444 nir_intrinsic_load_uniform;
445 }
446 break;
447 default:
448 unreachable("No other load files supported");
449 break;
450 }
451
452 load = nir_intrinsic_instr_create(b->shader, op);
453
454 load->num_components = 4;
455 load->const_index[0] = index;
456 if (dim) {
457 if (dimind) {
458 load->src[srcn] =
459 ttn_src_for_file_and_index(c, dimind->File, dimind->Index,
460 NULL, NULL, NULL);
461 } else {
462 /* UBOs start at index 1 in TGSI: */
463 load->src[srcn] =
464 nir_src_for_ssa(nir_imm_int(b, dim->Index - 1));
465 }
466 srcn++;
467 }
468 if (indirect) {
469 load->src[srcn] = ttn_src_for_indirect(c, indirect);
470 if (dim) {
471 assert(load->src[srcn].is_ssa);
472 /* we also need to covert vec4 to byte here too: */
473 load->src[srcn] =
474 nir_src_for_ssa(nir_ishl(b, load->src[srcn].ssa,
475 nir_imm_int(b, 4)));
476 }
477 srcn++;
478 }
479 nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
480 nir_builder_instr_insert(b, &load->instr);
481
482 src = nir_src_for_ssa(&load->dest.ssa);
483 break;
484 }
485
486 default:
487 unreachable("bad src file");
488 }
489
490
491 return src;
492 }
493
494 static nir_src
495 ttn_src_for_indirect(struct ttn_compile *c, struct tgsi_ind_register *indirect)
496 {
497 nir_builder *b = &c->build;
498 nir_alu_src src;
499 memset(&src, 0, sizeof(src));
500 for (int i = 0; i < 4; i++)
501 src.swizzle[i] = indirect->Swizzle;
502 src.src = ttn_src_for_file_and_index(c,
503 indirect->File,
504 indirect->Index,
505 NULL, NULL, NULL);
506 return nir_src_for_ssa(nir_imov_alu(b, src, 1));
507 }
508
509 static nir_alu_dest
510 ttn_get_dest(struct ttn_compile *c, struct tgsi_full_dst_register *tgsi_fdst)
511 {
512 struct tgsi_dst_register *tgsi_dst = &tgsi_fdst->Register;
513 nir_alu_dest dest;
514 unsigned index = tgsi_dst->Index;
515
516 memset(&dest, 0, sizeof(dest));
517
518 if (tgsi_dst->File == TGSI_FILE_TEMPORARY) {
519 if (c->temp_regs[index].var) {
520 nir_builder *b = &c->build;
521 nir_intrinsic_instr *load;
522 struct tgsi_ind_register *indirect =
523 tgsi_dst->Indirect ? &tgsi_fdst->Indirect : NULL;
524 nir_register *reg;
525
526 /* this works, because TGSI will give us a base offset
527 * (in case of indirect index) that points back into
528 * the array. Access can be direct or indirect, we
529 * don't really care. Just create a one-shot dst reg
530 * that will get store_var'd back into the array var
531 * at the end of ttn_emit_instruction()
532 */
533 reg = nir_local_reg_create(c->build.impl);
534 reg->num_components = 4;
535 dest.dest.reg.reg = reg;
536 dest.dest.reg.base_offset = 0;
537
538 /* since the alu op might not write to all components
539 * of the temporary, we must first do a load_var to
540 * get the previous array elements into the register.
541 * This is one area that NIR could use a bit of
542 * improvement (or opt pass to clean up the mess
543 * once things are scalarized)
544 */
545
546 load = nir_intrinsic_instr_create(c->build.shader,
547 nir_intrinsic_load_var);
548 load->num_components = 4;
549 load->variables[0] =
550 ttn_array_deref(c, load, c->temp_regs[index].var,
551 c->temp_regs[index].offset,
552 indirect);
553
554 load->dest = nir_dest_for_reg(reg);
555
556 nir_builder_instr_insert(b, &load->instr);
557 } else {
558 assert(!tgsi_dst->Indirect);
559 dest.dest.reg.reg = c->temp_regs[index].reg;
560 dest.dest.reg.base_offset = c->temp_regs[index].offset;
561 }
562 } else if (tgsi_dst->File == TGSI_FILE_OUTPUT) {
563 dest.dest.reg.reg = c->output_regs[index].reg;
564 dest.dest.reg.base_offset = c->output_regs[index].offset;
565 } else if (tgsi_dst->File == TGSI_FILE_ADDRESS) {
566 assert(index == 0);
567 dest.dest.reg.reg = c->addr_reg;
568 }
569
570 dest.write_mask = tgsi_dst->WriteMask;
571 dest.saturate = false;
572
573 if (tgsi_dst->Indirect && (tgsi_dst->File != TGSI_FILE_TEMPORARY)) {
574 nir_src *indirect = ralloc(c->build.shader, nir_src);
575 *indirect = ttn_src_for_indirect(c, &tgsi_fdst->Indirect);
576 dest.dest.reg.indirect = indirect;
577 }
578
579 return dest;
580 }
581
582 static nir_variable *
583 ttn_get_var(struct ttn_compile *c, struct tgsi_full_dst_register *tgsi_fdst)
584 {
585 struct tgsi_dst_register *tgsi_dst = &tgsi_fdst->Register;
586 unsigned index = tgsi_dst->Index;
587
588 if (tgsi_dst->File == TGSI_FILE_TEMPORARY) {
589 /* we should not have an indirect when there is no var! */
590 if (!c->temp_regs[index].var)
591 assert(!tgsi_dst->Indirect);
592 return c->temp_regs[index].var;
593 }
594
595 return NULL;
596 }
597
598 static nir_ssa_def *
599 ttn_get_src(struct ttn_compile *c, struct tgsi_full_src_register *tgsi_fsrc)
600 {
601 nir_builder *b = &c->build;
602 struct tgsi_src_register *tgsi_src = &tgsi_fsrc->Register;
603 unsigned tgsi_opcode = c->token->FullInstruction.Instruction.Opcode;
604 unsigned tgsi_src_type = tgsi_opcode_infer_src_type(tgsi_opcode);
605 bool src_is_float = !(tgsi_src_type == TGSI_TYPE_SIGNED ||
606 tgsi_src_type == TGSI_TYPE_UNSIGNED);
607 nir_alu_src src;
608
609 memset(&src, 0, sizeof(src));
610
611 if (tgsi_src->File == TGSI_FILE_NULL) {
612 return nir_imm_float(b, 0.0);
613 } else if (tgsi_src->File == TGSI_FILE_SAMPLER) {
614 /* Only the index of the sampler gets used in texturing, and it will
615 * handle looking that up on its own instead of using the nir_alu_src.
616 */
617 assert(!tgsi_src->Indirect);
618 return NULL;
619 } else {
620 struct tgsi_ind_register *ind = NULL;
621 struct tgsi_dimension *dim = NULL;
622 struct tgsi_ind_register *dimind = NULL;
623 if (tgsi_src->Indirect)
624 ind = &tgsi_fsrc->Indirect;
625 if (tgsi_src->Dimension) {
626 dim = &tgsi_fsrc->Dimension;
627 if (dim->Indirect)
628 dimind = &tgsi_fsrc->DimIndirect;
629 }
630 src.src = ttn_src_for_file_and_index(c,
631 tgsi_src->File,
632 tgsi_src->Index,
633 ind, dim, dimind);
634 }
635
636 src.swizzle[0] = tgsi_src->SwizzleX;
637 src.swizzle[1] = tgsi_src->SwizzleY;
638 src.swizzle[2] = tgsi_src->SwizzleZ;
639 src.swizzle[3] = tgsi_src->SwizzleW;
640
641 nir_ssa_def *def = nir_fmov_alu(b, src, 4);
642
643 if (tgsi_src->Absolute) {
644 if (src_is_float)
645 def = nir_fabs(b, def);
646 else
647 def = nir_iabs(b, def);
648 }
649
650 if (tgsi_src->Negate) {
651 if (src_is_float)
652 def = nir_fneg(b, def);
653 else
654 def = nir_ineg(b, def);
655 }
656
657 return def;
658 }
659
660 static void
661 ttn_alu(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
662 {
663 unsigned num_srcs = nir_op_infos[op].num_inputs;
664 nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
665 unsigned i;
666
667 for (i = 0; i < num_srcs; i++)
668 instr->src[i].src = nir_src_for_ssa(src[i]);
669
670 instr->dest = dest;
671 nir_builder_instr_insert(b, &instr->instr);
672 }
673
674 static void
675 ttn_move_dest_masked(nir_builder *b, nir_alu_dest dest,
676 nir_ssa_def *def, unsigned write_mask)
677 {
678 if (!(dest.write_mask & write_mask))
679 return;
680
681 nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_imov);
682 mov->dest = dest;
683 mov->dest.write_mask &= write_mask;
684 mov->src[0].src = nir_src_for_ssa(def);
685 for (unsigned i = def->num_components; i < 4; i++)
686 mov->src[0].swizzle[i] = def->num_components - 1;
687 nir_builder_instr_insert(b, &mov->instr);
688 }
689
690 static void
691 ttn_move_dest(nir_builder *b, nir_alu_dest dest, nir_ssa_def *def)
692 {
693 ttn_move_dest_masked(b, dest, def, TGSI_WRITEMASK_XYZW);
694 }
695
696 static void
697 ttn_arl(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
698 {
699 ttn_move_dest(b, dest, nir_f2i(b, nir_ffloor(b, src[0])));
700 }
701
702 /* EXP - Approximate Exponential Base 2
703 * dst.x = 2^{\lfloor src.x\rfloor}
704 * dst.y = src.x - \lfloor src.x\rfloor
705 * dst.z = 2^{src.x}
706 * dst.w = 1.0
707 */
708 static void
709 ttn_exp(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
710 {
711 nir_ssa_def *srcx = ttn_channel(b, src[0], X);
712
713 ttn_move_dest_masked(b, dest, nir_fexp2(b, nir_ffloor(b, srcx)),
714 TGSI_WRITEMASK_X);
715 ttn_move_dest_masked(b, dest, nir_fsub(b, srcx, nir_ffloor(b, srcx)),
716 TGSI_WRITEMASK_Y);
717 ttn_move_dest_masked(b, dest, nir_fexp2(b, srcx), TGSI_WRITEMASK_Z);
718 ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_W);
719 }
720
721 /* LOG - Approximate Logarithm Base 2
722 * dst.x = \lfloor\log_2{|src.x|}\rfloor
723 * dst.y = \frac{|src.x|}{2^{\lfloor\log_2{|src.x|}\rfloor}}
724 * dst.z = \log_2{|src.x|}
725 * dst.w = 1.0
726 */
727 static void
728 ttn_log(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
729 {
730 nir_ssa_def *abs_srcx = nir_fabs(b, ttn_channel(b, src[0], X));
731 nir_ssa_def *log2 = nir_flog2(b, abs_srcx);
732
733 ttn_move_dest_masked(b, dest, nir_ffloor(b, log2), TGSI_WRITEMASK_X);
734 ttn_move_dest_masked(b, dest,
735 nir_fdiv(b, abs_srcx, nir_fexp2(b, nir_ffloor(b, log2))),
736 TGSI_WRITEMASK_Y);
737 ttn_move_dest_masked(b, dest, nir_flog2(b, abs_srcx), TGSI_WRITEMASK_Z);
738 ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_W);
739 }
740
741 /* DST - Distance Vector
742 * dst.x = 1.0
743 * dst.y = src0.y \times src1.y
744 * dst.z = src0.z
745 * dst.w = src1.w
746 */
747 static void
748 ttn_dst(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
749 {
750 ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_X);
751 ttn_move_dest_masked(b, dest, nir_fmul(b, src[0], src[1]), TGSI_WRITEMASK_Y);
752 ttn_move_dest_masked(b, dest, nir_fmov(b, src[0]), TGSI_WRITEMASK_Z);
753 ttn_move_dest_masked(b, dest, nir_fmov(b, src[1]), TGSI_WRITEMASK_W);
754 }
755
756 /* LIT - Light Coefficients
757 * dst.x = 1.0
758 * dst.y = max(src.x, 0.0)
759 * dst.z = (src.x > 0.0) ? max(src.y, 0.0)^{clamp(src.w, -128.0, 128.0))} : 0
760 * dst.w = 1.0
761 */
762 static void
763 ttn_lit(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
764 {
765 ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_XW);
766
767 ttn_move_dest_masked(b, dest, nir_fmax(b, ttn_channel(b, src[0], X),
768 nir_imm_float(b, 0.0)), TGSI_WRITEMASK_Y);
769
770 if (dest.write_mask & TGSI_WRITEMASK_Z) {
771 nir_ssa_def *src0_y = ttn_channel(b, src[0], Y);
772 nir_ssa_def *wclamp = nir_fmax(b, nir_fmin(b, ttn_channel(b, src[0], W),
773 nir_imm_float(b, 128.0)),
774 nir_imm_float(b, -128.0));
775 nir_ssa_def *pow = nir_fpow(b, nir_fmax(b, src0_y, nir_imm_float(b, 0.0)),
776 wclamp);
777
778 ttn_move_dest_masked(b, dest,
779 nir_bcsel(b,
780 nir_fge(b,
781 nir_imm_float(b, 0.0),
782 ttn_channel(b, src[0], X)),
783 nir_imm_float(b, 0.0),
784 pow),
785 TGSI_WRITEMASK_Z);
786 }
787 }
788
789 /* SCS - Sine Cosine
790 * dst.x = \cos{src.x}
791 * dst.y = \sin{src.x}
792 * dst.z = 0.0
793 * dst.w = 1.0
794 */
795 static void
796 ttn_scs(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
797 {
798 ttn_move_dest_masked(b, dest, nir_fcos(b, ttn_channel(b, src[0], X)),
799 TGSI_WRITEMASK_X);
800 ttn_move_dest_masked(b, dest, nir_fsin(b, ttn_channel(b, src[0], X)),
801 TGSI_WRITEMASK_Y);
802 ttn_move_dest_masked(b, dest, nir_imm_float(b, 0.0), TGSI_WRITEMASK_Z);
803 ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_W);
804 }
805
806 static void
807 ttn_sle(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
808 {
809 ttn_move_dest(b, dest, nir_sge(b, src[1], src[0]));
810 }
811
812 static void
813 ttn_sgt(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
814 {
815 ttn_move_dest(b, dest, nir_slt(b, src[1], src[0]));
816 }
817
818 static void
819 ttn_clamp(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
820 {
821 ttn_move_dest(b, dest, nir_fmin(b, nir_fmax(b, src[0], src[1]), src[2]));
822 }
823
824 static void
825 ttn_xpd(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
826 {
827 ttn_move_dest_masked(b, dest,
828 nir_fsub(b,
829 nir_fmul(b,
830 ttn_swizzle(b, src[0], Y, Z, X, X),
831 ttn_swizzle(b, src[1], Z, X, Y, X)),
832 nir_fmul(b,
833 ttn_swizzle(b, src[1], Y, Z, X, X),
834 ttn_swizzle(b, src[0], Z, X, Y, X))),
835 TGSI_WRITEMASK_XYZ);
836 ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_W);
837 }
838
839 static void
840 ttn_dp2a(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
841 {
842 ttn_move_dest(b, dest,
843 ttn_channel(b, nir_fadd(b, nir_fdot2(b, src[0], src[1]),
844 src[2]),
845 X));
846 }
847
848 static void
849 ttn_dp2(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
850 {
851 ttn_move_dest(b, dest, nir_fdot2(b, src[0], src[1]));
852 }
853
854 static void
855 ttn_dp3(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
856 {
857 ttn_move_dest(b, dest, nir_fdot3(b, src[0], src[1]));
858 }
859
860 static void
861 ttn_dp4(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
862 {
863 ttn_move_dest(b, dest, nir_fdot4(b, src[0], src[1]));
864 }
865
866 static void
867 ttn_dph(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
868 {
869 ttn_move_dest(b, dest, nir_fadd(b, nir_fdot3(b, src[0], src[1]),
870 ttn_channel(b, src[1], W)));
871 }
872
873 static void
874 ttn_umad(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
875 {
876 ttn_move_dest(b, dest, nir_iadd(b, nir_imul(b, src[0], src[1]), src[2]));
877 }
878
879 static void
880 ttn_arr(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
881 {
882 ttn_move_dest(b, dest, nir_ffloor(b, nir_fadd(b, src[0], nir_imm_float(b, 0.5))));
883 }
884
885 static void
886 ttn_cmp(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
887 {
888 ttn_move_dest(b, dest, nir_bcsel(b,
889 nir_flt(b, src[0], nir_imm_float(b, 0.0)),
890 src[1], src[2]));
891 }
892
893 static void
894 ttn_ucmp(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
895 {
896 ttn_move_dest(b, dest, nir_bcsel(b,
897 nir_ine(b, src[0], nir_imm_int(b, 0)),
898 src[1], src[2]));
899 }
900
901 static void
902 ttn_kill(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
903 {
904 nir_intrinsic_instr *discard =
905 nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard);
906 nir_builder_instr_insert(b, &discard->instr);
907 }
908
909 static void
910 ttn_kill_if(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
911 {
912 nir_ssa_def *cmp = nir_bany4(b, nir_flt(b, src[0], nir_imm_float(b, 0.0)));
913 nir_intrinsic_instr *discard =
914 nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
915 discard->src[0] = nir_src_for_ssa(cmp);
916 nir_builder_instr_insert(b, &discard->instr);
917 }
918
919 static void
920 ttn_if(struct ttn_compile *c, nir_ssa_def *src, bool is_uint)
921 {
922 nir_builder *b = &c->build;
923
924 /* Save the outside-of-the-if-statement node list. */
925 c->if_stack[c->if_stack_pos] = b->cursor;
926 c->if_stack_pos++;
927
928 src = ttn_channel(b, src, X);
929
930 nir_if *if_stmt = nir_if_create(b->shader);
931 if (is_uint) {
932 if_stmt->condition = nir_src_for_ssa(nir_ine(b, src, nir_imm_int(b, 0)));
933 } else {
934 if_stmt->condition = nir_src_for_ssa(nir_fne(b, src, nir_imm_int(b, 0)));
935 }
936 nir_builder_cf_insert(b, &if_stmt->cf_node);
937
938 b->cursor = nir_after_cf_list(&if_stmt->then_list);
939
940 c->if_stack[c->if_stack_pos] = nir_after_cf_list(&if_stmt->else_list);
941 c->if_stack_pos++;
942 }
943
944 static void
945 ttn_else(struct ttn_compile *c)
946 {
947 nir_builder *b = &c->build;
948
949 b->cursor = c->if_stack[c->if_stack_pos - 1];
950 }
951
952 static void
953 ttn_endif(struct ttn_compile *c)
954 {
955 nir_builder *b = &c->build;
956
957 c->if_stack_pos -= 2;
958 b->cursor = c->if_stack[c->if_stack_pos];
959 }
960
961 static void
962 ttn_bgnloop(struct ttn_compile *c)
963 {
964 nir_builder *b = &c->build;
965
966 /* Save the outside-of-the-loop node list. */
967 c->loop_stack[c->loop_stack_pos] = b->cursor;
968 c->loop_stack_pos++;
969
970 nir_loop *loop = nir_loop_create(b->shader);
971 nir_builder_cf_insert(b, &loop->cf_node);
972
973 b->cursor = nir_after_cf_list(&loop->body);
974 }
975
976 static void
977 ttn_cont(nir_builder *b)
978 {
979 nir_jump_instr *instr = nir_jump_instr_create(b->shader, nir_jump_continue);
980 nir_builder_instr_insert(b, &instr->instr);
981 }
982
983 static void
984 ttn_brk(nir_builder *b)
985 {
986 nir_jump_instr *instr = nir_jump_instr_create(b->shader, nir_jump_break);
987 nir_builder_instr_insert(b, &instr->instr);
988 }
989
990 static void
991 ttn_endloop(struct ttn_compile *c)
992 {
993 nir_builder *b = &c->build;
994
995 c->loop_stack_pos--;
996 b->cursor = c->loop_stack[c->loop_stack_pos];
997 }
998
999 static void
1000 setup_texture_info(nir_tex_instr *instr, unsigned texture)
1001 {
1002 switch (texture) {
1003 case TGSI_TEXTURE_BUFFER:
1004 instr->sampler_dim = GLSL_SAMPLER_DIM_BUF;
1005 break;
1006 case TGSI_TEXTURE_1D:
1007 instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
1008 break;
1009 case TGSI_TEXTURE_1D_ARRAY:
1010 instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
1011 instr->is_array = true;
1012 break;
1013 case TGSI_TEXTURE_SHADOW1D:
1014 instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
1015 instr->is_shadow = true;
1016 break;
1017 case TGSI_TEXTURE_SHADOW1D_ARRAY:
1018 instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
1019 instr->is_shadow = true;
1020 instr->is_array = true;
1021 break;
1022 case TGSI_TEXTURE_2D:
1023 instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
1024 break;
1025 case TGSI_TEXTURE_2D_ARRAY:
1026 instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
1027 instr->is_array = true;
1028 break;
1029 case TGSI_TEXTURE_2D_MSAA:
1030 instr->sampler_dim = GLSL_SAMPLER_DIM_MS;
1031 break;
1032 case TGSI_TEXTURE_2D_ARRAY_MSAA:
1033 instr->sampler_dim = GLSL_SAMPLER_DIM_MS;
1034 instr->is_array = true;
1035 break;
1036 case TGSI_TEXTURE_SHADOW2D:
1037 instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
1038 instr->is_shadow = true;
1039 break;
1040 case TGSI_TEXTURE_SHADOW2D_ARRAY:
1041 instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
1042 instr->is_shadow = true;
1043 instr->is_array = true;
1044 break;
1045 case TGSI_TEXTURE_3D:
1046 instr->sampler_dim = GLSL_SAMPLER_DIM_3D;
1047 break;
1048 case TGSI_TEXTURE_CUBE:
1049 instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
1050 break;
1051 case TGSI_TEXTURE_CUBE_ARRAY:
1052 instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
1053 instr->is_array = true;
1054 break;
1055 case TGSI_TEXTURE_SHADOWCUBE:
1056 instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
1057 instr->is_shadow = true;
1058 break;
1059 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
1060 instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
1061 instr->is_shadow = true;
1062 instr->is_array = true;
1063 break;
1064 case TGSI_TEXTURE_RECT:
1065 instr->sampler_dim = GLSL_SAMPLER_DIM_RECT;
1066 break;
1067 case TGSI_TEXTURE_SHADOWRECT:
1068 instr->sampler_dim = GLSL_SAMPLER_DIM_RECT;
1069 instr->is_shadow = true;
1070 break;
1071 default:
1072 fprintf(stderr, "Unknown TGSI texture target %d\n", texture);
1073 abort();
1074 }
1075 }
1076
1077 static void
1078 ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
1079 {
1080 nir_builder *b = &c->build;
1081 struct tgsi_full_instruction *tgsi_inst = &c->token->FullInstruction;
1082 nir_tex_instr *instr;
1083 nir_texop op;
1084 unsigned num_srcs, samp = 1, sview, i;
1085
1086 switch (tgsi_inst->Instruction.Opcode) {
1087 case TGSI_OPCODE_TEX:
1088 op = nir_texop_tex;
1089 num_srcs = 1;
1090 break;
1091 case TGSI_OPCODE_TXP:
1092 op = nir_texop_tex;
1093 num_srcs = 2;
1094 break;
1095 case TGSI_OPCODE_TXB:
1096 op = nir_texop_txb;
1097 num_srcs = 2;
1098 break;
1099 case TGSI_OPCODE_TXB2:
1100 op = nir_texop_txb;
1101 num_srcs = 2;
1102 samp = 2;
1103 break;
1104 case TGSI_OPCODE_TXL:
1105 op = nir_texop_txl;
1106 num_srcs = 2;
1107 break;
1108 case TGSI_OPCODE_TXL2:
1109 op = nir_texop_txl;
1110 num_srcs = 2;
1111 samp = 2;
1112 break;
1113 case TGSI_OPCODE_TXF:
1114 if (tgsi_inst->Texture.Texture == TGSI_TEXTURE_2D_MSAA ||
1115 tgsi_inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY_MSAA) {
1116 op = nir_texop_txf_ms;
1117 } else {
1118 op = nir_texop_txf;
1119 }
1120 num_srcs = 2;
1121 break;
1122 case TGSI_OPCODE_TXD:
1123 op = nir_texop_txd;
1124 num_srcs = 3;
1125 samp = 3;
1126 break;
1127
1128 default:
1129 fprintf(stderr, "unknown TGSI tex op %d\n", tgsi_inst->Instruction.Opcode);
1130 abort();
1131 }
1132
1133 if (tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D ||
1134 tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY ||
1135 tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D ||
1136 tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY ||
1137 tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT ||
1138 tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
1139 tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
1140 num_srcs++;
1141 }
1142
1143 num_srcs += tgsi_inst->Texture.NumOffsets;
1144
1145 instr = nir_tex_instr_create(b->shader, num_srcs);
1146 instr->op = op;
1147
1148 setup_texture_info(instr, tgsi_inst->Texture.Texture);
1149
1150 switch (instr->sampler_dim) {
1151 case GLSL_SAMPLER_DIM_1D:
1152 case GLSL_SAMPLER_DIM_BUF:
1153 instr->coord_components = 1;
1154 break;
1155 case GLSL_SAMPLER_DIM_2D:
1156 case GLSL_SAMPLER_DIM_RECT:
1157 case GLSL_SAMPLER_DIM_EXTERNAL:
1158 case GLSL_SAMPLER_DIM_MS:
1159 instr->coord_components = 2;
1160 break;
1161 case GLSL_SAMPLER_DIM_3D:
1162 case GLSL_SAMPLER_DIM_CUBE:
1163 instr->coord_components = 3;
1164 break;
1165 }
1166
1167 if (instr->is_array)
1168 instr->coord_components++;
1169
1170 assert(tgsi_inst->Src[samp].Register.File == TGSI_FILE_SAMPLER);
1171 instr->sampler_index = tgsi_inst->Src[samp].Register.Index;
1172
1173 /* TODO if we supported any opc's which take an explicit SVIEW
1174 * src, we would use that here instead. But for the "legacy"
1175 * texture opc's the SVIEW index is same as SAMP index:
1176 */
1177 sview = instr->sampler_index;
1178
1179 if (sview < c->num_samp_types) {
1180 instr->dest_type = c->samp_types[sview];
1181 } else {
1182 instr->dest_type = nir_type_float;
1183 }
1184
1185 unsigned src_number = 0;
1186
1187 instr->src[src_number].src =
1188 nir_src_for_ssa(nir_swizzle(b, src[0], SWIZ(X, Y, Z, W),
1189 instr->coord_components, false));
1190 instr->src[src_number].src_type = nir_tex_src_coord;
1191 src_number++;
1192
1193 if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
1194 instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
1195 instr->src[src_number].src_type = nir_tex_src_projector;
1196 src_number++;
1197 }
1198
1199 if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXB) {
1200 instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
1201 instr->src[src_number].src_type = nir_tex_src_bias;
1202 src_number++;
1203 }
1204
1205 if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXB2) {
1206 instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[1], X));
1207 instr->src[src_number].src_type = nir_tex_src_bias;
1208 src_number++;
1209 }
1210
1211 if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXL) {
1212 instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
1213 instr->src[src_number].src_type = nir_tex_src_lod;
1214 src_number++;
1215 }
1216
1217 if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXL2) {
1218 instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[1], X));
1219 instr->src[src_number].src_type = nir_tex_src_lod;
1220 src_number++;
1221 }
1222
1223 if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
1224 instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
1225 if (op == nir_texop_txf_ms)
1226 instr->src[src_number].src_type = nir_tex_src_ms_index;
1227 else
1228 instr->src[src_number].src_type = nir_tex_src_lod;
1229 src_number++;
1230 }
1231
1232 if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
1233 instr->src[src_number].src =
1234 nir_src_for_ssa(nir_swizzle(b, src[1], SWIZ(X, Y, Z, W),
1235 instr->coord_components, false));
1236 instr->src[src_number].src_type = nir_tex_src_ddx;
1237 src_number++;
1238 instr->src[src_number].src =
1239 nir_src_for_ssa(nir_swizzle(b, src[2], SWIZ(X, Y, Z, W),
1240 instr->coord_components, false));
1241 instr->src[src_number].src_type = nir_tex_src_ddy;
1242 src_number++;
1243 }
1244
1245 if (instr->is_shadow) {
1246 if (instr->coord_components < 3)
1247 instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], Z));
1248 else
1249 instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
1250
1251 instr->src[src_number].src_type = nir_tex_src_comparitor;
1252 src_number++;
1253 }
1254
1255 for (i = 0; i < tgsi_inst->Texture.NumOffsets; i++) {
1256 struct tgsi_texture_offset *tex_offset = &tgsi_inst->TexOffsets[i];
1257 /* since TexOffset ins't using tgsi_full_src_register we get to
1258 * do some extra gymnastics:
1259 */
1260 nir_alu_src src;
1261
1262 memset(&src, 0, sizeof(src));
1263
1264 src.src = ttn_src_for_file_and_index(c,
1265 tex_offset->File,
1266 tex_offset->Index,
1267 NULL, NULL, NULL);
1268
1269 src.swizzle[0] = tex_offset->SwizzleX;
1270 src.swizzle[1] = tex_offset->SwizzleY;
1271 src.swizzle[2] = tex_offset->SwizzleZ;
1272 src.swizzle[3] = TGSI_SWIZZLE_W;
1273
1274 instr->src[src_number].src_type = nir_tex_src_offset;
1275 instr->src[src_number].src = nir_src_for_ssa(
1276 nir_fmov_alu(b, src, nir_tex_instr_src_size(instr, src_number)));
1277 src_number++;
1278 }
1279
1280 assert(src_number == num_srcs);
1281
1282 nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
1283 nir_builder_instr_insert(b, &instr->instr);
1284
1285 /* Resolve the writemask on the texture op. */
1286 ttn_move_dest(b, dest, &instr->dest.ssa);
1287 }
1288
1289 /* TGSI_OPCODE_TXQ is actually two distinct operations:
1290 *
1291 * dst.x = texture\_width(unit, lod)
1292 * dst.y = texture\_height(unit, lod)
1293 * dst.z = texture\_depth(unit, lod)
1294 * dst.w = texture\_levels(unit)
1295 *
1296 * dst.xyz map to NIR txs opcode, and dst.w maps to query_levels
1297 */
1298 static void
1299 ttn_txq(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
1300 {
1301 nir_builder *b = &c->build;
1302 struct tgsi_full_instruction *tgsi_inst = &c->token->FullInstruction;
1303 nir_tex_instr *txs, *qlv;
1304
1305 txs = nir_tex_instr_create(b->shader, 1);
1306 txs->op = nir_texop_txs;
1307 setup_texture_info(txs, tgsi_inst->Texture.Texture);
1308
1309 qlv = nir_tex_instr_create(b->shader, 0);
1310 qlv->op = nir_texop_query_levels;
1311 setup_texture_info(qlv, tgsi_inst->Texture.Texture);
1312
1313 assert(tgsi_inst->Src[1].Register.File == TGSI_FILE_SAMPLER);
1314 txs->sampler_index = tgsi_inst->Src[1].Register.Index;
1315 qlv->sampler_index = tgsi_inst->Src[1].Register.Index;
1316
1317 /* only single src, the lod: */
1318 txs->src[0].src = nir_src_for_ssa(ttn_channel(b, src[0], X));
1319 txs->src[0].src_type = nir_tex_src_lod;
1320
1321 nir_ssa_dest_init(&txs->instr, &txs->dest, 3, NULL);
1322 nir_builder_instr_insert(b, &txs->instr);
1323
1324 nir_ssa_dest_init(&qlv->instr, &qlv->dest, 1, NULL);
1325 nir_builder_instr_insert(b, &qlv->instr);
1326
1327 ttn_move_dest_masked(b, dest, &txs->dest.ssa, TGSI_WRITEMASK_XYZ);
1328 ttn_move_dest_masked(b, dest, &qlv->dest.ssa, TGSI_WRITEMASK_W);
1329 }
1330
1331 static const nir_op op_trans[TGSI_OPCODE_LAST] = {
1332 [TGSI_OPCODE_ARL] = 0,
1333 [TGSI_OPCODE_MOV] = nir_op_fmov,
1334 [TGSI_OPCODE_LIT] = 0,
1335 [TGSI_OPCODE_RCP] = nir_op_frcp,
1336 [TGSI_OPCODE_RSQ] = nir_op_frsq,
1337 [TGSI_OPCODE_EXP] = 0,
1338 [TGSI_OPCODE_LOG] = 0,
1339 [TGSI_OPCODE_MUL] = nir_op_fmul,
1340 [TGSI_OPCODE_ADD] = nir_op_fadd,
1341 [TGSI_OPCODE_DP3] = 0,
1342 [TGSI_OPCODE_DP4] = 0,
1343 [TGSI_OPCODE_DST] = 0,
1344 [TGSI_OPCODE_MIN] = nir_op_fmin,
1345 [TGSI_OPCODE_MAX] = nir_op_fmax,
1346 [TGSI_OPCODE_SLT] = nir_op_slt,
1347 [TGSI_OPCODE_SGE] = nir_op_sge,
1348 [TGSI_OPCODE_MAD] = nir_op_ffma,
1349 [TGSI_OPCODE_SUB] = nir_op_fsub,
1350 [TGSI_OPCODE_LRP] = 0,
1351 [TGSI_OPCODE_SQRT] = nir_op_fsqrt,
1352 [TGSI_OPCODE_DP2A] = 0,
1353 [TGSI_OPCODE_FRC] = nir_op_ffract,
1354 [TGSI_OPCODE_CLAMP] = 0,
1355 [TGSI_OPCODE_FLR] = nir_op_ffloor,
1356 [TGSI_OPCODE_ROUND] = nir_op_fround_even,
1357 [TGSI_OPCODE_EX2] = nir_op_fexp2,
1358 [TGSI_OPCODE_LG2] = nir_op_flog2,
1359 [TGSI_OPCODE_POW] = nir_op_fpow,
1360 [TGSI_OPCODE_XPD] = 0,
1361 [TGSI_OPCODE_ABS] = nir_op_fabs,
1362 [TGSI_OPCODE_DPH] = 0,
1363 [TGSI_OPCODE_COS] = nir_op_fcos,
1364 [TGSI_OPCODE_DDX] = nir_op_fddx,
1365 [TGSI_OPCODE_DDY] = nir_op_fddy,
1366 [TGSI_OPCODE_KILL] = 0,
1367 [TGSI_OPCODE_PK2H] = 0, /* XXX */
1368 [TGSI_OPCODE_PK2US] = 0, /* XXX */
1369 [TGSI_OPCODE_PK4B] = 0, /* XXX */
1370 [TGSI_OPCODE_PK4UB] = 0, /* XXX */
1371 [TGSI_OPCODE_SEQ] = nir_op_seq,
1372 [TGSI_OPCODE_SGT] = 0,
1373 [TGSI_OPCODE_SIN] = nir_op_fsin,
1374 [TGSI_OPCODE_SNE] = nir_op_sne,
1375 [TGSI_OPCODE_SLE] = 0,
1376 [TGSI_OPCODE_TEX] = 0,
1377 [TGSI_OPCODE_TXD] = 0,
1378 [TGSI_OPCODE_TXP] = 0,
1379 [TGSI_OPCODE_UP2H] = 0, /* XXX */
1380 [TGSI_OPCODE_UP2US] = 0, /* XXX */
1381 [TGSI_OPCODE_UP4B] = 0, /* XXX */
1382 [TGSI_OPCODE_UP4UB] = 0, /* XXX */
1383 [TGSI_OPCODE_ARR] = 0,
1384
1385 /* No function calls, yet. */
1386 [TGSI_OPCODE_CAL] = 0, /* XXX */
1387 [TGSI_OPCODE_RET] = 0, /* XXX */
1388
1389 [TGSI_OPCODE_SSG] = nir_op_fsign,
1390 [TGSI_OPCODE_CMP] = 0,
1391 [TGSI_OPCODE_SCS] = 0,
1392 [TGSI_OPCODE_TXB] = 0,
1393 [TGSI_OPCODE_DIV] = nir_op_fdiv,
1394 [TGSI_OPCODE_DP2] = 0,
1395 [TGSI_OPCODE_DP2A] = 0,
1396 [TGSI_OPCODE_TXL] = 0,
1397
1398 [TGSI_OPCODE_BRK] = 0,
1399 [TGSI_OPCODE_IF] = 0,
1400 [TGSI_OPCODE_UIF] = 0,
1401 [TGSI_OPCODE_ELSE] = 0,
1402 [TGSI_OPCODE_ENDIF] = 0,
1403
1404 [TGSI_OPCODE_DDX_FINE] = nir_op_fddx_fine,
1405 [TGSI_OPCODE_DDY_FINE] = nir_op_fddy_fine,
1406
1407 [TGSI_OPCODE_PUSHA] = 0, /* XXX */
1408 [TGSI_OPCODE_POPA] = 0, /* XXX */
1409
1410 [TGSI_OPCODE_CEIL] = nir_op_fceil,
1411 [TGSI_OPCODE_I2F] = nir_op_i2f,
1412 [TGSI_OPCODE_NOT] = nir_op_inot,
1413 [TGSI_OPCODE_TRUNC] = nir_op_ftrunc,
1414 [TGSI_OPCODE_SHL] = nir_op_ishl,
1415 [TGSI_OPCODE_AND] = nir_op_iand,
1416 [TGSI_OPCODE_OR] = nir_op_ior,
1417 [TGSI_OPCODE_MOD] = nir_op_umod,
1418 [TGSI_OPCODE_XOR] = nir_op_ixor,
1419 [TGSI_OPCODE_SAD] = 0, /* XXX */
1420 [TGSI_OPCODE_TXF] = 0,
1421 [TGSI_OPCODE_TXQ] = 0,
1422
1423 [TGSI_OPCODE_CONT] = 0,
1424
1425 [TGSI_OPCODE_EMIT] = 0, /* XXX */
1426 [TGSI_OPCODE_ENDPRIM] = 0, /* XXX */
1427
1428 [TGSI_OPCODE_BGNLOOP] = 0,
1429 [TGSI_OPCODE_BGNSUB] = 0, /* XXX: no function calls */
1430 [TGSI_OPCODE_ENDLOOP] = 0,
1431 [TGSI_OPCODE_ENDSUB] = 0, /* XXX: no function calls */
1432
1433 [TGSI_OPCODE_TXQ_LZ] = 0,
1434 [TGSI_OPCODE_NOP] = 0,
1435 [TGSI_OPCODE_FSEQ] = nir_op_feq,
1436 [TGSI_OPCODE_FSGE] = nir_op_fge,
1437 [TGSI_OPCODE_FSLT] = nir_op_flt,
1438 [TGSI_OPCODE_FSNE] = nir_op_fne,
1439
1440 /* No control flow yet */
1441 [TGSI_OPCODE_CALLNZ] = 0, /* XXX */
1442 [TGSI_OPCODE_BREAKC] = 0, /* not emitted by glsl_to_tgsi.cpp */
1443
1444 [TGSI_OPCODE_KILL_IF] = 0,
1445
1446 [TGSI_OPCODE_END] = 0,
1447
1448 [TGSI_OPCODE_F2I] = nir_op_f2i,
1449 [TGSI_OPCODE_IDIV] = nir_op_idiv,
1450 [TGSI_OPCODE_IMAX] = nir_op_imax,
1451 [TGSI_OPCODE_IMIN] = nir_op_imin,
1452 [TGSI_OPCODE_INEG] = nir_op_ineg,
1453 [TGSI_OPCODE_ISGE] = nir_op_ige,
1454 [TGSI_OPCODE_ISHR] = nir_op_ishr,
1455 [TGSI_OPCODE_ISLT] = nir_op_ilt,
1456 [TGSI_OPCODE_F2U] = nir_op_f2u,
1457 [TGSI_OPCODE_U2F] = nir_op_u2f,
1458 [TGSI_OPCODE_UADD] = nir_op_iadd,
1459 [TGSI_OPCODE_UDIV] = nir_op_udiv,
1460 [TGSI_OPCODE_UMAD] = 0,
1461 [TGSI_OPCODE_UMAX] = nir_op_umax,
1462 [TGSI_OPCODE_UMIN] = nir_op_umin,
1463 [TGSI_OPCODE_UMOD] = nir_op_umod,
1464 [TGSI_OPCODE_UMUL] = nir_op_imul,
1465 [TGSI_OPCODE_USEQ] = nir_op_ieq,
1466 [TGSI_OPCODE_USGE] = nir_op_uge,
1467 [TGSI_OPCODE_USHR] = nir_op_ushr,
1468 [TGSI_OPCODE_USLT] = nir_op_ult,
1469 [TGSI_OPCODE_USNE] = nir_op_ine,
1470
1471 [TGSI_OPCODE_SWITCH] = 0, /* not emitted by glsl_to_tgsi.cpp */
1472 [TGSI_OPCODE_CASE] = 0, /* not emitted by glsl_to_tgsi.cpp */
1473 [TGSI_OPCODE_DEFAULT] = 0, /* not emitted by glsl_to_tgsi.cpp */
1474 [TGSI_OPCODE_ENDSWITCH] = 0, /* not emitted by glsl_to_tgsi.cpp */
1475
1476 /* XXX: SAMPLE opcodes */
1477
1478 [TGSI_OPCODE_UARL] = nir_op_imov,
1479 [TGSI_OPCODE_UCMP] = 0,
1480 [TGSI_OPCODE_IABS] = nir_op_iabs,
1481 [TGSI_OPCODE_ISSG] = nir_op_isign,
1482
1483 /* XXX: atomics */
1484
1485 [TGSI_OPCODE_TEX2] = 0,
1486 [TGSI_OPCODE_TXB2] = 0,
1487 [TGSI_OPCODE_TXL2] = 0,
1488
1489 [TGSI_OPCODE_IMUL_HI] = nir_op_imul_high,
1490 [TGSI_OPCODE_UMUL_HI] = nir_op_umul_high,
1491
1492 [TGSI_OPCODE_TG4] = 0,
1493 [TGSI_OPCODE_LODQ] = 0, /* XXX */
1494
1495 [TGSI_OPCODE_IBFE] = nir_op_ibitfield_extract,
1496 [TGSI_OPCODE_UBFE] = nir_op_ubitfield_extract,
1497 [TGSI_OPCODE_BFI] = nir_op_bitfield_insert,
1498 [TGSI_OPCODE_BREV] = nir_op_bitfield_reverse,
1499 [TGSI_OPCODE_POPC] = nir_op_bit_count,
1500 [TGSI_OPCODE_LSB] = nir_op_find_lsb,
1501 [TGSI_OPCODE_IMSB] = nir_op_ifind_msb,
1502 [TGSI_OPCODE_UMSB] = nir_op_ifind_msb, /* XXX: signed vs unsigned */
1503
1504 [TGSI_OPCODE_INTERP_CENTROID] = 0, /* XXX */
1505 [TGSI_OPCODE_INTERP_SAMPLE] = 0, /* XXX */
1506 [TGSI_OPCODE_INTERP_OFFSET] = 0, /* XXX */
1507 };
1508
1509 static void
1510 ttn_emit_instruction(struct ttn_compile *c)
1511 {
1512 nir_builder *b = &c->build;
1513 struct tgsi_full_instruction *tgsi_inst = &c->token->FullInstruction;
1514 unsigned i;
1515 unsigned tgsi_op = tgsi_inst->Instruction.Opcode;
1516 struct tgsi_full_dst_register *tgsi_dst = &tgsi_inst->Dst[0];
1517
1518 if (tgsi_op == TGSI_OPCODE_END)
1519 return;
1520
1521 nir_ssa_def *src[TGSI_FULL_MAX_SRC_REGISTERS];
1522 for (i = 0; i < tgsi_inst->Instruction.NumSrcRegs; i++) {
1523 src[i] = ttn_get_src(c, &tgsi_inst->Src[i]);
1524 }
1525 nir_alu_dest dest = ttn_get_dest(c, tgsi_dst);
1526
1527 switch (tgsi_op) {
1528 case TGSI_OPCODE_RSQ:
1529 ttn_move_dest(b, dest, nir_frsq(b, ttn_channel(b, src[0], X)));
1530 break;
1531
1532 case TGSI_OPCODE_SQRT:
1533 ttn_move_dest(b, dest, nir_fsqrt(b, ttn_channel(b, src[0], X)));
1534 break;
1535
1536 case TGSI_OPCODE_RCP:
1537 ttn_move_dest(b, dest, nir_frcp(b, ttn_channel(b, src[0], X)));
1538 break;
1539
1540 case TGSI_OPCODE_EX2:
1541 ttn_move_dest(b, dest, nir_fexp2(b, ttn_channel(b, src[0], X)));
1542 break;
1543
1544 case TGSI_OPCODE_LG2:
1545 ttn_move_dest(b, dest, nir_flog2(b, ttn_channel(b, src[0], X)));
1546 break;
1547
1548 case TGSI_OPCODE_POW:
1549 ttn_move_dest(b, dest, nir_fpow(b,
1550 ttn_channel(b, src[0], X),
1551 ttn_channel(b, src[1], X)));
1552 break;
1553
1554 case TGSI_OPCODE_COS:
1555 ttn_move_dest(b, dest, nir_fcos(b, ttn_channel(b, src[0], X)));
1556 break;
1557
1558 case TGSI_OPCODE_SIN:
1559 ttn_move_dest(b, dest, nir_fsin(b, ttn_channel(b, src[0], X)));
1560 break;
1561
1562 case TGSI_OPCODE_ARL:
1563 ttn_arl(b, op_trans[tgsi_op], dest, src);
1564 break;
1565
1566 case TGSI_OPCODE_EXP:
1567 ttn_exp(b, op_trans[tgsi_op], dest, src);
1568 break;
1569
1570 case TGSI_OPCODE_LOG:
1571 ttn_log(b, op_trans[tgsi_op], dest, src);
1572 break;
1573
1574 case TGSI_OPCODE_DST:
1575 ttn_dst(b, op_trans[tgsi_op], dest, src);
1576 break;
1577
1578 case TGSI_OPCODE_LIT:
1579 ttn_lit(b, op_trans[tgsi_op], dest, src);
1580 break;
1581
1582 case TGSI_OPCODE_CLAMP:
1583 ttn_clamp(b, op_trans[tgsi_op], dest, src);
1584 break;
1585
1586 case TGSI_OPCODE_XPD:
1587 ttn_xpd(b, op_trans[tgsi_op], dest, src);
1588 break;
1589
1590 case TGSI_OPCODE_DP2:
1591 ttn_dp2(b, op_trans[tgsi_op], dest, src);
1592 break;
1593
1594 case TGSI_OPCODE_DP3:
1595 ttn_dp3(b, op_trans[tgsi_op], dest, src);
1596 break;
1597
1598 case TGSI_OPCODE_DP4:
1599 ttn_dp4(b, op_trans[tgsi_op], dest, src);
1600 break;
1601
1602 case TGSI_OPCODE_DP2A:
1603 ttn_dp2a(b, op_trans[tgsi_op], dest, src);
1604 break;
1605
1606 case TGSI_OPCODE_DPH:
1607 ttn_dph(b, op_trans[tgsi_op], dest, src);
1608 break;
1609
1610 case TGSI_OPCODE_UMAD:
1611 ttn_umad(b, op_trans[tgsi_op], dest, src);
1612 break;
1613
1614 case TGSI_OPCODE_LRP:
1615 ttn_move_dest(b, dest, nir_flrp(b, src[2], src[1], src[0]));
1616 break;
1617
1618 case TGSI_OPCODE_KILL:
1619 ttn_kill(b, op_trans[tgsi_op], dest, src);
1620 break;
1621
1622 case TGSI_OPCODE_ARR:
1623 ttn_arr(b, op_trans[tgsi_op], dest, src);
1624 break;
1625
1626 case TGSI_OPCODE_CMP:
1627 ttn_cmp(b, op_trans[tgsi_op], dest, src);
1628 break;
1629
1630 case TGSI_OPCODE_UCMP:
1631 ttn_ucmp(b, op_trans[tgsi_op], dest, src);
1632 break;
1633
1634 case TGSI_OPCODE_SCS:
1635 ttn_scs(b, op_trans[tgsi_op], dest, src);
1636 break;
1637
1638 case TGSI_OPCODE_SGT:
1639 ttn_sgt(b, op_trans[tgsi_op], dest, src);
1640 break;
1641
1642 case TGSI_OPCODE_SLE:
1643 ttn_sle(b, op_trans[tgsi_op], dest, src);
1644 break;
1645
1646 case TGSI_OPCODE_KILL_IF:
1647 ttn_kill_if(b, op_trans[tgsi_op], dest, src);
1648 break;
1649
1650 case TGSI_OPCODE_TEX:
1651 case TGSI_OPCODE_TXP:
1652 case TGSI_OPCODE_TXL:
1653 case TGSI_OPCODE_TXB:
1654 case TGSI_OPCODE_TXD:
1655 case TGSI_OPCODE_TXL2:
1656 case TGSI_OPCODE_TXB2:
1657 case TGSI_OPCODE_TXQ_LZ:
1658 case TGSI_OPCODE_TXF:
1659 case TGSI_OPCODE_TG4:
1660 ttn_tex(c, dest, src);
1661 break;
1662
1663 case TGSI_OPCODE_TXQ:
1664 ttn_txq(c, dest, src);
1665 break;
1666
1667 case TGSI_OPCODE_NOP:
1668 break;
1669
1670 case TGSI_OPCODE_IF:
1671 ttn_if(c, src[0], false);
1672 break;
1673
1674 case TGSI_OPCODE_UIF:
1675 ttn_if(c, src[0], true);
1676 break;
1677
1678 case TGSI_OPCODE_ELSE:
1679 ttn_else(c);
1680 break;
1681
1682 case TGSI_OPCODE_ENDIF:
1683 ttn_endif(c);
1684 break;
1685
1686 case TGSI_OPCODE_BGNLOOP:
1687 ttn_bgnloop(c);
1688 break;
1689
1690 case TGSI_OPCODE_BRK:
1691 ttn_brk(b);
1692 break;
1693
1694 case TGSI_OPCODE_CONT:
1695 ttn_cont(b);
1696 break;
1697
1698 case TGSI_OPCODE_ENDLOOP:
1699 ttn_endloop(c);
1700 break;
1701
1702 default:
1703 if (op_trans[tgsi_op] != 0 || tgsi_op == TGSI_OPCODE_MOV) {
1704 ttn_alu(b, op_trans[tgsi_op], dest, src);
1705 } else {
1706 fprintf(stderr, "unknown TGSI opcode: %s\n",
1707 tgsi_get_opcode_name(tgsi_op));
1708 abort();
1709 }
1710 break;
1711 }
1712
1713 if (tgsi_inst->Instruction.Saturate) {
1714 assert(!dest.dest.is_ssa);
1715 ttn_move_dest(b, dest, nir_fsat(b, ttn_src_for_dest(b, &dest)));
1716 }
1717
1718 /* if the dst has a matching var, append store_global to move
1719 * output from reg to var
1720 */
1721 nir_variable *var = ttn_get_var(c, tgsi_dst);
1722 if (var) {
1723 unsigned index = tgsi_dst->Register.Index;
1724 unsigned offset = c->temp_regs[index].offset;
1725 nir_intrinsic_instr *store =
1726 nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
1727 struct tgsi_ind_register *indirect = tgsi_dst->Register.Indirect ?
1728 &tgsi_dst->Indirect : NULL;
1729
1730 store->num_components = 4;
1731 store->variables[0] = ttn_array_deref(c, store, var, offset, indirect);
1732 store->src[0] = nir_src_for_reg(dest.dest.reg.reg);
1733
1734 nir_builder_instr_insert(b, &store->instr);
1735 }
1736 }
1737
1738 /**
1739 * Puts a NIR intrinsic to store of each TGSI_FILE_OUTPUT value to the output
1740 * variables at the end of the shader.
1741 *
1742 * We don't generate these incrementally as the TGSI_FILE_OUTPUT values are
1743 * written, because there's no output load intrinsic, which means we couldn't
1744 * handle writemasks.
1745 */
1746 static void
1747 ttn_add_output_stores(struct ttn_compile *c)
1748 {
1749 nir_builder *b = &c->build;
1750
1751 foreach_list_typed(nir_variable, var, node, &b->shader->outputs) {
1752 unsigned array_len = MAX2(glsl_get_length(var->type), 1);
1753 unsigned i;
1754
1755 for (i = 0; i < array_len; i++) {
1756 nir_intrinsic_instr *store =
1757 nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_output);
1758 unsigned loc = var->data.driver_location + i;
1759 store->num_components = 4;
1760 store->const_index[0] = loc;
1761 store->src[0].reg.reg = c->output_regs[loc].reg;
1762 store->src[0].reg.base_offset = c->output_regs[loc].offset;
1763 nir_builder_instr_insert(b, &store->instr);
1764 }
1765 }
1766 }
1767
1768 static gl_shader_stage
1769 tgsi_processor_to_shader_stage(unsigned processor)
1770 {
1771 switch (processor) {
1772 case TGSI_PROCESSOR_FRAGMENT: return MESA_SHADER_FRAGMENT;
1773 case TGSI_PROCESSOR_VERTEX: return MESA_SHADER_VERTEX;
1774 case TGSI_PROCESSOR_GEOMETRY: return MESA_SHADER_GEOMETRY;
1775 case TGSI_PROCESSOR_TESS_CTRL: return MESA_SHADER_TESS_CTRL;
1776 case TGSI_PROCESSOR_TESS_EVAL: return MESA_SHADER_TESS_EVAL;
1777 case TGSI_PROCESSOR_COMPUTE: return MESA_SHADER_COMPUTE;
1778 default:
1779 unreachable("invalid TGSI processor");
1780 };
1781 }
1782
1783 struct nir_shader *
1784 tgsi_to_nir(const void *tgsi_tokens,
1785 const nir_shader_compiler_options *options)
1786 {
1787 struct tgsi_parse_context parser;
1788 struct tgsi_shader_info scan;
1789 struct ttn_compile *c;
1790 struct nir_shader *s;
1791 int ret;
1792
1793 c = rzalloc(NULL, struct ttn_compile);
1794
1795 tgsi_scan_shader(tgsi_tokens, &scan);
1796 c->scan = &scan;
1797
1798 s = nir_shader_create(NULL, tgsi_processor_to_shader_stage(scan.processor),
1799 options);
1800
1801 nir_function *func = nir_function_create(s, "main");
1802 nir_function_overload *overload = nir_function_overload_create(func);
1803 nir_function_impl *impl = nir_function_impl_create(overload);
1804
1805 nir_builder_init(&c->build, impl);
1806 c->build.cursor = nir_after_cf_list(&impl->body);
1807
1808 s->num_inputs = scan.file_max[TGSI_FILE_INPUT] + 1;
1809 s->num_uniforms = scan.const_file_max[0] + 1;
1810 s->num_outputs = scan.file_max[TGSI_FILE_OUTPUT] + 1;
1811
1812 c->output_regs = rzalloc_array(c, struct ttn_reg_info,
1813 scan.file_max[TGSI_FILE_OUTPUT] + 1);
1814 c->temp_regs = rzalloc_array(c, struct ttn_reg_info,
1815 scan.file_max[TGSI_FILE_TEMPORARY] + 1);
1816 c->imm_defs = rzalloc_array(c, nir_ssa_def *,
1817 scan.file_max[TGSI_FILE_IMMEDIATE] + 1);
1818
1819 c->num_samp_types = scan.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
1820 c->samp_types = rzalloc_array(c, nir_alu_type, c->num_samp_types);
1821
1822 c->if_stack = rzalloc_array(c, nir_cursor,
1823 (scan.opcode_count[TGSI_OPCODE_IF] +
1824 scan.opcode_count[TGSI_OPCODE_UIF]) * 2);
1825 c->loop_stack = rzalloc_array(c, nir_cursor,
1826 scan.opcode_count[TGSI_OPCODE_BGNLOOP]);
1827
1828 ret = tgsi_parse_init(&parser, tgsi_tokens);
1829 assert(ret == TGSI_PARSE_OK);
1830
1831 while (!tgsi_parse_end_of_tokens(&parser)) {
1832 tgsi_parse_token(&parser);
1833 c->token = &parser.FullToken;
1834
1835 switch (parser.FullToken.Token.Type) {
1836 case TGSI_TOKEN_TYPE_DECLARATION:
1837 ttn_emit_declaration(c);
1838 break;
1839
1840 case TGSI_TOKEN_TYPE_INSTRUCTION:
1841 ttn_emit_instruction(c);
1842 break;
1843
1844 case TGSI_TOKEN_TYPE_IMMEDIATE:
1845 ttn_emit_immediate(c);
1846 break;
1847 }
1848 }
1849
1850 tgsi_parse_free(&parser);
1851
1852 ttn_add_output_stores(c);
1853
1854 ralloc_free(c);
1855 return s;
1856 }