--- /dev/null
+/*
+ * Copyright © 2022 Google LLC
+ *
+ * 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 (including the next
+ * paragraph) 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 MESA_INTERFACE_H
+#define MESA_INTERFACE_H
+
+#include "dri_interface.h"
+
+/* Mesa-internal interface between the GLX, GBM, and EGL DRI driver loaders, and
+ * the gallium dri_util.c code.
+ */
+
+typedef struct __DRImesaCoreExtensionRec __DRImesaCoreExtension;
+
+#define __DRI_MESA "DRI_Mesa"
+#define __DRI_MESA_VERSION 1
+
+/** Core struct that appears alongside __DRI_CORE for Mesa-internal usage.
+ * Implemented in the top-level dri/drisw/kopper extension list.
+ */
+struct __DRImesaCoreExtensionRec {
+ __DRIextension base;
+
+ /* Version string for verifying that the DRI driver is from the same build as
+ * the loader.
+ */
+#define MESA_INTERFACE_VERSION_STRING PACKAGE_VERSION MESA_GIT_SHA1
+ const char *version_string;
+};
+
+#endif /* MESA_INTERFACE_H */
static const struct dri_extension_match dri3_driver_extensions[] = {
{ __DRI_CORE, 1, offsetof(struct dri2_egl_display, core), false },
+ { __DRI_MESA, 1, offsetof(struct dri2_egl_display, mesa), false },
{ __DRI_IMAGE_DRIVER, 1, offsetof(struct dri2_egl_display, image_driver), false },
{ __DRI_CONFIG_OPTIONS, 2, offsetof(struct dri2_egl_display, configOptions), true },
};
static const struct dri_extension_match dri2_driver_extensions[] = {
{ __DRI_CORE, 1, offsetof(struct dri2_egl_display, core), false },
+ { __DRI_MESA, 1, offsetof(struct dri2_egl_display, mesa), false },
{ __DRI_DRI2, 4, offsetof(struct dri2_egl_display, dri2), false },
{ __DRI_CONFIG_OPTIONS, 2, offsetof(struct dri2_egl_display, configOptions), true },
};
static const struct dri_extension_match swrast_driver_extensions[] = {
{ __DRI_CORE, 1, offsetof(struct dri2_egl_display, core), false },
+ { __DRI_MESA, 1, offsetof(struct dri2_egl_display, mesa), false },
{ __DRI_SWRAST, 4, offsetof(struct dri2_egl_display, swrast), false },
{ __DRI_CONFIG_OPTIONS, 2, offsetof(struct dri2_egl_display, configOptions), true },
};
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
+#include <GL/internal/mesa_interface.h>
#include "kopper_interface.h"
#ifdef HAVE_DRM_PLATFORM
const __DRIconfig **driver_configs;
void *driver;
const __DRIcoreExtension *core;
+ const __DRImesaCoreExtension *mesa;
const __DRIimageDriverExtension *image_driver;
const __DRIdri2Extension *dri2;
const __DRIswrastExtension *swrast;
'drivers/dri2/egl_dri2.c',
'drivers/dri2/egl_dri2.h',
)
+ files_egl += sha1_h
deps_for_egl += idep_xmlconfig
link_for_egl += libloader
incs_for_egl += inc_loader
*/
#include <xf86drm.h>
+#include "git_sha1.h"
#include "GL/mesa_glinterop.h"
+#include "GL/internal/mesa_interface.h"
#include "util/disk_cache.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
.InitScreen = dri2_init_screen,
};
+static const struct __DRImesaCoreExtensionRec mesaCoreExtension = {
+ .base = { __DRI_MESA, 1 },
+ .version_string = MESA_INTERFACE_VERSION_STRING,
+};
+
/* This is the table of extensions that the loader will dlsym() for. */
const __DRIextension *galliumdrm_driver_extensions[] = {
&driCoreExtension.base,
+ &mesaCoreExtension.base,
&driImageDriverExtension.base,
&driDRI2Extension.base,
&gallium_config_options.base,
const __DRIextension *dri_swrast_kms_driver_extensions[] = {
&driCoreExtension.base,
+ &mesaCoreExtension.base,
&driImageDriverExtension.base,
&swkmsDRI2Extension.base,
&gallium_config_options.base,
*
**************************************************************************/
+#include "GL/internal/mesa_interface.h"
+#include "git_sha1.h"
#include "util/format/u_format.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
.copySubBuffer = driswCopySubBuffer,
};
+static const struct __DRImesaCoreExtensionRec mesaCoreExtension = {
+ .base = { __DRI_MESA, 1 },
+ .version_string = MESA_INTERFACE_VERSION_STRING,
+};
+
/* This is the table of extensions that the loader will dlsym() for. */
const __DRIextension *galliumsw_driver_extensions[] = {
&driCoreExtension.base,
+ &mesaCoreExtension.base,
&driSWRastExtension.base,
&driSWCopySubBufferExtension.base,
&gallium_config_options.base,
* DEALINGS IN THE SOFTWARE.
*/
+#include "GL/internal/mesa_interface.h"
+#include "git_sha1.h"
#include "util/format/u_format.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
.InitScreen = kopper_init_screen,
};
+static const struct __DRImesaCoreExtensionRec mesaCoreExtension = {
+ .base = { __DRI_MESA, 1 },
+ .version_string = MESA_INTERFACE_VERSION_STRING,
+};
+
const __DRIextension *galliumvk_driver_extensions[] = {
&driCoreExtension.base,
+ &mesaCoreExtension.base,
&driSWRastExtension.base,
&driDRI2Extension.base,
&driImageDriverExtension.base,
libdri = static_library(
'dri',
- files_libdri,
+ [ files_libdri, sha1_h ],
include_directories : [
inc_include, inc_util, inc_mesa, inc_mapi, inc_src, inc_gallium,
inc_gallium_aux, inc_util, inc_gallium_drivers,
static struct dri_extension_match gbm_dri_device_extensions[] = {
{ __DRI_CORE, 1, offsetof(struct gbm_dri_device, core), false },
+ { __DRI_MESA, 1, offsetof(struct gbm_dri_device, mesa), false },
{ __DRI_DRI2, 4, offsetof(struct gbm_dri_device, dri2), false },
};
static struct dri_extension_match gbm_swrast_device_extensions[] = {
{ __DRI_CORE, 1, offsetof(struct gbm_dri_device, core), false },
+ { __DRI_MESA, 1, offsetof(struct gbm_dri_device, mesa), false },
{ __DRI_SWRAST, 4, offsetof(struct gbm_dri_device, swrast), false },
{ __DRI_KOPPER, 1, offsetof(struct gbm_dri_device, kopper), true },
};
#include <GL/gl.h> /* dri_interface needs GL types */
#include "GL/internal/dri_interface.h"
+#include "GL/internal/mesa_interface.h"
#include "kopper_interface.h"
struct gbm_dri_surface;
mtx_t mutex;
const __DRIcoreExtension *core;
+ const __DRImesaCoreExtension *mesa;
const __DRIdri2Extension *dri2;
const __DRI2fenceExtension *fence;
const __DRIimageExtension *image;
static const struct dri_extension_match exts[] = {
{ __DRI_CORE, 1, offsetof(struct dri2_screen, core), false },
{ __DRI_DRI2, 4, offsetof(struct dri2_screen, dri2), false },
+ { __DRI_MESA, 1, offsetof(struct dri2_screen, mesa), false },
};
if (!loader_bind_extensions(psc, exts, ARRAY_SIZE(exts), extensions))
goto handle_error;
extern "C" {
#endif
+#include "GL/internal/mesa_interface.h"
+
struct dri2_screen {
struct glx_screen base;
__GLXDRIscreen vtable;
const __DRIdri2Extension *dri2;
const __DRIcoreExtension *core;
+ const __DRImesaCoreExtension *mesa;
const __DRI2flushExtension *f;
const __DRI2configQueryExtension *config;
static const struct dri_extension_match exts[] = {
{ __DRI_CORE, 1, offsetof(struct dri3_screen, core), false },
{ __DRI_IMAGE_DRIVER, 1, offsetof(struct dri3_screen, image_driver), false },
+ { __DRI_MESA, 1, offsetof(struct dri3_screen, mesa), false },
};
if (!loader_bind_extensions(psc, exts, ARRAY_SIZE(exts), extensions))
goto handle_error;
#include <xcb/sync.h>
#include "loader_dri3_helper.h"
+#include "GL/internal/mesa_interface.h"
struct dri3_display
{
const __DRIimageExtension *image;
const __DRIimageDriverExtension *image_driver;
const __DRIcoreExtension *core;
+ const __DRImesaCoreExtension *mesa;
const __DRI2flushExtension *f;
const __DRI2configQueryExtension *config;
const __DRItexBufferExtension *texBuffer;
{ __DRI_SWRAST, 4, offsetof(struct drisw_screen, swrast), false },
{ __DRI_KOPPER, 1, offsetof(struct drisw_screen, kopper), true },
{ __DRI_COPY_SUB_BUFFER, 1, offsetof(struct drisw_screen, copySubBuffer), true },
+ { __DRI_MESA, 1, offsetof(struct drisw_screen, mesa), false },
};
if (!loader_bind_extensions(psc, exts, ARRAY_SIZE(exts), extensions))
goto handle_error;
#include <X11/extensions/XShm.h>
#include "kopper_interface.h"
+#include "GL/internal/mesa_interface.h"
struct drisw_display
{
__DRIscreen *driScreen;
__GLXDRIscreen vtable;
const __DRIcoreExtension *core;
+ const __DRImesaCoreExtension *mesa;
const __DRIswrastExtension *swrast;
const __DRIkopperExtension *kopper;
const __DRI2flushExtension *f;
#endif
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
+#include <GL/internal/mesa_interface.h>
#include "loader.h"
#include "util/os_file.h"
#include "util/os_misc.h"
+#include "git_sha1.h"
#ifdef HAVE_LIBDRM
#include <xf86drm.h>
if (!match->optional)
ret = false;
}
+
+ /* The loaders rely on the loaded DRI drivers being from the same Mesa
+ * build so that we can reference the same structs on both sides.
+ */
+ if (strcmp(match->name, __DRI_MESA) == 0) {
+ const __DRImesaCoreExtension *mesa = (const __DRImesaCoreExtension *)*field;
+ if (strcmp(mesa->version_string, MESA_INTERFACE_VERSION_STRING) != 0) {
+ log_(_LOADER_FATAL, "DRI driver not from this Mesa build ('%s' vs '%s')\n",
+ mesa->version_string, MESA_INTERFACE_VERSION_STRING);
+ ret = false;
+ }
+ }
}
return ret;
]
libloader = static_library(
'loader',
- ['loader_dri_helper.c', 'loader.c'],
+ ['loader_dri_helper.c', 'loader.c', sha1_h],
c_args : loader_c_args,
gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src, inc_util],