1 /************************************************************************** 2 * 3 * Copyright 2011 Marek Olk <maraeo (at) gmail.com> 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* 29 * Authors: 30 * Marek Olk <maraeo (at) gmail.com> 31 */ 32 33 #include "main/glheader.h" 34 #include "main/macros.h" 35 #include "pipe/p_context.h" 36 #include "pipe/p_screen.h" 37 #include "st_context.h" 38 #include "st_cb_syncobj.h" 39 40 struct st_sync_object { 41 struct gl_sync_object b; 42 43 struct pipe_fence_handle *fence; 44 }; 45 46 47 static struct gl_sync_object * st_new_sync_object(struct gl_context *ctx, 48 GLenum type) 49 { 50 if (type == GL_SYNC_FENCE) 51 return (struct gl_sync_object*)CALLOC_STRUCT(st_sync_object); 52 else 53 return NULL; 54 } 55 56 static void st_delete_sync_object(struct gl_context *ctx, 57 struct gl_sync_object *obj) 58 { 59 struct pipe_screen *screen = st_context(ctx)->pipe->screen; 60 struct st_sync_object *so = (struct st_sync_object*)obj; 61 62 screen->fence_reference(screen, &so->fence, NULL); 63 FREE(so); 64 } 65 66 static void st_fence_sync(struct gl_context *ctx, struct gl_sync_object *obj, 67 GLenum condition, GLbitfield flags) 68 { 69 struct pipe_context *pipe = st_context(ctx)->pipe; 70 struct st_sync_object *so = (struct st_sync_object*)obj; 71 72 assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0); 73 assert(so->fence == NULL); 74 75 pipe->flush(pipe, &so->fence); 76 } 77 78 static void st_check_sync(struct gl_context *ctx, struct gl_sync_object *obj) 79 { 80 struct pipe_screen *screen = st_context(ctx)->pipe->screen; 81 struct st_sync_object *so = (struct st_sync_object*)obj; 82 83 if (so->fence && screen->fence_signalled(screen, so->fence)) { 84 screen->fence_reference(screen, &so->fence, NULL); 85 so->b.StatusFlag = GL_TRUE; 86 } 87 } 88 89 static void st_client_wait_sync(struct gl_context *ctx, 90 struct gl_sync_object *obj, 91 GLbitfield flags, GLuint64 timeout) 92 { 93 struct pipe_screen *screen = st_context(ctx)->pipe->screen; 94 struct st_sync_object *so = (struct st_sync_object*)obj; 95 96 /* We don't care about GL_SYNC_FLUSH_COMMANDS_BIT, because flush is 97 * already called when creating a fence. */ 98 99 if (so->fence && 100 screen->fence_finish(screen, so->fence, timeout)) { 101 screen->fence_reference(screen, &so->fence, NULL); 102 so->b.StatusFlag = GL_TRUE; 103 } 104 } 105 106 static void st_server_wait_sync(struct gl_context *ctx, 107 struct gl_sync_object *obj, 108 GLbitfield flags, GLuint64 timeout) 109 { 110 /* NO-OP. 111 * Neither Gallium nor DRM interfaces support blocking on the GPU. */ 112 } 113 114 void st_init_syncobj_functions(struct dd_function_table *functions) 115 { 116 functions->NewSyncObject = st_new_sync_object; 117 functions->FenceSync = st_fence_sync; 118 functions->DeleteSyncObject = st_delete_sync_object; 119 functions->CheckSync = st_check_sync; 120 functions->ClientWaitSync = st_client_wait_sync; 121 functions->ServerWaitSync = st_server_wait_sync; 122 } 123