19f464c52Smaya/* 29f464c52Smaya * Copyright (c) 2018-2019 Lima Project 39f464c52Smaya * 49f464c52Smaya * Permission is hereby granted, free of charge, to any person obtaining a 59f464c52Smaya * copy of this software and associated documentation files (the "Software"), 69f464c52Smaya * to deal in the Software without restriction, including without limitation 79f464c52Smaya * the rights to use, copy, modify, merge, publish, distribute, sub license, 89f464c52Smaya * and/or sell copies of the Software, and to permit persons to whom the 99f464c52Smaya * Software is furnished to do so, subject to the following conditions: 109f464c52Smaya * 119f464c52Smaya * The above copyright notice and this permission notice (including the 129f464c52Smaya * next paragraph) shall be included in all copies or substantial portions 139f464c52Smaya * of the Software. 149f464c52Smaya * 159f464c52Smaya * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 169f464c52Smaya * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 179f464c52Smaya * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 189f464c52Smaya * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 199f464c52Smaya * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 209f464c52Smaya * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 219f464c52Smaya * DEALINGS IN THE SOFTWARE. 229f464c52Smaya * 239f464c52Smaya */ 249f464c52Smaya 259f464c52Smaya#include <fcntl.h> 269f464c52Smaya#include <libsync.h> 279f464c52Smaya 287ec681f3Smrg#include "util/os_file.h" 299f464c52Smaya#include <util/u_memory.h> 309f464c52Smaya#include <util/u_inlines.h> 319f464c52Smaya 329f464c52Smaya#include "drm-uapi/lima_drm.h" 339f464c52Smaya 349f464c52Smaya#include "lima_screen.h" 359f464c52Smaya#include "lima_context.h" 369f464c52Smaya#include "lima_fence.h" 377ec681f3Smrg#include "lima_job.h" 389f464c52Smaya 399f464c52Smayastruct pipe_fence_handle { 409f464c52Smaya struct pipe_reference reference; 419f464c52Smaya int fd; 429f464c52Smaya}; 439f464c52Smaya 449f464c52Smayastatic void 459f464c52Smayalima_create_fence_fd(struct pipe_context *pctx, 469f464c52Smaya struct pipe_fence_handle **fence, 479f464c52Smaya int fd, enum pipe_fd_type type) 489f464c52Smaya{ 499f464c52Smaya assert(type == PIPE_FD_TYPE_NATIVE_SYNC); 507ec681f3Smrg *fence = lima_fence_create(os_dupfd_cloexec(fd)); 519f464c52Smaya} 529f464c52Smaya 539f464c52Smayastatic void 549f464c52Smayalima_fence_server_sync(struct pipe_context *pctx, 559f464c52Smaya struct pipe_fence_handle *fence) 569f464c52Smaya{ 579f464c52Smaya struct lima_context *ctx = lima_context(pctx); 589f464c52Smaya 597ec681f3Smrg sync_accumulate("lima", &ctx->in_sync_fd, fence->fd); 609f464c52Smaya} 619f464c52Smaya 629f464c52Smayavoid lima_fence_context_init(struct lima_context *ctx) 639f464c52Smaya{ 649f464c52Smaya ctx->base.create_fence_fd = lima_create_fence_fd; 659f464c52Smaya ctx->base.fence_server_sync = lima_fence_server_sync; 669f464c52Smaya} 679f464c52Smaya 689f464c52Smayastruct pipe_fence_handle * 699f464c52Smayalima_fence_create(int fd) 709f464c52Smaya{ 719f464c52Smaya struct pipe_fence_handle *fence; 729f464c52Smaya 739f464c52Smaya fence = CALLOC_STRUCT(pipe_fence_handle); 749f464c52Smaya if (!fence) 759f464c52Smaya return NULL; 769f464c52Smaya 779f464c52Smaya pipe_reference_init(&fence->reference, 1); 789f464c52Smaya fence->fd = fd; 799f464c52Smaya 809f464c52Smaya return fence; 819f464c52Smaya} 829f464c52Smaya 839f464c52Smayastatic int 849f464c52Smayalima_fence_get_fd(struct pipe_screen *pscreen, 859f464c52Smaya struct pipe_fence_handle *fence) 869f464c52Smaya{ 877ec681f3Smrg return os_dupfd_cloexec(fence->fd); 889f464c52Smaya} 899f464c52Smaya 909f464c52Smayastatic void 919f464c52Smayalima_fence_destroy(struct pipe_fence_handle *fence) 929f464c52Smaya{ 939f464c52Smaya if (fence->fd >= 0) 949f464c52Smaya close(fence->fd); 959f464c52Smaya FREE(fence); 969f464c52Smaya} 979f464c52Smaya 989f464c52Smayastatic void 999f464c52Smayalima_fence_reference(struct pipe_screen *pscreen, 1009f464c52Smaya struct pipe_fence_handle **ptr, 1019f464c52Smaya struct pipe_fence_handle *fence) 1029f464c52Smaya{ 1039f464c52Smaya if (pipe_reference(&(*ptr)->reference, &fence->reference)) 1049f464c52Smaya lima_fence_destroy(*ptr); 1059f464c52Smaya *ptr = fence; 1069f464c52Smaya} 1079f464c52Smaya 1087ec681f3Smrgstatic bool 1099f464c52Smayalima_fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx, 1109f464c52Smaya struct pipe_fence_handle *fence, uint64_t timeout) 1119f464c52Smaya{ 1129f464c52Smaya return !sync_wait(fence->fd, timeout / 1000000); 1139f464c52Smaya} 1149f464c52Smaya 1159f464c52Smayavoid 1169f464c52Smayalima_fence_screen_init(struct lima_screen *screen) 1179f464c52Smaya{ 1189f464c52Smaya screen->base.fence_reference = lima_fence_reference; 1199f464c52Smaya screen->base.fence_finish = lima_fence_finish; 1209f464c52Smaya screen->base.fence_get_fd = lima_fence_get_fd; 1219f464c52Smaya} 122