[Mesa-dev] [PATCH 2/5] draw: enable user plane clipping when clipdistance is used
Roland Scheidegger
sroland at vmware.com
Tue Jun 11 08:23:04 PDT 2013
Am 10.06.2013 16:31, schrieb Zack Rusin:
> 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
written
> just work.
>
> Signed-off-by: Zack Rusin <zackr at vmware.com>
> ---
> src/gallium/auxiliary/draw/draw_cliptest_tmp.h | 21 ++++++++++++++++-----
> src/gallium/auxiliary/draw/draw_llvm.c | 8 ++++++++
> 2 files changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
> index 7a385c8..6736dba 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,24 @@ 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)) {
> + unsigned i;
> + flags |= DO_CLIP_USER;
> + ucp_enable = 0;
> + for (i = 0; i < num_written_clipdistance; ++i)
> + ucp_enable |= 1 << i;
> + }
>
> for (j = 0; j < info->count; j++) {
> float *position = out->data[pos];
> @@ -111,8 +123,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 4a71955..82f4c20 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm.c
> @@ -1146,6 +1146,14 @@ generate_clipmask(struct draw_llvm *llvm,
> if (cd[0] != pos || cd[1] != pos)
> have_cd = true;
>
> + if (num_written_clipdistance && !clip_user) {
> + unsigned i;
> + clip_user = true;
> + ucp_enable = 0;
> + for (i = 0; i < num_written_clipdistance; ++i)
> + ucp_enable |= 1 << i;
> + }
> +
> 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 */
>
I'm not entirely sure there's no odd opengl case where this logic
wouldn't work but provided there's no piglit regressions this looks good
to me.
Roland
More information about the mesa-dev
mailing list