summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_driver.h3
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_from_sm4.cpp9
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp33
-rw-r--r--src/gallium/drivers/nvc0/nvc0_program.c17
-rw-r--r--src/gallium/drivers/nvc0/nvc0_program.h4
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state_validate.c12
6 files changed, 54 insertions, 24 deletions
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h b/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h
index a6a5e93f58c..4baef537370 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h
@@ -152,8 +152,9 @@ struct nv50_ir_prog_info
struct {
uint8_t clipDistance; /* index of first clip distance output */
- uint8_t clipDistanceCount;
+ uint8_t clipDistanceMask; /* mask of clip distances defined */
uint8_t cullDistanceMask; /* clip distance mode (1 bit per output) */
+ int8_t genUserClip; /* request user clip planes for ClipVertex */
uint8_t pointSize; /* output index for PointSize */
uint8_t edgeFlagIn;
uint8_t edgeFlagOut;
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_from_sm4.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_from_sm4.cpp
index 7ed00e336c6..11720d2db67 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_from_sm4.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_from_sm4.cpp
@@ -899,10 +899,10 @@ Converter::inspectDeclaration(const sm4_dcl& dcl)
assert(prog->getType() != Program::TYPE_FRAGMENT);
break;
case SM4_SV_CULL_DISTANCE: // XXX: order ?
- info.io.cullDistanceMask |= 1 << info.io.clipDistanceCount;
- // fall through
+ info.io.cullDistanceMask |= 1 << info.io.clipDistanceMask;
+ // fall through
case SM4_SV_CLIP_DISTANCE:
- info.io.clipDistanceCount++;
+ info.io.clipDistanceMask++; // abuse as count
break;
default:
break;
@@ -2257,6 +2257,9 @@ Converter::run()
for (unsigned int pos = 0; pos < sm4.dcls.size(); ++pos)
handleDeclaration(*sm4.dcls[pos]);
+ info.io.genUserClip = -1; // no UCPs permitted with SM4 shaders
+ info.io.clipDistanceMask = (1 << info.io.clipDistanceMask) - 1;
+
info.assignSlots(&info);
if (sm4.dcls.size() == 0 && sm4.insns.size() == 0)
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
index 6cb61b87766..050f2516b99 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
@@ -593,6 +593,8 @@ public:
bool mainTempsInLMem;
+ int clipVertexOutput;
+
uint8_t *resourceTargets; // TGSI_TEXTURE_*
unsigned resourceCount;
@@ -651,6 +653,8 @@ bool Source::scanSource()
if (!insns)
return false;
+ clipVertexOutput = -1;
+
resourceCount = scan.file_max[TGSI_FILE_RESOURCE] + 1;
resourceTargets = new uint8_t[resourceCount];
@@ -707,6 +711,9 @@ bool Source::scanSource()
if (mainTempsInLMem)
info->bin.tlsSpace += (scan.file_max[TGSI_FILE_TEMPORARY] + 1) * 16;
+ if (info->io.genUserClip > 0)
+ info->io.clipDistanceMask = (1 << info->io.genUserClip) - 1;
+
return info->assignSlots(info) == 0;
}
@@ -734,6 +741,9 @@ void Source::scanProperty(const struct tgsi_full_property *prop)
case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
// we don't care
break;
+ case TGSI_PROPERTY_VS_PROHIBIT_UCPS:
+ info->io.genUserClip = -1;
+ break;
default:
INFO("unhandled TGSI property %d\n", prop->Property.PropertyName);
break;
@@ -820,6 +830,9 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
case TGSI_SEMANTIC_POSITION:
if (info->type == PIPE_SHADER_FRAGMENT)
info->io.fragDepth = i;
+ else
+ if (clipVertexOutput < 0)
+ clipVertexOutput = i;
break;
case TGSI_SEMANTIC_COLOR:
if (info->type == PIPE_SHADER_FRAGMENT)
@@ -828,6 +841,14 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
case TGSI_SEMANTIC_EDGEFLAG:
info->io.edgeFlagOut = i;
break;
+ case TGSI_SEMANTIC_CLIPVERTEX:
+ clipVertexOutput = i;
+ break;
+ case TGSI_SEMANTIC_CLIPDIST:
+ info->io.clipDistanceMask |=
+ decl->Declaration.UsageMask << (si * 4);
+ info->io.genUserClip = -1;
+ break;
default:
break;
}
@@ -1324,9 +1345,9 @@ Converter::storeDst(int d, int c, Value *val)
Value *ptr = dst.isIndirect(0) ?
fetchSrc(dst.getIndirect(0), 0, NULL) : NULL;
- if (info->io.clipDistanceCount &&
+ if (info->io.genUserClip > 0 &&
dst.getFile() == TGSI_FILE_OUTPUT &&
- info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_POSITION) {
+ !dst.isIndirect(0) && dst.getIndex(0) == code->clipVertexOutput) {
mkMov(clipVtx[c], val);
val = clipVtx[c];
}
@@ -2136,7 +2157,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
setPosition(epilogue, true);
if (prog->getType() == Program::TYPE_FRAGMENT)
exportOutputs();
- if (info->io.clipDistanceCount)
+ if (info->io.genUserClip > 0)
handleUserClipPlanes();
mkOp(OP_EXIT, TYPE_NONE, NULL)->terminator = 1;
}
@@ -2173,7 +2194,7 @@ Converter::handleUserClipPlanes()
int i, c;
for (c = 0; c < 4; ++c) {
- for (i = 0; i < info->io.clipDistanceCount; ++i) {
+ for (i = 0; i < info->io.genUserClip; ++i) {
Value *ucp;
ucp = mkLoad(TYPE_F32, mkSymbol(FILE_MEMORY_CONST, 15, TYPE_F32,
i * 16 + c * 4), NULL);
@@ -2184,7 +2205,7 @@ Converter::handleUserClipPlanes()
}
}
- for (i = 0; i < info->io.clipDistanceCount; ++i)
+ for (i = 0; i < info->io.genUserClip; ++i)
mkOp2(OP_WRSV, TYPE_F32, NULL, mkSysVal(SV_CLIP_DISTANCE, i), res[i]);
}
@@ -2275,7 +2296,7 @@ Converter::run()
entryBBs.push(entry);
leaveBBs.push(leave);
- if (info->io.clipDistanceCount) {
+ if (info->io.genUserClip > 0) {
for (int c = 0; c < 4; ++c)
clipVtx[c] = getScratch();
}
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;