From 73ea0e7fd405af2866062492231c84580a306211 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Tue, 18 Oct 2011 12:07:01 +0200 Subject: [PATCH] nvc0: add support for clip distance shader outputs --- src/gallium/drivers/nvc0/nvc0_3d.xml.h | 52 +++++++++++++++---- src/gallium/drivers/nvc0/nvc0_context.h | 4 +- src/gallium/drivers/nvc0/nvc0_program.c | 5 ++ src/gallium/drivers/nvc0/nvc0_program.h | 2 + src/gallium/drivers/nvc0/nvc0_shader_state.c | 29 ++++++++++- .../drivers/nvc0/nvc0_state_validate.c | 12 +++-- 6 files changed, 88 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h index 9264b72dadd..a8d91082740 100644 --- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h +++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h @@ -697,15 +697,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_CLIPID_FILL_RECT_VERT_HIGH__MASK 0xffff0000 #define NVC0_3D_CLIPID_FILL_RECT_VERT_HIGH__SHIFT 16 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE 0x00001510 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE_0 0x00000001 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE_1 0x00000002 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE_2 0x00000004 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE_3 0x00000008 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE_4 0x00000010 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE_5 0x00000020 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE_6 0x00000040 -#define NVC0_3D_VP_CLIP_DISTANCE_ENABLE_7 0x00000080 +#define NVC0_3D_CLIP_DISTANCE_ENABLE 0x00001510 +#define NVC0_3D_CLIP_DISTANCE_ENABLE_0 0x00000001 +#define NVC0_3D_CLIP_DISTANCE_ENABLE_1 0x00000002 +#define NVC0_3D_CLIP_DISTANCE_ENABLE_2 0x00000004 +#define NVC0_3D_CLIP_DISTANCE_ENABLE_3 0x00000008 +#define NVC0_3D_CLIP_DISTANCE_ENABLE_4 0x00000010 +#define NVC0_3D_CLIP_DISTANCE_ENABLE_5 0x00000020 +#define NVC0_3D_CLIP_DISTANCE_ENABLE_6 0x00000040 +#define NVC0_3D_CLIP_DISTANCE_ENABLE_7 0x00000080 #define NVC0_3D_SAMPLECNT_ENABLE 0x00001514 @@ -1022,6 +1022,40 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1 0x00001000 #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2 0x00002000 +#define NVC0_3D_CLIP_DISTANCE_MODE 0x00001940 +#define NVC0_3D_CLIP_DISTANCE_MODE_0__MASK 0x00000001 +#define NVC0_3D_CLIP_DISTANCE_MODE_0__SHIFT 0 +#define NVC0_3D_CLIP_DISTANCE_MODE_0_CLIP 0x00000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_0_CULL 0x00000001 +#define NVC0_3D_CLIP_DISTANCE_MODE_1__MASK 0x00000010 +#define NVC0_3D_CLIP_DISTANCE_MODE_1__SHIFT 4 +#define NVC0_3D_CLIP_DISTANCE_MODE_1_CLIP 0x00000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_1_CULL 0x00000010 +#define NVC0_3D_CLIP_DISTANCE_MODE_2__MASK 0x00000100 +#define NVC0_3D_CLIP_DISTANCE_MODE_2__SHIFT 8 +#define NVC0_3D_CLIP_DISTANCE_MODE_2_CLIP 0x00000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_2_CULL 0x00000100 +#define NVC0_3D_CLIP_DISTANCE_MODE_3__MASK 0x00001000 +#define NVC0_3D_CLIP_DISTANCE_MODE_3__SHIFT 12 +#define NVC0_3D_CLIP_DISTANCE_MODE_3_CLIP 0x00000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_3_CULL 0x00001000 +#define NVC0_3D_CLIP_DISTANCE_MODE_4__MASK 0x00010000 +#define NVC0_3D_CLIP_DISTANCE_MODE_4__SHIFT 16 +#define NVC0_3D_CLIP_DISTANCE_MODE_4_CLIP 0x00000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_4_CULL 0x00010000 +#define NVC0_3D_CLIP_DISTANCE_MODE_5__MASK 0x00100000 +#define NVC0_3D_CLIP_DISTANCE_MODE_5__SHIFT 20 +#define NVC0_3D_CLIP_DISTANCE_MODE_5_CLIP 0x00000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_5_CULL 0x00100000 +#define NVC0_3D_CLIP_DISTANCE_MODE_6__MASK 0x01000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_6__SHIFT 24 +#define NVC0_3D_CLIP_DISTANCE_MODE_6_CLIP 0x00000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_6_CULL 0x01000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_7__MASK 0x10000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_7__SHIFT 28 +#define NVC0_3D_CLIP_DISTANCE_MODE_7_CLIP 0x00000000 +#define NVC0_3D_CLIP_DISTANCE_MODE_7_CULL 0x10000000 + #define NVC0_3D_CLIP_RECTS_EN 0x0000194c #define NVC0_3D_CLIP_RECTS_MODE 0x00001950 diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index c739b1b68e2..c46e7430f85 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -74,13 +74,15 @@ struct nvc0_context { int32_t index_bias; boolean prim_restart; boolean early_z; + uint16_t scissor; uint8_t num_vtxbufs; uint8_t num_vtxelts; uint8_t num_textures[5]; uint8_t num_samplers[5]; uint8_t tls_required; /* bitmask of shader types using l[] */ uint8_t c14_bound; /* whether immediate array constbuf is bound */ - uint16_t scissor; + uint8_t clip_enable; + uint32_t clip_mode; uint32_t uniform_buffer_bound[5]; } state; diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c index c422c9b1087..f3185b488e8 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nvc0/nvc0_program.c @@ -268,6 +268,11 @@ nvc0_vtgp_gen_header(struct nvc0_program *vp, struct nv50_ir_prog_info *info) } } + vp->vp.clip_enable = (1 << info->io.clipDistanceCount) - 1; + for (i = 0; i < 8; ++i) + if (info->io.cullDistanceMask & (1 << i)) + vp->vp.clip_mode |= 1 << (i * 4); + return 0; } diff --git a/src/gallium/drivers/nvc0/nvc0_program.h b/src/gallium/drivers/nvc0/nvc0_program.h index 239890bd89a..b107850ea92 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.h +++ b/src/gallium/drivers/nvc0/nvc0_program.h @@ -27,6 +27,8 @@ struct nvc0_program { uint32_t flags[2]; struct { + uint32_t clip_mode; /* clip/cull selection */ + uint8_t clip_enable; /* only applies if num_ucps == 0 */ uint8_t edgeflag; uint8_t num_ucps; uint8_t out_pos[PIPE_MAX_SHADER_OUTPUTS]; diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index 472bdb11aba..f4a12fbee11 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -59,6 +59,25 @@ nvc0_program_update_context_state(struct nvc0_context *nvc0, } } +static void +nvc0_program_validate_clip(struct nvc0_context *nvc0, struct nvc0_program *vp) +{ + struct nouveau_channel *chan = nvc0->screen->base.channel; + + if (nvc0->vertprog->vp.num_ucps) + return; + + if (nvc0->state.clip_enable != vp->vp.clip_enable) { + nvc0->state.clip_enable = vp->vp.clip_enable; + IMMED_RING(chan, RING_3D(CLIP_DISTANCE_ENABLE), vp->vp.clip_enable); + } + if (nvc0->state.clip_mode != vp->vp.clip_mode) { + nvc0->state.clip_mode = vp->vp.clip_mode; + BEGIN_RING(chan, RING_3D(CLIP_DISTANCE_MODE), 1); + OUT_RING (chan, vp->vp.clip_mode); + } +} + static INLINE boolean nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog) { @@ -98,6 +117,9 @@ nvc0_vertprog_validate(struct nvc0_context *nvc0) BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(1)), 1); OUT_RING (chan, vp->max_gpr); + if (!nvc0->gmtyprog && !nvc0->tevlprog) + nvc0_program_validate_clip(nvc0, vp); + // BEGIN_RING(chan, RING_3D_(0x163c), 1); // OUT_RING (chan, 0); } @@ -178,7 +200,10 @@ nvc0_tevlprog_validate(struct nvc0_context *nvc0) BEGIN_RING(chan, RING_3D(SP_START_ID(3)), 1); OUT_RING (chan, tp->code_base); BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(3)), 1); - OUT_RING (chan, tp->max_gpr); + OUT_RING (chan, tp->max_gpr); + + if (!nvc0->gmtyprog) + nvc0_program_validate_clip(nvc0, tp); } void @@ -205,6 +230,8 @@ nvc0_gmtyprog_validate(struct nvc0_context *nvc0) OUT_RING (chan, gp->max_gpr); BEGIN_RING(chan, RING_3D(LAYER), 1); OUT_RING (chan, (gp->hdr[13] & (1 << 9)) ? NVC0_3D_LAYER_USE_GP : 0); + + nvc0_program_validate_clip(nvc0, gp); } /* It's *is* kind of shader related. We need to inspect the program diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index 2fca2919ce6..5cf68c7b6f2 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -267,11 +267,13 @@ nvc0_validate_clip(struct nvc0_context *nvc0) 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 { - IMMED_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 0); + if (nvc0->vertprog->vp.num_ucps) { + nvc0->state.clip_mode = 0; + nvc0->state.clip_enable = (1 << nvc0->clip.nr) - 1; + IMMED_RING(chan, RING_3D(CLIP_DISTANCE_ENABLE), nvc0->state.clip_enable); + IMMED_RING(chan, RING_3D(CLIP_DISTANCE_MODE), 0); } } @@ -474,13 +476,13 @@ static struct state_validate { { nvc0_validate_stipple, NVC0_NEW_STIPPLE }, { nvc0_validate_scissor, NVC0_NEW_SCISSOR | NVC0_NEW_RASTERIZER }, { nvc0_validate_viewport, NVC0_NEW_VIEWPORT }, - { nvc0_validate_clip, NVC0_NEW_CLIP }, { nvc0_vertprog_validate, NVC0_NEW_VERTPROG }, { nvc0_tctlprog_validate, NVC0_NEW_TCTLPROG }, { nvc0_tevlprog_validate, NVC0_NEW_TEVLPROG }, { nvc0_gmtyprog_validate, NVC0_NEW_GMTYPROG }, { nvc0_fragprog_validate, NVC0_NEW_FRAGPROG }, { nvc0_validate_derived_1, NVC0_NEW_FRAGPROG | NVC0_NEW_ZSA }, + { nvc0_validate_clip, NVC0_NEW_CLIP }, { nvc0_constbufs_validate, NVC0_NEW_CONSTBUF }, { nvc0_validate_textures, NVC0_NEW_TEXTURES }, { nvc0_validate_samplers, NVC0_NEW_SAMPLERS }, -- 2.30.2