aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-09-13 07:44:32 +0200
committerMarek Olšák <[email protected]>2010-09-13 07:52:13 +0200
commitae1aa1496561ef0faf0524c4b95d21d63e12a9ee (patch)
tree26d92cf1f195b8dbc9f863343aa637b253d64400
parent185434fbe8e5e1ce650304bd077766b4e77b5f91 (diff)
r300g: fix map_buffer
https://bugs.freedesktop.org/show_bug.cgi?id=30145
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index cef59975ca8..19f194b36cb 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -20,9 +20,6 @@ struct radeon_drm_buffer {
struct radeon_bo *bo;
- /* The CS associated with the last buffer_map. */
- struct radeon_libdrm_cs *cs;
-
boolean flinked;
uint32_t flink;
@@ -95,9 +92,21 @@ radeon_drm_buffer_map_internal(struct pb_buffer *_buf,
struct radeon_libdrm_cs *cs = flush_ctx;
int write = 0;
+ /* Note how we use radeon_bo_is_referenced_by_cs here. There are
+ * basically two places this map function can be called from:
+ * - pb_map
+ * - create_buffer (in the buffer reuse case)
+ *
+ * Since pb managers are per-winsys managers, not per-context managers,
+ * and we shouldn't reuse buffers if they are in-use in any context,
+ * we simply ask: is this buffer referenced by *any* CS?
+ *
+ * The problem with buffer_create is that it comes from pipe_screen,
+ * so we have no CS to look at, though luckily the following code
+ * is sufficient to tell whether the buffer is in use. */
if (flags & PB_USAGE_DONTBLOCK) {
if (_buf->base.usage & RADEON_PB_USAGE_VERTEX)
- if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs))
+ if (radeon_bo_is_referenced_by_cs(buf->bo, NULL))
return NULL;
}
@@ -110,6 +119,10 @@ radeon_drm_buffer_map_internal(struct pb_buffer *_buf,
return NULL;
}
+ /* If we don't have any CS and the buffer is referenced,
+ * we cannot flush. */
+ assert(cs || !radeon_bo_is_referenced_by_cs(buf->bo, NULL));
+
if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) {
cs->flush_cs(cs->flush_data);
}