summaryrefslogtreecommitdiff
path: root/lib/mesa/src/loader
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2018-10-23 06:36:00 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2018-10-23 06:36:00 +0000
commitb65fcab046d3a1b6b6ac315720df220925c5322e (patch)
treeff73dcc383ac0799c655ff6194cda9dacb75dde9 /lib/mesa/src/loader
parent18d6381c51e253e4c41c62619f80d9ce745b95c8 (diff)
Merge Mesa 17.3.9
Mesa 18.x needs an ld with build-id for at least the intel code Mesa 18.2 assumes linux only memfd syscalls in intel code Tested by matthieu@, kettenis@ and myself on a variety of hardware and architectures. ok kettenis@
Diffstat (limited to 'lib/mesa/src/loader')
-rw-r--r--lib/mesa/src/loader/Makefile.am17
-rw-r--r--lib/mesa/src/loader/Makefile.in100
-rw-r--r--lib/mesa/src/loader/loader.c62
-rw-r--r--lib/mesa/src/loader/loader.h6
-rw-r--r--lib/mesa/src/loader/loader_dri3_helper.c737
-rw-r--r--lib/mesa/src/loader/loader_dri3_helper.h28
6 files changed, 645 insertions, 305 deletions
diff --git a/lib/mesa/src/loader/Makefile.am b/lib/mesa/src/loader/Makefile.am
index 93b46d9e1..74ac6c51e 100644
--- a/lib/mesa/src/loader/Makefile.am
+++ b/lib/mesa/src/loader/Makefile.am
@@ -26,6 +26,8 @@ EXTRA_DIST = SConscript
noinst_LTLIBRARIES = libloader.la
AM_CPPFLAGS = \
+ -I$(top_builddir)/src/util/ \
+ -DUSE_DRICONF \
$(DEFINES) \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src \
@@ -37,24 +39,12 @@ libloader_la_CPPFLAGS = $(AM_CPPFLAGS)
libloader_la_SOURCES = $(LOADER_C_FILES)
libloader_la_LIBADD =
-if HAVE_DRICOMMON
-libloader_la_CPPFLAGS += \
- -I$(top_builddir)/src/mesa/drivers/dri/common/ \
- -I$(top_srcdir)/src/mesa/drivers/dri/common/ \
- -I$(top_srcdir)/src/mesa/ \
- -I$(top_srcdir)/src/mapi/ \
- -DUSE_DRICONF
-
- libloader_la_LIBADD += \
- $(top_builddir)/src/mesa/drivers/dri/common/libxmlconfig.la
-
-endif
-
if HAVE_LIBDRM
libloader_la_LIBADD += \
$(LIBDRM_LIBS)
endif
+if HAVE_PLATFORM_X11
if HAVE_DRI3
noinst_LTLIBRARIES += libloader_dri3_helper.la
@@ -63,3 +53,4 @@ libloader_dri3_helper_la_SOURCES = \
loader_dri3_helper.h
libloader_dri3_helper_la_LIBADD = $(XCB_DRI3_LIBS)
endif
+endif
diff --git a/lib/mesa/src/loader/Makefile.in b/lib/mesa/src/loader/Makefile.in
index 4d40b8928..fb418ac81 100644
--- a/lib/mesa/src/loader/Makefile.in
+++ b/lib/mesa/src/loader/Makefile.in
@@ -74,23 +74,14 @@ host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/Makefile.sources $(top_srcdir)/bin/depcomp
-@HAVE_DRICOMMON_TRUE@am__append_1 = \
-@HAVE_DRICOMMON_TRUE@ -I$(top_builddir)/src/mesa/drivers/dri/common/ \
-@HAVE_DRICOMMON_TRUE@ -I$(top_srcdir)/src/mesa/drivers/dri/common/ \
-@HAVE_DRICOMMON_TRUE@ -I$(top_srcdir)/src/mesa/ \
-@HAVE_DRICOMMON_TRUE@ -I$(top_srcdir)/src/mapi/ \
-@HAVE_DRICOMMON_TRUE@ -DUSE_DRICONF
-
-@HAVE_DRICOMMON_TRUE@am__append_2 = \
-@HAVE_DRICOMMON_TRUE@ $(top_builddir)/src/mesa/drivers/dri/common/libxmlconfig.la
-
-@HAVE_LIBDRM_TRUE@am__append_3 = \
+@HAVE_LIBDRM_TRUE@am__append_1 = \
@HAVE_LIBDRM_TRUE@ $(LIBDRM_LIBS)
-@HAVE_DRI3_TRUE@am__append_4 = libloader_dri3_helper.la
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@am__append_2 = libloader_dri3_helper.la
subdir = src/loader
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_gnu_make.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_check_gnu_make.m4 \
$(top_srcdir)/m4/ax_check_python_mako_module.m4 \
$(top_srcdir)/m4/ax_gcc_builtin.m4 \
$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
@@ -108,7 +99,7 @@ CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
am__DEPENDENCIES_1 =
@HAVE_LIBDRM_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
-libloader_la_DEPENDENCIES = $(am__append_2) $(am__DEPENDENCIES_2)
+libloader_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
am__objects_1 = libloader_la-loader.lo \
libloader_la-pci_id_driver_map.lo
am_libloader_la_OBJECTS = $(am__objects_1)
@@ -117,15 +108,15 @@ AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
-@HAVE_DRI3_TRUE@libloader_dri3_helper_la_DEPENDENCIES = \
-@HAVE_DRI3_TRUE@ $(am__DEPENDENCIES_1)
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@libloader_dri3_helper_la_DEPENDENCIES = \
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@ $(am__DEPENDENCIES_1)
am__libloader_dri3_helper_la_SOURCES_DIST = loader_dri3_helper.c \
loader_dri3_helper.h
-@HAVE_DRI3_TRUE@am_libloader_dri3_helper_la_OBJECTS = \
-@HAVE_DRI3_TRUE@ loader_dri3_helper.lo
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@am_libloader_dri3_helper_la_OBJECTS = \
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@ loader_dri3_helper.lo
libloader_dri3_helper_la_OBJECTS = \
$(am_libloader_dri3_helper_la_OBJECTS)
-@HAVE_DRI3_TRUE@am_libloader_dri3_helper_la_rpath =
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@am_libloader_dri3_helper_la_rpath =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -176,6 +167,8 @@ AMDGPU_CFLAGS = @AMDGPU_CFLAGS@
AMDGPU_LIBS = @AMDGPU_LIBS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+ANDROID_CFLAGS = @ANDROID_CFLAGS@
+ANDROID_LIBS = @ANDROID_LIBS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -206,8 +199,6 @@ DLLTOOL = @DLLTOOL@
DLOPEN_LIBS = @DLOPEN_LIBS@
DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
-DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@
-DRI3PROTO_LIBS = @DRI3PROTO_LIBS@
DRIGL_CFLAGS = @DRIGL_CFLAGS@
DRIGL_LIBS = @DRIGL_LIBS@
DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@
@@ -220,10 +211,11 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGL_CFLAGS = @EGL_CFLAGS@
-EGL_CLIENT_APIS = @EGL_CLIENT_APIS@
EGL_LIB_DEPS = @EGL_LIB_DEPS@
EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@
EGREP = @EGREP@
+ETNAVIV_CFLAGS = @ETNAVIV_CFLAGS@
+ETNAVIV_LIBS = @ETNAVIV_LIBS@
EXEEXT = @EXEEXT@
EXPAT_CFLAGS = @EXPAT_CFLAGS@
EXPAT_LIBS = @EXPAT_LIBS@
@@ -250,6 +242,8 @@ GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@
GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@
GREP = @GREP@
HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@
+I915_CFLAGS = @I915_CFLAGS@
+I915_LIBS = @I915_LIBS@
INDENT = @INDENT@
INDENT_FLAGS = @INDENT_FLAGS@
INSTALL = @INSTALL@
@@ -257,45 +251,40 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INTEL_CFLAGS = @INTEL_CFLAGS@
-INTEL_LIBS = @INTEL_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LD_NO_UNDEFINED = @LD_NO_UNDEFINED@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBATOMIC_LIBS = @LIBATOMIC_LIBS@
LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@
LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@
LIBDRM_CFLAGS = @LIBDRM_CFLAGS@
LIBDRM_LIBS = @LIBDRM_LIBS@
LIBELF_CFLAGS = @LIBELF_CFLAGS@
LIBELF_LIBS = @LIBELF_LIBS@
+LIBGLVND_DATADIR = @LIBGLVND_DATADIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
-LIBSENSORS_LDFLAGS = @LIBSENSORS_LDFLAGS@
-LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@
-LIBSHA1_LIBS = @LIBSHA1_LIBS@
+LIBSENSORS_LIBS = @LIBSENSORS_LIBS@
LIBTOOL = @LIBTOOL@
+LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@
+LIBUNWIND_LIBS = @LIBUNWIND_LIBS@
LIB_DIR = @LIB_DIR@
LIB_EXT = @LIB_EXT@
LIPO = @LIPO@
-LLVM_BINDIR = @LLVM_BINDIR@
LLVM_CFLAGS = @LLVM_CFLAGS@
LLVM_CONFIG = @LLVM_CONFIG@
-LLVM_CPPFLAGS = @LLVM_CPPFLAGS@
LLVM_CXXFLAGS = @LLVM_CXXFLAGS@
LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@
LLVM_LDFLAGS = @LLVM_LDFLAGS@
-LLVM_LIBDIR = @LLVM_LIBDIR@
LLVM_LIBS = @LLVM_LIBS@
-LLVM_VERSION = @LLVM_VERSION@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
-MESA_LLVM = @MESA_LLVM@
MKDIR_P = @MKDIR_P@
MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@
MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@
@@ -311,13 +300,11 @@ NVVIEUX_CFLAGS = @NVVIEUX_CFLAGS@
NVVIEUX_LIBS = @NVVIEUX_LIBS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OMX_CFLAGS = @OMX_CFLAGS@
-OMX_LIBS = @OMX_LIBS@
-OMX_LIB_INSTALL_DIR = @OMX_LIB_INSTALL_DIR@
+OMX_BELLAGIO_CFLAGS = @OMX_BELLAGIO_CFLAGS@
+OMX_BELLAGIO_LIBS = @OMX_BELLAGIO_LIBS@
+OMX_BELLAGIO_LIB_INSTALL_DIR = @OMX_BELLAGIO_LIB_INSTALL_DIR@
OPENCL_LIBNAME = @OPENCL_LIBNAME@
OPENCL_VERSION = @OPENCL_VERSION@
-OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
-OPENSSL_LIBS = @OPENSSL_LIBS@
OSMESA_LIB = @OSMESA_LIB@
OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@
OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@
@@ -337,8 +324,6 @@ PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSIX_SHELL = @POSIX_SHELL@
-PRESENTPROTO_CFLAGS = @PRESENTPROTO_CFLAGS@
-PRESENTPROTO_LIBS = @PRESENTPROTO_LIBS@
PTHREADSTUBS_CFLAGS = @PTHREADSTUBS_CFLAGS@
PTHREADSTUBS_LIBS = @PTHREADSTUBS_LIBS@
PTHREAD_CC = @PTHREAD_CC@
@@ -354,8 +339,6 @@ SED = @SED@
SELINUX_CFLAGS = @SELINUX_CFLAGS@
SELINUX_LIBS = @SELINUX_LIBS@
SET_MAKE = @SET_MAKE@
-SHA1_CFLAGS = @SHA1_CFLAGS@
-SHA1_LIBS = @SHA1_LIBS@
SHELL = @SHELL@
SIMPENROSE_CFLAGS = @SIMPENROSE_CFLAGS@
SIMPENROSE_LIBS = @SIMPENROSE_LIBS@
@@ -364,7 +347,8 @@ STRIP = @STRIP@
SWR_AVX2_CXXFLAGS = @SWR_AVX2_CXXFLAGS@
SWR_AVX_CXXFLAGS = @SWR_AVX_CXXFLAGS@
SWR_CXX11_CXXFLAGS = @SWR_CXX11_CXXFLAGS@
-TIMESTAMP_CMD = @TIMESTAMP_CMD@
+SWR_KNL_CXXFLAGS = @SWR_KNL_CXXFLAGS@
+SWR_SKX_CXXFLAGS = @SWR_SKX_CXXFLAGS@
VALGRIND_CFLAGS = @VALGRIND_CFLAGS@
VALGRIND_LIBS = @VALGRIND_LIBS@
VA_CFLAGS = @VA_CFLAGS@
@@ -372,25 +356,28 @@ VA_LIBS = @VA_LIBS@
VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@
VA_MAJOR = @VA_MAJOR@
VA_MINOR = @VA_MINOR@
-VC4_CFLAGS = @VC4_CFLAGS@
-VC4_LIBS = @VC4_LIBS@
+VC5_SIMULATOR_CFLAGS = @VC5_SIMULATOR_CFLAGS@
+VC5_SIMULATOR_LIBS = @VC5_SIMULATOR_LIBS@
VDPAU_CFLAGS = @VDPAU_CFLAGS@
VDPAU_LIBS = @VDPAU_LIBS@
VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@
VDPAU_MAJOR = @VDPAU_MAJOR@
VDPAU_MINOR = @VDPAU_MINOR@
VERSION = @VERSION@
-VG_LIB_DEPS = @VG_LIB_DEPS@
VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@
VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@
VL_CFLAGS = @VL_CFLAGS@
VL_LIBS = @VL_LIBS@
VULKAN_ICD_INSTALL_DIR = @VULKAN_ICD_INSTALL_DIR@
-WAYLAND_CFLAGS = @WAYLAND_CFLAGS@
-WAYLAND_LIBS = @WAYLAND_LIBS@
+WAYLAND_CLIENT_CFLAGS = @WAYLAND_CLIENT_CFLAGS@
+WAYLAND_CLIENT_LIBS = @WAYLAND_CLIENT_LIBS@
+WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@
WAYLAND_SCANNER = @WAYLAND_SCANNER@
WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@
WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@
+WAYLAND_SERVER_CFLAGS = @WAYLAND_SERVER_CFLAGS@
+WAYLAND_SERVER_LIBS = @WAYLAND_SERVER_LIBS@
+WNO_OVERRIDE_INIT = @WNO_OVERRIDE_INIT@
X11_INCLUDES = @X11_INCLUDES@
XA_MAJOR = @XA_MAJOR@
XA_MINOR = @XA_MINOR@
@@ -409,9 +396,10 @@ XVMC_LIBS = @XVMC_LIBS@
XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@
XVMC_MAJOR = @XVMC_MAJOR@
XVMC_MINOR = @XVMC_MINOR@
-XXD = @XXD@
YACC = @YACC@
YFLAGS = @YFLAGS@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -479,8 +467,10 @@ LOADER_C_FILES := \
pci_id_driver_map.h
EXTRA_DIST = SConscript
-noinst_LTLIBRARIES = libloader.la $(am__append_4)
+noinst_LTLIBRARIES = libloader.la $(am__append_2)
AM_CPPFLAGS = \
+ -I$(top_builddir)/src/util/ \
+ -DUSE_DRICONF \
$(DEFINES) \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src \
@@ -488,14 +478,14 @@ AM_CPPFLAGS = \
$(XCB_DRI3_CFLAGS) \
$(LIBDRM_CFLAGS)
-libloader_la_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_1)
+libloader_la_CPPFLAGS = $(AM_CPPFLAGS)
libloader_la_SOURCES = $(LOADER_C_FILES)
-libloader_la_LIBADD = $(am__append_2) $(am__append_3)
-@HAVE_DRI3_TRUE@libloader_dri3_helper_la_SOURCES = \
-@HAVE_DRI3_TRUE@ loader_dri3_helper.c \
-@HAVE_DRI3_TRUE@ loader_dri3_helper.h
+libloader_la_LIBADD = $(am__append_1)
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@libloader_dri3_helper_la_SOURCES = \
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@ loader_dri3_helper.c \
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@ loader_dri3_helper.h
-@HAVE_DRI3_TRUE@libloader_dri3_helper_la_LIBADD = $(XCB_DRI3_LIBS)
+@HAVE_DRI3_TRUE@@HAVE_PLATFORM_X11_TRUE@libloader_dri3_helper_la_LIBADD = $(XCB_DRI3_LIBS)
all: all-am
.SUFFIXES:
diff --git a/lib/mesa/src/loader/loader.c b/lib/mesa/src/loader/loader.c
index fe9030776..182ba90a0 100644
--- a/lib/mesa/src/loader/loader.c
+++ b/lib/mesa/src/loader/loader.c
@@ -33,6 +33,8 @@
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
#ifdef MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#endif
@@ -42,12 +44,10 @@
#include "loader.h"
#ifdef HAVE_LIBDRM
-#include <stdlib.h>
-#include <unistd.h>
#include <xf86drm.h>
#ifdef USE_DRICONF
-#include "xmlconfig.h"
-#include "xmlpool.h"
+#include "util/xmlconfig.h"
+#include "util/xmlpool.h"
#endif
#endif
@@ -145,7 +145,7 @@ static char *drm_get_id_path_tag_for_fd(int fd)
drmDevicePtr device;
char *tag;
- if (drmGetDevice(fd, &device) != 0)
+ if (drmGetDevice2(fd, 0, &device) != 0)
return NULL;
tag = drm_construct_id_path_tag(device);
@@ -153,7 +153,7 @@ static char *drm_get_id_path_tag_for_fd(int fd)
return tag;
}
-int loader_get_user_preferred_fd(int default_fd, int *different_device)
+int loader_get_user_preferred_fd(int default_fd, bool *different_device)
{
/* Arbitrary "maximum" value of drm devices. */
#define MAX_DRM_DEVICES 32
@@ -171,7 +171,7 @@ int loader_get_user_preferred_fd(int default_fd, int *different_device)
#endif
if (prime == NULL) {
- *different_device = 0;
+ *different_device = false;
return default_fd;
}
@@ -179,7 +179,7 @@ int loader_get_user_preferred_fd(int default_fd, int *different_device)
if (default_tag == NULL)
goto err;
- num_devices = drmGetDevices(devices, MAX_DRM_DEVICES);
+ num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
if (num_devices < 0)
goto err;
@@ -230,16 +230,16 @@ int loader_get_user_preferred_fd(int default_fd, int *different_device)
return fd;
err:
- *different_device = 0;
+ *different_device = false;
free(default_tag);
free(prime);
return default_fd;
}
#else
-int loader_get_user_preferred_fd(int default_fd, int *different_device)
+int loader_get_user_preferred_fd(int default_fd, bool *different_device)
{
- *different_device = 0;
+ *different_device = false;
return default_fd;
}
#endif
@@ -275,14 +275,14 @@ drm_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
drmDevicePtr device;
int ret;
- if (drmGetDevice(fd, &device) == 0) {
+ if (drmGetDevice2(fd, 0, &device) == 0) {
if (device->bustype == DRM_BUS_PCI) {
*vendor_id = device->deviceinfo.pci->vendor_id;
*chip_id = device->deviceinfo.pci->device_id;
ret = 1;
}
else {
- log_(_LOADER_WARNING, "MESA-LOADER: device is not located on the PCI bus\n");
+ log_(_LOADER_DEBUG, "MESA-LOADER: device is not located on the PCI bus\n");
ret = 0;
}
drmFreeDevice(&device);
@@ -345,6 +345,17 @@ loader_get_driver_for_fd(int fd)
int vendor_id, chip_id, i, j;
char *driver = NULL;
+ /* Allow an environment variable to force choosing a different driver
+ * binary. If that driver binary can't survive on this FD, that's the
+ * user's problem, but this allows vc4 simulator to run on an i965 host,
+ * and may be useful for some touch testing of i915 on an i965 host.
+ */
+ if (geteuid() == getuid()) {
+ driver = getenv("MESA_LOADER_DRIVER_OVERRIDE");
+ if (driver)
+ return strdup(driver);
+ }
+
if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {
#if HAVE_LIBDRM
@@ -396,3 +407,28 @@ loader_set_logger(void (*logger)(int level, const char *fmt, ...))
{
log_ = logger;
}
+
+/* XXX: Local definition to avoid pulling the heavyweight GL/gl.h and
+ * GL/internal/dri_interface.h
+ */
+
+#ifndef __DRI_DRIVER_GET_EXTENSIONS
+#define __DRI_DRIVER_GET_EXTENSIONS "__driDriverGetExtensions"
+#endif
+
+char *
+loader_get_extensions_name(const char *driver_name)
+{
+ char *name = NULL;
+
+ if (asprintf(&name, "%s_%s", __DRI_DRIVER_GET_EXTENSIONS, driver_name) < 0)
+ return NULL;
+
+ const size_t len = strlen(name);
+ for (size_t i = 0; i < len; i++) {
+ if (name[i] == '-')
+ name[i] = '_';
+ }
+
+ return name;
+}
diff --git a/lib/mesa/src/loader/loader.h b/lib/mesa/src/loader/loader.h
index d404f5b67..3859b45dc 100644
--- a/lib/mesa/src/loader/loader.h
+++ b/lib/mesa/src/loader/loader.h
@@ -27,6 +27,8 @@
#ifndef LOADER_H
#define LOADER_H
+#include <stdbool.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -51,7 +53,7 @@ loader_get_device_name_for_fd(int fd);
*/
int
-loader_get_user_preferred_fd(int default_fd, int *different_device);
+loader_get_user_preferred_fd(int default_fd, bool *different_device);
/* for logging.. keep this aligned with egllog.h so we can just use
* _eglLog directly.
@@ -65,6 +67,8 @@ loader_get_user_preferred_fd(int default_fd, int *different_device);
void
loader_set_logger(void (*logger)(int level, const char *fmt, ...));
+char *
+loader_get_extensions_name(const char *driver_name);
#ifdef __cplusplus
}
diff --git a/lib/mesa/src/loader/loader_dri3_helper.c b/lib/mesa/src/loader/loader_dri3_helper.c
index d465a41e2..b4c458201 100644
--- a/lib/mesa/src/loader/loader_dri3_helper.c
+++ b/lib/mesa/src/loader/loader_dri3_helper.c
@@ -40,6 +40,127 @@
#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
#define DRI_CONF_VBLANK_ALWAYS_SYNC 3
+/**
+ * A cached blit context.
+ */
+struct loader_dri3_blit_context {
+ mtx_t mtx;
+ __DRIcontext *ctx;
+ __DRIscreen *cur_screen;
+ const __DRIcoreExtension *core;
+};
+
+/* For simplicity we maintain the cache only for a single screen at a time */
+static struct loader_dri3_blit_context blit_context = {
+ _MTX_INITIALIZER_NP, NULL
+};
+
+static void
+dri3_flush_present_events(struct loader_dri3_drawable *draw);
+
+static struct loader_dri3_buffer *
+dri3_find_back_alloc(struct loader_dri3_drawable *draw);
+
+/**
+ * Do we have blit functionality in the image blit extension?
+ *
+ * \param draw[in] The drawable intended to blit from / to.
+ * \return true if we have blit functionality. false otherwise.
+ */
+static bool loader_dri3_have_image_blit(const struct loader_dri3_drawable *draw)
+{
+ return draw->ext->image->base.version >= 9 &&
+ draw->ext->image->blitImage != NULL;
+}
+
+/**
+ * Get and lock (for use with the current thread) a dri context associated
+ * with the drawable's dri screen. The context is intended to be used with
+ * the dri image extension's blitImage method.
+ *
+ * \param draw[in] Pointer to the drawable whose dri screen we want a
+ * dri context for.
+ * \return A dri context or NULL if context creation failed.
+ *
+ * When the caller is done with the context (even if the context returned was
+ * NULL), the caller must call loader_dri3_blit_context_put.
+ */
+static __DRIcontext *
+loader_dri3_blit_context_get(struct loader_dri3_drawable *draw)
+{
+ mtx_lock(&blit_context.mtx);
+
+ if (blit_context.ctx && blit_context.cur_screen != draw->dri_screen) {
+ blit_context.core->destroyContext(blit_context.ctx);
+ blit_context.ctx = NULL;
+ }
+
+ if (!blit_context.ctx) {
+ blit_context.ctx = draw->ext->core->createNewContext(draw->dri_screen,
+ NULL, NULL, NULL);
+ blit_context.cur_screen = draw->dri_screen;
+ blit_context.core = draw->ext->core;
+ }
+
+ return blit_context.ctx;
+}
+
+/**
+ * Release (for use with other threads) a dri context previously obtained using
+ * loader_dri3_blit_context_get.
+ */
+static void
+loader_dri3_blit_context_put(void)
+{
+ mtx_unlock(&blit_context.mtx);
+}
+
+/**
+ * Blit (parts of) the contents of a DRI image to another dri image
+ *
+ * \param draw[in] The drawable which owns the images.
+ * \param dst[in] The destination image.
+ * \param src[in] The source image.
+ * \param dstx0[in] Start destination coordinate.
+ * \param dsty0[in] Start destination coordinate.
+ * \param width[in] Blit width.
+ * \param height[in] Blit height.
+ * \param srcx0[in] Start source coordinate.
+ * \param srcy0[in] Start source coordinate.
+ * \param flush_flag[in] Image blit flush flag.
+ * \return true iff successful.
+ */
+static bool
+loader_dri3_blit_image(struct loader_dri3_drawable *draw,
+ __DRIimage *dst, __DRIimage *src,
+ int dstx0, int dsty0, int width, int height,
+ int srcx0, int srcy0, int flush_flag)
+{
+ __DRIcontext *dri_context;
+ bool use_blit_context = false;
+
+ if (!loader_dri3_have_image_blit(draw))
+ return false;
+
+ dri_context = draw->vtable->get_dri_context(draw);
+
+ if (!dri_context || !draw->vtable->in_current_context(draw)) {
+ dri_context = loader_dri3_blit_context_get(draw);
+ use_blit_context = true;
+ flush_flag |= __BLIT_FLAG_FLUSH;
+ }
+
+ if (dri_context)
+ draw->ext->image->blitImage(dri_context, dst, src, dstx0, dsty0,
+ width, height, srcx0, srcy0,
+ width, height, flush_flag);
+
+ if (use_blit_context)
+ loader_dri3_blit_context_put();
+
+ return dri_context != NULL;
+}
+
static inline void
dri3_fence_reset(xcb_connection_t *c, struct loader_dri3_buffer *buffer)
{
@@ -59,10 +180,16 @@ dri3_fence_trigger(xcb_connection_t *c, struct loader_dri3_buffer *buffer)
}
static inline void
-dri3_fence_await(xcb_connection_t *c, struct loader_dri3_buffer *buffer)
+dri3_fence_await(xcb_connection_t *c, struct loader_dri3_drawable *draw,
+ struct loader_dri3_buffer *buffer)
{
xcb_flush(c);
xshmfence_await(buffer->shm_fence);
+ if (draw) {
+ mtx_lock(&draw->mtx);
+ dri3_flush_present_events(draw);
+ mtx_unlock(&draw->mtx);
+ }
}
static void
@@ -77,9 +204,7 @@ dri3_update_num_back(struct loader_dri3_drawable *draw)
void
loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw, int interval)
{
- interval = draw->vtable->clamp_swap_interval(draw, interval);
- draw->vtable->set_swap_interval(draw, interval);
- dri3_update_num_back(draw);
+ draw->swap_interval = interval;
}
/** dri3_free_render_buffer
@@ -95,9 +220,9 @@ dri3_free_render_buffer(struct loader_dri3_drawable *draw,
xcb_free_pixmap(draw->conn, buffer->pixmap);
xcb_sync_destroy_fence(draw->conn, buffer->sync_fence);
xshmfence_unmap_shm(buffer->shm_fence);
- (draw->ext->image->destroyImage)(buffer->image);
+ draw->ext->image->destroyImage(buffer->image);
if (buffer->linear_buffer)
- (draw->ext->image->destroyImage)(buffer->linear_buffer);
+ draw->ext->image->destroyImage(buffer->linear_buffer);
free(buffer);
}
@@ -106,7 +231,7 @@ loader_dri3_drawable_fini(struct loader_dri3_drawable *draw)
{
int i;
- (draw->ext->core->destroyDrawable)(draw->dri_drawable);
+ draw->ext->core->destroyDrawable(draw->dri_drawable);
for (i = 0; i < LOADER_DRI3_NUM_BUFFERS; i++) {
if (draw->buffers[i])
@@ -121,6 +246,9 @@ loader_dri3_drawable_fini(struct loader_dri3_drawable *draw)
xcb_discard_reply(draw->conn, cookie.sequence);
xcb_unregister_for_special_event(draw->conn, draw->special_event);
}
+
+ cnd_destroy(&draw->event_cnd);
+ mtx_destroy(&draw->mtx);
}
int
@@ -150,6 +278,11 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->have_fake_front = 0;
draw->first_init = true;
+ draw->cur_blit_source = -1;
+ draw->back_format = __DRI_IMAGE_FORMAT_NONE;
+ mtx_init(&draw->mtx, mtx_plain);
+ cnd_init(&draw->event_cnd);
+
if (draw->ext->config)
draw->ext->config->configQueryi(draw->dri_screen,
"vblank_mode", &vblank_mode);
@@ -165,15 +298,15 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
swap_interval = 1;
break;
}
- draw->vtable->set_swap_interval(draw, swap_interval);
+ draw->swap_interval = swap_interval;
dri3_update_num_back(draw);
/* Create a new drawable */
draw->dri_drawable =
- (draw->ext->image_driver->createNewDrawable)(dri_screen,
- dri_config,
- draw);
+ draw->ext->image_driver->createNewDrawable(dri_screen,
+ dri_config,
+ draw);
if (!draw->dri_drawable)
return 1;
@@ -191,6 +324,13 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->vtable->set_drawable_size(draw, draw->width, draw->height);
free(reply);
+ draw->swap_method = __DRI_ATTRIB_SWAP_UNDEFINED;
+ if (draw->ext->core->base.version >= 2) {
+ (void )draw->ext->core->getConfigAttrib(dri_config,
+ __DRI_ATTRIB_SWAP_METHOD,
+ &draw->swap_method);
+ }
+
/*
* Make sure server has the same swap interval we do for the new
* drawable.
@@ -214,6 +354,7 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
draw->width = ce->width;
draw->height = ce->height;
draw->vtable->set_drawable_size(draw, draw->width, draw->height);
+ draw->ext->flush->invalidate(draw->dri_drawable);
break;
}
case XCB_PRESENT_COMPLETE_NOTIFY: {
@@ -235,7 +376,6 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
draw->flipping = false;
break;
}
- dri3_update_num_back(draw);
if (draw->vtable->show_fps)
draw->vtable->show_fps(draw, ce->ust);
@@ -256,13 +396,14 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
for (b = 0; b < sizeof(draw->buffers) / sizeof(draw->buffers[0]); b++) {
struct loader_dri3_buffer *buf = draw->buffers[b];
- if (buf && buf->pixmap == ie->pixmap) {
+ if (buf && buf->pixmap == ie->pixmap)
buf->busy = 0;
- if (draw->num_back <= b && b < LOADER_DRI3_MAX_BACK) {
- dri3_free_render_buffer(draw, buf);
- draw->buffers[b] = NULL;
- }
- break;
+
+ if (buf && draw->num_back <= b && b < LOADER_DRI3_MAX_BACK &&
+ draw->cur_blit_source != b &&
+ !buf->busy) {
+ dri3_free_render_buffer(draw, buf);
+ draw->buffers[b] = NULL;
}
}
break;
@@ -272,13 +413,27 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
}
static bool
-dri3_wait_for_event(struct loader_dri3_drawable *draw)
+dri3_wait_for_event_locked(struct loader_dri3_drawable *draw)
{
xcb_generic_event_t *ev;
xcb_present_generic_event_t *ge;
xcb_flush(draw->conn);
- ev = xcb_wait_for_special_event(draw->conn, draw->special_event);
+
+ /* Only have one thread waiting for events at a time */
+ if (draw->has_event_waiter) {
+ cnd_wait(&draw->event_cnd, &draw->mtx);
+ /* Another thread has updated the protected info, so retest. */
+ return true;
+ } else {
+ draw->has_event_waiter = true;
+ /* Allow other threads access to the drawable while we're waiting. */
+ mtx_unlock(&draw->mtx);
+ ev = xcb_wait_for_special_event(draw->conn, draw->special_event);
+ mtx_lock(&draw->mtx);
+ draw->has_event_waiter = false;
+ cnd_broadcast(&draw->event_cnd);
+ }
if (!ev)
return false;
ge = (void *) ev;
@@ -307,19 +462,23 @@ loader_dri3_wait_for_msc(struct loader_dri3_drawable *draw,
divisor,
remainder);
+ mtx_lock(&draw->mtx);
xcb_flush(draw->conn);
/* Wait for the event */
if (draw->special_event) {
while ((int32_t) (msc_serial - draw->recv_msc_serial) > 0) {
- if (!dri3_wait_for_event(draw))
+ if (!dri3_wait_for_event_locked(draw)) {
+ mtx_unlock(&draw->mtx);
return false;
+ }
}
}
*ust = draw->notify_ust;
*msc = draw->notify_msc;
*sbc = draw->recv_sbc;
+ mtx_unlock(&draw->mtx);
return true;
}
@@ -341,17 +500,21 @@ loader_dri3_wait_for_sbc(struct loader_dri3_drawable *draw,
* swaps requested with glXSwapBuffersMscOML for that window have
* completed."
*/
+ mtx_lock(&draw->mtx);
if (!target_sbc)
target_sbc = draw->send_sbc;
while (draw->recv_sbc < target_sbc) {
- if (!dri3_wait_for_event(draw))
+ if (!dri3_wait_for_event_locked(draw)) {
+ mtx_unlock(&draw->mtx);
return 0;
+ }
}
*ust = draw->ust;
*msc = draw->msc;
*sbc = draw->recv_sbc;
+ mtx_unlock(&draw->mtx);
return 1;
}
@@ -364,25 +527,37 @@ static int
dri3_find_back(struct loader_dri3_drawable *draw)
{
int b;
- xcb_generic_event_t *ev;
- xcb_present_generic_event_t *ge;
+ int num_to_consider;
+
+ mtx_lock(&draw->mtx);
+ /* Increase the likelyhood of reusing current buffer */
+ dri3_flush_present_events(draw);
+
+ /* Check whether we need to reuse the current back buffer as new back.
+ * In that case, wait until it's not busy anymore.
+ */
+ dri3_update_num_back(draw);
+ num_to_consider = draw->num_back;
+ if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1) {
+ num_to_consider = 1;
+ draw->cur_blit_source = -1;
+ }
for (;;) {
- for (b = 0; b < draw->num_back; b++) {
+ for (b = 0; b < num_to_consider; b++) {
int id = LOADER_DRI3_BACK_ID((b + draw->cur_back) % draw->num_back);
struct loader_dri3_buffer *buffer = draw->buffers[id];
if (!buffer || !buffer->busy) {
draw->cur_back = id;
+ mtx_unlock(&draw->mtx);
return id;
}
}
- xcb_flush(draw->conn);
- ev = xcb_wait_for_special_event(draw->conn, draw->special_event);
- if (!ev)
+ if (!dri3_wait_for_event_locked(draw)) {
+ mtx_unlock(&draw->mtx);
return -1;
- ge = (void *) ev;
- dri3_handle_present_event(draw, ge);
+ }
}
}
@@ -468,9 +643,6 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
{
struct loader_dri3_buffer *back;
unsigned flags = __DRI2_FLUSH_DRAWABLE;
- __DRIcontext *dri_context;
-
- dri_context = draw->vtable->get_dri_context(draw);
/* Check we have the right attachments */
if (!draw->have_back || draw->is_pixmap)
@@ -480,33 +652,27 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
flags |= __DRI2_FLUSH_CONTEXT;
loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
- back = dri3_back_buffer(draw);
+ back = dri3_find_back_alloc(draw);
+ if (!back)
+ return;
+
y = draw->height - y - height;
- if (draw->is_different_gpu && draw->vtable->in_current_context(draw)) {
+ if (draw->is_different_gpu) {
/* Update the linear buffer part of the back buffer
* for the dri3_copy_area operation
*/
- draw->ext->image->blitImage(dri_context,
- back->linear_buffer,
- back->image,
- 0, 0, back->width,
- back->height,
- 0, 0, back->width,
- back->height, __BLIT_FLAG_FLUSH);
- /* We use blitImage to update our fake front,
- */
- if (draw->have_fake_front)
- draw->ext->image->blitImage(dri_context,
- dri3_fake_front_buffer(draw)->image,
- back->image,
- x, y, width, height,
- x, y, width, height, __BLIT_FLAG_FLUSH);
+ (void) loader_dri3_blit_image(draw,
+ back->linear_buffer,
+ back->image,
+ 0, 0, back->width, back->height,
+ 0, 0, __BLIT_FLAG_FLUSH);
}
+ loader_dri3_swapbuffer_barrier(draw);
dri3_fence_reset(draw->conn, back);
dri3_copy_area(draw->conn,
- dri3_back_buffer(draw)->pixmap,
+ back->pixmap,
draw->drawable,
dri3_drawable_gc(draw),
x, y, x, y, width, height);
@@ -514,17 +680,23 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
/* Refresh the fake front (if present) after we just damaged the real
* front.
*/
- if (draw->have_fake_front && !draw->is_different_gpu) {
+ if (draw->have_fake_front &&
+ !loader_dri3_blit_image(draw,
+ dri3_fake_front_buffer(draw)->image,
+ back->image,
+ x, y, width, height,
+ x, y, __BLIT_FLAG_FLUSH) &&
+ !draw->is_different_gpu) {
dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
dri3_copy_area(draw->conn,
- dri3_back_buffer(draw)->pixmap,
+ back->pixmap,
dri3_fake_front_buffer(draw)->pixmap,
dri3_drawable_gc(draw),
x, y, x, y, width, height);
dri3_fence_trigger(draw->conn, dri3_fake_front_buffer(draw));
- dri3_fence_await(draw->conn, dri3_fake_front_buffer(draw));
+ dri3_fence_await(draw->conn, NULL, dri3_fake_front_buffer(draw));
}
- dri3_fence_await(draw->conn, back);
+ dri3_fence_await(draw->conn, draw, back);
}
void
@@ -540,20 +712,18 @@ loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,
dri3_drawable_gc(draw),
0, 0, 0, 0, draw->width, draw->height);
dri3_fence_trigger(draw->conn, dri3_fake_front_buffer(draw));
- dri3_fence_await(draw->conn, dri3_fake_front_buffer(draw));
+ dri3_fence_await(draw->conn, draw, dri3_fake_front_buffer(draw));
}
void
loader_dri3_wait_x(struct loader_dri3_drawable *draw)
{
struct loader_dri3_buffer *front;
- __DRIcontext *dri_context;
if (draw == NULL || !draw->have_fake_front)
return;
front = dri3_fake_front_buffer(draw);
- dri_context = draw->vtable->get_dri_context(draw);
loader_dri3_copy_drawable(draw, front->pixmap, draw->drawable);
@@ -562,39 +732,34 @@ loader_dri3_wait_x(struct loader_dri3_drawable *draw)
* Copy back to the tiled buffer we use for rendering.
* Note that we don't need flushing.
*/
- if (draw->is_different_gpu && draw->vtable->in_current_context(draw))
- draw->ext->image->blitImage(dri_context,
- front->image,
- front->linear_buffer,
- 0, 0, front->width,
- front->height,
- 0, 0, front->width,
- front->height, 0);
+ if (draw->is_different_gpu)
+ (void) loader_dri3_blit_image(draw,
+ front->image,
+ front->linear_buffer,
+ 0, 0, front->width, front->height,
+ 0, 0, 0);
}
void
loader_dri3_wait_gl(struct loader_dri3_drawable *draw)
{
struct loader_dri3_buffer *front;
- __DRIcontext *dri_context;
if (draw == NULL || !draw->have_fake_front)
return;
front = dri3_fake_front_buffer(draw);
- dri_context = draw->vtable->get_dri_context(draw);
/* In the psc->is_different_gpu case, we update the linear_buffer
* before updating the real front.
*/
- if (draw->is_different_gpu && draw->vtable->in_current_context(draw))
- draw->ext->image->blitImage(dri_context,
- front->linear_buffer,
- front->image,
- 0, 0, front->width,
- front->height,
- 0, 0, front->width,
- front->height, __BLIT_FLAG_FLUSH);
+ if (draw->is_different_gpu)
+ (void) loader_dri3_blit_image(draw,
+ front->linear_buffer,
+ front->image,
+ 0, 0, front->width, front->height,
+ 0, 0, __BLIT_FLAG_FLUSH);
+ loader_dri3_swapbuffer_barrier(draw);
loader_dri3_copy_drawable(draw, draw->drawable, front->pixmap);
}
@@ -608,6 +773,9 @@ dri3_flush_present_events(struct loader_dri3_drawable *draw)
/* Check to see if any configuration changes have occurred
* since we were last invoked
*/
+ if (draw->has_event_waiter)
+ return;
+
if (draw->special_event) {
xcb_generic_event_t *ev;
@@ -630,34 +798,42 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
bool force_copy)
{
struct loader_dri3_buffer *back;
- __DRIcontext *dri_context;
int64_t ret = 0;
uint32_t options = XCB_PRESENT_OPTION_NONE;
- int swap_interval;
-
- dri_context = draw->vtable->get_dri_context(draw);
- swap_interval = draw->vtable->get_swap_interval(draw);
draw->vtable->flush_drawable(draw, flush_flags);
- back = draw->buffers[LOADER_DRI3_BACK_ID(draw->cur_back)];
+ back = dri3_find_back_alloc(draw);
+
+ mtx_lock(&draw->mtx);
if (draw->is_different_gpu && back) {
/* Update the linear buffer before presenting the pixmap */
- draw->ext->image->blitImage(dri_context,
- back->linear_buffer,
- back->image,
- 0, 0, back->width,
- back->height,
- 0, 0, back->width,
- back->height, __BLIT_FLAG_FLUSH);
- /* Update the fake front */
- if (draw->have_fake_front)
- draw->ext->image->blitImage(dri_context,
- draw->buffers[LOADER_DRI3_FRONT_ID]->image,
- back->image,
- 0, 0, draw->width, draw->height,
- 0, 0, draw->width, draw->height,
- __BLIT_FLAG_FLUSH);
+ (void) loader_dri3_blit_image(draw,
+ back->linear_buffer,
+ back->image,
+ 0, 0, back->width, back->height,
+ 0, 0, __BLIT_FLAG_FLUSH);
+ }
+
+ /* If we need to preload the new back buffer, remember the source.
+ * The force_copy parameter is used by EGL to attempt to preserve
+ * the back buffer across a call to this function.
+ */
+ if (draw->swap_method != __DRI_ATTRIB_SWAP_UNDEFINED || force_copy)
+ draw->cur_blit_source = LOADER_DRI3_BACK_ID(draw->cur_back);
+
+ /* Exchange the back and fake front. Even though the server knows about these
+ * buffers, it has no notion of back and fake front.
+ */
+ if (back && draw->have_fake_front) {
+ struct loader_dri3_buffer *tmp;
+
+ tmp = dri3_fake_front_buffer(draw);
+ draw->buffers[LOADER_DRI3_FRONT_ID] = back;
+ draw->buffers[LOADER_DRI3_BACK_ID(draw->cur_back)] = tmp;
+
+ if (draw->swap_method == __DRI_ATTRIB_SWAP_COPY || force_copy)
+ draw->cur_blit_source = LOADER_DRI3_FRONT_ID;
}
dri3_flush_present_events(draw);
@@ -672,7 +848,7 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
*/
++draw->send_sbc;
if (target_msc == 0 && divisor == 0 && remainder == 0)
- target_msc = draw->msc + swap_interval *
+ target_msc = draw->msc + draw->swap_interval *
(draw->send_sbc - draw->recv_sbc);
else if (divisor == 0 && remainder > 0) {
/* From the GLX_OML_sync_control spec:
@@ -696,10 +872,15 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
* behaviour by not using XCB_PRESENT_OPTION_ASYNC, but this should not be
* the default.
*/
- if (swap_interval == 0)
+ if (draw->swap_interval == 0)
options |= XCB_PRESENT_OPTION_ASYNC;
- if (force_copy)
- options |= XCB_PRESENT_OPTION_COPY;
+
+ /* If we need to populate the new back, but need to reuse the back
+ * buffer slot due to lack of local blit capabilities, make sure
+ * the server doesn't flip and we deadlock.
+ */
+ if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1)
+ options |= XCB_PRESENT_OPTION_COPY;
back->busy = 1;
back->last_swap = draw->send_sbc;
@@ -720,27 +901,33 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
remainder, 0, NULL);
ret = (int64_t) draw->send_sbc;
- /* If there's a fake front, then copy the source back buffer
- * to the fake front to keep it up to date. This needs
- * to reset the fence and make future users block until
- * the X server is done copying the bits
+ /* Schedule a server-side back-preserving blit if necessary.
+ * This happens iff all conditions below are satisfied:
+ * a) We have a fake front,
+ * b) We need to preserve the back buffer,
+ * c) We don't have local blit capabilities.
*/
- if (draw->have_fake_front && !draw->is_different_gpu) {
- dri3_fence_reset(draw->conn, draw->buffers[LOADER_DRI3_FRONT_ID]);
- dri3_copy_area(draw->conn,
- back->pixmap,
- draw->buffers[LOADER_DRI3_FRONT_ID]->pixmap,
+ if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1 &&
+ draw->cur_blit_source != LOADER_DRI3_BACK_ID(draw->cur_back)) {
+ struct loader_dri3_buffer *new_back = dri3_back_buffer(draw);
+ struct loader_dri3_buffer *src = draw->buffers[draw->cur_blit_source];
+
+ dri3_fence_reset(draw->conn, new_back);
+ dri3_copy_area(draw->conn, src->pixmap,
+ new_back->pixmap,
dri3_drawable_gc(draw),
- 0, 0, 0, 0,
- draw->width, draw->height);
- dri3_fence_trigger(draw->conn, draw->buffers[LOADER_DRI3_FRONT_ID]);
+ 0, 0, 0, 0, draw->width, draw->height);
+ dri3_fence_trigger(draw->conn, new_back);
+ new_back->last_swap = src->last_swap;
}
+
xcb_flush(draw->conn);
if (draw->stamp)
++(*draw->stamp);
}
+ mtx_unlock(&draw->mtx);
- (draw->ext->flush->invalidate)(draw->dri_drawable);
+ draw->ext->flush->invalidate(draw->dri_drawable);
return ret;
}
@@ -748,15 +935,15 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
int
loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw)
{
- int back_id = LOADER_DRI3_BACK_ID(dri3_find_back(draw));
+ struct loader_dri3_buffer *back = dri3_find_back_alloc(draw);
+ int ret;
- if (back_id < 0 || !draw->buffers[back_id])
- return 0;
+ mtx_lock(&draw->mtx);
+ ret = (!back || back->last_swap == 0) ? 0 :
+ draw->send_sbc - back->last_swap + 1;
+ mtx_unlock(&draw->mtx);
- if (draw->buffers[back_id]->last_swap != 0)
- return draw->send_sbc - draw->buffers[back_id]->last_swap + 1;
- else
- return 0;
+ return ret;
}
/** loader_dri3_open
@@ -814,6 +1001,27 @@ dri3_cpp_for_format(uint32_t format) {
}
}
+/* the DRIimage createImage function takes __DRI_IMAGE_FORMAT codes, while
+ * the createImageFromFds call takes __DRI_IMAGE_FOURCC codes. To avoid
+ * complete confusion, just deal in __DRI_IMAGE_FORMAT codes for now and
+ * translate to __DRI_IMAGE_FOURCC codes in the call to createImageFromFds
+ */
+static int
+image_format_to_fourcc(int format)
+{
+
+ /* Convert from __DRI_IMAGE_FORMAT to __DRI_IMAGE_FOURCC (sigh) */
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_SARGB8: return __DRI_IMAGE_FOURCC_SARGB8888;
+ case __DRI_IMAGE_FORMAT_RGB565: return __DRI_IMAGE_FOURCC_RGB565;
+ case __DRI_IMAGE_FORMAT_XRGB8888: return __DRI_IMAGE_FOURCC_XRGB8888;
+ case __DRI_IMAGE_FORMAT_ARGB8888: return __DRI_IMAGE_FOURCC_ARGB8888;
+ case __DRI_IMAGE_FORMAT_ABGR8888: return __DRI_IMAGE_FOURCC_ABGR8888;
+ case __DRI_IMAGE_FORMAT_XBGR8888: return __DRI_IMAGE_FOURCC_XBGR8888;
+ }
+ return 0;
+}
+
/** loader_dri3_alloc_render_buffer
*
* Use the driver createImage function to construct a __DRIimage, then
@@ -856,34 +1064,34 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
goto no_image;
if (!draw->is_different_gpu) {
- buffer->image = (draw->ext->image->createImage)(draw->dri_screen,
- width, height,
- format,
- __DRI_IMAGE_USE_SHARE |
- __DRI_IMAGE_USE_SCANOUT |
- __DRI_IMAGE_USE_BACKBUFFER,
- buffer);
+ buffer->image = draw->ext->image->createImage(draw->dri_screen,
+ width, height,
+ format,
+ __DRI_IMAGE_USE_SHARE |
+ __DRI_IMAGE_USE_SCANOUT |
+ __DRI_IMAGE_USE_BACKBUFFER,
+ buffer);
pixmap_buffer = buffer->image;
if (!buffer->image)
goto no_image;
} else {
- buffer->image = (draw->ext->image->createImage)(draw->dri_screen,
- width, height,
- format,
- 0,
- buffer);
+ buffer->image = draw->ext->image->createImage(draw->dri_screen,
+ width, height,
+ format,
+ 0,
+ buffer);
if (!buffer->image)
goto no_image;
buffer->linear_buffer =
- (draw->ext->image->createImage)(draw->dri_screen,
- width, height, format,
- __DRI_IMAGE_USE_SHARE |
- __DRI_IMAGE_USE_LINEAR |
- __DRI_IMAGE_USE_BACKBUFFER,
- buffer);
+ draw->ext->image->createImage(draw->dri_screen,
+ width, height, format,
+ __DRI_IMAGE_USE_SHARE |
+ __DRI_IMAGE_USE_LINEAR |
+ __DRI_IMAGE_USE_BACKBUFFER,
+ buffer);
pixmap_buffer = buffer->linear_buffer;
if (!buffer->linear_buffer)
@@ -892,14 +1100,14 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
/* X wants the stride, so ask the image for it
*/
- if (!(draw->ext->image->queryImage)(pixmap_buffer, __DRI_IMAGE_ATTRIB_STRIDE,
- &stride))
+ if (!draw->ext->image->queryImage(pixmap_buffer, __DRI_IMAGE_ATTRIB_STRIDE,
+ &stride))
goto no_buffer_attrib;
buffer->pitch = stride;
- if (!(draw->ext->image->queryImage)(pixmap_buffer, __DRI_IMAGE_ATTRIB_FD,
- &buffer_fd))
+ if (!draw->ext->image->queryImage(pixmap_buffer, __DRI_IMAGE_ATTRIB_FD,
+ &buffer_fd))
goto no_buffer_attrib;
xcb_dri3_pixmap_from_buffer(draw->conn,
@@ -930,10 +1138,10 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
return buffer;
no_buffer_attrib:
- (draw->ext->image->destroyImage)(pixmap_buffer);
+ draw->ext->image->destroyImage(pixmap_buffer);
no_linear_buffer:
if (draw->is_different_gpu)
- (draw->ext->image->destroyImage)(buffer->image);
+ draw->ext->image->destroyImage(buffer->image);
no_image:
free(buffer);
no_buffer:
@@ -953,6 +1161,7 @@ static int
dri3_update_drawable(__DRIdrawable *driDrawable,
struct loader_dri3_drawable *draw)
{
+ mtx_lock(&draw->mtx);
if (draw->first_init) {
xcb_get_geometry_cookie_t geom_cookie;
xcb_get_geometry_reply_t *geom_reply;
@@ -993,8 +1202,10 @@ dri3_update_drawable(__DRIdrawable *driDrawable,
geom_reply = xcb_get_geometry_reply(draw->conn, geom_cookie, NULL);
- if (!geom_reply)
+ if (!geom_reply) {
+ mtx_unlock(&draw->mtx);
return false;
+ }
draw->width = geom_reply->width;
draw->height = geom_reply->height;
@@ -1026,6 +1237,7 @@ dri3_update_drawable(__DRIdrawable *driDrawable,
if (error) {
if (error->error_code != BadWindow) {
free(error);
+ mtx_unlock(&draw->mtx);
return false;
}
draw->is_pixmap = true;
@@ -1034,30 +1246,10 @@ dri3_update_drawable(__DRIdrawable *driDrawable,
}
}
dri3_flush_present_events(draw);
+ mtx_unlock(&draw->mtx);
return true;
}
-/* the DRIimage createImage function takes __DRI_IMAGE_FORMAT codes, while
- * the createImageFromFds call takes __DRI_IMAGE_FOURCC codes. To avoid
- * complete confusion, just deal in __DRI_IMAGE_FORMAT codes for now and
- * translate to __DRI_IMAGE_FOURCC codes in the call to createImageFromFds
- */
-static int
-image_format_to_fourcc(int format)
-{
-
- /* Convert from __DRI_IMAGE_FORMAT to __DRI_IMAGE_FOURCC (sigh) */
- switch (format) {
- case __DRI_IMAGE_FORMAT_SARGB8: return __DRI_IMAGE_FOURCC_SARGB8888;
- case __DRI_IMAGE_FORMAT_RGB565: return __DRI_IMAGE_FOURCC_RGB565;
- case __DRI_IMAGE_FORMAT_XRGB8888: return __DRI_IMAGE_FOURCC_XRGB8888;
- case __DRI_IMAGE_FORMAT_ARGB8888: return __DRI_IMAGE_FOURCC_ARGB8888;
- case __DRI_IMAGE_FORMAT_ABGR8888: return __DRI_IMAGE_FOURCC_ABGR8888;
- case __DRI_IMAGE_FORMAT_XBGR8888: return __DRI_IMAGE_FOURCC_XBGR8888;
- }
- return 0;
-}
-
__DRIimage *
loader_dri3_create_image(xcb_connection_t *c,
xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
@@ -1082,19 +1274,19 @@ loader_dri3_create_image(xcb_connection_t *c,
* we've gotten the planar wrapper, pull the single plane out of it and
* discard the wrapper.
*/
- image_planar = (image->createImageFromFds)(dri_screen,
- bp_reply->width,
- bp_reply->height,
- image_format_to_fourcc(format),
- fds, 1,
- &stride, &offset, loaderPrivate);
+ image_planar = image->createImageFromFds(dri_screen,
+ bp_reply->width,
+ bp_reply->height,
+ image_format_to_fourcc(format),
+ fds, 1,
+ &stride, &offset, loaderPrivate);
close(fds[0]);
if (!image_planar)
return NULL;
- ret = (image->fromPlanar)(image_planar, 0, loaderPrivate);
+ ret = image->fromPlanar(image_planar, 0, loaderPrivate);
- (image->destroyImage)(image_planar);
+ image->destroyImage(image_planar);
return ret;
}
@@ -1152,7 +1344,7 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format,
* no contexts are currently bound. The latter case is at least necessary for
* obs-studio, when using Window Capture (Xcomposite) as a Source.
*/
- cur_screen = draw->vtable->get_dri_screen(draw);
+ cur_screen = draw->vtable->get_dri_screen();
if (!cur_screen) {
cur_screen = draw->dri_screen;
}
@@ -1167,7 +1359,6 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format,
buffer->own_pixmap = false;
buffer->width = bp_reply->width;
buffer->height = bp_reply->height;
- buffer->buffer_type = buffer_type;
buffer->shm_fence = shm_fence;
buffer->sync_fence = sync_fence;
@@ -1199,11 +1390,10 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
{
struct loader_dri3_buffer *buffer;
int buf_id;
- __DRIcontext *dri_context;
-
- dri_context = draw->vtable->get_dri_context(draw);
if (buffer_type == loader_dri3_buffer_back) {
+ draw->back_format = format;
+
buf_id = dri3_find_back(draw);
if (buf_id < 0)
@@ -1234,30 +1424,31 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
/* When resizing, copy the contents of the old buffer, waiting for that
* copy to complete using our fences before proceeding
*/
- switch (buffer_type) {
- case loader_dri3_buffer_back:
- if (buffer) {
- if (!buffer->linear_buffer) {
- dri3_fence_reset(draw->conn, new_buffer);
- dri3_fence_await(draw->conn, buffer);
- dri3_copy_area(draw->conn,
- buffer->pixmap,
- new_buffer->pixmap,
- dri3_drawable_gc(draw),
- 0, 0, 0, 0,
- draw->width, draw->height);
- dri3_fence_trigger(draw->conn, new_buffer);
- } else if (draw->vtable->in_current_context(draw)) {
- draw->ext->image->blitImage(dri_context,
- new_buffer->image,
- buffer->image,
- 0, 0, draw->width, draw->height,
- 0, 0, draw->width, draw->height, 0);
- }
- dri3_free_render_buffer(draw, buffer);
+ if ((buffer_type == loader_dri3_buffer_back ||
+ (buffer_type == loader_dri3_buffer_front && draw->have_fake_front))
+ && buffer) {
+
+ /* Fill the new buffer with data from an old buffer */
+ dri3_fence_await(draw->conn, draw, buffer);
+ if (!loader_dri3_blit_image(draw,
+ new_buffer->image,
+ buffer->image,
+ 0, 0, draw->width, draw->height,
+ 0, 0, 0) &&
+ !buffer->linear_buffer) {
+ dri3_fence_reset(draw->conn, new_buffer);
+ dri3_copy_area(draw->conn,
+ buffer->pixmap,
+ new_buffer->pixmap,
+ dri3_drawable_gc(draw),
+ 0, 0, 0, 0,
+ draw->width, draw->height);
+ dri3_fence_trigger(draw->conn, new_buffer);
}
- break;
- case loader_dri3_buffer_front:
+ dri3_free_render_buffer(draw, buffer);
+ } else if (buffer_type == loader_dri3_buffer_front) {
+ /* Fill the new fake front with data from a real front */
+ loader_dri3_swapbuffer_barrier(draw);
dri3_fence_reset(draw->conn, new_buffer);
dri3_copy_area(draw->conn,
draw->drawable,
@@ -1267,23 +1458,45 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
draw->width, draw->height);
dri3_fence_trigger(draw->conn, new_buffer);
- if (new_buffer->linear_buffer &&
- draw->vtable->in_current_context(draw)) {
- dri3_fence_await(draw->conn, new_buffer);
- draw->ext->image->blitImage(dri_context,
- new_buffer->image,
- new_buffer->linear_buffer,
- 0, 0, draw->width, draw->height,
- 0, 0, draw->width, draw->height, 0);
+ if (new_buffer->linear_buffer) {
+ dri3_fence_await(draw->conn, draw, new_buffer);
+ (void) loader_dri3_blit_image(draw,
+ new_buffer->image,
+ new_buffer->linear_buffer,
+ 0, 0, draw->width, draw->height,
+ 0, 0, 0);
}
- break;
}
buffer = new_buffer;
- buffer->buffer_type = buffer_type;
draw->buffers[buf_id] = buffer;
}
- dri3_fence_await(draw->conn, buffer);
+ dri3_fence_await(draw->conn, draw, buffer);
+ /*
+ * Do we need to preserve the content of a previous buffer?
+ *
+ * Note that this blit is needed only to avoid a wait for a buffer that
+ * is currently in the flip chain or being scanned out from. That's really
+ * a tradeoff. If we're ok with the wait we can reduce the number of back
+ * buffers to 1 for SWAP_EXCHANGE, and 1 for SWAP_COPY,
+ * but in the latter case we must disallow page-flipping.
+ */
+ if (buffer_type == loader_dri3_buffer_back &&
+ draw->cur_blit_source != -1 &&
+ draw->buffers[draw->cur_blit_source] &&
+ buffer != draw->buffers[draw->cur_blit_source]) {
+
+ struct loader_dri3_buffer *source = draw->buffers[draw->cur_blit_source];
+
+ /* Avoid flushing here. Will propably do good for tiling hardware. */
+ (void) loader_dri3_blit_image(draw,
+ buffer->image,
+ source->image,
+ 0, 0, draw->width, draw->height,
+ 0, 0, 0);
+ buffer->last_swap = source->last_swap;
+ draw->cur_blit_source = -1;
+ }
/* Return the requested buffer */
return buffer;
}
@@ -1307,10 +1520,12 @@ dri3_free_buffers(__DRIdrawable *driDrawable,
case loader_dri3_buffer_back:
first_id = LOADER_DRI3_BACK_ID(0);
n_id = LOADER_DRI3_MAX_BACK;
+ draw->cur_blit_source = -1;
break;
case loader_dri3_buffer_front:
first_id = LOADER_DRI3_FRONT_ID;
- n_id = 1;
+ /* Don't free a fake front holding new backbuffer content. */
+ n_id = (draw->cur_blit_source == LOADER_DRI3_FRONT_ID) ? 0 : 1;
}
for (buf_id = first_id; buf_id < first_id + n_id; buf_id++) {
@@ -1349,8 +1564,10 @@ loader_dri3_get_buffers(__DRIdrawable *driDrawable,
if (!dri3_update_drawable(driDrawable, draw))
return false;
- /* pixmaps always have front buffers */
- if (draw->is_pixmap)
+ /* pixmaps always have front buffers.
+ * Exchange swaps also mandate fake front buffers.
+ */
+ if (draw->is_pixmap || draw->swap_method == __DRI_ATTRIB_SWAP_EXCHANGE)
buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
@@ -1427,7 +1644,93 @@ loader_dri3_update_drawable_geometry(struct loader_dri3_drawable *draw)
draw->width = geom_reply->width;
draw->height = geom_reply->height;
draw->vtable->set_drawable_size(draw, draw->width, draw->height);
+ draw->ext->flush->invalidate(draw->dri_drawable);
free(geom_reply);
}
}
+
+
+/**
+ * Make sure the server has flushed all pending swap buffers to hardware
+ * for this drawable. Ideally we'd want to send an X protocol request to
+ * have the server block our connection until the swaps are complete. That
+ * would avoid the potential round-trip here.
+ */
+void
+loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw)
+{
+ int64_t ust, msc, sbc;
+
+ (void) loader_dri3_wait_for_sbc(draw, 0, &ust, &msc, &sbc);
+}
+
+/**
+ * Perform any cleanup associated with a close screen operation.
+ * \param dri_screen[in,out] Pointer to __DRIscreen about to be closed.
+ *
+ * This function destroys the screen's cached swap context if any.
+ */
+void
+loader_dri3_close_screen(__DRIscreen *dri_screen)
+{
+ mtx_lock(&blit_context.mtx);
+ if (blit_context.ctx && blit_context.cur_screen == dri_screen) {
+ blit_context.core->destroyContext(blit_context.ctx);
+ blit_context.ctx = NULL;
+ }
+ mtx_unlock(&blit_context.mtx);
+}
+
+/**
+ * Find a backbuffer slot - potentially allocating a back buffer
+ *
+ * \param draw[in,out] Pointer to the drawable for which to find back.
+ * \return Pointer to a new back buffer or NULL if allocation failed or was
+ * not mandated.
+ *
+ * Find a potentially new back buffer, and if it's not been allocated yet and
+ * in addition needs initializing, then try to allocate and initialize it.
+ */
+#include <stdio.h>
+static struct loader_dri3_buffer *
+dri3_find_back_alloc(struct loader_dri3_drawable *draw)
+{
+ struct loader_dri3_buffer *back;
+ int id;
+
+ id = dri3_find_back(draw);
+ if (id < 0)
+ return NULL;
+
+ back = draw->buffers[id];
+ /* Allocate a new back if we haven't got one */
+ if (!back && draw->back_format != __DRI_IMAGE_FORMAT_NONE &&
+ dri3_update_drawable(draw->dri_drawable, draw))
+ back = dri3_alloc_render_buffer(draw, draw->back_format,
+ draw->width, draw->height, draw->depth);
+
+ if (!back)
+ return NULL;
+
+ draw->buffers[id] = back;
+
+ /* If necessary, prefill the back with data according to swap_method mode. */
+ if (draw->cur_blit_source != -1 &&
+ draw->buffers[draw->cur_blit_source] &&
+ back != draw->buffers[draw->cur_blit_source]) {
+ struct loader_dri3_buffer *source = draw->buffers[draw->cur_blit_source];
+
+ dri3_fence_await(draw->conn, draw, source);
+ dri3_fence_await(draw->conn, draw, back);
+ (void) loader_dri3_blit_image(draw,
+ back->image,
+ source->image,
+ 0, 0, draw->width, draw->height,
+ 0, 0, 0);
+ back->last_swap = source->last_swap;
+ draw->cur_blit_source = -1;
+ }
+
+ return back;
+}
diff --git a/lib/mesa/src/loader/loader_dri3_helper.h b/lib/mesa/src/loader/loader_dri3_helper.h
index a865e4635..790f78427 100644
--- a/lib/mesa/src/loader/loader_dri3_helper.h
+++ b/lib/mesa/src/loader/loader_dri3_helper.h
@@ -33,6 +33,7 @@
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
+#include <c11/threads.h>
enum loader_dri3_buffer_type {
loader_dri3_buffer_back = 0,
@@ -67,8 +68,6 @@ struct loader_dri3_buffer {
uint32_t flags;
uint32_t width, height;
uint64_t last_swap;
-
- enum loader_dri3_buffer_type buffer_type;
};
@@ -97,13 +96,10 @@ struct loader_dri3_extensions {
struct loader_dri3_drawable;
struct loader_dri3_vtable {
- int (*get_swap_interval)(struct loader_dri3_drawable *);
- int (*clamp_swap_interval)(struct loader_dri3_drawable *, int);
- void (*set_swap_interval)(struct loader_dri3_drawable *, int);
void (*set_drawable_size)(struct loader_dri3_drawable *, int, int);
bool (*in_current_context)(struct loader_dri3_drawable *);
__DRIcontext *(*get_dri_context)(struct loader_dri3_drawable *);
- __DRIscreen *(*get_dri_screen)(struct loader_dri3_drawable *);
+ __DRIscreen *(*get_dri_screen)(void);
void (*flush_drawable)(struct loader_dri3_drawable *, unsigned);
void (*show_fps)(struct loader_dri3_drawable *, uint64_t);
};
@@ -149,6 +145,7 @@ struct loader_dri3_drawable {
struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS];
int cur_back;
int num_back;
+ int cur_blit_source;
uint32_t *stamp;
@@ -157,9 +154,22 @@ struct loader_dri3_drawable {
xcb_special_event_t *special_event;
bool first_init;
+ int swap_interval;
struct loader_dri3_extensions *ext;
const struct loader_dri3_vtable *vtable;
+
+ unsigned int swap_method;
+ unsigned int back_format;
+
+ /* Currently protects the following fields:
+ * event_cnd, has_event_waiter,
+ * recv_sbc, ust, msc, recv_msc_serial,
+ * notify_ust, notify_msc
+ */
+ mtx_t mtx;
+ cnd_t event_cnd;
+ bool has_event_waiter;
};
void
@@ -241,4 +251,10 @@ loader_dri3_get_buffers(__DRIdrawable *driDrawable,
void
loader_dri3_update_drawable_geometry(struct loader_dri3_drawable *draw);
+
+void
+loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw);
+
+void
+loader_dri3_close_screen(__DRIscreen *dri_screen);
#endif