/*
 * Copyright (c) 2014 Scott Mansell
 * Copyright © 2014 Broadcom
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <inttypes.h>
#include "util/format/u_format.h"
#include "util/crc32.h"
#include "util/u_helpers.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/ralloc.h"
#include "util/hash_table.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_parse.h"
#include "compiler/nir/nir.h"
#include "compiler/nir/nir_builder.h"
#include "compiler/nir_types.h"
#include "nir/tgsi_to_nir.h"
#include "vc4_context.h"
#include "vc4_qpu.h"
#include "vc4_qir.h"

static struct qreg
ntq_get_src(struct vc4_compile *c, nir_src src, int i);
static void
ntq_emit_cf_list(struct vc4_compile *c, struct exec_list *list);

static int
type_size(const struct glsl_type *type, bool bindless)
{
   return glsl_count_attribute_slots(type, false);
}

static void
resize_qreg_array(struct vc4_compile *c,
                  struct qreg **regs,
                  uint32_t *size,
                  uint32_t decl_size)
{
        if (*size >= decl_size)
                return;

        uint32_t old_size = *size;
        *size = MAX2(*size * 2, decl_size);
        *regs = reralloc(c, *regs, struct qreg, *size);
        if (!*regs) {
                fprintf(stderr, "Malloc failure\n");
                abort();
        }

        for (uint32_t i = old_size; i < *size; i++)
                (*regs)[i] = c->undef;
}

static void
ntq_emit_thrsw(struct vc4_compile *c)
{
        if (!c->fs_threaded)
                return;

        /* Always thread switch after each texture operation for now.
         *
         * We could do better by batching a bunch of texture fetches up and
         * then doing one thread switch and collecting all their results
         * afterward.
         */
        qir_emit_nondef(c, qir_inst(QOP_THRSW, c->undef,
                                    c->undef, c->undef));
        c->last_thrsw_at_top_level = (c->execute.file == QFILE_NULL);
}

static struct qreg
indirect_uniform_load(struct vc4_compile *c, nir_intrinsic_instr *intr)
{
        struct qreg indirect_offset = ntq_get_src(c, intr->src[0], 0);

        /* Clamp to [0, array size).  Note that MIN/MAX are signed. */
        uint32_t range = nir_intrinsic_range(intr);
        indirect_offset = qir_MAX(c, indirect_offset, qir_uniform_ui(c, 0));
        indirect_offset = qir_MIN_NOIMM(c, indirect_offset,
                                        qir_uniform_ui(c, range - 4));

        qir_ADD_dest(c, qir_reg(QFILE_TEX_S_DIRECT, 0),
                     indirect_offset,
                     qir_uniform(c, QUNIFORM_UBO0_ADDR,
                                 nir_intrinsic_base(intr)));

        c->num_texture_samples++;

        ntq_emit_thrsw(c);

        return qir_TEX_RESULT(c);
}

static struct qreg
vc4_ubo_load(struct vc4_compile *c, nir_intrinsic_instr *intr)
{
        int buffer_index = nir_src_as_uint(intr->src[0]);
        assert(buffer_index == 1);
        assert(c->stage == QSTAGE_FRAG);

        struct qreg offset = ntq_get_src(c, intr->src[1], 0);

        /* Clamp to [0, array size).  Note that MIN/MAX are signed. */
        offset = qir_MAX(c, offset, qir_uniform_ui(c, 0));
        offset = qir_MIN_NOIMM(c, offset,
                               qir_uniform_ui(c, c->fs_key->ubo_1_size - 4));

        qir_ADD_dest(c, qir_reg(QFILE_TEX_S_DIRECT, 0),
                     offset,
                     qir_uniform(c, QUNIFORM_UBO1_ADDR, 0));

        c->num_texture_samples++;

        ntq_emit_thrsw(c);

        return qir_TEX_RESULT(c);
}

nir_ssa_def *
vc4_nir_get_swizzled_channel(nir_builder *b, nir_ssa_def **srcs, int swiz)
{
        switch (swiz) {
        default:
        case PIPE_SWIZZLE_NONE:
                fprintf(stderr, "warning: unknown swizzle\n");
                /* FALLTHROUGH */
        case PIPE_SWIZZLE_0:
                return nir_imm_float(b, 0.0);
        case PIPE_SWIZZLE_1:
                return nir_imm_float(b, 1.0);
        case PIPE_SWIZZLE_X:
        case PIPE_SWIZZLE_Y:
        case PIPE_SWIZZLE_Z:
        case PIPE_SWIZZLE_W:
                return srcs[swiz];
        }
}

static struct qreg *
ntq_init_ssa_def(struct vc4_compile *c, nir_ssa_def *def)
{
        struct qreg *qregs = ralloc_array(c->def_ht, struct qreg,
                                          def->num_components);
        _mesa_hash_table_insert(c->def_ht, def, qregs);
        return qregs;
}

/**
 * This function is responsible for getting QIR results into the associated
 * storage for a NIR instruction.
 *
 * If it's a NIR SSA def, then we just set the associated hash table entry to
 * the new result.
 *
 * If it's a NIR reg, then we need to update the existing qreg assigned to the
 * NIR destination with the incoming value.  To do that without introducing
 * new MOVs, we require that the incoming qreg either be a uniform, or be
 * SSA-defined by the previous QIR instruction in the block and rewritable by
 * this function.  That lets us sneak ahead and insert the SF flag beforehand
 * (knowing that the previous instruction doesn't depend on flags) and rewrite
 * its destination to be the NIR reg's destination
 */
static void
ntq_store_dest(struct vc4_compile *c, nir_dest *dest, int chan,
               struct qreg result)
{
        struct qinst *last_inst = NULL;
        if (!list_is_empty(&c->cur_block->instructions))
                last_inst = (struct qinst *)c->cur_block->instructions.prev;

        assert(result.file == QFILE_UNIF ||
               (result.file == QFILE_TEMP &&
                last_inst && last_inst == c->defs[result.index]));

        if (dest->is_ssa) {
                assert(chan < dest->ssa.num_components);

                struct qreg *qregs;
                struct hash_entry *entry =
                        _mesa_hash_table_search(c->def_ht, &dest->ssa);

                if (entry)
                        qregs = entry->data;
                else
                        qregs = ntq_init_ssa_def(c, &dest->ssa);

                qregs[chan] = result;
        } else {
                nir_register *reg = dest->reg.reg;
                assert(dest->reg.base_offset == 0);
                assert(reg->num_array_elems == 0);
                struct hash_entry *entry =
                        _mesa_hash_table_search(c->def_ht, reg);
                struct qreg *qregs = entry->data;

                /* Insert a MOV if the source wasn't an SSA def in the
                 * previous instruction.
                 */
                if (result.file == QFILE_UNIF) {
                        result = qir_MOV(c, result);
                        last_inst = c->defs[result.index];
                }

                /* We know they're both temps, so just rewrite index. */
                c->defs[last_inst->dst.index] = NULL;
                last_inst->dst.index = qregs[chan].index;

                /* If we're in control flow, then make this update of the reg
                 * conditional on the execution mask.
                 */
                if (c->execute.file != QFILE_NULL) {
                        last_inst->dst.index = qregs[chan].index;

                        /* Set the flags to the current exec mask.  To insert
                         * the SF, we temporarily remove our SSA instruction.
                         */
                        list_del(&last_inst->link);
                        qir_SF(c, c->execute);
                        list_addtail(&last_inst->link,
                                     &c->cur_block->instructions);

                        last_inst->cond = QPU_COND_ZS;
                        last_inst->cond_is_exec_mask = true;
                }
        }
}

static struct qreg *
ntq_get_dest(struct vc4_compile *c, nir_dest *dest)
{
        if (dest->is_ssa) {
                struct qreg *qregs = ntq_init_ssa_def(c, &dest->ssa);
                for (int i = 0; i < dest->ssa.num_components; i++)
                        qregs[i] = c->undef;
                return qregs;
        } else {
                nir_register *reg = dest->reg.reg;
                assert(dest->reg.base_offset == 0);
                assert(reg->num_array_elems == 0);
                struct hash_entry *entry =
                        _mesa_hash_table_search(c->def_ht, reg);
                return entry->data;
        }
}

static struct qreg
ntq_get_src(struct vc4_compile *c, nir_src src, int i)
{
        struct hash_entry *entry;
        if (src.is_ssa) {
                entry = _mesa_hash_table_search(c->def_ht, src.ssa);
                assert(i < src.ssa->num_components);
        } else {
                nir_register *reg = src.reg.reg;
                entry = _mesa_hash_table_search(c->def_ht, reg);
                assert(reg->num_array_elems == 0);
                assert(src.reg.base_offset == 0);
                assert(i < reg->num_components);
        }

        struct qreg *qregs = entry->data;
        return qregs[i];
}

static struct qreg
ntq_get_alu_src(struct vc4_compile *c, nir_alu_instr *instr,
                unsigned src)
{
        assert(util_is_power_of_two_or_zero(instr->dest.write_mask));
        unsigned chan = ffs(instr->dest.write_mask) - 1;
        struct qreg r = ntq_get_src(c, instr->src[src].src,
                                    instr->src[src].swizzle[chan]);

        assert(!instr->src[src].abs);
        assert(!instr->src[src].negate);

        return r;
};

static inline struct qreg
qir_SAT(struct vc4_compile *c, struct qreg val)
{
        return qir_FMAX(c,
                        qir_FMIN(c, val, qir_uniform_f(c, 1.0)),
                        qir_uniform_f(c, 0.0));
}

static struct qreg
ntq_rcp(struct vc4_compile *c, struct qreg x)
{
        struct qreg r = qir_RCP(c, x);

        /* Apply a Newton-Raphson step to improve the accuracy. */
        r = qir_FMUL(c, r, qir_FSUB(c,
                                    qir_uniform_f(c, 2.0),
                                    qir_FMUL(c, x, r)));

        return r;
}

static struct qreg
ntq_rsq(struct vc4_compile *c, struct qreg x)
{
        struct qreg r = qir_RSQ(c, x);

        /* Apply a Newton-Raphson step to improve the accuracy. */
        r = qir_FMUL(c, r, qir_FSUB(c,
                                    qir_uniform_f(c, 1.5),
                                    qir_FMUL(c,
                                             qir_uniform_f(c, 0.5),
                                             qir_FMUL(c, x,
                                                      qir_FMUL(c, r, r)))));

        return r;
}

static struct qreg
ntq_umul(struct vc4_compile *c, struct qreg src0, struct qreg src1)
{
        struct qreg src0_hi = qir_SHR(c, src0,
                                      qir_uniform_ui(c, 24));
        struct qreg src1_hi = qir_SHR(c, src1,
                                      qir_uniform_ui(c, 24));

        struct qreg hilo = qir_MUL24(c, src0_hi, src1);
        struct qreg lohi = qir_MUL24(c, src0, src1_hi);
        struct qreg lolo = qir_MUL24(c, src0, src1);

        return qir_ADD(c, lolo, qir_SHL(c,
                                        qir_ADD(c, hilo, lohi),
                                        qir_uniform_ui(c, 24)));
}

static struct qreg
ntq_scale_depth_texture(struct vc4_compile *c, struct qreg src)
{
        struct qreg depthf = qir_ITOF(c, qir_SHR(c, src,
                                                 qir_uniform_ui(c, 8)));
        return qir_FMUL(c, depthf, qir_uniform_f(c, 1.0f/0xffffff));
}

/**
 * Emits a lowered TXF_MS from an MSAA texture.
 *
 * The addressing math has been lowered in NIR, and now we just need to read
 * it like a UBO.
 */
static void
ntq_emit_txf(struct vc4_compile *c, nir_tex_instr *instr)
{
        uint32_t tile_width = 32;
        uint32_t tile_height = 32;
        uint32_t tile_size = (tile_height * tile_width *
                              VC4_MAX_SAMPLES * sizeof(uint32_t));

        unsigned unit = instr->texture_index;
        uint32_t w = align(c->key->tex[unit].msaa_width, tile_width);
        uint32_t w_tiles = w / tile_width;
        uint32_t h = align(c->key->tex[unit].msaa_height, tile_height);
        uint32_t h_tiles = h / tile_height;
        uint32_t size = w_tiles * h_tiles * tile_size;

        struct qreg addr;
        assert(instr->num_srcs == 1);
        assert(instr->src[0].src_type == nir_tex_src_coord);
        addr = ntq_get_src(c, instr->src[0].src, 0);

        /* Perform the clamping required by kernel validation. */
        addr = qir_MAX(c, addr, qir_uniform_ui(c, 0));
        addr = qir_MIN_NOIMM(c, addr, qir_uniform_ui(c, size - 4));

        qir_ADD_dest(c, qir_reg(QFILE_TEX_S_DIRECT, 0),
                     addr, qir_uniform(c, QUNIFORM_TEXTURE_MSAA_ADDR, unit));

        ntq_emit_thrsw(c);

        struct qreg tex = qir_TEX_RESULT(c);
        c->num_texture_samples++;

        enum pipe_format format = c->key->tex[unit].format;
        if (util_format_is_depth_or_stencil(format)) {
                struct qreg scaled = ntq_scale_depth_texture(c, tex);
                for (int i = 0; i < 4; i++)
                        ntq_store_dest(c, &instr->dest, i, qir_MOV(c, scaled));
        } else {
                for (int i = 0; i < 4; i++)
                        ntq_store_dest(c, &instr->dest, i,
                                       qir_UNPACK_8_F(c, tex, i));
        }
}

