Mesa (nvc0): nvc0: support user clip planes

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Sat Dec 11 15:25:04 UTC 2010


Module: Mesa
Branch: nvc0
Commit: 5138ac033ad3708e2b82f2beebc887f65a77309e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5138ac033ad3708e2b82f2beebc887f65a77309e

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Sat Dec 11 16:23:43 2010 +0100

nvc0: support user clip planes

---

 src/gallium/drivers/nvc0/nvc0_program.c        |    7 +++
 src/gallium/drivers/nvc0/nvc0_program.h        |    2 +
 src/gallium/drivers/nvc0/nvc0_screen.c         |   12 +++++-
 src/gallium/drivers/nvc0/nvc0_shader_state.c   |    8 ++++
 src/gallium/drivers/nvc0/nvc0_state.c          |    5 ++
 src/gallium/drivers/nvc0/nvc0_state_validate.c |   17 ++++++++
 src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c     |   48 +++++++++++++++++++++++-
 7 files changed, 96 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c
index 7aa6ef0..e159b71 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nvc0/nvc0_program.c
@@ -418,6 +418,8 @@ nvc0_vp_gen_header(struct nvc0_program *vp, struct nvc0_translation_info *ti)
    vp->hdr[0] = 0x20461;
    vp->hdr[4] = 0xff000;
 
+   vp->hdr[18] = (1 << vp->vp.num_ucps) - 1;
+
    return nvc0_vp_gp_gen_header(vp, ti);
 }
 
@@ -605,6 +607,9 @@ nvc0_program_translate(struct nvc0_program *prog)
 
    ti->edgeflag_out = PIPE_MAX_SHADER_OUTPUTS;
 
+   if (prog->type == PIPE_SHADER_VERTEX && prog->vp.num_ucps)
+      ti->append_ucp = TRUE;
+
    ret = nvc0_prog_scan(ti);
    if (ret) {
       NOUVEAU_ERR("unsupported shader program\n");
@@ -646,5 +651,7 @@ nvc0_program_destroy(struct nvc0_context *nvc0, struct nvc0_program *prog)
    if (prog->relocs)
       FREE(prog->relocs);
 
+   memset(prog->hdr, 0, sizeof(prog->hdr));
+
    prog->translated = FALSE;
 }
diff --git a/src/gallium/drivers/nvc0/nvc0_program.h b/src/gallium/drivers/nvc0/nvc0_program.h
index 42d9be3..1271303 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.h
+++ b/src/gallium/drivers/nvc0/nvc0_program.h
@@ -27,6 +27,7 @@ struct nvc0_program {
 
    struct {
       uint8_t edgeflag;
+      uint8_t num_ucps;
    } vp;
 
    void *relocs;
@@ -71,6 +72,7 @@ struct nvc0_translation_info {
    ubyte edgeflag_out;
    struct nvc0_subroutine *subr;
    unsigned num_subrs;
+   boolean append_ucp;
    struct tgsi_shader_info scan;
 };
 
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index fb100e5..f0d06be 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -457,11 +457,21 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
    nouveau_resource_init(&screen->text_heap, 0, 1 << 20);
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 5 << 16,
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16,
                         &screen->uniforms);
    if (ret)
       goto fail;
 
+   /* auxiliary constants (6 user clip planes, base instance id) */
+   BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
+   OUT_RING  (chan, 256);
+   OUT_RELOCh(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   for (i = 0; i < 5; ++i) {
+      BEGIN_RING(chan, RING_3D(CB_BIND(i)), 1);
+      OUT_RING  (chan, (15 << 4) | 1);
+   }
+
    screen->tls_size = 4 * 4 * 32 * 128 * 4;
    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17,
                         screen->tls_size, &screen->tls);
diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c
index a16fa6c..a6595c5 100644
--- a/src/gallium/drivers/nvc0/nvc0_shader_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c
@@ -67,6 +67,14 @@ nvc0_vertprog_validate(struct nvc0_context *nvc0)
    struct nouveau_channel *chan = nvc0->screen->base.channel;
    struct nvc0_program *vp = nvc0->vertprog;
 
+   if (nvc0->clip.nr > vp->vp.num_ucps) {
+      assert(nvc0->clip.nr <= 6);
+      vp->vp.num_ucps = 6;
+
+      if (vp->translated)
+         nvc0_program_destroy(nvc0, vp);
+   }
+
    if (!nvc0_program_validate(nvc0, vp))
          return;
 
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index c7a8c4b..8d29323 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -699,8 +699,13 @@ nvc0_set_clip_state(struct pipe_context *pipe,
                     const struct pipe_clip_state *clip)
 {
     struct nvc0_context *nvc0 = nvc0_context(pipe);
+    const unsigned size = clip->nr * sizeof(clip->ucp[0]);
+
+    memcpy(&nvc0->clip.ucp[0][0], &clip->ucp[0][0], size);
+    nvc0->clip.nr = clip->nr;
 
     nvc0->clip.depth_clamp = clip->depth_clamp;
+
     nvc0->dirty |= NVC0_NEW_CLIP;
 }
 
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index 2b38ebc..ded461b 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -193,6 +193,23 @@ nvc0_validate_clip(struct nvc0_context *nvc0)
 
    BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
    OUT_RING  (chan, clip);
