summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-11-20 16:34:59 -0500
committerIlia Mirkin <[email protected]>2016-11-21 21:11:26 -0500
commitd48740568faff4aad78a46c67f73ea3c5ea3bd0c (patch)
tree89fe35fa10263d279d4a3dd7becbff1c89d3ffc5
parent16d42f2f3dcc8bec8d75b53d1e9e9cf5af6e528c (diff)
swr: allocate all scratch space in one go for vertex buffers
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]> Reviewed-by: Bruce Cherniak <[email protected]>
-rw-r--r--src/gallium/drivers/swr/swr_scratch.cpp4
-rw-r--r--src/gallium/drivers/swr/swr_state.cpp32
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 28eb2acb910..2515c8beaf3 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 e9ae786164a..a48baec251a 100644
--- a/src/gallium/drivers/swr/swr_state.cpp
+++ b/src/gallium/drivers/swr/swr_state.cpp
@@ -1002,14 +1002,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++) {
@@ -1046,8 +1071,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;
}