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

Reply via email to