summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2011-02-16 22:23:23 +0100
committerMarek Olšák <maraeo@gmail.com>2011-02-16 22:23:23 +0100
commitfa3f1348e49feeac511dbe5b22bbddc47f56ba81 (patch)
tree1d3cae04ff7a746975fb5a0d6202200324a116c9 /src/gallium/winsys/radeon/drm/radeon_drm_bo.c
parent2d1cc27729bd1808a39b226ae3eda5663328ba74 (diff)
r300g: fix a race between CS and SET_TILING ioctls
Diffstat (limited to 'src/gallium/winsys/radeon/drm/radeon_drm_bo.c')
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_bo.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index afb8131acb..3094337a3c 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -394,13 +394,26 @@ static void radeon_bo_get_tiling(struct r300_winsys_bo *_buf,
}
static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf,
+ struct r300_winsys_cs *rcs,
enum r300_buffer_tiling microtiled,
enum r300_buffer_tiling macrotiled,
uint32_t pitch)
{
struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf));
+ struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
struct drm_radeon_gem_set_tiling args = {};
+ /* Tiling determines how DRM treats the buffer data.
+ * We must flush CS when changing it if the buffer is referenced. */
+ if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) {
+ radeon_drm_cs_flush(rcs);
+ radeon_drm_cs_sync_flush(rcs);
+ }
+
+ while (p_atomic_read(&bo->num_active_ioctls)) {
+ sched_yield();
+ }
+
if (microtiled == R300_BUFFER_TILED)
args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE;
else if (microtiled == R300_BUFFER_SQUARETILED)