summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_blit.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2013-04-21 23:26:52 +0200
committerMarek Olšák <[email protected]>2013-04-23 20:26:20 +0200
commitb69207642079fe8ba33c594750415e8d9c66a06f (patch)
treef71b6cfd90363297b7f15c0acd55508267fc7a5a /src/gallium/drivers/r600/r600_blit.c
parent1ba46bbb4c99caa7e297f2ec6717e962765275cb (diff)
r600g: initialize CMASK and HTILE with the GPU using streamout
This fixes a crash when a resource cannot be mapped to the CPU's address space because it's too big. 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. Reviewed-by: Alex Deucher <[email protected]> NOTE: This is a candidate for the 9.1 branch.
Diffstat (limited to 'src/gallium/drivers/r600/r600_blit.c')
-rw-r--r--src/gallium/drivers/r600/r600_blit.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 8fc83aaad25..a0384bf366a 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);