r300g: fix revoking hyperz access
authorMarek Olšák <maraeo@gmail.com>
Sat, 1 Dec 2012 20:18:59 +0000 (21:18 +0100)
committerMarek Olšák <maraeo@gmail.com>
Sat, 1 Dec 2012 20:43:17 +0000 (21:43 +0100)
The bug was uncovered by 67c8e96f5ace67f9c17556934ee9532877d3a00.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57763

src/gallium/drivers/r300/r300_flush.c

index 2383ba1bb4a35b0096b6a8c4a3c6042b3615c410..732529a317e79b73150e89db60a608f30a59793a 100644 (file)
@@ -105,30 +105,32 @@ void r300_flush(struct pipe_context *pipe,
     }
 
     /* Update Hyper-Z status. */
-    if (r300->num_z_clears) {
-        r300->hyperz_time_of_last_flush = os_time_get();
-    } else if (r300->hyperz_time_of_last_flush > 2000000) {
-        /* 2 seconds without a Z clear pretty much means a dead context
-         * for HyperZ. */
-
-        r300->hiz_in_use = FALSE;
-
-        /* Decompress Z buffer. */
-        if (r300->zmask_in_use) {
-            if (r300->locked_zbuffer) {
-                r300_decompress_zmask_locked(r300);
-            } else {
-                r300_decompress_zmask(r300);
+    if (r300->hyperz_enabled) {
+        /* If there was a Z clear, keep Hyper-Z access. */
+        if (r300->num_z_clears) {
+            r300->hyperz_time_of_last_flush = os_time_get();
+            r300->num_z_clears = 0;
+        } else if (r300->hyperz_time_of_last_flush - os_time_get() > 2000000) {
+            /* If there hasn't been a Z clear for 2 seconds, revoke Hyper-Z access. */
+            r300->hiz_in_use = FALSE;
+
+            /* Decompress the Z buffer. */
+            if (r300->zmask_in_use) {
+                if (r300->locked_zbuffer) {
+                    r300_decompress_zmask_locked(r300);
+                } else {
+                    r300_decompress_zmask(r300);
+                }
+
+                r300_flush_and_cleanup(r300, flags);
             }
 
-            r300_flush_and_cleanup(r300, flags);
+            /* Revoke Hyper-Z access, so that some other process can take it. */
+            r300->rws->cs_request_feature(r300->cs, RADEON_FID_R300_HYPERZ_ACCESS,
+                                          FALSE);
+            r300->hyperz_enabled = FALSE;
         }
-
-        /* Release HyperZ. */
-        r300->rws->cs_request_feature(r300->cs, RADEON_FID_R300_HYPERZ_ACCESS,
-                                      FALSE);
     }
-    r300->num_z_clears = 0;
 }
 
 static void r300_flush_wrapped(struct pipe_context *pipe,