[Mesa-dev] [PATCH 1/8] softpipe: add depth clamping support.

Roland Scheidegger sroland at vmware.com
Tue Jun 10 06:42:39 PDT 2014


Am 10.06.2014 07:57, schrieb Dave Airlie:
> From: Dave Airlie <airlied at redhat.com>
> 
> This passes the piglit depth clamp tests.
> 
> this is required for GL 3.2.
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/gallium/drivers/softpipe/sp_quad_depth_test.c | 37 ++++++++++++++++++-----
>  src/gallium/drivers/softpipe/sp_screen.c          |  2 +-
>  2 files changed, 31 insertions(+), 8 deletions(-)
> 
> diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
> index f4d7993..2a63fa0 100644
> --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
> +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
> @@ -148,10 +148,11 @@ interpolate_quad_depth( struct quad_header *quad )
>   * Compute the depth_data::qzzzz[] values from the float fragment Z values.
>   */
>  static void
> -convert_quad_depth( struct depth_data *data, 
> +convert_quad_depth( struct quad_stage *qs, struct depth_data *data, 
>                      const struct quad_header *quad )
>  {
>     unsigned j;
> +   float dvals[TGSI_QUAD_SIZE];
>  
>     /* Convert quad's float depth values to int depth values (qzzzz).
>      * If the Z buffer stores integer values, we _have_ to do the depth
> @@ -159,13 +160,31 @@ convert_quad_depth( struct depth_data *data,
>      * conversion of Z values (which isn't an identity function) will cause
>      * Z-fighting errors.
>      */
> +   if (!qs->softpipe->rasterizer->depth_clip) {
> +      float near_val, far_val;
> +      float minval, maxval;
> +
> +      near_val = qs->softpipe->viewport.translate[2] - qs->softpipe->viewport.scale[2];
> +      far_val = near_val + (qs->softpipe->viewport.scale[2] * 2.0);
> +
> +      minval = MIN2(near_val, far_val);
> +      maxval = MAX2(near_val, far_val);
I guess you could precalculate minval/maxval before running the fs. No
biggie though.
(And I'm wondering, though it's only partially related to this code, if
the depth 0/1 clamp is actually happening somewhere. This code here will
clamp to 0/1 if depth clamp is enabled (since the near/far range can't
be outside that), but not if depth clamp is disabled - clipping will
eliminate values outside that, but if depth is written by the fs it
won't of course. GL (but not d3d10) still requires you to clamp depth to
0/1 in this case, and while everybody hates that behavior for float
depth buffers at least if you have non-float depth buffers you need to
do it somewhere otherwise the values outside 0/1 will be random. But
maybe this is done elsewhere.)

> +      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> +         dvals[j] = CLAMP(quad->output.depth[j], minval, maxval);
> +      }
> +   } else {
> +      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> +         dvals[j] = quad->output.depth[j];
> +      }
> +   }
> +
>     switch (data->format) {
>     case PIPE_FORMAT_Z16_UNORM:
>        {
>           float scale = 65535.0;
>  
>           for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -            data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
> +            data->qzzzz[j] = (unsigned) (dvals[j] * scale);
>           }
>        }
>        break;
> @@ -174,7 +193,7 @@ convert_quad_depth( struct depth_data *data,
>           double scale = (double) (uint) ~0UL;
>  
>           for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -            data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
> +            data->qzzzz[j] = (unsigned) (dvals[j] * scale);
>           }
>        }
>        break;
> @@ -184,7 +203,7 @@ convert_quad_depth( struct depth_data *data,
>           float scale = (float) ((1 << 24) - 1);
>  
>           for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -            data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
> +            data->qzzzz[j] = (unsigned) (dvals[j] * scale);
>           }
>        }
>        break;
> @@ -194,7 +213,7 @@ convert_quad_depth( struct depth_data *data,
>           float scale = (float) ((1 << 24) - 1);
>  
>           for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -            data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
> +            data->qzzzz[j] = (unsigned) (dvals[j] * scale);
>           }
>        }
>        break;
> @@ -204,7 +223,7 @@ convert_quad_depth( struct depth_data *data,
>           union fi fui;
>  
>           for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -            fui.f = quad->output.depth[j];
> +            fui.f = dvals[j];
>              data->qzzzz[j] = fui.ui;
>           }
>        }
> @@ -796,7 +815,7 @@ depth_test_quads_fallback(struct quad_stage *qs,
>              if (interp_depth)
>                 interpolate_quad_depth(quads[i]);
>  
> -            convert_quad_depth(&data, quads[i]);
> +            convert_quad_depth(qs, &data, quads[i]);
>           }
>  
>           if (qs->softpipe->depth_stencil->stencil[0].enabled) {
> @@ -895,6 +914,8 @@ choose_depth_test(struct quad_stage *qs,
>  
>     boolean occlusion = qs->softpipe->active_query_count;
>  
> +   boolean clipped = qs->softpipe->rasterizer->depth_clip;
> +
>     if(!qs->softpipe->framebuffer.zsbuf)
>        depth = depthwrite = stencil = FALSE;
>  
> @@ -905,6 +926,7 @@ choose_depth_test(struct quad_stage *qs,
>     if (!alpha &&
>         !depth &&
>         !occlusion &&
> +       !clipped && 
>         !stencil) {
>        qs->run = depth_noop;
>     }
> @@ -913,6 +935,7 @@ choose_depth_test(struct quad_stage *qs,
>              depth && 
>              depthwrite && 
>              !occlusion &&
> +            !clipped &&
>              !stencil) 
>     {
>        if (qs->softpipe->framebuffer.zsbuf->format == PIPE_FORMAT_Z16_UNORM) {
> diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
> index 34dbb91..7851777 100644
> --- a/src/gallium/drivers/softpipe/sp_screen.c
> +++ b/src/gallium/drivers/softpipe/sp_screen.c
> @@ -111,7 +111,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
>     case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
>        return 1;
>     case PIPE_CAP_DEPTH_CLIP_DISABLE:
> -      return 0;
> +      return 1;
>     case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
>        return PIPE_MAX_SO_BUFFERS;
>     case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
> 

Reviewed-by: Roland Scheidegger <sroland at vmware.com>


More information about the mesa-dev mailing list