diff options
author | Marek Olšák <maraeo@gmail.com> | 2011-02-16 22:23:23 +0100 |
---|---|---|
committer | Marek Olšák <maraeo@gmail.com> | 2011-02-16 22:23:23 +0100 |
commit | fa3f1348e49feeac511dbe5b22bbddc47f56ba81 (patch) | |
tree | 1d3cae04ff7a746975fb5a0d6202200324a116c9 /src/gallium/winsys/radeon/drm/radeon_drm_bo.c | |
parent | 2d1cc27729bd1808a39b226ae3eda5663328ba74 (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.c | 13 |
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) |