2012-03-16 15:39:01 +00:00
|
|
|
/*
|
|
|
|
* (C) Copyright IBM Corporation 2002, 2004
|
|
|
|
* 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
|
|
|
|
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
|
|
|
* license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS AND/OR THEIR SUPPLIERS 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.
|
|
|
|
*/
|
|
|
|
|
2004-04-14 13:39:58 +01:00
|
|
|
/**
|
|
|
|
* \file dri_util.c
|
|
|
|
* DRI utility functions.
|
|
|
|
*
|
|
|
|
* This module acts as glue between GLX and the actual hardware driver. A DRI
|
|
|
|
* driver doesn't really \e have to use any of this - it's optional. But, some
|
|
|
|
* useful stuff is done here that otherwise would have to be duplicated in most
|
|
|
|
* drivers.
|
2022-07-28 09:11:04 +01:00
|
|
|
*
|
2004-04-14 13:39:58 +01:00
|
|
|
* Basically, these utility functions take care of some of the dirty details of
|
|
|
|
* screen initialization, context creation, context binding, DRM setup, etc.
|
|
|
|
*
|
|
|
|
* These functions are compiled into each DRI driver so libGL.so knows nothing
|
|
|
|
* about them.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
dri: Move API version validation into dri/common.
i965, i915, radeon, r200, swrast, and nouveau were mostly trying to do the
same logic, except where they failed to. Notably, swrast had code that
appeared to try to enable GLES1/2 but forgot to set api_mask (thus
preventing any gles context from being created), and the non-intel drivers
didn't support MESA_GL_VERSION_OVERRIDE.
nouveau still relies on _mesa_compute_version(), because I don't know what
its limits actually are, and gallium drivers don't declare limits up front
at all. I think I've heard talk about doing so, though.
v2: Compat max version should be 30 (noted by Ken)
Drop r100's custom max version check, too (noted by Emil Velikov)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-09-26 20:01:56 +01:00
|
|
|
#include <stdbool.h>
|
2004-06-07 22:23:12 +01:00
|
|
|
#include "dri_util.h"
|
2022-03-29 18:36:37 +01:00
|
|
|
#include "dri_context.h"
|
2022-03-30 15:11:04 +01:00
|
|
|
#include "dri_screen.h"
|
2019-08-29 23:45:18 +01:00
|
|
|
#include "util/u_endian.h"
|
2020-06-12 10:42:32 +01:00
|
|
|
#include "util/driconf.h"
|
2015-09-27 20:28:22 +01:00
|
|
|
#include "main/framebuffer.h"
|
dri: Move API version validation into dri/common.
i965, i915, radeon, r200, swrast, and nouveau were mostly trying to do the
same logic, except where they failed to. Notably, swrast had code that
appeared to try to enable GLES1/2 but forgot to set api_mask (thus
preventing any gles context from being created), and the non-intel drivers
didn't support MESA_GL_VERSION_OVERRIDE.
nouveau still relies on _mesa_compute_version(), because I don't know what
its limits actually are, and gallium drivers don't declare limits up front
at all. I think I've heard talk about doing so, though.
v2: Compat max version should be 30 (noted by Ken)
Drop r100's custom max version check, too (noted by Emil Velikov)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-09-26 20:01:56 +01:00
|
|
|
#include "main/version.h"
|
2016-02-08 17:52:02 +00:00
|
|
|
#include "main/debug_output.h"
|
2014-02-07 01:21:58 +00:00
|
|
|
#include "main/errors.h"
|
2010-04-22 20:49:03 +01:00
|
|
|
|
2020-09-25 20:56:22 +01:00
|
|
|
driOptionDescription __dri2ConfigOptions[] = {
|
2020-10-15 16:29:45 +01:00
|
|
|
DRI_CONF_SECTION_DEBUG
|
|
|
|
DRI_CONF_GLX_EXTENSION_OVERRIDE()
|
2020-10-20 14:20:20 +01:00
|
|
|
DRI_CONF_INDIRECT_GL_EXTENSION_OVERRIDE()
|
2020-10-15 16:29:45 +01:00
|
|
|
DRI_CONF_SECTION_END
|
|
|
|
|
2010-04-22 20:49:03 +01:00
|
|
|
DRI_CONF_SECTION_PERFORMANCE
|
|
|
|
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
|
|
|
|
DRI_CONF_SECTION_END
|
2020-09-25 20:56:22 +01:00
|
|
|
};
|
2010-04-22 20:49:03 +01:00
|
|
|
|
2011-11-04 14:14:58 +00:00
|
|
|
/*****************************************************************/
|
|
|
|
/** \name Screen handling functions */
|
|
|
|
/*****************************************************************/
|
|
|
|
/*@{*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
setupLoaderExtensions(__DRIscreen *psp,
|
|
|
|
const __DRIextension **extensions)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; extensions[i]; i++) {
|
|
|
|
if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
|
|
|
|
psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
|
|
|
|
if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
|
|
|
|
psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
|
|
|
|
if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0)
|
|
|
|
psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i];
|
2012-11-14 22:39:21 +00:00
|
|
|
if (strcmp(extensions[i]->name, __DRI_BACKGROUND_CALLABLE) == 0)
|
|
|
|
psp->dri2.backgroundCallable = (__DRIbackgroundCallableExtension *) extensions[i];
|
2013-09-26 19:35:31 +01:00
|
|
|
if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
|
|
|
|
psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
|
2013-11-05 02:09:51 +00:00
|
|
|
if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0)
|
|
|
|
psp->image.loader = (__DRIimageLoaderExtension *) extensions[i];
|
2018-03-31 09:16:14 +01:00
|
|
|
if (strcmp(extensions[i]->name, __DRI_MUTABLE_RENDER_BUFFER_LOADER) == 0)
|
|
|
|
psp->mutableRenderBuffer.loader = (__DRImutableRenderBufferLoaderExtension *) extensions[i];
|
2022-03-15 19:36:28 +00:00
|
|
|
if (strcmp(extensions[i]->name, __DRI_KOPPER_LOADER) == 0)
|
|
|
|
psp->kopper_loader = (__DRIkopperLoaderExtension *) extensions[i];
|
2011-11-04 14:14:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-26 18:33:12 +01:00
|
|
|
/**
|
|
|
|
* This is the first entrypoint in the driver called by the DRI driver loader
|
|
|
|
* after dlopen()ing it.
|
|
|
|
*
|
|
|
|
* It's used to create global state for the driver across contexts on the same
|
|
|
|
* Display.
|
|
|
|
*/
|
2011-11-04 14:14:58 +00:00
|
|
|
static __DRIscreen *
|
2013-06-04 04:49:25 +01:00
|
|
|
driCreateNewScreen2(int scrn, int fd,
|
|
|
|
const __DRIextension **extensions,
|
|
|
|
const __DRIextension **driver_extensions,
|
|
|
|
const __DRIconfig ***driver_configs, void *data)
|
2011-11-04 14:14:58 +00:00
|
|
|
{
|
|
|
|
static const __DRIextension *emptyExtensionList[] = { NULL };
|
|
|
|
__DRIscreen *psp;
|
|
|
|
|
|
|
|
psp = calloc(1, sizeof(*psp));
|
|
|
|
if (!psp)
|
|
|
|
return NULL;
|
|
|
|
|
2022-03-30 15:19:56 +01:00
|
|
|
assert(driver_extensions);
|
|
|
|
for (int i = 0; driver_extensions[i]; i++) {
|
|
|
|
if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) {
|
|
|
|
psp->driver =
|
|
|
|
((__DRIDriverVtableExtension *)driver_extensions[i])->vtable;
|
2013-09-26 18:51:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-04 14:14:58 +00:00
|
|
|
setupLoaderExtensions(psp, extensions);
|
2021-06-02 19:40:33 +01:00
|
|
|
// dri2 drivers require working invalidate
|
2022-05-24 00:50:20 +01:00
|
|
|
if (fd != -1 && !psp->dri2.useInvalidate) {
|
|
|
|
free(psp);
|
2021-06-02 19:40:33 +01:00
|
|
|
return NULL;
|
2022-05-24 00:50:20 +01:00
|
|
|
}
|
2011-11-04 14:14:58 +00:00
|
|
|
|
2011-11-04 14:35:49 +00:00
|
|
|
psp->loaderPrivate = data;
|
|
|
|
|
2011-11-04 14:14:58 +00:00
|
|
|
psp->extensions = emptyExtensionList;
|
|
|
|
psp->fd = fd;
|
|
|
|
psp->myNum = scrn;
|
|
|
|
|
2017-12-15 22:04:54 +00:00
|
|
|
/* Option parsing before ->InitScreen(), as some options apply there. */
|
2020-09-25 20:56:22 +01:00
|
|
|
driParseOptionInfo(&psp->optionInfo,
|
|
|
|
__dri2ConfigOptions, ARRAY_SIZE(__dri2ConfigOptions));
|
2019-09-08 10:59:32 +01:00
|
|
|
driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum,
|
2021-07-29 02:17:42 +01:00
|
|
|
"dri2", NULL, NULL, NULL, 0, NULL, 0);
|
2017-12-15 22:04:54 +00:00
|
|
|
|
2013-09-26 18:51:29 +01:00
|
|
|
*driver_configs = psp->driver->InitScreen(psp);
|
2011-11-04 14:14:58 +00:00
|
|
|
if (*driver_configs == NULL) {
|
|
|
|
free(psp);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-05-26 20:14:39 +01:00
|
|
|
struct gl_constants consts = { 0 };
|
|
|
|
gl_api api;
|
2015-05-29 18:28:58 +01:00
|
|
|
unsigned version;
|
2015-05-26 20:14:39 +01:00
|
|
|
|
2015-04-30 00:12:40 +01:00
|
|
|
api = API_OPENGLES2;
|
|
|
|
if (_mesa_override_gl_version_contextless(&consts, &api, &version))
|
|
|
|
psp->max_gl_es2_version = version;
|
|
|
|
|
2015-05-26 20:14:39 +01:00
|
|
|
api = API_OPENGL_COMPAT;
|
|
|
|
if (_mesa_override_gl_version_contextless(&consts, &api, &version)) {
|
2018-03-02 13:25:32 +00:00
|
|
|
psp->max_gl_core_version = version;
|
|
|
|
if (api == API_OPENGL_COMPAT)
|
2015-05-26 20:14:39 +01:00
|
|
|
psp->max_gl_compat_version = version;
|
dri: Move API version validation into dri/common.
i965, i915, radeon, r200, swrast, and nouveau were mostly trying to do the
same logic, except where they failed to. Notably, swrast had code that
appeared to try to enable GLES1/2 but forgot to set api_mask (thus
preventing any gles context from being created), and the non-intel drivers
didn't support MESA_GL_VERSION_OVERRIDE.
nouveau still relies on _mesa_compute_version(), because I don't know what
its limits actually are, and gallium drivers don't declare limits up front
at all. I think I've heard talk about doing so, though.
v2: Compat max version should be 30 (noted by Ken)
Drop r100's custom max version check, too (noted by Emil Velikov)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-09-26 20:01:56 +01:00
|
|
|
}
|
|
|
|
|
2015-07-31 09:11:47 +01:00
|
|
|
psp->api_mask = 0;
|
|
|
|
if (psp->max_gl_compat_version > 0)
|
|
|
|
psp->api_mask |= (1 << __DRI_API_OPENGL);
|
dri: Move API version validation into dri/common.
i965, i915, radeon, r200, swrast, and nouveau were mostly trying to do the
same logic, except where they failed to. Notably, swrast had code that
appeared to try to enable GLES1/2 but forgot to set api_mask (thus
preventing any gles context from being created), and the non-intel drivers
didn't support MESA_GL_VERSION_OVERRIDE.
nouveau still relies on _mesa_compute_version(), because I don't know what
its limits actually are, and gallium drivers don't declare limits up front
at all. I think I've heard talk about doing so, though.
v2: Compat max version should be 30 (noted by Ken)
Drop r100's custom max version check, too (noted by Emil Velikov)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-09-26 20:01:56 +01:00
|
|
|
if (psp->max_gl_core_version > 0)
|
|
|
|
psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
|
|
|
|
if (psp->max_gl_es1_version > 0)
|
|
|
|
psp->api_mask |= (1 << __DRI_API_GLES);
|
|
|
|
if (psp->max_gl_es2_version > 0)
|
|
|
|
psp->api_mask |= (1 << __DRI_API_GLES2);
|
|
|
|
if (psp->max_gl_es2_version >= 30)
|
|
|
|
psp->api_mask |= (1 << __DRI_API_GLES3);
|
|
|
|
|
2011-11-04 14:14:58 +00:00
|
|
|
return psp;
|
|
|
|
}
|
|
|
|
|
2013-09-27 19:39:25 +01:00
|
|
|
static __DRIscreen *
|
|
|
|
dri2CreateNewScreen(int scrn, int fd,
|
|
|
|
const __DRIextension **extensions,
|
|
|
|
const __DRIconfig ***driver_configs, void *data)
|
|
|
|
{
|
2022-03-30 15:11:04 +01:00
|
|
|
return driCreateNewScreen2(scrn, fd, extensions,
|
|
|
|
galliumdrm_driver_extensions,
|
|
|
|
driver_configs, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __DRIscreen *
|
|
|
|
swkmsCreateNewScreen(int scrn, int fd,
|
|
|
|
const __DRIextension **extensions,
|
|
|
|
const __DRIconfig ***driver_configs, void *data)
|
|
|
|
{
|
|
|
|
return driCreateNewScreen2(scrn, fd, extensions,
|
2022-06-09 10:42:05 +01:00
|
|
|
dri_swrast_kms_driver_extensions,
|
2022-03-30 15:11:04 +01:00
|
|
|
driver_configs, data);
|
2013-09-27 19:39:25 +01:00
|
|
|
}
|
|
|
|
|
2013-09-26 19:35:31 +01:00
|
|
|
/** swrast driver createNewScreen entrypoint. */
|
|
|
|
static __DRIscreen *
|
2013-09-27 19:39:25 +01:00
|
|
|
driSWRastCreateNewScreen(int scrn, const __DRIextension **extensions,
|
|
|
|
const __DRIconfig ***driver_configs, void *data)
|
|
|
|
{
|
2022-03-30 15:11:04 +01:00
|
|
|
return driCreateNewScreen2(scrn, -1, extensions,
|
|
|
|
galliumsw_driver_extensions,
|
|
|
|
driver_configs, data);
|
2013-09-27 19:39:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static __DRIscreen *
|
|
|
|
driSWRastCreateNewScreen2(int scrn, const __DRIextension **extensions,
|
|
|
|
const __DRIextension **driver_extensions,
|
|
|
|
const __DRIconfig ***driver_configs, void *data)
|
2013-09-26 19:35:31 +01:00
|
|
|
{
|
2013-06-04 04:49:25 +01:00
|
|
|
return driCreateNewScreen2(scrn, -1, extensions, driver_extensions,
|
2013-09-27 19:39:25 +01:00
|
|
|
driver_configs, data);
|
2013-09-26 19:35:31 +01:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:14:58 +00:00
|
|
|
/**
|
|
|
|
* Destroy the per-screen private information.
|
2022-07-28 09:11:04 +01:00
|
|
|
*
|
2011-11-04 14:14:58 +00:00
|
|
|
* \internal
|
|
|
|
* This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
|
|
|
|
* drmClose(), and finally frees \p screenPrivate.
|
|
|
|
*/
|
|
|
|
static void driDestroyScreen(__DRIscreen *psp)
|
|
|
|
{
|
|
|
|
if (psp) {
|
|
|
|
/* No interaction with the X-server is possible at this point. This
|
|
|
|
* routine is called after XCloseDisplay, so there is no protocol
|
|
|
|
* stream open to the X-server anymore.
|
|
|
|
*/
|
|
|
|
|
2013-09-26 18:51:29 +01:00
|
|
|
psp->driver->DestroyScreen(psp);
|
2011-11-04 14:14:58 +00:00
|
|
|
|
|
|
|
driDestroyOptionCache(&psp->optionCache);
|
|
|
|
driDestroyOptionInfo(&psp->optionInfo);
|
|
|
|
|
|
|
|
free(psp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const __DRIextension **driGetExtensions(__DRIscreen *psp)
|
|
|
|
{
|
|
|
|
return psp->extensions;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*@}*/
|
|
|
|
|
2022-05-06 20:21:53 +01:00
|
|
|
/* WARNING: HACK: Local defines to avoid pulling glx.h.
|
|
|
|
*/
|
|
|
|
#define GLX_NONE 0x8000
|
|
|
|
#define GLX_DONT_CARE 0xFFFFFFFF
|
|
|
|
|
|
|
|
#define __ATTRIB(attrib, field) case attrib: *value = config->modes.field; break
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the value of a configuration attribute. The attribute is
|
|
|
|
* indicated by the index.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
driGetConfigAttribIndex(const __DRIconfig *config,
|
|
|
|
unsigned int index, unsigned int *value)
|
|
|
|
{
|
|
|
|
switch (index + 1) {
|
|
|
|
__ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits);
|
|
|
|
case __DRI_ATTRIB_LEVEL:
|
|
|
|
case __DRI_ATTRIB_LUMINANCE_SIZE:
|
|
|
|
case __DRI_ATTRIB_AUX_BUFFERS:
|
|
|
|
*value = 0;
|
|
|
|
break;
|
|
|
|
__ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits);
|
|
|
|
case __DRI_ATTRIB_ALPHA_MASK_SIZE:
|
|
|
|
/* I have no idea what this value was ever meant to mean, it's
|
|
|
|
* never been set to anything, just say 0.
|
|
|
|
*/
|
|
|
|
*value = 0;
|
|
|
|
break;
|
|
|
|
__ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits);
|
|
|
|
case __DRI_ATTRIB_SAMPLE_BUFFERS:
|
|
|
|
*value = !!config->modes.samples;
|
|
|
|
break;
|
|
|
|
__ATTRIB(__DRI_ATTRIB_SAMPLES, samples);
|
|
|
|
case __DRI_ATTRIB_RENDER_TYPE:
|
|
|
|
/* no support for color index mode */
|
|
|
|
*value = __DRI_ATTRIB_RGBA_BIT;
|
|
|
|
if (config->modes.floatMode)
|
|
|
|
*value |= __DRI_ATTRIB_FLOAT_BIT;
|
|
|
|
break;
|
|
|
|
case __DRI_ATTRIB_CONFIG_CAVEAT:
|
|
|
|
if (config->modes.accumRedBits != 0)
|
|
|
|
*value = __DRI_ATTRIB_SLOW_BIT;
|
|
|
|
else
|
|
|
|
*value = 0;
|
|
|
|
break;
|
|
|
|
case __DRI_ATTRIB_CONFORMANT:
|
|
|
|
*value = GL_TRUE;
|
|
|
|
break;
|
|
|
|
__ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_STEREO, stereoMode);
|
|
|
|
case __DRI_ATTRIB_TRANSPARENT_TYPE:
|
|
|
|
case __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE: /* horrible bc hack */
|
|
|
|
*value = GLX_NONE;
|
|
|
|
break;
|
|
|
|
case __DRI_ATTRIB_TRANSPARENT_RED_VALUE:
|
|
|
|
case __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE:
|
|
|
|
case __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE:
|
|
|
|
case __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE:
|
|
|
|
*value = GLX_DONT_CARE;
|
|
|
|
break;
|
|
|
|
case __DRI_ATTRIB_FLOAT_MODE:
|
|
|
|
*value = config->modes.floatMode;
|
|
|
|
break;
|
|
|
|
__ATTRIB(__DRI_ATTRIB_RED_MASK, redMask);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask);
|
|
|
|
case __DRI_ATTRIB_MAX_PBUFFER_WIDTH:
|
|
|
|
case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT:
|
|
|
|
case __DRI_ATTRIB_MAX_PBUFFER_PIXELS:
|
|
|
|
case __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH:
|
|
|
|
case __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT:
|
|
|
|
case __DRI_ATTRIB_VISUAL_SELECT_GROUP:
|
|
|
|
*value = 0;
|
|
|
|
break;
|
|
|
|
__ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod);
|
|
|
|
case __DRI_ATTRIB_MAX_SWAP_INTERVAL:
|
|
|
|
*value = INT_MAX;
|
|
|
|
break;
|
|
|
|
case __DRI_ATTRIB_MIN_SWAP_INTERVAL:
|
|
|
|
*value = 0;
|
|
|
|
break;
|
|
|
|
case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB:
|
|
|
|
case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA:
|
|
|
|
case __DRI_ATTRIB_YINVERTED:
|
|
|
|
*value = GL_TRUE;
|
|
|
|
break;
|
|
|
|
case __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE:
|
|
|
|
*value = GL_FALSE;
|
|
|
|
break;
|
|
|
|
case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
|
|
|
|
*value = __DRI_ATTRIB_TEXTURE_1D_BIT |
|
|
|
|
__DRI_ATTRIB_TEXTURE_2D_BIT |
|
|
|
|
__DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
|
|
|
|
break;
|
|
|
|
__ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable);
|
|
|
|
case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER:
|
|
|
|
*value = GL_FALSE;
|
|
|
|
break;
|
|
|
|
__ATTRIB(__DRI_ATTRIB_RED_SHIFT, redShift);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_GREEN_SHIFT, greenShift);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_BLUE_SHIFT, blueShift);
|
|
|
|
__ATTRIB(__DRI_ATTRIB_ALPHA_SHIFT, alphaShift);
|
|
|
|
default:
|
|
|
|
/* XXX log an error or smth */
|
|
|
|
return GL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GL_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the value of a configuration attribute.
|
|
|
|
* \param attrib the attribute (one of the _DRI_ATTRIB_x tokens)
|
|
|
|
* \param value returns the attribute's value
|
|
|
|
* \return 1 for success, 0 for failure
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
driGetConfigAttrib(const __DRIconfig *config,
|
|
|
|
unsigned int attrib, unsigned int *value)
|
|
|
|
{
|
|
|
|
return driGetConfigAttribIndex(config, attrib - 1, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a configuration attribute name and value, given an index.
|
|
|
|
* \param index which field of the __DRIconfig to query
|
|
|
|
* \param attrib returns the attribute name (one of the _DRI_ATTRIB_x tokens)
|
|
|
|
* \param value returns the attribute's value
|
|
|
|
* \return 1 for success, 0 for failure
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
driIndexConfigAttrib(const __DRIconfig *config, int index,
|
|
|
|
unsigned int *attrib, unsigned int *value)
|
|
|
|
{
|
|
|
|
if (driGetConfigAttribIndex(config, index, value)) {
|
|
|
|
*attrib = index + 1;
|
|
|
|
return GL_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GL_FALSE;
|
|
|
|
}
|
2011-11-04 14:14:58 +00:00
|
|
|
|
dri: Move API version validation into dri/common.
i965, i915, radeon, r200, swrast, and nouveau were mostly trying to do the
same logic, except where they failed to. Notably, swrast had code that
appeared to try to enable GLES1/2 but forgot to set api_mask (thus
preventing any gles context from being created), and the non-intel drivers
didn't support MESA_GL_VERSION_OVERRIDE.
nouveau still relies on _mesa_compute_version(), because I don't know what
its limits actually are, and gallium drivers don't declare limits up front
at all. I think I've heard talk about doing so, though.
v2: Compat max version should be 30 (noted by Ken)
Drop r100's custom max version check, too (noted by Emil Velikov)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-09-26 20:01:56 +01:00
|
|
|
static bool
|
|
|
|
validate_context_version(__DRIscreen *screen,
|
|
|
|
int mesa_api,
|
|
|
|
unsigned major_version,
|
|
|
|
unsigned minor_version,
|
|
|
|
unsigned *dri_ctx_error)
|
|
|
|
{
|
|
|
|
unsigned req_version = 10 * major_version + minor_version;
|
|
|
|
unsigned max_version = 0;
|
|
|
|
|
|
|
|
switch (mesa_api) {
|
|
|
|
case API_OPENGL_COMPAT:
|
|
|
|
max_version = screen->max_gl_compat_version;
|
|
|
|
break;
|
|
|
|
case API_OPENGL_CORE:
|
|
|
|
max_version = screen->max_gl_core_version;
|
|
|
|
break;
|
|
|
|
case API_OPENGLES:
|
|
|
|
max_version = screen->max_gl_es1_version;
|
|
|
|
break;
|
|
|
|
case API_OPENGLES2:
|
|
|
|
max_version = screen->max_gl_es2_version;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
max_version = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (max_version == 0) {
|
|
|
|
*dri_ctx_error = __DRI_CTX_ERROR_BAD_API;
|
|
|
|
return false;
|
|
|
|
} else if (req_version > max_version) {
|
|
|
|
*dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-11-04 14:19:22 +00:00
|
|
|
/*****************************************************************/
|
|
|
|
/** \name Context handling functions */
|
|
|
|
/*****************************************************************/
|
|
|
|
/*@{*/
|
|
|
|
|
|
|
|
static __DRIcontext *
|
2013-06-04 04:49:25 +01:00
|
|
|
driCreateContextAttribs(__DRIscreen *screen, int api,
|
|
|
|
const __DRIconfig *config,
|
|
|
|
__DRIcontext *shared,
|
|
|
|
unsigned num_attribs,
|
|
|
|
const uint32_t *attribs,
|
|
|
|
unsigned *error,
|
|
|
|
void *data)
|
2011-11-04 14:19:22 +00:00
|
|
|
{
|
|
|
|
__DRIcontext *context;
|
|
|
|
const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
|
|
|
|
void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
|
|
|
|
gl_api mesa_api;
|
2014-10-01 20:00:46 +01:00
|
|
|
struct __DriverContextConfig ctx_config;
|
|
|
|
|
|
|
|
ctx_config.major_version = 1;
|
|
|
|
ctx_config.minor_version = 0;
|
|
|
|
ctx_config.flags = 0;
|
|
|
|
ctx_config.attribute_mask = 0;
|
|
|
|
ctx_config.priority = __DRI_CTX_PRIORITY_MEDIUM;
|
2011-12-01 02:05:36 +00:00
|
|
|
|
|
|
|
assert((num_attribs == 0) || (attribs != NULL));
|
2011-11-04 14:19:22 +00:00
|
|
|
|
2011-12-01 02:05:36 +00:00
|
|
|
if (!(screen->api_mask & (1 << api))) {
|
|
|
|
*error = __DRI_CTX_ERROR_BAD_API;
|
2011-11-04 14:19:22 +00:00
|
|
|
return NULL;
|
2011-12-01 02:05:36 +00:00
|
|
|
}
|
2011-11-04 14:19:22 +00:00
|
|
|
|
|
|
|
switch (api) {
|
|
|
|
case __DRI_API_OPENGL:
|
2012-11-27 20:26:51 +00:00
|
|
|
mesa_api = API_OPENGL_COMPAT;
|
2011-12-01 02:05:36 +00:00
|
|
|
break;
|
2011-11-04 14:19:22 +00:00
|
|
|
case __DRI_API_GLES:
|
2011-12-01 02:05:36 +00:00
|
|
|
mesa_api = API_OPENGLES;
|
|
|
|
break;
|
2011-11-04 14:19:22 +00:00
|
|
|
case __DRI_API_GLES2:
|
2012-11-20 21:27:14 +00:00
|
|
|
case __DRI_API_GLES3:
|
2011-12-01 02:05:36 +00:00
|
|
|
mesa_api = API_OPENGLES2;
|
|
|
|
break;
|
|
|
|
case __DRI_API_OPENGL_CORE:
|
2012-08-07 19:26:19 +01:00
|
|
|
mesa_api = API_OPENGL_CORE;
|
|
|
|
break;
|
2011-11-04 14:19:22 +00:00
|
|
|
default:
|
2011-12-01 02:05:36 +00:00
|
|
|
*error = __DRI_CTX_ERROR_BAD_API;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < num_attribs; i++) {
|
|
|
|
switch (attribs[i * 2]) {
|
|
|
|
case __DRI_CTX_ATTRIB_MAJOR_VERSION:
|
2014-10-01 20:00:46 +01:00
|
|
|
ctx_config.major_version = attribs[i * 2 + 1];
|
2011-12-01 02:05:36 +00:00
|
|
|
break;
|
|
|
|
case __DRI_CTX_ATTRIB_MINOR_VERSION:
|
2014-10-01 20:00:46 +01:00
|
|
|
ctx_config.minor_version = attribs[i * 2 + 1];
|
2011-12-01 02:05:36 +00:00
|
|
|
break;
|
|
|
|
case __DRI_CTX_ATTRIB_FLAGS:
|
2014-10-01 20:00:46 +01:00
|
|
|
ctx_config.flags = attribs[i * 2 + 1];
|
2011-12-01 02:05:36 +00:00
|
|
|
break;
|
2012-09-10 15:11:33 +01:00
|
|
|
case __DRI_CTX_ATTRIB_RESET_STRATEGY:
|
2014-10-01 20:00:46 +01:00
|
|
|
if (attribs[i * 2 + 1] != __DRI_CTX_RESET_NO_NOTIFICATION) {
|
|
|
|
ctx_config.attribute_mask |=
|
|
|
|
__DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY;
|
|
|
|
ctx_config.reset_strategy = attribs[i * 2 + 1];
|
|
|
|
} else {
|
|
|
|
ctx_config.attribute_mask &=
|
|
|
|
~__DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY;
|
|
|
|
}
|
2012-09-10 15:11:33 +01:00
|
|
|
break;
|
2016-10-27 19:54:49 +01:00
|
|
|
case __DRI_CTX_ATTRIB_PRIORITY:
|
2014-10-01 20:00:46 +01:00
|
|
|
ctx_config.attribute_mask |= __DRIVER_CONTEXT_ATTRIB_PRIORITY;
|
|
|
|
ctx_config.priority = attribs[i * 2 + 1];
|
2016-10-27 19:54:49 +01:00
|
|
|
break;
|
2014-10-01 20:00:47 +01:00
|
|
|
case __DRI_CTX_ATTRIB_RELEASE_BEHAVIOR:
|
|
|
|
if (attribs[i * 2 + 1] != __DRI_CTX_RELEASE_BEHAVIOR_FLUSH) {
|
|
|
|
ctx_config.attribute_mask |=
|
|
|
|
__DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR;
|
|
|
|
ctx_config.release_behavior = attribs[i * 2 + 1];
|
|
|
|
} else {
|
|
|
|
ctx_config.attribute_mask &=
|
|
|
|
~__DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR;
|
|
|
|
}
|
|
|
|
break;
|
2021-10-04 22:46:46 +01:00
|
|
|
case __DRI_CTX_ATTRIB_NO_ERROR:
|
|
|
|
if (attribs[i * 2 + 1] != 0) {
|
|
|
|
ctx_config.attribute_mask |=
|
|
|
|
__DRIVER_CONTEXT_ATTRIB_NO_ERROR;
|
|
|
|
ctx_config.no_error = attribs[i * 2 + 1];
|
|
|
|
} else {
|
|
|
|
ctx_config.attribute_mask &=
|
|
|
|
~__DRIVER_CONTEXT_ATTRIB_NO_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
2011-12-01 02:05:36 +00:00
|
|
|
default:
|
|
|
|
/* We can't create a context that satisfies the requirements of an
|
|
|
|
* attribute that we don't understand. Return failure.
|
|
|
|
*/
|
2011-12-01 22:06:58 +00:00
|
|
|
assert(!"Should not get here.");
|
|
|
|
*error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
|
2011-12-01 02:05:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-02 22:55:46 +00:00
|
|
|
/* The specific Mesa driver may not support the GL_ARB_compatibilty
|
|
|
|
* extension or the compatibility profile. In that case, we treat an
|
|
|
|
* API_OPENGL_COMPAT 3.1 as API_OPENGL_CORE. We reject API_OPENGL_COMPAT
|
|
|
|
* 3.2+ in any case.
|
|
|
|
*/
|
|
|
|
if (mesa_api == API_OPENGL_COMPAT &&
|
|
|
|
ctx_config.major_version == 3 && ctx_config.minor_version == 1 &&
|
|
|
|
screen->max_gl_compat_version < 31)
|
|
|
|
mesa_api = API_OPENGL_CORE;
|
|
|
|
|
2014-11-12 12:13:42 +00:00
|
|
|
/* The latest version of EGL_KHR_create_context spec says:
|
2012-07-18 22:26:24 +01:00
|
|
|
*
|
2014-11-12 12:13:42 +00:00
|
|
|
* "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in
|
|
|
|
* EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created.
|
|
|
|
* [...] This bit is supported for OpenGL and OpenGL ES contexts.
|
2012-07-18 22:26:24 +01:00
|
|
|
*
|
2016-04-11 23:12:15 +01:00
|
|
|
* No other EGL_CONTEXT_OPENGL_*_BIT is legal for an ES context.
|
|
|
|
*
|
|
|
|
* However, Mesa's EGL layer translates the context attribute
|
|
|
|
* EGL_CONTEXT_OPENGL_ROBUST_ACCESS into the context flag
|
|
|
|
* __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS. That attribute is legal for ES
|
|
|
|
* (with EGL 1.5 or EGL_EXT_create_context_robustness) and GL (only with
|
|
|
|
* EGL 1.5).
|
|
|
|
*
|
|
|
|
* From the EGL_EXT_create_context_robustness spec:
|
|
|
|
*
|
|
|
|
* This extension is written against the OpenGL ES 2.0 Specification
|
|
|
|
* but can apply to OpenGL ES 1.1 and up.
|
|
|
|
*
|
|
|
|
* From the EGL 1.5 (2014.08.27) spec, p55:
|
|
|
|
*
|
|
|
|
* If the EGL_CONTEXT_OPENGL_ROBUST_ACCESS attribute is set to
|
|
|
|
* EGL_TRUE, a context supporting robust buffer access will be created.
|
|
|
|
* OpenGL contexts must support the GL_ARB_robustness extension, or
|
|
|
|
* equivalent core API functional- ity. OpenGL ES contexts must support
|
|
|
|
* the GL_EXT_robustness extension, or equivalent core API
|
|
|
|
* functionality.
|
2012-07-18 22:26:24 +01:00
|
|
|
*/
|
2012-11-27 20:26:51 +00:00
|
|
|
if (mesa_api != API_OPENGL_COMPAT
|
2012-08-07 17:58:55 +01:00
|
|
|
&& mesa_api != API_OPENGL_CORE
|
2014-10-01 20:00:46 +01:00
|
|
|
&& (ctx_config.flags & ~(__DRI_CTX_FLAG_DEBUG |
|
2021-10-04 22:46:46 +01:00
|
|
|
__DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS))) {
|
2012-07-18 22:26:24 +01:00
|
|
|
*error = __DRI_CTX_ERROR_BAD_FLAG;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-01 02:05:36 +00:00
|
|
|
/* There are no forward-compatible contexts before OpenGL 3.0. The
|
|
|
|
* GLX_ARB_create_context spec says:
|
|
|
|
*
|
|
|
|
* "Forward-compatible contexts are defined only for OpenGL versions
|
|
|
|
* 3.0 and later."
|
|
|
|
*
|
2012-08-17 17:23:50 +01:00
|
|
|
* Forward-looking contexts are supported by silently converting the
|
|
|
|
* requested API to API_OPENGL_CORE.
|
2011-12-01 02:05:36 +00:00
|
|
|
*
|
|
|
|
* In Mesa, a debug context is the same as a regular context.
|
|
|
|
*/
|
2014-10-01 20:00:46 +01:00
|
|
|
if ((ctx_config.flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) {
|
2012-08-17 17:23:50 +01:00
|
|
|
mesa_api = API_OPENGL_CORE;
|
2011-12-01 22:06:58 +00:00
|
|
|
}
|
|
|
|
|
2013-11-20 17:09:50 +00:00
|
|
|
const uint32_t allowed_flags = (__DRI_CTX_FLAG_DEBUG
|
|
|
|
| __DRI_CTX_FLAG_FORWARD_COMPATIBLE
|
2017-06-29 02:24:15 +01:00
|
|
|
| __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS
|
2021-10-04 22:46:46 +01:00
|
|
|
| __DRI_CTX_FLAG_RESET_ISOLATION);
|
2014-10-01 20:00:46 +01:00
|
|
|
if (ctx_config.flags & ~allowed_flags) {
|
2011-12-01 22:06:58 +00:00
|
|
|
*error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
|
|
|
|
return NULL;
|
2011-11-04 14:19:22 +00:00
|
|
|
}
|
|
|
|
|
dri: Move API version validation into dri/common.
i965, i915, radeon, r200, swrast, and nouveau were mostly trying to do the
same logic, except where they failed to. Notably, swrast had code that
appeared to try to enable GLES1/2 but forgot to set api_mask (thus
preventing any gles context from being created), and the non-intel drivers
didn't support MESA_GL_VERSION_OVERRIDE.
nouveau still relies on _mesa_compute_version(), because I don't know what
its limits actually are, and gallium drivers don't declare limits up front
at all. I think I've heard talk about doing so, though.
v2: Compat max version should be 30 (noted by Ken)
Drop r100's custom max version check, too (noted by Emil Velikov)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-09-26 20:01:56 +01:00
|
|
|
if (!validate_context_version(screen, mesa_api,
|
2014-10-01 20:00:46 +01:00
|
|
|
ctx_config.major_version,
|
|
|
|
ctx_config.minor_version,
|
|
|
|
error))
|
dri: Move API version validation into dri/common.
i965, i915, radeon, r200, swrast, and nouveau were mostly trying to do the
same logic, except where they failed to. Notably, swrast had code that
appeared to try to enable GLES1/2 but forgot to set api_mask (thus
preventing any gles context from being created), and the non-intel drivers
didn't support MESA_GL_VERSION_OVERRIDE.
nouveau still relies on _mesa_compute_version(), because I don't know what
its limits actually are, and gallium drivers don't declare limits up front
at all. I think I've heard talk about doing so, though.
v2: Compat max version should be 30 (noted by Ken)
Drop r100's custom max version check, too (noted by Emil Velikov)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-09-26 20:01:56 +01:00
|
|
|
return NULL;
|
|
|
|
|
2012-09-26 19:08:11 +01:00
|
|
|
context = calloc(1, sizeof *context);
|
2011-12-01 02:05:36 +00:00
|
|
|
if (!context) {
|
|
|
|
*error = __DRI_CTX_ERROR_NO_MEMORY;
|
2011-11-04 14:19:22 +00:00
|
|
|
return NULL;
|
2011-12-01 02:05:36 +00:00
|
|
|
}
|
2011-11-04 14:19:22 +00:00
|
|
|
|
2011-11-04 14:35:49 +00:00
|
|
|
context->loaderPrivate = data;
|
|
|
|
|
2011-11-04 14:19:22 +00:00
|
|
|
context->driScreenPriv = screen;
|
|
|
|
context->driDrawablePriv = NULL;
|
2011-11-04 14:35:49 +00:00
|
|
|
context->driReadablePriv = NULL;
|
2011-11-04 14:19:22 +00:00
|
|
|
|
2022-03-29 18:36:37 +01:00
|
|
|
if (!dri_create_context(mesa_api, modes, context, &ctx_config, error,
|
|
|
|
shareCtx)) {
|
2011-11-04 14:19:22 +00:00
|
|
|
free(context);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-12-08 06:02:11 +00:00
|
|
|
*error = __DRI_CTX_ERROR_SUCCESS;
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
2011-12-01 02:05:36 +00:00
|
|
|
static __DRIcontext *
|
2013-06-04 04:49:25 +01:00
|
|
|
driCreateNewContextForAPI(__DRIscreen *screen, int api,
|
|
|
|
const __DRIconfig *config,
|
|
|
|
__DRIcontext *shared, void *data)
|
2011-12-01 02:05:36 +00:00
|
|
|
{
|
|
|
|
unsigned error;
|
|
|
|
|
2013-06-04 04:49:25 +01:00
|
|
|
return driCreateContextAttribs(screen, api, config, shared, 0, NULL,
|
|
|
|
&error, data);
|
2011-12-01 02:05:36 +00:00
|
|
|
}
|
2011-11-04 14:19:22 +00:00
|
|
|
|
|
|
|
static __DRIcontext *
|
2013-06-04 04:49:25 +01:00
|
|
|
driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
|
|
|
|
__DRIcontext *shared, void *data)
|
2011-11-04 14:19:22 +00:00
|
|
|
{
|
2013-06-04 04:49:25 +01:00
|
|
|
return driCreateNewContextForAPI(screen, __DRI_API_OPENGL,
|
|
|
|
config, shared, data);
|
2011-11-04 14:19:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy the per-context private information.
|
2022-07-28 09:11:04 +01:00
|
|
|
*
|
2011-11-04 14:19:22 +00:00
|
|
|
* \internal
|
|
|
|
* This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
|
|
|
|
* drmDestroyContext(), and finally frees \p contextPrivate.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
driDestroyContext(__DRIcontext *pcp)
|
|
|
|
{
|
|
|
|
if (pcp) {
|
2022-03-29 18:36:37 +01:00
|
|
|
dri_destroy_context(pcp);
|
2011-11-04 14:19:22 +00:00
|
|
|
free(pcp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
|
|
|
|
{
|
|
|
|
(void) dest;
|
|
|
|
(void) src;
|
|
|
|
(void) mask;
|
|
|
|
return GL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*@}*/
|
|
|
|
|
|
|
|
|
2004-04-14 13:39:58 +01:00
|
|
|
/*****************************************************************/
|
|
|
|
/** \name Context (un)binding functions */
|
|
|
|
/*****************************************************************/
|
|
|
|
/*@{*/
|
|
|
|
|
2011-11-04 14:24:19 +00:00
|
|
|
static void dri_get_drawable(__DRIdrawable *pdp);
|
|
|
|
static void dri_put_drawable(__DRIdrawable *pdp);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function takes both a read buffer and a draw buffer. This is needed
|
|
|
|
* for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
|
|
|
|
* function.
|
|
|
|
*/
|
|
|
|
static int driBindContext(__DRIcontext *pcp,
|
|
|
|
__DRIdrawable *pdp,
|
|
|
|
__DRIdrawable *prp)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
** Assume error checking is done properly in glXMakeCurrent before
|
|
|
|
** calling driUnbindContext.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (!pcp)
|
|
|
|
return GL_FALSE;
|
|
|
|
|
|
|
|
/* Bind the drawable to the context */
|
|
|
|
pcp->driDrawablePriv = pdp;
|
|
|
|
pcp->driReadablePriv = prp;
|
|
|
|
if (pdp) {
|
|
|
|
pdp->driContextPriv = pcp;
|
|
|
|
dri_get_drawable(pdp);
|
|
|
|
}
|
|
|
|
if (prp && pdp != prp) {
|
|
|
|
dri_get_drawable(prp);
|
|
|
|
}
|
|
|
|
|
2022-03-29 18:36:37 +01:00
|
|
|
return dri_make_current(pcp, pdp, prp);
|
2011-11-04 14:24:19 +00:00
|
|
|
}
|
|
|
|
|
2004-04-14 13:39:58 +01:00
|
|
|
/**
|
|
|
|
* Unbind context.
|
2022-07-28 09:11:04 +01:00
|
|
|
*
|
2007-05-10 20:52:22 +01:00
|
|
|
* \param scrn the screen.
|
2004-04-14 13:39:58 +01:00
|
|
|
* \param gc context.
|
|
|
|
*
|
|
|
|
* \return \c GL_TRUE on success, or \c GL_FALSE on failure.
|
2022-07-28 09:11:04 +01:00
|
|
|
*
|
2004-04-14 13:39:58 +01:00
|
|
|
* \internal
|
|
|
|
* This function calls __DriverAPIRec::UnbindContext, and then decrements
|
2010-01-01 22:09:12 +00:00
|
|
|
* __DRIdrawableRec::refcount which must be non-zero for a successful
|
2004-04-14 13:39:58 +01:00
|
|
|
* return.
|
2022-07-28 09:11:04 +01:00
|
|
|
*
|
2004-04-14 13:39:58 +01:00
|
|
|
* While casting the opaque private pointers associated with the parameters
|
2022-07-28 09:11:04 +01:00
|
|
|
* into their respective real types it also assures they are not \c NULL.
|
2004-04-14 13:39:58 +01:00
|
|
|
*/
|
DRI interface changes and DRI2 direct rendering support.
Add DRI2 direct rendering support to libGL and add DRI2 client side
protocol code. Extend the GLX 1.3 create drawable functions in
glx_pbuffer.c to call into the DRI driver when possible.
Introduce __DRIconfig, opaque struct that represents a DRI driver
configuration. Get's rid of the open coded __GLcontextModes in the
DRI driver interface and the context modes create and destroy
functions that the loader was requires to provide. glcore.h is no
longer part of the DRI driver interface. The DRI config is GL binding
agnostic, that is, not specific to GLX, EGL or other bindings.
The core API is now also an extension, and the driver exports a list
of extensions as the symbol __driDriverExtensions, which the loader
must dlsym() for. The list of extension will always include the DRI
core extension, which allows creating and manipulating DRI screens,
drawables and contexts. The DRI legacy extension, when available,
provides alternative entry points for creating the DRI objects that
work with the XF86DRI infrastructure.
Change DRI2 client code to not use drm drawables or contexts. We
never used drm_drawable_t's and the only use for drm_context_t was as
a unique identifier when taking the lock. We now just allocate a
unique lock ID out of the DRILock sarea block. Once we get rid of the
lock entirely, we can drop this hack.
Change the interface between dri_util.c and the drivers, so that the
drivers now export the DriverAPI struct as driDriverAPI instead of the
InitScreen entry point. This lets us avoid dlsym()'ing for the DRI2
init screen function to see if DRI2 is supported by the driver.
2008-03-26 23:26:59 +00:00
|
|
|
static int driUnbindContext(__DRIcontext *pcp)
|
2004-04-14 13:39:58 +01:00
|
|
|
{
|
2009-08-25 03:03:58 +01:00
|
|
|
__DRIdrawable *pdp;
|
|
|
|
__DRIdrawable *prp;
|
2004-04-14 13:39:58 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
** Assume error checking is done properly in glXMakeCurrent before
|
2005-07-24 07:29:14 +01:00
|
|
|
** calling driUnbindContext.
|
2004-04-14 13:39:58 +01:00
|
|
|
*/
|
|
|
|
|
DRI interface changes and DRI2 direct rendering support.
Add DRI2 direct rendering support to libGL and add DRI2 client side
protocol code. Extend the GLX 1.3 create drawable functions in
glx_pbuffer.c to call into the DRI driver when possible.
Introduce __DRIconfig, opaque struct that represents a DRI driver
configuration. Get's rid of the open coded __GLcontextModes in the
DRI driver interface and the context modes create and destroy
functions that the loader was requires to provide. glcore.h is no
longer part of the DRI driver interface. The DRI config is GL binding
agnostic, that is, not specific to GLX, EGL or other bindings.
The core API is now also an extension, and the driver exports a list
of extensions as the symbol __driDriverExtensions, which the loader
must dlsym() for. The list of extension will always include the DRI
core extension, which allows creating and manipulating DRI screens,
drawables and contexts. The DRI legacy extension, when available,
provides alternative entry points for creating the DRI objects that
work with the XF86DRI infrastructure.
Change DRI2 client code to not use drm drawables or contexts. We
never used drm_drawable_t's and the only use for drm_context_t was as
a unique identifier when taking the lock. We now just allocate a
unique lock ID out of the DRILock sarea block. Once we get rid of the
lock entirely, we can drop this hack.
Change the interface between dri_util.c and the drivers, so that the
drivers now export the DriverAPI struct as driDriverAPI instead of the
InitScreen entry point. This lets us avoid dlsym()'ing for the DRI2
init screen function to see if DRI2 is supported by the driver.
2008-03-26 23:26:59 +00:00
|
|
|
if (pcp == NULL)
|
2011-11-04 14:35:49 +00:00
|
|
|
return GL_FALSE;
|
2004-04-14 13:39:58 +01:00
|
|
|
|
2014-10-24 11:03:13 +01:00
|
|
|
/*
|
2022-03-29 18:36:37 +01:00
|
|
|
** Call dri_unbind_context before checking for valid drawables
|
2014-10-24 11:03:13 +01:00
|
|
|
** to handle surfaceless contexts properly.
|
|
|
|
*/
|
2022-03-29 18:36:37 +01:00
|
|
|
dri_unbind_context(pcp);
|
2014-10-24 11:03:13 +01:00
|
|
|
|
2009-08-25 03:03:58 +01:00
|
|
|
pdp = pcp->driDrawablePriv;
|
|
|
|
prp = pcp->driReadablePriv;
|
2004-04-14 13:39:58 +01:00
|
|
|
|
2009-08-25 03:03:58 +01:00
|
|
|
/* already unbound */
|
|
|
|
if (!pdp && !prp)
|
2011-11-04 14:35:49 +00:00
|
|
|
return GL_TRUE;
|
|
|
|
|
2010-02-28 00:51:17 +00:00
|
|
|
assert(pdp);
|
2009-08-25 03:03:58 +01:00
|
|
|
if (pdp->refcount == 0) {
|
|
|
|
/* ERROR!!! */
|
|
|
|
return GL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dri_put_drawable(pdp);
|
|
|
|
|
|
|
|
if (prp != pdp) {
|
2011-11-04 14:35:49 +00:00
|
|
|
if (prp->refcount == 0) {
|
2009-08-25 03:03:58 +01:00
|
|
|
/* ERROR!!! */
|
|
|
|
return GL_FALSE;
|
|
|
|
}
|
|
|
|
|
2011-11-04 14:35:49 +00:00
|
|
|
dri_put_drawable(prp);
|
2009-08-25 03:03:58 +01:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:35:49 +00:00
|
|
|
pcp->driDrawablePriv = NULL;
|
|
|
|
pcp->driReadablePriv = NULL;
|
2009-08-25 03:03:58 +01:00
|
|
|
|
2004-04-14 13:39:58 +01:00
|
|
|
return GL_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-11-04 14:24:19 +00:00
|
|
|
/*@}*/
|
2004-04-14 13:39:58 +01:00
|
|
|
|
|
|
|
|
2011-11-04 14:25:51 +00:00
|
|
|
static void dri_get_drawable(__DRIdrawable *pdp)
|
|
|
|
{
|
|
|
|
pdp->refcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dri_put_drawable(__DRIdrawable *pdp)
|
|
|
|
{
|
|
|
|
if (pdp) {
|
|
|
|
pdp->refcount--;
|
|
|
|
if (pdp->refcount)
|
|
|
|
return;
|
|
|
|
|
2013-09-26 18:51:29 +01:00
|
|
|
pdp->driScreenPriv->driver->DestroyBuffer(pdp);
|
2011-11-04 14:25:51 +00:00
|
|
|
free(pdp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
DRI interface changes and DRI2 direct rendering support.
Add DRI2 direct rendering support to libGL and add DRI2 client side
protocol code. Extend the GLX 1.3 create drawable functions in
glx_pbuffer.c to call into the DRI driver when possible.
Introduce __DRIconfig, opaque struct that represents a DRI driver
configuration. Get's rid of the open coded __GLcontextModes in the
DRI driver interface and the context modes create and destroy
functions that the loader was requires to provide. glcore.h is no
longer part of the DRI driver interface. The DRI config is GL binding
agnostic, that is, not specific to GLX, EGL or other bindings.
The core API is now also an extension, and the driver exports a list
of extensions as the symbol __driDriverExtensions, which the loader
must dlsym() for. The list of extension will always include the DRI
core extension, which allows creating and manipulating DRI screens,
drawables and contexts. The DRI legacy extension, when available,
provides alternative entry points for creating the DRI objects that
work with the XF86DRI infrastructure.
Change DRI2 client code to not use drm drawables or contexts. We
never used drm_drawable_t's and the only use for drm_context_t was as
a unique identifier when taking the lock. We now just allocate a
unique lock ID out of the DRILock sarea block. Once we get rid of the
lock entirely, we can drop this hack.
Change the interface between dri_util.c and the drivers, so that the
drivers now export the DriverAPI struct as driDriverAPI instead of the
InitScreen entry point. This lets us avoid dlsym()'ing for the DRI2
init screen function to see if DRI2 is supported by the driver.
2008-03-26 23:26:59 +00:00
|
|
|
static __DRIdrawable *
|
2013-06-04 04:49:25 +01:00
|
|
|
driCreateNewDrawable(__DRIscreen *screen,
|
|
|
|
const __DRIconfig *config,
|
|
|
|
void *data)
|
2004-04-14 13:39:58 +01:00
|
|
|
{
|
2011-10-28 20:14:41 +01:00
|
|
|
__DRIdrawable *pdraw;
|
2004-04-14 13:39:58 +01:00
|
|
|
|
2017-01-27 10:55:14 +00:00
|
|
|
assert(data != NULL);
|
|
|
|
|
2011-10-28 20:14:41 +01:00
|
|
|
pdraw = malloc(sizeof *pdraw);
|
|
|
|
if (!pdraw)
|
2004-04-14 13:39:58 +01:00
|
|
|
return NULL;
|
|
|
|
|
2011-11-04 14:35:49 +00:00
|
|
|
pdraw->loaderPrivate = data;
|
|
|
|
|
|
|
|
pdraw->driScreenPriv = screen;
|
2011-10-28 20:14:41 +01:00
|
|
|
pdraw->driContextPriv = NULL;
|
2011-11-04 14:35:49 +00:00
|
|
|
pdraw->refcount = 0;
|
2011-10-28 20:14:41 +01:00
|
|
|
pdraw->lastStamp = 0;
|
|
|
|
pdraw->w = 0;
|
|
|
|
pdraw->h = 0;
|
|
|
|
|
2011-11-04 14:35:49 +00:00
|
|
|
dri_get_drawable(pdraw);
|
|
|
|
|
2013-09-26 18:51:29 +01:00
|
|
|
if (!screen->driver->CreateBuffer(screen, pdraw, &config->modes,
|
|
|
|
GL_FALSE)) {
|
2011-10-28 20:14:41 +01:00
|
|
|
free(pdraw);
|
2004-04-14 13:39:58 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-28 21:22:03 +01:00
|
|
|
pdraw->dri2.stamp = pdraw->lastStamp + 1;
|
2010-02-08 18:27:56 +00:00
|
|
|
|
DRI interface changes and DRI2 direct rendering support.
Add DRI2 direct rendering support to libGL and add DRI2 client side
protocol code. Extend the GLX 1.3 create drawable functions in
glx_pbuffer.c to call into the DRI driver when possible.
Introduce __DRIconfig, opaque struct that represents a DRI driver
configuration. Get's rid of the open coded __GLcontextModes in the
DRI driver interface and the context modes create and destroy
functions that the loader was requires to provide. glcore.h is no
longer part of the DRI driver interface. The DRI config is GL binding
agnostic, that is, not specific to GLX, EGL or other bindings.
The core API is now also an extension, and the driver exports a list
of extensions as the symbol __driDriverExtensions, which the loader
must dlsym() for. The list of extension will always include the DRI
core extension, which allows creating and manipulating DRI screens,
drawables and contexts. The DRI legacy extension, when available,
provides alternative entry points for creating the DRI objects that
work with the XF86DRI infrastructure.
Change DRI2 client code to not use drm drawables or contexts. We
never used drm_drawable_t's and the only use for drm_context_t was as
a unique identifier when taking the lock. We now just allocate a
unique lock ID out of the DRILock sarea block. Once we get rid of the
lock entirely, we can drop this hack.
Change the interface between dri_util.c and the drivers, so that the
drivers now export the DriverAPI struct as driDriverAPI instead of the
InitScreen entry point. This lets us avoid dlsym()'ing for the DRI2
init screen function to see if DRI2 is supported by the driver.
2008-03-26 23:26:59 +00:00
|
|
|
return pdraw;
|
2004-04-14 13:39:58 +01:00
|
|
|
}
|
|
|
|
|
2011-11-04 14:25:51 +00:00
|
|
|
static void
|
|
|
|
driDestroyDrawable(__DRIdrawable *pdp)
|
|
|
|
{
|
2017-01-27 10:55:14 +00:00
|
|
|
/*
|
|
|
|
* The loader's data structures are going away, even if pdp itself stays
|
|
|
|
* around for the time being because it is currently bound. This happens
|
|
|
|
* when a currently bound GLX pixmap is destroyed.
|
|
|
|
*
|
|
|
|
* Clear out the pointer back into the loader's data structures to avoid
|
|
|
|
* accessing an outdated pointer.
|
|
|
|
*/
|
|
|
|
pdp->loaderPrivate = NULL;
|
|
|
|
|
2011-11-04 14:25:51 +00:00
|
|
|
dri_put_drawable(pdp);
|
|
|
|
}
|
|
|
|
|
2011-02-04 10:59:12 +00:00
|
|
|
static __DRIbuffer *
|
|
|
|
dri2AllocateBuffer(__DRIscreen *screen,
|
|
|
|
unsigned int attachment, unsigned int format,
|
|
|
|
int width, int height)
|
|
|
|
{
|
2013-09-26 18:51:29 +01:00
|
|
|
return screen->driver->AllocateBuffer(screen, attachment, format,
|
|
|
|
width, height);
|
2011-02-04 10:59:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
|
|
|
|
{
|
2013-09-26 18:51:29 +01:00
|
|
|
screen->driver->ReleaseBuffer(screen, buffer);
|
2011-02-04 10:59:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-22 20:47:41 +01:00
|
|
|
static int
|
2014-07-01 23:24:05 +01:00
|
|
|
dri2ConfigQueryb(__DRIscreen *screen, const char *var, unsigned char *val)
|
2010-04-22 20:47:41 +01:00
|
|
|
{
|
|
|
|
if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*val = driQueryOptionb(&screen->optionCache, var);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2014-06-27 04:23:24 +01:00
|
|
|
dri2ConfigQueryi(__DRIscreen *screen, const char *var, int *val)
|
2010-04-22 20:47:41 +01:00
|
|
|
{
|
|
|
|
if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
|
|
|
|
!driCheckOption(&screen->optionCache, var, DRI_ENUM))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*val = driQueryOptioni(&screen->optionCache, var);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2014-06-27 04:23:24 +01:00
|
|
|
dri2ConfigQueryf(__DRIscreen *screen, const char *var, float *val)
|
2010-04-22 20:47:41 +01:00
|
|
|
{
|
|
|
|
if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*val = driQueryOptionf(&screen->optionCache, var);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-15 13:23:05 +01:00
|
|
|
static int
|
|
|
|
dri2ConfigQuerys(__DRIscreen *screen, const char *var, char **val)
|
|
|
|
{
|
|
|
|
if (!driCheckOption(&screen->optionCache, var, DRI_STRING))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*val = driQueryOptionstr(&screen->optionCache, var);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-04-27 16:04:51 +01:00
|
|
|
static unsigned int
|
2013-06-04 04:49:25 +01:00
|
|
|
driGetAPIMask(__DRIscreen *screen)
|
2010-04-27 16:04:51 +01:00
|
|
|
{
|
|
|
|
return screen->api_mask;
|
|
|
|
}
|
|
|
|
|
2013-09-26 19:35:31 +01:00
|
|
|
/**
|
|
|
|
* swrast swapbuffers entrypoint.
|
|
|
|
*
|
|
|
|
* DRI2 implements this inside the loader with only flushes handled by the
|
|
|
|
* driver.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
driSwapBuffers(__DRIdrawable *pdp)
|
|
|
|
{
|
|
|
|
assert(pdp->driScreenPriv->swrast_loader);
|
|
|
|
|
2013-09-26 18:51:29 +01:00
|
|
|
pdp->driScreenPriv->driver->SwapBuffers(pdp);
|
2013-09-26 19:35:31 +01:00
|
|
|
}
|
DRI interface changes and DRI2 direct rendering support.
Add DRI2 direct rendering support to libGL and add DRI2 client side
protocol code. Extend the GLX 1.3 create drawable functions in
glx_pbuffer.c to call into the DRI driver when possible.
Introduce __DRIconfig, opaque struct that represents a DRI driver
configuration. Get's rid of the open coded __GLcontextModes in the
DRI driver interface and the context modes create and destroy
functions that the loader was requires to provide. glcore.h is no
longer part of the DRI driver interface. The DRI config is GL binding
agnostic, that is, not specific to GLX, EGL or other bindings.
The core API is now also an extension, and the driver exports a list
of extensions as the symbol __driDriverExtensions, which the loader
must dlsym() for. The list of extension will always include the DRI
core extension, which allows creating and manipulating DRI screens,
drawables and contexts. The DRI legacy extension, when available,
provides alternative entry points for creating the DRI objects that
work with the XF86DRI infrastructure.
Change DRI2 client code to not use drm drawables or contexts. We
never used drm_drawable_t's and the only use for drm_context_t was as
a unique identifier when taking the lock. We now just allocate a
unique lock ID out of the DRILock sarea block. Once we get rid of the
lock entirely, we can drop this hack.
Change the interface between dri_util.c and the drivers, so that the
drivers now export the DriverAPI struct as driDriverAPI instead of the
InitScreen entry point. This lets us avoid dlsym()'ing for the DRI2
init screen function to see if DRI2 is supported by the driver.
2008-03-26 23:26:59 +00:00
|
|
|
|
2008-08-13 16:46:25 +01:00
|
|
|
/** Core interface */
|
DRI interface changes and DRI2 direct rendering support.
Add DRI2 direct rendering support to libGL and add DRI2 client side
protocol code. Extend the GLX 1.3 create drawable functions in
glx_pbuffer.c to call into the DRI driver when possible.
Introduce __DRIconfig, opaque struct that represents a DRI driver
configuration. Get's rid of the open coded __GLcontextModes in the
DRI driver interface and the context modes create and destroy
functions that the loader was requires to provide. glcore.h is no
longer part of the DRI driver interface. The DRI config is GL binding
agnostic, that is, not specific to GLX, EGL or other bindings.
The core API is now also an extension, and the driver exports a list
of extensions as the symbol __driDriverExtensions, which the loader
must dlsym() for. The list of extension will always include the DRI
core extension, which allows creating and manipulating DRI screens,
drawables and contexts. The DRI legacy extension, when available,
provides alternative entry points for creating the DRI objects that
work with the XF86DRI infrastructure.
Change DRI2 client code to not use drm drawables or contexts. We
never used drm_drawable_t's and the only use for drm_context_t was as
a unique identifier when taking the lock. We now just allocate a
unique lock ID out of the DRILock sarea block. Once we get rid of the
lock entirely, we can drop this hack.
Change the interface between dri_util.c and the drivers, so that the
drivers now export the DriverAPI struct as driDriverAPI instead of the
InitScreen entry point. This lets us avoid dlsym()'ing for the DRI2
init screen function to see if DRI2 is supported by the driver.
2008-03-26 23:26:59 +00:00
|
|
|
const __DRIcoreExtension driCoreExtension = {
|
2017-08-09 09:50:23 +01:00
|
|
|
.base = { __DRI_CORE, 2 },
|
2012-11-19 21:40:00 +00:00
|
|
|
|
|
|
|
.createNewScreen = NULL,
|
|
|
|
.destroyScreen = driDestroyScreen,
|
|
|
|
.getExtensions = driGetExtensions,
|
|
|
|
.getConfigAttrib = driGetConfigAttrib,
|
|
|
|
.indexConfigAttrib = driIndexConfigAttrib,
|
|
|
|
.createNewDrawable = NULL,
|
|
|
|
.destroyDrawable = driDestroyDrawable,
|
2013-09-26 19:35:31 +01:00
|
|
|
.swapBuffers = driSwapBuffers, /* swrast */
|
2013-06-04 04:49:25 +01:00
|
|
|
.createNewContext = driCreateNewContext, /* swrast */
|
2012-11-19 21:40:00 +00:00
|
|
|
.copyContext = driCopyContext,
|
|
|
|
.destroyContext = driDestroyContext,
|
|
|
|
.bindContext = driBindContext,
|
|
|
|
.unbindContext = driUnbindContext
|
DRI interface changes and DRI2 direct rendering support.
Add DRI2 direct rendering support to libGL and add DRI2 client side
protocol code. Extend the GLX 1.3 create drawable functions in
glx_pbuffer.c to call into the DRI driver when possible.
Introduce __DRIconfig, opaque struct that represents a DRI driver
configuration. Get's rid of the open coded __GLcontextModes in the
DRI driver interface and the context modes create and destroy
functions that the loader was requires to provide. glcore.h is no
longer part of the DRI driver interface. The DRI config is GL binding
agnostic, that is, not specific to GLX, EGL or other bindings.
The core API is now also an extension, and the driver exports a list
of extensions as the symbol __driDriverExtensions, which the loader
must dlsym() for. The list of extension will always include the DRI
core extension, which allows creating and manipulating DRI screens,
drawables and contexts. The DRI legacy extension, when available,
provides alternative entry points for creating the DRI objects that
work with the XF86DRI infrastructure.
Change DRI2 client code to not use drm drawables or contexts. We
never used drm_drawable_t's and the only use for drm_context_t was as
a unique identifier when taking the lock. We now just allocate a
unique lock ID out of the DRILock sarea block. Once we get rid of the
lock entirely, we can drop this hack.
Change the interface between dri_util.c and the drivers, so that the
drivers now export the DriverAPI struct as driDriverAPI instead of the
InitScreen entry point. This lets us avoid dlsym()'ing for the DRI2
init screen function to see if DRI2 is supported by the driver.
2008-03-26 23:26:59 +00:00
|
|
|
};
|
|
|
|
|
2022-07-28 09:12:49 +01:00
|
|
|
#if HAVE_DRI2
|
|
|
|
|
2010-01-01 22:56:29 +00:00
|
|
|
/** DRI2 interface */
|
2008-08-13 16:46:25 +01:00
|
|
|
const __DRIdri2Extension driDRI2Extension = {
|
2013-09-27 19:39:25 +01:00
|
|
|
.base = { __DRI_DRI2, 4 },
|
2012-11-19 21:40:00 +00:00
|
|
|
|
|
|
|
.createNewScreen = dri2CreateNewScreen,
|
2013-06-04 04:49:25 +01:00
|
|
|
.createNewDrawable = driCreateNewDrawable,
|
|
|
|
.createNewContext = driCreateNewContext,
|
|
|
|
.getAPIMask = driGetAPIMask,
|
|
|
|
.createNewContextForAPI = driCreateNewContextForAPI,
|
2012-11-19 21:40:00 +00:00
|
|
|
.allocateBuffer = dri2AllocateBuffer,
|
|
|
|
.releaseBuffer = dri2ReleaseBuffer,
|
2013-06-04 04:49:25 +01:00
|
|
|
.createContextAttribs = driCreateContextAttribs,
|
|
|
|
.createNewScreen2 = driCreateNewScreen2,
|
2008-08-13 16:46:25 +01:00
|
|
|
};
|
|
|
|
|
2022-03-30 15:11:04 +01:00
|
|
|
const __DRIdri2Extension swkmsDRI2Extension = {
|
|
|
|
.base = { __DRI_DRI2, 4 },
|
|
|
|
|
|
|
|
.createNewScreen = swkmsCreateNewScreen,
|
|
|
|
.createNewDrawable = driCreateNewDrawable,
|
|
|
|
.createNewContext = driCreateNewContext,
|
|
|
|
.getAPIMask = driGetAPIMask,
|
|
|
|
.createNewContextForAPI = driCreateNewContextForAPI,
|
|
|
|
.allocateBuffer = dri2AllocateBuffer,
|
|
|
|
.releaseBuffer = dri2ReleaseBuffer,
|
|
|
|
.createContextAttribs = driCreateContextAttribs,
|
|
|
|
.createNewScreen2 = driCreateNewScreen2,
|
|
|
|
};
|
|
|
|
|
2022-07-28 09:12:49 +01:00
|
|
|
#endif
|
|
|
|
|
2013-09-26 19:35:31 +01:00
|
|
|
const __DRIswrastExtension driSWRastExtension = {
|
2014-02-12 17:08:43 +00:00
|
|
|
.base = { __DRI_SWRAST, 4 },
|
|
|
|
|
|
|
|
.createNewScreen = driSWRastCreateNewScreen,
|
|
|
|
.createNewDrawable = driCreateNewDrawable,
|
|
|
|
.createNewContextForAPI = driCreateNewContextForAPI,
|
|
|
|
.createContextAttribs = driCreateContextAttribs,
|
|
|
|
.createNewScreen2 = driSWRastCreateNewScreen2,
|
2013-09-26 19:35:31 +01:00
|
|
|
};
|
|
|
|
|
2010-04-22 20:47:41 +01:00
|
|
|
const __DRI2configQueryExtension dri2ConfigQueryExtension = {
|
2020-10-15 13:23:05 +01:00
|
|
|
.base = { __DRI2_CONFIG_QUERY, 2 },
|
2012-11-19 21:40:00 +00:00
|
|
|
|
|
|
|
.configQueryb = dri2ConfigQueryb,
|
|
|
|
.configQueryi = dri2ConfigQueryi,
|
|
|
|
.configQueryf = dri2ConfigQueryf,
|
2020-10-15 13:23:05 +01:00
|
|
|
.configQuerys = dri2ConfigQuerys,
|
2010-04-22 20:47:41 +01:00
|
|
|
};
|
|
|
|
|
2014-10-01 20:00:47 +01:00
|
|
|
const __DRI2flushControlExtension dri2FlushControlExtension = {
|
|
|
|
.base = { __DRI2_FLUSH_CONTROL, 1 }
|
|
|
|
};
|
|
|
|
|
2018-05-18 15:58:58 +01:00
|
|
|
/*
|
|
|
|
* Note: the first match is returned, which is important for formats like
|
|
|
|
* __DRI_IMAGE_FORMAT_R8 which maps to both MESA_FORMAT_{R,L}_UNORM8
|
|
|
|
*/
|
|
|
|
static const struct {
|
|
|
|
uint32_t image_format;
|
|
|
|
mesa_format mesa_format;
|
2019-11-07 01:18:13 +00:00
|
|
|
GLenum internal_format;
|
2018-05-18 15:58:58 +01:00
|
|
|
} format_mapping[] = {
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_RGB565,
|
|
|
|
.mesa_format = MESA_FORMAT_B5G6R5_UNORM,
|
|
|
|
.internal_format = GL_RGB565,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_ARGB1555,
|
|
|
|
.mesa_format = MESA_FORMAT_B5G5R5A1_UNORM,
|
|
|
|
.internal_format = GL_RGB5_A1,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_XRGB8888,
|
|
|
|
.mesa_format = MESA_FORMAT_B8G8R8X8_UNORM,
|
2020-06-22 23:19:38 +01:00
|
|
|
.internal_format = GL_RGB8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
2019-01-25 01:10:02 +00:00
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_ABGR16161616F,
|
|
|
|
.mesa_format = MESA_FORMAT_RGBA_FLOAT16,
|
|
|
|
.internal_format = GL_RGBA16F,
|
2019-01-25 01:10:02 +00:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_XBGR16161616F,
|
|
|
|
.mesa_format = MESA_FORMAT_RGBX_FLOAT16,
|
|
|
|
.internal_format = GL_RGBA16F,
|
2019-01-25 01:10:02 +00:00
|
|
|
},
|
2022-01-18 03:03:20 +00:00
|
|
|
{
|
|
|
|
.image_format = __DRI_IMAGE_FORMAT_ABGR16161616,
|
|
|
|
.mesa_format = MESA_FORMAT_RGBA_UNORM16,
|
|
|
|
.internal_format = GL_RGBA16,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.image_format = __DRI_IMAGE_FORMAT_XBGR16161616,
|
|
|
|
.mesa_format = MESA_FORMAT_RGBX_UNORM16,
|
|
|
|
.internal_format = GL_RGBA16,
|
|
|
|
},
|
2018-05-18 15:58:58 +01:00
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_ARGB2101010,
|
|
|
|
.mesa_format = MESA_FORMAT_B10G10R10A2_UNORM,
|
|
|
|
.internal_format = GL_RGB10_A2,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_XRGB2101010,
|
|
|
|
.mesa_format = MESA_FORMAT_B10G10R10X2_UNORM,
|
|
|
|
.internal_format = GL_RGB10_A2,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_ABGR2101010,
|
|
|
|
.mesa_format = MESA_FORMAT_R10G10B10A2_UNORM,
|
|
|
|
.internal_format = GL_RGB10_A2,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_XBGR2101010,
|
|
|
|
.mesa_format = MESA_FORMAT_R10G10B10X2_UNORM,
|
|
|
|
.internal_format = GL_RGB10_A2,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_ARGB8888,
|
|
|
|
.mesa_format = MESA_FORMAT_B8G8R8A8_UNORM,
|
|
|
|
.internal_format = GL_RGBA8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_ABGR8888,
|
|
|
|
.mesa_format = MESA_FORMAT_R8G8B8A8_UNORM,
|
|
|
|
.internal_format = GL_RGBA8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_XBGR8888,
|
|
|
|
.mesa_format = MESA_FORMAT_R8G8B8X8_UNORM,
|
2020-05-13 22:32:13 +01:00
|
|
|
.internal_format = GL_RGB8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_R8,
|
|
|
|
.mesa_format = MESA_FORMAT_R_UNORM8,
|
|
|
|
.internal_format = GL_R8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_R8,
|
|
|
|
.mesa_format = MESA_FORMAT_L_UNORM8,
|
|
|
|
.internal_format = GL_R8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
2018-11-10 00:23:08 +00:00
|
|
|
#if UTIL_ARCH_LITTLE_ENDIAN
|
2018-05-18 15:58:58 +01:00
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_GR88,
|
|
|
|
.mesa_format = MESA_FORMAT_RG_UNORM8,
|
|
|
|
.internal_format = GL_RG8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_GR88,
|
|
|
|
.mesa_format = MESA_FORMAT_LA_UNORM8,
|
|
|
|
.internal_format = GL_RG8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
2019-09-05 22:42:15 +01:00
|
|
|
#endif
|
2018-05-18 15:58:58 +01:00
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_SABGR8,
|
|
|
|
.mesa_format = MESA_FORMAT_R8G8B8A8_SRGB,
|
|
|
|
.internal_format = GL_SRGB8_ALPHA8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_SARGB8,
|
|
|
|
.mesa_format = MESA_FORMAT_B8G8R8A8_SRGB,
|
|
|
|
.internal_format = GL_SRGB8_ALPHA8,
|
2018-05-18 15:58:58 +01:00
|
|
|
},
|
2019-11-15 07:12:15 +00:00
|
|
|
{
|
|
|
|
.image_format = __DRI_IMAGE_FORMAT_SXRGB8,
|
2019-11-07 01:18:13 +00:00
|
|
|
.mesa_format = MESA_FORMAT_B8G8R8X8_SRGB,
|
|
|
|
.internal_format = GL_SRGB8_ALPHA8,
|
2019-11-15 07:12:15 +00:00
|
|
|
},
|
2018-06-06 12:57:18 +01:00
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_R16,
|
|
|
|
.mesa_format = MESA_FORMAT_R_UNORM16,
|
|
|
|
.internal_format = GL_R16,
|
2018-06-06 12:57:18 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_R16,
|
|
|
|
.mesa_format = MESA_FORMAT_L_UNORM16,
|
|
|
|
.internal_format = GL_R16,
|
2018-06-06 12:57:18 +01:00
|
|
|
},
|
2018-11-10 00:23:08 +00:00
|
|
|
#if UTIL_ARCH_LITTLE_ENDIAN
|
2018-06-06 12:57:18 +01:00
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_GR1616,
|
|
|
|
.mesa_format = MESA_FORMAT_RG_UNORM16,
|
|
|
|
.internal_format = GL_RG16,
|
2018-06-06 12:57:18 +01:00
|
|
|
},
|
|
|
|
{
|
2019-11-07 01:18:13 +00:00
|
|
|
.image_format = __DRI_IMAGE_FORMAT_GR1616,
|
|
|
|
.mesa_format = MESA_FORMAT_LA_UNORM16,
|
|
|
|
.internal_format = GL_RG16,
|
2018-06-06 12:57:18 +01:00
|
|
|
},
|
2019-08-29 23:45:18 +01:00
|
|
|
#endif
|
2018-05-18 15:58:58 +01:00
|
|
|
};
|
|
|
|
|
2013-11-05 01:29:08 +00:00
|
|
|
uint32_t
|
2014-01-04 22:11:43 +00:00
|
|
|
driGLFormatToImageFormat(mesa_format format)
|
2013-11-05 01:29:08 +00:00
|
|
|
{
|
2018-05-18 15:58:58 +01:00
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++)
|
|
|
|
if (format_mapping[i].mesa_format == format)
|
|
|
|
return format_mapping[i].image_format;
|
|
|
|
|
|
|
|
return __DRI_IMAGE_FORMAT_NONE;
|
2013-11-05 01:29:08 +00:00
|
|
|
}
|
|
|
|
|
2019-11-07 01:18:13 +00:00
|
|
|
uint32_t
|
|
|
|
driGLFormatToSizedInternalGLFormat(mesa_format format)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++)
|
|
|
|
if (format_mapping[i].mesa_format == format)
|
|
|
|
return format_mapping[i].internal_format;
|
|
|
|
|
|
|
|
return GL_NONE;
|
|
|
|
}
|
|
|
|
|
2014-01-04 22:11:43 +00:00
|
|
|
mesa_format
|
2013-11-05 01:29:08 +00:00
|
|
|
driImageFormatToGLFormat(uint32_t image_format)
|
|
|
|
{
|
2018-05-18 15:58:58 +01:00
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++)
|
|
|
|
if (format_mapping[i].image_format == image_format)
|
|
|
|
return format_mapping[i].mesa_format;
|
|
|
|
|
|
|
|
return MESA_FORMAT_NONE;
|
2013-11-05 01:29:08 +00:00
|
|
|
}
|
2013-11-05 02:09:51 +00:00
|
|
|
|
|
|
|
/** Image driver interface */
|
|
|
|
const __DRIimageDriverExtension driImageDriverExtension = {
|
2014-02-12 18:51:49 +00:00
|
|
|
.base = { __DRI_IMAGE_DRIVER, 1 },
|
2013-11-05 02:09:51 +00:00
|
|
|
|
|
|
|
.createNewScreen2 = driCreateNewScreen2,
|
|
|
|
.createNewDrawable = driCreateNewDrawable,
|
|
|
|
.getAPIMask = driGetAPIMask,
|
|
|
|
.createContextAttribs = driCreateContextAttribs,
|
|
|
|
};
|