gallium: simplify throttle implementation
authorJames Xiong <james.xiong@intel.com>
Mon, 14 Oct 2019 08:05:40 +0000 (10:05 +0200)
committerMichel Dänzer <mdaenzer@redhat.com>
Mon, 14 Oct 2019 08:05:40 +0000 (10:05 +0200)
All gallium drivers currently set MAX_FRAME_IN_FLIGHT to either 1
or 0, which means that the drivers either throttle on the previous
render or don't throttle, the current implementation is more
complicated than necessary and can be simplified.

Signed-off-by: James Xiong <james.xiong@intel.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/state_trackers/dri/dri2.c
src/gallium/state_trackers/dri/dri_drawable.c
src/gallium/state_trackers/dri/dri_drawable.h
src/gallium/state_trackers/dri/dri_screen.h

index 574ddaea5c78c95e38099e8e80b6c433de642d03..6acfc6aa977920e15b799dc4c4a16271ee30faa7 100644 (file)
@@ -2057,8 +2057,8 @@ dri2_init_screen(__DRIscreen * sPriv)
    if (!pscreen)
        goto release_pipe;
 
-   screen->default_throttle_frames =
-      pscreen->get_param(pscreen, PIPE_CAP_MAX_FRAMES_IN_FLIGHT);
+   screen->throttle =
+      pscreen->get_param(pscreen, PIPE_CAP_MAX_FRAMES_IN_FLIGHT) > 0;
 
    if (pscreen->resource_create_with_modifiers)
       dri2ImageExtension.createImageWithModifiers =
index 8f5055407cd02d0c34f1dc38a8b540dab8c212cd..6335127952c19955c68671a70925256147a4e4af 100644 (file)
@@ -40,9 +40,6 @@
 
 static uint32_t drifb_ID = 0;
 
