OSDN Git Service

ptn: Emit mul+add for MAD
[android-x86/external-mesa.git] / src / mesa / program / prog_to_nir.c
1 /*
2  * Copyright © 2015 Intel Corporation
3  * Copyright © 2014-2015 Broadcom
4  * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23  * IN THE SOFTWARE.
24  */
25
26 #include "compiler/nir/nir.h"
27 #include "compiler/nir/nir_builder.h"
28 #include "compiler/glsl/list.h"
29 #include "main/imports.h"
30 #include "util/ralloc.h"
31
32 #include "prog_to_nir.h"
33 #include "prog_instruction.h"
34 #include "prog_parameter.h"
35 #include "prog_print.h"
36 #include "program.h"
37
38 /**
39  * \file prog_to_nir.c
40  *
41  * A translator from Mesa IR (prog_instruction.h) to NIR.  This is primarily
42  * intended to support ARB_vertex_program, ARB_fragment_program, and fixed-function
43  * vertex processing.  Full GLSL support should use glsl_to_nir instead.
44  */
45
46 struct ptn_compile {
47    const struct gl_program *prog;
48    nir_builder build;
49    bool error;
50
51    nir_variable *parameters;
52    nir_variable *input_vars[VARYING_SLOT_MAX];
53    nir_variable *output_vars[VARYING_SLOT_MAX];
54    nir_register **output_regs;
55    nir_register **temp_regs;
56
57    nir_register *addr_reg;
58 };
59
60 #define SWIZ(X, Y, Z, W) \
61    (unsigned[4]){ SWIZZLE_##X, SWIZZLE_##Y, SWIZZLE_##Z, SWIZZLE_##W }
62 #define ptn_channel(b, src, ch) nir_swizzle(b, src, SWIZ(ch, ch, ch, ch), 1, true)
63
64 static nir_ssa_def *
65 ptn_src_for_dest(struct ptn_compile *c, nir_alu_dest *dest)
66 {
67    nir_builder *b = &c->build;
68
69    nir_alu_src src;
70    memset(&src, 0, sizeof(src));
71
72    if (dest->dest.is_ssa)
73       src.src = nir_src_for_ssa(&dest->dest.ssa);
74    else {
75       assert(!dest->dest.reg.indirect);
76       src.src = nir_src_for_reg(dest->dest.reg.reg);
77       src.src.reg.base_offset = dest->dest.reg.base_offset;
78    }
79
80    for (int i = 0; i < 4; i++)
81       src.swizzle[i] = i;
82
83    return nir_fmov_alu(b, src, 4);
84 }
85
86 static nir_alu_dest
87 ptn_get_dest(struct ptn_compile *c, const struct prog_dst_register *prog_dst)
88 {
89    nir_alu_dest dest;
90
91    memset(&dest, 0, sizeof(dest));
92
93    switch (prog_dst->File) {
94    case PROGRAM_TEMPORARY:
95       dest.dest.reg.reg = c->temp_regs[prog_dst->Index];
96       break;
97    case PROGRAM_OUTPUT:
98       dest.dest.reg.reg = c->output_regs[prog_dst->Index];
99       break;
100    case PROGRAM_ADDRESS:
101       assert(prog_dst->Index == 0);
102       dest.dest.reg.reg = c->addr_reg;
103       break;
104    case PROGRAM_UNDEFINED:
105       break;
106    }
107
108    dest.write_mask = prog_dst->WriteMask;
109    dest.saturate = false;
110
111    assert(!prog_dst->RelAddr);
112
113    return dest;
114 }
115
116 static nir_ssa_def *
117 ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
118 {
119    nir_builder *b = &c->build;
120    nir_alu_src src;
121
122    memset(&src, 0, sizeof(src));
123
124    switch (prog_src->File) {
125    case PROGRAM_UNDEFINED:
126       return nir_imm_float(b, 0.0);
127    case PROGRAM_TEMPORARY:
128       assert(!prog_src->RelAddr && prog_src->Index >= 0);
129       src.src.reg.reg = c->temp_regs[prog_src->Index];
130       break;
131    case PROGRAM_INPUT: {
132       /* ARB_vertex_program doesn't allow relative addressing on vertex
133        * attributes; ARB_fragment_program has no relative addressing at all.
134        */
135       assert(!prog_src->RelAddr);
136
137       assert(prog_src->Index >= 0 && prog_src->Index < VARYING_SLOT_MAX);
138
139       nir_intrinsic_instr *load =
140          nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
141       load->num_components = 4;
142       load->variables[0] = nir_deref_var_create(load, c->input_vars[prog_src->Index]);
143
144       nir_ssa_dest_init(&load->instr, &load->dest, 4, 32, NULL);
145       nir_builder_instr_insert(b, &load->instr);
146
147       src.src = nir_src_for_ssa(&load->dest.ssa);
148       break;
149    }
150    case PROGRAM_STATE_VAR:
151    case PROGRAM_CONSTANT: {
152       /* We actually want to look at the type in the Parameters list for this,
153        * because it lets us upload constant builtin uniforms as actual
154        * constants.
155        */
156       struct gl_program_parameter_list *plist = c->prog->Parameters;
157       gl_register_file file = prog_src->RelAddr ? prog_src->File :
158          plist->Parameters[prog_src->Index].Type;
159
160       switch (file) {
161       case PROGRAM_CONSTANT:
162          if ((c->prog->IndirectRegisterFiles & (1 << PROGRAM_CONSTANT)) == 0) {
163             float *v = (float *) plist->ParameterValues[prog_src->Index];
164             src.src = nir_src_for_ssa(nir_imm_vec4(b, v[0], v[1], v[2], v[3]));
165             break;
166          }
167          /* FALLTHROUGH */
168       case PROGRAM_STATE_VAR: {
169          assert(c->parameters != NULL);
170
171          nir_intrinsic_instr *load =
172             nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
173          nir_ssa_dest_init(&load->instr, &load->dest, 4, 32, NULL);
174          load->num_components = 4;
175
176          load->variables[0] = nir_deref_var_create(load, c->parameters);
177          nir_deref_array *deref_arr =
178             nir_deref_array_create(load->variables[0]);
179          deref_arr->deref.type = glsl_vec4_type();
180          load->variables[0]->deref.child = &deref_arr->deref;
181
182          if (prog_src->RelAddr) {
183             deref_arr->deref_array_type = nir_deref_array_type_indirect;
184
185             nir_alu_src addr_src = { NIR_SRC_INIT };
186             addr_src.src = nir_src_for_reg(c->addr_reg);
187             nir_ssa_def *reladdr = nir_imov_alu(b, addr_src, 1);
188
189             if (prog_src->Index < 0) {
190                /* This is a negative offset which should be added to the address
191                 * register's value.
192                 */
193                reladdr = nir_iadd(b, reladdr, nir_imm_int(b, prog_src->Index));
194
195                deref_arr->base_offset = 0;
196             } else {
197                deref_arr->base_offset = prog_src->Index;
198             }
199             deref_arr->indirect = nir_src_for_ssa(reladdr);
200          } else {
201             deref_arr->deref_array_type = nir_deref_array_type_direct;
202             deref_arr->base_offset = prog_src->Index;
203          }
204
205          nir_builder_instr_insert(b, &load->instr);
206
207          src.src = nir_src_for_ssa(&load->dest.ssa);
208          break;
209       }
210       default:
211          fprintf(stderr, "bad uniform src register file: %s (%d)\n",
212                  _mesa_register_file_name(file), file);
213          abort();
214       }
215       break;
216    }
217    default:
218       fprintf(stderr, "unknown src register file: %s (%d)\n",
219               _mesa_register_file_name(prog_src->File), prog_src->File);
220       abort();
221    }
222
223    nir_ssa_def *def;
224    if (!HAS_EXTENDED_SWIZZLE(prog_src->Swizzle) &&
225        (prog_src->Negate == NEGATE_NONE || prog_src->Negate == NEGATE_XYZW)) {
226       /* The simple non-SWZ case. */
227       for (int i = 0; i < 4; i++)
228          src.swizzle[i] = GET_SWZ(prog_src->Swizzle, i);
229
230       def = nir_fmov_alu(b, src, 4);
231
232       if (prog_src->Negate)
233          def = nir_fneg(b, def);
234    } else {
235       /* The SWZ instruction allows per-component zero/one swizzles, and also
236        * per-component negation.
237        */
238       nir_ssa_def *chans[4];
239       for (int i = 0; i < 4; i++) {
240          int swizzle = GET_SWZ(prog_src->Swizzle, i);
241          if (swizzle == SWIZZLE_ZERO) {
242             chans[i] = nir_imm_float(b, 0.0);
243          } else if (swizzle == SWIZZLE_ONE) {
244             chans[i] = nir_imm_float(b, 1.0);
245          } else {
246             assert(swizzle != SWIZZLE_NIL);
247             nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_fmov);
248             nir_ssa_dest_init(&mov->instr, &mov->dest.dest, 1, 32, NULL);
249             mov->dest.write_mask = 0x1;
250             mov->src[0] = src;
251             mov->src[0].swizzle[0] = swizzle;
252             nir_builder_instr_insert(b, &mov->instr);
253
254             chans[i] = &mov->dest.dest.ssa;
255          }
256
257          if (prog_src->Negate & (1 << i))
258             chans[i] = nir_fneg(b, chans[i]);
259       }
260       def = nir_vec4(b, chans[0], chans[1], chans[2], chans[3]);
261    }
262
263    return def;
264 }
265
266 static void
267 ptn_alu(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
268 {
269    unsigned num_srcs = nir_op_infos[op].num_inputs;
270    nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
271    unsigned i;
272
273    for (i = 0; i < num_srcs; i++)
274       instr->src[i].src = nir_src_for_ssa(src[i]);
275
276    instr->dest = dest;
277    nir_builder_instr_insert(b, &instr->instr);
278 }
279
280 static void
281 ptn_move_dest_masked(nir_builder *b, nir_alu_dest dest,
282                      nir_ssa_def *def, unsigned write_mask)
283 {
284    if (!(dest.write_mask & write_mask))
285       return;
286
287    nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_fmov);
288    if (!mov)
289       return;
290
291    mov->dest = dest;
292    mov->dest.write_mask &= write_mask;
293    mov->src[0].src = nir_src_for_ssa(def);
294    for (unsigned i = def->num_components; i < 4; i++)
295       mov->src[0].swizzle[i] = def->num_components - 1;
296    nir_builder_instr_insert(b, &mov->instr);
297 }
298
299 static void
300 ptn_move_dest(nir_builder *b, nir_alu_dest dest, nir_ssa_def *def)
301 {
302    ptn_move_dest_masked(b, dest, def, WRITEMASK_XYZW);
303 }
304
305 static void
306 ptn_arl(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
307 {
308    ptn_move_dest(b, dest, nir_f2i(b, nir_ffloor(b, src[0])));
309 }
310
311 /* EXP - Approximate Exponential Base 2
312  *  dst.x = 2^{\lfloor src.x\rfloor}
313  *  dst.y = src.x - \lfloor src.x\rfloor
314  *  dst.z = 2^{src.x}
315  *  dst.w = 1.0
316  */
317 static void
318 ptn_exp(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
319 {
320    nir_ssa_def *srcx = ptn_channel(b, src[0], X);
321
322    ptn_move_dest_masked(b, dest, nir_fexp2(b, nir_ffloor(b, srcx)), WRITEMASK_X);
323    ptn_move_dest_masked(b, dest, nir_fsub(b, srcx, nir_ffloor(b, srcx)), WRITEMASK_Y);
324    ptn_move_dest_masked(b, dest, nir_fexp2(b, srcx), WRITEMASK_Z);
325    ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
326 }
327
328 /* LOG - Approximate Logarithm Base 2
329  *  dst.x = \lfloor\log_2{|src.x|}\rfloor
330  *  dst.y = |src.x| * 2^{-\lfloor\log_2{|src.x|}\rfloor}}
331  *  dst.z = \log_2{|src.x|}
332  *  dst.w = 1.0
333  */
334 static void
335 ptn_log(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
336 {
337    nir_ssa_def *abs_srcx = nir_fabs(b, ptn_channel(b, src[0], X));
338    nir_ssa_def *log2 = nir_flog2(b, abs_srcx);
339    nir_ssa_def *floor_log2 = nir_ffloor(b, log2);
340
341    ptn_move_dest_masked(b, dest, floor_log2, WRITEMASK_X);
342    ptn_move_dest_masked(b, dest,
343                         nir_fmul(b, abs_srcx,
344                                  nir_fexp2(b, nir_fneg(b, floor_log2))),
345                         WRITEMASK_Y);
346    ptn_move_dest_masked(b, dest, log2, WRITEMASK_Z);
347    ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
348 }
349
350 /* DST - Distance Vector
351  *   dst.x = 1.0
352  *   dst.y = src0.y \times src1.y
353  *   dst.z = src0.z
354  *   dst.w = src1.w
355  */
356 static void
357 ptn_dst(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
358 {
359    ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_X);
360    ptn_move_dest_masked(b, dest, nir_fmul(b, src[0], src[1]), WRITEMASK_Y);
361    ptn_move_dest_masked(b, dest, nir_fmov(b, src[0]), WRITEMASK_Z);
362    ptn_move_dest_masked(b, dest, nir_fmov(b, src[1]), WRITEMASK_W);
363 }
364
365 /* LIT - Light Coefficients
366  *  dst.x = 1.0
367  *  dst.y = max(src.x, 0.0)
368  *  dst.z = (src.x > 0.0) ? max(src.y, 0.0)^{clamp(src.w, -128.0, 128.0))} : 0
369  *  dst.w = 1.0
370  */
371 static void
372 ptn_lit(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
373 {
374    ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_XW);
375
376    ptn_move_dest_masked(b, dest, nir_fmax(b, ptn_channel(b, src[0], X),
377                                           nir_imm_float(b, 0.0)), WRITEMASK_Y);
378
379    if (dest.write_mask & WRITEMASK_Z) {
380       nir_ssa_def *src0_y = ptn_channel(b, src[0], Y);
381       nir_ssa_def *wclamp = nir_fmax(b, nir_fmin(b, ptn_channel(b, src[0], W),
382                                                  nir_imm_float(b, 128.0)),
383                                      nir_imm_float(b, -128.0));
384       nir_ssa_def *pow = nir_fpow(b, nir_fmax(b, src0_y, nir_imm_float(b, 0.0)),
385                                   wclamp);
386
387       nir_ssa_def *z;
388       if (b->shader->options->native_integers) {
389          z = nir_bcsel(b,
390                        nir_fge(b, nir_imm_float(b, 0.0), ptn_channel(b, src[0], X)),
391                        nir_imm_float(b, 0.0),
392                        pow);
393       } else {
394          z = nir_fcsel(b,
395                        nir_sge(b, nir_imm_float(b, 0.0), ptn_channel(b, src[0], X)),
396                        nir_imm_float(b, 0.0),
397                        pow);
398       }
399
400       ptn_move_dest_masked(b, dest, z, WRITEMASK_Z);
401    }
402 }
403
404 /* SCS - Sine Cosine
405  *   dst.x = \cos{src.x}
406  *   dst.y = \sin{src.x}
407  *   dst.z = 0.0
408  *   dst.w = 1.0
409  */
410 static void
411 ptn_scs(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
412 {
413    ptn_move_dest_masked(b, dest, nir_fcos(b, ptn_channel(b, src[0], X)),
414                         WRITEMASK_X);
415    ptn_move_dest_masked(b, dest, nir_fsin(b, ptn_channel(b, src[0], X)),
416                         WRITEMASK_Y);
417    ptn_move_dest_masked(b, dest, nir_imm_float(b, 0.0), WRITEMASK_Z);
418    ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
419 }
420
421 /**
422  * Emit SLT.  For platforms with integers, prefer b2f(flt(...)).
423  */
424 static void
425 ptn_slt(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
426 {
427    if (b->shader->options->native_integers) {
428       ptn_move_dest(b, dest, nir_b2f(b, nir_flt(b, src[0], src[1])));
429    } else {
430       ptn_move_dest(b, dest, nir_slt(b, src[0], src[1]));
431    }
432 }
433
434 /**
435  * Emit SGE.  For platforms with integers, prefer b2f(fge(...)).
436  */
437 static void
438 ptn_sge(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
439 {
440    if (b->shader->options->native_integers) {
441       ptn_move_dest(b, dest, nir_b2f(b, nir_fge(b, src[0], src[1])));
442    } else {
443       ptn_move_dest(b, dest, nir_sge(b, src[0], src[1]));
444    }
445 }
446
447 static void
448 ptn_xpd(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
449 {
450    ptn_move_dest_masked(b, dest,
451                         nir_fsub(b,
452                                  nir_fmul(b,
453                                           nir_swizzle(b, src[0], SWIZ(Y, Z, X, W), 3, true),
454                                           nir_swizzle(b, src[1], SWIZ(Z, X, Y, W), 3, true)),
455                                  nir_fmul(b,
456                                           nir_swizzle(b, src[1], SWIZ(Y, Z, X, W), 3, true),
457                                           nir_swizzle(b, src[0], SWIZ(Z, X, Y, W), 3, true))),
458                         WRITEMASK_XYZ);
459    ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
460 }
461
462 static void
463 ptn_dp2(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
464 {
465    ptn_move_dest(b, dest, nir_fdot2(b, src[0], src[1]));
466 }
467
468 static void
469 ptn_dp3(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
470 {
471    ptn_move_dest(b, dest, nir_fdot3(b, src[0], src[1]));
472 }
473
474 static void
475 ptn_dp4(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
476 {
477    ptn_move_dest(b, dest, nir_fdot4(b, src[0], src[1]));
478 }
479
480 static void
481 ptn_dph(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
482 {
483    ptn_move_dest(b, dest, nir_fdph(b, src[0], src[1]));
484 }
485
486 static void
487 ptn_cmp(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
488 {
489    if (b->shader->options->native_integers) {
490       ptn_move_dest(b, dest, nir_bcsel(b,
491                                        nir_flt(b, src[0], nir_imm_float(b, 0.0)),
492                                        src[1], src[2]));
493    } else {
494       ptn_move_dest(b, dest, nir_fcsel(b,
495                                        nir_slt(b, src[0], nir_imm_float(b, 0.0)),
496                                        src[1], src[2]));
497    }
498 }
499
500 static void
501 ptn_lrp(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
502 {
503    ptn_move_dest(b, dest, nir_flrp(b, src[2], src[1], src[0]));
504 }
505
506 static void
507 ptn_kil(nir_builder *b, nir_ssa_def **src)
508 {
509    nir_ssa_def *cmp = b->shader->options->native_integers ?
510       nir_bany_inequal4(b, nir_flt(b, src[0], nir_imm_float(b, 0.0)), nir_imm_int(b, 0)) :
511       nir_fany_nequal4(b, nir_slt(b, src[0], nir_imm_float(b, 0.0)), nir_imm_float(b, 0.0));
512
513    nir_intrinsic_instr *discard =
514       nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
515    discard->src[0] = nir_src_for_ssa(cmp);
516    nir_builder_instr_insert(b, &discard->instr);
517 }
518
519 static void
520 ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
521         struct prog_instruction *prog_inst)
522 {
523    nir_tex_instr *instr;
524    nir_texop op;
525    unsigned num_srcs;
526
527    switch (prog_inst->Opcode) {
528    case OPCODE_TEX:
529       op = nir_texop_tex;
530       num_srcs = 1;
531       break;
532    case OPCODE_TXB:
533       op = nir_texop_txb;
534       num_srcs = 2;
535       break;
536    case OPCODE_TXD:
537       op = nir_texop_txd;
538       num_srcs = 3;
539       break;
540    case OPCODE_TXL:
541       op = nir_texop_txl;
542       num_srcs = 2;
543       break;
544    case OPCODE_TXP:
545       op = nir_texop_tex;
546       num_srcs = 2;
547       break;
548    default:
549       fprintf(stderr, "unknown tex op %d\n", prog_inst->Opcode);
550       abort();
551    }
552
553    if (prog_inst->TexShadow)
554       num_srcs++;
555
556    instr = nir_tex_instr_create(b->shader, num_srcs);
557    instr->op = op;
558    instr->dest_type = nir_type_float;
559    instr->is_shadow = prog_inst->TexShadow;
560    instr->texture_index = prog_inst->TexSrcUnit;
561    instr->sampler_index = prog_inst->TexSrcUnit;
562
563    switch (prog_inst->TexSrcTarget) {
564    case TEXTURE_1D_INDEX:
565       instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
566       break;
567    case TEXTURE_2D_INDEX:
568       instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
569       break;
570    case TEXTURE_3D_INDEX:
571       instr->sampler_dim = GLSL_SAMPLER_DIM_3D;
572       break;
573    case TEXTURE_CUBE_INDEX:
574       instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
575       break;
576    case TEXTURE_RECT_INDEX:
577       instr->sampler_dim = GLSL_SAMPLER_DIM_RECT;
578       break;
579    default:
580       fprintf(stderr, "Unknown texture target %d\n", prog_inst->TexSrcTarget);
581       abort();
582    }
583
584    switch (instr->sampler_dim) {
585    case GLSL_SAMPLER_DIM_1D:
586    case GLSL_SAMPLER_DIM_BUF:
587       instr->coord_components = 1;
588       break;
589    case GLSL_SAMPLER_DIM_2D:
590    case GLSL_SAMPLER_DIM_RECT:
591    case GLSL_SAMPLER_DIM_EXTERNAL:
592    case GLSL_SAMPLER_DIM_MS:
593       instr->coord_components = 2;
594       break;
595    case GLSL_SAMPLER_DIM_3D:
596    case GLSL_SAMPLER_DIM_CUBE:
597       instr->coord_components = 3;
598       break;
599    }
600
601    unsigned src_number = 0;
602
603    instr->src[src_number].src =
604       nir_src_for_ssa(nir_swizzle(b, src[0], SWIZ(X, Y, Z, W),
605                                   instr->coord_components, true));
606    instr->src[src_number].src_type = nir_tex_src_coord;
607    src_number++;
608
609    if (prog_inst->Opcode == OPCODE_TXP) {
610       instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
611       instr->src[src_number].src_type = nir_tex_src_projector;
612       src_number++;
613    }
614
615    if (prog_inst->Opcode == OPCODE_TXB) {
616       instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
617       instr->src[src_number].src_type = nir_tex_src_bias;
618       src_number++;
619    }
620
621    if (prog_inst->Opcode == OPCODE_TXL) {
622       instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
623       instr->src[src_number].src_type = nir_tex_src_lod;
624       src_number++;
625    }
626
627    if (instr->is_shadow) {
628       if (instr->coord_components < 3)
629          instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], Z));
630       else
631          instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
632
633       instr->src[src_number].src_type = nir_tex_src_comparitor;
634       src_number++;
635    }
636
637    assert(src_number == num_srcs);
638
639    nir_ssa_dest_init(&instr->instr, &instr->dest, 4, 32, NULL);
640    nir_builder_instr_insert(b, &instr->instr);
641
642    /* Resolve the writemask on the texture op. */
643    ptn_move_dest(b, dest, &instr->dest.ssa);
644 }
645
646 static const nir_op op_trans[MAX_OPCODE] = {
647    [OPCODE_NOP] = 0,
648    [OPCODE_ABS] = nir_op_fabs,
649    [OPCODE_ADD] = nir_op_fadd,
650    [OPCODE_ARL] = 0,
651    [OPCODE_CMP] = 0,
652    [OPCODE_COS] = 0,
653    [OPCODE_DDX] = nir_op_fddx,
654    [OPCODE_DDY] = nir_op_fddy,
655    [OPCODE_DP2] = 0,
656    [OPCODE_DP3] = 0,
657    [OPCODE_DP4] = 0,
658    [OPCODE_DPH] = 0,
659    [OPCODE_DST] = 0,
660    [OPCODE_END] = 0,
661    [OPCODE_EX2] = 0,
662    [OPCODE_EXP] = 0,
663    [OPCODE_FLR] = nir_op_ffloor,
664    [OPCODE_FRC] = nir_op_ffract,
665    [OPCODE_LG2] = 0,
666    [OPCODE_LIT] = 0,
667    [OPCODE_LOG] = 0,
668    [OPCODE_LRP] = 0,
669    [OPCODE_MAD] = 0,
670    [OPCODE_MAX] = nir_op_fmax,
671    [OPCODE_MIN] = nir_op_fmin,
672    [OPCODE_MOV] = nir_op_fmov,
673    [OPCODE_MUL] = nir_op_fmul,
674    [OPCODE_POW] = 0,
675    [OPCODE_RCP] = 0,
676
677    [OPCODE_RSQ] = 0,
678    [OPCODE_SCS] = 0,
679    [OPCODE_SGE] = 0,
680    [OPCODE_SIN] = 0,
681    [OPCODE_SLT] = 0,
682    [OPCODE_SSG] = nir_op_fsign,
683    [OPCODE_SUB] = nir_op_fsub,
684    [OPCODE_SWZ] = 0,
685    [OPCODE_TEX] = 0,
686    [OPCODE_TRUNC] = nir_op_ftrunc,
687    [OPCODE_TXB] = 0,
688    [OPCODE_TXD] = 0,
689    [OPCODE_TXL] = 0,
690    [OPCODE_TXP] = 0,
691    [OPCODE_XPD] = 0,
692 };
693
694 static void
695 ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst)
696 {
697    nir_builder *b = &c->build;
698    unsigned i;
699    const unsigned op = prog_inst->Opcode;
700
701    if (op == OPCODE_END)
702       return;
703
704    nir_ssa_def *src[3];
705    for (i = 0; i < 3; i++) {
706       src[i] = ptn_get_src(c, &prog_inst->SrcReg[i]);
707    }
708    nir_alu_dest dest = ptn_get_dest(c, &prog_inst->DstReg);
709    if (c->error)
710       return;
711
712    switch (op) {
713    case OPCODE_RSQ:
714       ptn_move_dest(b, dest,
715                     nir_frsq(b, nir_fabs(b, ptn_channel(b, src[0], X))));
716       break;
717
718    case OPCODE_RCP:
719       ptn_move_dest(b, dest, nir_frcp(b, ptn_channel(b, src[0], X)));
720       break;
721
722    case OPCODE_EX2:
723       ptn_move_dest(b, dest, nir_fexp2(b, ptn_channel(b, src[0], X)));
724       break;
725
726    case OPCODE_LG2:
727       ptn_move_dest(b, dest, nir_flog2(b, ptn_channel(b, src[0], X)));
728       break;
729
730    case OPCODE_POW:
731       ptn_move_dest(b, dest, nir_fpow(b,
732                                       ptn_channel(b, src[0], X),
733                                       ptn_channel(b, src[1], X)));
734       break;
735
736    case OPCODE_COS:
737       ptn_move_dest(b, dest, nir_fcos(b, ptn_channel(b, src[0], X)));
738       break;
739
740    case OPCODE_SIN:
741       ptn_move_dest(b, dest, nir_fsin(b, ptn_channel(b, src[0], X)));
742       break;
743
744    case OPCODE_ARL:
745       ptn_arl(b, dest, src);
746       break;
747
748    case OPCODE_EXP:
749       ptn_exp(b, dest, src);
750       break;
751
752    case OPCODE_LOG:
753       ptn_log(b, dest, src);
754       break;
755
756    case OPCODE_LRP:
757       ptn_lrp(b, dest, src);
758       break;
759
760    case OPCODE_MAD:
761       ptn_move_dest(b, dest, nir_fadd(b, nir_fmul(b, src[0], src[1]), src[2]));
762       break;
763
764    case OPCODE_DST:
765       ptn_dst(b, dest, src);
766       break;
767
768    case OPCODE_LIT:
769       ptn_lit(b, dest, src);
770       break;
771
772    case OPCODE_XPD:
773       ptn_xpd(b, dest, src);
774       break;
775
776    case OPCODE_DP2:
777       ptn_dp2(b, dest, src);
778       break;
779
780    case OPCODE_DP3:
781       ptn_dp3(b, dest, src);
782       break;
783
784    case OPCODE_DP4:
785       ptn_dp4(b, dest, src);
786       break;
787
788    case OPCODE_DPH:
789       ptn_dph(b, dest, src);
790       break;
791
792    case OPCODE_KIL:
793       ptn_kil(b, src);
794       break;
795
796    case OPCODE_CMP:
797       ptn_cmp(b, dest, src);
798       break;
799
800    case OPCODE_SCS:
801       ptn_scs(b, dest, src);
802       break;
803
804    case OPCODE_SLT:
805       ptn_slt(b, dest, src);
806       break;
807
808    case OPCODE_SGE:
809       ptn_sge(b, dest, src);
810       break;
811
812    case OPCODE_TEX:
813    case OPCODE_TXB:
814    case OPCODE_TXD:
815    case OPCODE_TXL:
816    case OPCODE_TXP:
817       ptn_tex(b, dest, src, prog_inst);
818       break;
819
820    case OPCODE_SWZ:
821       /* Extended swizzles were already handled in ptn_get_src(). */
822       ptn_alu(b, nir_op_fmov, dest, src);
823       break;
824
825    case OPCODE_NOP:
826       break;
827
828    default:
829       if (op_trans[op] != 0) {
830          ptn_alu(b, op_trans[op], dest, src);
831       } else {
832          fprintf(stderr, "unknown opcode: %s\n", _mesa_opcode_string(op));
833          abort();
834       }
835       break;
836    }
837
838    if (prog_inst->Saturate) {
839       assert(prog_inst->Saturate);
840       assert(!dest.dest.is_ssa);
841       ptn_move_dest(b, dest, nir_fsat(b, ptn_src_for_dest(c, &dest)));
842    }
843 }
844
845 /**
846  * Puts a NIR intrinsic to store of each PROGRAM_OUTPUT value to the output
847  * variables at the end of the shader.
848  *
849  * We don't generate these incrementally as the PROGRAM_OUTPUT values are
850  * written, because there's no output load intrinsic, which means we couldn't
851  * handle writemasks.
852  */
853 static void
854 ptn_add_output_stores(struct ptn_compile *c)
855 {
856    nir_builder *b = &c->build;
857
858    nir_foreach_variable(var, &b->shader->outputs) {
859       nir_intrinsic_instr *store =
860          nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
861       store->num_components = glsl_get_vector_elements(var->type);
862       nir_intrinsic_set_write_mask(store, (1 << store->num_components) - 1);
863       store->variables[0] =
864          nir_deref_var_create(store, c->output_vars[var->data.location]);
865
866       if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
867           var->data.location == FRAG_RESULT_DEPTH) {
868          /* result.depth has this strange convention of being the .z component of
869           * a vec4 with undefined .xyw components.  We resolve it to a scalar, to
870           * match GLSL's gl_FragDepth and the expectations of most backends.
871           */
872          nir_alu_src alu_src = { NIR_SRC_INIT };
873          alu_src.src = nir_src_for_reg(c->output_regs[FRAG_RESULT_DEPTH]);
874          alu_src.swizzle[0] = SWIZZLE_Z;
875          store->src[0] = nir_src_for_ssa(nir_fmov_alu(b, alu_src, 1));
876       } else {
877          store->src[0].reg.reg = c->output_regs[var->data.location];
878       }
879       nir_builder_instr_insert(b, &store->instr);
880    }
881 }
882
883 static void
884 setup_registers_and_variables(struct ptn_compile *c)
885 {
886    nir_builder *b = &c->build;
887    struct nir_shader *shader = b->shader;
888
889    /* Create input variables. */
890    const int num_inputs = _mesa_flsll(c->prog->InputsRead);
891    for (int i = 0; i < num_inputs; i++) {
892       if (!(c->prog->InputsRead & BITFIELD64_BIT(i)))
893          continue;
894
895       nir_variable *var =
896          nir_variable_create(shader, nir_var_shader_in, glsl_vec4_type(),
897                              ralloc_asprintf(shader, "in_%d", i));
898       var->data.location = i;
899       var->data.index = 0;
900
901       if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
902          struct gl_fragment_program *fp =
903             (struct gl_fragment_program *) c->prog;
904
905          var->data.interpolation = fp->InterpQualifier[i];
906
907          if (i == VARYING_SLOT_POS) {
908             var->data.origin_upper_left = fp->OriginUpperLeft;
909             var->data.pixel_center_integer = fp->PixelCenterInteger;
910          } else if (i == VARYING_SLOT_FOGC) {
911             /* fogcoord is defined as <f, 0.0, 0.0, 1.0>.  Make the actual
912              * input variable a float, and create a local containing the
913              * full vec4 value.
914              */
915             var->type = glsl_float_type();
916
917             nir_intrinsic_instr *load_x =
918                nir_intrinsic_instr_create(shader, nir_intrinsic_load_var);
919             load_x->num_components = 1;
920             load_x->variables[0] = nir_deref_var_create(load_x, var);
921             nir_ssa_dest_init(&load_x->instr, &load_x->dest, 1, 32, NULL);
922             nir_builder_instr_insert(b, &load_x->instr);
923
924             nir_ssa_def *f001 = nir_vec4(b, &load_x->dest.ssa, nir_imm_float(b, 0.0),
925                                          nir_imm_float(b, 0.0), nir_imm_float(b, 1.0));
926
927             nir_variable *fullvar =
928                nir_local_variable_create(b->impl, glsl_vec4_type(),
929                                          "fogcoord_tmp");
930             nir_intrinsic_instr *store =
931                nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
932             store->num_components = 4;
933             nir_intrinsic_set_write_mask(store, WRITEMASK_XYZW);
934             store->variables[0] = nir_deref_var_create(store, fullvar);
935             store->src[0] = nir_src_for_ssa(f001);
936             nir_builder_instr_insert(b, &store->instr);
937
938             /* We inserted the real input into the list so the driver has real
939              * inputs, but we set c->input_vars[i] to the temporary so we use
940              * the splatted value.
941              */
942             c->input_vars[i] = fullvar;
943             continue;
944          }
945       }
946
947       c->input_vars[i] = var;
948    }
949
950    /* Create output registers and variables. */
951    int max_outputs = _mesa_fls(c->prog->OutputsWritten);
952    c->output_regs = rzalloc_array(c, nir_register *, max_outputs);
953
954    for (int i = 0; i < max_outputs; i++) {
955       if (!(c->prog->OutputsWritten & BITFIELD64_BIT(i)))
956          continue;
957
958       /* Since we can't load from outputs in the IR, we make temporaries
959        * for the outputs and emit stores to the real outputs at the end of
960        * the shader.
961        */
962       nir_register *reg = nir_local_reg_create(b->impl);
963       reg->num_components = 4;
964
965       nir_variable *var = rzalloc(shader, nir_variable);
966       if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB && i == FRAG_RESULT_DEPTH)
967          var->type = glsl_float_type();
968       else
969          var->type = glsl_vec4_type();
970       var->data.mode = nir_var_shader_out;
971       var->name = ralloc_asprintf(var, "out_%d", i);
972
973       var->data.location = i;
974       var->data.index = 0;
975
976       c->output_regs[i] = reg;
977
978       exec_list_push_tail(&shader->outputs, &var->node);
979       c->output_vars[i] = var;
980    }
981
982    /* Create temporary registers. */
983    c->temp_regs = rzalloc_array(c, nir_register *, c->prog->NumTemporaries);
984
985    nir_register *reg;
986    for (unsigned i = 0; i < c->prog->NumTemporaries; i++) {
987       reg = nir_local_reg_create(b->impl);
988       if (!reg) {
989          c->error = true;
990          return;
991       }
992       reg->num_components = 4;
993       c->temp_regs[i] = reg;
994    }
995
996    /* Create the address register (for ARB_vertex_program). */
997    reg = nir_local_reg_create(b->impl);
998    if (!reg) {
999       c->error = true;
1000       return;
1001    }
1002    reg->num_components = 1;
1003    c->addr_reg = reg;
1004 }
1005
1006 struct nir_shader *
1007 prog_to_nir(const struct gl_program *prog,
1008             const nir_shader_compiler_options *options)
1009 {
1010    struct ptn_compile *c;
1011    struct nir_shader *s;
1012    gl_shader_stage stage = _mesa_program_enum_to_shader_stage(prog->Target);
1013
1014    c = rzalloc(NULL, struct ptn_compile);
1015    if (!c)
1016       return NULL;
1017    c->prog = prog;
1018
1019    nir_builder_init_simple_shader(&c->build, NULL, stage, options);
1020    s = c->build.shader;
1021
1022    if (prog->Parameters->NumParameters > 0) {
1023       c->parameters = rzalloc(s, nir_variable);
1024       c->parameters->type =
1025          glsl_array_type(glsl_vec4_type(), prog->Parameters->NumParameters);
1026       c->parameters->name = "parameters";
1027       c->parameters->data.read_only = true;
1028       c->parameters->data.mode = nir_var_uniform;
1029       exec_list_push_tail(&s->uniforms, &c->parameters->node);
1030    }
1031
1032    setup_registers_and_variables(c);
1033    if (unlikely(c->error))
1034       goto fail;
1035
1036    for (unsigned int i = 0; i < prog->NumInstructions; i++) {
1037       ptn_emit_instruction(c, &prog->Instructions[i]);
1038
1039       if (unlikely(c->error))
1040          break;
1041    }
1042
1043    ptn_add_output_stores(c);
1044
1045    s->info.name = ralloc_asprintf(s, "ARB%d", prog->Id);
1046    s->info.num_textures = _mesa_fls(prog->SamplersUsed);
1047    s->info.num_ubos = 0;
1048    s->info.num_abos = 0;
1049    s->info.num_ssbos = 0;
1050    s->info.num_images = 0;
1051    s->info.inputs_read = prog->InputsRead;
1052    s->info.outputs_written = prog->OutputsWritten;
1053    s->info.system_values_read = prog->SystemValuesRead;
1054    s->info.uses_texture_gather = false;
1055    s->info.uses_clip_distance_out = false;
1056    s->info.separate_shader = false;
1057
1058    if (stage == MESA_SHADER_FRAGMENT) {
1059       struct gl_fragment_program *fp = (struct gl_fragment_program *)prog;
1060
1061       s->info.fs.uses_discard = fp->UsesKill;
1062    }
1063
1064 fail:
1065    if (c->error) {
1066       ralloc_free(s);
1067       s = NULL;
1068    }
1069    ralloc_free(c);
1070    return s;
1071 }