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