diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2018-10-23 05:47:28 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2018-10-23 05:47:28 +0000 |
commit | f6666e4c3977a5d74f3da7464672ea48e44dff4b (patch) | |
tree | 21df237f03b2aabc094d514d3d8f0d13c4f00f4e /lib/mesa/src/gallium/state_trackers/dri | |
parent | 6f93ffbe5713be116f31de00cb562a09606a779c (diff) |
Import Mesa 17.3.9
Diffstat (limited to 'lib/mesa/src/gallium/state_trackers/dri')
5 files changed, 444 insertions, 1 deletions
diff --git a/lib/mesa/src/gallium/state_trackers/dri/Makefile.am b/lib/mesa/src/gallium/state_trackers/dri/Makefile.am index 61a1cabeb..8b427f98a 100644 --- a/lib/mesa/src/gallium/state_trackers/dri/Makefile.am +++ b/lib/mesa/src/gallium/state_trackers/dri/Makefile.am @@ -28,7 +28,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src/mapi \ -I$(top_srcdir)/src/mesa \ - -I$(top_builddir)/src/mesa/drivers/dri/common \ + -I$(top_builddir)/src/util \ -I$(top_srcdir)/src/mesa/drivers/dri/common \ $(GALLIUM_CFLAGS) \ $(LIBDRM_CFLAGS) \ diff --git a/lib/mesa/src/gallium/state_trackers/dri/dri_context.h b/lib/mesa/src/gallium/state_trackers/dri/dri_context.h index 96f06442f..afa9c49ff 100644 --- a/lib/mesa/src/gallium/state_trackers/dri/dri_context.h +++ b/lib/mesa/src/gallium/state_trackers/dri/dri_context.h @@ -90,6 +90,7 @@ dri_create_context(gl_api api, unsigned minor_version, uint32_t flags, bool notify_reset, + unsigned priority, unsigned *error, void *sharedContextPrivate); diff --git a/lib/mesa/src/gallium/state_trackers/dri/dri_drawable.h b/lib/mesa/src/gallium/state_trackers/dri/dri_drawable.h index 1f9842ea5..7c45004ba 100644 --- a/lib/mesa/src/gallium/state_trackers/dri/dri_drawable.h +++ b/lib/mesa/src/gallium/state_trackers/dri/dri_drawable.h @@ -85,6 +85,8 @@ struct dri_drawable void (*update_tex_buffer)(struct dri_drawable *drawable, struct dri_context *ctx, struct pipe_resource *res); + void (*flush_swapbuffers)(struct dri_context *ctx, + struct dri_drawable *drawable); }; static inline struct dri_drawable * diff --git a/lib/mesa/src/gallium/state_trackers/dri/dri_helpers.c b/lib/mesa/src/gallium/state_trackers/dri/dri_helpers.c new file mode 100644 index 000000000..06309d8f0 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/dri/dri_helpers.c @@ -0,0 +1,388 @@ +/* + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <dlfcn.h> +#include "util/u_memory.h" +#include "pipe/p_screen.h" +#include "state_tracker/st_texture.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_fbo.h" +#include "main/texobj.h" + +#include "dri_helpers.h" + +static bool +dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen) +{ + return screen->opencl_dri_event_add_ref && + screen->opencl_dri_event_release && + screen->opencl_dri_event_wait && + screen->opencl_dri_event_get_fence; +} + +static bool +dri2_load_opencl_interop(struct dri_screen *screen) +{ +#if defined(RTLD_DEFAULT) + bool success; + + mtx_lock(&screen->opencl_func_mutex); + + if (dri2_is_opencl_interop_loaded_locked(screen)) { + mtx_unlock(&screen->opencl_func_mutex); + return true; + } + + screen->opencl_dri_event_add_ref = + dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref"); + screen->opencl_dri_event_release = + dlsym(RTLD_DEFAULT, "opencl_dri_event_release"); + screen->opencl_dri_event_wait = + dlsym(RTLD_DEFAULT, "opencl_dri_event_wait"); + screen->opencl_dri_event_get_fence = + dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence"); + + success = dri2_is_opencl_interop_loaded_locked(screen); + mtx_unlock(&screen->opencl_func_mutex); + return success; +#else + return false; +#endif +} + +struct dri2_fence { + struct dri_screen *driscreen; + struct pipe_fence_handle *pipe_fence; + void *cl_event; +}; + +static unsigned dri2_fence_get_caps(__DRIscreen *_screen) +{ + struct dri_screen *driscreen = dri_screen(_screen); + struct pipe_screen *screen = driscreen->base.screen; + unsigned caps = 0; + + if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD)) + caps |= __DRI_FENCE_CAP_NATIVE_FD; + + return caps; +} + +static void * +dri2_create_fence(__DRIcontext *_ctx) +{ + struct pipe_context *ctx = dri_context(_ctx)->st->pipe; + struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence); + + if (!fence) + return NULL; + + ctx->flush(ctx, &fence->pipe_fence, 0); + + if (!fence->pipe_fence) { + FREE(fence); + return NULL; + } + + fence->driscreen = dri_screen(_ctx->driScreenPriv); + return fence; +} + +static void * +dri2_create_fence_fd(__DRIcontext *_ctx, int fd) +{ + struct pipe_context *ctx = dri_context(_ctx)->st->pipe; + struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence); + + if (fd == -1) { + /* exporting driver created fence, flush: */ + ctx->flush(ctx, &fence->pipe_fence, + PIPE_FLUSH_DEFERRED | PIPE_FLUSH_FENCE_FD); + } else { + /* importing a foreign fence fd: */ + ctx->create_fence_fd(ctx, &fence->pipe_fence, fd); + } + if (!fence->pipe_fence) { + FREE(fence); + return NULL; + } + + fence->driscreen = dri_screen(_ctx->driScreenPriv); + return fence; +} + +static int +dri2_get_fence_fd(__DRIscreen *_screen, void *_fence) +{ + struct dri_screen *driscreen = dri_screen(_screen); + struct pipe_screen *screen = driscreen->base.screen; + struct dri2_fence *fence = (struct dri2_fence*)_fence; + + return screen->fence_get_fd(screen, fence->pipe_fence); +} + +static void * +dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event) +{ + struct dri_screen *driscreen = dri_screen(_screen); + struct dri2_fence *fence; + + if (!dri2_load_opencl_interop(driscreen)) + return NULL; + + fence = CALLOC_STRUCT(dri2_fence); + if (!fence) + return NULL; + + fence->cl_event = (void*)cl_event; + + if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) { + free(fence); + return NULL; + } + + fence->driscreen = driscreen; + return fence; +} + +static void +dri2_destroy_fence(__DRIscreen *_screen, void *_fence) +{ + struct dri_screen *driscreen = dri_screen(_screen); + struct pipe_screen *screen = driscreen->base.screen; + struct dri2_fence *fence = (struct dri2_fence*)_fence; + + if (fence->pipe_fence) + screen->fence_reference(screen, &fence->pipe_fence, NULL); + else if (fence->cl_event) + driscreen->opencl_dri_event_release(fence->cl_event); + else + assert(0); + + FREE(fence); +} + +static GLboolean +dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags, + uint64_t timeout) +{ + struct dri2_fence *fence = (struct dri2_fence*)_fence; + struct dri_screen *driscreen = fence->driscreen; + struct pipe_screen *screen = driscreen->base.screen; + + /* No need to flush. The context was flushed when the fence was created. */ + + if (fence->pipe_fence) + return screen->fence_finish(screen, NULL, fence->pipe_fence, timeout); + else if (fence->cl_event) { + struct pipe_fence_handle *pipe_fence = + driscreen->opencl_dri_event_get_fence(fence->cl_event); + + if (pipe_fence) + return screen->fence_finish(screen, NULL, pipe_fence, timeout); + else + return driscreen->opencl_dri_event_wait(fence->cl_event, timeout); + } + else { + assert(0); + return false; + } +} + +static void +dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags) +{ + struct pipe_context *ctx = dri_context(_ctx)->st->pipe; + struct dri2_fence *fence = (struct dri2_fence*)_fence; + + if (ctx->fence_server_sync) + ctx->fence_server_sync(ctx, fence->pipe_fence); +} + +const __DRI2fenceExtension dri2FenceExtension = { + .base = { __DRI2_FENCE, 2 }, + + .create_fence = dri2_create_fence, + .get_fence_from_cl_event = dri2_get_fence_from_cl_event, + .destroy_fence = dri2_destroy_fence, + .client_wait_sync = dri2_client_wait_sync, + .server_wait_sync = dri2_server_wait_sync, + .get_capabilities = dri2_fence_get_caps, + .create_fence_fd = dri2_create_fence_fd, + .get_fence_fd = dri2_get_fence_fd, +}; + +__DRIimage * +dri2_lookup_egl_image(struct dri_screen *screen, void *handle) +{ + const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image; + __DRIimage *img; + + if (!loader->lookupEGLImage) + return NULL; + + img = loader->lookupEGLImage(screen->sPriv, + handle, screen->sPriv->loaderPrivate); + + return img; +} + +__DRIimage * +dri2_create_image_from_renderbuffer2(__DRIcontext *context, + int renderbuffer, void *loaderPrivate, + unsigned *error) +{ + struct gl_context *ctx = ((struct st_context *)dri_context(context)->st)->ctx; + struct gl_renderbuffer *rb; + struct pipe_resource *tex; + __DRIimage *img; + + /* Section 3.9 (EGLImage Specification and Management) of the EGL 1.5 + * specification says: + * + * "If target is EGL_GL_RENDERBUFFER and buffer is not the name of a + * renderbuffer object, or if buffer is the name of a multisampled + * renderbuffer object, the error EGL_BAD_PARAMETER is generated." + * + * "If target is EGL_GL_TEXTURE_2D , EGL_GL_TEXTURE_CUBE_MAP_*, + * EGL_GL_RENDERBUFFER or EGL_GL_TEXTURE_3D and buffer refers to the + * default GL texture object (0) for the corresponding GL target, the + * error EGL_BAD_PARAMETER is generated." + * (rely on _mesa_lookup_renderbuffer returning NULL in this case) + */ + rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); + if (!rb || rb->NumSamples > 0) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + tex = st_get_renderbuffer_resource(rb); + if (!tex) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + img = CALLOC_STRUCT(__DRIimageRec); + if (!img) { + *error = __DRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + img->dri_format = driGLFormatToImageFormat(rb->Format); + img->loader_private = loaderPrivate; + + if (img->dri_format == __DRI_IMAGE_FORMAT_NONE) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + free(img); + return NULL; + } + + pipe_resource_reference(&img->texture, tex); + + *error = __DRI_IMAGE_ERROR_SUCCESS; + return img; +} + +__DRIimage * +dri2_create_image_from_renderbuffer(__DRIcontext *context, + int renderbuffer, void *loaderPrivate) +{ + unsigned error; + return dri2_create_image_from_renderbuffer2(context, renderbuffer, + loaderPrivate, &error); +} + +void +dri2_destroy_image(__DRIimage *img) +{ + pipe_resource_reference(&img->texture, NULL); + FREE(img); +} + + +__DRIimage * +dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture, + int depth, int level, unsigned *error, + void *loaderPrivate) +{ + __DRIimage *img; + struct gl_context *ctx = ((struct st_context *)dri_context(context)->st)->ctx; + struct gl_texture_object *obj; + struct pipe_resource *tex; + GLuint face = 0; + + obj = _mesa_lookup_texture(ctx, texture); + if (!obj || obj->Target != target) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + tex = st_get_texobj_resource(obj); + if (!tex) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + if (target == GL_TEXTURE_CUBE_MAP) + face = depth; + + _mesa_test_texobj_completeness(ctx, obj); + if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + if (level < obj->BaseLevel || level > obj->_MaxLevel) { + *error = __DRI_IMAGE_ERROR_BAD_MATCH; + return NULL; + } + + if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) { + *error = __DRI_IMAGE_ERROR_BAD_MATCH; + return NULL; + } + + img = CALLOC_STRUCT(__DRIimageRec); + if (!img) { + *error = __DRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + img->level = level; + img->layer = depth; + img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat); + + img->loader_private = loaderPrivate; + + if (img->dri_format == __DRI_IMAGE_FORMAT_NONE) { + *error = __DRI_IMAGE_ERROR_BAD_PARAMETER; + free(img); + return NULL; + } + + pipe_resource_reference(&img->texture, tex); + + *error = __DRI_IMAGE_ERROR_SUCCESS; + return img; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/lib/mesa/src/gallium/state_trackers/dri/dri_helpers.h b/lib/mesa/src/gallium/state_trackers/dri/dri_helpers.h new file mode 100644 index 000000000..76f024fd6 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/dri/dri_helpers.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef DRI_HELPERS_H +#define DRI_HELPERS_H + +#include "dri_context.h" +#include "dri_screen.h" + +extern const __DRI2fenceExtension dri2FenceExtension; + +__DRIimage * +dri2_lookup_egl_image(struct dri_screen *screen, void *handle); + +__DRIimage * +dri2_create_image_from_renderbuffer(__DRIcontext *context, + int renderbuffer, void *loaderPrivate); + +__DRIimage * +dri2_create_image_from_renderbuffer2(__DRIcontext *context, + int renderbuffer, void *loaderPrivate, + unsigned *error); + +void +dri2_destroy_image(__DRIimage *img); + +__DRIimage * +dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture, + int depth, int level, unsigned *error, + void *loaderPrivate); +#endif + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ |