[Mesa-dev] [PATCH 2/2] r600g: initialize CMASK and HTILE with the GPU using streamout

Marek Olšák maraeo at gmail.com
Sun Apr 21 16:25:34 PDT 2013


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



More information about the mesa-dev mailing list