From a65e29ccb261f3c127c49e73d0da92124234668f Mon Sep 17 00:00:00 2001 From: James Xiong Date: Mon, 14 Oct 2019 10:05:40 +0200 Subject: [PATCH] gallium: simplify throttle implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Michel Dänzer Reviewed-by: Marek Olšák --- src/gallium/state_trackers/dri/dri2.c | 4 +- src/gallium/state_trackers/dri/dri_drawable.c | 107 ++---------------- src/gallium/state_trackers/dri/dri_drawable.h | 10 +- src/gallium/state_trackers/dri/dri_screen.h | 2 +- 4 files changed, 13 insertions(+), 110 deletions(-) diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c index 574ddaea5c7..6acfc6aa977 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -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 = diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 8f5055407cd..6335127952c 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -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); diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index 3a142144f44..05c82056697 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -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 */ diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index f16715dee56..4a80d96df95 100644 --- a/src/gallium/state_trackers/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -57,7 +57,7 @@ struct dri_screen /* dri */ __DRIscreen *sPriv; - unsigned default_throttle_frames; + boolean throttle; struct st_config_options options;