2012-03-16 09:39:01 -06: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 12:39:58 +00: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.
|
|
|
|
|
*
|
|
|
|
|
* 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 12:01:56 -07:00
|
|
|
#include <stdbool.h>
|
2013-09-26 11:35:31 -07:00
|
|
|
#ifndef __NOT_HAVE_DRM_H
|
2011-11-03 12:46:08 +02:00
|
|
|
#include <xf86drm.h>
|
2013-09-26 11:35:31 -07:00
|
|
|
#endif
|
2004-06-07 21:23:12 +00:00
|
|
|
#include "dri_util.h"
|
2008-05-11 14:43:22 +03:00
|
|
|
#include "utils.h"
|
2010-04-22 12:49:03 -07:00
|
|
|
#include "xmlpool.h"
|
2010-08-27 14:43:39 -07:00
|
|
|
#include "../glsl/glsl_parser_extras.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 12:01:56 -07:00
|
|
|
#include "main/version.h"
|
|
|
|
|
#include "main/macros.h"
|
2010-04-22 12:49:03 -07:00
|
|
|
|
|
|
|
|
PUBLIC const char __dri2ConfigOptions[] =
|
|
|
|
|
DRI_CONF_BEGIN
|
|
|
|
|
DRI_CONF_SECTION_PERFORMANCE
|
|
|
|
|
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
|
|
|
|
|
DRI_CONF_SECTION_END
|
|
|
|
|
DRI_CONF_END;
|
|
|
|
|
|
2011-11-04 16:14:58 +02: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];
|
2013-09-26 11:35:31 -07:00
|
|
|
if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
|
|
|
|
|
psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
|
2011-11-04 16:14:58 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-26 10:33:12 -07: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 16:14:58 +02:00
|
|
|
static __DRIscreen *
|
|
|
|
|
dri2CreateNewScreen(int scrn, int fd,
|
|
|
|
|
const __DRIextension **extensions,
|
|
|
|
|
const __DRIconfig ***driver_configs, void *data)
|
|
|
|
|
{
|
|
|
|
|
static const __DRIextension *emptyExtensionList[] = { NULL };
|
|
|
|
|
__DRIscreen *psp;
|
|
|
|
|
|
|
|
|
|
psp = calloc(1, sizeof(*psp));
|
|
|
|
|
if (!psp)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2013-09-26 10:51:29 -07:00
|
|
|
psp->driver = &driDriverAPI;
|
|
|
|
|
|
2011-11-04 16:14:58 +02:00
|
|
|
setupLoaderExtensions(psp, extensions);
|
|
|
|
|
|
2013-09-26 11:35:31 -07:00
|
|
|
#ifndef __NOT_HAVE_DRM_H
|
|
|
|
|
if (fd != -1) {
|
|
|
|
|
drmVersionPtr version = drmGetVersion(fd);
|
|
|
|
|
if (version) {
|
|
|
|
|
psp->drm_version.major = version->version_major;
|
|
|
|
|
psp->drm_version.minor = version->version_minor;
|
|
|
|
|
psp->drm_version.patch = version->version_patchlevel;
|
|
|
|
|
drmFreeVersion(version);
|
|
|
|
|
}
|
2011-11-04 16:14:58 +02:00
|
|
|
}
|
2013-09-26 11:35:31 -07:00
|
|
|
#endif
|
2011-11-04 16:14:58 +02:00
|
|
|
|
2011-11-04 16:35:49 +02:00
|
|
|
psp->loaderPrivate = data;
|
|
|
|
|
|
2011-11-04 16:14:58 +02:00
|
|
|
psp->extensions = emptyExtensionList;
|
|
|
|
|
psp->fd = fd;
|
|
|
|
|
psp->myNum = scrn;
|
|
|
|
|
|
2013-09-26 10:51:29 -07:00
|
|
|
*driver_configs = psp->driver->InitScreen(psp);
|
2011-11-04 16:14:58 +02:00
|
|
|
if (*driver_configs == NULL) {
|
|
|
|
|
free(psp);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
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 12:01:56 -07:00
|
|
|
int gl_version_override = _mesa_get_gl_version_override();
|
|
|
|
|
if (gl_version_override >= 31) {
|
|
|
|
|
psp->max_gl_core_version = MAX2(psp->max_gl_core_version,
|
|
|
|
|
gl_version_override);
|
|
|
|
|
} else {
|
|
|
|
|
psp->max_gl_compat_version = MAX2(psp->max_gl_compat_version,
|
|
|
|
|
gl_version_override);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
psp->api_mask = (1 << __DRI_API_OPENGL);
|
|
|
|
|
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);
|
|
|
|
|
|
2013-06-26 15:22:13 -07:00
|
|
|
driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions);
|
2011-11-04 16:35:49 +02:00
|
|
|
driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2");
|
2011-11-04 16:14:58 +02: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 12:01:56 -07:00
|
|
|
|
2011-11-04 16:14:58 +02:00
|
|
|
return psp;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-26 11:35:31 -07:00
|
|
|
/** swrast driver createNewScreen entrypoint. */
|
|
|
|
|
static __DRIscreen *
|
|
|
|
|
driCreateNewScreen(int scrn, const __DRIextension **extensions,
|
|
|
|
|
const __DRIconfig ***driver_configs, void *data)
|
|
|
|
|
{
|
|
|
|
|
return dri2CreateNewScreen(scrn, -1, extensions, driver_configs, data);
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-04 16:14:58 +02:00
|
|
|
/**
|
|
|
|
|
* Destroy the per-screen private information.
|
|
|
|
|
*
|
|
|
|
|
* \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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
_mesa_destroy_shader_compiler();
|
|
|
|
|
|
2013-09-26 10:51:29 -07:00
|
|
|
psp->driver->DestroyScreen(psp);
|
2011-11-04 16:14:58 +02:00
|
|
|
|
|
|
|
|
driDestroyOptionCache(&psp->optionCache);
|
|
|
|
|
driDestroyOptionInfo(&psp->optionInfo);
|
|
|
|
|
|
|
|
|
|
free(psp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const __DRIextension **driGetExtensions(__DRIscreen *psp)
|
|
|
|
|
{
|
|
|
|
|
return psp->extensions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*@}*/
|
|
|
|
|
|
|
|
|
|
|
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 12:01:56 -07: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 16:19:22 +02:00
|
|
|
/*****************************************************************/
|
|
|
|
|
/** \name Context handling functions */
|
|
|
|
|
/*****************************************************************/
|
|
|
|
|
/*@{*/
|
|
|
|
|
|
|
|
|
|
static __DRIcontext *
|
2011-11-30 18:05:36 -08:00
|
|
|
dri2CreateContextAttribs(__DRIscreen *screen, int api,
|
|
|
|
|
const __DRIconfig *config,
|
|
|
|
|
__DRIcontext *shared,
|
|
|
|
|
unsigned num_attribs,
|
|
|
|
|
const uint32_t *attribs,
|
|
|
|
|
unsigned *error,
|
|
|
|
|
void *data)
|
2011-11-04 16:19:22 +02:00
|
|
|
{
|
|
|
|
|
__DRIcontext *context;
|
|
|
|
|
const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
|
|
|
|
|
void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
|
|
|
|
|
gl_api mesa_api;
|
2011-11-30 18:05:36 -08:00
|
|
|
unsigned major_version = 1;
|
|
|
|
|
unsigned minor_version = 0;
|
|
|
|
|
uint32_t flags = 0;
|
|
|
|
|
|
|
|
|
|
assert((num_attribs == 0) || (attribs != NULL));
|
2011-11-04 16:19:22 +02:00
|
|
|
|
2011-11-30 18:05:36 -08:00
|
|
|
if (!(screen->api_mask & (1 << api))) {
|
|
|
|
|
*error = __DRI_CTX_ERROR_BAD_API;
|
2011-11-04 16:19:22 +02:00
|
|
|
return NULL;
|
2011-11-30 18:05:36 -08:00
|
|
|
}
|
2011-11-04 16:19:22 +02:00
|
|
|
|
|
|
|
|
switch (api) {
|
|
|
|
|
case __DRI_API_OPENGL:
|
2012-11-27 12:26:51 -08:00
|
|
|
mesa_api = API_OPENGL_COMPAT;
|
2011-11-30 18:05:36 -08:00
|
|
|
break;
|
2011-11-04 16:19:22 +02:00
|
|
|
case __DRI_API_GLES:
|
2011-11-30 18:05:36 -08:00
|
|
|
mesa_api = API_OPENGLES;
|
|
|
|
|
break;
|
2011-11-04 16:19:22 +02:00
|
|
|
case __DRI_API_GLES2:
|
2012-11-20 13:27:14 -08:00
|
|
|
case __DRI_API_GLES3:
|
2011-11-30 18:05:36 -08:00
|
|
|
mesa_api = API_OPENGLES2;
|
|
|
|
|
break;
|
|
|
|
|
case __DRI_API_OPENGL_CORE:
|
2012-08-07 11:26:19 -07:00
|
|
|
mesa_api = API_OPENGL_CORE;
|
|
|
|
|
break;
|
2011-11-04 16:19:22 +02:00
|
|
|
default:
|
2011-11-30 18:05:36 -08: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:
|
|
|
|
|
major_version = attribs[i * 2 + 1];
|
|
|
|
|
break;
|
|
|
|
|
case __DRI_CTX_ATTRIB_MINOR_VERSION:
|
|
|
|
|
minor_version = attribs[i * 2 + 1];
|
|
|
|
|
break;
|
|
|
|
|
case __DRI_CTX_ATTRIB_FLAGS:
|
|
|
|
|
flags = attribs[i * 2 + 1];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
/* We can't create a context that satisfies the requirements of an
|
|
|
|
|
* attribute that we don't understand. Return failure.
|
|
|
|
|
*/
|
2011-12-01 14:06:58 -08:00
|
|
|
assert(!"Should not get here.");
|
|
|
|
|
*error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
|
2011-11-30 18:05:36 -08:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-07 11:26:19 -07:00
|
|
|
/* Mesa does not support the GL_ARB_compatibilty extension or the
|
2012-11-27 12:26:51 -08:00
|
|
|
* compatibility profile. This means that we treat a API_OPENGL_COMPAT 3.1 as
|
|
|
|
|
* API_OPENGL_CORE and reject API_OPENGL_COMPAT 3.2+.
|
2012-08-07 11:26:19 -07:00
|
|
|
*/
|
2012-11-27 12:26:51 -08:00
|
|
|
if (mesa_api == API_OPENGL_COMPAT && major_version == 3 && minor_version == 1)
|
2012-08-07 11:26:19 -07:00
|
|
|
mesa_api = API_OPENGL_CORE;
|
|
|
|
|
|
2012-11-27 12:26:51 -08:00
|
|
|
if (mesa_api == API_OPENGL_COMPAT
|
2012-08-07 11:26:19 -07:00
|
|
|
&& ((major_version > 3)
|
|
|
|
|
|| (major_version == 3 && minor_version >= 2))) {
|
|
|
|
|
*error = __DRI_CTX_ERROR_BAD_API;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-18 14:26:24 -07:00
|
|
|
/* The EGL_KHR_create_context spec says:
|
|
|
|
|
*
|
|
|
|
|
* "Flags are only defined for OpenGL context creation, and specifying
|
|
|
|
|
* a flags value other than zero for other types of contexts,
|
|
|
|
|
* including OpenGL ES contexts, will generate an error."
|
|
|
|
|
*
|
|
|
|
|
* The GLX_EXT_create_context_es2_profile specification doesn't say
|
|
|
|
|
* anything specific about this case. However, none of the known flags
|
|
|
|
|
* have any meaning in an ES context, so this seems safe.
|
|
|
|
|
*/
|
2012-11-27 12:26:51 -08:00
|
|
|
if (mesa_api != API_OPENGL_COMPAT
|
2012-08-07 09:58:55 -07:00
|
|
|
&& mesa_api != API_OPENGL_CORE
|
2012-07-18 14:26:24 -07:00
|
|
|
&& flags != 0) {
|
|
|
|
|
*error = __DRI_CTX_ERROR_BAD_FLAG;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-30 18:05:36 -08: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 09:23:50 -07:00
|
|
|
* Forward-looking contexts are supported by silently converting the
|
|
|
|
|
* requested API to API_OPENGL_CORE.
|
2011-11-30 18:05:36 -08:00
|
|
|
*
|
|
|
|
|
* In Mesa, a debug context is the same as a regular context.
|
|
|
|
|
*/
|
2011-12-01 14:06:58 -08:00
|
|
|
if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) {
|
2012-08-17 09:23:50 -07:00
|
|
|
mesa_api = API_OPENGL_CORE;
|
2011-12-01 14:06:58 -08:00
|
|
|
}
|
|
|
|
|
|
2012-08-17 09:23:50 -07:00
|
|
|
if ((flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE))
|
|
|
|
|
!= 0) {
|
2011-12-01 14:06:58 -08:00
|
|
|
*error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
|
|
|
|
|
return NULL;
|
2011-11-04 16:19:22 +02: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 12:01:56 -07:00
|
|
|
if (!validate_context_version(screen, mesa_api,
|
|
|
|
|
major_version, minor_version, error))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2012-09-26 11:08:11 -07:00
|
|
|
context = calloc(1, sizeof *context);
|
2011-11-30 18:05:36 -08:00
|
|
|
if (!context) {
|
|
|
|
|
*error = __DRI_CTX_ERROR_NO_MEMORY;
|
2011-11-04 16:19:22 +02:00
|
|
|
return NULL;
|
2011-11-30 18:05:36 -08:00
|
|
|
}
|
2011-11-04 16:19:22 +02:00
|
|
|
|
2011-11-04 16:35:49 +02:00
|
|
|
context->loaderPrivate = data;
|
|
|
|
|
|
2011-11-04 16:19:22 +02:00
|
|
|
context->driScreenPriv = screen;
|
|
|
|
|
context->driDrawablePriv = NULL;
|
2011-11-04 16:35:49 +02:00
|
|
|
context->driReadablePriv = NULL;
|
2011-11-04 16:19:22 +02:00
|
|
|
|
2013-09-26 10:51:29 -07:00
|
|
|
if (!screen->driver->CreateContext(mesa_api, modes, context,
|
|
|
|
|
major_version, minor_version,
|
|
|
|
|
flags, error, shareCtx) ) {
|
2011-11-04 16:19:22 +02:00
|
|
|
free(context);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-30 18:05:36 -08:00
|
|
|
*error = __DRI_CTX_ERROR_SUCCESS;
|
2011-11-04 16:19:22 +02:00
|
|
|
return context;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-30 18:05:36 -08:00
|
|
|
static __DRIcontext *
|
|
|
|
|
dri2CreateNewContextForAPI(__DRIscreen *screen, int api,
|
|
|
|
|
const __DRIconfig *config,
|
|
|
|
|
__DRIcontext *shared, void *data)
|
|
|
|
|
{
|
|
|
|
|
unsigned error;
|
|
|
|
|
|
|
|
|
|
return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL,
|
2012-01-02 13:38:11 -08:00
|
|
|
&error, data);
|
2011-11-30 18:05:36 -08:00
|
|
|
}
|
2011-11-04 16:19:22 +02:00
|
|
|
|
|
|
|
|
static __DRIcontext *
|
|
|
|
|
dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
|
|
|
|
|
__DRIcontext *shared, void *data)
|
|
|
|
|
{
|
2011-11-04 16:35:49 +02:00
|
|
|
return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
|
|
|
|
|
config, shared, data);
|
2011-11-04 16:19:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Destroy the per-context private information.
|
|
|
|
|
*
|
|
|
|
|
* \internal
|
|
|
|
|
* This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
|
|
|
|
|
* drmDestroyContext(), and finally frees \p contextPrivate.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
driDestroyContext(__DRIcontext *pcp)
|
|
|
|
|
{
|
|
|
|
|
if (pcp) {
|
2013-09-26 10:51:29 -07:00
|
|
|
pcp->driScreenPriv->driver->DestroyContext(pcp);
|
2011-11-04 16:19:22 +02: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 12:39:58 +00:00
|
|
|
/*****************************************************************/
|
|
|
|
|
/** \name Context (un)binding functions */
|
|
|
|
|
/*****************************************************************/
|
|
|
|
|
/*@{*/
|
|
|
|
|
|
2011-11-04 16:24:19 +02: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);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-26 10:51:29 -07:00
|
|
|
return pcp->driScreenPriv->driver->MakeCurrent(pcp, pdp, prp);
|
2011-11-04 16:24:19 +02:00
|
|
|
}
|
|
|
|
|
|
2004-04-14 12:39:58 +00:00
|
|
|
/**
|
|
|
|
|
* Unbind context.
|
|
|
|
|
*
|
2007-05-10 15:52:22 -04:00
|
|
|
* \param scrn the screen.
|
2004-04-14 12:39:58 +00:00
|
|
|
* \param gc context.
|
|
|
|
|
*
|
|
|
|
|
* \return \c GL_TRUE on success, or \c GL_FALSE on failure.
|
|
|
|
|
*
|
|
|
|
|
* \internal
|
|
|
|
|
* This function calls __DriverAPIRec::UnbindContext, and then decrements
|
2010-01-01 17:09:12 -05:00
|
|
|
* __DRIdrawableRec::refcount which must be non-zero for a successful
|
2004-04-14 12:39:58 +00:00
|
|
|
* return.
|
|
|
|
|
*
|
|
|
|
|
* While casting the opaque private pointers associated with the parameters
|
|
|
|
|
* into their respective real types it also assures they are not \c NULL.
|
|
|
|
|
*/
|
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 19:26:59 -04:00
|
|
|
static int driUnbindContext(__DRIcontext *pcp)
|
2004-04-14 12:39:58 +00:00
|
|
|
{
|
2009-08-25 05:03:58 +03:00
|
|
|
__DRIdrawable *pdp;
|
|
|
|
|
__DRIdrawable *prp;
|
2004-04-14 12:39:58 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Assume error checking is done properly in glXMakeCurrent before
|
2005-07-24 06:29:14 +00:00
|
|
|
** calling driUnbindContext.
|
2004-04-14 12:39:58 +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 19:26:59 -04:00
|
|
|
if (pcp == NULL)
|
2011-11-04 16:35:49 +02:00
|
|
|
return GL_FALSE;
|
2004-04-14 12:39:58 +00:00
|
|
|
|
2009-08-25 05:03:58 +03:00
|
|
|
pdp = pcp->driDrawablePriv;
|
|
|
|
|
prp = pcp->driReadablePriv;
|
2004-04-14 12:39:58 +00:00
|
|
|
|
2009-08-25 05:03:58 +03:00
|
|
|
/* already unbound */
|
|
|
|
|
if (!pdp && !prp)
|
2011-11-04 16:35:49 +02:00
|
|
|
return GL_TRUE;
|
|
|
|
|
|
2013-09-26 10:51:29 -07:00
|
|
|
pcp->driScreenPriv->driver->UnbindContext(pcp);
|
2004-04-14 12:39:58 +00:00
|
|
|
|
2010-02-27 16:51:17 -08:00
|
|
|
assert(pdp);
|
2009-08-25 05:03:58 +03:00
|
|
|
if (pdp->refcount == 0) {
|
|
|
|
|
/* ERROR!!! */
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dri_put_drawable(pdp);
|
|
|
|
|
|
|
|
|
|
if (prp != pdp) {
|
2011-11-04 16:35:49 +02:00
|
|
|
if (prp->refcount == 0) {
|
2009-08-25 05:03:58 +03:00
|
|
|
/* ERROR!!! */
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-04 16:35:49 +02:00
|
|
|
dri_put_drawable(prp);
|
2009-08-25 05:03:58 +03:00
|
|
|
}
|
|
|
|
|
|
2011-11-04 16:35:49 +02:00
|
|
|
pcp->driDrawablePriv = NULL;
|
|
|
|
|
pcp->driReadablePriv = NULL;
|
2009-08-25 05:03:58 +03:00
|
|
|
|
2004-04-14 12:39:58 +00:00
|
|
|
return GL_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-04 16:24:19 +02:00
|
|
|
/*@}*/
|
2004-04-14 12:39:58 +00:00
|
|
|
|
|
|
|
|
|
2011-11-04 16:25:51 +02: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 10:51:29 -07:00
|
|
|
pdp->driScreenPriv->driver->DestroyBuffer(pdp);
|
2011-11-04 16:25:51 +02: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 19:26:59 -04:00
|
|
|
static __DRIdrawable *
|
2011-10-28 15:14:41 -04:00
|
|
|
dri2CreateNewDrawable(__DRIscreen *screen,
|
|
|
|
|
const __DRIconfig *config,
|
2011-11-04 16:35:49 +02:00
|
|
|
void *data)
|
2004-04-14 12:39:58 +00:00
|
|
|
{
|
2011-10-28 15:14:41 -04:00
|
|
|
__DRIdrawable *pdraw;
|
2004-04-14 12:39:58 +00:00
|
|
|
|
2011-10-28 15:14:41 -04:00
|
|
|
pdraw = malloc(sizeof *pdraw);
|
|
|
|
|
if (!pdraw)
|
2004-04-14 12:39:58 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
2011-11-04 16:35:49 +02:00
|
|
|
pdraw->loaderPrivate = data;
|
|
|
|
|
|
|
|
|
|
pdraw->driScreenPriv = screen;
|
2011-10-28 15:14:41 -04:00
|
|
|
pdraw->driContextPriv = NULL;
|
2011-11-04 16:35:49 +02:00
|
|
|
pdraw->refcount = 0;
|
2011-10-28 15:14:41 -04:00
|
|
|
pdraw->lastStamp = 0;
|
|
|
|
|
pdraw->w = 0;
|
|
|
|
|
pdraw->h = 0;
|
|
|
|
|
|
2011-11-04 16:35:49 +02:00
|
|
|
dri_get_drawable(pdraw);
|
|
|
|
|
|
2013-09-26 10:51:29 -07:00
|
|
|
if (!screen->driver->CreateBuffer(screen, pdraw, &config->modes,
|
|
|
|
|
GL_FALSE)) {
|
2011-10-28 15:14:41 -04:00
|
|
|
free(pdraw);
|
2004-04-14 12:39:58 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-28 16:22:03 -04:00
|
|
|
pdraw->dri2.stamp = pdraw->lastStamp + 1;
|
2010-02-08 19:27:56 +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 19:26:59 -04:00
|
|
|
return pdraw;
|
2004-04-14 12:39:58 +00:00
|
|
|
}
|
|
|
|
|
|
2011-11-04 16:25:51 +02:00
|
|
|
static void
|
|
|
|
|
driDestroyDrawable(__DRIdrawable *pdp)
|
|
|
|
|
{
|
|
|
|
|
dri_put_drawable(pdp);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-04 11:59:12 +01:00
|
|
|
static __DRIbuffer *
|
|
|
|
|
dri2AllocateBuffer(__DRIscreen *screen,
|
|
|
|
|
unsigned int attachment, unsigned int format,
|
|
|
|
|
int width, int height)
|
|
|
|
|
{
|
2013-09-26 10:51:29 -07:00
|
|
|
return screen->driver->AllocateBuffer(screen, attachment, format,
|
|
|
|
|
width, height);
|
2011-02-04 11:59:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
|
|
|
|
|
{
|
2013-09-26 10:51:29 -07:00
|
|
|
screen->driver->ReleaseBuffer(screen, buffer);
|
2011-02-04 11:59:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-04-22 12:47:41 -07:00
|
|
|
static int
|
|
|
|
|
dri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val)
|
|
|
|
|
{
|
|
|
|
|
if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
*val = driQueryOptionb(&screen->optionCache, var);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
dri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val)
|
|
|
|
|
{
|
|
|
|
|
if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
|
|
|
|
|
!driCheckOption(&screen->optionCache, var, DRI_ENUM))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
*val = driQueryOptioni(&screen->optionCache, var);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val)
|
|
|
|
|
{
|
|
|
|
|
if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
*val = driQueryOptionf(&screen->optionCache, var);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-27 11:04:51 -04:00
|
|
|
static unsigned int
|
|
|
|
|
dri2GetAPIMask(__DRIscreen *screen)
|
|
|
|
|
{
|
|
|
|
|
return screen->api_mask;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-26 11:35:31 -07: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 10:51:29 -07:00
|
|
|
pdp->driScreenPriv->driver->SwapBuffers(pdp);
|
2013-09-26 11:35:31 -07: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 19:26:59 -04:00
|
|
|
|
2008-08-13 11:46:25 -04: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 19:26:59 -04:00
|
|
|
const __DRIcoreExtension driCoreExtension = {
|
2012-11-19 13:40:00 -08:00
|
|
|
.base = { __DRI_CORE, __DRI_CORE_VERSION },
|
|
|
|
|
|
|
|
|
|
.createNewScreen = NULL,
|
|
|
|
|
.destroyScreen = driDestroyScreen,
|
|
|
|
|
.getExtensions = driGetExtensions,
|
|
|
|
|
.getConfigAttrib = driGetConfigAttrib,
|
|
|
|
|
.indexConfigAttrib = driIndexConfigAttrib,
|
|
|
|
|
.createNewDrawable = NULL,
|
|
|
|
|
.destroyDrawable = driDestroyDrawable,
|
2013-09-26 11:35:31 -07:00
|
|
|
.swapBuffers = driSwapBuffers, /* swrast */
|
|
|
|
|
.createNewContext = dri2CreateNewContext, /* swrast */
|
2012-11-19 13:40:00 -08: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 19:26:59 -04:00
|
|
|
};
|
|
|
|
|
|
2010-01-01 17:56:29 -05:00
|
|
|
/** DRI2 interface */
|
2008-08-13 11:46:25 -04:00
|
|
|
const __DRIdri2Extension driDRI2Extension = {
|
2012-11-19 13:40:00 -08:00
|
|
|
.base = { __DRI_DRI2, 3 },
|
|
|
|
|
|
|
|
|
|
.createNewScreen = dri2CreateNewScreen,
|
|
|
|
|
.createNewDrawable = dri2CreateNewDrawable,
|
|
|
|
|
.createNewContext = dri2CreateNewContext,
|
|
|
|
|
.getAPIMask = dri2GetAPIMask,
|
|
|
|
|
.createNewContextForAPI = dri2CreateNewContextForAPI,
|
|
|
|
|
.allocateBuffer = dri2AllocateBuffer,
|
|
|
|
|
.releaseBuffer = dri2ReleaseBuffer,
|
|
|
|
|
.createContextAttribs = dri2CreateContextAttribs
|
2008-08-13 11:46:25 -04:00
|
|
|
};
|
|
|
|
|
|
2013-09-26 11:35:31 -07:00
|
|
|
const __DRIswrastExtension driSWRastExtension = {
|
|
|
|
|
{ __DRI_SWRAST, __DRI_SWRAST_VERSION },
|
|
|
|
|
driCreateNewScreen,
|
|
|
|
|
dri2CreateNewDrawable,
|
|
|
|
|
dri2CreateNewContextForAPI,
|
|
|
|
|
dri2CreateContextAttribs
|
|
|
|
|
};
|
|
|
|
|
|
2010-04-22 12:47:41 -07:00
|
|
|
const __DRI2configQueryExtension dri2ConfigQueryExtension = {
|
2012-11-19 13:40:00 -08:00
|
|
|
.base = { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
|
|
|
|
|
|
|
|
|
|
.configQueryb = dri2ConfigQueryb,
|
|
|
|
|
.configQueryi = dri2ConfigQueryi,
|
|
|
|
|
.configQueryf = dri2ConfigQueryf,
|
2010-04-22 12:47:41 -07:00
|
|
|
};
|
|
|
|
|
|
2010-02-08 19:27:56 +01:00
|
|
|
void
|
|
|
|
|
dri2InvalidateDrawable(__DRIdrawable *drawable)
|
|
|
|
|
{
|
|
|
|
|
drawable->dri2.stamp++;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-28 16:49:44 -04:00
|
|
|
/**
|
|
|
|
|
* Check that the gl_framebuffer associated with dPriv is the right size.
|
|
|
|
|
* Resize the gl_framebuffer if needed.
|
|
|
|
|
* It's expected that the dPriv->driverPrivate member points to a
|
|
|
|
|
* gl_framebuffer object.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv)
|
|
|
|
|
{
|
|
|
|
|
struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate;
|
|
|
|
|
if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) {
|
|
|
|
|
ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h);
|
|
|
|
|
/* if the driver needs the hw lock for ResizeBuffers, the drawable
|
|
|
|
|
might have changed again by now */
|
|
|
|
|
assert(fb->Width == dPriv->w);
|
|
|
|
|
assert(fb->Height == dPriv->h);
|
|
|
|
|
}
|
|
|
|
|
}
|