1/*
2 * Copyright (c) 2014 Scott Mansell
3 * Copyright © 2014 Broadcom
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 <inttypes.h>
26#include "util/u_format.h"
27#include "util/crc32.h"
28#include "util/u_math.h"
29#include "util/u_memory.h"
30#include "util/ralloc.h"
31#include "util/hash_table.h"
32#include "tgsi/tgsi_dump.h"
33#include "tgsi/tgsi_parse.h"
34#include "compiler/nir/nir.h"
35#include "compiler/nir/nir_builder.h"
36#include "compiler/nir_types.h"
37#include "nir/tgsi_to_nir.h"
38#include "vc4_context.h"
39#include "vc4_qpu.h"
40#include "vc4_qir.h"
41
42static struct qreg
43ntq_get_src(struct vc4_compile *c, nir_src src, int i);
44static void
45ntq_emit_cf_list(struct vc4_compile *c, struct exec_list *list);
46
47static int
48type_size(const struct glsl_type *type, bool bindless)
49{
50   return glsl_count_attribute_slots(type, false);
51}
52
53static void
54resize_qreg_array(struct vc4_compile *c,
55                  struct qreg **regs,
56                  uint32_t *size,
57                  uint32_t decl_size)
58{
59        if (*size >= decl_size)
60                return;
61
62        uint32_t old_size = *size;
63        *size = MAX2(*size * 2, decl_size);
64        *regs = reralloc(c, *regs, struct qreg, *size);
65        if (!*regs) {
66                fprintf(stderr, "Malloc failure\n");
67                abort();
68        }
69
70        for (uint32_t i = old_size; i < *size; i++)
71                (*regs)[i] = c->undef;
72}
73
74static void
75ntq_emit_thrsw(struct vc4_compile *c)
76{
77        if (!c->fs_threaded)
78                return;
79
80        /* Always thread switch after each texture operation for now.
81         *
82         * We could do better by batching a bunch of texture fetches up and
83         * then doing one thread switch and collecting all their results
84         * afterward.
85         */
86        qir_emit_nondef(c, qir_inst(QOP_THRSW, c->undef,
87                                    c->undef, c->undef));
88        c->last_thrsw_at_top_level = (c->execute.file == QFILE_NULL);
89}
90
91static struct qreg
92indirect_uniform_load(struct vc4_compile *c, nir_intrinsic_instr *intr)
93{
94        struct qreg indirect_offset = ntq_get_src(c, intr->src[0], 0);
95
96        /* Clamp to [0, array size).  Note that MIN/MAX are signed. */
97        uint32_t range = nir_intrinsic_range(intr);
98        indirect_offset = qir_MAX(c, indirect_offset, qir_uniform_ui(c, 0));
99        indirect_offset = qir_MIN_NOIMM(c, indirect_offset,
100                                        qir_uniform_ui(c, range - 4));
101
102        qir_ADD_dest(c, qir_reg(QFILE_TEX_S_DIRECT, 0),
103                     indirect_offset,
104                     qir_uniform(c, QUNIFORM_UBO0_ADDR,
105                                 nir_intrinsic_base(intr)));
106
107        c->num_texture_samples++;
108
109        ntq_emit_thrsw(c);
110
111        return qir_TEX_RESULT(c);
112}
113
114static struct qreg
115vc4_ubo_load(struct vc4_compile *c, nir_intrinsic_instr *intr)
116{
117        int buffer_index = nir_src_as_uint(intr->src[0]);
118        assert(buffer_index == 1);
119        assert(c->stage == QSTAGE_FRAG);
120
121        struct qreg offset = ntq_get_src(c, intr->src[1], 0);
122
123        /* Clamp to [0, array size).  Note that MIN/MAX are signed. */
124        offset = qir_MAX(c, offset, qir_uniform_ui(c, 0));
125        offset = qir_MIN_NOIMM(c, offset,
126                               qir_uniform_ui(c, c->fs_key->ubo_1_size - 4));
127
128        qir_ADD_dest(c, qir_reg(QFILE_TEX_S_DIRECT, 0),
129                     offset,
130                     qir_uniform(c, QUNIFORM_UBO1_ADDR, 0));
131
132        c->num_texture_samples++;
133
134        ntq_emit_thrsw(c);
135
136        return qir_TEX_RESULT(c);
137}
138
139nir_ssa_def *
140vc4_nir_get_swizzled_channel(nir_builder *b, nir_ssa_def **srcs, int swiz)
141{
142        switch (swiz) {
143        default:
144        case PIPE_SWIZZLE_NONE:
145                fprintf(stderr, "warning: unknown swizzle\n");
146                /* FALLTHROUGH */
147        case PIPE_SWIZZLE_0:
148                return nir_imm_float(b, 0.0);
149        case PIPE_SWIZZLE_1:
150                return nir_imm_float(b, 1.0);
151        case PIPE_SWIZZLE_X:
152        case PIPE_SWIZZLE_Y:
153        case PIPE_SWIZZLE_Z:
154        case PIPE_SWIZZLE_W:
155                return srcs[swiz];
156        }
157}
158
159static struct qreg *
160ntq_init_ssa_def(struct vc4_compile *c, nir_ssa_def *def)
161{
162        struct qreg *qregs = ralloc_array(c->def_ht, struct qreg,
163                                          def->num_components);
164        _mesa_hash_table_insert(c->def_ht, def, qregs);
165        return qregs;
166}
167
168/**
169 * This function is responsible for getting QIR results into the associated
170 * storage for a NIR instruction.
171 *
172 * If it's a NIR SSA def, then we just set the associated hash table entry to
173 * the new result.
174 *
175 * If it's a NIR reg, then we need to update the existing qreg assigned to the
176 * NIR destination with the incoming value.  To do that without introducing
177 * new MOVs, we require that the incoming qreg either be a uniform, or be
178 * SSA-defined by the previous QIR instruction in the block and rewritable by
179 * this function.  That lets us sneak ahead and insert the SF flag beforehand
180 * (knowing that the previous instruction doesn't depend on flags) and rewrite
181 * its destination to be the NIR reg's destination
182 */
183static void
184ntq_store_dest(struct vc4_compile *c, nir_dest *dest, int chan,
185               struct qreg result)
186{
187        struct qinst *last_inst = NULL;
188        if (!list_empty(&c->cur_block->instructions))
189                last_inst = (struct qinst *)c->cur_block->instructions.prev;
190
191        assert(result.file == QFILE_UNIF ||
192               (result.file == QFILE_TEMP &&
193                last_inst && last_inst == c->defs[result.index]));
194
195        if (dest->is_ssa) {
196                assert(chan < dest->ssa.num_components);
197
198                struct qreg *qregs;
199                struct hash_entry *entry =
200                        _mesa_hash_table_search(c->def_ht, &dest->ssa);
201
202                if (entry)
203                        qregs = entry->data;
204                else
205                        qregs = ntq_init_ssa_def(c, &dest->ssa);
206
207                qregs[chan] = result;
208        } else {
209                nir_register *reg = dest->reg.reg;
210                assert(dest->reg.base_offset == 0);
211                assert(reg->num_array_elems == 0);
212                struct hash_entry *entry =
213                        _mesa_hash_table_search(c->def_ht, reg);
214                struct qreg *qregs = entry->data;
215
216                /* Insert a MOV if the source wasn't an SSA def in the
217                 * previous instruction.
218                 */
219                if (result.file == QFILE_UNIF) {
220                        result = qir_MOV(c, result);
221                        last_inst = c->defs[result.index];
222                }
223
224                /* We know they're both temps, so just rewrite index. */
225                c->defs[last_inst->dst.index] = NULL;
226                last_inst->dst.index = qregs[chan].index;
227
228                /* If we're in control flow, then make this update of the reg
229                 * conditional on the execution mask.
230                 */
231                if (c->execute.file != QFILE_NULL) {
232                        last_inst->dst.index = qregs[chan].index;
233
234                        /* Set the flags to the current exec mask.  To insert
235                         * the SF, we temporarily remove our SSA instruction.
236                         */
237                        list_del(&last_inst->link);
238                        qir_SF(c, c->execute);
239                        list_addtail(&last_inst->link,
240                                     &c->cur_block->instructions);
241
242                        last_inst->cond = QPU_COND_ZS;
243                        last_inst->cond_is_exec_mask = true;
244                }
245        }
246}
247
248static struct qreg *
249ntq_get_dest(struct vc4_compile *c, nir_dest *dest)
250{
251        if (dest->is_ssa) {
252                struct qreg *qregs = ntq_init_ssa_def(c, &dest->ssa);
253                for (int i = 0; i < dest->ssa.num_components; i++)
254                        qregs[i] = c->undef;
255                return qregs;
256        } else {
257                nir_register *reg = dest->reg.reg;
258                assert(dest->reg.base_offset == 0);
259                assert(reg->num_array_elems == 0);
260                struct hash_entry *entry =
261                        _mesa_hash_table_search(c->def_ht, reg);
262                return entry->data;
263        }
264}
265
266static struct qreg
267ntq_get_src(struct vc4_compile *c, nir_src src, int i)
268{
269        struct hash_entry *entry;
270        if (src.is_ssa) {
271                entry = _mesa_hash_table_search(c->def_ht, src.ssa);
272                assert(i < src.ssa->num_components);
273        } else {
274                nir_register *reg = src.reg.reg;
275                entry = _mesa_hash_table_search(c->def_ht, reg);
276                assert(reg->num_array_elems == 0);
277                assert(src.reg.base_offset == 0);
278                assert(i < reg->num_components);
279        }
280
281        struct qreg *qregs = entry->data;
282        return qregs[i];
283}
284
285static struct qreg
286ntq_get_alu_src(struct vc4_compile *c, nir_alu_instr *instr,
287                unsigned src)
288{
289        assert(util_is_power_of_two_or_zero(instr->dest.write_mask));
290        unsigned chan = ffs(instr->dest.write_mask) - 1;
291        struct qreg r = ntq_get_src(c, instr->src[src].src,
292                                    instr->src[src].swizzle[chan]);
293
294        assert(!instr->src[src].abs);
295        assert(!instr->src[src].negate);
296
297        return r;
298};
299
300static inline struct qreg
301qir_SAT(struct vc4_compile *c, struct qreg val)
302{
303        return qir_FMAX(c,
304                        qir_FMIN(c, val, qir_uniform_f(c, 1.0)),
305                        qir_uniform_f(c, 0.0));
306}
307
308static struct qreg
309ntq_rcp(struct vc4_compile *c, struct qreg x)
310{
311        struct qreg r = qir_RCP(c, x);
312
313        /* Apply a Newton-Raphson step to improve the accuracy. */
314        r = qir_FMUL(c, r, qir_FSUB(c,
315                                    qir_uniform_f(c, 2.0),
316                                    qir_FMUL(c, x, r)));
317
318        return r;
319}
320
321static struct qreg
322ntq_rsq(struct vc4_compile *c, struct qreg x)
323{
324        struct qreg r = qir_RSQ(c, x);
325
326        /* Apply a Newton-Raphson step to improve the accuracy. */
327        r = qir_FMUL(c, r, qir_FSUB(c,
328                                    qir_uniform_f(c, 1.5),
329                                    qir_FMUL(c,
330                                             qir_uniform_f(c, 0.5),
331                                             qir_FMUL(c, x,
332                                                      qir_FMUL(c, r, r)))));
333
334        return r;
335}
336
337static struct qreg
338ntq_umul(struct vc4_compile *c, struct qreg src0, struct qreg src1)
339{
340        struct qreg src0_hi = qir_SHR(c, src0,
341                                      qir_uniform_ui(c, 24));
342        struct qreg src1_hi = qir_SHR(c, src1,
343                                      qir_uniform_ui(c, 24));
344
345        struct qreg hilo = qir_MUL24(c, src0_hi, src1);
346        struct qreg lohi = qir_MUL24(c, src0, src1_hi);
347        struct qreg lolo = qir_MUL24(c, src0, src1);
348
349        return qir_ADD(c, lolo, qir_SHL(c,
350                                        qir_ADD(c, hilo, lohi),
351                                        qir_uniform_ui(c, 24)));
352}
353
354static struct qreg
355ntq_scale_depth_texture(struct vc4_compile *c, struct qreg src)
356{
357        struct qreg depthf = qir_ITOF(c, qir_SHR(c, src,
358                                                 qir_uniform_ui(c, 8)));
359        return qir_FMUL(c, depthf, qir_uniform_f(c, 1.0f/0xffffff));
360}
361
362/**
363 * Emits a lowered TXF_MS from an MSAA texture.
364 *
365 * The addressing math has been lowered in NIR, and now we just need to read
366 * it like a UBO.
367 */
368static void
369ntq_emit_txf(struct vc4_compile *c, nir_tex_instr *instr)
370{
371        uint32_t tile_width = 32;
372        uint32_t tile_height = 32;
373        uint32_t tile_size = (tile_height * tile_width *
374                              VC4_MAX_SAMPLES * sizeof(uint32_t));
375
376        unsigned unit = instr->texture_index;
377        uint32_t w = align(c->key->tex[unit].msaa_width, tile_width);
378        uint32_t w_tiles = w / tile_width;
379        uint32_t h = align(c->key->tex[unit].msaa_height, tile_height);
380        uint32_t h_tiles = h / tile_height;
381        uint32_t size = w_tiles * h_tiles * tile_size;
382
383        struct qreg addr;
384        assert(instr->num_srcs == 1);
385        assert(instr->src[0].src_type == nir_tex_src_coord);
386        addr = ntq_get_src(c, instr->src[0].src, 0);
387
388        /* Perform the clamping required by kernel validation. */
389        addr = qir_MAX(c, addr, qir_uniform_ui(c, 0));
390        addr = qir_MIN_NOIMM(c, addr, qir_uniform_ui(c, size - 4));
391
392        qir_ADD_dest(c, qir_reg(QFILE_TEX_S_DIRECT, 0),
393                     addr, qir_uniform(c, QUNIFORM_TEXTURE_MSAA_ADDR, unit));
394
395        ntq_emit_thrsw(c);
396
397        struct qreg tex = qir_TEX_RESULT(c);
398        c->num_texture_samples++;
399
400        enum pipe_format format = c->key->tex[unit].format;
401        if (util_format_is_depth_or_stencil(format)) {
402                struct qreg scaled = ntq_scale_depth_texture(c, tex);
403                for (int i = 0; i < 4; i++)
404                        ntq_store_dest(c, &instr->dest, i, qir_MOV(c, scaled));
405        } else {
406                for (int i = 0; i < 4; i++)
407                        ntq_store_dest(c, &instr->dest, i,
408                                       qir_UNPACK_8_F(c, tex, i));
409        }
410}
411
412static void
413ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr)
414{
415        struct qreg s, t, r, lod, compare;
416        bool is_txb = false, is_txl = false;
417        unsigned unit = instr->texture_index;
418
419        if (instr->op == nir_texop_txf) {
420                ntq_emit_txf(c, instr);
421                return;
422        }
423
424        for (unsigned i = 0; i < instr->num_srcs; i++) {
425                switch (instr->src[i].src_type) {
426                case nir_tex_src_coord:
427                        s = ntq_get_src(c, instr->src[i].src, 0);
428                        if (instr->sampler_dim == GLSL_SAMPLER_DIM_1D)
429                                t = qir_uniform_f(c, 0.5);
430                        else
431                                t = ntq_get_src(c, instr->src[i].src, 1);
432                        if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
433                                r = ntq_get_src(c, instr->src[i].src, 2);
434                        break;
435                case nir_tex_src_bias:
436                        lod = ntq_get_src(c, instr->src[i].src, 0);
437                        is_txb = true;
438                        break;
439                case nir_tex_src_lod:
440                        lod = ntq_get_src(c, instr->src[i].src, 0);
441                        is_txl = true;
442                        break;
443                case nir_tex_src_comparator:
444                        compare = ntq_get_src(c, instr->src[i].src, 0);
445                        break;
446                default:
447                        unreachable("unknown texture source");
448                }
449        }
450
451        if (c->stage != QSTAGE_FRAG && !is_txl) {
452                /* From the GLSL 1.20 spec:
453                 *
454                 *     "If it is mip-mapped and running on the vertex shader,
455                 *      then the base texture is used."
456                 */
457                is_txl = true;
458                lod = qir_uniform_ui(c, 0);
459        }
460
461        if (c->key->tex[unit].force_first_level) {
462                lod = qir_uniform(c, QUNIFORM_TEXTURE_FIRST_LEVEL, unit);
463                is_txl = true;
464                is_txb = false;
465        }
466
467        struct qreg texture_u[] = {
468                qir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P0, unit),
469                qir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P1, unit),
470                qir_uniform(c, QUNIFORM_CONSTANT, 0),
471                qir_uniform(c, QUNIFORM_CONSTANT, 0),
472        };
473        uint32_t next_texture_u = 0;
474
475        /* There is no native support for GL texture rectangle coordinates, so
476         * we have to rescale from ([0, width], [0, height]) to ([0, 1], [0,
477         * 1]).
478         */
479        if (instr->sampler_dim == GLSL_SAMPLER_DIM_RECT) {
480                s = qir_FMUL(c, s,
481                             qir_uniform(c, QUNIFORM_TEXRECT_SCALE_X, unit));
482                t = qir_FMUL(c, t,
483                             qir_uniform(c, QUNIFORM_TEXRECT_SCALE_Y, unit));
484        }
485
486        if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE || is_txl) {
487                texture_u[2] = qir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P2,
488                                           unit | (is_txl << 16));
489        }
490
491        struct qinst *tmu;
492        if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE) {
493                tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_R, 0), r);
494                tmu->src[qir_get_tex_uniform_src(tmu)] =
495                        texture_u[next_texture_u++];
496        } else if (c->key->tex[unit].wrap_s == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
497                   c->key->tex[unit].wrap_s == PIPE_TEX_WRAP_CLAMP ||
498                   c->key->tex[unit].wrap_t == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
499                   c->key->tex[unit].wrap_t == PIPE_TEX_WRAP_CLAMP) {
500                tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_R, 0),
501                                   qir_uniform(c, QUNIFORM_TEXTURE_BORDER_COLOR,
502                                               unit));
503                tmu->src[qir_get_tex_uniform_src(tmu)] =
504                        texture_u[next_texture_u++];
505        }
506
507        if (c->key->tex[unit].wrap_s == PIPE_TEX_WRAP_CLAMP) {
508                s = qir_SAT(c, s);
509        }
510
511        if (c->key->tex[unit].wrap_t == PIPE_TEX_WRAP_CLAMP) {
512                t = qir_SAT(c, t);
513        }
514
515        tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_T, 0), t);
516        tmu->src[qir_get_tex_uniform_src(tmu)] =
517                texture_u[next_texture_u++];
518
519        if (is_txl || is_txb) {
520                tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_B, 0), lod);
521                tmu->src[qir_get_tex_uniform_src(tmu)] =
522                        texture_u[next_texture_u++];
523        }
524
525        tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_S, 0), s);
526        tmu->src[qir_get_tex_uniform_src(tmu)] = texture_u[next_texture_u++];
527
528        c->num_texture_samples++;
529
530        ntq_emit_thrsw(c);
531
532        struct qreg tex = qir_TEX_RESULT(c);
533
534        enum pipe_format format = c->key->tex[unit].format;
535
536        struct qreg *dest = ntq_get_dest(c, &instr->dest);
537        if (util_format_is_depth_or_stencil(format)) {
538                struct qreg normalized = ntq_scale_depth_texture(c, tex);
539                struct qreg depth_output;
540
541                struct qreg u0 = qir_uniform_f(c, 0.0f);
542                struct qreg u1 = qir_uniform_f(c, 1.0f);
543                if (c->key->tex[unit].compare_mode) {
544                        /* From the GL_ARB_shadow spec:
545                         *
546                         *     "Let Dt (D subscript t) be the depth texture
547                         *      value, in the range [0, 1].  Let R be the
548                         *      interpolated texture coordinate clamped to the
549                         *      range [0, 1]."
550                         */
551                        compare = qir_SAT(c, compare);
552
553                        switch (c->key->tex[unit].compare_func) {
554                        case PIPE_FUNC_NEVER:
555                                depth_output = qir_uniform_f(c, 0.0f);
556                                break;
557                        case PIPE_FUNC_ALWAYS:
558                                depth_output = u1;
559                                break;
560                        case PIPE_FUNC_EQUAL:
561                                qir_SF(c, qir_FSUB(c, compare, normalized));
562                                depth_output = qir_SEL(c, QPU_COND_ZS, u1, u0);
563                                break;
564                        case PIPE_FUNC_NOTEQUAL:
565                                qir_SF(c, qir_FSUB(c, compare, normalized));
566                                depth_output = qir_SEL(c, QPU_COND_ZC, u1, u0);
567                                break;
568                        case PIPE_FUNC_GREATER:
569                                qir_SF(c, qir_FSUB(c, compare, normalized));
570                                depth_output = qir_SEL(c, QPU_COND_NC, u1, u0);
571                                break;
572                        case PIPE_FUNC_GEQUAL:
573                                qir_SF(c, qir_FSUB(c, normalized, compare));
574                                depth_output = qir_SEL(c, QPU_COND_NS, u1, u0);
575                                break;
576                        case PIPE_FUNC_LESS:
577                                qir_SF(c, qir_FSUB(c, compare, normalized));
578                                depth_output = qir_SEL(c, QPU_COND_NS, u1, u0);
579                                break;
580                        case PIPE_FUNC_LEQUAL:
581                                qir_SF(c, qir_FSUB(c, normalized, compare));
582                                depth_output = qir_SEL(c, QPU_COND_NC, u1, u0);
583                                break;
584                        }
585                } else {
586                        depth_output = normalized;
587                }
588
589                for (int i = 0; i < 4; i++)
590                        dest[i] = depth_output;
591        } else {
592                for (int i = 0; i < 4; i++)
593                        dest[i] = qir_UNPACK_8_F(c, tex, i);
594        }
595}
596
597/**
598 * Computes x - floor(x), which is tricky because our FTOI truncates (rounds
599 * to zero).
600 */
601static struct qreg
602ntq_ffract(struct vc4_compile *c, struct qreg src)
603{
604        struct qreg trunc = qir_ITOF(c, qir_FTOI(c, src));
605        struct qreg diff = qir_FSUB(c, src, trunc);
606        qir_SF(c, diff);
607
608        qir_FADD_dest(c, diff,
609                      diff, qir_uniform_f(c, 1.0))->cond = QPU_COND_NS;
610
611        return qir_MOV(c, diff);
612}
613
614/**
615 * Computes floor(x), which is tricky because our FTOI truncates (rounds to
616 * zero).
617 */
618static struct qreg
619ntq_ffloor(struct vc4_compile *c, struct qreg src)
620{
621        struct qreg result = qir_ITOF(c, qir_FTOI(c, src));
622
623        /* This will be < 0 if we truncated and the truncation was of a value
624         * that was < 0 in the first place.
625         */
626        qir_SF(c, qir_FSUB(c, src, result));
627
628        struct qinst *sub = qir_FSUB_dest(c, result,
629                                          result, qir_uniform_f(c, 1.0));
630        sub->cond = QPU_COND_NS;
631
632        return qir_MOV(c, result);
633}
634
635/**
636 * Computes ceil(x), which is tricky because our FTOI truncates (rounds to
637 * zero).
638 */
639static struct qreg
640ntq_fceil(struct vc4_compile *c, struct qreg src)
641{
642        struct qreg result = qir_ITOF(c, qir_FTOI(c, src));
643
644        /* This will be < 0 if we truncated and the truncation was of a value
645         * that was > 0 in the first place.
646         */
647        qir_SF(c, qir_FSUB(c, result, src));
648
649        qir_FADD_dest(c, result,
650                      result, qir_uniform_f(c, 1.0))->cond = QPU_COND_NS;
651
652        return qir_MOV(c, result);
653}
654
655static struct qreg
656ntq_shrink_sincos_input_range(struct vc4_compile *c, struct qreg x)
657{
658        /* Since we're using a Taylor approximation, we want to have a small
659         * number of coefficients and take advantage of sin/cos repeating
660         * every 2pi.  We keep our x as close to 0 as we can, since the series
661         * will be less accurate as |x| increases.  (Also, be careful of
662         * shifting the input x value to be tricky with sin/cos relations,
663         * because getting accurate values for x==0 is very important for SDL
664         * rendering)
665         */
666        struct qreg scaled_x =
667                qir_FMUL(c, x,
668                         qir_uniform_f(c, 1.0f / (M_PI * 2.0f)));
669        /* Note: FTOI truncates toward 0. */
670        struct qreg x_frac = qir_FSUB(c, scaled_x,
671                                      qir_ITOF(c, qir_FTOI(c, scaled_x)));
672        /* Map [0.5, 1] to [-0.5, 0] */
673        qir_SF(c, qir_FSUB(c, x_frac, qir_uniform_f(c, 0.5)));
674        qir_FSUB_dest(c, x_frac, x_frac, qir_uniform_f(c, 1.0))->cond = QPU_COND_NC;
675        /* Map [-1, -0.5] to [0, 0.5] */
676        qir_SF(c, qir_FADD(c, x_frac, qir_uniform_f(c, 0.5)));
677        qir_FADD_dest(c, x_frac, x_frac, qir_uniform_f(c, 1.0))->cond = QPU_COND_NS;
678
679        return x_frac;
680}
681
682static struct qreg
683ntq_fsin(struct vc4_compile *c, struct qreg src)
684{
685        float coeff[] = {
686                2.0 * M_PI,
687                -pow(2.0 * M_PI, 3) / (3 * 2 * 1),
688                pow(2.0 * M_PI, 5) / (5 * 4 * 3 * 2 * 1),
689                -pow(2.0 * M_PI, 7) / (7 * 6 * 5 * 4 * 3 * 2 * 1),
690                pow(2.0 * M_PI, 9) / (9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1),
691        };
692
693        struct qreg x = ntq_shrink_sincos_input_range(c, src);
694        struct qreg x2 = qir_FMUL(c, x, x);
695        struct qreg sum = qir_FMUL(c, x, qir_uniform_f(c, coeff[0]));
696        for (int i = 1; i < ARRAY_SIZE(coeff); i++) {
697                x = qir_FMUL(c, x, x2);
698                sum = qir_FADD(c,
699                               sum,
700                               qir_FMUL(c,
701                                        x,
702                                        qir_uniform_f(c, coeff[i])));
703        }
704        return sum;
705}
706
707static struct qreg
708ntq_fcos(struct vc4_compile *c, struct qreg src)
709{
710        float coeff[] = {
711                1.0f,
712                -pow(2.0 * M_PI, 2) / (2 * 1),
713                pow(2.0 * M_PI, 4) / (4 * 3 * 2 * 1),
714                -pow(2.0 * M_PI, 6) / (6 * 5 * 4 * 3 * 2 * 1),
715                pow(2.0 * M_PI, 8) / (8 * 7 * 6 * 5 * 4 * 3 * 2 * 1),
716                -pow(2.0 * M_PI, 10) / (10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1),
717        };
718
719        struct qreg x_frac = ntq_shrink_sincos_input_range(c, src);
720        struct qreg sum = qir_uniform_f(c, coeff[0]);
721        struct qreg x2 = qir_FMUL(c, x_frac, x_frac);
722        struct qreg x = x2; /* Current x^2, x^4, or x^6 */
723        for (int i = 1; i < ARRAY_SIZE(coeff); i++) {
724                if (i != 1)
725                        x = qir_FMUL(c, x, x2);
726
727                sum = qir_FADD(c, qir_FMUL(c,
728                                           x,
729                                           qir_uniform_f(c, coeff[i])),
730                               sum);
731        }
732        return sum;
733}
734
735static struct qreg
736ntq_fsign(struct vc4_compile *c, struct qreg src)
737{
738        struct qreg t = qir_get_temp(c);
739
740        qir_SF(c, src);
741        qir_MOV_dest(c, t, qir_uniform_f(c, 0.0));
742        qir_MOV_dest(c, t, qir_uniform_f(c, 1.0))->cond = QPU_COND_ZC;
743        qir_MOV_dest(c, t, qir_uniform_f(c, -1.0))->cond = QPU_COND_NS;
744        return qir_MOV(c, t);
745}
746
747static void
748emit_vertex_input(struct vc4_compile *c, int attr)
749{
750        enum pipe_format format = c->vs_key->attr_formats[attr];
751        uint32_t attr_size = util_format_get_blocksize(format);
752
753        c->vattr_sizes[attr] = align(attr_size, 4);
754        for (int i = 0; i < align(attr_size, 4) / 4; i++) {
755                c->inputs[attr * 4 + i] =
756                        qir_MOV(c, qir_reg(QFILE_VPM, attr * 4 + i));
757                c->num_inputs++;
758        }
759}
760
761static void
762emit_fragcoord_input(struct vc4_compile *c, int attr)
763{
764        c->inputs[attr * 4 + 0] = qir_ITOF(c, qir_reg(QFILE_FRAG_X, 0));
765        c->inputs[attr * 4 + 1] = qir_ITOF(c, qir_reg(QFILE_FRAG_Y, 0));
766        c->inputs[attr * 4 + 2] =
767                qir_FMUL(c,
768                         qir_ITOF(c, qir_FRAG_Z(c)),
769                         qir_uniform_f(c, 1.0 / 0xffffff));
770        c->inputs[attr * 4 + 3] = qir_RCP(c, qir_FRAG_W(c));
771}
772
773static struct qreg
774emit_fragment_varying(struct vc4_compile *c, gl_varying_slot slot,
775                      uint8_t swizzle)
776{
777        uint32_t i = c->num_input_slots++;
778        struct qreg vary = {
779                QFILE_VARY,
780                i
781        };
782
783        if (c->num_input_slots >= c->input_slots_array_size) {
784                c->input_slots_array_size =
785                        MAX2(4, c->input_slots_array_size * 2);
786
787                c->input_slots = reralloc(c, c->input_slots,
788                                          struct vc4_varying_slot,
789                                          c->input_slots_array_size);
790        }
791
792        c->input_slots[i].slot = slot;
793        c->input_slots[i].swizzle = swizzle;
794
795        return qir_VARY_ADD_C(c, qir_FMUL(c, vary, qir_FRAG_W(c)));
796}
797
798static void
799emit_fragment_input(struct vc4_compile *c, int attr, gl_varying_slot slot)
800{
801        for (int i = 0; i < 4; i++) {
802                c->inputs[attr * 4 + i] =
803                        emit_fragment_varying(c, slot, i);
804                c->num_inputs++;
805        }
806}
807
808static void
809add_output(struct vc4_compile *c,
810           uint32_t decl_offset,
811           uint8_t slot,
812           uint8_t swizzle)
813{
814        uint32_t old_array_size = c->outputs_array_size;
815        resize_qreg_array(c, &c->outputs, &c->outputs_array_size,
816                          decl_offset + 1);
817
818        if (old_array_size != c->outputs_array_size) {
819                c->output_slots = reralloc(c,
820                                           c->output_slots,
821                                           struct vc4_varying_slot,
822                                           c->outputs_array_size);
823        }
824
825        c->output_slots[decl_offset].slot = slot;
826        c->output_slots[decl_offset].swizzle = swizzle;
827}
828
829static bool
830ntq_src_is_only_ssa_def_user(nir_src *src)
831{
832        if (!src->is_ssa)
833                return false;
834
835        if (!list_empty(&src->ssa->if_uses))
836                return false;
837
838        return (src->ssa->uses.next == &src->use_link &&
839                src->ssa->uses.next->next == &src->ssa->uses);
840}
841
842/**
843 * In general, emits a nir_pack_unorm_4x8 as a series of MOVs with the pack
844 * bit set.
845 *
846 * However, as an optimization, it tries to find the instructions generating
847 * the sources to be packed and just emit the pack flag there, if possible.
848 */
849static void
850ntq_emit_pack_unorm_4x8(struct vc4_compile *c, nir_alu_instr *instr)
851{
852        struct qreg result = qir_get_temp(c);
853        struct nir_alu_instr *vec4 = NULL;
854
855        /* If packing from a vec4 op (as expected), identify it so that we can
856         * peek back at what generated its sources.
857         */
858        if (instr->src[0].src.is_ssa &&
859            instr->src[0].src.ssa->parent_instr->type == nir_instr_type_alu &&
860            nir_instr_as_alu(instr->src[0].src.ssa->parent_instr)->op ==
861            nir_op_vec4) {
862                vec4 = nir_instr_as_alu(instr->src[0].src.ssa->parent_instr);
863        }
864
865        /* If the pack is replicating the same channel 4 times, use the 8888
866         * pack flag.  This is common for blending using the alpha
867         * channel.
868         */
869        if (instr->src[0].swizzle[0] == instr->src[0].swizzle[1] &&
870            instr->src[0].swizzle[0] == instr->src[0].swizzle[2] &&
871            instr->src[0].swizzle[0] == instr->src[0].swizzle[3]) {
872                struct qreg rep = ntq_get_src(c,
873                                              instr->src[0].src,
874                                              instr->src[0].swizzle[0]);
875                ntq_store_dest(c, &instr->dest.dest, 0, qir_PACK_8888_F(c, rep));
876                return;
877        }
878
879        for (int i = 0; i < 4; i++) {
880                int swiz = instr->src[0].swizzle[i];
881                struct qreg src;
882                if (vec4) {
883                        src = ntq_get_src(c, vec4->src[swiz].src,
884                                          vec4->src[swiz].swizzle[0]);
885                } else {
886                        src = ntq_get_src(c, instr->src[0].src, swiz);
887                }
888
889                if (vec4 &&
890                    ntq_src_is_only_ssa_def_user(&vec4->src[swiz].src) &&
891                    src.file == QFILE_TEMP &&
892                    c->defs[src.index] &&
893                    qir_is_mul(c->defs[src.index]) &&
894                    !c->defs[src.index]->dst.pack) {
895                        struct qinst *rewrite = c->defs[src.index];
896                        c->defs[src.index] = NULL;
897                        rewrite->dst = result;
898                        rewrite->dst.pack = QPU_PACK_MUL_8A + i;
899                        continue;
900                }
901
902                qir_PACK_8_F(c, result, src, i);
903        }
904
905        ntq_store_dest(c, &instr->dest.dest, 0, qir_MOV(c, result));
906}
907
908/** Handles sign-extended bitfield extracts for 16 bits. */
909static struct qreg
910ntq_emit_ibfe(struct vc4_compile *c, struct qreg base, struct qreg offset,
911              struct qreg bits)
912{
913        assert(bits.file == QFILE_UNIF &&
914               c->uniform_contents[bits.index] == QUNIFORM_CONSTANT &&
915               c->uniform_data[bits.index] == 16);
916
917        assert(offset.file == QFILE_UNIF &&
918               c->uniform_contents[offset.index] == QUNIFORM_CONSTANT);
919        int offset_bit = c->uniform_data[offset.index];
920        assert(offset_bit % 16 == 0);
921
922        return qir_UNPACK_16_I(c, base, offset_bit / 16);
923}
924
925/** Handles unsigned bitfield extracts for 8 bits. */
926static struct qreg
927ntq_emit_ubfe(struct vc4_compile *c, struct qreg base, struct qreg offset,
928              struct qreg bits)
929{
930        assert(bits.file == QFILE_UNIF &&
931               c->uniform_contents[bits.index] == QUNIFORM_CONSTANT &&
932               c->uniform_data[bits.index] == 8);
933
934        assert(offset.file == QFILE_UNIF &&
935               c->uniform_contents[offset.index] == QUNIFORM_CONSTANT);
936        int offset_bit = c->uniform_data[offset.index];
937        assert(offset_bit % 8 == 0);
938
939        return qir_UNPACK_8_I(c, base, offset_bit / 8);
940}
941
942/**
943 * If compare_instr is a valid comparison instruction, emits the
944 * compare_instr's comparison and returns the sel_instr's return value based
945 * on the compare_instr's result.
946 */
947static bool
948ntq_emit_comparison(struct vc4_compile *c, struct qreg *dest,
949                    nir_alu_instr *compare_instr,
950                    nir_alu_instr *sel_instr)
951{
952        enum qpu_cond cond;
953
954        switch (compare_instr->op) {
955        case nir_op_feq32:
956        case nir_op_ieq32:
957        case nir_op_seq:
958                cond = QPU_COND_ZS;
959                break;
960        case nir_op_fne32:
961        case nir_op_ine32:
962        case nir_op_sne:
963                cond = QPU_COND_ZC;
964                break;
965        case nir_op_fge32:
966        case nir_op_ige32:
967        case nir_op_uge32:
968        case nir_op_sge:
969                cond = QPU_COND_NC;
970                break;
971        case nir_op_flt32:
972        case nir_op_ilt32:
973        case nir_op_slt:
974                cond = QPU_COND_NS;
975                break;
976        default:
977                return false;
978        }
979
980        struct qreg src0 = ntq_get_alu_src(c, compare_instr, 0);
981        struct qreg src1 = ntq_get_alu_src(c, compare_instr, 1);
982
983        unsigned unsized_type =
984                nir_alu_type_get_base_type(nir_op_infos[compare_instr->op].input_types[0]);
985        if (unsized_type == nir_type_float)
986                qir_SF(c, qir_FSUB(c, src0, src1));
987        else
988                qir_SF(c, qir_SUB(c, src0, src1));
989
990        switch (sel_instr->op) {
991        case nir_op_seq:
992        case nir_op_sne:
993        case nir_op_sge:
994        case nir_op_slt:
995                *dest = qir_SEL(c, cond,
996                                qir_uniform_f(c, 1.0), qir_uniform_f(c, 0.0));
997                break;
998
999        case nir_op_b32csel:
1000                *dest = qir_SEL(c, cond,
1001                                ntq_get_alu_src(c, sel_instr, 1),
1002                                ntq_get_alu_src(c, sel_instr, 2));
1003                break;
1004
1005        default:
1006                *dest = qir_SEL(c, cond,
1007                                qir_uniform_ui(c, ~0), qir_uniform_ui(c, 0));
1008                break;
1009        }
1010
1011        /* Make the temporary for nir_store_dest(). */
1012        *dest = qir_MOV(c, *dest);
1013
1014        return true;
1015}
1016
1017/**
1018 * Attempts to fold a comparison generating a boolean result into the
1019 * condition code for selecting between two values, instead of comparing the
1020 * boolean result against 0 to generate the condition code.
1021 */
1022static struct qreg ntq_emit_bcsel(struct vc4_compile *c, nir_alu_instr *instr,
1023                                  struct qreg *src)
1024{
1025        if (!instr->src[0].src.is_ssa)
1026                goto out;
1027        if (instr->src[0].src.ssa->parent_instr->type != nir_instr_type_alu)
1028                goto out;
1029        nir_alu_instr *compare =
1030                nir_instr_as_alu(instr->src[0].src.ssa->parent_instr);
1031        if (!compare)
1032                goto out;
1033
1034        struct qreg dest;
1035        if (ntq_emit_comparison(c, &dest, compare, instr))
1036                return dest;
1037
1038out:
1039        qir_SF(c, src[0]);
1040        return qir_MOV(c, qir_SEL(c, QPU_COND_NS, src[1], src[2]));
1041}
1042
1043static struct qreg
1044ntq_fddx(struct vc4_compile *c, struct qreg src)
1045{
1046        /* Make sure that we have a bare temp to use for MUL rotation, so it
1047         * can be allocated to an accumulator.
1048         */
1049        if (src.pack || src.file != QFILE_TEMP)
1050                src = qir_MOV(c, src);
1051
1052        struct qreg from_left = qir_ROT_MUL(c, src, 1);
1053        struct qreg from_right = qir_ROT_MUL(c, src, 15);
1054
1055        /* Distinguish left/right pixels of the quad. */
1056        qir_SF(c, qir_AND(c, qir_reg(QFILE_QPU_ELEMENT, 0),
1057                          qir_uniform_ui(c, 1)));
1058
1059        return qir_MOV(c, qir_SEL(c, QPU_COND_ZS,
1060                                  qir_FSUB(c, from_right, src),
1061                                  qir_FSUB(c, src, from_left)));
1062}
1063
1064static struct qreg
1065ntq_fddy(struct vc4_compile *c, struct qreg src)
1066{
1067        if (src.pack || src.file != QFILE_TEMP)
1068                src = qir_MOV(c, src);
1069
1070        struct qreg from_bottom = qir_ROT_MUL(c, src, 2);
1071        struct qreg from_top = qir_ROT_MUL(c, src, 14);
1072
1073        /* Distinguish top/bottom pixels of the quad. */
1074        qir_SF(c, qir_AND(c,
1075                          qir_reg(QFILE_QPU_ELEMENT, 0),
1076                          qir_uniform_ui(c, 2)));
1077
1078        return qir_MOV(c, qir_SEL(c, QPU_COND_ZS,
1079                                  qir_FSUB(c, from_top, src),
1080                                  qir_FSUB(c, src, from_bottom)));
1081}
1082
1083static void
1084ntq_emit_alu(struct vc4_compile *c, nir_alu_instr *instr)
1085{
1086        /* This should always be lowered to ALU operations for VC4. */
1087        assert(!instr->dest.saturate);
1088
1089        /* Vectors are special in that they have non-scalarized writemasks,
1090         * and just take the first swizzle channel for each argument in order
1091         * into each writemask channel.
1092         */
1093        if (instr->op == nir_op_vec2 ||
1094            instr->op == nir_op_vec3 ||
1095            instr->op == nir_op_vec4) {
1096                struct qreg srcs[4];
1097                for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
1098                        srcs[i] = ntq_get_src(c, instr->src[i].src,
1099                                              instr->src[i].swizzle[0]);
1100                for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
1101                        ntq_store_dest(c, &instr->dest.dest, i,
1102                                       qir_MOV(c, srcs[i]));
1103                return;
1104        }
1105
1106        if (instr->op == nir_op_pack_unorm_4x8) {
1107                ntq_emit_pack_unorm_4x8(c, instr);
1108                return;
1109        }
1110
1111        if (instr->op == nir_op_unpack_unorm_4x8) {
1112                struct qreg src = ntq_get_src(c, instr->src[0].src,
1113                                              instr->src[0].swizzle[0]);
1114                for (int i = 0; i < 4; i++) {
1115                        if (instr->dest.write_mask & (1 << i))
1116                                ntq_store_dest(c, &instr->dest.dest, i,
1117                                               qir_UNPACK_8_F(c, src, i));
1118                }
1119                return;
1120        }
1121
1122        /* General case: We can just grab the one used channel per src. */
1123        struct qreg src[nir_op_infos[instr->op].num_inputs];
1124        for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
1125                src[i] = ntq_get_alu_src(c, instr, i);
1126        }
1127
1128        struct qreg result;
1129
1130        switch (instr->op) {
1131        case nir_op_fmov:
1132        case nir_op_imov:
1133                result = qir_MOV(c, src[0]);
1134                break;
1135        case nir_op_fmul:
1136                result = qir_FMUL(c, src[0], src[1]);
1137                break;
1138        case nir_op_fadd:
1139                result = qir_FADD(c, src[0], src[1]);
1140                break;
1141        case nir_op_fsub:
1142                result = qir_FSUB(c, src[0], src[1]);
1143                break;
1144        case nir_op_fmin:
1145                result = qir_FMIN(c, src[0], src[1]);
1146                break;
1147        case nir_op_fmax:
1148                result = qir_FMAX(c, src[0], src[1]);
1149                break;
1150
1151        case nir_op_f2i32:
1152        case nir_op_f2u32:
1153                result = qir_FTOI(c, src[0]);
1154                break;
1155        case nir_op_i2f32:
1156        case nir_op_u2f32:
1157                result = qir_ITOF(c, src[0]);
1158                break;
1159        case nir_op_b2f32:
1160                result = qir_AND(c, src[0], qir_uniform_f(c, 1.0));
1161                break;
1162        case nir_op_b2i32:
1163                result = qir_AND(c, src[0], qir_uniform_ui(c, 1));
1164                break;
1165        case nir_op_i2b32:
1166        case nir_op_f2b32:
1167                qir_SF(c, src[0]);
1168                result = qir_MOV(c, qir_SEL(c, QPU_COND_ZC,
1169                                            qir_uniform_ui(c, ~0),
1170                                            qir_uniform_ui(c, 0)));
1171                break;
1172
1173        case nir_op_iadd:
1174                result = qir_ADD(c, src[0], src[1]);
1175                break;
1176        case nir_op_ushr:
1177                result = qir_SHR(c, src[0], src[1]);
1178                break;
1179        case nir_op_isub:
1180                result = qir_SUB(c, src[0], src[1]);
1181                break;
1182        case nir_op_ishr:
1183                result = qir_ASR(c, src[0], src[1]);
1184                break;
1185        case nir_op_ishl:
1186                result = qir_SHL(c, src[0], src[1]);
1187                break;
1188        case nir_op_imin:
1189                result = qir_MIN(c, src[0], src[1]);
1190                break;
1191        case nir_op_imax:
1192                result = qir_MAX(c, src[0], src[1]);
1193                break;
1194        case nir_op_iand:
1195                result = qir_AND(c, src[0], src[1]);
1196                break;
1197        case nir_op_ior:
1198                result = qir_OR(c, src[0], src[1]);
1199                break;
1200        case nir_op_ixor:
1201                result = qir_XOR(c, src[0], src[1]);
1202                break;
1203        case nir_op_inot:
1204                result = qir_NOT(c, src[0]);
1205                break;
1206
1207        case nir_op_imul:
1208                result = ntq_umul(c, src[0], src[1]);
1209                break;
1210
1211        case nir_op_seq:
1212        case nir_op_sne:
1213        case nir_op_sge:
1214        case nir_op_slt:
1215        case nir_op_feq32:
1216        case nir_op_fne32:
1217        case nir_op_fge32:
1218        case nir_op_flt32:
1219        case nir_op_ieq32:
1220        case nir_op_ine32:
1221        case nir_op_ige32:
1222        case nir_op_uge32:
1223        case nir_op_ilt32:
1224                if (!ntq_emit_comparison(c, &result, instr, instr)) {
1225                        fprintf(stderr, "Bad comparison instruction\n");
1226                }
1227                break;
1228
1229        case nir_op_b32csel:
1230                result = ntq_emit_bcsel(c, instr, src);
1231                break;
1232        case nir_op_fcsel:
1233                qir_SF(c, src[0]);
1234                result = qir_MOV(c, qir_SEL(c, QPU_COND_ZC, src[1], src[2]));
1235                break;
1236
1237        case nir_op_frcp:
1238                result = ntq_rcp(c, src[0]);
1239                break;
1240        case nir_op_frsq:
1241                result = ntq_rsq(c, src[0]);
1242                break;
1243        case nir_op_fexp2:
1244                result = qir_EXP2(c, src[0]);
1245                break;
1246        case nir_op_flog2:
1247                result = qir_LOG2(c, src[0]);
1248                break;
1249
1250        case nir_op_ftrunc:
1251                result = qir_ITOF(c, qir_FTOI(c, src[0]));
1252                break;
1253        case nir_op_fceil:
1254                result = ntq_fceil(c, src[0]);
1255                break;
1256        case nir_op_ffract:
1257                result = ntq_ffract(c, src[0]);
1258                break;
1259        case nir_op_ffloor:
1260                result = ntq_ffloor(c, src[0]);
1261                break;
1262
1263        case nir_op_fsin:
1264                result = ntq_fsin(c, src[0]);
1265                break;
1266        case nir_op_fcos:
1267                result = ntq_fcos(c, src[0]);
1268                break;
1269
1270        case nir_op_fsign:
1271                result = ntq_fsign(c, src[0]);
1272                break;
1273
1274        case nir_op_fabs:
1275                result = qir_FMAXABS(c, src[0], src[0]);
1276                break;
1277        case nir_op_iabs:
1278                result = qir_MAX(c, src[0],
1279                                qir_SUB(c, qir_uniform_ui(c, 0), src[0]));
1280                break;
1281
1282        case nir_op_ibitfield_extract:
1283                result = ntq_emit_ibfe(c, src[0], src[1], src[2]);
1284                break;
1285
1286        case nir_op_ubitfield_extract:
1287                result = ntq_emit_ubfe(c, src[0], src[1], src[2]);
1288                break;
1289
1290        case nir_op_usadd_4x8:
1291                result = qir_V8ADDS(c, src[0], src[1]);
1292                break;
1293
1294        case nir_op_ussub_4x8:
1295                result = qir_V8SUBS(c, src[0], src[1]);
1296                break;
1297
1298        case nir_op_umin_4x8:
1299                result = qir_V8MIN(c, src[0], src[1]);
1300                break;
1301
1302        case nir_op_umax_4x8:
1303                result = qir_V8MAX(c, src[0], src[1]);
1304                break;
1305
1306        case nir_op_umul_unorm_4x8:
1307                result = qir_V8MULD(c, src[0], src[1]);
1308                break;
1309
1310        case nir_op_fddx:
1311        case nir_op_fddx_coarse:
1312        case nir_op_fddx_fine:
1313                result = ntq_fddx(c, src[0]);
1314                break;
1315
1316        case nir_op_fddy:
1317        case nir_op_fddy_coarse:
1318        case nir_op_fddy_fine:
1319                result = ntq_fddy(c, src[0]);
1320                break;
1321
1322        default:
1323                fprintf(stderr, "unknown NIR ALU inst: ");
1324                nir_print_instr(&instr->instr, stderr);
1325                fprintf(stderr, "\n");
1326                abort();
1327        }
1328
1329        /* We have a scalar result, so the instruction should only have a
1330         * single channel written to.
1331         */
1332        assert(util_is_power_of_two_or_zero(instr->dest.write_mask));
1333        ntq_store_dest(c, &instr->dest.dest,
1334                       ffs(instr->dest.write_mask) - 1, result);
1335}
1336
1337static void
1338emit_frag_end(struct vc4_compile *c)
1339{
1340        struct qreg color;
1341        if (c->output_color_index != -1) {
1342                color = c->outputs[c->output_color_index];
1343        } else {
1344                color = qir_uniform_ui(c, 0);
1345        }
1346
1347        uint32_t discard_cond = QPU_COND_ALWAYS;
1348        if (c->s->info.fs.uses_discard) {
1349                qir_SF(c, c->discard);
1350                discard_cond = QPU_COND_ZS;
1351        }
1352
1353        if (c->fs_key->stencil_enabled) {
1354                qir_MOV_dest(c, qir_reg(QFILE_TLB_STENCIL_SETUP, 0),
1355                             qir_uniform(c, QUNIFORM_STENCIL, 0));
1356                if (c->fs_key->stencil_twoside) {
1357                        qir_MOV_dest(c, qir_reg(QFILE_TLB_STENCIL_SETUP, 0),
1358                                     qir_uniform(c, QUNIFORM_STENCIL, 1));
1359                }
1360                if (c->fs_key->stencil_full_writemasks) {
1361                        qir_MOV_dest(c, qir_reg(QFILE_TLB_STENCIL_SETUP, 0),
1362                                     qir_uniform(c, QUNIFORM_STENCIL, 2));
1363                }
1364        }
1365
1366        if (c->output_sample_mask_index != -1) {
1367                qir_MS_MASK(c, c->outputs[c->output_sample_mask_index]);
1368        }
1369
1370        if (c->fs_key->depth_enabled) {
1371                if (c->output_position_index != -1) {
1372                        qir_FTOI_dest(c, qir_reg(QFILE_TLB_Z_WRITE, 0),
1373                                      qir_FMUL(c,
1374                                               c->outputs[c->output_position_index],
1375                                               qir_uniform_f(c, 0xffffff)))->cond = discard_cond;
1376                } else {
1377                        qir_MOV_dest(c, qir_reg(QFILE_TLB_Z_WRITE, 0),
1378                                     qir_FRAG_Z(c))->cond = discard_cond;
1379                }
1380        }
1381
1382        if (!c->msaa_per_sample_output) {
1383                qir_MOV_dest(c, qir_reg(QFILE_TLB_COLOR_WRITE, 0),
1384                             color)->cond = discard_cond;
1385        } else {
1386                for (int i = 0; i < VC4_MAX_SAMPLES; i++) {
1387                        qir_MOV_dest(c, qir_reg(QFILE_TLB_COLOR_WRITE_MS, 0),
1388                                     c->sample_colors[i])->cond = discard_cond;
1389                }
1390        }
1391}
1392
1393static void
1394emit_scaled_viewport_write(struct vc4_compile *c, struct qreg rcp_w)
1395{
1396        struct qreg packed = qir_get_temp(c);
1397
1398        for (int i = 0; i < 2; i++) {
1399                struct qreg scale =
1400                        qir_uniform(c, QUNIFORM_VIEWPORT_X_SCALE + i, 0);
1401
1402                struct qreg packed_chan = packed;
1403                packed_chan.pack = QPU_PACK_A_16A + i;
1404
1405                qir_FTOI_dest(c, packed_chan,
1406                              qir_FMUL(c,
1407                                       qir_FMUL(c,
1408                                                c->outputs[c->output_position_index + i],
1409                                                scale),
1410                                       rcp_w));
1411        }
1412
1413        qir_VPM_WRITE(c, packed);
1414}
1415
1416static void
1417emit_zs_write(struct vc4_compile *c, struct qreg rcp_w)
1418{
1419        struct qreg zscale = qir_uniform(c, QUNIFORM_VIEWPORT_Z_SCALE, 0);
1420        struct qreg zoffset = qir_uniform(c, QUNIFORM_VIEWPORT_Z_OFFSET, 0);
1421
1422        qir_VPM_WRITE(c, qir_FADD(c, qir_FMUL(c, qir_FMUL(c,
1423                                                          c->outputs[c->output_position_index + 2],
1424                                                          zscale),
1425                                              rcp_w),
1426                                  zoffset));
1427}
1428
1429static void
1430emit_rcp_wc_write(struct vc4_compile *c, struct qreg rcp_w)
1431{
1432        qir_VPM_WRITE(c, rcp_w);
1433}
1434
1435static void
1436emit_point_size_write(struct vc4_compile *c)
1437{
1438        struct qreg point_size;
1439
1440        if (c->output_point_size_index != -1)
1441                point_size = c->outputs[c->output_point_size_index];
1442        else
1443                point_size = qir_uniform_f(c, 1.0);
1444
1445        /* Workaround: HW-2726 PTB does not handle zero-size points (BCM2835,
1446         * BCM21553).
1447         */
1448        point_size = qir_FMAX(c, point_size, qir_uniform_f(c, .125));
1449
1450        qir_VPM_WRITE(c, point_size);
1451}
1452
1453/**
1454 * Emits a VPM read of the stub vertex attribute set up by vc4_draw.c.
1455 *
1456 * The simulator insists that there be at least one vertex attribute, so
1457 * vc4_draw.c will emit one if it wouldn't have otherwise.  The simulator also
1458 * insists that all vertex attributes loaded get read by the VS/CS, so we have
1459 * to consume it here.
1460 */
1461static void
1462emit_stub_vpm_read(struct vc4_compile *c)
1463{
1464        if (c->num_inputs)
1465                return;
1466
1467        c->vattr_sizes[0] = 4;
1468        (void)qir_MOV(c, qir_reg(QFILE_VPM, 0));
1469        c->num_inputs++;
1470}
1471
1472static void
1473emit_vert_end(struct vc4_compile *c,
1474              struct vc4_varying_slot *fs_inputs,
1475              uint32_t num_fs_inputs)
1476{
1477        struct qreg rcp_w = ntq_rcp(c, c->outputs[c->output_position_index + 3]);
1478
1479        emit_stub_vpm_read(c);
1480
1481        emit_scaled_viewport_write(c, rcp_w);
1482        emit_zs_write(c, rcp_w);
1483        emit_rcp_wc_write(c, rcp_w);
1484        if (c->vs_key->per_vertex_point_size)
1485                emit_point_size_write(c);
1486
1487        for (int i = 0; i < num_fs_inputs; i++) {
1488                struct vc4_varying_slot *input = &fs_inputs[i];
1489                int j;
1490
1491                for (j = 0; j < c->num_outputs; j++) {
1492                        struct vc4_varying_slot *output =
1493                                &c->output_slots[j];
1494
1495                        if (input->slot == output->slot &&
1496                            input->swizzle == output->swizzle) {
1497                                qir_VPM_WRITE(c, c->outputs[j]);
1498                                break;
1499                        }
1500                }
1501                /* Emit padding if we didn't find a declared VS output for
1502                 * this FS input.
1503                 */
1504                if (j == c->num_outputs)
1505                        qir_VPM_WRITE(c, qir_uniform_f(c, 0.0));
1506        }
1507}
1508
1509static void
1510emit_coord_end(struct vc4_compile *c)
1511{
1512        struct qreg rcp_w = ntq_rcp(c, c->outputs[c->output_position_index + 3]);
1513
1514        emit_stub_vpm_read(c);
1515
1516        for (int i = 0; i < 4; i++)
1517                qir_VPM_WRITE(c, c->outputs[c->output_position_index + i]);
1518
1519        emit_scaled_viewport_write(c, rcp_w);
1520        emit_zs_write(c, rcp_w);
1521        emit_rcp_wc_write(c, rcp_w);
1522        if (c->vs_key->per_vertex_point_size)
1523                emit_point_size_write(c);
1524}
1525
1526static void
1527vc4_optimize_nir(struct nir_shader *s)
1528{
1529        bool progress;
1530
1531        do {
1532                progress = false;
1533
1534                NIR_PASS_V(s, nir_lower_vars_to_ssa);
1535                NIR_PASS(progress, s, nir_lower_alu_to_scalar);
1536                NIR_PASS(progress, s, nir_lower_phis_to_scalar);
1537                NIR_PASS(progress, s, nir_copy_prop);
1538                NIR_PASS(progress, s, nir_opt_remove_phis);
1539                NIR_PASS(progress, s, nir_opt_dce);
1540                NIR_PASS(progress, s, nir_opt_dead_cf);
1541                NIR_PASS(progress, s, nir_opt_cse);
1542                NIR_PASS(progress, s, nir_opt_peephole_select, 8, true, true);
1543                NIR_PASS(progress, s, nir_opt_algebraic);
1544                NIR_PASS(progress, s, nir_opt_constant_folding);
1545                NIR_PASS(progress, s, nir_opt_undef);
1546                NIR_PASS(progress, s, nir_opt_loop_unroll,
1547                         nir_var_shader_in |
1548                         nir_var_shader_out |
1549                         nir_var_function_temp);
1550        } while (progress);
1551}
1552
1553static int
1554driver_location_compare(const void *in_a, const void *in_b)
1555{
1556        const nir_variable *const *a = in_a;
1557        const nir_variable *const *b = in_b;
1558
1559        return (*a)->data.driver_location - (*b)->data.driver_location;
1560}
1561
1562static void
1563ntq_setup_inputs(struct vc4_compile *c)
1564{
1565        unsigned num_entries = 0;
1566        nir_foreach_variable(var, &c->s->inputs)
1567                num_entries++;
1568
1569        nir_variable *vars[num_entries];
1570
1571        unsigned i = 0;
1572        nir_foreach_variable(var, &c->s->inputs)
1573                vars[i++] = var;
1574
1575        /* Sort the variables so that we emit the input setup in
1576         * driver_location order.  This is required for VPM reads, whose data
1577         * is fetched into the VPM in driver_location (TGSI register index)
1578         * order.
1579         */
1580        qsort(&vars, num_entries, sizeof(*vars), driver_location_compare);
1581
1582        for (unsigned i = 0; i < num_entries; i++) {
1583                nir_variable *var = vars[i];
1584                unsigned array_len = MAX2(glsl_get_length(var->type), 1);
1585                unsigned loc = var->data.driver_location;
1586
1587                assert(array_len == 1);
1588                (void)array_len;
1589                resize_qreg_array(c, &c->inputs, &c->inputs_array_size,
1590                                  (loc + 1) * 4);
1591
1592                if (c->stage == QSTAGE_FRAG) {
1593                        if (var->data.location == VARYING_SLOT_POS) {
1594                                emit_fragcoord_input(c, loc);
1595                        } else if (var->data.location == VARYING_SLOT_PNTC ||
1596                                   (var->data.location >= VARYING_SLOT_VAR0 &&
1597                                    (c->fs_key->point_sprite_mask &
1598                                     (1 << (var->data.location -
1599                                            VARYING_SLOT_VAR0))))) {
1600                                c->inputs[loc * 4 + 0] = c->point_x;
1601                                c->inputs[loc * 4 + 1] = c->point_y;
1602                        } else {
1603                                emit_fragment_input(c, loc, var->data.location);
1604                        }
1605                } else {
1606                        emit_vertex_input(c, loc);
1607                }
1608        }
1609}
1610
1611static void
1612ntq_setup_outputs(struct vc4_compile *c)
1613{
1614        nir_foreach_variable(var, &c->s->outputs) {
1615                unsigned array_len = MAX2(glsl_get_length(var->type), 1);
1616                unsigned loc = var->data.driver_location * 4;
1617
1618                assert(array_len == 1);
1619                (void)array_len;
1620
1621                for (int i = 0; i < 4; i++)
1622                        add_output(c, loc + i, var->data.location, i);
1623
1624                if (c->stage == QSTAGE_FRAG) {
1625                        switch (var->data.location) {
1626                        case FRAG_RESULT_COLOR:
1627                        case FRAG_RESULT_DATA0:
1628                                c->output_color_index = loc;
1629                                break;
1630                        case FRAG_RESULT_DEPTH:
1631                                c->output_position_index = loc;
1632                                break;
1633                        case FRAG_RESULT_SAMPLE_MASK:
1634                                c->output_sample_mask_index = loc;
1635                                break;
1636                        }
1637                } else {
1638                        switch (var->data.location) {
1639                        case VARYING_SLOT_POS:
1640                                c->output_position_index = loc;
1641                                break;
1642                        case VARYING_SLOT_PSIZ:
1643                                c->output_point_size_index = loc;
1644                                break;
1645                        }
1646                }
1647        }
1648}
1649
1650/**
1651 * Sets up the mapping from nir_register to struct qreg *.
1652 *
1653 * Each nir_register gets a struct qreg per 32-bit component being stored.
1654 */
1655static void
1656ntq_setup_registers(struct vc4_compile *c, struct exec_list *list)
1657{
1658        foreach_list_typed(nir_register, nir_reg, node, list) {
1659                unsigned array_len = MAX2(nir_reg->num_array_elems, 1);
1660                struct qreg *qregs = ralloc_array(c->def_ht, struct qreg,
1661                                                  array_len *
1662                                                  nir_reg->num_components);
1663
1664                _mesa_hash_table_insert(c->def_ht, nir_reg, qregs);
1665
1666                for (int i = 0; i < array_len * nir_reg->num_components; i++)
1667                        qregs[i] = qir_get_temp(c);
1668        }
1669}
1670
1671static void
1672ntq_emit_load_const(struct vc4_compile *c, nir_load_const_instr *instr)
1673{
1674        struct qreg *qregs = ntq_init_ssa_def(c, &instr->def);
1675        for (int i = 0; i < instr->def.num_components; i++)
1676                qregs[i] = qir_uniform_ui(c, instr->value[i].u32);
1677
1678        _mesa_hash_table_insert(c->def_ht, &instr->def, qregs);
1679}
1680
1681static void
1682ntq_emit_ssa_undef(struct vc4_compile *c, nir_ssa_undef_instr *instr)
1683{
1684        struct qreg *qregs = ntq_init_ssa_def(c, &instr->def);
1685
1686        /* QIR needs there to be *some* value, so pick 0 (same as for
1687         * ntq_setup_registers().
1688         */
1689        for (int i = 0; i < instr->def.num_components; i++)
1690                qregs[i] = qir_uniform_ui(c, 0);
1691}
1692
1693static void
1694ntq_emit_color_read(struct vc4_compile *c, nir_intrinsic_instr *instr)
1695{
1696        assert(nir_src_as_uint(instr->src[0]) == 0);
1697
1698        /* Reads of the per-sample color need to be done in
1699         * order.
1700         */
1701        int sample_index = (nir_intrinsic_base(instr) -
1702                            VC4_NIR_TLB_COLOR_READ_INPUT);
1703        for (int i = 0; i <= sample_index; i++) {
1704                if (c->color_reads[i].file == QFILE_NULL) {
1705                        c->color_reads[i] =
1706                                qir_TLB_COLOR_READ(c);
1707                }
1708        }
1709        ntq_store_dest(c, &instr->dest, 0,
1710                       qir_MOV(c, c->color_reads[sample_index]));
1711}
1712
1713static void
1714ntq_emit_load_input(struct vc4_compile *c, nir_intrinsic_instr *instr)
1715{
1716        assert(instr->num_components == 1);
1717        assert(nir_src_is_const(instr->src[0]) &&
1718               "vc4 doesn't support indirect inputs");
1719
1720        if (c->stage == QSTAGE_FRAG &&
1721            nir_intrinsic_base(instr) >= VC4_NIR_TLB_COLOR_READ_INPUT) {
1722                ntq_emit_color_read(c, instr);
1723                return;
1724        }
1725
1726        uint32_t offset = nir_intrinsic_base(instr) +
1727                          nir_src_as_uint(instr->src[0]);
1728        int comp = nir_intrinsic_component(instr);
1729        ntq_store_dest(c, &instr->dest, 0,
1730                       qir_MOV(c, c->inputs[offset * 4 + comp]));
1731}
1732
1733static void
1734ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
1735{
1736        unsigned offset;
1737
1738        switch (instr->intrinsic) {
1739        case nir_intrinsic_load_uniform:
1740                assert(instr->num_components == 1);
1741                if (nir_src_is_const(instr->src[0])) {
1742                        offset = nir_intrinsic_base(instr) +
1743                                 nir_src_as_uint(instr->src[0]);
1744                        assert(offset % 4 == 0);
1745                        /* We need dwords */
1746                        offset = offset / 4;
1747                        ntq_store_dest(c, &instr->dest, 0,
1748                                       qir_uniform(c, QUNIFORM_UNIFORM,
1749                                                   offset));
1750                } else {
1751                        ntq_store_dest(c, &instr->dest, 0,
1752                                       indirect_uniform_load(c, instr));
1753                }
1754                break;
1755
1756        case nir_intrinsic_load_ubo:
1757                assert(instr->num_components == 1);
1758                ntq_store_dest(c, &instr->dest, 0, vc4_ubo_load(c, instr));
1759                break;
1760
1761        case nir_intrinsic_load_user_clip_plane:
1762                for (int i = 0; i < instr->num_components; i++) {
1763                        ntq_store_dest(c, &instr->dest, i,
1764                                       qir_uniform(c, QUNIFORM_USER_CLIP_PLANE,
1765                                                   nir_intrinsic_ucp_id(instr) *
1766                                                   4 + i));
1767                }
1768                break;
1769
1770        case nir_intrinsic_load_blend_const_color_r_float:
1771        case nir_intrinsic_load_blend_const_color_g_float:
1772        case nir_intrinsic_load_blend_const_color_b_float:
1773        case nir_intrinsic_load_blend_const_color_a_float:
1774                ntq_store_dest(c, &instr->dest, 0,
1775                               qir_uniform(c, QUNIFORM_BLEND_CONST_COLOR_X +
1776                                           (instr->intrinsic -
1777                                            nir_intrinsic_load_blend_const_color_r_float),
1778                                           0));
1779                break;
1780
1781        case nir_intrinsic_load_blend_const_color_rgba8888_unorm:
1782                ntq_store_dest(c, &instr->dest, 0,
1783                               qir_uniform(c, QUNIFORM_BLEND_CONST_COLOR_RGBA,
1784                                           0));
1785                break;
1786
1787        case nir_intrinsic_load_blend_const_color_aaaa8888_unorm:
1788                ntq_store_dest(c, &instr->dest, 0,
1789                               qir_uniform(c, QUNIFORM_BLEND_CONST_COLOR_AAAA,
1790                                           0));
1791                break;
1792
1793        case nir_intrinsic_load_alpha_ref_float:
1794                ntq_store_dest(c, &instr->dest, 0,
1795                               qir_uniform(c, QUNIFORM_ALPHA_REF, 0));
1796                break;
1797
1798        case nir_intrinsic_load_sample_mask_in:
1799                ntq_store_dest(c, &instr->dest, 0,
1800                               qir_uniform(c, QUNIFORM_SAMPLE_MASK, 0));
1801                break;
1802
1803        case nir_intrinsic_load_front_face:
1804                /* The register contains 0 (front) or 1 (back), and we need to
1805                 * turn it into a NIR bool where true means front.
1806                 */
1807                ntq_store_dest(c, &instr->dest, 0,
1808                               qir_ADD(c,
1809                                       qir_uniform_ui(c, -1),
1810                                       qir_reg(QFILE_FRAG_REV_FLAG, 0)));
1811                break;
1812
1813        case nir_intrinsic_load_input:
1814                ntq_emit_load_input(c, instr);
1815                break;
1816
1817        case nir_intrinsic_store_output:
1818                assert(nir_src_is_const(instr->src[1]) &&
1819                       "vc4 doesn't support indirect outputs");
1820                offset = nir_intrinsic_base(instr) +
1821                         nir_src_as_uint(instr->src[1]);
1822
1823                /* MSAA color outputs are the only case where we have an
1824                 * output that's not lowered to being a store of a single 32
1825                 * bit value.
1826                 */
1827                if (c->stage == QSTAGE_FRAG && instr->num_components == 4) {
1828                        assert(offset == c->output_color_index);
1829                        for (int i = 0; i < 4; i++) {
1830                                c->sample_colors[i] =
1831                                        qir_MOV(c, ntq_get_src(c, instr->src[0],
1832                                                               i));
1833                        }
1834                } else {
1835                        offset = offset * 4 + nir_intrinsic_component(instr);
1836                        assert(instr->num_components == 1);
1837                        c->outputs[offset] =
1838                                qir_MOV(c, ntq_get_src(c, instr->src[0], 0));
1839                        c->num_outputs = MAX2(c->num_outputs, offset + 1);
1840                }
1841                break;
1842
1843        case nir_intrinsic_discard:
1844                if (c->execute.file != QFILE_NULL) {
1845                        qir_SF(c, c->execute);
1846                        qir_MOV_cond(c, QPU_COND_ZS, c->discard,
1847                                     qir_uniform_ui(c, ~0));
1848                } else {
1849                        qir_MOV_dest(c, c->discard, qir_uniform_ui(c, ~0));
1850                }
1851                break;
1852
1853        case nir_intrinsic_discard_if: {
1854                /* true (~0) if we're discarding */
1855                struct qreg cond = ntq_get_src(c, instr->src[0], 0);
1856
1857                if (c->execute.file != QFILE_NULL) {
1858                        /* execute == 0 means the channel is active.  Invert
1859                         * the condition so that we can use zero as "executing
1860                         * and discarding."
1861                         */
1862                        qir_SF(c, qir_AND(c, c->execute, qir_NOT(c, cond)));
1863                        qir_MOV_cond(c, QPU_COND_ZS, c->discard, cond);
1864                } else {
1865                        qir_OR_dest(c, c->discard, c->discard,
1866                                    ntq_get_src(c, instr->src[0], 0));
1867                }
1868
1869                break;
1870        }
1871
1872        default:
1873                fprintf(stderr, "Unknown intrinsic: ");
1874                nir_print_instr(&instr->instr, stderr);
1875                fprintf(stderr, "\n");
1876                break;
1877        }
1878}
1879
1880/* Clears (activates) the execute flags for any channels whose jump target
1881 * matches this block.
1882 */
1883static void
1884ntq_activate_execute_for_block(struct vc4_compile *c)
1885{
1886        qir_SF(c, qir_SUB(c,
1887                          c->execute,
1888                          qir_uniform_ui(c, c->cur_block->index)));
1889        qir_MOV_cond(c, QPU_COND_ZS, c->execute, qir_uniform_ui(c, 0));
1890}
1891
1892static void
1893ntq_emit_if(struct vc4_compile *c, nir_if *if_stmt)
1894{
1895        if (!c->vc4->screen->has_control_flow) {
1896                fprintf(stderr,
1897                        "IF statement support requires updated kernel.\n");
1898                return;
1899        }
1900
1901        nir_block *nir_else_block = nir_if_first_else_block(if_stmt);
1902        bool empty_else_block =
1903                (nir_else_block == nir_if_last_else_block(if_stmt) &&
1904                 exec_list_is_empty(&nir_else_block->instr_list));
1905
1906        struct qblock *then_block = qir_new_block(c);
1907        struct qblock *after_block = qir_new_block(c);
1908        struct qblock *else_block;
1909        if (empty_else_block)
1910                else_block = after_block;
1911        else
1912                else_block = qir_new_block(c);
1913
1914        bool was_top_level = false;
1915        if (c->execute.file == QFILE_NULL) {
1916                c->execute = qir_MOV(c, qir_uniform_ui(c, 0));
1917                was_top_level = true;
1918        }
1919
1920        /* Set ZS for executing (execute == 0) and jumping (if->condition ==
1921         * 0) channels, and then update execute flags for those to point to
1922         * the ELSE block.
1923         */
1924        qir_SF(c, qir_OR(c,
1925                         c->execute,
1926                         ntq_get_src(c, if_stmt->condition, 0)));
1927        qir_MOV_cond(c, QPU_COND_ZS, c->execute,
1928                     qir_uniform_ui(c, else_block->index));
1929
1930        /* Jump to ELSE if nothing is active for THEN, otherwise fall
1931         * through.
1932         */
1933        qir_SF(c, c->execute);
1934        qir_BRANCH(c, QPU_COND_BRANCH_ALL_ZC);
1935        qir_link_blocks(c->cur_block, else_block);
1936        qir_link_blocks(c->cur_block, then_block);
1937
1938        /* Process the THEN block. */
1939        qir_set_emit_block(c, then_block);
1940        ntq_emit_cf_list(c, &if_stmt->then_list);
1941
1942        if (!empty_else_block) {
1943                /* Handle the end of the THEN block.  First, all currently
1944                 * active channels update their execute flags to point to
1945                 * ENDIF
1946                 */
1947                qir_SF(c, c->execute);
1948                qir_MOV_cond(c, QPU_COND_ZS, c->execute,
1949                             qir_uniform_ui(c, after_block->index));
1950
1951                /* If everything points at ENDIF, then jump there immediately. */
1952                qir_SF(c, qir_SUB(c, c->execute, qir_uniform_ui(c, after_block->index)));
1953                qir_BRANCH(c, QPU_COND_BRANCH_ALL_ZS);
1954                qir_link_blocks(c->cur_block, after_block);
1955                qir_link_blocks(c->cur_block, else_block);
1956
1957                qir_set_emit_block(c, else_block);
1958                ntq_activate_execute_for_block(c);
1959                ntq_emit_cf_list(c, &if_stmt->else_list);
1960        }
1961
1962        qir_link_blocks(c->cur_block, after_block);
1963
1964        qir_set_emit_block(c, after_block);
1965        if (was_top_level) {
1966                c->execute = c->undef;
1967                c->last_top_block = c->cur_block;
1968        } else {
1969                ntq_activate_execute_for_block(c);
1970        }
1971}
1972
1973static void
1974ntq_emit_jump(struct vc4_compile *c, nir_jump_instr *jump)
1975{
1976        struct qblock *jump_block;
1977        switch (jump->type) {
1978        case nir_jump_break:
1979                jump_block = c->loop_break_block;
1980                break;
1981        case nir_jump_continue:
1982                jump_block = c->loop_cont_block;
1983                break;
1984        default:
1985                unreachable("Unsupported jump type\n");
1986        }
1987
1988        qir_SF(c, c->execute);
1989        qir_MOV_cond(c, QPU_COND_ZS, c->execute,
1990                     qir_uniform_ui(c, jump_block->index));
1991
1992        /* Jump to the destination block if everyone has taken the jump. */
1993        qir_SF(c, qir_SUB(c, c->execute, qir_uniform_ui(c, jump_block->index)));
1994        qir_BRANCH(c, QPU_COND_BRANCH_ALL_ZS);
1995        struct qblock *new_block = qir_new_block(c);
1996        qir_link_blocks(c->cur_block, jump_block);
1997        qir_link_blocks(c->cur_block, new_block);
1998        qir_set_emit_block(c, new_block);
1999}
2000
2001static void
2002ntq_emit_instr(struct vc4_compile *c, nir_instr *instr)
2003{
2004        switch (instr->type) {
2005        case nir_instr_type_alu:
2006                ntq_emit_alu(c, nir_instr_as_alu(instr));
2007                break;
2008
2009        case nir_instr_type_intrinsic:
2010                ntq_emit_intrinsic(c, nir_instr_as_intrinsic(instr));
2011                break;
2012
2013        case nir_instr_type_load_const:
2014                ntq_emit_load_const(c, nir_instr_as_load_const(instr));
2015                break;
2016
2017        case nir_instr_type_ssa_undef:
2018                ntq_emit_ssa_undef(c, nir_instr_as_ssa_undef(instr));
2019                break;
2020
2021        case nir_instr_type_tex:
2022                ntq_emit_tex(c, nir_instr_as_tex(instr));
2023                break;
2024
2025        case nir_instr_type_jump:
2026                ntq_emit_jump(c, nir_instr_as_jump(instr));
2027                break;
2028
2029        default:
2030                fprintf(stderr, "Unknown NIR instr type: ");
2031                nir_print_instr(instr, stderr);
2032                fprintf(stderr, "\n");
2033                abort();
2034        }
2035}
2036
2037static void
2038ntq_emit_block(struct vc4_compile *c, nir_block *block)
2039{
2040        nir_foreach_instr(instr, block) {
2041                ntq_emit_instr(c, instr);
2042        }
2043}
2044
2045static void ntq_emit_cf_list(struct vc4_compile *c, struct exec_list *list);
2046
2047static void
2048ntq_emit_loop(struct vc4_compile *c, nir_loop *loop)
2049{
2050        if (!c->vc4->screen->has_control_flow) {
2051                fprintf(stderr,
2052                        "loop support requires updated kernel.\n");
2053                ntq_emit_cf_list(c, &loop->body);
2054                return;
2055        }
2056
2057        bool was_top_level = false;
2058        if (c->execute.file == QFILE_NULL) {
2059                c->execute = qir_MOV(c, qir_uniform_ui(c, 0));
2060                was_top_level = true;
2061        }
2062
2063        struct qblock *save_loop_cont_block = c->loop_cont_block;
2064        struct qblock *save_loop_break_block = c->loop_break_block;
2065
2066        c->loop_cont_block = qir_new_block(c);
2067        c->loop_break_block = qir_new_block(c);
2068
2069        qir_link_blocks(c->cur_block, c->loop_cont_block);
2070        qir_set_emit_block(c, c->loop_cont_block);
2071        ntq_activate_execute_for_block(c);
2072
2073        ntq_emit_cf_list(c, &loop->body);
2074
2075        /* If anything had explicitly continued, or is here at the end of the
2076         * loop, then we need to loop again.  SF updates are masked by the
2077         * instruction's condition, so we can do the OR of the two conditions
2078         * within SF.
2079         */
2080        qir_SF(c, c->execute);
2081        struct qinst *cont_check =
2082                qir_SUB_dest(c,
2083                             c->undef,
2084                             c->execute,
2085                             qir_uniform_ui(c, c->loop_cont_block->index));
2086        cont_check->cond = QPU_COND_ZC;
2087        cont_check->sf = true;
2088
2089        qir_BRANCH(c, QPU_COND_BRANCH_ANY_ZS);
2090        qir_link_blocks(c->cur_block, c->loop_cont_block);
2091        qir_link_blocks(c->cur_block, c->loop_break_block);
2092
2093        qir_set_emit_block(c, c->loop_break_block);
2094        if (was_top_level) {
2095                c->execute = c->undef;
2096                c->last_top_block = c->cur_block;
2097        } else {
2098                ntq_activate_execute_for_block(c);
2099        }
2100
2101        c->loop_break_block = save_loop_break_block;
2102        c->loop_cont_block = save_loop_cont_block;
2103}
2104
2105static void
2106ntq_emit_function(struct vc4_compile *c, nir_function_impl *func)
2107{
2108        fprintf(stderr, "FUNCTIONS not handled.\n");
2109        abort();
2110}
2111
2112static void
2113ntq_emit_cf_list(struct vc4_compile *c, struct exec_list *list)
2114{
2115        foreach_list_typed(nir_cf_node, node, node, list) {
2116                switch (node->type) {
2117                case nir_cf_node_block:
2118                        ntq_emit_block(c, nir_cf_node_as_block(node));
2119                        break;
2120
2121                case nir_cf_node_if:
2122                        ntq_emit_if(c, nir_cf_node_as_if(node));
2123                        break;
2124
2125                case nir_cf_node_loop:
2126                        ntq_emit_loop(c, nir_cf_node_as_loop(node));
2127                        break;
2128
2129                case nir_cf_node_function:
2130                        ntq_emit_function(c, nir_cf_node_as_function(node));
2131                        break;
2132
2133                default:
2134                        fprintf(stderr, "Unknown NIR node type\n");
2135                        abort();
2136                }
2137        }
2138}
2139
2140static void
2141ntq_emit_impl(struct vc4_compile *c, nir_function_impl *impl)
2142{
2143        ntq_setup_registers(c, &impl->registers);
2144        ntq_emit_cf_list(c, &impl->body);
2145}
2146
2147static void
2148nir_to_qir(struct vc4_compile *c)
2149{
2150        if (c->stage == QSTAGE_FRAG && c->s->info.fs.uses_discard)
2151                c->discard = qir_MOV(c, qir_uniform_ui(c, 0));
2152
2153        ntq_setup_inputs(c);
2154        ntq_setup_outputs(c);
2155
2156        /* Find the main function and emit the body. */
2157        nir_foreach_function(function, c->s) {
2158                assert(strcmp(function->name, "main") == 0);
2159                assert(function->impl);
2160                ntq_emit_impl(c, function->impl);
2161        }
2162}
2163
2164static const nir_shader_compiler_options nir_options = {
2165        .lower_all_io_to_temps = true,
2166        .lower_extract_byte = true,
2167        .lower_extract_word = true,
2168        .lower_fdiv = true,
2169        .lower_ffma = true,
2170        .lower_flrp32 = true,
2171        .lower_fpow = true,
2172        .lower_fsat = true,
2173        .lower_fsqrt = true,
2174        .lower_ldexp = true,
2175        .lower_negate = true,
2176        .native_integers = true,
2177        .max_unroll_iterations = 32,
2178};
2179
2180const void *
2181vc4_screen_get_compiler_options(struct pipe_screen *pscreen,
2182                                enum pipe_shader_ir ir,
2183                                enum pipe_shader_type shader)
2184{
2185        return &nir_options;
2186}
2187
2188static int
2189count_nir_instrs(nir_shader *nir)
2190{
2191        int count = 0;
2192        nir_foreach_function(function, nir) {
2193                if (!function->impl)
2194                        continue;
2195                nir_foreach_block(block, function->impl) {
2196                        nir_foreach_instr(instr, block)
2197                                count++;
2198                }
2199        }
2200        return count;
2201}
2202
2203static struct vc4_compile *
2204vc4_shader_ntq(struct vc4_context *vc4, enum qstage stage,
2205               struct vc4_key *key, bool fs_threaded)
2206{
2207        struct vc4_compile *c = qir_compile_init();
2208
2209        c->vc4 = vc4;
2210        c->stage = stage;
2211        c->shader_state = &key->shader_state->base;
2212        c->program_id = key->shader_state->program_id;
2213        c->variant_id =
2214                p_atomic_inc_return(&key->shader_state->compiled_variant_count);
2215        c->fs_threaded = fs_threaded;
2216
2217        c->key = key;
2218        switch (stage) {
2219        case QSTAGE_FRAG:
2220                c->fs_key = (struct vc4_fs_key *)key;
2221                if (c->fs_key->is_points) {
2222                        c->point_x = emit_fragment_varying(c, ~0, 0);
2223                        c->point_y = emit_fragment_varying(c, ~0, 0);
2224                } else if (c->fs_key->is_lines) {
2225                        c->line_x = emit_fragment_varying(c, ~0, 0);
2226                }
2227                break;
2228        case QSTAGE_VERT:
2229                c->vs_key = (struct vc4_vs_key *)key;
2230                break;
2231        case QSTAGE_COORD:
2232                c->vs_key = (struct vc4_vs_key *)key;
2233                break;
2234        }
2235
2236        c->s = nir_shader_clone(c, key->shader_state->base.ir.nir);
2237
2238        if (stage == QSTAGE_FRAG) {
2239                if (c->fs_key->alpha_test_func != COMPARE_FUNC_ALWAYS) {
2240                        NIR_PASS_V(c->s, nir_lower_alpha_test,
2241                                   c->fs_key->alpha_test_func,
2242                                   c->fs_key->sample_alpha_to_one &&
2243                                   c->fs_key->msaa);
2244                }
2245                NIR_PASS_V(c->s, vc4_nir_lower_blend, c);
2246        }
2247
2248        struct nir_lower_tex_options tex_options = {
2249                /* We would need to implement txs, but we don't want the
2250                 * int/float conversions
2251                 */
2252                .lower_rect = false,
2253
2254                .lower_txp = ~0,
2255
2256                /* Apply swizzles to all samplers. */
2257                .swizzle_result = ~0,
2258        };
2259
2260        /* Lower the format swizzle and ARB_texture_swizzle-style swizzle.
2261         * The format swizzling applies before sRGB decode, and
2262         * ARB_texture_swizzle is the last thing before returning the sample.
2263         */
2264        for (int i = 0; i < ARRAY_SIZE(key->tex); i++) {
2265                enum pipe_format format = c->key->tex[i].format;
2266
2267                if (!format)
2268                        continue;
2269
2270                const uint8_t *format_swizzle = vc4_get_format_swizzle(format);
2271
2272                for (int j = 0; j < 4; j++) {
2273                        uint8_t arb_swiz = c->key->tex[i].swizzle[j];
2274
2275                        if (arb_swiz <= 3) {
2276                                tex_options.swizzles[i][j] =
2277                                        format_swizzle[arb_swiz];
2278                        } else {
2279                                tex_options.swizzles[i][j] = arb_swiz;
2280                        }
2281                }
2282
2283                if (util_format_is_srgb(format))
2284                        tex_options.lower_srgb |= (1 << i);
2285        }
2286
2287        NIR_PASS_V(c->s, nir_lower_tex, &tex_options);
2288
2289        if (c->fs_key && c->fs_key->light_twoside)
2290                NIR_PASS_V(c->s, nir_lower_two_sided_color);
2291
2292        if (c->vs_key && c->vs_key->clamp_color)
2293                NIR_PASS_V(c->s, nir_lower_clamp_color_outputs);
2294
2295        if (c->key->ucp_enables) {
2296                if (stage == QSTAGE_FRAG) {
2297                        NIR_PASS_V(c->s, nir_lower_clip_fs, c->key->ucp_enables);
2298                } else {
2299                        NIR_PASS_V(c->s, nir_lower_clip_vs,
2300				   c->key->ucp_enables, false);
2301                        NIR_PASS_V(c->s, nir_lower_io_to_scalar,
2302                                   nir_var_shader_out);
2303                }
2304        }
2305
2306        /* FS input scalarizing must happen after nir_lower_two_sided_color,
2307         * which only handles a vec4 at a time.  Similarly, VS output
2308         * scalarizing must happen after nir_lower_clip_vs.
2309         */
2310        if (c->stage == QSTAGE_FRAG)
2311                NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_in);
2312        else
2313                NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out);
2314
2315        NIR_PASS_V(c->s, vc4_nir_lower_io, c);
2316        NIR_PASS_V(c->s, vc4_nir_lower_txf_ms, c);
2317        NIR_PASS_V(c->s, nir_lower_idiv);
2318
2319        vc4_optimize_nir(c->s);
2320
2321        NIR_PASS_V(c->s, nir_lower_bool_to_int32);
2322
2323        NIR_PASS_V(c->s, nir_convert_from_ssa, true);
2324
2325        if (vc4_debug & VC4_DEBUG_SHADERDB) {
2326                fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d NIR instructions\n",
2327                        qir_get_stage_name(c->stage),
2328                        c->program_id, c->variant_id,
2329                        count_nir_instrs(c->s));
2330        }
2331
2332        if (vc4_debug & VC4_DEBUG_NIR) {
2333                fprintf(stderr, "%s prog %d/%d NIR:\n",
2334                        qir_get_stage_name(c->stage),
2335                        c->program_id, c->variant_id);
2336                nir_print_shader(c->s, stderr);
2337        }
2338
2339        nir_to_qir(c);
2340
2341        switch (stage) {
2342        case QSTAGE_FRAG:
2343                /* FS threading requires that the thread execute
2344                 * QPU_SIG_LAST_THREAD_SWITCH exactly once before terminating
2345                 * (with no other THRSW afterwards, obviously).  If we didn't
2346                 * fetch a texture at a top level block, this wouldn't be
2347                 * true.
2348                 */
2349                if (c->fs_threaded && !c->last_thrsw_at_top_level) {
2350                        c->failed = true;
2351                        return c;
2352                }
2353
2354                emit_frag_end(c);
2355                break;
2356        case QSTAGE_VERT:
2357                emit_vert_end(c,
2358                              c->vs_key->fs_inputs->input_slots,
2359                              c->vs_key->fs_inputs->num_inputs);
2360                break;
2361        case QSTAGE_COORD:
2362                emit_coord_end(c);
2363                break;
2364        }
2365
2366        if (vc4_debug & VC4_DEBUG_QIR) {
2367                fprintf(stderr, "%s prog %d/%d pre-opt QIR:\n",
2368                        qir_get_stage_name(c->stage),
2369                        c->program_id, c->variant_id);
2370                qir_dump(c);
2371                fprintf(stderr, "\n");
2372        }
2373
2374        qir_optimize(c);
2375        qir_lower_uniforms(c);
2376
2377        qir_schedule_instructions(c);
2378        qir_emit_uniform_stream_resets(c);
2379
2380        if (vc4_debug & VC4_DEBUG_QIR) {
2381                fprintf(stderr, "%s prog %d/%d QIR:\n",
2382                        qir_get_stage_name(c->stage),
2383                        c->program_id, c->variant_id);
2384                qir_dump(c);
2385                fprintf(stderr, "\n");
2386        }
2387
2388        qir_reorder_uniforms(c);
2389        vc4_generate_code(vc4, c);
2390
2391        if (vc4_debug & VC4_DEBUG_SHADERDB) {
2392                fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d instructions\n",
2393                        qir_get_stage_name(c->stage),
2394                        c->program_id, c->variant_id,
2395                        c->qpu_inst_count);
2396                fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d uniforms\n",
2397                        qir_get_stage_name(c->stage),
2398                        c->program_id, c->variant_id,
2399                        c->num_uniforms);
2400        }
2401
2402        ralloc_free(c->s);
2403
2404        return c;
2405}
2406
2407static void *
2408vc4_shader_state_create(struct pipe_context *pctx,
2409                        const struct pipe_shader_state *cso)
2410{
2411        struct vc4_context *vc4 = vc4_context(pctx);
2412        struct vc4_uncompiled_shader *so = CALLOC_STRUCT(vc4_uncompiled_shader);
2413        if (!so)
2414                return NULL;
2415
2416        so->program_id = vc4->next_uncompiled_program_id++;
2417
2418        nir_shader *s;
2419
2420        if (cso->type == PIPE_SHADER_IR_NIR) {
2421                /* The backend takes ownership of the NIR shader on state
2422                 * creation.
2423                 */
2424                s = cso->ir.nir;
2425       } else {
2426                assert(cso->type == PIPE_SHADER_IR_TGSI);
2427
2428                if (vc4_debug & VC4_DEBUG_TGSI) {
2429                        fprintf(stderr, "prog %d TGSI:\n",
2430                                so->program_id);
2431                        tgsi_dump(cso->tokens, 0);
2432                        fprintf(stderr, "\n");
2433                }
2434                s = tgsi_to_nir(cso->tokens, pctx->screen);
2435        }
2436
2437        NIR_PASS_V(s, nir_lower_io, nir_var_all, type_size,
2438                   (nir_lower_io_options)0);
2439
2440        NIR_PASS_V(s, nir_lower_regs_to_ssa);
2441        NIR_PASS_V(s, nir_normalize_cubemap_coords);
2442
2443        NIR_PASS_V(s, nir_lower_load_const_to_scalar);
2444
2445        vc4_optimize_nir(s);
2446
2447        NIR_PASS_V(s, nir_remove_dead_variables, nir_var_function_temp);
2448
2449        /* Garbage collect dead instructions */
2450        nir_sweep(s);
2451
2452        so->base.type = PIPE_SHADER_IR_NIR;
2453        so->base.ir.nir = s;
2454
2455        if (vc4_debug & VC4_DEBUG_NIR) {
2456                fprintf(stderr, "%s prog %d NIR:\n",
2457                        gl_shader_stage_name(s->info.stage),
2458                        so->program_id);
2459                nir_print_shader(s, stderr);
2460                fprintf(stderr, "\n");
2461        }
2462
2463        return so;
2464}
2465
2466static void
2467copy_uniform_state_to_shader(struct vc4_compiled_shader *shader,
2468                             struct vc4_compile *c)
2469{
2470        int count = c->num_uniforms;
2471        struct vc4_shader_uniform_info *uinfo = &shader->uniforms;
2472
2473        uinfo->count = count;
2474        uinfo->data = ralloc_array(shader, uint32_t, count);
2475        memcpy(uinfo->data, c->uniform_data,
2476               count * sizeof(*uinfo->data));
2477        uinfo->contents = ralloc_array(shader, enum quniform_contents, count);
2478        memcpy(uinfo->contents, c->uniform_contents,
2479               count * sizeof(*uinfo->contents));
2480        uinfo->num_texture_samples = c->num_texture_samples;
2481
2482        vc4_set_shader_uniform_dirty_flags(shader);
2483}
2484
2485static void
2486vc4_setup_compiled_fs_inputs(struct vc4_context *vc4, struct vc4_compile *c,
2487                             struct vc4_compiled_shader *shader)
2488{
2489        struct vc4_fs_inputs inputs;
2490
2491        memset(&inputs, 0, sizeof(inputs));
2492        inputs.input_slots = ralloc_array(shader,
2493                                          struct vc4_varying_slot,
2494                                          c->num_input_slots);
2495
2496        bool input_live[c->num_input_slots];
2497
2498        memset(input_live, 0, sizeof(input_live));
2499        qir_for_each_inst_inorder(inst, c) {
2500                for (int i = 0; i < qir_get_nsrc(inst); i++) {
2501                        if (inst->src[i].file == QFILE_VARY)
2502                                input_live[inst->src[i].index] = true;
2503                }
2504        }
2505
2506        for (int i = 0; i < c->num_input_slots; i++) {
2507                struct vc4_varying_slot *slot = &c->input_slots[i];
2508
2509                if (!input_live[i])
2510                        continue;
2511
2512                /* Skip non-VS-output inputs. */
2513                if (slot->slot == (uint8_t)~0)
2514                        continue;
2515
2516                if (slot->slot == VARYING_SLOT_COL0 ||
2517                    slot->slot == VARYING_SLOT_COL1 ||
2518                    slot->slot == VARYING_SLOT_BFC0 ||
2519                    slot->slot == VARYING_SLOT_BFC1) {
2520                        shader->color_inputs |= (1 << inputs.num_inputs);
2521                }
2522
2523                inputs.input_slots[inputs.num_inputs] = *slot;
2524                inputs.num_inputs++;
2525        }
2526        shader->num_inputs = inputs.num_inputs;
2527
2528        /* Add our set of inputs to the set of all inputs seen.  This way, we
2529         * can have a single pointer that identifies an FS inputs set,
2530         * allowing VS to avoid recompiling when the FS is recompiled (or a
2531         * new one is bound using separate shader objects) but the inputs
2532         * don't change.
2533         */
2534        struct set_entry *entry = _mesa_set_search(vc4->fs_inputs_set, &inputs);
2535        if (entry) {
2536                shader->fs_inputs = entry->key;
2537                ralloc_free(inputs.input_slots);
2538        } else {
2539                struct vc4_fs_inputs *alloc_inputs;
2540
2541                alloc_inputs = rzalloc(vc4->fs_inputs_set, struct vc4_fs_inputs);
2542                memcpy(alloc_inputs, &inputs, sizeof(inputs));
2543                ralloc_steal(alloc_inputs, inputs.input_slots);
2544                _mesa_set_add(vc4->fs_inputs_set, alloc_inputs);
2545
2546                shader->fs_inputs = alloc_inputs;
2547        }
2548}
2549
2550static struct vc4_compiled_shader *
2551vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage,
2552                        struct vc4_key *key)
2553{
2554        struct hash_table *ht;
2555        uint32_t key_size;
2556        bool try_threading;
2557
2558        if (stage == QSTAGE_FRAG) {
2559                ht = vc4->fs_cache;
2560                key_size = sizeof(struct vc4_fs_key);
2561                try_threading = vc4->screen->has_threaded_fs;
2562        } else {
2563                ht = vc4->vs_cache;
2564                key_size = sizeof(struct vc4_vs_key);
2565                try_threading = false;
2566        }
2567
2568        struct vc4_compiled_shader *shader;
2569        struct hash_entry *entry = _mesa_hash_table_search(ht, key);
2570        if (entry)
2571                return entry->data;
2572
2573        struct vc4_compile *c = vc4_shader_ntq(vc4, stage, key, try_threading);
2574        /* If the FS failed to compile threaded, fall back to single threaded. */
2575        if (try_threading && c->failed) {
2576                qir_compile_destroy(c);
2577                c = vc4_shader_ntq(vc4, stage, key, false);
2578        }
2579
2580        shader = rzalloc(NULL, struct vc4_compiled_shader);
2581
2582        shader->program_id = vc4->next_compiled_program_id++;
2583        if (stage == QSTAGE_FRAG) {
2584                vc4_setup_compiled_fs_inputs(vc4, c, shader);
2585
2586                /* Note: the temporary clone in c->s has been freed. */
2587                nir_shader *orig_shader = key->shader_state->base.ir.nir;
2588                if (orig_shader->info.outputs_written & (1 << FRAG_RESULT_DEPTH))
2589                        shader->disable_early_z = true;
2590        } else {
2591                shader->num_inputs = c->num_inputs;
2592
2593                shader->vattr_offsets[0] = 0;
2594                for (int i = 0; i < 8; i++) {
2595                        shader->vattr_offsets[i + 1] =
2596                                shader->vattr_offsets[i] + c->vattr_sizes[i];
2597
2598                        if (c->vattr_sizes[i])
2599                                shader->vattrs_live |= (1 << i);
2600                }
2601        }
2602
2603        shader->failed = c->failed;
2604        if (c->failed) {
2605                shader->failed = true;
2606        } else {
2607                copy_uniform_state_to_shader(shader, c);
2608                shader->bo = vc4_bo_alloc_shader(vc4->screen, c->qpu_insts,
2609                                                 c->qpu_inst_count *
2610                                                 sizeof(uint64_t));
2611        }
2612
2613        shader->fs_threaded = c->fs_threaded;
2614
2615        if ((vc4_debug & VC4_DEBUG_SHADERDB) && stage == QSTAGE_FRAG) {
2616                fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d FS threads\n",
2617                        qir_get_stage_name(c->stage),
2618                        c->program_id, c->variant_id,
2619                        1 + shader->fs_threaded);
2620        }
2621
2622        qir_compile_destroy(c);
2623
2624        struct vc4_key *dup_key;
2625        dup_key = rzalloc_size(shader, key_size); /* TODO: don't use rzalloc */
2626        memcpy(dup_key, key, key_size);
2627        _mesa_hash_table_insert(ht, dup_key, shader);
2628
2629        return shader;
2630}
2631
2632static void
2633vc4_setup_shared_key(struct vc4_context *vc4, struct vc4_key *key,
2634                     struct vc4_texture_stateobj *texstate)
2635{
2636        for (int i = 0; i < texstate->num_textures; i++) {
2637                struct pipe_sampler_view *sampler = texstate->textures[i];
2638                struct vc4_sampler_view *vc4_sampler = vc4_sampler_view(sampler);
2639                struct pipe_sampler_state *sampler_state =
2640                        texstate->samplers[i];
2641
2642                if (!sampler)
2643                        continue;
2644
2645                key->tex[i].format = sampler->format;
2646                key->tex[i].swizzle[0] = sampler->swizzle_r;
2647                key->tex[i].swizzle[1] = sampler->swizzle_g;
2648                key->tex[i].swizzle[2] = sampler->swizzle_b;
2649                key->tex[i].swizzle[3] = sampler->swizzle_a;
2650
2651                if (sampler->texture->nr_samples > 1) {
2652                        key->tex[i].msaa_width = sampler->texture->width0;
2653                        key->tex[i].msaa_height = sampler->texture->height0;
2654                } else if (sampler){
2655                        key->tex[i].compare_mode = sampler_state->compare_mode;
2656                        key->tex[i].compare_func = sampler_state->compare_func;
2657                        key->tex[i].wrap_s = sampler_state->wrap_s;
2658                        key->tex[i].wrap_t = sampler_state->wrap_t;
2659                        key->tex[i].force_first_level =
2660                                vc4_sampler->force_first_level;
2661                }
2662        }
2663
2664        key->ucp_enables = vc4->rasterizer->base.clip_plane_enable;
2665}
2666
2667static void
2668vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
2669{
2670        struct vc4_job *job = vc4->job;
2671        struct vc4_fs_key local_key;
2672        struct vc4_fs_key *key = &local_key;
2673
2674        if (!(vc4->dirty & (VC4_DIRTY_PRIM_MODE |
2675                            VC4_DIRTY_BLEND |
2676                            VC4_DIRTY_FRAMEBUFFER |
2677                            VC4_DIRTY_ZSA |
2678                            VC4_DIRTY_RASTERIZER |
2679                            VC4_DIRTY_SAMPLE_MASK |
2680                            VC4_DIRTY_FRAGTEX |
2681                            VC4_DIRTY_UNCOMPILED_FS |
2682                            VC4_DIRTY_UBO_1_SIZE))) {
2683                return;
2684        }
2685
2686        memset(key, 0, sizeof(*key));
2687        vc4_setup_shared_key(vc4, &key->base, &vc4->fragtex);
2688        key->base.shader_state = vc4->prog.bind_fs;
2689        key->is_points = (prim_mode == PIPE_PRIM_POINTS);
2690        key->is_lines = (prim_mode >= PIPE_PRIM_LINES &&
2691                         prim_mode <= PIPE_PRIM_LINE_STRIP);
2692        key->blend = vc4->blend->rt[0];
2693        if (vc4->blend->logicop_enable) {
2694                key->logicop_func = vc4->blend->logicop_func;
2695        } else {
2696                key->logicop_func = PIPE_LOGICOP_COPY;
2697        }
2698        if (job->msaa) {
2699                key->msaa = vc4->rasterizer->base.multisample;
2700                key->sample_coverage = (vc4->sample_mask != (1 << VC4_MAX_SAMPLES) - 1);
2701                key->sample_alpha_to_coverage = vc4->blend->alpha_to_coverage;
2702                key->sample_alpha_to_one = vc4->blend->alpha_to_one;
2703        }
2704
2705        if (vc4->framebuffer.cbufs[0])
2706                key->color_format = vc4->framebuffer.cbufs[0]->format;
2707
2708        key->stencil_enabled = vc4->zsa->stencil_uniforms[0] != 0;
2709        key->stencil_twoside = vc4->zsa->stencil_uniforms[1] != 0;
2710        key->stencil_full_writemasks = vc4->zsa->stencil_uniforms[2] != 0;
2711        key->depth_enabled = (vc4->zsa->base.depth.enabled ||
2712                              key->stencil_enabled);
2713        if (vc4->zsa->base.alpha.enabled)
2714                key->alpha_test_func = vc4->zsa->base.alpha.func;
2715        else
2716                key->alpha_test_func = COMPARE_FUNC_ALWAYS;
2717
2718        if (key->is_points) {
2719                key->point_sprite_mask =
2720                        vc4->rasterizer->base.sprite_coord_enable;
2721                key->point_coord_upper_left =
2722                        (vc4->rasterizer->base.sprite_coord_mode ==
2723                         PIPE_SPRITE_COORD_UPPER_LEFT);
2724        }
2725
2726        key->ubo_1_size = vc4->constbuf[PIPE_SHADER_FRAGMENT].cb[1].buffer_size;
2727        key->light_twoside = vc4->rasterizer->base.light_twoside;
2728
2729        struct vc4_compiled_shader *old_fs = vc4->prog.fs;
2730        vc4->prog.fs = vc4_get_compiled_shader(vc4, QSTAGE_FRAG, &key->base);
2731        if (vc4->prog.fs == old_fs)
2732                return;
2733
2734        vc4->dirty |= VC4_DIRTY_COMPILED_FS;
2735
2736        if (vc4->rasterizer->base.flatshade &&
2737            (!old_fs || vc4->prog.fs->color_inputs != old_fs->color_inputs)) {
2738                vc4->dirty |= VC4_DIRTY_FLAT_SHADE_FLAGS;
2739        }
2740
2741        if (!old_fs || vc4->prog.fs->fs_inputs != old_fs->fs_inputs)
2742                vc4->dirty |= VC4_DIRTY_FS_INPUTS;
2743}
2744
2745static void
2746vc4_update_compiled_vs(struct vc4_context *vc4, uint8_t prim_mode)
2747{
2748        struct vc4_vs_key local_key;
2749        struct vc4_vs_key *key = &local_key;
2750
2751        if (!(vc4->dirty & (VC4_DIRTY_PRIM_MODE |
2752                            VC4_DIRTY_RASTERIZER |
2753                            VC4_DIRTY_VERTTEX |
2754                            VC4_DIRTY_VTXSTATE |
2755                            VC4_DIRTY_UNCOMPILED_VS |
2756                            VC4_DIRTY_FS_INPUTS))) {
2757                return;
2758        }
2759
2760        memset(key, 0, sizeof(*key));
2761        vc4_setup_shared_key(vc4, &key->base, &vc4->verttex);
2762        key->base.shader_state = vc4->prog.bind_vs;
2763        key->fs_inputs = vc4->prog.fs->fs_inputs;
2764        key->clamp_color = vc4->rasterizer->base.clamp_vertex_color;
2765
2766        for (int i = 0; i < ARRAY_SIZE(key->attr_formats); i++)
2767                key->attr_formats[i] = vc4->vtx->pipe[i].src_format;
2768
2769        key->per_vertex_point_size =
2770                (prim_mode == PIPE_PRIM_POINTS &&
2771                 vc4->rasterizer->base.point_size_per_vertex);
2772
2773        struct vc4_compiled_shader *vs =
2774                vc4_get_compiled_shader(vc4, QSTAGE_VERT, &key->base);
2775        if (vs != vc4->prog.vs) {
2776                vc4->prog.vs = vs;
2777                vc4->dirty |= VC4_DIRTY_COMPILED_VS;
2778        }
2779
2780        key->is_coord = true;
2781        /* Coord shaders don't care what the FS inputs are. */
2782        key->fs_inputs = NULL;
2783        struct vc4_compiled_shader *cs =
2784                vc4_get_compiled_shader(vc4, QSTAGE_COORD, &key->base);
2785        if (cs != vc4->prog.cs) {
2786                vc4->prog.cs = cs;
2787                vc4->dirty |= VC4_DIRTY_COMPILED_CS;
2788        }
2789}
2790
2791bool
2792vc4_update_compiled_shaders(struct vc4_context *vc4, uint8_t prim_mode)
2793{
2794        vc4_update_compiled_fs(vc4, prim_mode);
2795        vc4_update_compiled_vs(vc4, prim_mode);
2796
2797        return !(vc4->prog.cs->failed ||
2798                 vc4->prog.vs->failed ||
2799                 vc4->prog.fs->failed);
2800}
2801
2802static uint32_t
2803fs_cache_hash(const void *key)
2804{
2805        return _mesa_hash_data(key, sizeof(struct vc4_fs_key));
2806}
2807
2808static uint32_t
2809vs_cache_hash(const void *key)
2810{
2811        return _mesa_hash_data(key, sizeof(struct vc4_vs_key));
2812}
2813
2814static bool
2815fs_cache_compare(const void *key1, const void *key2)
2816{
2817        return memcmp(key1, key2, sizeof(struct vc4_fs_key)) == 0;
2818}
2819
2820static bool
2821vs_cache_compare(const void *key1, const void *key2)
2822{
2823        return memcmp(key1, key2, sizeof(struct vc4_vs_key)) == 0;
2824}
2825
2826static uint32_t
2827fs_inputs_hash(const void *key)
2828{
2829        const struct vc4_fs_inputs *inputs = key;
2830
2831        return _mesa_hash_data(inputs->input_slots,
2832                               sizeof(*inputs->input_slots) *
2833                               inputs->num_inputs);
2834}
2835
2836static bool
2837fs_inputs_compare(const void *key1, const void *key2)
2838{
2839        const struct vc4_fs_inputs *inputs1 = key1;
2840        const struct vc4_fs_inputs *inputs2 = key2;
2841
2842        return (inputs1->num_inputs == inputs2->num_inputs &&
2843                memcmp(inputs1->input_slots,
2844                       inputs2->input_slots,
2845                       sizeof(*inputs1->input_slots) *
2846                       inputs1->num_inputs) == 0);
2847}
2848
2849static void
2850delete_from_cache_if_matches(struct hash_table *ht,
2851                             struct vc4_compiled_shader **last_compile,
2852                             struct hash_entry *entry,
2853                             struct vc4_uncompiled_shader *so)
2854{
2855        const struct vc4_key *key = entry->key;
2856
2857        if (key->shader_state == so) {
2858                struct vc4_compiled_shader *shader = entry->data;
2859                _mesa_hash_table_remove(ht, entry);
2860                vc4_bo_unreference(&shader->bo);
2861
2862                if (shader == *last_compile)
2863                        *last_compile = NULL;
2864
2865                ralloc_free(shader);
2866        }
2867}
2868
2869static void
2870vc4_shader_state_delete(struct pipe_context *pctx, void *hwcso)
2871{
2872        struct vc4_context *vc4 = vc4_context(pctx);
2873        struct vc4_uncompiled_shader *so = hwcso;
2874
2875        hash_table_foreach(vc4->fs_cache, entry) {
2876                delete_from_cache_if_matches(vc4->fs_cache, &vc4->prog.fs,
2877                                             entry, so);
2878        }
2879        hash_table_foreach(vc4->vs_cache, entry) {
2880                delete_from_cache_if_matches(vc4->vs_cache, &vc4->prog.vs,
2881                                             entry, so);
2882        }
2883
2884        ralloc_free(so->base.ir.nir);
2885        free(so);
2886}
2887
2888static void
2889vc4_fp_state_bind(struct pipe_context *pctx, void *hwcso)
2890{
2891        struct vc4_context *vc4 = vc4_context(pctx);
2892        vc4->prog.bind_fs = hwcso;
2893        vc4->dirty |= VC4_DIRTY_UNCOMPILED_FS;
2894}
2895
2896static void
2897vc4_vp_state_bind(struct pipe_context *pctx, void *hwcso)
2898{
2899        struct vc4_context *vc4 = vc4_context(pctx);
2900        vc4->prog.bind_vs = hwcso;
2901        vc4->dirty |= VC4_DIRTY_UNCOMPILED_VS;
2902}
2903
2904void
2905vc4_program_init(struct pipe_context *pctx)
2906{
2907        struct vc4_context *vc4 = vc4_context(pctx);
2908
2909        pctx->create_vs_state = vc4_shader_state_create;
2910        pctx->delete_vs_state = vc4_shader_state_delete;
2911
2912        pctx->create_fs_state = vc4_shader_state_create;
2913        pctx->delete_fs_state = vc4_shader_state_delete;
2914
2915        pctx->bind_fs_state = vc4_fp_state_bind;
2916        pctx->bind_vs_state = vc4_vp_state_bind;
2917
2918        vc4->fs_cache = _mesa_hash_table_create(pctx, fs_cache_hash,
2919                                                fs_cache_compare);
2920        vc4->vs_cache = _mesa_hash_table_create(pctx, vs_cache_hash,
2921                                                vs_cache_compare);
2922        vc4->fs_inputs_set = _mesa_set_create(pctx, fs_inputs_hash,
2923                                              fs_inputs_compare);
2924}
2925
2926void
2927vc4_program_fini(struct pipe_context *pctx)
2928{
2929        struct vc4_context *vc4 = vc4_context(pctx);
2930
2931        hash_table_foreach(vc4->fs_cache, entry) {
2932                struct vc4_compiled_shader *shader = entry->data;
2933                vc4_bo_unreference(&shader->bo);
2934                ralloc_free(shader);
2935                _mesa_hash_table_remove(vc4->fs_cache, entry);
2936        }
2937
2938        hash_table_foreach(vc4->vs_cache, entry) {
2939                struct vc4_compiled_shader *shader = entry->data;
2940                vc4_bo_unreference(&shader->bo);
2941                ralloc_free(shader);
2942                _mesa_hash_table_remove(vc4->vs_cache, entry);
2943        }
2944}
2945