This will be useful for efficient handling of the DISCARD transfer flags. --- src/gallium/drivers/r600/r600_blit.c | 78 +++++++++++++++++++++++---------- 1 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 9ab85c8..0d9618d 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -27,18 +27,21 @@ enum r600_blitter_op /* bitmask */ { - R600_SAVE_TEXTURES = 1, - R600_SAVE_FRAMEBUFFER = 2, - R600_DISABLE_RENDER_COND = 4, + R600_SAVE_FRAGMENT_STATE = 1, + R600_SAVE_TEXTURES = 2, + R600_SAVE_FRAMEBUFFER = 4, + R600_DISABLE_RENDER_COND = 8, - R600_CLEAR = 0, + R600_CLEAR = R600_SAVE_FRAGMENT_STATE, - R600_CLEAR_SURFACE = R600_SAVE_FRAMEBUFFER, + R600_CLEAR_SURFACE = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER, - R600_COPY = R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES | + R600_COPY_BUFFER = R600_DISABLE_RENDER_COND, + + R600_COPY_TEXTURE = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES | R600_DISABLE_RENDER_COND, - R600_DECOMPRESS = R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND, + R600_DECOMPRESS = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND, }; static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op) @@ -47,23 +50,26 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op r600_suspend_nontimer_queries(rctx); - util_blitter_save_blend(rctx->blitter, rctx->states[R600_PIPE_STATE_BLEND]); - util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->states[R600_PIPE_STATE_DSA]); - if (rctx->states[R600_PIPE_STATE_STENCIL_REF]) { - util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref); - } - util_blitter_save_rasterizer(rctx->blitter, rctx->states[R600_PIPE_STATE_RASTERIZER]); - util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); - util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); - util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements); - if (rctx->states[R600_PIPE_STATE_VIEWPORT]) { - util_blitter_save_viewport(rctx->blitter, &rctx->viewport); - } util_blitter_save_vertex_buffers(rctx->blitter, rctx->vbuf_mgr->nr_vertex_buffers, rctx->vbuf_mgr->vertex_buffer); + util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements); + util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets, (struct pipe_stream_output_target**)rctx->so_targets); + util_blitter_save_rasterizer(rctx->blitter, rctx->states[R600_PIPE_STATE_RASTERIZER]); + + if (op & R600_SAVE_FRAGMENT_STATE) { + if (rctx->states[R600_PIPE_STATE_VIEWPORT]) { + util_blitter_save_viewport(rctx->blitter, &rctx->viewport); + } + util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); + util_blitter_save_blend(rctx->blitter, rctx->states[R600_PIPE_STATE_BLEND]); + util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->states[R600_PIPE_STATE_DSA]); + if (rctx->states[R600_PIPE_STATE_STENCIL_REF]) { + util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref); + } + } if (op & R600_SAVE_FRAMEBUFFER) util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer); @@ -240,7 +246,32 @@ static void r600_clear_depth_stencil(struct pipe_context *ctx, r600_blitter_end(ctx); } - +static void r600_copy_buffer(struct pipe_context *ctx, + struct pipe_resource *dst, + unsigned dstx, + struct pipe_resource *src, + const struct pipe_box *src_box) +{ + struct r600_context *rctx = (struct r600_context*)ctx; + + if (rctx->screen->info.r600_has_streamout && + /* Require dword alignment. */ + dstx % 4 == 0 && src_box->x % 4 == 0 && src_box->width % 4 == 0) { +#if 0 + printf("copy_buffer in hw (streamout=%i, dstx = %i, srcx = %i, size = %i\n", + rctx->screen->info.r600_has_streamout, dstx, src_box->x, src_box->width); +#endif + r600_blitter_begin(ctx, R600_COPY_BUFFER); + util_blitter_copy_buffer(rctx->blitter, dst, dstx, src, src_box->x, src_box->width); + r600_blitter_end(ctx); + } else { +#if 0 + printf("copy_buffer in sw (streamout=%i, dstx = %i, srcx = %i, size = %i\n", + rctx->screen->info.r600_has_streamout, dstx, src_box->x, src_box->width); +#endif + util_resource_copy_region(ctx, dst, 0, dstx, 0, 0, src, 0, src_box); + } +} /* Copy a block of pixels from one surface to another using HW. */ static void r600_hw_copy_region(struct pipe_context *ctx, @@ -253,7 +284,7 @@ static void r600_hw_copy_region(struct pipe_context *ctx, { struct r600_context *rctx = (struct r600_context *)ctx; - r600_blitter_begin(ctx, R600_COPY); + r600_blitter_begin(ctx, R600_COPY_TEXTURE); util_blitter_copy_texture(rctx->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box, TRUE); r600_blitter_end(ctx); @@ -334,10 +365,9 @@ static void r600_resource_copy_region(struct pipe_context *ctx, memset(orig_info, 0, sizeof(orig_info)); - /* Fallback for buffers. */ + /* Handle buffers first. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { - util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, - src, src_level, src_box); + r600_copy_buffer(ctx, dst, dstx, src, src_box); return; } -- 1.7.5.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev