summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/state_trackers/dri
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2018-10-23 05:47:28 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2018-10-23 05:47:28 +0000
commitf6666e4c3977a5d74f3da7464672ea48e44dff4b (patch)
tree21df237f03b2aabc094d514d3d8f0d13c4f00f4e /lib/mesa/src/gallium/state_trackers/dri
parent6f93ffbe5713be116f31de00cb562a09606a779c (diff)
Import Mesa 17.3.9
Diffstat (limited to 'lib/mesa/src/gallium/state_trackers/dri')
-rw-r--r--lib/mesa/src/gallium/state_trackers/dri/Makefile.am2
-rw-r--r--lib/mesa/src/gallium/state_trackers/dri/dri_context.h1
-rw-r--r--lib/mesa/src/gallium/state_trackers/dri/dri_drawable.h2
-rw-r--r--lib/mesa/src/gallium/state_trackers/dri/dri_helpers.c388
-rw-r--r--lib/mesa/src/gallium/state_trackers/dri/dri_helpers.h52
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: */