diff options
-rw-r--r-- | include/GL/internal/dri_interface.h | 28 | ||||
-rw-r--r-- | src/glx/x11/dri2_glx.c | 104 |
2 files changed, 112 insertions, 20 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 335bf62a801..bfa8a33b3c7 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -649,6 +649,7 @@ struct __DRIswrastExtensionRec { #define __DRI_BUFFER_ACCUM 6 #define __DRI_BUFFER_FAKE_FRONT_LEFT 7 #define __DRI_BUFFER_FAKE_FRONT_RIGHT 8 +#define __DRI_BUFFER_DEPTH_STENCIL 9 /**< Only available with DRI2 1.1 */ struct __DRIbufferRec { unsigned int attachment; @@ -659,7 +660,7 @@ struct __DRIbufferRec { }; #define __DRI_DRI2_LOADER "DRI_DRI2Loader" -#define __DRI_DRI2_LOADER_VERSION 2 +#define __DRI_DRI2_LOADER_VERSION 3 struct __DRIdri2LoaderExtensionRec { __DRIextension base; @@ -680,6 +681,31 @@ struct __DRIdri2LoaderExtensionRec { * into __DRIdri2ExtensionRec::createNewDrawable */ void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate); + + + /** + * Get list of buffers from the server + * + * Gets a list of buffer for the specified set of attachments. Unlike + * \c ::getBuffers, this function takes a list of attachments paired with + * opaque \c unsigned \c int value describing the format of the buffer. + * It is the responsibility of the caller to know what the service that + * allocates the buffers will expect to receive for the format. + * + * \param driDrawable Drawable whose buffers are being queried. + * \param width Output where the width of the buffers is stored. + * \param height Output where the height of the buffers is stored. + * \param attachments List of pairs of attachment ID and opaque format + * requested for the drawable. + * \param count Number of attachment / format pairs stored in + * \c attachments. + * \param loaderPrivate Loader's private data that was previously passed + * into __DRIdri2ExtensionRec::createNewDrawable. + */ + __DRIbuffer *(*getBuffersWithFormat)(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate); }; /** diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index b6eeb913b66..fb31898db2d 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -47,6 +47,9 @@ #include "dri2.h" #include "dri_common.h" +#undef DRI2_MINOR +#define DRI2_MINOR 1 + typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate; typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate; typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate; @@ -289,30 +292,25 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc) psc->__driScreen = NULL; } -static __DRIbuffer * -dri2GetBuffers(__DRIdrawable *driDrawable, - int *width, int *height, - unsigned int *attachments, int count, - int *out_count, void *loaderPrivate) +/** + * Process list of buffer received from the server + * + * Processes the list of buffers received in a reply from the server to either + * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat. + */ +static void +process_buffers(__GLXDRIdrawablePrivate *pdraw, DRI2Buffer *buffers, + unsigned count) { - __GLXDRIdrawablePrivate *pdraw = loaderPrivate; - DRI2Buffer *buffers; int i; - buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable, - width, height, attachments, count, out_count); - if (buffers == NULL) - return NULL; - - pdraw->width = *width; - pdraw->height = *height; - pdraw->bufferCount = *out_count; + pdraw->bufferCount = count; pdraw->have_fake_front = 0; pdraw->have_back = 0; /* This assumes the DRI2 buffer attachment tokens matches the * __DRIbuffer tokens. */ - for (i = 0; i < *out_count; i++) { + for (i = 0; i < count; i++) { pdraw->buffers[i].attachment = buffers[i].attachment; pdraw->buffers[i].name = buffers[i].name; pdraw->buffers[i].pitch = buffers[i].pitch; @@ -324,6 +322,51 @@ dri2GetBuffers(__DRIdrawable *driDrawable, pdraw->have_back = 1; } +} + +static __DRIbuffer * +dri2GetBuffers(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + __GLXDRIdrawablePrivate *pdraw = loaderPrivate; + DRI2Buffer *buffers; + + buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable, + width, height, attachments, count, out_count); + if (buffers == NULL) + return NULL; + + pdraw->width = *width; + pdraw->height = *height; + process_buffers(pdraw, buffers, *out_count); + + Xfree(buffers); + + return pdraw->buffers; +} + +static __DRIbuffer * +dri2GetBuffersWithFormat(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + __GLXDRIdrawablePrivate *pdraw = loaderPrivate; + DRI2Buffer *buffers; + + buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy, + pdraw->base.xDrawable, + width, height, attachments, + count, out_count); + if (buffers == NULL) + return NULL; + + pdraw->width = *width; + pdraw->height = *height; + process_buffers(pdraw, buffers, *out_count); + Xfree(buffers); return pdraw->buffers; @@ -332,7 +375,15 @@ dri2GetBuffers(__DRIdrawable *driDrawable, static const __DRIdri2LoaderExtension dri2LoaderExtension = { { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, dri2GetBuffers, - dri2FlushFrontBuffer + dri2FlushFrontBuffer, + dri2GetBuffersWithFormat, +}; + +static const __DRIdri2LoaderExtension dri2LoaderExtension_old = { + { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, + dri2GetBuffers, + dri2FlushFrontBuffer, + NULL, }; static const __DRIextension *loader_extensions[] = { @@ -341,11 +392,19 @@ static const __DRIextension *loader_extensions[] = { NULL }; +static const __DRIextension *loader_extensions_old[] = { + &dri2LoaderExtension_old.base, + &systemTimeExtension.base, + NULL +}; + static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, __GLXdisplayPrivate *priv) { const __DRIconfig **driver_configs; const __DRIextension **extensions; + const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *) + priv->dri2Display; __GLXDRIscreen *psp; char *driverName, *deviceName; drm_magic_t magic; @@ -402,9 +461,16 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, return NULL; } + /* If the server does not support the protocol for + * DRI2GetBuffersWithFormat, don't supply that interface to the driver. + */ psc->__driScreen = - psc->dri2->createNewScreen(screen, psc->fd, - loader_extensions, &driver_configs, psc); + psc->dri2->createNewScreen(screen, psc->fd, + ((pdp->driMinor < 1) + ? loader_extensions_old + : loader_extensions), + &driver_configs, psc); + if (psc->__driScreen == NULL) { ErrorMessageF("failed to create dri screen\n"); return NULL; |