Home | History | Annotate | Download | only in etnaviv
      1 /*
      2  * Copyright (c) 2012-2015 Etnaviv Project
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sub license,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the
     12  * next paragraph) shall be included in all copies or substantial portions
     13  * of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  *
     23  * Authors:
     24  *    Wladimir J. van der Laan <laanwj (at) gmail.com>
     25  *    Rob Clark <robclark (at) freedesktop.org>
     26  */
     27 
     28 #include <libsync.h>
     29 
     30 #include "etnaviv_fence.h"
     31 #include "etnaviv_context.h"
     32 #include "etnaviv_screen.h"
     33 
     34 #include "util/u_inlines.h"
     35 #include "util/u_memory.h"
     36 
     37 struct pipe_fence_handle {
     38    struct pipe_reference reference;
     39    struct etna_context *ctx;
     40    struct etna_screen *screen;
     41    int fence_fd;
     42    uint32_t timestamp;
     43 };
     44 
     45 static void
     46 etna_fence_destroy(struct pipe_fence_handle *fence)
     47 {
     48    if (fence->fence_fd != -1)
     49       close(fence->fence_fd);
     50    FREE(fence);
     51 }
     52 
     53 static void
     54 etna_screen_fence_reference(struct pipe_screen *pscreen,
     55                             struct pipe_fence_handle **ptr,
     56                             struct pipe_fence_handle *fence)
     57 {
     58    if (pipe_reference(&(*ptr)->reference, &fence->reference))
     59       etna_fence_destroy(*ptr);
     60 
     61    *ptr = fence;
     62 }
     63 
     64 static boolean
     65 etna_screen_fence_finish(struct pipe_screen *pscreen, struct pipe_context *ctx,
     66                          struct pipe_fence_handle *fence, uint64_t timeout)
     67 {
     68    if (fence->fence_fd != -1)
     69 	return !sync_wait(fence->fence_fd, timeout / 1000000);
     70 
     71    if (etna_pipe_wait_ns(fence->screen->pipe, fence->timestamp, timeout))
     72       return false;
     73 
     74    return true;
     75 }
     76 
     77 void
     78 etna_create_fence_fd(struct pipe_context *pctx,
     79                      struct pipe_fence_handle **pfence, int fd)
     80 {
     81    *pfence = etna_fence_create(pctx, dup(fd));
     82 }
     83 
     84 void
     85 etna_fence_server_sync(struct pipe_context *pctx,
     86                        struct pipe_fence_handle *pfence)
     87 {
     88    struct etna_context *ctx = etna_context(pctx);
     89 
     90    sync_accumulate("etnaviv", &ctx->in_fence_fd, pfence->fence_fd);
     91 }
     92 
     93 static int
     94 etna_screen_fence_get_fd(struct pipe_screen *pscreen,
     95                          struct pipe_fence_handle *pfence)
     96 {
     97    return dup(pfence->fence_fd);
     98 }
     99 
    100 struct pipe_fence_handle *
    101 etna_fence_create(struct pipe_context *pctx, int fence_fd)
    102 {
    103    struct pipe_fence_handle *fence;
    104    struct etna_context *ctx = etna_context(pctx);
    105 
    106    fence = CALLOC_STRUCT(pipe_fence_handle);
    107    if (!fence)
    108       return NULL;
    109 
    110    pipe_reference_init(&fence->reference, 1);
    111 
    112    fence->ctx = ctx;
    113    fence->screen = ctx->screen;
    114    fence->timestamp = etna_cmd_stream_timestamp(ctx->stream);
    115    fence->fence_fd = fence_fd;
    116 
    117    return fence;
    118 }
    119 
    120 void
    121 etna_fence_screen_init(struct pipe_screen *pscreen)
    122 {
    123    pscreen->fence_reference = etna_screen_fence_reference;
    124    pscreen->fence_finish = etna_screen_fence_finish;
    125    pscreen->fence_get_fd = etna_screen_fence_get_fd;
    126 }
    127