static void
ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr)
{
        struct qreg s, t, r, lod, compare;
        bool is_txb = false, is_txl = false;
        unsigned unit = instr->texture_index;

        if (instr->op == nir_texop_txf) {
                ntq_emit_txf(c, instr);
                return;
        }

        for (unsigned i = 0; i < instr->num_srcs; i++) {
                switch (instr->src[i].src_type) {
                case nir_tex_src_coord:
                        s = ntq_get_src(c, instr->src[i].src, 0);
                        if (instr->sampler_dim == GLSL_SAMPLER_DIM_1D)
                                t = qir_uniform_f(c, 0.5);
                        else
                                t = ntq_get_src(c, instr->src[i].src, 1);
                        if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
                                r = ntq_get_src(c, instr->src[i].src, 2);
                        break;
                case nir_tex_src_bias:
                        lod = ntq_get_src(c, instr->src[i].src, 0);
                        is_txb = true;
                        break;
                case nir_tex_src_lod:
                        lod = ntq_get_src(c, instr->src[i].src, 0);
                        is_txl = true;
                        break;
                case nir_tex_src_comparator:
                        compare = ntq_get_src(c, instr->src[i].src, 0);
                        break;
                default:
                        unreachable("unknown texture source");
                }
        }

        if (c->stage != QSTAGE_FRAG && !is_txl) {
                /* From the GLSL 1.20 spec:
                 *
                 *     "If it is mip-mapped and running on the vertex shader,
                 *      then the base texture is used."
                 */
                is_txl = true;
                lod = qir_uniform_ui(c, 0);
        }

        if (c->key->tex[unit].force_first_level) {
                lod = qir_uniform(c, QUNIFORM_TEXTURE_FIRST_LEVEL, unit);
                is_txl = true;
                is_txb = false;
        }

        struct qreg texture_u[] = {
                qir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P0, unit),
                qir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P1, unit),
                qir_uniform(c, QUNIFORM_CONSTANT, 0),
                qir_uniform(c, QUNIFORM_CONSTANT, 0),
        };
        uint32_t next_texture_u = 0;

        /* There is no native support for GL texture rectangle coordinates, so
         * we have to rescale from ([0, width], [0, height]) to ([0, 1], [0,
         * 1]).
         */
        if (instr->sampler_dim == GLSL_SAMPLER_DIM_RECT) {
                s = qir_FMUL(c, s,
                             qir_uniform(c, QUNIFORM_TEXRECT_SCALE_X, unit));
                t = qir_FMUL(c, t,
                             qir_uniform(c, QUNIFORM_TEXRECT_SCALE_Y, unit));
        }

        if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE || is_txl) {
                texture_u[2] = qir_uniform(c, QUNIFORM_TEXTURE_CONFIG_P2,
                                           unit | (is_txl << 16));
        }

        struct qinst *tmu;
        if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE) {
                tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_R, 0), r);
                tmu->src[qir_get_tex_uniform_src(tmu)] =
                        texture_u[next_texture_u++];
        } else if (c->key->tex[unit].wrap_s == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
                   c->key->tex[unit].wrap_s == PIPE_TEX_WRAP_CLAMP ||
                   c->key->tex[unit].wrap_t == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
                   c->key->tex[unit].wrap_t == PIPE_TEX_WRAP_CLAMP) {
                tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_R, 0),
                                   qir_uniform(c, QUNIFORM_TEXTURE_BORDER_COLOR,
                                               unit));
                tmu->src[qir_get_tex_uniform_src(tmu)] =
                        texture_u[next_texture_u++];
        }

        if (c->key->tex[unit].wrap_s == PIPE_TEX_WRAP_CLAMP) {
                s = qir_SAT(c, s);
        }

        if (c->key->tex[unit].wrap_t == PIPE_TEX_WRAP_CLAMP) {
                t = qir_SAT(c, t);
        }

        tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_T, 0), t);
        tmu->src[qir_get_tex_uniform_src(tmu)] =
                texture_u[next_texture_u++];

        if (is_txl || is_txb) {
                tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_B, 0), lod);
                tmu->src[qir_get_tex_uniform_src(tmu)] =
                        texture_u[next_texture_u++];
        }

        tmu = qir_MOV_dest(c, qir_reg(QFILE_TEX_S, 0), s);
        tmu->src[qir_get_tex_uniform_src(tmu)] = texture_u[next_texture_u++];

        c->num_texture_samples++;

        ntq_emit_thrsw(c);

        struct qreg tex = qir_TEX_RESULT(c);

        enum pipe_format format = c->key->tex[unit].format;

        struct qreg *dest = ntq_get_dest(c, &instr->dest);
        if (util_format_is_depth_or_stencil(format)) {
                struct qreg normalized = ntq_scale_depth_texture(c, tex);
                struct qreg depth_output;

                struct qreg u0 = qir_uniform_f(c, 0.0f);
                struct qreg u1 = qir_uniform_f(c, 1.0f);
                if (c->key->tex[unit].compare_mode) {
                        /* From the GL_ARB_shadow spec:
                         *
                         *     "Let Dt (D subscript t) be the depth texture
                         *      value, in the range [0, 1].  Let R be the
                         *      interpolated texture coordinate clamped to the
                         *      range [0, 1]."
                         */
                        compare = qir_SAT(c, compare);

                        switch (c->key->tex[unit].compare_func) {
                        case PIPE_FUNC_NEVER:
                                depth_output = qir_uniform_f(c, 0.0f);
                                break;
                        case PIPE_FUNC_ALWAYS:
                                depth_output = u1;
                                break;
                        case PIPE_FUNC_EQUAL:
                                qir_SF(c, qir_FSUB(c, compare, normalized));
                                depth_output = qir_SEL(c, QPU_COND_ZS, u1, u0);
                                break;
                        case PIPE_FUNC_NOTEQUAL:
                                qir_SF(c, qir_FSUB(c, compare, normalized));
                                depth_output = qir_SEL(c, QPU_COND_ZC, u1, u0);
                                break;
                        case PIPE_FUNC_GREATER:
                                qir_SF(c, qir_FSUB(c, compare, normalized));
                                depth_output = qir_SEL(c, QPU_COND_NC, u1, u0);
                                break;
                        case PIPE_FUNC_GEQUAL:
                                qir_SF(c, qir_FSUB(c, normalized, compare));
                                depth_output = qir_SEL(c, QPU_COND_NS, u1, u0);
                                break;
                        case PIPE_FUNC_LESS:
                                qir_SF(c, qir_FSUB(c, compare, normalized));
                                depth_output = qir_SEL(c, QPU_COND_NS, u1, u0);
                                break;
                        case PIPE_FUNC_LEQUAL:
                                qir_SF(c, qir_FSUB(c, normalized, compare));
                                depth_output = qir_SEL(c, QPU_COND_NC, u1, u0);
                                break;
                        }
                } else {
                        depth_output = normalized;
                }

                for (int i = 0; i < 4; i++)
                        dest[i] = depth_output;
        } else {
                for (int i = 0; i < 4; i++)
                        dest[i] = qir_UNPACK_8_F(c, tex, i);
        }
}

/**
 * Computes x - floor(x), which is tricky because our FTOI truncates (rounds
 * to zero).
 */
static struct qreg
ntq_ffract(struct vc4_compile *c, struct qreg src)
{
        struct qreg trunc = qir_ITOF(c, qir_FTOI(c, src));
        struct qreg diff = qir_FSUB(c, src, trunc);
        qir_SF(c, diff);

        qir_FADD_dest(c, diff,
                      diff, qir_uniform_f(c, 1.0))->cond = QPU_COND_NS;

        return qir_MOV(c, diff);
}

/**
 * Computes floor(x), which is tricky because our FTOI truncates (rounds to
 * zero).
 */
static struct qreg
ntq_ffloor(struct vc4_compile *c, struct qreg src)
{
        struct qreg result = qir_ITOF(c, qir_FTOI(c, src));

        /* This will be < 0 if we truncated and the truncation was of a value
         * that was < 0 in the first place.
         */
        qir_SF(c, qir_FSUB(c, src, result));

        struct qinst *sub = qir_FSUB_dest(c, result,
                                          result, qir_uniform_f(c, 1.0));
        sub->cond = QPU_COND_NS;

        return qir_MOV(c, result);
}

/**
 * Computes ceil(x), which is tricky because our FTOI truncates (rounds to
 * zero).
 */
static struct qreg
ntq_fceil(struct vc4_compile *c, struct qreg src)
{
        struct qreg result = qir_ITOF(c, qir_FTOI(c, src));

        /* This will be < 0 if we truncated and the truncation was of a value
         * that was > 0 in the first place.
         */
        qir_SF(c, qir_FSUB(c, result, src));

        qir_FADD_dest(c, result,
                      result, qir_uniform_f(c, 1.0))->cond = QPU_COND_NS;

        return qir_MOV(c, result);
}

static struct qreg
ntq_shrink_sincos_input_range(struct vc4_compile *c, struct qreg x)
{
        /* Since we're using a Taylor approximation, we want to have a small
         * number of coefficients and take advantage of sin/cos repeating
         * every 2pi.  We keep our x as close to 0 as we can, since the series
         * will be less accurate as |x| increases.  (Also, be careful of
         * shifting the input x value to be tricky with sin/cos relations,
         * because getting accurate values for x==0 is very important for SDL
         * rendering)
         */
        struct qreg scaled_x =
                qir_FMUL(c, x,
                         qir_uniform_f(c, 1.0f / (M_PI * 2.0f)));
        /* Note: FTOI truncates toward 0. */
        struct qreg x_frac = qir_FSUB(c, scaled_x,
                                      qir_ITOF(c, qir_FTOI(c, scaled_x)));
        /* Map [0.5, 1] to [-0.5, 0] */
        qir_SF(c, qir_FSUB(c, x_frac, qir_uniform_f(c, 0.5)));
        qir_FSUB_dest(c, x_frac, x_frac, qir_uniform_f(c, 1.0))->cond = QPU_COND_NC;
        /* Map [-1, -0.5] to [0, 0.5] */
        qir_SF(c, qir_FADD(c, x_frac, qir_uniform_f(c, 0.5)));
        qir_FADD_dest(c, x_frac, x_frac, qir_uniform_f(c, 1.0))->cond = QPU_COND_NS;

        return x_frac;
}

static struct qreg
ntq_fsin(struct vc4_compile *c, struct qreg src)
{
        float coeff[] = {
                2.0 * M_PI,
                -pow(2.0 * M_PI, 3) / (3 * 2 * 1),
                pow(2.0 * M_PI, 5) / (5 * 4 * 3 * 2 * 1),
                -pow(2.0 * M_PI, 7) / (7 * 6 * 5 * 4 * 3 * 2 * 1),
                pow(2.0 * M_PI, 9) / (9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1),
        };

        struct qreg x = ntq_shrink_sincos_input_range(c, src);
        struct qreg x2 = qir_FMUL(c, x, x);
        struct qreg sum = qir_FMUL(c, x, qir_uniform_f(c, coeff[0]));
        for (int i = 1; i < ARRAY_SIZE(coeff); i++) {
                x = qir_FMUL(c, x, x2);
                sum = qir_FADD(c,
                               sum,
                               qir_FMUL(c,
                                        x,
                                        qir_uniform_f(c, coeff[i])));
        }
        return sum;
}

static struct qreg
ntq_fcos(struct vc4_compile *c, struct qreg src)
{
        float coeff[] = {
                1.0f,
                -pow(2.0 * M_PI, 2) / (2 * 1),
                pow(2.0 * M_PI, 4) / (4 * 3 * 2 * 1),
                -pow(2.0 * M_PI, 6) / (6 * 5 * 4 * 3 * 2 * 1),
                pow(2.0 * M_PI, 8) / (8 * 7 * 6 * 5 * 4 * 3 * 2 * 1),
                -pow(2.0 * M_PI, 10) / (10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1),
        };

        struct qreg x_frac = ntq_shrink_sincos_input_range(c, src);
        struct qreg sum = qir_uniform_f(c, coeff[0]);
        struct qreg x2 = qir_FMUL(c, x_frac, x_frac);
        struct qreg x = x2; /* Current x^2, x^4, or x^6 */
        for (int i = 1; i < ARRAY_SIZE(coeff); i++) {
                if (i != 1)
                        x = qir_FMUL(c, x, x2);

                sum = qir_FADD(c, qir_FMUL(c,
                                           x,
                                           qir_uniform_f(c, coeff[i])),
                               sum);
        }
        return sum;
}

static struct qreg
ntq_fsign(struct vc4_compile *c, struct qreg src)
{
        struct qreg t = qir_get_temp(c);

        qir_SF(c, src);
        qir_MOV_dest(c, t, qir_uniform_f(c, 0.0));
        qir_MOV_dest(c, t, qir_uniform_f(c, 1.0))->cond = QPU_COND_ZC;
        qir_MOV_dest(c, t, qir_uniform_f(c, -1.0))->cond = QPU_COND_NS;
        return qir_MOV(c, t);
}

static void
emit_vertex_input(struct vc4_compile *c, int attr)
{
        enum pipe_format format = c->vs_key->attr_formats[attr];
        uint32_t attr_size = util_format_get_blocksize(format);

        c->vattr_sizes[attr] = align(attr_size, 4);
        for (int i = 0; i < align(attr_size, 4) / 4; i++) {
                c->inputs[attr * 4 + i] =
                        qir_MOV(c, qir_reg(QFILE_VPM, attr * 4 + i));
                c->num_inputs++;
        }
}

static void
emit_fragcoord_input(struct vc4_compile *c, int attr)
{
        c->inputs[attr * 4 + 0] = qir_ITOF(c, qir_reg(QFILE_FRAG_X, 0));
        c->inputs[attr * 4 + 1] = qir_ITOF(c, qir_reg(QFILE_FRAG_Y, 0));
        c->inputs[attr * 4 + 2] =
                qir_FMUL(c,
                         qir_ITOF(c, qir_FRAG_Z(c)),
                         qir_uniform_f(c, 1.0 / 0xffffff));
        c->inputs[attr * 4 + 3] = qir_RCP(c, qir_FRAG_W(c));
}

static struct qreg
emit_fragment_varying(struct vc4_compile *c, gl_varying_slot slot,
                      uint8_t swizzle)
{
        uint32_t i = c->num_input_slots++;
        struct qreg vary = {
                QFILE_VARY,
                i
        };

        if (c->num_input_slots >= c->input_slots_array_size) {
                c->input_slots_array_size =
                        MAX2(4, c->input_slots_array_size * 2);

                c->input_slots = reralloc(c, c->input_slots,
                                          struct vc4_varying_slot,
                                          c->input_slots_array_size);
        }

        c->input_slots[i].slot = slot;
        c->input_slots[i].swizzle = swizzle;

        return qir_VARY_ADD_C(c, qir_FMUL(c, vary, qir_FRAG_W(c)));
}

static void
emit_fragment_input(struct vc4_compile *c, int attr, gl_varying_slot slot)
{
        for (int i = 0; i < 4; i++) {
                c->inputs[attr * 4 + i] =
                        emit_fragment_varying(c, slot, i);
                c->num_inputs++;
        }
}

static void
add_output(struct vc4_compile *c,
           uint32_t decl_offset,
           uint8_t slot,
           uint8_t swizzle)
{
        uint32_t old_array_size = c->outputs_array_size;
        resize_qreg_array(c, &c->outputs, &c->outputs_array_size,
                          decl_offset + 1);

        if (old_array_size != c->outputs_array_size) {
                c->output_slots = reralloc(c,
                                           c->output_slots,
                                           struct vc4_varying_slot,
                                           c->outputs_array_size);
        }

        c->output_slots[decl_offset].slot = slot;
        c->output_slots[decl_offset].swizzle = swizzle;
}

static bool
ntq_src_is_only_ssa_def_user(nir_src *src)
{
        if (!src->is_ssa)
                return false;

        if (!list_is_empty(&src->ssa->if_uses))
                return false;

        return (src->ssa->uses.next == &src->use_link &&
                src->ssa->uses.next->next == &src->ssa->uses);
}

/**
 * In general, emits a nir_pack_unorm_4x8 as a series of MOVs with the pack
 * bit set.
 *
 * However, as an optimization, it tries to find the instructions generating
 * the sources to be packed and just emit the pack flag there, if possible.
 */
static void
ntq_emit_pack_unorm_4x8(struct vc4_compile *c, nir_alu_instr *instr)
{
        struct qreg result = qir_get_temp(c);
        struct nir_alu_instr *vec4 = NULL;

        /* If packing from a vec4 op (as expected), identify it so that we can
         * peek back at what generated its sources.
         */
        if (instr->src[0].src.is_ssa &&
            instr->src[0].src.ssa->parent_instr->type == nir_instr_type_alu &&
            nir_instr_as_alu(instr->src[0].src.ssa->parent_instr)->op ==
            nir_op_vec4) {
                vec4 = nir_instr_as_alu(instr->src[0].src.ssa->parent_instr);
        }

        /* If the pack is replicating the same channel 4 times, use the 8888
         * pack flag.  This is common for blending using the alpha
         * channel.
         */
        if (instr->src[0].swizzle[0] == instr->src[0].swizzle[1] &&
            instr->src[0].swizzle[0] == instr->src[0].swizzle[2] &&
            instr->src[0].swizzle[0] == instr->src[0].swizzle[3]) {
                struct qreg rep = ntq_get_src(c,
                                              instr->src[0].src,
                                              instr->src[0].swizzle[0]);
                ntq_store_dest(c, &instr->dest.dest, 0, qir_PACK_8888_F(c, rep));
                return;
        }

        for (int i = 0; i < 4; i++) {
                int swiz = instr->src[0].swizzle[i];
                struct qreg src;
                if (vec4) {
                        src = ntq_get_src(c, vec4->src[swiz].src,
                                          vec4->src[swiz].swizzle[0]);
                } else {
                        src = ntq_get_src(c, instr->src[0].src, swiz);
                }

                if (vec4 &&
                    ntq_src_is_only_ssa_def_user(&vec4->src[swiz].src) &&
                    src.file == QFILE_TEMP &&
                    c->defs[src.index] &&
                    qir_is_mul(c->defs[src.index]) &&
                    !c->defs[src.index]->dst.pack) {
                        struct qinst *rewrite = c->defs[src.index];
                        c->defs[src.index] = NULL;
                        rewrite->dst = result;
                        rewrite->dst.pack = QPU_PACK_MUL_8A + i;
                        continue;
                }

                qir_PACK_8_F(c, result, src, i);
        }

        ntq_store_dest(c, &instr->dest.dest, 0, qir_MOV(c, result));
}

/** Handles sign-extended bitfield extracts for 16 bits. */
static struct qreg
ntq_emit_ibfe(struct vc4_compile *c, struct qreg base, struct qreg offset,
              struct qreg bits)
{
        assert(bits.file == QFILE_UNIF &&
               c->uniform_contents[bits.index] == QUNIFORM_CONSTANT &&
               c->uniform_data[bits.index] == 16);

        assert(offset.file == QFILE_UNIF &&
               c->uniform_contents[offset.index] == QUNIFORM_CONSTANT);
        int offset_bit = c->uniform_data[offset.index];
        assert(offset_bit % 16 == 0);

        return qir_UNPACK_16_I(c, base, offset_bit / 16);
}

/** Handles unsigned bitfield extracts for 8 bits. */
static struct qreg
ntq_emit_ubfe(struct vc4_compile *c, struct qreg base, struct qreg offset,
              struct qreg bits)
{
        assert(bits.file == QFILE_UNIF &&
               c->uniform_contents[bits.index] == QUNIFORM_CONSTANT &&
               c->uniform_data[bits.index] == 8);

        assert(offset.file == QFILE_UNIF &&
               c->uniform_contents[offset.index] == QUNIFORM_CONSTANT);
        int offset_bit = c->uniform_data[offset.index];
        assert(offset_bit % 8 == 0);

        return qir_UNPACK_8_I(c, base, offset_bit / 8);
}

/**
 * If compare_instr is a valid comparison instruction, emits the
 * compare_instr's comparison and returns the sel_instr's return value based
 * on the compare_instr's result.
 */
static bool
ntq_emit_comparison(struct vc4_compile *c, struct qreg *dest,
                    nir_alu_instr *compare_instr,
                    nir_alu_instr *sel_instr)
{
        enum qpu_cond cond;

        switch (compare_instr->op) {
        case nir_op_feq32:
        case nir_op_ieq32:
        case nir_op_seq:
                cond = QPU_COND_ZS;
                break;
        case nir_op_fneu32:
        case nir_op_ine32:
        case nir_op_sne:
                cond = QPU_COND_ZC;
                break;
        case nir_op_fge32:
        case nir_op_ige32:
        case nir_op_uge32:
        case nir_op_sge:
                cond = QPU_COND_NC;
                break;
        case nir_op_flt32:
        case nir_op_ilt32:
        case nir_op_slt:
                cond = QPU_COND_NS;
                break;
        default:
                return false;
        }

        struct qreg src0 = ntq_get_alu_src(c, compare_instr, 0);
        struct qreg src1 = ntq_get_alu_src(c, compare_instr, 1);

        unsigned unsized_type =
                nir_alu_type_get_base_type(nir_op_infos[compare_instr->op].input_types[0]);
        if (unsized_type == nir_type_float)
                qir_SF(c, qir_FSUB(c, src0, src1));
        else
                qir_SF(c, qir_SUB(c, src0, src1));

        switch (sel_instr->op) {
        case nir_op_seq:
        case nir_op_sne:
        case nir_op_sge:
        case nir_op_slt:
                *dest = qir_SEL(c, cond,
                                qir_uniform_f(c, 1.0), qir_uniform_f(c, 0.0));
                break;

        case nir_op_b32csel:
                *dest = qir_SEL(c, cond,
                                ntq_get_alu_src(c, sel_instr, 1),
                                ntq_get_alu_src(c, sel_instr, 2));
                break;

        default:
                *dest = qir_SEL(c, cond,
                                qir_uniform_ui(c, ~0), qir_uniform_ui(c, 0));
                break;
        }

        /* Make the temporary for nir_store_dest(). */
        *dest = qir_MOV(c, *dest);

        return true;
}

/**
 * Attempts to fold a comparison generating a boolean result into the
 * condition code for selecting between two values, instead of comparing the
 * boolean result against 0 to generate the condition code.
 */
static struct qreg ntq_emit_bcsel(struct vc4_compile *c, nir_alu_instr *instr,
                                  struct qreg *src)
{
        if (!instr->src[0].src.is_ssa)
                goto out;
        if (instr->src[0].src.ssa->parent_instr->type != nir_instr_type_alu)
                goto out;
        nir_alu_instr *compare =
                nir_instr_as_alu(instr->src[0].src.ssa->parent_instr);
        if (!compare)
                goto out;

        struct qreg dest;
        if (ntq_emit_comparison(c, &dest, compare, instr))
                return dest;

out:
        qir_SF(c, src[0]);
        return qir_MOV(c, qir_SEL(c, QPU_COND_NS, src[1], src[2]));
}

static struct qreg
ntq_fddx(struct vc4_compile *c, struct qreg src)
{
        /* Make sure that we have a bare temp to use for MUL rotation, so it
         * can be allocated to an accumulator.
         */
        if (src.pack || src.file != QFILE_TEMP)
                src = qir_MOV(c, src);

        struct qreg from_left = qir_ROT_MUL(c, src, 1);
        struct qreg from_right = qir_ROT_MUL(c, src, 15);

        /* Distinguish left/right pixels of the quad. */
        qir_SF(c, qir_AND(c, qir_reg(QFILE_QPU_ELEMENT, 0),
                          qir_uniform_ui(c, 1)));

        return qir_MOV(c, qir_SEL(c, QPU_COND_ZS,
                                  qir_FSUB(c, from_right, src),
                                  qir_FSUB(c, src, from_left)));
}

static struct qreg
ntq_fddy(struct vc4_compile *c, struct qreg src)
{
        if (src.pack || src.file != QFILE_TEMP)
                src = qir_MOV(c, src);

        struct qreg from_bottom = qir_ROT_MUL(c, src, 2);
        struct qreg from_top = qir_ROT_MUL(c, src, 14);

        /* Distinguish top/bottom pixels of the quad. */
        qir_SF(c, qir_AND(c,
                          qir_reg(QFILE_QPU_ELEMENT, 0),
                          qir_uniform_ui(c, 2)));

        return qir_MOV(c, qir_SEL(c, QPU_COND_ZS,
                                  qir_FSUB(c, from_top, src),
                                  qir_FSUB(c, src, from_bottom)));
}

