summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2013-06-05 23:17:10 -0400
committerZack Rusin <[email protected]>2013-06-10 22:04:27 -0400
commit2b2e7bb13361fa93c49c4872cc5070a66a7b1746 (patch)
tree562d262275793efb583ae5965924d51ec90508e5
parentc1a50f5ed7beb2f6aecfbacdc3339c8cb0107257 (diff)
draw: enable user plane clipping when clipdistance is used
Draw depended on clip_plane_enable being set in the rasterizer to use clipdistance registers for clipping. That's really unfriendly because it requires that rasterizer state to have variants for every shader out there. Instead of depending on the rasterizer lets extract the info from the available state: if a shader writes clipdistance then we need to use it and we need to clip using a number of planes equal to the number of writen clipdistance components. This way clipdistances just work. Signed-off-by: Zack Rusin <[email protected]> Reviewed-by: Jose Fonseca <[email protected]> Reviewed-by: Brian Paul <[email protected]> Reviewed-by: Roland Scheidegger <[email protected]>
-rw-r--r--src/gallium/auxiliary/draw/draw_cliptest_tmp.h22
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c5
2 files changed, 20 insertions, 7 deletions
diff --git a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
index 7a385c8d067..e4500dbd971 100644
--- a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
@@ -35,8 +35,8 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
const unsigned cv = draw_current_shader_clipvertex_output(pvs->draw);
unsigned cd[2];
const unsigned ef = pvs->draw->vs.edgeflag_output;
- const unsigned ucp_enable = pvs->draw->rasterizer->clip_plane_enable;
- const unsigned flags = (FLAGS);
+ unsigned ucp_enable = pvs->draw->rasterizer->clip_plane_enable;
+ unsigned flags = (FLAGS);
unsigned need_pipeline = 0;
unsigned j;
unsigned i;
@@ -46,12 +46,21 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
int viewport_index =
draw_current_shader_uses_viewport_index(pvs->draw) ?
*((unsigned*)out->data[viewport_index_output]): 0;
-
+ int num_written_clipdistance =
+ draw_current_shader_num_written_clipdistances(pvs->draw);
+
cd[0] = draw_current_shader_clipdistance_output(pvs->draw, 0);
cd[1] = draw_current_shader_clipdistance_output(pvs->draw, 1);
-
+
if (cd[0] != pos || cd[1] != pos)
- have_cd = true;
+ have_cd = true;
+
+ /* If clipdistance semantic has been written by the shader
+ * that means we're expected to do 'user plane clipping' */
+ if (num_written_clipdistance && !(flags & DO_CLIP_USER)) {
+ flags |= DO_CLIP_USER;
+ ucp_enable = (1 << num_written_clipdistance) - 1;
+ }
for (j = 0; j < info->count; j++) {
float *position = out->data[pos];
@@ -111,8 +120,7 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
if (flags & DO_CLIP_USER) {
unsigned ucp_mask = ucp_enable;
- int num_written_clipdistance =
- draw_current_shader_num_written_clipdistances(pvs->draw);
+
while (ucp_mask) {
unsigned plane_idx = ffs(ucp_mask)-1;
ucp_mask &= ~(1 << plane_idx);
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 4a71955f56a..6733e08fa4a 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -1146,6 +1146,11 @@ generate_clipmask(struct draw_llvm *llvm,
if (cd[0] != pos || cd[1] != pos)
have_cd = true;
+ if (num_written_clipdistance && !clip_user) {
+ clip_user = true;
+ ucp_enable = (1 << num_written_clipdistance) - 1;
+ }
+
mask = lp_build_const_int_vec(gallivm, i32_type, 0);
temp = lp_build_const_int_vec(gallivm, i32_type, 0);
zero = lp_build_const_vec(gallivm, f32_type, 0); /* 0.0f 0.0f 0.0f 0.0f */