diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_shader_state.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state_validate.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 27 |
4 files changed, 40 insertions, 1 deletions
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 41d3e14dc0f..4def93d6b84 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -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: diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 82c346cb5ea..5d3f52c38c1 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -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 */ diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index cdf1a982fcc..11561f5a8e6 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -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 diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c index 25dcaaea14f..15aa40cddd1 100644 --- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c +++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c @@ -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 |