static void
ntq_emit_alu(struct vc4_compile *c, nir_alu_instr *instr)
{
        /* This should always be lowered to ALU operations for VC4. */
        assert(!instr->dest.saturate);

        /* Vectors are special in that they have non-scalarized writemasks,
         * and just take the first swizzle channel for each argument in order
         * into each writemask channel.
         */
        if (instr->op == nir_op_vec2 ||
            instr->op == nir_op_vec3 ||
            instr->op == nir_op_vec4) {
                struct qreg srcs[4];
                for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
                        srcs[i] = ntq_get_src(c, instr->src[i].src,
                                              instr->src[i].swizzle[0]);
                for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
                        ntq_store_dest(c, &instr->dest.dest, i,
                                       qir_MOV(c, srcs[i]));
                return;
        }

        if (instr->op == nir_op_pack_unorm_4x8) {
                ntq_emit_pack_unorm_4x8(c, instr);
                return;
        }

        if (instr->op == nir_op_unpack_unorm_4x8) {
                struct qreg src = ntq_get_src(c, instr->src[0].src,
                                              instr->src[0].swizzle[0]);
                for (int i = 0; i < 4; i++) {
                        if (instr->dest.write_mask & (1 << i))
                                ntq_store_dest(c, &instr->dest.dest, i,
                                               qir_UNPACK_8_F(c, src, i));
                }
                return;
        }

        /* General case: We can just grab the one used channel per src. */
        struct qreg src[nir_op_infos[instr->op].num_inputs];
        for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
                src[i] = ntq_get_alu_src(c, instr, i);
        }

        struct qreg result;

        switch (instr->op) {
        case nir_op_mov:
                result = qir_MOV(c, src[0]);
                break;
        case nir_op_fmul:
                result = qir_FMUL(c, src[0], src[1]);
                break;
        case nir_op_fadd:
                result = qir_FADD(c, src[0], src[1]);
                break;
        case nir_op_fsub:
                result = qir_FSUB(c, src[0], src[1]);
                break;
        case nir_op_fmin:
                result = qir_FMIN(c, src[0], src[1]);
                break;
        case nir_op_fmax:
                result = qir_FMAX(c, src[0], src[1]);
                break;

        case nir_op_f2i32:
        case nir_op_f2u32:
                result = qir_FTOI(c, src[0]);
                break;
        case nir_op_i2f32:
        case nir_op_u2f32:
                result = qir_ITOF(c, src[0]);
                break;
        case nir_op_b2f32:
                result = qir_AND(c, src[0], qir_uniform_f(c, 1.0));
                break;
        case nir_op_b2i32:
                result = qir_AND(c, src[0], qir_uniform_ui(c, 1));
                break;
        case nir_op_i2b32:
        case nir_op_f2b32:
                qir_SF(c, src[0]);
                result = qir_MOV(c, qir_SEL(c, QPU_COND_ZC,
                                            qir_uniform_ui(c, ~0),
                                            qir_uniform_ui(c, 0)));
                break;

        case nir_op_iadd:
                result = qir_ADD(c, src[0], src[1]);
                break;
        case nir_op_ushr:
                result = qir_SHR(c, src[0], src[1]);
                break;
        case nir_op_isub:
                result = qir_SUB(c, src[0], src[1]);
                break;
        case nir_op_ishr:
                result = qir_ASR(c, src[0], src[1]);
                break;
        case nir_op_ishl:
                result = qir_SHL(c, src[0], src[1]);
                break;
        case nir_op_imin:
                result = qir_MIN(c, src[0], src[1]);
                break;
        case nir_op_imax:
                result = qir_MAX(c, src[0], src[1]);
                break;
        case nir_op_iand:
                result = qir_AND(c, src[0], src[1]);
                break;
        case nir_op_ior:
                result = qir_OR(c, src[0], src[1]);
                break;
        case nir_op_ixor:
                result = qir_XOR(c, src[0], src[1]);
                break;
        case nir_op_inot:
                result = qir_NOT(c, src[0]);
                break;

        case nir_op_imul:
                result = ntq_umul(c, src[0], src[1]);
                break;

        case nir_op_seq:
        case nir_op_sne:
        case nir_op_sge:
        case nir_op_slt:
        case nir_op_feq32:
        case nir_op_fneu32:
        case nir_op_fge32:
        case nir_op_flt32:
        case nir_op_ieq32:
        case nir_op_ine32:
        case nir_op_ige32:
        case nir_op_uge32:
        case nir_op_ilt32:
                if (!ntq_emit_comparison(c, &result, instr, instr)) {
                        fprintf(stderr, "Bad comparison instruction\n");
                }
                break;

        case nir_op_b32csel:
                result = ntq_emit_bcsel(c, instr, src);
                break;
        case nir_op_fcsel:
                qir_SF(c, src[0]);
                result = qir_MOV(c, qir_SEL(c, QPU_COND_ZC, src[1], src[2]));
                break;

        case nir_op_frcp:
                result = ntq_rcp(c, src[0]);
                break;
        case nir_op_frsq:
                result = ntq_rsq(c, src[0]);
                break;
        case nir_op_fexp2:
                result = qir_EXP2(c, src[0]);
                break;
        case nir_op_flog2:
                result = qir_LOG2(c, src[0]);
                break;

        case nir_op_ftrunc:
                result = qir_ITOF(c, qir_FTOI(c, src[0]));
                break;
        case nir_op_fceil:
                result = ntq_fceil(c, src[0]);
                break;
        case nir_op_ffract:
                result = ntq_ffract(c, src[0]);
                break;
        case nir_op_ffloor:
                result = ntq_ffloor(c, src[0]);
                break;

        case nir_op_fsin:
                result = ntq_fsin(c, src[0]);
                break;
        case nir_op_fcos:
                result = ntq_fcos(c, src[0]);
                break;

        case nir_op_fsign:
                result = ntq_fsign(c, src[0]);
                break;

        case nir_op_fabs:
                result = qir_FMAXABS(c, src[0], src[0]);
                break;
        case nir_op_iabs:
                result = qir_MAX(c, src[0],
                                qir_SUB(c, qir_uniform_ui(c, 0), src[0]));
                break;

        case nir_op_ibitfield_extract:
                result = ntq_emit_ibfe(c, src[0], src[1], src[2]);
                break;

        case nir_op_ubitfield_extract:
                result = ntq_emit_ubfe(c, src[0], src[1], src[2]);
                break;

        case nir_op_usadd_4x8:
                result = qir_V8ADDS(c, src[0], src[1]);
                break;

        case nir_op_ussub_4x8:
                result = qir_V8SUBS(c, src[0], src[1]);
                break;

        case nir_op_umin_4x8:
                result = qir_V8MIN(c, src[0], src[1]);
                break;

        case nir_op_umax_4x8:
                result = qir_V8MAX(c, src[0], src[1]);
                break;

        case nir_op_umul_unorm_4x8:
                result = qir_V8MULD(c, src[0], src[1]);
                break;

        case nir_op_fddx:
        case nir_op_fddx_coarse:
        case nir_op_fddx_fine:
                result = ntq_fddx(c, src[0]);
                break;

        case nir_op_fddy:
        case nir_op_fddy_coarse:
        case nir_op_fddy_fine:
                result = ntq_fddy(c, src[0]);
                break;

        default:
                fprintf(stderr, "unknown NIR ALU inst: ");
                nir_print_instr(&instr->instr, stderr);
                fprintf(stderr, "\n");
                abort();
        }

        /* We have a scalar result, so the instruction should only have a
         * single channel written to.
         */
        assert(util_is_power_of_two_or_zero(instr->dest.write_mask));
        ntq_store_dest(c, &instr->dest.dest,
                       ffs(instr->dest.write_mask) - 1, result);
}

static void
emit_frag_end(struct vc4_compile *c)
{
        struct qreg color;
        if (c->output_color_index != -1) {
                color = c->outputs[c->output_color_index];
        } else {
                color = qir_uniform_ui(c, 0);
        }

        uint32_t discard_cond = QPU_COND_ALWAYS;
        if (c->s->info.fs.uses_discard) {
                qir_SF(c, c->discard);
                discard_cond = QPU_COND_ZS;
        }

        if (c->fs_key->stencil_enabled) {
                qir_MOV_dest(c, qir_reg(QFILE_TLB_STENCIL_SETUP, 0),
                             qir_uniform(c, QUNIFORM_STENCIL, 0));
                if (c->fs_key->stencil_twoside) {
                        qir_MOV_dest(c, qir_reg(QFILE_TLB_STENCIL_SETUP, 0),
                                     qir_uniform(c, QUNIFORM_STENCIL, 1));
                }
                if (c->fs_key->stencil_full_writemasks) {
                        qir_MOV_dest(c, qir_reg(QFILE_TLB_STENCIL_SETUP, 0),
                                     qir_uniform(c, QUNIFORM_STENCIL, 2));
                }
        }

        if (c->output_sample_mask_index != -1) {
                qir_MS_MASK(c, c->outputs[c->output_sample_mask_index]);
        }

        if (c->fs_key->depth_enabled) {
                if (c->output_position_index != -1) {
                        qir_FTOI_dest(c, qir_reg(QFILE_TLB_Z_WRITE, 0),
                                      qir_FMUL(c,
                                               c->outputs[c->output_position_index],
                                               qir_uniform_f(c, 0xffffff)))->cond = discard_cond;
                } else {
                        qir_MOV_dest(c, qir_reg(QFILE_TLB_Z_WRITE, 0),
                                     qir_FRAG_Z(c))->cond = discard_cond;
                }
        }

        if (!c->msaa_per_sample_output) {
                qir_MOV_dest(c, qir_reg(QFILE_TLB_COLOR_WRITE, 0),
                             color)->cond = discard_cond;
        } else {
                for (int i = 0; i < VC4_MAX_SAMPLES; i++) {
                        qir_MOV_dest(c, qir_reg(QFILE_TLB_COLOR_WRITE_MS, 0),
                                     c->sample_colors[i])->cond = discard_cond;
                }
        }
}

static void
emit_scaled_viewport_write(struct vc4_compile *c, struct qreg rcp_w)
{
        struct qreg packed = qir_get_temp(c);

        for (int i = 0; i < 2; i++) {
                struct qreg scale =
                        qir_uniform(c, QUNIFORM_VIEWPORT_X_SCALE + i, 0);

                struct qreg packed_chan = packed;
                packed_chan.pack = QPU_PACK_A_16A + i;

                qir_FTOI_dest(c, packed_chan,
                              qir_FMUL(c,
                                       qir_FMUL(c,
                                                c->outputs[c->output_position_index + i],
                                                scale),
                                       rcp_w));
        }

        qir_VPM_WRITE(c, packed);
}

static void
emit_zs_write(struct vc4_compile *c, struct qreg rcp_w)
{
        struct qreg zscale = qir_uniform(c, QUNIFORM_VIEWPORT_Z_SCALE, 0);
        struct qreg zoffset = qir_uniform(c, QUNIFORM_VIEWPORT_Z_OFFSET, 0);

        qir_VPM_WRITE(c, qir_FADD(c, qir_FMUL(c, qir_FMUL(c,
                                                          c->outputs[c->output_position_index + 2],
                                                          zscale),
                                              rcp_w),
                                  zoffset));
}

static void
emit_rcp_wc_write(struct vc4_compile *c, struct qreg rcp_w)
{
        qir_VPM_WRITE(c, rcp_w);
}

static void
emit_point_size_write(struct vc4_compile *c)
{
        struct qreg point_size;

        if (c->output_point_size_index != -1)
                point_size = c->outputs[c->output_point_size_index];
        else
                point_size = qir_uniform_f(c, 1.0);

        qir_VPM_WRITE(c, point_size);
}

/**
 * Emits a VPM read of the stub vertex attribute set up by vc4_draw.c.
 *
 * The simulator insists that there be at least one vertex attribute, so
 * vc4_draw.c will emit one if it wouldn't have otherwise.  The simulator also
 * insists that all vertex attributes loaded get read by the VS/CS, so we have
 * to consume it here.
 */
static void
emit_stub_vpm_read(struct vc4_compile *c)
{
        if (c->num_inputs)
                return;

        c->vattr_sizes[0] = 4;
        (void)qir_MOV(c, qir_reg(QFILE_VPM, 0));
        c->num_inputs++;
}

static void
emit_vert_end(struct vc4_compile *c,
              struct vc4_varying_slot *fs_inputs,
              uint32_t num_fs_inputs)
{
        struct qreg rcp_w = ntq_rcp(c, c->outputs[c->output_position_index + 3]);

        emit_stub_vpm_read(c);

        emit_scaled_viewport_write(c, rcp_w);
        emit_zs_write(c, rcp_w);
        emit_rcp_wc_write(c, rcp_w);
        if (c->vs_key->per_vertex_point_size)
                emit_point_size_write(c);

        for (int i = 0; i < num_fs_inputs; i++) {
                struct vc4_varying_slot *input = &fs_inputs[i];
                int j;

                for (j = 0; j < c->num_outputs; j++) {
                        struct vc4_varying_slot *output =
                                &c->output_slots[j];

                        if (input->slot == output->slot &&
                            input->swizzle == output->swizzle) {
                                qir_VPM_WRITE(c, c->outputs[j]);
                                break;
                        }
                }
                /* Emit padding if we didn't find a declared VS output for
                 * this FS input.
                 */
                if (j == c->num_outputs)
                        qir_VPM_WRITE(c, qir_uniform_f(c, 0.0));
        }
}

