From a864b82a04efd0642f5b2a9489b3c20dac46551f Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Tue, 20 Sep 2011 16:43:06 -0700 Subject: [PATCH] i965: allow for nonconsecutive elements of gl_ClipDistance to be enabled. When using user-defined clipping planes, the i965 driver compacts the array of clipping planes so that disabled clipping planes do not appear in it--this saves precious push constant space and makes it easier to generate the pre-GEN6 clip program. As a result, when enabling clipping planes in GEN6+ hardware, we always enable clipping planes 0 through n-1 (where n is the number of clipping planes enabled), regardless of which clipping planes the user actually requested. However, we can't do this when using gl_ClipDistance, because it would be prohibitively complex to compact the gl_ClipDistance array inside the user-supplied vertex shader. So, when enabling clipping planes in GEN6+ hardware, if gl_ClipDistance is in use, we need to pass the user-supplied enable flags directly through to the hardware rather than just enabling the first n planes. Fixes Piglit test vs-clip-distance-enables. Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_state.h | 5 +++++ src/mesa/drivers/dri/i965/gen6_clip_state.c | 28 ++++++++++++++++++++++++++-- src/mesa/drivers/dri/i965/gen7_clip_state.c | 9 +++++++-- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 6fc95eb646e..fabf0c0d26a 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -213,4 +213,9 @@ get_attr_override(struct brw_vue_map *vue_map, int urb_entry_read_offset, unsigned int gen7_depth_format(struct brw_context *brw); +/* gen6_clip_state.c */ +uint32_t +brw_compute_userclip_flags(bool uses_clip_distance, + GLbitfield clip_planes_enabled); + #endif diff --git a/src/mesa/drivers/dri/i965/gen6_clip_state.c b/src/mesa/drivers/dri/i965/gen6_clip_state.c index 872465dacc2..ffe2c53acfd 100644 --- a/src/mesa/drivers/dri/i965/gen6_clip_state.c +++ b/src/mesa/drivers/dri/i965/gen6_clip_state.c @@ -31,6 +31,25 @@ #include "brw_util.h" #include "intel_batchbuffer.h" +uint32_t +brw_compute_userclip_flags(bool uses_clip_distance, + GLbitfield clip_planes_enabled) +{ + if (uses_clip_distance) { + /* When using gl_ClipDistance, it is up to the shader to decide which + * clip distance values to use. + */ + return clip_planes_enabled; + } else { + /* When using clipping planes, we compact the ones that are in use so + * that they are always numbered consecutively from zero, so we need to + * enable clipping planes 0 through n-1 in the hardware regardless of + * which planes the user has selected. + */ + return (1 << brw_count_bits(clip_planes_enabled)) - 1; + } +} + static void upload_clip_state(struct brw_context *brw) { @@ -39,6 +58,10 @@ upload_clip_state(struct brw_context *brw) uint32_t depth_clamp = 0; uint32_t provoking, userclip; + /* BRW_NEW_VERTEX_PROGRAM */ + struct brw_vertex_program *vp = + (struct brw_vertex_program *)brw->vertex_program; + if (!ctx->Transform.DepthClamp) depth_clamp = GEN6_CLIP_Z_TEST; @@ -56,7 +79,8 @@ upload_clip_state(struct brw_context *brw) } /* _NEW_TRANSFORM */ - userclip = (1 << brw_count_bits(ctx->Transform.ClipPlanesEnabled)) - 1; + userclip = brw_compute_userclip_flags(vp->program.UsesClipDistance, + ctx->Transform.ClipPlanesEnabled); BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2)); @@ -77,7 +101,7 @@ upload_clip_state(struct brw_context *brw) const struct brw_tracked_state gen6_clip_state = { .dirty = { .mesa = _NEW_TRANSFORM | _NEW_LIGHT, - .brw = BRW_NEW_CONTEXT, + .brw = BRW_NEW_CONTEXT | BRW_NEW_VERTEX_PROGRAM, .cache = 0 }, .emit = upload_clip_state, diff --git a/src/mesa/drivers/dri/i965/gen7_clip_state.c b/src/mesa/drivers/dri/i965/gen7_clip_state.c index c23ba8cab5c..5458ce81046 100644 --- a/src/mesa/drivers/dri/i965/gen7_clip_state.c +++ b/src/mesa/drivers/dri/i965/gen7_clip_state.c @@ -39,6 +39,10 @@ upload_clip_state(struct brw_context *brw) /* _NEW_BUFFERS */ GLboolean render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0; + /* BRW_NEW_VERTEX_PROGRAM */ + struct brw_vertex_program *vp = + (struct brw_vertex_program *)brw->vertex_program; + dw1 |= GEN7_CLIP_EARLY_CULL; /* _NEW_POLYGON */ @@ -82,7 +86,8 @@ upload_clip_state(struct brw_context *brw) } /* _NEW_TRANSFORM */ - userclip = (1 << brw_count_bits(ctx->Transform.ClipPlanesEnabled)) - 1; + userclip = brw_compute_userclip_flags(vp->program.UsesClipDistance, + ctx->Transform.ClipPlanesEnabled); BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2)); @@ -106,7 +111,7 @@ const struct brw_tracked_state gen7_clip_state = { _NEW_POLYGON | _NEW_LIGHT | _NEW_TRANSFORM), - .brw = BRW_NEW_CONTEXT, + .brw = BRW_NEW_CONTEXT | BRW_NEW_VERTEX_PROGRAM, .cache = 0 }, .emit = upload_clip_state, -- 2.11.0