This puts a global pipe_context in r600_screen, which is guarded by a mutex,
so that we can use pipe_context when there isn't one around.
Hopefully our multi-context support is solid.
---
 src/gallium/drivers/r600/r600_blit.c    |   31 ++++++++++++++++++++++++
 src/gallium/drivers/r600/r600_pipe.c    |   39 +++++++++++++++++++++++++++++++
 src/gallium/drivers/r600/r600_pipe.h    |    7 ++++++
 src/gallium/drivers/r600/r600_texture.c |   10 +++-----
 4 files changed, 80 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_blit.c 
b/src/gallium/drivers/r600/r600_blit.c
index 8fc83aa..a0384bf 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -522,6 +522,37 @@ void r600_copy_buffer(struct pipe_context *ctx, struct 
pipe_resource *dst, unsig
        }
 }
 
+static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource 
*dst,
+                             unsigned offset, unsigned size, unsigned char 
value)
+{
+       struct r600_context *rctx = (struct r600_context*)ctx;
+
+       if (rctx->screen->has_streamout && offset % 4 == 0 && size % 4 == 0) {
+               union pipe_color_union clear_value;
+               uint32_t v = value;
+
+               clear_value.ui[0] = v | (v << 8) | (v << 16) | (v << 24);
+
+               r600_blitter_begin(ctx, R600_DISABLE_RENDER_COND);
+               util_blitter_clear_buffer(rctx->blitter, dst, offset, size,
+                                         1, &clear_value);
+               r600_blitter_end(ctx);
+       } else {
+               char *map = r600_buffer_mmap_sync_with_rings(rctx, 
r600_resource(dst),
+                                                            
PIPE_TRANSFER_WRITE);
+               memset(map + offset, value, size);
+       }
+}
+
+void r600_screen_clear_buffer(struct r600_screen *rscreen, struct 
pipe_resource *dst,
+                             unsigned offset, unsigned size, unsigned char 
value)
+{
+       pipe_mutex_lock(rscreen->aux_context_lock);
+       r600_clear_buffer(rscreen->aux_context, dst, offset, size, value);
+       rscreen->aux_context->flush(rscreen->aux_context, NULL, 0);
+       pipe_mutex_unlock(rscreen->aux_context_lock);
+}
+
 static bool util_format_is_subsampled_2x1_32bpp(enum pipe_format format)
 {
        const struct util_format_description *desc = 
util_format_description(format);
diff --git a/src/gallium/drivers/r600/r600_pipe.c 
b/src/gallium/drivers/r600/r600_pipe.c
index 4948ddd..008539d 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -940,6 +940,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)
        if (rscreen == NULL)
                return;
 
+       pipe_mutex_destroy(rscreen->aux_context_lock);
+       rscreen->aux_context->destroy(rscreen->aux_context);
+
        if (rscreen->global_pool) {
                compute_memory_pool_delete(rscreen->global_pool);
        }
@@ -1319,5 +1322,41 @@ struct pipe_screen *r600_screen_create(struct 
radeon_winsys *ws)
        }
 #endif
 
+       /* Create the auxiliary context. */
+       pipe_mutex_init(rscreen->aux_context_lock);
+       rscreen->aux_context = rscreen->screen.context_create(&rscreen->screen, 
NULL);
+
+#if 0 /* This is for testing whether aux_context and buffer clearing work 
correctly. */
+       struct pipe_resource templ = {};
+
+       templ.width0 = 4;
+       templ.height0 = 2048;
+       templ.depth0 = 1;
+       templ.array_size = 1;
+       templ.target = PIPE_TEXTURE_2D;
+       templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
+       templ.usage = PIPE_USAGE_STATIC;
+
+       struct r600_resource *res = 
r600_resource(rscreen->screen.resource_create(&rscreen->screen, &templ));
+       unsigned char *map = ws->buffer_map(res->cs_buf, NULL, 
PIPE_TRANSFER_WRITE);
+
+       memset(map, 0, 256);
+
+       r600_screen_clear_buffer(rscreen, &res->b.b, 4, 4, 0xCC);
+       r600_screen_clear_buffer(rscreen, &res->b.b, 8, 4, 0xDD);
+       r600_screen_clear_buffer(rscreen, &res->b.b, 12, 4, 0xEE);
+       r600_screen_clear_buffer(rscreen, &res->b.b, 20, 4, 0xFF);
+       r600_screen_clear_buffer(rscreen, &res->b.b, 32, 20, 0x87);
+
+       ws->buffer_wait(res->buf, RADEON_USAGE_WRITE);
+
+       int i;
+       for (i = 0; i < 256; i++) {
+               printf("%02X", map[i]);
+               if (i % 16 == 15)
+                       printf("\n");
+       }
+#endif
+
        return &rscreen->screen;
 }
diff --git a/src/gallium/drivers/r600/r600_pipe.h 
b/src/gallium/drivers/r600/r600_pipe.h
index 4a692e7..1dbed80 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -290,6 +290,11 @@ struct r600_screen {
        unsigned                        cs_count;
 #endif
        r600g_dma_blit_t                dma_blit;
+
+       /* Auxiliary context. Mainly used to initialize resources.
+        * It must be locked prior to using and flushed before unlocking. */
+       struct pipe_context             *aux_context;
+       pipe_mutex                      aux_context_lock;
 };
 
 struct r600_pipe_sampler_view {
@@ -721,6 +726,8 @@ void evergreen_update_db_shader_control(struct r600_context 
* rctx);
 /* r600_blit.c */
 void r600_copy_buffer(struct pipe_context *ctx, struct pipe_resource *dst, 
unsigned dstx,
                      struct pipe_resource *src, const struct pipe_box 
*src_box);
+void r600_screen_clear_buffer(struct r600_screen *rscreen, struct 
pipe_resource *dst,
+                             unsigned offset, unsigned size, unsigned char 
value);
 void r600_init_blit_functions(struct r600_context *rctx);
 void r600_blit_decompress_depth(struct pipe_context *ctx,
                struct r600_texture *texture,
diff --git a/src/gallium/drivers/r600/r600_texture.c 
b/src/gallium/drivers/r600/r600_texture.c
index 98cb118..3a1f2fe 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -480,10 +480,7 @@ r600_texture_create_object(struct pipe_screen *screen,
                         */
                        R600_ERR("r600: failed to create bo for htile 
buffers\n");
                } else {
-                       void *ptr;
-                       ptr = rscreen->ws->buffer_map(rtex->htile->cs_buf, 
NULL, PIPE_TRANSFER_WRITE);
-                       memset(ptr, 0x0, htile_size);
-                       rscreen->ws->buffer_unmap(rtex->htile->cs_buf);
+                       r600_screen_clear_buffer(rscreen, &rtex->htile->b.b, 0, 
htile_size, 0);
                }
        }
 
@@ -505,9 +502,8 @@ r600_texture_create_object(struct pipe_screen *screen,
 
        if (rtex->cmask_size) {
                /* Initialize the cmask to 0xCC (= compressed state). */
-               char *ptr = rscreen->ws->buffer_map(resource->cs_buf, NULL, 
PIPE_TRANSFER_WRITE);
-               memset(ptr + rtex->cmask_offset, 0xCC, rtex->cmask_size);
-               rscreen->ws->buffer_unmap(resource->cs_buf);
+               r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
+                                        rtex->cmask_offset, rtex->cmask_size, 
0xCC);
        }
 
        if (rscreen->debug_flags & DBG_VM) {
-- 
1.7.10.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to