static void
emit_coord_end(struct vc4_compile *c)
{
        struct qreg rcp_w = ntq_rcp(c, c->outputs[c->output_position_index + 3]);

        emit_stub_vpm_read(c);

        for (int i = 0; i < 4; i++)
                qir_VPM_WRITE(c, c->outputs[c->output_position_index + i]);

        emit_scaled_viewport_write(c, rcp_w);
        emit_zs_write(c, rcp_w);
        emit_rcp_wc_write(c, rcp_w);
        if (c->vs_key->per_vertex_point_size)
                emit_point_size_write(c);
}

static void
vc4_optimize_nir(struct nir_shader *s)
{
        bool progress;
        unsigned lower_flrp =
                (s->options->lower_flrp16 ? 16 : 0) |
                (s->options->lower_flrp32 ? 32 : 0) |
                (s->options->lower_flrp64 ? 64 : 0);

        do {
                progress = false;

                NIR_PASS_V(s, nir_lower_vars_to_ssa);
                NIR_PASS(progress, s, nir_lower_alu_to_scalar, NULL, NULL);
                NIR_PASS(progress, s, nir_lower_phis_to_scalar);
                NIR_PASS(progress, s, nir_copy_prop);
                NIR_PASS(progress, s, nir_opt_remove_phis);
                NIR_PASS(progress, s, nir_opt_dce);
                NIR_PASS(progress, s, nir_opt_dead_cf);
                NIR_PASS(progress, s, nir_opt_cse);
                NIR_PASS(progress, s, nir_opt_peephole_select, 8, true, true);
                NIR_PASS(progress, s, nir_opt_algebraic);
                NIR_PASS(progress, s, nir_opt_constant_folding);
                if (lower_flrp != 0) {
                        bool lower_flrp_progress = false;

                        NIR_PASS(lower_flrp_progress, s, nir_lower_flrp,
                                 lower_flrp,
                                 false /* always_precise */,
                                 s->options->lower_ffma);
                        if (lower_flrp_progress) {
                                NIR_PASS(progress, s, nir_opt_constant_folding);
                                progress = true;
                        }

                        /* Nothing should rematerialize any flrps, so we only
                         * need to do this lowering once.
                         */
                        lower_flrp = 0;
                }

                NIR_PASS(progress, s, nir_opt_undef);
                NIR_PASS(progress, s, nir_opt_loop_unroll,
                         nir_var_shader_in |
                         nir_var_shader_out |
                         nir_var_function_temp);
        } while (progress);
}

static int
driver_location_compare(const void *in_a, const void *in_b)
{
        const nir_variable *const *a = in_a;
        const nir_variable *const *b = in_b;

        return (*a)->data.driver_location - (*b)->data.driver_location;
}

static void
ntq_setup_inputs(struct vc4_compile *c)
{
        unsigned num_entries = 0;
        nir_foreach_shader_in_variable(var, c->s)
                num_entries++;

        nir_variable *vars[num_entries];

        unsigned i = 0;
        nir_foreach_shader_in_variable(var, c->s)
                vars[i++] = var;

        /* Sort the variables so that we emit the input setup in
         * driver_location order.  This is required for VPM reads, whose data
         * is fetched into the VPM in driver_location (TGSI register index)
         * order.
         */
        qsort(&vars, num_entries, sizeof(*vars), driver_location_compare);

        for (unsigned i = 0; i < num_entries; i++) {
                nir_variable *var = vars[i];
                unsigned array_len = MAX2(glsl_get_length(var->type), 1);
                unsigned loc = var->data.driver_location;

                assert(array_len == 1);
                (void)array_len;
                resize_qreg_array(c, &c->inputs, &c->inputs_array_size,
                                  (loc + 1) * 4);

                if (c->stage == QSTAGE_FRAG) {
                        if (var->data.location == VARYING_SLOT_POS) {
                                emit_fragcoord_input(c, loc);
                        } else if (util_varying_is_point_coord(var->data.location,
                                                               c->fs_key->point_sprite_mask)) {
                                c->inputs[loc * 4 + 0] = c->point_x;
                                c->inputs[loc * 4 + 1] = c->point_y;
                        } else {
                                emit_fragment_input(c, loc, var->data.location);
                        }
                } else {
                        emit_vertex_input(c, loc);
                }
        }
}

static void
ntq_setup_outputs(struct vc4_compile *c)
{
        nir_foreach_shader_out_variable(var, c->s) {
                unsigned array_len = MAX2(glsl_get_length(var->type), 1);
                unsigned loc = var->data.driver_location * 4;

                assert(array_len == 1);
                (void)array_len;

                for (int i = 0; i < 4; i++)
                        add_output(c, loc + i, var->data.location, i);

                if (c->stage == QSTAGE_FRAG) {
                        switch (var->data.location) {
                        case FRAG_RESULT_COLOR:
                        case FRAG_RESULT_DATA0:
                                c->output_color_index = loc;
                                break;
                        case FRAG_RESULT_DEPTH:
                                c->output_position_index = loc;
                                break;
                        case FRAG_RESULT_SAMPLE_MASK:
                                c->output_sample_mask_index = loc;
                                break;
                        }
                } else {
                        switch (var->data.location) {
                        case VARYING_SLOT_POS:
                                c->output_position_index = loc;
                                break;
                        case VARYING_SLOT_PSIZ:
                                c->output_point_size_index = loc;
                                break;
                        }
                }
        }
}

/**
 * Sets up the mapping from nir_register to struct qreg *.
 *
 * Each nir_register gets a struct qreg per 32-bit component being stored.
 */
static void
ntq_setup_registers(struct vc4_compile *c, struct exec_list *list)
{
        foreach_list_typed(nir_register, nir_reg, node, list) {
                unsigned array_len = MAX2(nir_reg->num_array_elems, 1);
                struct qreg *qregs = ralloc_array(c->def_ht, struct qreg,
                                                  array_len *
                                                  nir_reg->num_components);

                _mesa_hash_table_insert(c->def_ht, nir_reg, qregs);

                for (int i = 0; i < array_len * nir_reg->num_components; i++)
                        qregs[i] = qir_get_temp(c);
        }
}

static void
ntq_emit_load_const(struct vc4_compile *c, nir_load_const_instr *instr)
{
        struct qreg *qregs = ntq_init_ssa_def(c, &instr->def);
        for (int i = 0; i < instr->def.num_components; i++)
                qregs[i] = qir_uniform_ui(c, instr->value[i].u32);

        _mesa_hash_table_insert(c->def_ht, &instr->def, qregs);
}

static void
ntq_emit_ssa_undef(struct vc4_compile *c, nir_ssa_undef_instr *instr)
{
        struct qreg *qregs = ntq_init_ssa_def(c, &instr->def);

        /* QIR needs there to be *some* value, so pick 0 (same as for
         * ntq_setup_registers().
         */
        for (int i = 0; i < instr->def.num_components; i++)
                qregs[i] = qir_uniform_ui(c, 0);
}

static void
ntq_emit_color_read(struct vc4_compile *c, nir_intrinsic_instr *instr)
{
        assert(nir_src_as_uint(instr->src[0]) == 0);

        /* Reads of the per-sample color need to be done in
         * order.
         */
        int sample_index = (nir_intrinsic_base(instr) -
                            VC4_NIR_TLB_COLOR_READ_INPUT);
        for (int i = 0; i <= sample_index; i++) {
                if (c->color_reads[i].file == QFILE_NULL) {
                        c->color_reads[i] =
                                qir_TLB_COLOR_READ(c);
                }
        }
        ntq_store_dest(c, &instr->dest, 0,
                       qir_MOV(c, c->color_reads[sample_index]));
}

static void
ntq_emit_load_input(struct vc4_compile *c, nir_intrinsic_instr *instr)
{
        assert(instr->num_components == 1);
        assert(nir_src_is_const(instr->src[0]) &&
               "vc4 doesn't support indirect inputs");

        if (c->stage == QSTAGE_FRAG &&
            nir_intrinsic_base(instr) >= VC4_NIR_TLB_COLOR_READ_INPUT) {
                ntq_emit_color_read(c, instr);
                return;
        }

        uint32_t offset = nir_intrinsic_base(instr) +
                          nir_src_as_uint(instr->src[0]);
        int comp = nir_intrinsic_component(instr);
        ntq_store_dest(c, &instr->dest, 0,
                       qir_MOV(c, c->inputs[offset * 4 + comp]));
}

static void
ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
{
        unsigned offset;

        switch (instr->intrinsic) {
        case nir_intrinsic_load_uniform:
                assert(instr->num_components == 1);
                if (nir_src_is_const(instr->src[0])) {
                        offset = nir_intrinsic_base(instr) +
                                 nir_src_as_uint(instr->src[0]);
                        assert(offset % 4 == 0);
                        /* We need dwords */
                        offset = offset / 4;
                        ntq_store_dest(c, &instr->dest, 0,
                                       qir_uniform(c, QUNIFORM_UNIFORM,
                                                   offset));
                } else {
                        ntq_store_dest(c, &instr->dest, 0,
                                       indirect_uniform_load(c, instr));
                }
                break;

        case nir_intrinsic_load_ubo:
                assert(instr->num_components == 1);
                ntq_store_dest(c, &instr->dest, 0, vc4_ubo_load(c, instr));
                break;

        case nir_intrinsic_load_user_clip_plane:
                for (int i = 0; i < nir_intrinsic_dest_components(instr); i++) {
                        ntq_store_dest(c, &instr->dest, i,
                                       qir_uniform(c, QUNIFORM_USER_CLIP_PLANE,
                                                   nir_intrinsic_ucp_id(instr) *
                                                   4 + i));
                }
                break;

        case nir_intrinsic_load_blend_const_color_r_float:
        case nir_intrinsic_load_blend_const_color_g_float:
        case nir_intrinsic_load_blend_const_color_b_float:
        case nir_intrinsic_load_blend_const_color_a_float:
                ntq_store_dest(c, &instr->dest, 0,
                               qir_uniform(c, QUNIFORM_BLEND_CONST_COLOR_X +
                                           (instr->intrinsic -
                                            nir_intrinsic_load_blend_const_color_r_float),
                                           0));
                break;

        case nir_intrinsic_load_blend_const_color_rgba8888_unorm:
                ntq_store_dest(c, &instr->dest, 0,
                               qir_uniform(c, QUNIFORM_BLEND_CONST_COLOR_RGBA,
                                           0));
                break;

        case nir_intrinsic_load_blend_const_color_aaaa8888_unorm:
                ntq_store_dest(c, &instr->dest, 0,
                               qir_uniform(c, QUNIFORM_BLEND_CONST_COLOR_AAAA,
                                           0));
                break;

        case nir_intrinsic_load_alpha_ref_float:
                ntq_store_dest(c, &instr->dest, 0,
                               qir_uniform(c, QUNIFORM_ALPHA_REF, 0));
                break;

        case nir_intrinsic_load_sample_mask_in:
                ntq_store_dest(c, &instr->dest, 0,
                               qir_uniform(c, QUNIFORM_SAMPLE_MASK, 0));
                break;

        case nir_intrinsic_load_front_face:
                /* The register contains 0 (front) or 1 (back), and we need to
                 * turn it into a NIR bool where true means front.
                 */
                ntq_store_dest(c, &instr->dest, 0,
                               qir_ADD(c,
                                       qir_uniform_ui(c, -1),
                                       qir_reg(QFILE_FRAG_REV_FLAG, 0)));
                break;

        case nir_intrinsic_load_input:
                ntq_emit_load_input(c, instr);
                break;

        case nir_intrinsic_store_output:
                assert(nir_src_is_const(instr->src[1]) &&
                       "vc4 doesn't support indirect outputs");
                offset = nir_intrinsic_base(instr) +
                         nir_src_as_uint(instr->src[1]);

                /* MSAA color outputs are the only case where we have an
                 * output that's not lowered to being a store of a single 32
                 * bit value.
                 */
                if (c->stage == QSTAGE_FRAG && instr->num_components == 4) {
                        assert(offset == c->output_color_index);
                        for (int i = 0; i < 4; i++) {
                                c->sample_colors[i] =
                                        qir_MOV(c, ntq_get_src(c, instr->src[0],
                                                               i));
                        }
                } else {
                        offset = offset * 4 + nir_intrinsic_component(instr);
                        assert(instr->num_components == 1);
                        c->outputs[offset] =
                                qir_MOV(c, ntq_get_src(c, instr->src[0], 0));
                        c->num_outputs = MAX2(c->num_outputs, offset + 1);
                }
                break;

        case nir_intrinsic_discard:
                if (c->execute.file != QFILE_NULL) {
                        qir_SF(c, c->execute);
                        qir_MOV_cond(c, QPU_COND_ZS, c->discard,
                                     qir_uniform_ui(c, ~0));
                } else {
                        qir_MOV_dest(c, c->discard, qir_uniform_ui(c, ~0));
                }
                break;

        case nir_intrinsic_discard_if: {
                /* true (~0) if we're discarding */
                struct qreg cond = ntq_get_src(c, instr->src[0], 0);

                if (c->execute.file != QFILE_NULL) {
                        /* execute == 0 means the channel is active.  Invert
                         * the condition so that we can use zero as "executing
                         * and discarding."
                         */
                        qir_SF(c, qir_AND(c, c->execute, qir_NOT(c, cond)));
                        qir_MOV_cond(c, QPU_COND_ZS, c->discard, cond);
                } else {
                        qir_OR_dest(c, c->discard, c->discard,
                                    ntq_get_src(c, instr->src[0], 0));
                }

                break;
        }

        default:
                fprintf(stderr, "Unknown intrinsic: ");
                nir_print_instr(&instr->instr, stderr);
                fprintf(stderr, "\n");
                break;
        }
}

