nir/prog: Use nir_bany in kill handling
[mesa.git] / src / mesa / program / prog_to_nir.c
index d96b7bc878271b464ac35f83255f87c91617f95f..47103306ad460248b419840f584d6968e6f4e71d 100644 (file)
  * IN THE SOFTWARE.
  */
 
-#include "nir/nir.h"
-#include "nir/nir_builder.h"
-#include "glsl/list.h"
+#include "compiler/nir/nir.h"
+#include "compiler/nir/nir_builder.h"
+#include "compiler/glsl/list.h"
 #include "main/imports.h"
+#include "main/mtypes.h"
 #include "util/ralloc.h"
 
 #include "prog_to_nir.h"
@@ -51,6 +52,7 @@ struct ptn_compile {
    nir_variable *parameters;
    nir_variable *input_vars[VARYING_SLOT_MAX];
    nir_variable *output_vars[VARYING_SLOT_MAX];
+   nir_variable *sampler_vars[32]; /* matches number of bits in TexSrcUnit */
    nir_register **output_regs;
    nir_register **temp_regs;
 
@@ -59,7 +61,6 @@ struct ptn_compile {
 
 #define SWIZ(X, Y, Z, W) \
    (unsigned[4]){ SWIZZLE_##X, SWIZZLE_##Y, SWIZZLE_##Z, SWIZZLE_##W }
-#define ptn_swizzle(b, src, x, y, z, w) nir_swizzle(b, src, SWIZ(x, y, z, w), 4, true)
 #define ptn_channel(b, src, ch) nir_swizzle(b, src, SWIZ(ch, ch, ch, ch), 1, true)
 
 static nir_ssa_def *
@@ -137,15 +138,8 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
 
       assert(prog_src->Index >= 0 && prog_src->Index < VARYING_SLOT_MAX);
 
-      nir_intrinsic_instr *load =
-         nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
-      load->num_components = 4;
-      load->variables[0] = nir_deref_var_create(load, c->input_vars[prog_src->Index]);
-
-      nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
-      nir_builder_instr_insert(b, &load->instr);
-
-      src.src = nir_src_for_ssa(&load->dest.ssa);
+      nir_variable *var = c->input_vars[prog_src->Index];
+      src.src = nir_src_for_ssa(nir_load_var(b, var));
       break;
    }
    case PROGRAM_STATE_VAR:
@@ -160,8 +154,10 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
 
       switch (file) {
       case PROGRAM_CONSTANT:
-         if ((c->prog->IndirectRegisterFiles & (1 << PROGRAM_CONSTANT)) == 0) {
-            float *v = (float *) plist->ParameterValues[prog_src->Index];
+         if ((c->prog->arb.IndirectRegisterFiles &
+              (1 << PROGRAM_CONSTANT)) == 0) {
+            unsigned pvo = plist->ParameterValueOffset[prog_src->Index];
+            float *v = (float *) plist->ParameterValues + pvo;
             src.src = nir_src_for_ssa(nir_imm_vec4(b, v[0], v[1], v[2], v[3]));
             break;
          }
@@ -169,43 +165,14 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
       case PROGRAM_STATE_VAR: {
          assert(c->parameters != NULL);
 
-         nir_intrinsic_instr *load =
-            nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
-         nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
-         load->num_components = 4;
-
-         load->variables[0] = nir_deref_var_create(load, c->parameters);
-         nir_deref_array *deref_arr =
-            nir_deref_array_create(load->variables[0]);
-         deref_arr->deref.type = glsl_vec4_type();
-         load->variables[0]->deref.child = &deref_arr->deref;
-
-         if (prog_src->RelAddr) {
-            deref_arr->deref_array_type = nir_deref_array_type_indirect;
-
-            nir_alu_src addr_src = { NIR_SRC_INIT };
-            addr_src.src = nir_src_for_reg(c->addr_reg);
-            nir_ssa_def *reladdr = nir_imov_alu(b, addr_src, 1);
-
-            if (prog_src->Index < 0) {
-               /* This is a negative offset which should be added to the address
-                * register's value.
-                */
-               reladdr = nir_iadd(b, reladdr, nir_imm_int(b, prog_src->Index));
-
-               deref_arr->base_offset = 0;
-            } else {
-               deref_arr->base_offset = prog_src->Index;
-            }
-            deref_arr->indirect = nir_src_for_ssa(reladdr);
-         } else {
-            deref_arr->deref_array_type = nir_deref_array_type_direct;
-            deref_arr->base_offset = prog_src->Index;
-         }
+         nir_deref_instr *deref = nir_build_deref_var(b, c->parameters);
 
-         nir_builder_instr_insert(b, &load->instr);
+         nir_ssa_def *index = nir_imm_int(b, prog_src->Index);
+         if (prog_src->RelAddr)
+            index = nir_iadd(b, index, nir_load_reg(b, c->addr_reg));
+         deref = nir_build_deref_array(b, deref, nir_channel(b, index, 0));
 
-         src.src = nir_src_for_ssa(&load->dest.ssa);
+         src.src = nir_src_for_ssa(nir_load_deref(b, deref));
          break;
       }
       default:
@@ -230,9 +197,6 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
 
       def = nir_fmov_alu(b, src, 4);
 
-      if (prog_src->Abs)
-         def = nir_fabs(b, def);
-
       if (prog_src->Negate)
          def = nir_fneg(b, def);
    } else {
@@ -249,7 +213,7 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
          } else {
             assert(swizzle != SWIZZLE_NIL);
             nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_fmov);
-            nir_ssa_dest_init(&mov->instr, &mov->dest.dest, 1, NULL);
+            nir_ssa_dest_init(&mov->instr, &mov->dest.dest, 1, 32, NULL);
             mov->dest.write_mask = 0x1;
             mov->src[0] = src;
             mov->src[0].swizzle[0] = swizzle;
@@ -258,9 +222,6 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
             chans[i] = &mov->dest.dest.ssa;
          }
 
-         if (prog_src->Abs)
-            chans[i] = nir_fabs(b, chans[i]);
-
          if (prog_src->Negate & (1 << i))
             chans[i] = nir_fneg(b, chans[i]);
       }
@@ -312,7 +273,7 @@ ptn_move_dest(nir_builder *b, nir_alu_dest dest, nir_ssa_def *def)
 static void
 ptn_arl(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
 {
-   ptn_move_dest(b, dest, nir_f2i(b, nir_ffloor(b, src[0])));
+   ptn_move_dest(b, dest, nir_f2i32(b, nir_ffloor(b, src[0])));
 }
 
 /* EXP - Approximate Exponential Base 2
@@ -451,57 +412,17 @@ ptn_sge(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
    }
 }
 
-static void
-ptn_sle(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
-{
-   nir_ssa_def *commuted[] = { src[1], src[0] };
-   ptn_sge(b, dest, commuted);
-}
-
-static void
-ptn_sgt(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
-{
-   nir_ssa_def *commuted[] = { src[1], src[0] };
-   ptn_slt(b, dest, commuted);
-}
-
-/**
- * Emit SEQ.  For platforms with integers, prefer b2f(feq(...)).
- */
-static void
-ptn_seq(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
-{
-   if (b->shader->options->native_integers) {
-      ptn_move_dest(b, dest, nir_b2f(b, nir_feq(b, src[0], src[1])));
-   } else {
-      ptn_move_dest(b, dest, nir_seq(b, src[0], src[1]));
-   }
-}
-
-/**
- * Emit SNE.  For platforms with integers, prefer b2f(fne(...)).
- */
-static void
-ptn_sne(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
-{
-   if (b->shader->options->native_integers) {
-      ptn_move_dest(b, dest, nir_b2f(b, nir_fne(b, src[0], src[1])));
-   } else {
-      ptn_move_dest(b, dest, nir_sne(b, src[0], src[1]));
-   }
-}
-
 static void
 ptn_xpd(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
 {
    ptn_move_dest_masked(b, dest,
                         nir_fsub(b,
                                  nir_fmul(b,
-                                          ptn_swizzle(b, src[0], Y, Z, X, X),
-                                          ptn_swizzle(b, src[1], Z, X, Y, X)),
+                                          nir_swizzle(b, src[0], SWIZ(Y, Z, X, W), 3, true),
+                                          nir_swizzle(b, src[1], SWIZ(Z, X, Y, W), 3, true)),
                                  nir_fmul(b,
-                                          ptn_swizzle(b, src[1], Y, Z, X, X),
-                                          ptn_swizzle(b, src[0], Z, X, Y, X))),
+                                          nir_swizzle(b, src[1], SWIZ(Y, Z, X, W), 3, true),
+                                          nir_swizzle(b, src[0], SWIZ(Z, X, Y, W), 3, true))),
                         WRITEMASK_XYZ);
    ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
 }
@@ -527,8 +448,7 @@ ptn_dp4(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
 static void
 ptn_dph(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
 {
-   nir_ssa_def *dp3 = nir_fdot3(b, src[0], src[1]);
-   ptn_move_dest(b, dest, nir_fadd(b, dp3, ptn_channel(b, src[1], W)));
+   ptn_move_dest(b, dest, nir_fdph(b, src[0], src[1]));
 }
 
 static void
@@ -552,11 +472,11 @@ ptn_lrp(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
 }
 
 static void
-ptn_kil(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+ptn_kil(nir_builder *b, nir_ssa_def **src)
 {
    nir_ssa_def *cmp = b->shader->options->native_integers ?
-      nir_bany4(b, nir_flt(b, src[0], nir_imm_float(b, 0.0))) :
-      nir_fany4(b, nir_slt(b, src[0], nir_imm_float(b, 0.0)));
+      nir_bany(b, nir_flt(b, src[0], nir_imm_float(b, 0.0))) :
+      nir_fany_nequal4(b, nir_slt(b, src[0], nir_imm_float(b, 0.0)), nir_imm_float(b, 0.0));
 
    nir_intrinsic_instr *discard =
       nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
@@ -565,9 +485,10 @@ ptn_kil(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
 }
 
 static void
-ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
+ptn_tex(struct ptn_compile *c, nir_alu_dest dest, nir_ssa_def **src,
         struct prog_instruction *prog_inst)
 {
+   nir_builder *b = &c->build;
    nir_tex_instr *instr;
    nir_texop op;
    unsigned num_srcs;
@@ -593,11 +514,6 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
       op = nir_texop_tex;
       num_srcs = 2;
       break;
-   case OPCODE_TXP_NV:
-      assert(!"not handled");
-      op = nir_texop_tex;
-      num_srcs = 2;
-      break;
    default:
       fprintf(stderr, "unknown tex op %d\n", prog_inst->Opcode);
       abort();
@@ -610,6 +526,7 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
    instr->op = op;
    instr->dest_type = nir_type_float;
    instr->is_shadow = prog_inst->TexShadow;
+   instr->texture_index = prog_inst->TexSrcUnit;
    instr->sampler_index = prog_inst->TexSrcUnit;
 
    switch (prog_inst->TexSrcTarget) {
@@ -648,12 +565,25 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
    case GLSL_SAMPLER_DIM_CUBE:
       instr->coord_components = 3;
       break;
+   case GLSL_SAMPLER_DIM_SUBPASS:
+   case GLSL_SAMPLER_DIM_SUBPASS_MS:
+      unreachable("can't reach");
+   }
+
+   if (!c->sampler_vars[prog_inst->TexSrcUnit]) {
+      const struct glsl_type *type =
+         glsl_sampler_type(instr->sampler_dim, false, false, GLSL_TYPE_FLOAT);
+      nir_variable *var =
+         nir_variable_create(b->shader, nir_var_uniform, type, "sampler");
+      var->data.binding = prog_inst->TexSrcUnit;
+      c->sampler_vars[prog_inst->TexSrcUnit] = var;
    }
 
    unsigned src_number = 0;
 
    instr->src[src_number].src =
-      nir_src_for_ssa(ptn_swizzle(b, src[0], X, Y, Z, W));
+      nir_src_for_ssa(nir_swizzle(b, src[0], SWIZ(X, Y, Z, W),
+                                  instr->coord_components, true));
    instr->src[src_number].src_type = nir_tex_src_coord;
    src_number++;
 
@@ -681,13 +611,13 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
       else
          instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
 
-      instr->src[src_number].src_type = nir_tex_src_comparitor;
+      instr->src[src_number].src_type = nir_tex_src_comparator;
       src_number++;
    }
 
    assert(src_number == num_srcs);
 
-   nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
+   nir_ssa_dest_init(&instr->instr, &instr->dest, 4, 32, NULL);
    nir_builder_instr_insert(b, &instr->instr);
 
    /* Resolve the writemask on the texture op. */
@@ -717,7 +647,7 @@ static const nir_op op_trans[MAX_OPCODE] = {
    [OPCODE_LIT] = 0,
    [OPCODE_LOG] = 0,
    [OPCODE_LRP] = 0,
-   [OPCODE_MAD] = nir_op_ffma,
+   [OPCODE_MAD] = 0,
    [OPCODE_MAX] = nir_op_fmax,
    [OPCODE_MIN] = nir_op_fmin,
    [OPCODE_MOV] = nir_op_fmov,
@@ -727,13 +657,9 @@ static const nir_op op_trans[MAX_OPCODE] = {
 
    [OPCODE_RSQ] = 0,
    [OPCODE_SCS] = 0,
-   [OPCODE_SEQ] = 0,
    [OPCODE_SGE] = 0,
-   [OPCODE_SGT] = 0,
    [OPCODE_SIN] = 0,
-   [OPCODE_SLE] = 0,
    [OPCODE_SLT] = 0,
-   [OPCODE_SNE] = 0,
    [OPCODE_SSG] = nir_op_fsign,
    [OPCODE_SUB] = nir_op_fsub,
    [OPCODE_SWZ] = 0,
@@ -743,7 +669,6 @@ static const nir_op op_trans[MAX_OPCODE] = {
    [OPCODE_TXD] = 0,
    [OPCODE_TXL] = 0,
    [OPCODE_TXP] = 0,
-   [OPCODE_TXP_NV] = 0,
    [OPCODE_XPD] = 0,
 };
 
@@ -813,6 +738,10 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst)
       ptn_lrp(b, dest, src);
       break;
 
+   case OPCODE_MAD:
+      ptn_move_dest(b, dest, nir_fadd(b, nir_fmul(b, src[0], src[1]), src[2]));
+      break;
+
    case OPCODE_DST:
       ptn_dst(b, dest, src);
       break;
@@ -842,7 +771,7 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst)
       break;
 
    case OPCODE_KIL:
-      ptn_kil(b, dest, src);
+      ptn_kil(b, src);
       break;
 
    case OPCODE_CMP:
@@ -857,33 +786,16 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst)
       ptn_slt(b, dest, src);
       break;
 
-   case OPCODE_SGT:
-      ptn_sgt(b, dest, src);
-      break;
-
-   case OPCODE_SLE:
-      ptn_sle(b, dest, src);
-      break;
-
    case OPCODE_SGE:
       ptn_sge(b, dest, src);
       break;
 
-   case OPCODE_SEQ:
-      ptn_seq(b, dest, src);
-      break;
-
-   case OPCODE_SNE:
-      ptn_sne(b, dest, src);
-      break;
-
    case OPCODE_TEX:
    case OPCODE_TXB:
    case OPCODE_TXD:
    case OPCODE_TXL:
    case OPCODE_TXP:
-   case OPCODE_TXP_NV:
-      ptn_tex(b, dest, src, prog_inst);
+      ptn_tex(c, dest, src, prog_inst);
       break;
 
    case OPCODE_SWZ:
@@ -924,27 +836,18 @@ ptn_add_output_stores(struct ptn_compile *c)
 {
    nir_builder *b = &c->build;
 
-   foreach_list_typed(nir_variable, var, node, &b->shader->outputs) {
-      nir_intrinsic_instr *store =
-         nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
-      store->num_components = glsl_get_vector_elements(var->type);
-      store->variables[0] =
-         nir_deref_var_create(store, c->output_vars[var->data.location]);
-
+   nir_foreach_variable(var, &b->shader->outputs) {
+      nir_ssa_def *src = nir_load_reg(b, c->output_regs[var->data.location]);
       if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
           var->data.location == FRAG_RESULT_DEPTH) {
          /* result.depth has this strange convention of being the .z component of
           * a vec4 with undefined .xyw components.  We resolve it to a scalar, to
           * match GLSL's gl_FragDepth and the expectations of most backends.
           */
-         nir_alu_src alu_src = { NIR_SRC_INIT };
-         alu_src.src = nir_src_for_reg(c->output_regs[FRAG_RESULT_DEPTH]);
-         alu_src.swizzle[0] = SWIZZLE_Z;
-         store->src[0] = nir_src_for_ssa(nir_fmov_alu(b, alu_src, 1));
-      } else {
-         store->src[0].reg.reg = c->output_regs[var->data.location];
+         src = nir_channel(b, src, 2);
       }
-      nir_builder_instr_insert(b, &store->instr);
+      unsigned num_components = glsl_get_vector_elements(var->type);
+      nir_store_var(b, var, src, (1 << num_components) - 1);
    }
 }
 
@@ -955,27 +858,21 @@ setup_registers_and_variables(struct ptn_compile *c)
    struct nir_shader *shader = b->shader;
 
    /* Create input variables. */
-   const int num_inputs = _mesa_flsll(c->prog->InputsRead);
+   const int num_inputs = util_last_bit64(c->prog->info.inputs_read);
    for (int i = 0; i < num_inputs; i++) {
-      if (!(c->prog->InputsRead & BITFIELD64_BIT(i)))
+      if (!(c->prog->info.inputs_read & BITFIELD64_BIT(i)))
          continue;
-      nir_variable *var = rzalloc(shader, nir_variable);
-      var->type = glsl_vec4_type();
-      var->data.read_only = true;
-      var->data.mode = nir_var_shader_in;
-      var->name = ralloc_asprintf(var, "in_%d", i);
+
+      nir_variable *var =
+         nir_variable_create(shader, nir_var_shader_in, glsl_vec4_type(),
+                             ralloc_asprintf(shader, "in_%d", i));
       var->data.location = i;
       var->data.index = 0;
 
       if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
-         struct gl_fragment_program *fp =
-            (struct gl_fragment_program *) c->prog;
-
-         var->data.interpolation = fp->InterpQualifier[i];
-
          if (i == VARYING_SLOT_POS) {
-            var->data.origin_upper_left = fp->OriginUpperLeft;
-            var->data.pixel_center_integer = fp->PixelCenterInteger;
+            var->data.origin_upper_left = c->prog->OriginUpperLeft;
+            var->data.pixel_center_integer = c->prog->PixelCenterInteger;
          } else if (i == VARYING_SLOT_FOGC) {
             /* fogcoord is defined as <f, 0.0, 0.0, 1.0>.  Make the actual
              * input variable a float, and create a local containing the
@@ -983,49 +880,35 @@ setup_registers_and_variables(struct ptn_compile *c)
              */
             var->type = glsl_float_type();
 
-            nir_intrinsic_instr *load_x =
-               nir_intrinsic_instr_create(shader, nir_intrinsic_load_var);
-            load_x->num_components = 1;
-            load_x->variables[0] = nir_deref_var_create(load_x, var);
-            nir_ssa_dest_init(&load_x->instr, &load_x->dest, 1, NULL);
-            nir_builder_instr_insert(b, &load_x->instr);
-
-            nir_ssa_def *f001 = nir_vec4(b, &load_x->dest.ssa, nir_imm_float(b, 0.0),
-                                         nir_imm_float(b, 0.0), nir_imm_float(b, 1.0));
-
-            nir_variable *fullvar = rzalloc(shader, nir_variable);
-            fullvar->type = glsl_vec4_type();
-            fullvar->data.mode = nir_var_local;
-            fullvar->name = "fogcoord_tmp";
-            exec_list_push_tail(&b->impl->locals, &fullvar->node);
-
-            nir_intrinsic_instr *store =
-               nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
-            store->num_components = 4;
-            store->variables[0] = nir_deref_var_create(store, fullvar);
-            store->src[0] = nir_src_for_ssa(f001);
-            nir_builder_instr_insert(b, &store->instr);
-
-            /* Insert the real input into the list so the driver has real
-             * inputs, but set c->input_vars[i] to the temporary so we use
+            nir_variable *fullvar =
+               nir_local_variable_create(b->impl, glsl_vec4_type(),
+                                         "fogcoord_tmp");
+
+            nir_store_var(b, fullvar,
+                          nir_vec4(b, nir_load_var(b, var),
+                                   nir_imm_float(b, 0.0),
+                                   nir_imm_float(b, 0.0),
+                                   nir_imm_float(b, 1.0)),
+                          WRITEMASK_XYZW);
+
+            /* We inserted the real input into the list so the driver has real
+             * inputs, but we set c->input_vars[i] to the temporary so we use
              * the splatted value.
              */
-            exec_list_push_tail(&shader->inputs, &var->node);
             c->input_vars[i] = fullvar;
             continue;
          }
       }
 
-      exec_list_push_tail(&shader->inputs, &var->node);
       c->input_vars[i] = var;
    }
 
    /* Create output registers and variables. */
-   int max_outputs = _mesa_fls(c->prog->OutputsWritten);
+   int max_outputs = util_last_bit(c->prog->info.outputs_written);
    c->output_regs = rzalloc_array(c, nir_register *, max_outputs);
 
    for (int i = 0; i < max_outputs; i++) {
-      if (!(c->prog->OutputsWritten & BITFIELD64_BIT(i)))
+      if (!(c->prog->info.outputs_written & BITFIELD64_BIT(i)))
          continue;
 
       /* Since we can't load from outputs in the IR, we make temporaries
@@ -1053,10 +936,11 @@ setup_registers_and_variables(struct ptn_compile *c)
    }
 
    /* Create temporary registers. */
-   c->temp_regs = rzalloc_array(c, nir_register *, c->prog->NumTemporaries);
+   c->temp_regs = rzalloc_array(c, nir_register *,
+                                c->prog->arb.NumTemporaries);
 
    nir_register *reg;
-   for (int i = 0; i < c->prog->NumTemporaries; i++) {
+   for (unsigned i = 0; i < c->prog->arb.NumTemporaries; i++) {
       reg = nir_local_reg_create(b->impl);
       if (!reg) {
          c->error = true;
@@ -1087,11 +971,15 @@ prog_to_nir(const struct gl_program *prog,
    c = rzalloc(NULL, struct ptn_compile);
    if (!c)
       return NULL;
-   s = nir_shader_create(NULL, stage, options);
-   if (!s)
-      goto fail;
    c->prog = prog;
 
+   nir_builder_init_simple_shader(&c->build, NULL, stage, options);
+
+   /* Copy the shader_info from the gl_program */
+   c->build.shader->info = prog->info;
+
+   s = c->build.shader;
+
    if (prog->Parameters->NumParameters > 0) {
       c->parameters = rzalloc(s, nir_variable);
       c->parameters->type =
@@ -1102,20 +990,12 @@ prog_to_nir(const struct gl_program *prog,
       exec_list_push_tail(&s->uniforms, &c->parameters->node);
    }
 
-   nir_function *func = nir_function_create(s, "main");
-   nir_function_overload *overload = nir_function_overload_create(func);
-   nir_function_impl *impl = nir_function_impl_create(overload);
-
-   c->build.shader = s;
-   c->build.impl = impl;
-   nir_builder_insert_after_cf_list(&c->build, &impl->body);
-
    setup_registers_and_variables(c);
    if (unlikely(c->error))
       goto fail;
 
-   for (unsigned int i = 0; i < prog->NumInstructions; i++) {
-      ptn_emit_instruction(c, &prog->Instructions[i]);
+   for (unsigned int i = 0; i < prog->arb.NumInstructions; i++) {
+      ptn_emit_instruction(c, &prog->arb.Instructions[i]);
 
       if (unlikely(c->error))
          break;
@@ -1123,6 +1003,17 @@ prog_to_nir(const struct gl_program *prog,
 
    ptn_add_output_stores(c);
 
+   s->info.name = ralloc_asprintf(s, "ARB%d", prog->Id);
+   s->info.num_textures = util_last_bit(prog->SamplersUsed);
+   s->info.num_ubos = 0;
+   s->info.num_abos = 0;
+   s->info.num_ssbos = 0;
+   s->info.num_images = 0;
+   s->info.uses_texture_gather = false;
+   s->info.clip_distance_array_size = 0;
+   s->info.cull_distance_array_size = 0;
+   s->info.separate_shader = false;
+
 fail:
    if (c->error) {
       ralloc_free(s);