diff options
Diffstat (limited to 'mesalib/src/mesa/drivers/dri/common/dri_util.c')
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/dri_util.c | 533 |
1 files changed, 256 insertions, 277 deletions
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index da4e39f9c..1640c1448 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -15,12 +15,7 @@ */ -#include <assert.h> -#include <stdarg.h> -#include <stdio.h> - -#include "main/imports.h" - +#include <xf86drm.h> #include "dri_util.h" #include "utils.h" #include "xmlpool.h" @@ -35,18 +30,230 @@ PUBLIC const char __dri2ConfigOptions[] = static const uint __dri2NConfigOptions = 1; -#ifndef GLX_OML_sync_control -typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator); -#endif +/*****************************************************************/ +/** \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]; + } +} + +static __DRIscreen * +dri2CreateNewScreen(int scrn, int fd, + const __DRIextension **extensions, + const __DRIconfig ***driver_configs, void *data) +{ + static const __DRIextension *emptyExtensionList[] = { NULL }; + __DRIscreen *psp; + drmVersionPtr version; + + psp = calloc(1, sizeof(*psp)); + if (!psp) + return NULL; + + setupLoaderExtensions(psp, extensions); + + 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); + } + + psp->loaderPrivate = data; + + psp->extensions = emptyExtensionList; + psp->fd = fd; + psp->myNum = scrn; + + psp->api_mask = (1 << __DRI_API_OPENGL); + + *driver_configs = driDriverAPI.InitScreen(psp); + if (*driver_configs == NULL) { + free(psp); + return NULL; + } + + driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions, __dri2NConfigOptions); + driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2"); + + return psp; +} + +/** + * 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(); + + driDriverAPI.DestroyScreen(psp); + + driDestroyOptionCache(&psp->optionCache); + driDestroyOptionInfo(&psp->optionInfo); + + free(psp); + } +} + +static const __DRIextension **driGetExtensions(__DRIscreen *psp) +{ + return psp->extensions; +} + +/*@}*/ + + +/*****************************************************************/ +/** \name Context handling functions */ +/*****************************************************************/ +/*@{*/ + +static __DRIcontext * +dri2CreateNewContextForAPI(__DRIscreen *screen, int api, + const __DRIconfig *config, + __DRIcontext *shared, void *data) +{ + __DRIcontext *context; + const struct gl_config *modes = (config != NULL) ? &config->modes : NULL; + void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; + gl_api mesa_api; + + if (!(screen->api_mask & (1 << api))) + return NULL; + + switch (api) { + case __DRI_API_OPENGL: + mesa_api = API_OPENGL; + break; + case __DRI_API_GLES: + mesa_api = API_OPENGLES; + break; + case __DRI_API_GLES2: + mesa_api = API_OPENGLES2; + break; + default: + return NULL; + } + + context = malloc(sizeof *context); + if (!context) + return NULL; + + context->loaderPrivate = data; + + context->driScreenPriv = screen; + context->driDrawablePriv = NULL; + context->driReadablePriv = NULL; + + if (!driDriverAPI.CreateContext(mesa_api, modes, context, shareCtx) ) { + free(context); + return NULL; + } + + return context; +} + + +static __DRIcontext * +dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, + __DRIcontext *shared, void *data) +{ + return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL, + config, shared, data); +} + +/** + * 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) { + driDriverAPI.DestroyContext(pcp); + free(pcp); + } +} + +static int +driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) +{ + (void) dest; + (void) src; + (void) mask; + return GL_FALSE; +} + +/*@}*/ -static void dri_get_drawable(__DRIdrawable *pdp); -static void dri_put_drawable(__DRIdrawable *pdp); /*****************************************************************/ /** \name Context (un)binding functions */ /*****************************************************************/ /*@{*/ +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); + } + + return driDriverAPI.MakeCurrent(pcp, pdp, prp); +} + /** * Unbind context. * @@ -65,7 +272,6 @@ static void dri_put_drawable(__DRIdrawable *pdp); */ static int driUnbindContext(__DRIcontext *pcp) { - __DRIscreen *psp; __DRIdrawable *pdp; __DRIdrawable *prp; @@ -75,17 +281,16 @@ static int driUnbindContext(__DRIcontext *pcp) */ if (pcp == NULL) - return GL_FALSE; + return GL_FALSE; - psp = pcp->driScreenPriv; pdp = pcp->driDrawablePriv; prp = pcp->driReadablePriv; /* already unbound */ if (!pdp && !prp) - return GL_TRUE; - /* Let driver unbind drawable from context */ - (*psp->DriverAPI.UnbindContext)(pcp); + return GL_TRUE; + + driDriverAPI.UnbindContext(pcp); assert(pdp); if (pdp->refcount == 0) { @@ -96,63 +301,48 @@ static int driUnbindContext(__DRIcontext *pcp) dri_put_drawable(pdp); if (prp != pdp) { - if (prp->refcount == 0) { + if (prp->refcount == 0) { /* ERROR!!! */ return GL_FALSE; } - dri_put_drawable(prp); + dri_put_drawable(prp); } - /* XXX this is disabled so that if we call SwapBuffers on an unbound * window we can determine the last context bound to the window and * use that context's lock. (BrianP, 2-Dec-2000) */ - pcp->driDrawablePriv = pcp->driReadablePriv = NULL; + pcp->driDrawablePriv = NULL; + pcp->driReadablePriv = NULL; return GL_TRUE; } -/** - * 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) -{ - __DRIscreen *psp = NULL; +/*@}*/ - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driUnbindContext. - */ - if (!pcp) - return GL_FALSE; +static void dri_get_drawable(__DRIdrawable *pdp) +{ + pdp->refcount++; +} - /* Bind the drawable to the context */ - psp = pcp->driScreenPriv; - pcp->driDrawablePriv = pdp; - pcp->driReadablePriv = prp; +static void dri_put_drawable(__DRIdrawable *pdp) +{ if (pdp) { - pdp->driContextPriv = pcp; - dri_get_drawable(pdp); - } - if (prp && pdp != prp) { - dri_get_drawable(prp); - } + pdp->refcount--; + if (pdp->refcount) + return; - /* Call device-specific MakeCurrent */ - return (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); + driDriverAPI.DestroyBuffer(pdp); + free(pdp); + } } static __DRIdrawable * dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config, - void *loaderPrivate) + void *data) { __DRIdrawable *pdraw; @@ -160,15 +350,18 @@ dri2CreateNewDrawable(__DRIscreen *screen, if (!pdraw) return NULL; + pdraw->loaderPrivate = data; + + pdraw->driScreenPriv = screen; pdraw->driContextPriv = NULL; - pdraw->loaderPrivate = loaderPrivate; - pdraw->refcount = 1; + pdraw->refcount = 0; pdraw->lastStamp = 0; pdraw->w = 0; pdraw->h = 0; - pdraw->driScreenPriv = screen; - if (!(*screen->DriverAPI.CreateBuffer)(screen, pdraw, &config->modes, 0)) { + dri_get_drawable(pdraw); + + if (!driDriverAPI.CreateBuffer(screen, pdraw, &config->modes, GL_FALSE)) { free(pdraw); return NULL; } @@ -178,19 +371,25 @@ dri2CreateNewDrawable(__DRIscreen *screen, return pdraw; } +static void +driDestroyDrawable(__DRIdrawable *pdp) +{ + dri_put_drawable(pdp); +} + static __DRIbuffer * dri2AllocateBuffer(__DRIscreen *screen, unsigned int attachment, unsigned int format, int width, int height) { - return (*screen->DriverAPI.AllocateBuffer)(screen, attachment, format, - width, height); + return driDriverAPI.AllocateBuffer(screen, attachment, format, + width, height); } static void dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer) { - (*screen->DriverAPI.ReleaseBuffer)(screen, buffer); + driDriverAPI.ReleaseBuffer(screen, buffer); } @@ -228,232 +427,12 @@ dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val) return 0; } - -static void dri_get_drawable(__DRIdrawable *pdp) -{ - pdp->refcount++; -} - -static void dri_put_drawable(__DRIdrawable *pdp) -{ - __DRIscreen *psp; - - if (pdp) { - pdp->refcount--; - if (pdp->refcount) - return; - - psp = pdp->driScreenPriv; - (*psp->DriverAPI.DestroyBuffer)(pdp); - free(pdp); - } -} - -static void -driDestroyDrawable(__DRIdrawable *pdp) -{ - dri_put_drawable(pdp); -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Context handling functions */ -/*****************************************************************/ -/*@{*/ - -/** - * 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) { - (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); - free(pcp); - } -} - static unsigned int dri2GetAPIMask(__DRIscreen *screen) { return screen->api_mask; } -static __DRIcontext * -dri2CreateNewContextForAPI(__DRIscreen *screen, int api, - const __DRIconfig *config, - __DRIcontext *shared, void *data) -{ - __DRIcontext *context; - const struct gl_config *modes = (config != NULL) ? &config->modes : NULL; - void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; - gl_api mesa_api; - - if (!(screen->api_mask & (1 << api))) - return NULL; - - switch (api) { - case __DRI_API_OPENGL: - mesa_api = API_OPENGL; - break; - case __DRI_API_GLES: - mesa_api = API_OPENGLES; - break; - case __DRI_API_GLES2: - mesa_api = API_OPENGLES2; - break; - default: - return NULL; - } - - context = malloc(sizeof *context); - if (!context) - return NULL; - - context->driScreenPriv = screen; - context->driDrawablePriv = NULL; - context->loaderPrivate = data; - - if (!(*screen->DriverAPI.CreateContext)(mesa_api, modes, - context, shareCtx) ) { - free(context); - return NULL; - } - - return context; -} - - -static __DRIcontext * -dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, - __DRIcontext *shared, void *data) -{ - return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL, - config, shared, data); -} - -static int -driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) -{ - (void) dest; - (void) src; - (void) mask; - return GL_FALSE; -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Screen handling functions */ -/*****************************************************************/ -/*@{*/ - -/** - * 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(); - - if (psp->DriverAPI.DestroyScreen) - (*psp->DriverAPI.DestroyScreen)(psp); - - driDestroyOptionCache(&psp->optionCache); - driDestroyOptionInfo(&psp->optionInfo); - - free(psp); - } -} - -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]; - } -} - -/** - * DRI2 - */ -static __DRIscreen * -dri2CreateNewScreen(int scrn, int fd, - const __DRIextension **extensions, - const __DRIconfig ***driver_configs, void *data) -{ - static const __DRIextension *emptyExtensionList[] = { NULL }; - __DRIscreen *psp; - drmVersionPtr version; - - if (driDriverAPI.InitScreen2 == NULL) - return NULL; - - psp = calloc(1, sizeof(*psp)); - if (!psp) - return NULL; - - setupLoaderExtensions(psp, extensions); - - 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); - } - - psp->extensions = emptyExtensionList; - psp->fd = fd; - psp->myNum = scrn; - - psp->DriverAPI = driDriverAPI; - psp->api_mask = (1 << __DRI_API_OPENGL); - *driver_configs = driDriverAPI.InitScreen2(psp); - if (*driver_configs == NULL) { - free(psp); - return NULL; - } - - psp->DriverAPI = driDriverAPI; - psp->loaderPrivate = data; - - driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions, - __dri2NConfigOptions); - driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, - "dri2"); - - return psp; -} - -static const __DRIextension **driGetExtensions(__DRIscreen *psp) -{ - return psp->extensions; -} /** Core interface */ const __DRIcoreExtension driCoreExtension = { |