+
+   if (nvc0->clip.nr) {
+      struct nouveau_bo *bo = nvc0->screen->uniforms;
+
+      BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
+      OUT_RING  (chan, 256);
+      OUT_RELOCh(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+      OUT_RELOCl(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+      BEGIN_RING_1I(chan, RING_3D(CB_POS), nvc0->clip.nr * 4 + 1);
+      OUT_RING  (chan, 0);
+      OUT_RINGp (chan, &nvc0->clip.ucp[0][0], nvc0->clip.nr * 4);
+
+      BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
+      OUT_RING  (chan, (1 << nvc0->clip.nr) - 1);
+   } else {
+      INLIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 0);
+   }
 }
 
 static void
diff --git a/src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c b/src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c
index 8a20983..d0c8275 100644
--- a/src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c
+++ b/src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c
@@ -111,6 +111,7 @@ struct bld_context {
    struct bld_register ovs[BLD_MAX_OUTPS][4]; /* TGSI_FILE_OUTPUT, FP only */
 
    uint32_t outputs_written[(PIPE_MAX_SHADER_OUTPUTS + 7) / 8];
+   int hpos_index;
 
    struct nv_value *zero;
    struct nv_value *frag_coord[4];
@@ -904,6 +905,38 @@ bld_is_output_written(struct bld_context *bld, int i, int c)
 }
 
 static void
+bld_append_vp_ucp(struct bld_context *bld)
+{
+   struct nv_value *res[6];
+   struct nv_value *ucp, *vtx, *out;
+   struct nv_instruction *insn;
+   int i, c;
+
+   assert(bld->ti->prog->vp.num_ucps <= 6);
+
+   for (c = 0; c < 4; ++c) {
+      vtx = bld_fetch_global(bld, &bld->ovs[bld->hpos_index][c]);
+
+      for (i = 0; i < bld->ti->prog->vp.num_ucps; ++i) {
+         ucp = new_value(bld->pc, NV_FILE_MEM_C(15), 4);
+         ucp->reg.address = i * 16 + c * 4;
+
+         if (c == 0)
+            res[i] = bld_insn_2(bld, NV_OP_MUL_F32, vtx, ucp);
+         else
+            res[i] = bld_insn_3(bld, NV_OP_MAD_F32, vtx, ucp, res[i]);
+      }
+   }
+
+   for (i = 0; i < bld->ti->prog->vp.num_ucps; ++i) {
+      (out = new_value(bld->pc, NV_FILE_MEM_V, 4))->reg.address = 0x2c0 + i * 4;
+      (insn = new_instruction(bld->pc, NV_OP_EXPORT))->fixed = 1;
+      nv_reference(bld->pc, insn, 0, out);
+      nv_reference(bld->pc, insn, 1, res[i]);
+   }
+}
+
+static void
 bld_export_fp_outputs(struct bld_context *bld)
 {
    struct nv_value *vals[4];
@@ -1755,11 +1788,13 @@ bld_instruction(struct bld_context *bld,
       /* VP outputs are exported in-place as scalars, optimization later */
       if (bld->pc->is_fragprog)
          bld_export_fp_outputs(bld);
-      break;
+      if (bld->ti->append_ucp)
+         bld_append_vp_ucp(bld);
+      return;
    default:
       NOUVEAU_ERR("unhandled opcode %u\n", insn->Instruction.Opcode);
       abort();
-      break;
+      return;
    }
 
    if (insn->Dst[0].Register.File == TGSI_FILE_OUTPUT &&
@@ -1767,6 +1802,15 @@ bld_instruction(struct bld_context *bld,
       struct nv_instruction *mi = NULL;
       uint size;
 
+      if (bld->ti->append_ucp) {
+         if (bld->ti->output_loc[insn->Dst[0].Register.Index][0] == 0x70) {
+            bld->hpos_index = insn->Dst[0].Register.Index;
+            for (c = 0; c < 4; ++c)
+               if (mask & (1 << c))
+                  STORE_OUTP(insn->Dst[0].Register.Index, c, dst0[c]);
+         }
+      }
+
       for (c = 0; c < 4; ++c)
          if ((mask & (1 << c)) &&
              ((dst0[c]->reg.file == NV_FILE_IMM) ||




More information about the mesa-commit mailing list