svga: add context pointer to the invalidate surface interface
[mesa.git] / src / gallium / winsys / svga / drm / vmw_context.c
index 4dc32366d61baee79533b820384e79414f573cc4..c306d988e0ce6a336ec5020d46662afc23a7d927 100644 (file)
@@ -179,11 +179,36 @@ vmw_swc_flush(struct svga_winsys_context *swc,
               struct pipe_fence_handle **pfence)
 {
    struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+   struct vmw_winsys_screen *vws = vswc->vws;
    struct pipe_fence_handle *fence = NULL;
    unsigned i;
    enum pipe_error ret;
 
+   /*
+    * If we hit a retry, lock the mutex and retry immediately.
+    * If we then still hit a retry, sleep until another thread
+    * wakes us up after it has released its buffers from the
+    * validate list.
+    *
+    * If we hit another error condition, we still need to broadcast since
+    * pb_validate_validate releases validated buffers in its error path.
+    */
+
    ret = pb_validate_validate(vswc->validate);
+   if (ret != PIPE_OK) {
+      mtx_lock(&vws->cs_mutex);
+      while (ret == PIPE_ERROR_RETRY) {
+         ret = pb_validate_validate(vswc->validate);
+         if (ret == PIPE_ERROR_RETRY) {
+            cnd_wait(&vws->cs_cond, &vws->cs_mutex);
+         }
+      }
+      if (ret != PIPE_OK) {
+         cnd_broadcast(&vws->cs_cond);
+      }
+      mtx_unlock(&vws->cs_mutex);
+   }
+
    assert(ret == PIPE_OK);
    if(ret == PIPE_OK) {
    
@@ -210,7 +235,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
       }
 
       if (vswc->command.used || pfence != NULL)
-         vmw_ioctl_command(vswc->vws,
+         vmw_ioctl_command(vws,
                           vswc->base.cid,
                           0,
                            vswc->command.buffer,
@@ -218,6 +243,9 @@ vmw_swc_flush(struct svga_winsys_context *swc,
                            &fence);
 
       pb_validate_fence(vswc->validate, fence);
+      mtx_lock(&vws->cs_mutex);
+      cnd_broadcast(&vws->cs_cond);
+      mtx_unlock(&vws->cs_mutex);
    }
 
    vswc->command.used = 0;
@@ -251,7 +279,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
    vswc->must_flush = FALSE;
    debug_flush_flush(vswc->fctx);
 #endif
-   swc->hints &= ~SVGA_HINT_FLAG_DRAW_EMITTED;
+   swc->hints &= ~SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    vswc->preemptive_flush = FALSE;
    vswc->seen_surfaces = 0;
    vswc->seen_regions = 0;
@@ -315,6 +343,13 @@ vmw_swc_reserve(struct svga_winsys_context *swc,
    return vswc->command.buffer + vswc->command.used;
 }
 
+static unsigned
+vmw_swc_get_command_buffer_size(struct svga_winsys_context *swc)
+{
+   const struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+   return vswc->command.used;
+}
+
 static void
 vmw_swc_context_relocation(struct svga_winsys_context *swc,
                           uint32 *cid)
@@ -373,7 +408,7 @@ vmw_swc_region_relocation(struct svga_winsys_context *swc,
 
    if (vmw_swc_add_validate_buffer(vswc, reloc->buffer, flags)) {
       vswc->seen_regions += reloc->buffer->size;
-      if ((swc->hints & SVGA_HINT_FLAG_DRAW_EMITTED) &&
+      if ((swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) &&
           vswc->seen_regions >= VMW_GMR_POOL_SIZE/5)
          vswc->preemptive_flush = TRUE;
    }
@@ -416,7 +451,7 @@ vmw_swc_mob_relocation(struct svga_winsys_context *swc,
    if (vmw_swc_add_validate_buffer(vswc, pb_buffer, flags)) {
       vswc->seen_mobs += pb_buffer->size;
 
-      if ((swc->hints & SVGA_HINT_FLAG_DRAW_EMITTED) &&
+      if ((swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) &&
           vswc->seen_mobs >=
             vswc->vws->ioctl.max_mob_memory / VMW_MAX_MOB_MEM_FACTOR)
          vswc->preemptive_flush = TRUE;
@@ -479,7 +514,7 @@ vmw_swc_surface_only_relocation(struct svga_winsys_context *swc,
       ++vswc->surface.staged;
 
       vswc->seen_surfaces += vsurf->size;
-      if ((swc->hints & SVGA_HINT_FLAG_DRAW_EMITTED) &&
+      if ((swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) &&
           vswc->seen_surfaces >=
             vswc->vws->ioctl.max_surface_memory / VMW_MAX_SURF_MEM_FACTOR)
          vswc->preemptive_flush = TRUE;
@@ -521,12 +556,12 @@ vmw_swc_surface_relocation(struct svga_winsys_context *swc,
        * Make sure backup buffer ends up fenced.
        */
 
-      pipe_mutex_lock(vsurf->mutex);
+      mtx_lock(&vsurf->mutex);
       assert(vsurf->buf != NULL);
       
       vmw_swc_mob_relocation(swc, mobid, NULL, (struct svga_winsys_buffer *)
                              vsurf->buf, 0, flags);
-      pipe_mutex_unlock(vsurf->mutex);
+      mtx_unlock(&vsurf->mutex);
    }
 }
 
@@ -761,6 +796,7 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
 
    vswc->base.destroy = vmw_swc_destroy;
    vswc->base.reserve = vmw_swc_reserve;
+   vswc->base.get_command_buffer_size = vmw_swc_get_command_buffer_size;
    vswc->base.surface_relocation = vmw_swc_surface_relocation;
    vswc->base.region_relocation = vmw_swc_region_relocation;
    vswc->base.mob_relocation = vmw_swc_mob_relocation;
@@ -772,11 +808,12 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
    vswc->base.flush = vmw_swc_flush;
    vswc->base.surface_map = vmw_svga_winsys_surface_map;
    vswc->base.surface_unmap = vmw_svga_winsys_surface_unmap;
+   vswc->base.surface_invalidate = vmw_svga_winsys_surface_invalidate;
 
-  vswc->base.shader_create = vmw_svga_winsys_vgpu10_shader_create;
-  vswc->base.shader_destroy = vmw_svga_winsys_vgpu10_shader_destroy;
+   vswc->base.shader_create = vmw_svga_winsys_vgpu10_shader_create;
+   vswc->base.shader_destroy = vmw_svga_winsys_vgpu10_shader_destroy;
 
-  vswc->base.resource_rebind = vmw_svga_winsys_resource_rebind;
+   vswc->base.resource_rebind = vmw_svga_winsys_resource_rebind;
 
    if (sws->have_vgpu10)
       vswc->base.cid = vmw_ioctl_extended_context_create(vws, sws->have_vgpu10);