nv50/ir: fix constant folding for OP_MUL subop HIGH
[mesa.git] / src / gallium / drivers / nouveau / nv50 / nv50_shader_state.c
index b24e3ac90e610da972d7e0d411390133f4350ee8..c698782d8bd65fd2276c9c726b197787767ad314 100644 (file)
@@ -172,6 +172,8 @@ nv50_fragprog_validate(struct nv50_context *nv50)
    struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_program *fp = nv50->fragprog;
 
+   fp->fp.sample_interp = nv50->min_samples > 1;
+
    if (!nv50_program_validate(nv50, fp))
          return;
    nv50_program_update_context_state(nv50, fp, 1);
@@ -186,6 +188,17 @@ nv50_fragprog_validate(struct nv50_context *nv50)
    PUSH_DATA (push, fp->fp.flags[1]);
    BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
    PUSH_DATA (push, fp->code_base);
+
+   if (nv50->screen->tesla->oclass >= NVA3_3D_CLASS) {
+      BEGIN_NV04(push, SUBC_3D(NVA3_3D_FP_MULTISAMPLE), 1);
+      if (nv50->min_samples > 1 || fp->fp.has_samplemask)
+         PUSH_DATA(push,
+                   NVA3_3D_FP_MULTISAMPLE_FORCE_PER_SAMPLE |
+                   (NVA3_3D_FP_MULTISAMPLE_EXPORT_SAMPLE_MASK *
+                    fp->fp.has_samplemask));
+      else
+         PUSH_DATA(push, 0);
+   }
 }
 
 void
@@ -346,7 +359,8 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    struct nv50_varying dummy;
    int i, n, c, m;
    uint32_t primid = 0;
-   uint32_t layerid = vp->gp.layerid;
+   uint32_t layerid = 0;
+   uint32_t viewportid = 0;
    uint32_t psiz = 0x000;
    uint32_t interp = fp->fp.interp;
    uint32_t colors = fp->fp.colors;
@@ -401,22 +415,29 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
          if (vp->out[n].sn == fp->in[i].sn &&
              vp->out[n].si == fp->in[i].si)
             break;
+      switch (fp->in[i].sn) {
+      case TGSI_SEMANTIC_PRIMID:
+         primid = m;
+         break;
+      case TGSI_SEMANTIC_LAYER:
+         layerid = m;
+         break;
+      case TGSI_SEMANTIC_VIEWPORT_INDEX:
+         viewportid = m;
+         break;
+      }
       m = nv50_vec4_map(map, m, lin,
                         &fp->in[i], (n < vp->out_nr) ? &vp->out[n] : &dummy);
    }
 
-   /* PrimitiveID either is replaced by the system value, or
-    * written by the geometry shader into an output register
-    */
-   if (fp->gp.primid < 0x80) {
-      primid = m;
-      map[m++] = vp->gp.primid;
+   if (vp->gp.has_layer && !layerid) {
+      layerid = m;
+      map[m++] = vp->gp.layerid;
    }
 
-   if (vp->gp.has_layer) {
-      // In GL4.x, layer can be an fp input, but not in 3.x. Make sure to add
-      // it to the output map.
-      map[m++] = layerid;
+   if (vp->gp.has_viewport && !viewportid) {
+      viewportid = m;
+      map[m++] = vp->gp.viewportid;
    }
 
    if (nv50->rast->pipe.point_size_per_vertex) {
@@ -461,23 +482,28 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
       PUSH_DATAp(push, map, n);
    } else {
       BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1);
-      PUSH_DATA (push, vp->vp.attrs[2]);
+      PUSH_DATA (push, vp->vp.attrs[2] | fp->vp.attrs[2]);
 
       BEGIN_NV04(push, NV50_3D(SEMANTIC_PRIM_ID), 1);
       PUSH_DATA (push, primid);
 
+      assert(m > 0);
       BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1);
       PUSH_DATA (push, m);
       BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n);
       PUSH_DATAp(push, map, n);
    }
 
-   BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 4);
+   BEGIN_NV04(push, NV50_3D(GP_VIEWPORT_ID_ENABLE), 5);
+   PUSH_DATA (push, vp->gp.has_viewport);
    PUSH_DATA (push, colors);
    PUSH_DATA (push, (vp->vp.clpd_nr << 8) | 4);
    PUSH_DATA (push, layerid);
    PUSH_DATA (push, psiz);
 
+   BEGIN_NV04(push, NV50_3D(SEMANTIC_VIEWPORT), 1);
+   PUSH_DATA (push, viewportid);
+
    BEGIN_NV04(push, NV50_3D(LAYER), 1);
    PUSH_DATA (push, vp->gp.has_layer << 16);
 
@@ -528,6 +554,8 @@ nv50_vp_gp_mapping(uint8_t *map, int m,
          oid += mv & 1;
       }
    }
+   if (!m)
+      map[m++] = 0;
    return m;
 }
 
@@ -552,6 +580,7 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
    BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1);
    PUSH_DATA (push, vp->vp.attrs[2] | gp->vp.attrs[2]);
 
+   assert(m > 0);
    BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1);
    PUSH_DATA (push, m);
    BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n);