-static void
-swap_fences_unref(struct dri_drawable *draw);
-
 static bool
 dri_st_framebuffer_validate(struct st_context_iface *stctx,
                             struct st_framebuffer_iface *stfbi,
@@ -167,9 +164,6 @@ dri_create_buffer(__DRIscreen * sPriv,
    drawable->screen = screen;
    drawable->sPriv = sPriv;
    drawable->dPriv = dPriv;
-   drawable->desired_fences = screen->default_throttle_frames;
-   if (drawable->desired_fences > DRI_SWAP_FENCES_MAX)
-      drawable->desired_fences = DRI_SWAP_FENCES_MAX;
 
    dPriv->driverPrivate = (void *)drawable;
    p_atomic_set(&drawable->base.stamp, 1);
@@ -197,7 +191,8 @@ dri_destroy_buffer(__DRIdrawable * dPriv)
    for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
       pipe_resource_reference(&drawable->msaa_textures[i], NULL);
 
-   swap_fences_unref(drawable);
+   screen->base.screen->fence_reference(screen->base.screen,
+         &drawable->throttle_fence, NULL);
 
    /* Notify the st manager that this drawable is no longer valid */
    stapi->destroy_drawable(stapi, &drawable->base);
@@ -336,75 +331,6 @@ dri_drawable_get_format(struct dri_drawable *drawable,
    }
 }
 
-
-/**
- * swap_fences_pop_front - pull a fence from the throttle queue
- *
- * If the throttle queue is filled to the desired number of fences,
- * pull fences off the queue until the number is less than the desired
- * number of fences, and return the last fence pulled.
- */
-static struct pipe_fence_handle *
-swap_fences_pop_front(struct dri_drawable *draw)
-{
-   struct pipe_screen *screen = draw->screen->base.screen;
-   struct pipe_fence_handle *fence = NULL;
-
-   if (draw->desired_fences == 0)
-      return NULL;
-
-   if (draw->cur_fences >= draw->desired_fences) {
-      screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
-      screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
-      draw->tail &= DRI_SWAP_FENCES_MASK;
-      --draw->cur_fences;
-   }
-   return fence;
-}
-
-
-/**
- * swap_fences_push_back - push a fence onto the throttle queue
- *
- * push a fence onto the throttle queue and pull fences of the queue
- * so that the desired number of fences are on the queue.
- */
-static void
-swap_fences_push_back(struct dri_drawable *draw,
-                     struct pipe_fence_handle *fence)
-{
-   struct pipe_screen *screen = draw->screen->base.screen;
-
-   if (!fence || draw->desired_fences == 0)
-      return;
-
-   while(draw->cur_fences == draw->desired_fences)
-      swap_fences_pop_front(draw);
-
-   draw->cur_fences++;
-   screen->fence_reference(screen, &draw->swap_fences[draw->head++],
-                          fence);
-   draw->head &= DRI_SWAP_FENCES_MASK;
-}
-
-
-/**
- * swap_fences_unref - empty the throttle queue
- *
- * pulls fences of the throttle queue until it is empty.
- */
-static void
-swap_fences_unref(struct dri_drawable *draw)
-{
-   struct pipe_screen *screen = draw->screen->base.screen;
-
-   while(draw->cur_fences) {
-      screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
-      draw->tail &= DRI_SWAP_FENCES_MASK;
-      --draw->cur_fences;
-   }
-}
-
 void
 dri_pipe_blit(struct pipe_context *pipe,
               struct pipe_resource *dst,
@@ -552,35 +478,20 @@ dri_flush(__DRIcontext *cPriv,
       flush_flags |= ST_FLUSH_END_OF_FRAME;
 
    /* Flush the context and throttle if needed. */
-   if (dri_screen(ctx->sPriv)->default_throttle_frames &&
+   if (dri_screen(ctx->sPriv)->throttle &&
        drawable &&
        (reason == __DRI2_THROTTLE_SWAPBUFFER ||
         reason == __DRI2_THROTTLE_FLUSHFRONT)) {
-      /* Throttle.
-       *
-       * This pulls a fence off the throttling queue and waits for it if the
-       * number of fences on the throttling queue has reached the desired
-       * number.
-       *
-       * Then flushes to insert a fence at the current rendering position, and
-       * pushes that fence on the queue. This requires that the st_context_iface
-       * flush method returns a fence even if there are no commands to flush.
-       */
+
       struct pipe_screen *screen = drawable->screen->base.screen;
-      struct pipe_fence_handle *oldest_fence, *new_fence = NULL;
+      struct pipe_fence_handle *new_fence = NULL;
 
       st->flush(st, flush_flags, &new_fence);
 
-      oldest_fence = swap_fences_pop_front(drawable);
-      if (oldest_fence) {
-         screen->fence_finish(screen, NULL, oldest_fence, PIPE_TIMEOUT_INFINITE);
-         screen->fence_reference(screen, &oldest_fence, NULL);
-      }
-
-      if (new_fence) {
-         swap_fences_push_back(drawable, new_fence);
-         screen->fence_reference(screen, &new_fence, NULL);
-      }
+      /* throttle on the previous fence */
+      if (drawable->throttle_fence)
+         screen->fence_finish(screen, NULL, drawable->throttle_fence, PIPE_TIMEOUT_INFINITE);
+      screen->fence_reference(screen, &drawable->throttle_fence, new_fence);
    }
    else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) {
       st->flush(st, flush_flags, NULL);
index 3a142144f445b07609e20c158eaa2fbcdd006546..05c82056697d42ea3b675247f5868cd160b54560 100644 (file)
@@ -36,10 +36,6 @@ struct pipe_surface;
 struct st_framebuffer;
 struct dri_context;
 
-#define DRI_SWAP_FENCES_MAX 4
-#define DRI_SWAP_FENCES_MASK 3
-#define DRI_SWAP_FENCES_DEFAULT 1
-
 struct dri_drawable
 {
    struct st_framebuffer_iface base;
@@ -60,11 +56,7 @@ struct dri_drawable
    struct pipe_resource *msaa_textures[ST_ATTACHMENT_COUNT];
    unsigned int texture_mask, texture_stamp;
 
-   struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
-   unsigned int cur_fences;
-   unsigned int head;
-   unsigned int tail;
-   unsigned int desired_fences;
+   struct pipe_fence_handle *throttle_fence;
    bool flushing; /* prevents recursion in dri_flush */
 
    /* used only by DRISW */
index f16715dee5633d0f54087e046b2b38ab2bc1ca63..4a80d96df9582335fbb6f31d9e24fb6ed35da477 100644 (file)
@@ -57,7 +57,7 @@ struct dri_screen
 
    /* dri */
    __DRIscreen *sPriv;
-   unsigned default_throttle_frames;
+   boolean throttle;
 
    struct st_config_options options;