PIPE_FLUSH_END_OF_FRAME: Whether the flush marks the end of frame.
PIPE_FLUSH_DEFERRED: It is not required to flush right away, but it is required
-to return a valid fence. The behavior of fence_finish or any other call isn't
-changed. The only side effect can be that fence_finish will wait a little
-longer. No guidance is given as to how drivers should implement fence_finish
-with deferred flushes. If some drivers can't do deferred flushes safely, they
-should just ignore the flag.
-
+to return a valid fence. If fence_finish is called with the returned fence
+and the context is still unflushed, and the ctx parameter of fence_finish is
+equal to the context where the fence was created, fence_finish will flush
+the context.
``flush_resource``
if (!fence)
return false;
- idle = screen->fence_finish(screen, fence, timeout_ms * 1000000);
+ idle = screen->fence_finish(screen, NULL, fence, timeout_ms * 1000000);
screen->fence_reference(screen, &fence, NULL);
if (!idle)
fprintf(stderr, "dd: GPU hang detected!\n");
static boolean
dd_screen_fence_finish(struct pipe_screen *_screen,
+ struct pipe_context *_ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
struct pipe_screen *screen = dd_screen(_screen)->screen;
+ struct pipe_context *ctx = _ctx ? dd_context(_ctx)->pipe : NULL;
- return screen->fence_finish(screen, fence, timeout);
+ return screen->fence_finish(screen, ctx, fence, timeout);
}
}
boolean fd_screen_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *pfence);
boolean fd_screen_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *pfence,
uint64_t timeout);
struct pipe_fence_handle * fd_fence_create(struct pipe_context *pctx,
static boolean
i915_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
static boolean
ilo_screen_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
struct pipe_fence_handle *fence = NULL;
llvmpipe_flush(pipe, &fence, reason);
if (fence) {
- pipe->screen->fence_finish(pipe->screen, fence, PIPE_TIMEOUT_INFINITE);
+ pipe->screen->fence_finish(pipe->screen, NULL, fence,
+ PIPE_TIMEOUT_INFINITE);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
}
}
*/
static boolean
llvmpipe_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence_handle,
uint64_t timeout)
{
static boolean
nouveau_screen_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *pfence,
uint64_t timeout)
{
}
static boolean r300_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
}
static boolean r600_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
return true;
case PIPE_QUERY_GPU_FINISHED: {
struct pipe_screen *screen = rctx->b.screen;
- result->b = screen->fence_finish(screen, query->fence,
+ result->b = screen->fence_finish(screen, NULL, query->fence,
wait ? PIPE_TIMEOUT_INFINITE : 0);
return result->b;
}
static boolean
rbug_screen_fence_finish(struct pipe_screen *_screen,
+ struct pipe_context *_ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
struct rbug_screen *rb_screen = rbug_screen(_screen);
struct pipe_screen *screen = rb_screen->screen;
+ struct pipe_context *ctx = _ctx ? rbug_context(_ctx)->pipe : NULL;
- return screen->fence_finish(screen,
- fence,
- timeout);
+ return screen->fence_finish(screen, ctx, fence, timeout);
}
boolean
static boolean
softpipe_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
* This is for illustrative purposes only, as softpipe does not
* have fences.
*/
- pipe->screen->fence_finish(pipe->screen, fence,
+ pipe->screen->fence_finish(pipe->screen, NULL, fence,
PIPE_TIMEOUT_INFINITE);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
}
if (SVGA_DEBUG & DEBUG_SYNC) {
if (fence)
- svga->pipe.screen->fence_finish( svga->pipe.screen, fence,
+ svga->pipe.screen->fence_finish( svga->pipe.screen, NULL, fence,
PIPE_TIMEOUT_INFINITE);
}
struct pipe_fence_handle *fence = NULL;
svga_context_flush(svga, &fence);
- screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
+ screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
}
static boolean
svga_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
if (!swr_is_fence_pending(screen->flush_fence))
swr_fence_submit(swr_context(pipe), screen->flush_fence);
- swr_fence_finish(pipe->screen, screen->flush_fence, 0);
+ swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
swr_resource_unused(resource);
}
}
swr_store_dirty_resource(pipe, src, SWR_TILE_RESOLVED);
swr_store_dirty_resource(pipe, dst, SWR_TILE_RESOLVED);
- swr_fence_finish(pipe->screen, screen->flush_fence, 0);
+ swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
swr_resource_unused(src);
swr_resource_unused(dst);
struct pipe_fence_handle *fence = nullptr;
swr_flush(pipe, &fence, 0);
- swr_fence_finish(pipe->screen, fence, 0);
+ swr_fence_finish(pipe->screen, NULL, fence, 0);
swr_fence_reference(pipe->screen, &fence, NULL);
}
*/
boolean
swr_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence_handle,
uint64_t timeout)
{
struct pipe_fence_handle *f);
boolean swr_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence_handle,
uint64_t timeout);
if (pq->fence) {
if (swr_is_fence_pending(pq->fence))
- swr_fence_finish(pipe->screen, pq->fence, 0);
+ swr_fence_finish(pipe->screen, NULL, pq->fence, 0);
swr_fence_reference(pipe->screen, &pq->fence, NULL);
}
if (!wait && !swr_is_fence_done(pq->fence))
return FALSE;
- swr_fence_finish(pipe->screen, pq->fence, 0);
+ swr_fence_finish(pipe->screen, NULL, pq->fence, 0);
swr_fence_reference(pipe->screen, &pq->fence, NULL);
}
if (!swr_is_fence_pending(screen->flush_fence))
swr_fence_submit(swr_context(pipe), screen->flush_fence);
- swr_fence_finish(p_screen, screen->flush_fence, 0);
+ swr_fence_finish(p_screen, NULL, screen->flush_fence, 0);
swr_resource_unused(pt);
}
struct pipe_context *pipe = screen->pipe;
if (pipe) {
- swr_fence_finish(p_screen, screen->flush_fence, 0);
+ swr_fence_finish(p_screen, NULL, screen->flush_fence, 0);
swr_resource_unused(resource);
SwrEndFrame(swr_context(pipe)->swrContext);
}
fprintf(stderr, "SWR destroy screen!\n");
- swr_fence_finish(p_screen, screen->flush_fence, 0);
+ swr_fence_finish(p_screen, NULL, screen->flush_fence, 0);
swr_fence_reference(p_screen, &screen->flush_fence, NULL);
JitDestroyContext(screen->hJitMgr);
/* Ensure that any in-progress attachment change StoreTiles finish */
if (swr_is_fence_pending(screen->flush_fence))
- swr_fence_finish(pipe->screen, screen->flush_fence, 0);
+ swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
/* Finally, update the in-use status of all resources involved in draw */
swr_update_resource_status(pipe, p_draw_info);
static boolean
trace_screen_fence_finish(struct pipe_screen *_screen,
+ struct pipe_context *_ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
+ struct pipe_context *ctx = _ctx ? trace_context(_ctx)->pipe : NULL;
int result;
trace_dump_call_begin("pipe_screen", "fence_finish");
trace_dump_arg(ptr, screen);
+ trace_dump_arg(ptr, ctx);
trace_dump_arg(ptr, fence);
trace_dump_arg(uint, timeout);
- result = screen->fence_finish(screen, fence, timeout);
+ result = screen->fence_finish(screen, ctx, fence, timeout);
trace_dump_ret(bool, result);
static boolean
vc4_fence_finish(struct pipe_screen *pscreen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *pf,
uint64_t timeout_ns)
{
}
static boolean virgl_fence_finish(struct pipe_screen *screen,
+ struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
/**
* Wait for the fence to finish.
+ *
+ * If the fence was created with PIPE_FLUSH_DEFERRED, and the context is
+ * still unflushed, and the ctx parameter of fence_finish is equal to
+ * the context where the fence was created, fence_finish will flush
+ * the context prior to waiting for the fence.
+ *
+ * In all other cases, the ctx parameter has no effect.
+ *
* \param timeout in nanoseconds (may be PIPE_TIMEOUT_INFINITE).
*/
- boolean (*fence_finish)( struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- uint64_t timeout );
+ boolean (*fence_finish)(struct pipe_screen *screen,
+ struct pipe_context *ctx,
+ struct pipe_fence_handle *fence,
+ uint64_t timeout);
/**
* Returns a driver-specific query.
else if (!_fence)
return CL_QUEUED;
- else if (!screen->fence_finish(screen, _fence, 0))
+ else if (!screen->fence_finish(screen, NULL, _fence, 0))
return CL_SUBMITTED;
else
queue()->flush();
if (!_fence ||
- !screen->fence_finish(screen, _fence, PIPE_TIMEOUT_INFINITE))
+ !screen->fence_finish(screen, NULL, _fence, PIPE_TIMEOUT_INFINITE))
throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
}
screen = dri_screen(ctx->sPriv)->base.screen;
pipe->flush_resource(pipe, dst->texture);
ctx->st->flush(ctx->st, 0, &fence);
- (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
+ (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
}
}
/* No need to flush. The context was flushed when the fence was created. */
if (fence->pipe_fence)
- return screen->fence_finish(screen, fence->pipe_fence, timeout);
+ return screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);
else if (fence->cl_event) {
struct pipe_fence_handle *pipe_fence =
driscreen->opencl_dri_event_get_fence(fence->cl_event);
if (pipe_fence)
- return screen->fence_finish(screen, pipe_fence, timeout);
+ return screen->fence_finish(screen, NULL, pipe_fence, timeout);
else
return driscreen->opencl_dri_event_wait(fence->cl_event, timeout);
}
fence = swap_fences_pop_front(drawable);
if (fence) {
- (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
+ (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
}
c->st->flush(c->st, ST_FLUSH_FRONT, &fence);
if (fence) {
- xmdpy->screen->fence_finish(xmdpy->screen, fence,
+ xmdpy->screen->fence_finish(xmdpy->screen, NULL, fence,
PIPE_TIMEOUT_INFINITE);
xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
}
{
struct end_present_struct *work = data;
if (work->fence_to_wait) {
- (void) work->screen->fence_finish(work->screen, work->fence_to_wait, PIPE_TIMEOUT_INFINITE);
+ (void) work->screen->fence_finish(work->screen, NULL, work->fence_to_wait, PIPE_TIMEOUT_INFINITE);
work->screen->fence_reference(work->screen, &(work->fence_to_wait), NULL);
}
ID3DPresent_PresentBuffer(work->present, work->present_handle, work->hDestWindowOverride, NULL, NULL, NULL, 0);
BOOL still_draw = FALSE;
fence = swap_fences_see_front(This);
if (fence) {
- still_draw = !This->screen->fence_finish(This->screen, fence, 0);
+ still_draw = !This->screen->fence_finish(This->screen, NULL, fence, 0);
This->screen->fence_reference(This->screen, &fence, NULL);
}
if (still_draw)
This->tasks[0]=NULL;
fence = swap_fences_pop_front(This);
if (fence) {
- (void) This->screen->fence_finish(This->screen, fence, PIPE_TIMEOUT_INFINITE);
+ (void) This->screen->fence_finish(This->screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
This->screen->fence_reference(This->screen, &fence, NULL);
}
pipe_mutex_lock(pq->device->mutex);
if (surf->fence) {
screen = pq->device->vscreen->pscreen;
- screen->fence_finish(screen, surf->fence, PIPE_TIMEOUT_INFINITE);
+ screen->fence_finish(screen, NULL, surf->fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &surf->fence, NULL);
}
pipe_mutex_unlock(pq->device->mutex);
} else {
pipe_mutex_lock(pq->device->mutex);
screen = pq->device->vscreen->pscreen;
- if (screen->fence_finish(screen, surf->fence, 0)) {
+ if (screen->fence_finish(screen, NULL, surf->fence, 0)) {
screen->fence_reference(screen, &surf->fence, NULL);
*status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE;
pipe_mutex_unlock(pq->device->mutex);
struct pipe_screen *screen = fence->xa->screen;
boolean timed_out;
- timed_out = !screen->fence_finish(screen, fence->pipe_fence, timeout);
+ timed_out = !screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);
if (timed_out)
return -XA_ERR_BUSY;
*status = 0;
if (surface_priv->fence)
- if (!pipe->screen->fence_finish(pipe->screen, surface_priv->fence, 0))
+ if (!pipe->screen->fence_finish(pipe->screen, NULL, surface_priv->fence, 0))
*status |= XVMC_RENDERING;
return Success;
st_flush(st, &fence, 0);
if(fence) {
- st->pipe->screen->fence_finish(st->pipe->screen, fence,
+ st->pipe->screen->fence_finish(st->pipe->screen, NULL, fence,
PIPE_TIMEOUT_INFINITE);
st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL);
}
return;
}
- if (screen->fence_finish(screen, so->fence, 0)) {
+ if (screen->fence_finish(screen, NULL, so->fence, 0)) {
screen->fence_reference(screen, &so->fence, NULL);
so->b.StatusFlag = GL_TRUE;
}
* already called when creating a fence. */
if (so->fence &&
- screen->fence_finish(screen, so->fence, timeout)) {
+ screen->fence_finish(screen, NULL, so->fence, timeout)) {
screen->fence_reference(screen, &so->fence, NULL);
so->b.StatusFlag = GL_TRUE;
}