From b85e93c0ca5ce881a59412b3ae617b5ac2c3aeb6 Mon Sep 17 00:00:00 2001
From: Christoph Bumiller <e0425955@student.tuwien.ac.at>
Date: Sat, 7 Jan 2012 17:26:58 +0100
Subject: nv50/ir,nvc0: make ClipDistance and ClipVertex work

---
 src/gallium/drivers/nvc0/nvc0_program.c        | 17 ++++++++++++-----
 src/gallium/drivers/nvc0/nvc0_program.h        |  4 ++--
 src/gallium/drivers/nvc0/nvc0_state_validate.c | 12 +++++-------
 3 files changed, 19 insertions(+), 14 deletions(-)

(limited to 'src/gallium/drivers/nvc0')

diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c
index 605bca5e6ba..5eee895fea7 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nvc0/nvc0_program.c
@@ -59,7 +59,9 @@ nvc0_shader_input_address(unsigned sn, unsigned si, unsigned ubase)
    case TGSI_SEMANTIC_FOG:          return 0x270;
    case TGSI_SEMANTIC_COLOR:        return 0x280 + si * 0x10;
    case TGSI_SEMANTIC_BCOLOR:       return 0x2a0 + si * 0x10;
-   case NV50_SEMANTIC_CLIPDISTANCE: return 0x2c0 + si * 0x10;
+   case NV50_SEMANTIC_CLIPDISTANCE: return 0x2c0 + si * 0x4;
+   case TGSI_SEMANTIC_CLIPDIST:     return 0x2c0 + si * 0x10;
+   case TGSI_SEMANTIC_CLIPVERTEX:   return 0x260;
    case NV50_SEMANTIC_POINTCOORD:   return 0x2e0;
    case NV50_SEMANTIC_TESSCOORD:    return 0x2f0;
    case TGSI_SEMANTIC_INSTANCEID:   return 0x2f8;
@@ -87,7 +89,9 @@ nvc0_shader_output_address(unsigned sn, unsigned si, unsigned ubase)
    case TGSI_SEMANTIC_FOG:           return 0x270;
    case TGSI_SEMANTIC_COLOR:         return 0x280 + si * 0x10;
    case TGSI_SEMANTIC_BCOLOR:        return 0x2a0 + si * 0x10;
-   case NV50_SEMANTIC_CLIPDISTANCE:  return 0x2c0 + si * 0x10;
+   case NV50_SEMANTIC_CLIPDISTANCE:  return 0x2c0 + si * 0x4;
+   case TGSI_SEMANTIC_CLIPDIST:      return 0x2c0 + si * 0x10;
+   case TGSI_SEMANTIC_CLIPVERTEX:    return 0x260;
    case NV50_SEMANTIC_TEXCOORD:      return 0x300 + si * 0x10;
    case TGSI_SEMANTIC_EDGEFLAG:      return ~0;
    default:
@@ -268,11 +272,14 @@ nvc0_vtgp_gen_header(struct nvc0_program *vp, struct nv50_ir_prog_info *info)
       }
    }
 
-   vp->vp.clip_enable = (1 << info->io.clipDistanceCount) - 1;
+   vp->vp.clip_enable = info->io.clipDistanceMask;
    for (i = 0; i < 8; ++i)
       if (info->io.cullDistanceMask & (1 << i))
          vp->vp.clip_mode |= 1 << (i * 4);
 
+   if (info->io.genUserClip < 0)
+      vp->vp.num_ucps = PIPE_MAX_CLIP_PLANES; /* prevent rebuilding */
+
    return 0;
 }
 
@@ -282,7 +289,7 @@ nvc0_vp_gen_header(struct nvc0_program *vp, struct nv50_ir_prog_info *info)
    vp->hdr[0] = 0x20061 | (1 << 10);
    vp->hdr[4] = 0xff000;
 
-   vp->hdr[18] = (1 << info->io.clipDistanceCount) - 1;
+   vp->hdr[18] = info->io.clipDistanceMask;
 
    return nvc0_vtgp_gen_header(vp, info);
 }
@@ -549,7 +556,7 @@ nvc0_program_translate(struct nvc0_program *prog)
    info->bin.sourceRep = NV50_PROGRAM_IR_TGSI;
    info->bin.source = (void *)prog->pipe.tokens;
 
-   info->io.clipDistanceCount = prog->vp.num_ucps;
+   info->io.genUserClip = prog->vp.num_ucps;
 
    info->assignSlots = nvc0_program_assign_varying_slots;
 
diff --git a/src/gallium/drivers/nvc0/nvc0_program.h b/src/gallium/drivers/nvc0/nvc0_program.h
index 10eb9f724d5..c384ef534d5 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.h
+++ b/src/gallium/drivers/nvc0/nvc0_program.h
@@ -36,9 +36,9 @@ struct nvc0_program {
 
    struct {
       uint32_t clip_mode; /* clip/cull selection */
-      uint8_t clip_enable; /* only applies if num_ucps == 0 */
+      uint8_t clip_enable; /* mask of defined clip planes */
       uint8_t edgeflag;
-      uint8_t num_ucps;
+      uint8_t num_ucps; /* also set to max if ClipDistance is used */
    } vp;
    struct {
       uint8_t early_z;
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index 472ddee5216..6307b3a3de6 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -301,7 +301,7 @@ nvc0_validate_clip(struct nvc0_context *nvc0)
 {
    struct nouveau_channel *chan = nvc0->screen->base.channel;
    struct nvc0_program *vp;
-   uint8_t clip_enable;
+   uint8_t clip_enable = nvc0->rast->pipe.clip_plane_enable;
 
    if (nvc0->dirty & NVC0_NEW_CLIP)
       nvc0_upload_uclip_planes(nvc0);
@@ -312,13 +312,11 @@ nvc0_validate_clip(struct nvc0_context *nvc0)
       if (!vp)
          vp = nvc0->vertprog;
    }
-   clip_enable = vp->vp.clip_enable;
 
-   if (!clip_enable) {
-      clip_enable = nvc0->rast->pipe.clip_plane_enable;
-      if (unlikely(clip_enable))
-         nvc0_check_program_ucps(nvc0, vp, clip_enable);
-   }
+   if (clip_enable && vp->vp.num_ucps < PIPE_MAX_CLIP_PLANES)
+      nvc0_check_program_ucps(nvc0, vp, clip_enable);
+
+   clip_enable &= vp->vp.clip_enable;
 
    if (nvc0->state.clip_enable != clip_enable) {
       nvc0->state.clip_enable = clip_enable;
-- 
cgit v1.2.3