/* Clears (activates) the execute flags for any channels whose jump target
 * matches this block.
 */
static void
ntq_activate_execute_for_block(struct vc4_compile *c)
{
        qir_SF(c, qir_SUB(c,
                          c->execute,
                          qir_uniform_ui(c, c->cur_block->index)));
        qir_MOV_cond(c, QPU_COND_ZS, c->execute, qir_uniform_ui(c, 0));
}

static void
ntq_emit_if(struct vc4_compile *c, nir_if *if_stmt)
{
        if (!c->vc4->screen->has_control_flow) {
                fprintf(stderr,
                        "IF statement support requires updated kernel.\n");
                return;
        }

        nir_block *nir_else_block = nir_if_first_else_block(if_stmt);
        bool empty_else_block =
                (nir_else_block == nir_if_last_else_block(if_stmt) &&
                 exec_list_is_empty(&nir_else_block->instr_list));

        struct qblock *then_block = qir_new_block(c);
        struct qblock *after_block = qir_new_block(c);
        struct qblock *else_block;
        if (empty_else_block)
                else_block = after_block;
        else
                else_block = qir_new_block(c);

        bool was_top_level = false;
        if (c->execute.file == QFILE_NULL) {
                c->execute = qir_MOV(c, qir_uniform_ui(c, 0));
                was_top_level = true;
        }

        /* Set ZS for executing (execute == 0) and jumping (if->condition ==
         * 0) channels, and then update execute flags for those to point to
         * the ELSE block.
         */
        qir_SF(c, qir_OR(c,
                         c->execute,
                         ntq_get_src(c, if_stmt->condition, 0)));
        qir_MOV_cond(c, QPU_COND_ZS, c->execute,
                     qir_uniform_ui(c, else_block->index));

        /* Jump to ELSE if nothing is active for THEN, otherwise fall
         * through.
         */
        qir_SF(c, c->execute);
        qir_BRANCH(c, QPU_COND_BRANCH_ALL_ZC);
        qir_link_blocks(c->cur_block, else_block);
        qir_link_blocks(c->cur_block, then_block);

        /* Process the THEN block. */
        qir_set_emit_block(c, then_block);
        ntq_emit_cf_list(c, &if_stmt->then_list);

        if (!empty_else_block) {
                /* Handle the end of the THEN block.  First, all currently
                 * active channels update their execute flags to point to
                 * ENDIF
                 */
                qir_SF(c, c->execute);
                qir_MOV_cond(c, QPU_COND_ZS, c->execute,
                             qir_uniform_ui(c, after_block->index));

                /* If everything points at ENDIF, then jump there immediately. */
                qir_SF(c, qir_SUB(c, c->execute, qir_uniform_ui(c, after_block->index)));
                qir_BRANCH(c, QPU_COND_BRANCH_ALL_ZS);
                qir_link_blocks(c->cur_block, after_block);
                qir_link_blocks(c->cur_block, else_block);

                qir_set_emit_block(c, else_block);
                ntq_activate_execute_for_block(c);
                ntq_emit_cf_list(c, &if_stmt->else_list);
        }

        qir_link_blocks(c->cur_block, after_block);

        qir_set_emit_block(c, after_block);
        if (was_top_level) {
                c->execute = c->undef;
                c->last_top_block = c->cur_block;
        } else {
                ntq_activate_execute_for_block(c);
        }
}

static void
ntq_emit_jump(struct vc4_compile *c, nir_jump_instr *jump)
{
        struct qblock *jump_block;
        switch (jump->type) {
        case nir_jump_break:
                jump_block = c->loop_break_block;
                break;
        case nir_jump_continue:
                jump_block = c->loop_cont_block;
                break;
        default:
                unreachable("Unsupported jump type\n");
        }

        qir_SF(c, c->execute);
        qir_MOV_cond(c, QPU_COND_ZS, c->execute,
                     qir_uniform_ui(c, jump_block->index));

        /* Jump to the destination block if everyone has taken the jump. */
        qir_SF(c, qir_SUB(c, c->execute, qir_uniform_ui(c, jump_block->index)));
        qir_BRANCH(c, QPU_COND_BRANCH_ALL_ZS);
        struct qblock *new_block = qir_new_block(c);
        qir_link_blocks(c->cur_block, jump_block);
        qir_link_blocks(c->cur_block, new_block);
        qir_set_emit_block(c, new_block);
}

static void
ntq_emit_instr(struct vc4_compile *c, nir_instr *instr)
{
        switch (instr->type) {
        case nir_instr_type_alu:
                ntq_emit_alu(c, nir_instr_as_alu(instr));
                break;

        case nir_instr_type_intrinsic:
                ntq_emit_intrinsic(c, nir_instr_as_intrinsic(instr));
                break;

        case nir_instr_type_load_const:
                ntq_emit_load_const(c, nir_instr_as_load_const(instr));
                break;

        case nir_instr_type_ssa_undef:
                ntq_emit_ssa_undef(c, nir_instr_as_ssa_undef(instr));
                break;

        case nir_instr_type_tex:
                ntq_emit_tex(c, nir_instr_as_tex(instr));
                break;

        case nir_instr_type_jump:
                ntq_emit_jump(c, nir_instr_as_jump(instr));
                break;

        default:
                fprintf(stderr, "Unknown NIR instr type: ");
                nir_print_instr(instr, stderr);
                fprintf(stderr, "\n");
                abort();
        }
}

static void
ntq_emit_block(struct vc4_compile *c, nir_block *block)
{
        nir_foreach_instr(instr, block) {
                ntq_emit_instr(c, instr);
        }
}

static void ntq_emit_cf_list(struct vc4_compile *c, struct exec_list *list);

static void
ntq_emit_loop(struct vc4_compile *c, nir_loop *loop)
{
        if (!c->vc4->screen->has_control_flow) {
                fprintf(stderr,
                        "loop support requires updated kernel.\n");
                ntq_emit_cf_list(c, &loop->body);
                return;
        }

        bool was_top_level = false;
        if (c->execute.file == QFILE_NULL) {
                c->execute = qir_MOV(c, qir_uniform_ui(c, 0));
                was_top_level = true;
        }

        struct qblock *save_loop_cont_block = c->loop_cont_block;
        struct qblock *save_loop_break_block = c->loop_break_block;

        c->loop_cont_block = qir_new_block(c);
        c->loop_break_block = qir_new_block(c);

        qir_link_blocks(c->cur_block, c->loop_cont_block);
        qir_set_emit_block(c, c->loop_cont_block);
        ntq_activate_execute_for_block(c);

        ntq_emit_cf_list(c, &loop->body);

        /* If anything had explicitly continued, or is here at the end of the
         * loop, then we need to loop again.  SF updates are masked by the
         * instruction's condition, so we can do the OR of the two conditions
         * within SF.
         */
        qir_SF(c, c->execute);
        struct qinst *cont_check =
                qir_SUB_dest(c,
                             c->undef,
                             c->execute,
                             qir_uniform_ui(c, c->loop_cont_block->index));
        cont_check->cond = QPU_COND_ZC;
        cont_check->sf = true;

        qir_BRANCH(c, QPU_COND_BRANCH_ANY_ZS);
        qir_link_blocks(c->cur_block, c->loop_cont_block);
        qir_link_blocks(c->cur_block, c->loop_break_block);

        qir_set_emit_block(c, c->loop_break_block);
        if (was_top_level) {
                c->execute = c->undef;
                c->last_top_block = c->cur_block;
        } else {
                ntq_activate_execute_for_block(c);
        }

        c->loop_break_block = save_loop_break_block;
        c->loop_cont_block = save_loop_cont_block;
}

static void
ntq_emit_function(struct vc4_compile *c, nir_function_impl *func)
{
        fprintf(stderr, "FUNCTIONS not handled.\n");
        abort();
}

static void
ntq_emit_cf_list(struct vc4_compile *c, struct exec_list *list)
{
        foreach_list_typed(nir_cf_node, node, node, list) {
                switch (node->type) {
                case nir_cf_node_block:
                        ntq_emit_block(c, nir_cf_node_as_block(node));
                        break;

                case nir_cf_node_if:
                        ntq_emit_if(c, nir_cf_node_as_if(node));
                        break;

                case nir_cf_node_loop:
                        ntq_emit_loop(c, nir_cf_node_as_loop(node));
                        break;

                case nir_cf_node_function:
                        ntq_emit_function(c, nir_cf_node_as_function(node));
                        break;

                default:
                        fprintf(stderr, "Unknown NIR node type\n");
                        abort();
                }
        }
}

static void
ntq_emit_impl(struct vc4_compile *c, nir_function_impl *impl)
{
        ntq_setup_registers(c, &impl->registers);
        ntq_emit_cf_list(c, &impl->body);
}

static void
nir_to_qir(struct vc4_compile *c)
{
        if (c->stage == QSTAGE_FRAG && c->s->info.fs.uses_discard)
                c->discard = qir_MOV(c, qir_uniform_ui(c, 0));

        ntq_setup_inputs(c);
        ntq_setup_outputs(c);

        /* Find the main function and emit the body. */
        nir_foreach_function(function, c->s) {
                assert(strcmp(function->name, "main") == 0);
                assert(function->impl);
                ntq_emit_impl(c, function->impl);
        }
}

static const nir_shader_compiler_options nir_options = {
        .lower_all_io_to_temps = true,
        .lower_extract_byte = true,
        .lower_extract_word = true,
        .lower_fdiv = true,
        .lower_ffma = true,
        .lower_flrp32 = true,
        .lower_fmod = true,
        .lower_fpow = true,
        .lower_fsat = true,
        .lower_fsqrt = true,
        .lower_ldexp = true,
        .lower_negate = true,
        .lower_rotate = true,
        .lower_to_scalar = true,
        .max_unroll_iterations = 32,
};

const void *
vc4_screen_get_compiler_options(struct pipe_screen *pscreen,
                                enum pipe_shader_ir ir,
                                enum pipe_shader_type shader)
{
        return &nir_options;
}

static int
count_nir_instrs(nir_shader *nir)
{
        int count = 0;
        nir_foreach_function(function, nir) {
                if (!function->impl)
                        continue;
                nir_foreach_block(block, function->impl) {
                        nir_foreach_instr(instr, block)
                                count++;
                }
        }
        return count;
}

static struct vc4_compile *
vc4_shader_ntq(struct vc4_context *vc4, enum qstage stage,
               struct vc4_key *key, bool fs_threaded)
{
        struct vc4_compile *c = qir_compile_init();

        c->vc4 = vc4;
        c->stage = stage;
        c->shader_state = &key->shader_state->base;
        c->program_id = key->shader_state->program_id;
        c->variant_id =
                p_atomic_inc_return(&key->shader_state->compiled_variant_count);
        c->fs_threaded = fs_threaded;

        c->key = key;
        switch (stage) {
        case QSTAGE_FRAG:
                c->fs_key = (struct vc4_fs_key *)key;
                if (c->fs_key->is_points) {
                        c->point_x = emit_fragment_varying(c, ~0, 0);
                        c->point_y = emit_fragment_varying(c, ~0, 0);
                } else if (c->fs_key->is_lines) {
                        c->line_x = emit_fragment_varying(c, ~0, 0);
                }
                break;
        case QSTAGE_VERT:
                c->vs_key = (struct vc4_vs_key *)key;
                break;
        case QSTAGE_COORD:
                c->vs_key = (struct vc4_vs_key *)key;
                break;
        }

        c->s = nir_shader_clone(c, key->shader_state->base.ir.nir);

        if (stage == QSTAGE_FRAG) {
                if (c->fs_key->alpha_test_func != COMPARE_FUNC_ALWAYS) {
                        NIR_PASS_V(c->s, nir_lower_alpha_test,
                                   c->fs_key->alpha_test_func,
                                   c->fs_key->sample_alpha_to_one &&
                                   c->fs_key->msaa,
                                   NULL);
                }
                NIR_PASS_V(c->s, vc4_nir_lower_blend, c);
        }

        struct nir_lower_tex_options tex_options = {
                /* We would need to implement txs, but we don't want the
                 * int/float conversions
                 */
                .lower_rect = false,

