r300g: implement blit
authorMarek Olšák <maraeo@gmail.com>
Wed, 12 Sep 2012 22:38:44 +0000 (00:38 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sun, 30 Sep 2012 16:57:56 +0000 (18:57 +0200)
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/drivers/r300/r300_blit.c

index 3e8217622c5fc5070bda4349e90a9e62217a466f..96c96c367a26901a9af1da56449bf3ccf6f5762a 100644 (file)
@@ -42,6 +42,9 @@ enum r300_blitter_op /* bitmask */
     R300_COPY          = R300_STOP_QUERY | R300_SAVE_FRAMEBUFFER |
                          R300_SAVE_TEXTURES | R300_IGNORE_RENDER_COND,
 
+    R300_BLIT          = R300_STOP_QUERY | R300_SAVE_FRAMEBUFFER |
+                         R300_SAVE_TEXTURES | R300_IGNORE_RENDER_COND,
+
     R300_DECOMPRESS    = R300_STOP_QUERY | R300_IGNORE_RENDER_COND,
 };
 
@@ -62,6 +65,7 @@ static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op o
     util_blitter_save_fragment_shader(r300->blitter, r300->fs.state);
     util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
     util_blitter_save_viewport(r300->blitter, &r300->viewport);
+    util_blitter_save_scissor(r300->blitter, r300->scissor_state.state);
     util_blitter_save_vertex_buffers(r300->blitter, r300->nr_vertex_buffers,
                                      r300->vertex_buffer);
     util_blitter_save_vertex_elements(r300->blitter, r300->velems);
@@ -588,10 +592,46 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
     pipe_sampler_view_reference(&src_view, NULL);
 }
 
+static void r300_blit(struct pipe_context *pipe,
+                      const struct pipe_blit_info *blit_info)
+{
+    struct r300_context *r300 = r300_context(pipe);
+    struct pipe_framebuffer_state *fb =
+        (struct pipe_framebuffer_state*)r300->fb_state.state;
+    struct pipe_blit_info info = *blit_info;
+
+    /* Decompress ZMASK. */
+    if (r300->zmask_in_use && !r300->locked_zbuffer) {
+        if (fb->zsbuf->texture == info.src.resource ||
+            fb->zsbuf->texture == info.dst.resource) {
+            r300_decompress_zmask(r300);
+        }
+    }
+
+    /* Blit a combined depth-stencil resource as color.
+     * S8Z24 is the only supported stencil format. */
+    if ((info.mask & PIPE_MASK_S) &&
+        info.src.format == PIPE_FORMAT_S8_UINT_Z24_UNORM &&
+        info.dst.format == PIPE_FORMAT_S8_UINT_Z24_UNORM) {
+        info.src.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+        info.dst.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+        if (info.mask & PIPE_MASK_Z) {
+            info.mask = PIPE_MASK_RGBA; /* depth+stencil */
+        } else {
+            info.mask = PIPE_MASK_B; /* stencil only */
+        }
+    }
+
+    r300_blitter_begin(r300, R300_BLIT);
+    util_blitter_blit(r300->blitter, &info);
+    r300_blitter_end(r300);
+}
+
 void r300_init_blit_functions(struct r300_context *r300)
 {
     r300->context.clear = r300_clear;
     r300->context.clear_render_target = r300_clear_render_target;
     r300->context.clear_depth_stencil = r300_clear_depth_stencil;
     r300->context.resource_copy_region = r300_resource_copy_region;
+    r300->context.blit = r300_blit;
 }