Reviewed-by: Bruce Cherniak <[email protected]> > On Nov 20, 2016, at 4:25 PM, Ilia Mirkin <[email protected]> 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 <[email protected]> > --- > > 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 >
_______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
