nv50: handle gl_Layer writes in GP
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 15 Jan 2014 08:47:48 +0000 (03:47 -0500)
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>
Mon, 27 Jan 2014 15:40:42 +0000 (16:40 +0100)
Marks gl_Layer as only having one component, and makes sure to keep
track of where it is and emit it in the output map, since it is not an
input to the FP.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nouveau/nv50/nv50_program.c
src/gallium/drivers/nouveau/nv50/nv50_program.h
src/gallium/drivers/nouveau/nv50/nv50_shader_state.c

index 321410e4d45768ab110c70e5063ae603a5c747dd..33ebb54da9776956383a657a723930210be4183a 100644 (file)
@@ -1030,6 +1030,7 @@ bool Source::scanInstruction(const struct tgsi_full_instruction *inst)
 
          if (info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_PSIZE ||
              info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_PRIMID ||
+             info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_LAYER ||
              info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_FOG)
             info->out[dst.getIndex(0)].mask &= 1;
 
index f46f240cc3c80bc087dbd4492508adb30d09ff97..82e1b8a223289211a2f01147519a7432f7e3f220 100644 (file)
@@ -103,6 +103,10 @@ nv50_vertprog_assign_slots(struct nv50_ir_prog_info *info)
       case TGSI_SEMANTIC_BCOLOR:
          prog->vp.bfc[info->out[i].si] = i;
          break;
+      case TGSI_SEMANTIC_LAYER:
+         prog->gp.has_layer = true;
+         prog->gp.layerid = n;
+         break;
       default:
          break;
       }
@@ -331,6 +335,7 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset)
    prog->vp.clpd[1] = map_undef;
    prog->vp.psiz = map_undef;
    prog->gp.primid = 0x80;
+   prog->gp.has_layer = 0;
 
    info->driverPriv = prog;
 
index 95167272f44615c0c4e294fe9e0793ecf3a288a0..5b092bde8153d998c99fc2aa12d8d4f08d72e0ad 100644 (file)
@@ -90,6 +90,8 @@ struct nv50_program {
       uint32_t vert_count;
       ubyte primid; /* primitive id output register */
       uint8_t prim_type; /* point, line strip or tri strip */
+      bool has_layer;
+      ubyte layerid; /* hw value of layer output */
    } gp;
 
    void *fixups; /* relocation records */
index ff711f96b639873180e6f2ad80ca53cc35d19d15..b24e3ac90e610da972d7e0d411390133f4350ee8 100644 (file)
@@ -346,6 +346,7 @@ 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 psiz = 0x000;
    uint32_t interp = fp->fp.interp;
    uint32_t colors = fp->fp.colors;
@@ -412,6 +413,12 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
       map[m++] = vp->gp.primid;
    }
 
+   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 (nv50->rast->pipe.point_size_per_vertex) {
       psiz = (m << 4) | 1;
       map[m++] = vp->vp.psiz;
@@ -468,9 +475,12 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 4);
    PUSH_DATA (push, colors);
    PUSH_DATA (push, (vp->vp.clpd_nr << 8) | 4);
-   PUSH_DATA (push, 0);
+   PUSH_DATA (push, layerid);
    PUSH_DATA (push, psiz);
 
+   BEGIN_NV04(push, NV50_3D(LAYER), 1);
+   PUSH_DATA (push, vp->gp.has_layer << 16);
+
    BEGIN_NV04(push, NV50_3D(FP_INTERPOLANT_CTRL), 1);
    PUSH_DATA (push, interp);