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