mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 06:30:11 +01:00
nv50: add support for user clip planes
Clip distance is calculated each time vertex position is written which is suboptiomal is some cases but very safe. User clip planes are an obsolete feature anyway. Every time number of clip planes increases, the vertex program is recompiled. That ensures no overhead in normal case (no user clip planes) and reasonable overhead otherwise. Fixes 3D windows in compiz, and reflection effect in neverball. Also fixes compiz expo plugin when windows were dragged and each window shown 3 times.
This commit is contained in:
parent
bfaa458445
commit
116133af34
4 changed files with 40 additions and 1 deletions
|
|
@ -395,6 +395,9 @@ nv50_vertprog_prepare(struct nv50_translation_info *ti)
|
|||
}
|
||||
}
|
||||
|
||||
p->vp.clpd = p->max_out;
|
||||
p->max_out += p->vp.clpd_nr;
|
||||
|
||||
for (i = 0; i < TGSI_SEMANTIC_COUNT; ++i) {
|
||||
switch (ti->sysval_map[i]) {
|
||||
case 2:
|
||||
|
|
|
|||
|
|
@ -170,6 +170,12 @@ nv50_vertprog_validate(struct nv50_context *nv50)
|
|||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nv50_program *vp = nv50->vertprog;
|
||||
|
||||
if (nv50->clip.nr > vp->vp.clpd_nr) {
|
||||
if (vp->translated)
|
||||
nv50_program_destroy(nv50, vp);
|
||||
vp->vp.clpd_nr = nv50->clip.nr;
|
||||
}
|
||||
|
||||
if (!nv50_program_validate(nv50, vp))
|
||||
return;
|
||||
|
||||
|
|
@ -369,7 +375,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
|
|||
m = nv50_vec4_map(map, 0, lin, &dummy, &vp->out[0]);
|
||||
|
||||
for (c = 0; c < vp->vp.clpd_nr; ++c)
|
||||
map[m++] |= vp->vp.clpd + c;
|
||||
map[m++] = vp->vp.clpd + c;
|
||||
|
||||
colors |= m << 8; /* adjust BFC0 id */
|
||||
|
||||
|
|
|
|||
|
|
@ -225,6 +225,9 @@ nv50_validate_clip(struct nv50_context *nv50)
|
|||
|
||||
BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
|
||||
OUT_RING (chan, (1 << nv50->clip.nr) - 1);
|
||||
|
||||
if (nv50->vertprog && nv50->clip.nr > nv50->vertprog->vp.clpd_nr)
|
||||
nv50->dirty |= NV50_NEW_VERTPROG;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -1552,6 +1552,8 @@ static void
|
|||
bld_instruction(struct bld_context *bld,
|
||||
const struct tgsi_full_instruction *insn)
|
||||
{
|
||||
struct nv50_program *prog = bld->ti->p;
|
||||
const struct tgsi_full_dst_register *dreg = &insn->Dst[0];
|
||||
struct nv_value *src0;
|
||||
struct nv_value *src1;
|
||||
struct nv_value *src2;
|
||||
|
|
@ -1990,6 +1992,31 @@ bld_instruction(struct bld_context *bld,
|
|||
|
||||
FOR_EACH_DST0_ENABLED_CHANNEL(c, insn)
|
||||
emit_store(bld, insn, c, dst0[c]);
|
||||
|
||||
if (prog->type == PIPE_SHADER_VERTEX && prog->vp.clpd_nr &&
|
||||
dreg->Register.File == TGSI_FILE_OUTPUT && !dreg->Register.Indirect &&
|
||||
prog->out[dreg->Register.Index].sn == TGSI_SEMANTIC_POSITION) {
|
||||
|
||||
int p;
|
||||
for (p = 0; p < prog->vp.clpd_nr; p++) {
|
||||
struct nv_value *clipd = NULL;
|
||||
|
||||
for (c = 0; c < 4; c++) {
|
||||
temp = new_value(bld->pc, NV_FILE_MEM_C(15), NV_TYPE_F32);
|
||||
temp->reg.id = p * 4 + c;
|
||||
temp = bld_insn_1(bld, NV_OP_LDA, temp);
|
||||
|
||||
clipd = clipd ?
|
||||
bld_insn_3(bld, NV_OP_MAD, dst0[c], temp, clipd) :
|
||||
bld_insn_2(bld, NV_OP_MUL, dst0[c], temp);
|
||||
}
|
||||
|
||||
temp = bld_insn_1(bld, NV_OP_MOV, clipd);
|
||||
temp->reg.file = NV_FILE_OUT;
|
||||
temp->reg.id = bld->ti->p->vp.clpd + p;
|
||||
temp->insn->fixed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue