Path: blob/21.2-virgl/src/gallium/drivers/swr/swr_fence.cpp
4570 views
/****************************************************************************1* Copyright (C) 2015 Intel Corporation. All Rights Reserved.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21***************************************************************************/2223#include "pipe/p_screen.h"24#include "util/u_memory.h"25#include "util/os_time.h"2627#include "swr_context.h"28#include "swr_screen.h"29#include "swr_fence.h"3031#ifdef __APPLE__32#include <sched.h>33#endif3435#if defined(PIPE_CC_MSVC) // portable thread yield36#define sched_yield SwitchToThread37#endif3839/*40* Fence callback, called by back-end thread on completion of all rendering up41* to SwrSync call.42*/43static void44swr_fence_cb(uint64_t userData, uint64_t userData2, uint64_t userData3)45{46struct swr_fence *fence = (struct swr_fence *)userData;4748/* Complete all work attached to the fence */49swr_fence_do_work(fence);5051/* Correct value is in SwrSync data, and not the fence write field. */52/* Contexts may not finish in order, but fence value always increases */53if (fence->read < userData2)54fence->read = userData2;55}5657/*58* Submit an existing fence.59*/60void61swr_fence_submit(struct swr_context *ctx, struct pipe_fence_handle *fh)62{63struct swr_fence *fence = swr_fence(fh);6465fence->write++;66fence->pending = TRUE;67ctx->api.pfnSwrSync(ctx->swrContext, swr_fence_cb, (uint64_t)fence, fence->write, 0);68}6970/*71* Create a new fence object.72*/73struct pipe_fence_handle *74swr_fence_create()75{76static int fence_id = 0;77struct swr_fence *fence = CALLOC_STRUCT(swr_fence);78if (!fence)79return NULL;8081pipe_reference_init(&fence->reference, 1);82fence->id = fence_id++;83fence->work.tail = &fence->work.head;8485return (struct pipe_fence_handle *)fence;86}8788/** Destroy a fence. Called when refcount hits zero. */89static void90swr_fence_destroy(struct swr_fence *fence)91{92/* Complete any work left if fence was not submitted */93swr_fence_do_work(fence);94FREE(fence);95}9697/**98* Set ptr = fence, with reference counting99*/100void101swr_fence_reference(struct pipe_screen *screen,102struct pipe_fence_handle **ptr,103struct pipe_fence_handle *f)104{105struct swr_fence *fence = swr_fence(f);106struct swr_fence *old;107108if (likely(ptr)) {109old = swr_fence(*ptr);110*ptr = f;111} else {112old = NULL;113}114115if (pipe_reference(&old->reference, &fence->reference)) {116swr_fence_finish(screen, NULL, (struct pipe_fence_handle *) old, 0);117swr_fence_destroy(old);118}119}120121122/*123* Wait for the fence to finish.124*/125bool126swr_fence_finish(struct pipe_screen *screen,127struct pipe_context *ctx,128struct pipe_fence_handle *fence_handle,129uint64_t timeout)130{131while (!swr_is_fence_done(fence_handle))132sched_yield();133134swr_fence(fence_handle)->pending = FALSE;135136return TRUE;137}138139140uint64_t141swr_get_timestamp(struct pipe_screen *screen)142{143return os_time_get_nano();144}145146147void148swr_fence_init(struct pipe_screen *p_screen)149{150p_screen->fence_reference = swr_fence_reference;151p_screen->fence_finish = swr_fence_finish;152p_screen->get_timestamp = swr_get_timestamp;153154/* Create persistant StoreTiles "flush" fence, used to signal completion155* of flushing tile state back to resource texture, via StoreTiles. */156struct swr_screen *screen = swr_screen(p_screen);157screen->flush_fence = swr_fence_create();158}159160161