drm/radeon: flush read cache for gtt with fence on r6xx and newer GPU V3
authorJerome Glisse <jglisse@redhat.com>
Wed, 26 Oct 2011 15:41:22 +0000 (11:41 -0400)
committerDave Airlie <airlied@redhat.com>
Tue, 1 Nov 2011 16:02:07 +0000 (16:02 +0000)
Cayman seems to be particularly sensitive to read cache returning
old data after bind/unbind to GTT. Flush read cache for GTT range
with each fences for all new hw. Should fix several rendering glitches.
Like

V2 flush whole address space
V3 also flush shader read cache

https://bugs.freedesktop.org/show_bug.cgi?id=40221
https://bugs.freedesktop.org/show_bug.cgi?id=38022
https://bugzilla.redhat.com/show_bug.cgi?id=738790

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_blit_kms.c

index 551e76f283f7f2e1a3acb0f7dde1662cc276db84..914e5af84163cc38b9e03e214af13db747b7dd80 100644 (file)
@@ -625,9 +625,9 @@ int evergreen_blit_init(struct radeon_device *rdev)
        rdev->r600_blit.primitives.set_default_state = set_default_state;
 
        rdev->r600_blit.ring_size_common = 55; /* shaders + def state */
-       rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */
        rdev->r600_blit.ring_size_common += 5; /* done copy */
-       rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */
 
        rdev->r600_blit.ring_size_per_loop = 74;
        if (rdev->family >= CHIP_CAYMAN)
index 12470b090ddf871a62e478d2bca0c340792175d3..1f007adc272313e0f3b114d6884562947cb9b104 100644 (file)
@@ -2331,6 +2331,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
        if (rdev->wb.use_event) {
                u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET +
                        (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base);
+               /* flush read cache over gart */
+               radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
+               radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA |
+                                       PACKET3_VC_ACTION_ENA |
+                                       PACKET3_SH_ACTION_ENA);
+               radeon_ring_write(rdev, 0xFFFFFFFF);
+               radeon_ring_write(rdev, 0);
+               radeon_ring_write(rdev, 10); /* poll interval */
                /* EVENT_WRITE_EOP - flush caches, send int */
                radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
                radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
@@ -2339,6 +2347,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
                radeon_ring_write(rdev, fence->seq);
                radeon_ring_write(rdev, 0);
        } else {
+               /* flush read cache over gart */
+               radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
+               radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA |
+                                       PACKET3_VC_ACTION_ENA |
+                                       PACKET3_SH_ACTION_ENA);
+               radeon_ring_write(rdev, 0xFFFFFFFF);
+               radeon_ring_write(rdev, 0);
+               radeon_ring_write(rdev, 10); /* poll interval */
                radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
                radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0));
                /* wait for 3D idle clean */
index ff36532734b7d32fe32268bcf082dd3d099a035c..e09d2818f949f55615c8e33723f14d73bdb69660 100644 (file)
@@ -503,9 +503,9 @@ int r600_blit_init(struct radeon_device *rdev)
        rdev->r600_blit.primitives.set_default_state = set_default_state;
 
        rdev->r600_blit.ring_size_common = 40; /* shaders + def state */
-       rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */
        rdev->r600_blit.ring_size_common += 5; /* done copy */
-       rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */
 
        rdev->r600_blit.ring_size_per_loop = 76;
        /* set_render_target emits 2 extra dwords on rv6xx */