                .lower_txp = ~0,

                /* Apply swizzles to all samplers. */
                .swizzle_result = ~0,
        };

        /* Lower the format swizzle and ARB_texture_swizzle-style swizzle.
         * The format swizzling applies before sRGB decode, and
         * ARB_texture_swizzle is the last thing before returning the sample.
         */
        for (int i = 0; i < ARRAY_SIZE(key->tex); i++) {
                enum pipe_format format = c->key->tex[i].format;

                if (!format)
                        continue;

                const uint8_t *format_swizzle = vc4_get_format_swizzle(format);

                for (int j = 0; j < 4; j++) {
                        uint8_t arb_swiz = c->key->tex[i].swizzle[j];

                        if (arb_swiz <= 3) {
                                tex_options.swizzles[i][j] =
                                        format_swizzle[arb_swiz];
                        } else {
                                tex_options.swizzles[i][j] = arb_swiz;
                        }
                }

                if (util_format_is_srgb(format))
                        tex_options.lower_srgb |= (1 << i);
        }

        NIR_PASS_V(c->s, nir_lower_tex, &tex_options);

        if (c->fs_key && c->fs_key->light_twoside)
                NIR_PASS_V(c->s, nir_lower_two_sided_color, true);

        if (c->vs_key && c->vs_key->clamp_color)
                NIR_PASS_V(c->s, nir_lower_clamp_color_outputs);

        if (c->key->ucp_enables) {
                if (stage == QSTAGE_FRAG) {
                        NIR_PASS_V(c->s, nir_lower_clip_fs,
                                   c->key->ucp_enables, false);
                } else {
                        NIR_PASS_V(c->s, nir_lower_clip_vs,
                                   c->key->ucp_enables, false, false, NULL);
                        NIR_PASS_V(c->s, nir_lower_io_to_scalar,
                                   nir_var_shader_out);
                }
        }

        /* FS input scalarizing must happen after nir_lower_two_sided_color,
         * which only handles a vec4 at a time.  Similarly, VS output
         * scalarizing must happen after nir_lower_clip_vs.
         */
        if (c->stage == QSTAGE_FRAG)
                NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_in);
        else
                NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out);

        NIR_PASS_V(c->s, vc4_nir_lower_io, c);
        NIR_PASS_V(c->s, vc4_nir_lower_txf_ms, c);
        NIR_PASS_V(c->s, nir_lower_idiv, nir_lower_idiv_fast);

        vc4_optimize_nir(c->s);

        /* Do late algebraic optimization to turn add(a, neg(b)) back into
         * subs, then the mandatory cleanup after algebraic.  Note that it may
         * produce fnegs, and if so then we need to keep running to squash
         * fneg(fneg(a)).
         */
        bool more_late_algebraic = true;
        while (more_late_algebraic) {
                more_late_algebraic = false;
                NIR_PASS(more_late_algebraic, c->s, nir_opt_algebraic_late);
                NIR_PASS_V(c->s, nir_opt_constant_folding);
                NIR_PASS_V(c->s, nir_copy_prop);
                NIR_PASS_V(c->s, nir_opt_dce);
                NIR_PASS_V(c->s, nir_opt_cse);
        }

        NIR_PASS_V(c->s, nir_lower_bool_to_int32);

        NIR_PASS_V(c->s, nir_convert_from_ssa, true);

        if (vc4_debug & VC4_DEBUG_SHADERDB) {
                fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d NIR instructions\n",
                        qir_get_stage_name(c->stage),
                        c->program_id, c->variant_id,
                        count_nir_instrs(c->s));
        }

        if (vc4_debug & VC4_DEBUG_NIR) {
                fprintf(stderr, "%s prog %d/%d NIR:\n",
                        qir_get_stage_name(c->stage),
                        c->program_id, c->variant_id);
                nir_print_shader(c->s, stderr);
        }

        nir_to_qir(c);

        switch (stage) {
        case QSTAGE_FRAG:
                /* FS threading requires that the thread execute
                 * QPU_SIG_LAST_THREAD_SWITCH exactly once before terminating
                 * (with no other THRSW afterwards, obviously).  If we didn't
                 * fetch a texture at a top level block, this wouldn't be
                 * true.
                 */
                if (c->fs_threaded && !c->last_thrsw_at_top_level) {
                        c->failed = true;
                        return c;
                }

                emit_frag_end(c);
                break;
        case QSTAGE_VERT:
                emit_vert_end(c,
                              c->vs_key->fs_inputs->input_slots,
                              c->vs_key->fs_inputs->num_inputs);
                break;
        case QSTAGE_COORD:
                emit_coord_end(c);
                break;
        }

        if (vc4_debug & VC4_DEBUG_QIR) {
                fprintf(stderr, "%s prog %d/%d pre-opt QIR:\n",
                        qir_get_stage_name(c->stage),
                        c->program_id, c->variant_id);
                qir_dump(c);
                fprintf(stderr, "\n");
        }

        qir_optimize(c);
        qir_lower_uniforms(c);

        qir_schedule_instructions(c);
        qir_emit_uniform_stream_resets(c);

        if (vc4_debug & VC4_DEBUG_QIR) {
                fprintf(stderr, "%s prog %d/%d QIR:\n",
                        qir_get_stage_name(c->stage),
                        c->program_id, c->variant_id);
                qir_dump(c);
                fprintf(stderr, "\n");
        }

        qir_reorder_uniforms(c);
        vc4_generate_code(vc4, c);

        if (vc4_debug & VC4_DEBUG_SHADERDB) {
                fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d instructions\n",
                        qir_get_stage_name(c->stage),
                        c->program_id, c->variant_id,
                        c->qpu_inst_count);
                fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d uniforms\n",
                        qir_get_stage_name(c->stage),
                        c->program_id, c->variant_id,
                        c->num_uniforms);
        }

        ralloc_free(c->s);

        return c;
}

static void *
vc4_shader_state_create(struct pipe_context *pctx,
                        const struct pipe_shader_state *cso)
{
        struct vc4_context *vc4 = vc4_context(pctx);
        struct vc4_uncompiled_shader *so = CALLOC_STRUCT(vc4_uncompiled_shader);
        if (!so)
                return NULL;

        so->program_id = vc4->next_uncompiled_program_id++;

        nir_shader *s;

        if (cso->type == PIPE_SHADER_IR_NIR) {
                /* The backend takes ownership of the NIR shader on state
                 * creation.
                 */
                s = cso->ir.nir;
       } else {
                assert(cso->type == PIPE_SHADER_IR_TGSI);

                if (vc4_debug & VC4_DEBUG_TGSI) {
                        fprintf(stderr, "prog %d TGSI:\n",
                                so->program_id);
                        tgsi_dump(cso->tokens, 0);
                        fprintf(stderr, "\n");
                }
                s = tgsi_to_nir(cso->tokens, pctx->screen, false);
        }

        if (s->info.stage == MESA_SHADER_VERTEX)
                NIR_PASS_V(s, nir_lower_point_size, 1.0f, 0.0f);

        NIR_PASS_V(s, nir_lower_io, nir_var_shader_in | nir_var_shader_out,
                   type_size, (nir_lower_io_options)0);

        NIR_PASS_V(s, nir_lower_regs_to_ssa);
        NIR_PASS_V(s, nir_normalize_cubemap_coords);

        NIR_PASS_V(s, nir_lower_load_const_to_scalar);

        vc4_optimize_nir(s);

        NIR_PASS_V(s, nir_remove_dead_variables, nir_var_function_temp, NULL);

        /* Garbage collect dead instructions */
        nir_sweep(s);

        so->base.type = PIPE_SHADER_IR_NIR;
        so->base.ir.nir = s;

        if (vc4_debug & VC4_DEBUG_NIR) {
                fprintf(stderr, "%s prog %d NIR:\n",
                        gl_shader_stage_name(s->info.stage),
                        so->program_id);
                nir_print_shader(s, stderr);
                fprintf(stderr, "\n");
        }

        return so;
}

static void
copy_uniform_state_to_shader(struct vc4_compiled_shader *shader,
                             struct vc4_compile *c)
{
        int count = c->num_uniforms;
        struct vc4_shader_uniform_info *uinfo = &shader->uniforms;

        uinfo->count = count;
        uinfo->data = ralloc_array(shader, uint32_t, count);
        memcpy(uinfo->data, c->uniform_data,
               count * sizeof(*uinfo->data));
        uinfo->contents = ralloc_array(shader, enum quniform_contents, count);
        memcpy(uinfo->contents, c->uniform_contents,
               count * sizeof(*uinfo->contents));
        uinfo->num_texture_samples = c->num_texture_samples;

        vc4_set_shader_uniform_dirty_flags(shader);
}

static void
vc4_setup_compiled_fs_inputs(struct vc4_context *vc4, struct vc4_compile *c,
                             struct vc4_compiled_shader *shader)
{
        struct vc4_fs_inputs inputs;

        memset(&inputs, 0, sizeof(inputs));
        inputs.input_slots = ralloc_array(shader,
                                          struct vc4_varying_slot,
                                          c->num_input_slots);

        bool input_live[c->num_input_slots];

        memset(input_live, 0, sizeof(input_live));
        qir_for_each_inst_inorder(inst, c) {
                for (int i = 0; i < qir_get_nsrc(inst); i++) {
                        if (inst->src[i].file == QFILE_VARY)
                                input_live[inst->src[i].index] = true;
                }
        }

        for (int i = 0; i < c->num_input_slots; i++) {
                struct vc4_varying_slot *slot = &c->input_slots[i];

                if (!input_live[i])
                        continue;

                /* Skip non-VS-output inputs. */
                if (slot->slot == (uint8_t)~0)
                        continue;

                if (slot->slot == VARYING_SLOT_COL0 ||
                    slot->slot == VARYING_SLOT_COL1 ||
                    slot->slot == VARYING_SLOT_BFC0 ||
                    slot->slot == VARYING_SLOT_BFC1) {
                        shader->color_inputs |= (1 << inputs.num_inputs);
                }

                inputs.input_slots[inputs.num_inputs] = *slot;
                inputs.num_inputs++;
        }
        shader->num_inputs = inputs.num_inputs;

        /* Add our set of inputs to the set of all inputs seen.  This way, we
         * can have a single pointer that identifies an FS inputs set,
         * allowing VS to avoid recompiling when the FS is recompiled (or a
         * new one is bound using separate shader objects) but the inputs
         * don't change.
         */
        struct set_entry *entry = _mesa_set_search(vc4->fs_inputs_set, &inputs);
        if (entry) {
                shader->fs_inputs = entry->key;
                ralloc_free(inputs.input_slots);
        } else {
                struct vc4_fs_inputs *alloc_inputs;

                alloc_inputs = rzalloc(vc4->fs_inputs_set, struct vc4_fs_inputs);
                memcpy(alloc_inputs, &inputs, sizeof(inputs));
                ralloc_steal(alloc_inputs, inputs.input_slots);
                _mesa_set_add(vc4->fs_inputs_set, alloc_inputs);

                shader->fs_inputs = alloc_inputs;
        }
}

static struct vc4_compiled_shader *
vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage,
                        struct vc4_key *key)
{
        struct hash_table *ht;
        uint32_t key_size;
        bool try_threading;

        if (stage == QSTAGE_FRAG) {
                ht = vc4->fs_cache;
                key_size = sizeof(struct vc4_fs_key);
                try_threading = vc4->screen->has_threaded_fs;
        } else {
                ht = vc4->vs_cache;
                key_size = sizeof(struct vc4_vs_key);
                try_threading = false;
        }

        struct vc4_compiled_shader *shader;
        struct hash_entry *entry = _mesa_hash_table_search(ht, key);
        if (entry)
                return entry->data;

        struct vc4_compile *c = vc4_shader_ntq(vc4, stage, key, try_threading);
        /* If the FS failed to compile threaded, fall back to single threaded. */
        if (try_threading && c->failed) {
                qir_compile_destroy(c);
                c = vc4_shader_ntq(vc4, stage, key, false);
        }

        shader = rzalloc(NULL, struct vc4_compiled_shader);

        shader->program_id = vc4->next_compiled_program_id++;
        if (stage == QSTAGE_FRAG) {
                vc4_setup_compiled_fs_inputs(vc4, c, shader);

                /* Note: the temporary clone in c->s has been freed. */
                nir_shader *orig_shader = key->shader_state->base.ir.nir;
                if (orig_shader->info.outputs_written & (1 << FRAG_RESULT_DEPTH))
                        shader->disable_early_z = true;
        } else {
                shader->num_inputs = c->num_inputs;

                shader->vattr_offsets[0] = 0;
                for (int i = 0; i < 8; i++) {
                        shader->vattr_offsets[i + 1] =
                                shader->vattr_offsets[i] + c->vattr_sizes[i];

                        if (c->vattr_sizes[i])
                                shader->vattrs_live |= (1 << i);
                }
        }

