r300g: fix map_buffer
authorMarek Olšák <maraeo@gmail.com>
Mon, 13 Sep 2010 05:44:32 +0000 (07:44 +0200)
committerMarek Olšák <maraeo@gmail.com>
Mon, 13 Sep 2010 05:52:13 +0000 (07:52 +0200)
https://bugs.freedesktop.org/show_bug.cgi?id=30145

src/gallium/winsys/radeon/drm/radeon_drm_buffer.c

index cef59975ca8b4a7dd5cff6392a693519b151c480..19f194b36cb305276083c2f6141b57d3d2ad5106 100644 (file)
@@ -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);
     }