#include "dri_util.h"
#include "drm_sarea.h"
#include "utils.h"
+#include "xmlpool.h"
+#include "../glsl/glsl_parser_extras.h"
+
+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;
+
+static const uint __dri2NConfigOptions = 1;
#ifndef GLX_OML_sync_control
typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
__DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
};
-/**
- * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
- * is set.
- *
- * Is called from the drivers.
- *
- * \param f \c printf like format string.
- */
-void
-__driUtilMessage(const char *f, ...)
-{
- va_list args;
-
- if (getenv("LIBGL_DEBUG")) {
- fprintf(stderr, "libGL: ");
- va_start(args, f);
- vfprintf(stderr, f, args);
- va_end(args);
- fprintf(stderr, "\n");
- }
-}
-
GLint
driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
{
*
* \internal
* This function calls __DriverAPIRec::UnbindContext, and then decrements
- * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful
+ * __DRIdrawableRec::refcount which must be non-zero for a successful
* return.
*
* While casting the opaque private pointers associated with the parameters
/* Let driver unbind drawable from context */
(*psp->DriverAPI.UnbindContext)(pcp);
+ assert(pdp);
if (pdp->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
*/
pcp->driDrawablePriv = pcp->driReadablePriv = NULL;
-#if 0
- /* Unbind the drawable */
- pdp->driContextPriv = &psp->dummyContextPriv;
-#endif
-
return GL_TRUE;
}
__DRIdrawable *pdp,
__DRIdrawable *prp)
{
- __DRIscreenPrivate *psp = NULL;
+ __DRIscreen *psp = NULL;
- /* Bind the drawable to the context */
+ /*
+ ** Assume error checking is done properly in glXMakeCurrent before
+ ** calling driUnbindContext.
+ */
- if (pcp) {
- psp = pcp->driScreenPriv;
- pcp->driDrawablePriv = pdp;
- pcp->driReadablePriv = prp;
- if (pdp) {
- pdp->driContextPriv = pcp;
- dri_get_drawable(pdp);
- }
- if ( prp && pdp != prp ) {
- dri_get_drawable(prp);
- }
+ if (!pcp)
+ return GL_FALSE;
+
+ /* Bind the drawable to the context */
+ psp = pcp->driScreenPriv;
+ pcp->driDrawablePriv = pdp;
+ pcp->driReadablePriv = prp;
+ if (pdp) {
+ pdp->driContextPriv = pcp;
+ dri_get_drawable(pdp);
+ }
+ if (prp && pdp != prp) {
+ dri_get_drawable(prp);
}
/*
}
/* Call device-specific MakeCurrent */
-
return (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp);
}
*
* \param pdp pointer to the private drawable information to update.
*
- * This function basically updates the __DRIdrawablePrivate struct's
+ * This function basically updates the __DRIdrawable struct's
* cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo.
* This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which
* compares the __DRIdrwablePrivate pStamp and lastStamp values. If
* info.
*/
void
-__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
+__driUtilUpdateDrawableInfo(__DRIdrawable *pdp)
{
- __DRIscreenPrivate *psp = pdp->driScreenPriv;
- __DRIcontextPrivate *pcp = pdp->driContextPriv;
+ __DRIscreen *psp = pdp->driScreenPriv;
+ __DRIcontext *pcp = pdp->driContextPriv;
if (!pcp
|| ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) {
}
if (pdp->pClipRects) {
- _mesa_free(pdp->pClipRects);
+ free(pdp->pClipRects);
pdp->pClipRects = NULL;
}
if (pdp->pBackClipRects) {
- _mesa_free(pdp->pBackClipRects);
+ free(pdp->pBackClipRects);
pdp->pBackClipRects = NULL;
}
* \param drawablePrivate opaque pointer to the per-drawable private info.
*
* \internal
- * This function calls __DRIdrawablePrivate::swapBuffers.
+ * This function calls __DRIdrawable::swapBuffers.
*
* Is called directly from glXSwapBuffers().
*/
if (!dPriv->numClipRects)
return;
- rects = _mesa_malloc(sizeof(*rects) * dPriv->numClipRects);
+ rects = malloc(sizeof(*rects) * dPriv->numClipRects);
if (!rects)
return;
}
driReportDamage(dPriv, rects, dPriv->numClipRects);
- _mesa_free(rects);
+ free(rects);
}
static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
*/
(void) attrs;
- pdp = _mesa_malloc(sizeof *pdp);
+ pdp = malloc(sizeof *pdp);
if (!pdp) {
return NULL;
}
+ pdp->driContextPriv = NULL;
pdp->loaderPrivate = data;
pdp->hHWDrawable = hwDrawable;
pdp->refcount = 1;
pdp->vblFlags = 0;
pdp->driScreenPriv = psp;
- pdp->driContextPriv = &psp->dummyContextPriv;
- if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
- renderType == GLX_PIXMAP_BIT)) {
- _mesa_free(pdp);
+ if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, 0)) {
+ free(pdp);
return NULL;
}
if (!pdraw)
return NULL;
- pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
- pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
+ pdraw->pClipRects = &pdraw->dri2.clipRect;
+ pdraw->pBackClipRects = &pdraw->dri2.clipRect;
+
+ pdraw->pStamp = &pdraw->dri2.stamp;
+ *pdraw->pStamp = pdraw->lastStamp + 1;
return pdraw;
}
+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;
+}
+
+
static void dri_get_drawable(__DRIdrawable *pdp)
{
pdp->refcount++;
static void dri_put_drawable(__DRIdrawable *pdp)
{
- __DRIscreenPrivate *psp;
+ __DRIscreen *psp;
if (pdp) {
pdp->refcount--;
psp = pdp->driScreenPriv;
(*psp->DriverAPI.DestroyBuffer)(pdp);
- if (pdp->pClipRects) {
- _mesa_free(pdp->pClipRects);
+ if (pdp->pClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
+ free(pdp->pClipRects);
pdp->pClipRects = NULL;
}
- if (pdp->pBackClipRects) {
- _mesa_free(pdp->pBackClipRects);
+ if (pdp->pBackClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
+ free(pdp->pBackClipRects);
pdp->pBackClipRects = NULL;
}
- _mesa_free(pdp);
+ free(pdp);
}
}
{
if (pcp) {
(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
- _mesa_free(pcp);
+ free(pcp);
}
}
* success, or \c NULL on failure.
*
* \internal
- * This function allocates and fills a __DRIcontextPrivateRec structure. It
+ * This function allocates and fills a __DRIcontextRec structure. It
* performs some device independent initialization and passes all the
* relevent information to __DriverAPIRec::CreateContext to create the
* context.
__DRIcontext *pcp;
void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
- pcp = _mesa_malloc(sizeof *pcp);
+ pcp = malloc(sizeof *pcp);
if (!pcp)
return NULL;
pcp->driScreenPriv = psp;
pcp->driDrawablePriv = NULL;
+ pcp->loaderPrivate = data;
+
+ pcp->dri2.draw_stamp = 0;
+ pcp->dri2.read_stamp = 0;
- /* When the first context is created for a screen, initialize a "dummy"
- * context.
- */
+ pcp->hHWContext = hwContext;
- if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) {
- psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
- psp->dummyContextPriv.driScreenPriv = psp;
- psp->dummyContextPriv.driDrawablePriv = NULL;
- psp->dummyContextPriv.driverPrivate = NULL;
- /* No other fields should be used! */
+ if ( !(*psp->DriverAPI.CreateContext)(API_OPENGL,
+ &config->modes, pcp, shareCtx) ) {
+ free(pcp);
+ return NULL;
}
- pcp->hHWContext = hwContext;
+ return 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;
+ }
- if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) {
- _mesa_free(pcp);
+ 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 pcp;
+ return context;
}
dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
__DRIcontext *shared, void *data)
{
- return driCreateNewContext(screen, config, 0, shared, 0, data);
+ return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
+ config, shared, data);
}
-
static int
driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
{
* stream open to the X-server anymore.
*/
+ _mesa_destroy_shader_compiler();
+
if (psp->DriverAPI.DestroyScreen)
(*psp->DriverAPI.DestroyScreen)(psp);
(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
(void)drmCloseOnce(psp->fd);
+ } else {
+ driDestroyOptionCache(&psp->optionCache);
+ driDestroyOptionInfo(&psp->optionInfo);
}
- _mesa_free(psp);
+ free(psp);
}
}
psp->systemTime = (__DRIsystemTimeExtension *) extensions[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];
}
}
* This is the bootstrap function for the driver. libGL supplies all of the
* requisite information about the system, and the driver initializes itself.
* This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
+ * with the \c struct gl_config that the driver can support for windows or
* pbuffers.
*
* For legacy DRI.
* \param drm_version Version of the kernel DRM.
* \param frame_buffer Data describing the location and layout of the
* framebuffer.
- * \param pSAREA Pointer the the SAREA.
+ * \param pSAREA Pointer to the SAREA.
* \param fd Device handle for the DRM.
* \param extensions ??
* \param driver_modes Returns modes suppoted by the driver
static const __DRIextension *emptyExtensionList[] = { NULL };
__DRIscreen *psp;
- psp = _mesa_calloc(sizeof *psp);
+ psp = calloc(1, sizeof *psp);
if (!psp)
return NULL;
psp->myNum = scrn;
psp->dri2.enabled = GL_FALSE;
- /*
- ** Do not init dummy context here; actual initialization will be
- ** done when the first DRI context is created. Init screen priv ptr
- ** to NULL to let CreateContext routine that it needs to be inited.
- */
- psp->dummyContextPriv.driScreenPriv = NULL;
-
psp->DriverAPI = driDriverAPI;
+ psp->api_mask = (1 << __DRI_API_OPENGL);
*driver_modes = driDriverAPI.InitScreen(psp);
if (*driver_modes == NULL) {
- _mesa_free(psp);
+ free(psp);
return NULL;
}
if (driDriverAPI.InitScreen2 == NULL)
return NULL;
- psp = _mesa_calloc(sizeof(*psp));
+ psp = calloc(1, sizeof(*psp));
if (!psp)
return NULL;
psp->dri2.enabled = GL_TRUE;
psp->DriverAPI = driDriverAPI;
+ psp->api_mask = (1 << __DRI_API_OPENGL);
*driver_configs = driDriverAPI.InitScreen2(psp);
if (*driver_configs == NULL) {
- _mesa_free(psp);
+ 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;
}
driCreateNewContext,
};
-/** Legacy DRI interface */
+/** DRI2 interface */
const __DRIdri2Extension driDRI2Extension = {
{ __DRI_DRI2, __DRI_DRI2_VERSION },
dri2CreateNewScreen,
dri2CreateNewDrawable,
dri2CreateNewContext,
+ dri2GetAPIMask,
+ dri2CreateNewContextForAPI
};
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
- &driCoreExtension.base,
- &driLegacyExtension.base,
- &driDRI2Extension.base,
- NULL
-};
-
-static int
-driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
-{
- return GLX_BAD_CONTEXT;
-}
-
-static int
-driQueryFrameTracking(__DRIdrawable *dpriv,
- int64_t * sbc, int64_t * missedFrames,
- float * lastMissedUsage, float * usage)
-{
- __DRIswapInfo sInfo;
- int status;
- int64_t ust;
- __DRIscreenPrivate *psp = dpriv->driScreenPriv;
-
- status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
- if ( status == 0 ) {
- *sbc = sInfo.swap_count;
- *missedFrames = sInfo.swap_missed_count;
- *lastMissedUsage = sInfo.swap_missed_usage;
-
- (*psp->systemTime->getUST)( & ust );
- *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
- }
-
- return status;
-}
-
-const __DRIframeTrackingExtension driFrameTrackingExtension = {
- { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
- driFrameTracking,
- driQueryFrameTracking
+const __DRI2configQueryExtension dri2ConfigQueryExtension = {
+ { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
+ dri2ConfigQueryb,
+ dri2ConfigQueryi,
+ dri2ConfigQueryf,
};
/**
* be possible to cache the sync rate?
*/
float
-driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
+driCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust,
int64_t current_ust )
{
int32_t n;
int32_t d;
int interval;
float usage = 1.0;
- __DRIscreenPrivate *psp = dPriv->driScreenPriv;
+ __DRIscreen *psp = dPriv->driScreenPriv;
if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
return usage;
}
+void
+dri2InvalidateDrawable(__DRIdrawable *drawable)
+{
+ drawable->dri2.stamp++;
+}
+
/*@}*/