        shader->failed = c->failed;
        if (c->failed) {
                shader->failed = true;
        } else {
                copy_uniform_state_to_shader(shader, c);
                shader->bo = vc4_bo_alloc_shader(vc4->screen, c->qpu_insts,
                                                 c->qpu_inst_count *
                                                 sizeof(uint64_t));
        }

        shader->fs_threaded = c->fs_threaded;

        if ((vc4_debug & VC4_DEBUG_SHADERDB) && stage == QSTAGE_FRAG) {
                fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d FS threads\n",
                        qir_get_stage_name(c->stage),
                        c->program_id, c->variant_id,
                        1 + shader->fs_threaded);
        }

        qir_compile_destroy(c);

        struct vc4_key *dup_key;
        dup_key = rzalloc_size(shader, key_size); /* TODO: don't use rzalloc */
        memcpy(dup_key, key, key_size);
        _mesa_hash_table_insert(ht, dup_key, shader);

        return shader;
}

static void
vc4_setup_shared_key(struct vc4_context *vc4, struct vc4_key *key,
                     struct vc4_texture_stateobj *texstate)
{
        for (int i = 0; i < texstate->num_textures; i++) {
                struct pipe_sampler_view *sampler = texstate->textures[i];
                struct vc4_sampler_view *vc4_sampler = vc4_sampler_view(sampler);
                struct pipe_sampler_state *sampler_state =
                        texstate->samplers[i];

                if (!sampler)
                        continue;

                key->tex[i].format = sampler->format;
                key->tex[i].swizzle[0] = sampler->swizzle_r;
                key->tex[i].swizzle[1] = sampler->swizzle_g;
                key->tex[i].swizzle[2] = sampler->swizzle_b;
                key->tex[i].swizzle[3] = sampler->swizzle_a;

                if (sampler->texture->nr_samples > 1) {
                        key->tex[i].msaa_width = sampler->texture->width0;
                        key->tex[i].msaa_height = sampler->texture->height0;
                } else if (sampler){
                        key->tex[i].compare_mode = sampler_state->compare_mode;
                        key->tex[i].compare_func = sampler_state->compare_func;
                        key->tex[i].wrap_s = sampler_state->wrap_s;
                        key->tex[i].wrap_t = sampler_state->wrap_t;
                        key->tex[i].force_first_level =
                                vc4_sampler->force_first_level;
                }
        }

        key->ucp_enables = vc4->rasterizer->base.clip_plane_enable;
}

static void
vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
{
        struct vc4_job *job = vc4->job;
        struct vc4_fs_key local_key;
        struct vc4_fs_key *key = &local_key;

        if (!(vc4->dirty & (VC4_DIRTY_PRIM_MODE |
                            VC4_DIRTY_BLEND |
                            VC4_DIRTY_FRAMEBUFFER |
                            VC4_DIRTY_ZSA |
                            VC4_DIRTY_RASTERIZER |
                            VC4_DIRTY_SAMPLE_MASK |
                            VC4_DIRTY_FRAGTEX |
                            VC4_DIRTY_UNCOMPILED_FS |
                            VC4_DIRTY_UBO_1_SIZE))) {
                return;
        }

        memset(key, 0, sizeof(*key));
        vc4_setup_shared_key(vc4, &key->base, &vc4->fragtex);
        key->base.shader_state = vc4->prog.bind_fs;
        key->is_points = (prim_mode == PIPE_PRIM_POINTS);
        key->is_lines = (prim_mode >= PIPE_PRIM_LINES &&
                         prim_mode <= PIPE_PRIM_LINE_STRIP);
        key->blend = vc4->blend->rt[0];
        if (vc4->blend->logicop_enable) {
                key->logicop_func = vc4->blend->logicop_func;
        } else {
                key->logicop_func = PIPE_LOGICOP_COPY;
        }
        if (job->msaa) {
                key->msaa = vc4->rasterizer->base.multisample;
                key->sample_coverage = (vc4->sample_mask != (1 << VC4_MAX_SAMPLES) - 1);
                key->sample_alpha_to_coverage = vc4->blend->alpha_to_coverage;
                key->sample_alpha_to_one = vc4->blend->alpha_to_one;
        }

        if (vc4->framebuffer.cbufs[0])
                key->color_format = vc4->framebuffer.cbufs[0]->format;

        key->stencil_enabled = vc4->zsa->stencil_uniforms[0] != 0;
        key->stencil_twoside = vc4->zsa->stencil_uniforms[1] != 0;
        key->stencil_full_writemasks = vc4->zsa->stencil_uniforms[2] != 0;
        key->depth_enabled = (vc4->zsa->base.depth.enabled ||
                              key->stencil_enabled);
        if (vc4->zsa->base.alpha.enabled)
                key->alpha_test_func = vc4->zsa->base.alpha.func;
        else
                key->alpha_test_func = COMPARE_FUNC_ALWAYS;

        if (key->is_points) {
                key->point_sprite_mask =
                        vc4->rasterizer->base.sprite_coord_enable;
                key->point_coord_upper_left =
                        (vc4->rasterizer->base.sprite_coord_mode ==
                         PIPE_SPRITE_COORD_UPPER_LEFT);
        }

        key->ubo_1_size = vc4->constbuf[PIPE_SHADER_FRAGMENT].cb[1].buffer_size;
        key->light_twoside = vc4->rasterizer->base.light_twoside;

        struct vc4_compiled_shader *old_fs = vc4->prog.fs;
        vc4->prog.fs = vc4_get_compiled_shader(vc4, QSTAGE_FRAG, &key->base);
        if (vc4->prog.fs == old_fs)
                return;

        vc4->dirty |= VC4_DIRTY_COMPILED_FS;

        if (vc4->rasterizer->base.flatshade &&
            (!old_fs || vc4->prog.fs->color_inputs != old_fs->color_inputs)) {
                vc4->dirty |= VC4_DIRTY_FLAT_SHADE_FLAGS;
        }

        if (!old_fs || vc4->prog.fs->fs_inputs != old_fs->fs_inputs)
                vc4->dirty |= VC4_DIRTY_FS_INPUTS;
}

static void
vc4_update_compiled_vs(struct vc4_context *vc4, uint8_t prim_mode)
{
        struct vc4_vs_key local_key;
        struct vc4_vs_key *key = &local_key;

        if (!(vc4->dirty & (VC4_DIRTY_PRIM_MODE |
                            VC4_DIRTY_RASTERIZER |
                            VC4_DIRTY_VERTTEX |
                            VC4_DIRTY_VTXSTATE |
                            VC4_DIRTY_UNCOMPILED_VS |
                            VC4_DIRTY_FS_INPUTS))) {
                return;
        }

        memset(key, 0, sizeof(*key));
        vc4_setup_shared_key(vc4, &key->base, &vc4->verttex);
        key->base.shader_state = vc4->prog.bind_vs;
        key->fs_inputs = vc4->prog.fs->fs_inputs;
        key->clamp_color = vc4->rasterizer->base.clamp_vertex_color;

        for (int i = 0; i < ARRAY_SIZE(key->attr_formats); i++)
                key->attr_formats[i] = vc4->vtx->pipe[i].src_format;

        key->per_vertex_point_size =
                (prim_mode == PIPE_PRIM_POINTS &&
                 vc4->rasterizer->base.point_size_per_vertex);

        struct vc4_compiled_shader *vs =
                vc4_get_compiled_shader(vc4, QSTAGE_VERT, &key->base);
        if (vs != vc4->prog.vs) {
                vc4->prog.vs = vs;
                vc4->dirty |= VC4_DIRTY_COMPILED_VS;
        }

        key->is_coord = true;
        /* Coord shaders don't care what the FS inputs are. */
        key->fs_inputs = NULL;
        struct vc4_compiled_shader *cs =
                vc4_get_compiled_shader(vc4, QSTAGE_COORD, &key->base);
        if (cs != vc4->prog.cs) {
                vc4->prog.cs = cs;
                vc4->dirty |= VC4_DIRTY_COMPILED_CS;
        }
}

bool
vc4_update_compiled_shaders(struct vc4_context *vc4, uint8_t prim_mode)
{
        vc4_update_compiled_fs(vc4, prim_mode);
        vc4_update_compiled_vs(vc4, prim_mode);

        return !(vc4->prog.cs->failed ||
                 vc4->prog.vs->failed ||
                 vc4->prog.fs->failed);
}

static uint32_t
fs_cache_hash(const void *key)
{
        return _mesa_hash_data(key, sizeof(struct vc4_fs_key));
}

static uint32_t
vs_cache_hash(const void *key)
{
        return _mesa_hash_data(key, sizeof(struct vc4_vs_key));
}

static bool
fs_cache_compare(const void *key1, const void *key2)
{
        return memcmp(key1, key2, sizeof(struct vc4_fs_key)) == 0;
}

static bool
vs_cache_compare(const void *key1, const void *key2)
{
        return memcmp(key1, key2, sizeof(struct vc4_vs_key)) == 0;
}

static uint32_t
fs_inputs_hash(const void *key)
{
        const struct vc4_fs_inputs *inputs = key;

        return _mesa_hash_data(inputs->input_slots,
                               sizeof(*inputs->input_slots) *
                               inputs->num_inputs);
}

static bool
fs_inputs_compare(const void *key1, const void *key2)
{
        const struct vc4_fs_inputs *inputs1 = key1;
        const struct vc4_fs_inputs *inputs2 = key2;

        return (inputs1->num_inputs == inputs2->num_inputs &&
                memcmp(inputs1->input_slots,
                       inputs2->input_slots,
                       sizeof(*inputs1->input_slots) *
                       inputs1->num_inputs) == 0);
}

static void
delete_from_cache_if_matches(struct hash_table *ht,
                             struct vc4_compiled_shader **last_compile,
                             struct hash_entry *entry,
                             struct vc4_uncompiled_shader *so)
{
        const struct vc4_key *key = entry->key;

        if (key->shader_state == so) {
                struct vc4_compiled_shader *shader = entry->data;
                _mesa_hash_table_remove(ht, entry);
                vc4_bo_unreference(&shader->bo);

                if (shader == *last_compile)
                        *last_compile = NULL;

                ralloc_free(shader);
        }
}

static void
vc4_shader_state_delete(struct pipe_context *pctx, void *hwcso)
{
        struct vc4_context *vc4 = vc4_context(pctx);
        struct vc4_uncompiled_shader *so = hwcso;

        hash_table_foreach(vc4->fs_cache, entry) {
                delete_from_cache_if_matches(vc4->fs_cache, &vc4->prog.fs,
                                             entry, so);
        }
        hash_table_foreach(vc4->vs_cache, entry) {
                delete_from_cache_if_matches(vc4->vs_cache, &vc4->prog.vs,
                                             entry, so);
        }

        ralloc_free(so->base.ir.nir);
        free(so);
}

static void
vc4_fp_state_bind(struct pipe_context *pctx, void *hwcso)
{
        struct vc4_context *vc4 = vc4_context(pctx);
        vc4->prog.bind_fs = hwcso;
        vc4->dirty |= VC4_DIRTY_UNCOMPILED_FS;
}

static void
vc4_vp_state_bind(struct pipe_context *pctx, void *hwcso)
{
        struct vc4_context *vc4 = vc4_context(pctx);
        vc4->prog.bind_vs = hwcso;
        vc4->dirty |= VC4_DIRTY_UNCOMPILED_VS;
}

void
vc4_program_init(struct pipe_context *pctx)
{
        struct vc4_context *vc4 = vc4_context(pctx);

        pctx->create_vs_state = vc4_shader_state_create;
        pctx->delete_vs_state = vc4_shader_state_delete;

        pctx->create_fs_state = vc4_shader_state_create;
        pctx->delete_fs_state = vc4_shader_state_delete;

        pctx->bind_fs_state = vc4_fp_state_bind;
        pctx->bind_vs_state = vc4_vp_state_bind;

        vc4->fs_cache = _mesa_hash_table_create(pctx, fs_cache_hash,
                                                fs_cache_compare);
        vc4->vs_cache = _mesa_hash_table_create(pctx, vs_cache_hash,
                                                vs_cache_compare);
        vc4->fs_inputs_set = _mesa_set_create(pctx, fs_inputs_hash,
                                              fs_inputs_compare);
}

void
vc4_program_fini(struct pipe_context *pctx)
{
        struct vc4_context *vc4 = vc4_context(pctx);

        hash_table_foreach(vc4->fs_cache, entry) {
                struct vc4_compiled_shader *shader = entry->data;
                vc4_bo_unreference(&shader->bo);
                ralloc_free(shader);
                _mesa_hash_table_remove(vc4->fs_cache, entry);
        }

        hash_table_foreach(vc4->vs_cache, entry) {
                struct vc4_compiled_shader *shader = entry->data;
                vc4_bo_unreference(&shader->bo);
                ralloc_free(shader);
                _mesa_hash_table_remove(vc4->vs_cache, entry);
        }
}
