> On Jul 11, 2017, at 8:20 PM, Bruce Cherniak <bruce.chern...@intel.com> wrote: > > If size of client memory copy is too large, don't copy. The draw will > access user-buffer directly and then block. This is faster and more > efficient than queuing many large client draws. > > Applications that use large draws from client arrays benefit from this. > VMD is an example. > > The threshold for this path defaults to 32KB. This value can be > overridden by setting environment variable SWR_CLIENT_COPY_LIMIT. > --- > src/gallium/drivers/swr/swr_context.h | 1 + > src/gallium/drivers/swr/swr_draw.cpp | 9 +++++++++ > src/gallium/drivers/swr/swr_screen.cpp | 10 +++++++++ > src/gallium/drivers/swr/swr_screen.h | 2 ++ > src/gallium/drivers/swr/swr_state.cpp | 37 ++++++++++++++++++++++++---------- > 5 files changed, 48 insertions(+), 11 deletions(-) > > diff --git a/src/gallium/drivers/swr/swr_context.h > b/src/gallium/drivers/swr/swr_context.h > index 3ff4bf3e2f..ab3057af96 100644 > --- a/src/gallium/drivers/swr/swr_context.h > +++ b/src/gallium/drivers/swr/swr_context.h > @@ -51,6 +51,7 @@ > #define SWR_NEW_FRAMEBUFFER (1 << 15) > #define SWR_NEW_CLIP (1 << 16) > #define SWR_NEW_SO (1 << 17) > +#define SWR_LARGE_CLIENT_DRAW (1<<18) // Indicates client draw will block > > namespace std > { > diff --git a/src/gallium/drivers/swr/swr_draw.cpp > b/src/gallium/drivers/swr/swr_draw.cpp > index f26b8e873c..cbd1558624 100644 > --- a/src/gallium/drivers/swr/swr_draw.cpp > +++ b/src/gallium/drivers/swr/swr_draw.cpp > @@ -188,6 +188,15 @@ swr_draw_vbo(struct pipe_context *pipe, const struct > pipe_draw_info *info) > info->instance_count, > info->start, > info->start_instance); > + > + /* On large client-buffer draw, we used client buffer directly, without > + * copy. Block until draw is finished. > + * VMD is an example application that benefits from this. */ > + if (ctx->dirty & SWR_LARGE_CLIENT_DRAW) { > + struct swr_screen *screen = swr_screen(pipe->screen); > + swr_fence_submit(ctx, screen->flush_fence); > + swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0); > + } > } > > > diff --git a/src/gallium/drivers/swr/swr_screen.cpp > b/src/gallium/drivers/swr/swr_screen.cpp > index 9b3897ce6b..8be09697e6 100644 > --- a/src/gallium/drivers/swr/swr_screen.cpp > +++ b/src/gallium/drivers/swr/swr_screen.cpp > @@ -1066,6 +1066,16 @@ swr_destroy_screen(struct pipe_screen *p_screen) > static void > swr_validate_env_options(struct swr_screen *screen) > { > + /* The client_copy_limit sets a maximum on the amount of user-buffer > memory > + * copied to scratch space on a draw. Past this, the draw will access > + * user-buffer directly and then block. This is faster than queuing many > + * large client draws. */ > + screen->client_copy_limit = 32768; > + int client_copy_limit = > + debug_get_num_option("SWR_CLIENT_COPY_LIMIT", 32768);
Could you move the default value into a macro defined at the top of the file, so it can be easily spotted in the future? > + if (client_copy_limit > 0) > + screen->client_copy_limit = client_copy_limit; > + > /* XXX msaa under development, disable by default for now */ > screen->msaa_max_count = 0; /* was SWR_MAX_NUM_MULTISAMPLES; */ > > diff --git a/src/gallium/drivers/swr/swr_screen.h > b/src/gallium/drivers/swr/swr_screen.h > index dc1bb47f02..6d6d1cb87d 100644 > --- a/src/gallium/drivers/swr/swr_screen.h > +++ b/src/gallium/drivers/swr/swr_screen.h > @@ -43,8 +43,10 @@ struct swr_screen { > > struct sw_winsys *winsys; > > + /* Configurable environment settings */ > boolean msaa_force_enable; > uint8_t msaa_max_count; > + uint32_t client_copy_limit; > > HANDLE hJitMgr; > }; > diff --git a/src/gallium/drivers/swr/swr_state.cpp > b/src/gallium/drivers/swr/swr_state.cpp > index 45c9c213e5..6c406a37ec 100644 > --- a/src/gallium/drivers/swr/swr_state.cpp > +++ b/src/gallium/drivers/swr/swr_state.cpp > @@ -1267,12 +1267,20 @@ swr_update_derived(struct pipe_context *pipe, > partial_inbounds = 0; > min_vertex_index = info.min_index; > > - /* Copy only needed vertices to scratch space */ > size = AlignUp(size, 4); > - const void *ptr = (const uint8_t *) vb->buffer.user + base; > - ptr = (uint8_t *)swr_copy_to_scratch_space( > - ctx, &ctx->scratch->vertex_buffer, ptr, size); > - p_data = (const uint8_t *)ptr - base; > + /* If size of client memory copy is too large, don't copy. The > + * draw will access user-buffer directly and then block. This is > + * faster than queuing many large client draws. */ > + if (size >= screen->client_copy_limit) { > + post_update_dirty_flags |= SWR_LARGE_CLIENT_DRAW; > + p_data = (const uint8_t *) vb->buffer.user; > + } else { > + /* Copy only needed vertices to scratch space */ > + const void *ptr = (const uint8_t *) vb->buffer.user + base; > + ptr = (uint8_t *)swr_copy_to_scratch_space( > + ctx, &ctx->scratch->vertex_buffer, ptr, size); > + p_data = (const uint8_t *)ptr - base; > + } > } > > swrVertexBuffers[i] = {0}; > @@ -1311,12 +1319,19 @@ swr_update_derived(struct pipe_context *pipe, > > size = info.count * pitch; > size = AlignUp(size, 4); > - > - /* Copy indices to scratch space */ > - const void *ptr = info.index.user; > - ptr = swr_copy_to_scratch_space( > - ctx, &ctx->scratch->index_buffer, ptr, size); > - p_data = (const uint8_t *)ptr; > + /* If size of client memory copy is too large, don't copy. The > + * draw will access user-buffer directly and then block. This is > + * faster than queuing many large client draws. */ > + if (size >= screen->client_copy_limit) { > + post_update_dirty_flags |= SWR_LARGE_CLIENT_DRAW; > + p_data = (const uint8_t *) info.index.user; > + } else { > + /* Copy indices to scratch space */ > + const void *ptr = info.index.user; > + ptr = swr_copy_to_scratch_space( > + ctx, &ctx->scratch->index_buffer, ptr, size); > + p_data = (const uint8_t *)ptr; > + } > } > > SWR_INDEX_BUFFER_STATE swrIndexBuffer; > -- > 2.11.0 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev