nouveau: Fix compiler warning regression
[mesa.git] / src / gallium / drivers / nouveau / nouveau_fence.c
index 26e4775b12df829485093ec6d60334712b31a7e8..c6867104adb4544084ab7bbd30d942b738dfefdf 100644 (file)
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "util/u_double_list.h"
 
 #include "nouveau_screen.h"
+#include "nouveau_winsys.h"
 #include "nouveau_fence.h"
 
-#include "nouveau/nouveau_pushbuf.h"
-
 #ifdef PIPE_OS_UNIX
 #include <sched.h>
 #endif
@@ -86,12 +85,10 @@ nouveau_fence_emit(struct nouveau_fence *fence)
 {
    struct nouveau_screen *screen = fence->screen;
 
-   fence->sequence = ++screen->fence.sequence;
-
    assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE);
 
    /* set this now, so that if fence.emit triggers a flush we don't recurse */
-   fence->state = NOUVEAU_FENCE_STATE_EMITTED;
+   fence->state = NOUVEAU_FENCE_STATE_EMITTING;
 
    ++fence->ref;
 
@@ -102,7 +99,10 @@ nouveau_fence_emit(struct nouveau_fence *fence)
 
    screen->fence.tail = fence;
 
-   screen->fence.emit(&screen->base, fence->sequence);
+   screen->fence.emit(&screen->base, &fence->sequence);
+
+   assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING);
+   fence->state = NOUVEAU_FENCE_STATE_EMITTED;
 }
 
 void
@@ -162,7 +162,8 @@ nouveau_fence_update(struct nouveau_screen *screen, boolean flushed)
 
    if (flushed) {
       for (fence = next; fence; fence = fence->next)
-         fence->state = NOUVEAU_FENCE_STATE_FLUSHED;
+         if (fence->state == NOUVEAU_FENCE_STATE_EMITTED)
+            fence->state = NOUVEAU_FENCE_STATE_FLUSHED;
    }
 }
 
@@ -185,20 +186,26 @@ nouveau_fence_wait(struct nouveau_fence *fence)
    struct nouveau_screen *screen = fence->screen;
    uint32_t spins = 0;
 
-   if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) {
+   /* wtf, someone is waiting on a fence in flush_notify handler? */
+   assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
+
+   if (fence->state < NOUVEAU_FENCE_STATE_EMITTED)
       nouveau_fence_emit(fence);
 
-      if (fence == screen->fence.current)
-         nouveau_fence_new(screen, &screen->fence.current, FALSE);
-   }
    if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
-      FIRE_RING(screen->channel);
+      if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
+         return FALSE;
+
+   if (fence == screen->fence.current)
+      nouveau_fence_next(screen);
 
    do {
       nouveau_fence_update(screen, FALSE);
 
       if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
          return TRUE;
+      if (!spins)
+         NOUVEAU_DRV_STAT(screen, any_non_kernel_fence_sync_count, 1);
       spins++;
 #ifdef PIPE_OS_UNIX
       if (!(spins % 8)) /* donate a few cycles */
@@ -216,7 +223,7 @@ nouveau_fence_wait(struct nouveau_fence *fence)
 void
 nouveau_fence_next(struct nouveau_screen *screen)
 {
-   if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTED)
+   if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTING)
       nouveau_fence_emit(screen->fence.current);
 
    nouveau_fence_ref(NULL, &screen->fence.current);