gallium: simplify throttle implementation
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>
This commit is contained in:
parent
ea92273cea
commit
a65e29ccb2
|
@ -2057,8 +2057,8 @@ dri2_init_screen(__DRIscreen * sPriv)
|
||||||
if (!pscreen)
|
if (!pscreen)
|
||||||
goto release_pipe;
|
goto release_pipe;
|
||||||
|
|
||||||
screen->default_throttle_frames =
|
screen->throttle =
|
||||||
pscreen->get_param(pscreen, PIPE_CAP_MAX_FRAMES_IN_FLIGHT);
|
pscreen->get_param(pscreen, PIPE_CAP_MAX_FRAMES_IN_FLIGHT) > 0;
|
||||||
|
|
||||||
if (pscreen->resource_create_with_modifiers)
|
if (pscreen->resource_create_with_modifiers)
|
||||||
dri2ImageExtension.createImageWithModifiers =
|
dri2ImageExtension.createImageWithModifiers =
|
||||||
|
|
|
@ -40,9 +40,6 @@
|
||||||
|
|
||||||
static uint32_t drifb_ID = 0;
|
static uint32_t drifb_ID = 0;
|
||||||
|
|
||||||
static void
|
|
||||||
swap_fences_unref(struct dri_drawable *draw);
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
dri_st_framebuffer_validate(struct st_context_iface *stctx,
|
dri_st_framebuffer_validate(struct st_context_iface *stctx,
|
||||||
struct st_framebuffer_iface *stfbi,
|
struct st_framebuffer_iface *stfbi,
|
||||||
|
@ -167,9 +164,6 @@ dri_create_buffer(__DRIscreen * sPriv,
|
||||||
drawable->screen = screen;
|
drawable->screen = screen;
|
||||||
drawable->sPriv = sPriv;
|
drawable->sPriv = sPriv;
|
||||||
drawable->dPriv = dPriv;
|
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;
|
dPriv->driverPrivate = (void *)drawable;
|
||||||
p_atomic_set(&drawable->base.stamp, 1);
|
p_atomic_set(&drawable->base.stamp, 1);
|
||||||
|
@ -197,7 +191,8 @@ dri_destroy_buffer(__DRIdrawable * dPriv)
|
||||||
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
|
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
|
||||||
pipe_resource_reference(&drawable->msaa_textures[i], NULL);
|
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 */
|
/* Notify the st manager that this drawable is no longer valid */
|
||||||
stapi->destroy_drawable(stapi, &drawable->base);
|
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
|
void
|
||||||
dri_pipe_blit(struct pipe_context *pipe,
|
dri_pipe_blit(struct pipe_context *pipe,
|
||||||
struct pipe_resource *dst,
|
struct pipe_resource *dst,
|
||||||
|
@ -552,35 +478,20 @@ dri_flush(__DRIcontext *cPriv,
|
||||||
flush_flags |= ST_FLUSH_END_OF_FRAME;
|
flush_flags |= ST_FLUSH_END_OF_FRAME;
|
||||||
|
|
||||||
/* Flush the context and throttle if needed. */
|
/* Flush the context and throttle if needed. */
|
||||||
if (dri_screen(ctx->sPriv)->default_throttle_frames &&
|
if (dri_screen(ctx->sPriv)->throttle &&
|
||||||
drawable &&
|
drawable &&
|
||||||
(reason == __DRI2_THROTTLE_SWAPBUFFER ||
|
(reason == __DRI2_THROTTLE_SWAPBUFFER ||
|
||||||
reason == __DRI2_THROTTLE_FLUSHFRONT)) {
|
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_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);
|
st->flush(st, flush_flags, &new_fence);
|
||||||
|
|
||||||
oldest_fence = swap_fences_pop_front(drawable);
|
/* throttle on the previous fence */
|
||||||
if (oldest_fence) {
|
if (drawable->throttle_fence)
|
||||||
screen->fence_finish(screen, NULL, oldest_fence, PIPE_TIMEOUT_INFINITE);
|
screen->fence_finish(screen, NULL, drawable->throttle_fence, PIPE_TIMEOUT_INFINITE);
|
||||||
screen->fence_reference(screen, &oldest_fence, NULL);
|
screen->fence_reference(screen, &drawable->throttle_fence, new_fence);
|
||||||
}
|
|
||||||
|
|
||||||
if (new_fence) {
|
|
||||||
swap_fences_push_back(drawable, new_fence);
|
|
||||||
screen->fence_reference(screen, &new_fence, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) {
|
else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) {
|
||||||
st->flush(st, flush_flags, NULL);
|
st->flush(st, flush_flags, NULL);
|
||||||
|
|
|
@ -36,10 +36,6 @@ struct pipe_surface;
|
||||||
struct st_framebuffer;
|
struct st_framebuffer;
|
||||||
struct dri_context;
|
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 dri_drawable
|
||||||
{
|
{
|
||||||
struct st_framebuffer_iface base;
|
struct st_framebuffer_iface base;
|
||||||
|
@ -60,11 +56,7 @@ struct dri_drawable
|
||||||
struct pipe_resource *msaa_textures[ST_ATTACHMENT_COUNT];
|
struct pipe_resource *msaa_textures[ST_ATTACHMENT_COUNT];
|
||||||
unsigned int texture_mask, texture_stamp;
|
unsigned int texture_mask, texture_stamp;
|
||||||
|
|
||||||
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
|
struct pipe_fence_handle *throttle_fence;
|
||||||
unsigned int cur_fences;
|
|
||||||
unsigned int head;
|
|
||||||
unsigned int tail;
|
|
||||||
unsigned int desired_fences;
|
|
||||||
bool flushing; /* prevents recursion in dri_flush */
|
bool flushing; /* prevents recursion in dri_flush */
|
||||||
|
|
||||||
/* used only by DRISW */
|
/* used only by DRISW */
|
||||||
|
|
|
@ -57,7 +57,7 @@ struct dri_screen
|
||||||
|
|
||||||
/* dri */
|
/* dri */
|
||||||
__DRIscreen *sPriv;
|
__DRIscreen *sPriv;
|
||||||
unsigned default_throttle_frames;
|
boolean throttle;
|
||||||
|
|
||||||
struct st_config_options options;
|
struct st_config_options options;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue