[Mesa-dev] [PATCH] swr: allocate all scratch space in one go for vertex buffers

Cherniak, Bruce bruce.cherniak at intel.com
Mon Nov 21 23:44:53 UTC 2016


Reviewed-by: Bruce Cherniak <bruce.cherniak at intel.com> 

> On Nov 20, 2016, at 4:25 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> 
> Multiple buffers may reference client arrays. When this happens, we
> might reach for scratch space multiple times, which could cause later
> arrays to invalidate the pointers allocated for the earlier ones.
> 
> This fixes copyteximage 2D_ARRAY.
> 
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
> 
> It also fixes a bunch of random piglits. Also explains why it was always the
> first thing that failed in copyteximage 2D_ARRAY -- the later ones had enough
> scratch space to hold the whole thing.
> 
> src/gallium/drivers/swr/swr_scratch.cpp |  4 ++--
> src/gallium/drivers/swr/swr_state.cpp   | 32 +++++++++++++++++++++++++++++---
> 2 files changed, 31 insertions(+), 5 deletions(-)
> 
> diff --git a/src/gallium/drivers/swr/swr_scratch.cpp b/src/gallium/drivers/swr/swr_scratch.cpp
> index 28eb2ac..2515c8b 100644
> --- a/src/gallium/drivers/swr/swr_scratch.cpp
> +++ b/src/gallium/drivers/swr/swr_scratch.cpp
> @@ -35,7 +35,6 @@ swr_copy_to_scratch_space(struct swr_context *ctx,
> {
>    void *ptr;
>    assert(space);
> -   assert(user_buffer);
>    assert(size);
> 
>    if (size >= 2048) { /* XXX TODO create KNOB_ for this */
> @@ -82,7 +81,8 @@ swr_copy_to_scratch_space(struct swr_context *ctx,
>    }
> 
>    /* Copy user_buffer to scratch */
> -   memcpy(ptr, user_buffer, size);
> +   if (user_buffer)
> +      memcpy(ptr, user_buffer, size);
> 
>    return ptr;
> }
> diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp
> index f5f42ba..dcbe434 100644
> --- a/src/gallium/drivers/swr/swr_state.cpp
> +++ b/src/gallium/drivers/swr/swr_state.cpp
> @@ -1039,14 +1039,39 @@ swr_update_derived(struct pipe_context *pipe,
>    /* Set vertex & index buffers */
>    /* (using draw info if called by swr_draw_vbo) */
>    if (ctx->dirty & SWR_NEW_VERTEX) {
> -      uint32_t size, pitch, max_vertex, partial_inbounds;
> +      uint32_t size, pitch, max_vertex, partial_inbounds, scratch_total;
>       const uint8_t *p_data;
> +      uint8_t *scratch = NULL;
> 
>       /* If being called by swr_draw_vbo, copy draw details */
>       struct pipe_draw_info info = {0};
>       if (p_draw_info)
>          info = *p_draw_info;
> 
> +      /* We must get all the scratch space in one go */
> +      scratch_total = 0;
> +      for (UINT i = 0; i < ctx->num_vertex_buffers; i++) {
> +         struct pipe_vertex_buffer *vb = &ctx->vertex_buffer[i];
> +
> +         if (!vb->user_buffer)
> +            continue;
> +
> +         if (vb->stride) {
> +            size = (info.max_index - info.min_index + 1) * vb->stride;
> +         } else {
> +            /* pitch = 0, means constant value
> +             * set size to 1 vertex */
> +            size = ctx->velems->stream_pitch[i];
> +         }
> +
> +         scratch_total += AlignUp(size, 4);
> +      }
> +
> +      if (scratch_total) {
> +         scratch = (uint8_t *)swr_copy_to_scratch_space(
> +               ctx, &ctx->scratch->vertex_buffer, NULL, scratch_total);
> +      }
> +
>       /* vertex buffers */
>       SWR_VERTEX_BUFFER_STATE swrVertexBuffers[PIPE_MAX_ATTRIBS];
>       for (UINT i = 0; i < ctx->num_vertex_buffers; i++) {
> @@ -1083,8 +1108,9 @@ swr_update_derived(struct pipe_context *pipe,
>             size = AlignUp(size, 4);
>             const void *ptr = (const uint8_t *) vb->user_buffer
>                + info.min_index * pitch;
> -            ptr = swr_copy_to_scratch_space(
> -               ctx, &ctx->scratch->vertex_buffer, ptr, size);
> +            memcpy(scratch, ptr, size);
> +            ptr = scratch;
> +            scratch += size;
>             p_data = (const uint8_t *)ptr - info.min_index * pitch;
>          }
> 
> -- 
> 2.7.3
> 



More information about the mesa-dev mailing list