Path: blob/21.2-virgl/src/gallium/drivers/swr/swr_fence_work.cpp
4570 views
/****************************************************************************1* Copyright (C) 2016 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 "swr_context.h"24#include "swr_fence.h"2526#include "util/u_inlines.h"27#include "util/u_memory.h"2829/*30* Called by swr_fence_cb to complete the work queue31*/32void33swr_fence_do_work(struct swr_fence *fence)34{35struct swr_fence_work *work, *tmp;3637if (fence->work.head.next) {38work = fence->work.head.next;39/* Immediately clear the head so any new work gets added to a new work40* queue */41p_atomic_set(&fence->work.head.next, 0);42p_atomic_set(&fence->work.tail, &fence->work.head);43p_atomic_set(&fence->work.count, 0);4445do {46tmp = work->next;47work->callback(work);48FREE(work);49work = tmp;50} while(work);51}52}535455/*56* Called by one of the specialized work routines below57*/58static inline void59swr_add_fence_work(struct pipe_fence_handle *fh,60struct swr_fence_work *work)61{62/* If no fence, just do the work now */63if (!fh) {64work->callback(work);65FREE(work);66return;67}6869struct swr_fence *fence = swr_fence(fh);70p_atomic_set(&fence->work.tail->next, work);71p_atomic_set(&fence->work.tail, work);72p_atomic_inc(&fence->work.count);73}747576/*77* Generic free/free_aligned, and delete vs/fs78*/79template<bool aligned_free>80static void81swr_free_cb(struct swr_fence_work *work)82{83if (aligned_free)84AlignedFree(work->free.data);85else86FREE(work->free.data);87}8889static void90swr_delete_vs_cb(struct swr_fence_work *work)91{92delete work->free.swr_vs;93}9495static void96swr_delete_fs_cb(struct swr_fence_work *work)97{98delete work->free.swr_fs;99}100101static void102swr_delete_gs_cb(struct swr_fence_work *work)103{104delete work->free.swr_gs;105}106107static void108swr_delete_tcs_cb(struct swr_fence_work *work)109{110delete work->free.swr_tcs;111}112113static void114swr_delete_tes_cb(struct swr_fence_work *work)115{116delete work->free.swr_tes;117}118119120bool121swr_fence_work_free(struct pipe_fence_handle *fence, void *data,122bool aligned_free)123{124struct swr_fence_work *work = CALLOC_STRUCT(swr_fence_work);125if (!work)126return false;127if (aligned_free)128work->callback = swr_free_cb<true>;129else130work->callback = swr_free_cb<false>;131work->free.data = data;132133swr_add_fence_work(fence, work);134135return true;136}137138bool139swr_fence_work_delete_vs(struct pipe_fence_handle *fence,140struct swr_vertex_shader *swr_vs)141{142struct swr_fence_work *work = CALLOC_STRUCT(swr_fence_work);143if (!work)144return false;145work->callback = swr_delete_vs_cb;146work->free.swr_vs = swr_vs;147148swr_add_fence_work(fence, work);149150return true;151}152153bool154swr_fence_work_delete_fs(struct pipe_fence_handle *fence,155struct swr_fragment_shader *swr_fs)156{157struct swr_fence_work *work = CALLOC_STRUCT(swr_fence_work);158if (!work)159return false;160work->callback = swr_delete_fs_cb;161work->free.swr_fs = swr_fs;162163swr_add_fence_work(fence, work);164165return true;166}167168bool169swr_fence_work_delete_gs(struct pipe_fence_handle *fence,170struct swr_geometry_shader *swr_gs)171{172struct swr_fence_work *work = CALLOC_STRUCT(swr_fence_work);173if (!work)174return false;175work->callback = swr_delete_gs_cb;176work->free.swr_gs = swr_gs;177178swr_add_fence_work(fence, work);179180return true;181}182183bool184swr_fence_work_delete_tcs(struct pipe_fence_handle *fence,185struct swr_tess_control_shader *swr_tcs)186{187struct swr_fence_work *work = CALLOC_STRUCT(swr_fence_work);188if (!work)189return false;190work->callback = swr_delete_tcs_cb;191work->free.swr_tcs = swr_tcs;192193swr_add_fence_work(fence, work);194195return true;196}197198199bool200swr_fence_work_delete_tes(struct pipe_fence_handle *fence,201struct swr_tess_evaluation_shader *swr_tes)202{203struct swr_fence_work *work = CALLOC_STRUCT(swr_fence_work);204if (!work)205return false;206work->callback = swr_delete_tes_cb;207work->free.swr_tes = swr_tes;208209swr_add_fence_work(fence, work);210211return true;212}213214