Add loader for the swrast dri driver.

This commit is contained in:
George Sapountzis 2008-05-20 16:36:22 -04:00 committed by Kristian Høgsberg
parent 925e895b86
commit 6ff6465931
8 changed files with 806 additions and 207 deletions

View File

@ -62,6 +62,8 @@ libglx_la_SOURCES = \
glxext.c \
glxext.h \
glxglcore.c \
glxdriswrast.c \
glxdricommon.c \
glxscreens.c \
glxscreens.h \
glxserver.h \

View File

@ -52,6 +52,7 @@
#define DRI_NEW_INTERFACE_ONLY
#include "glxserver.h"
#include "glxutil.h"
#include "glxdricommon.h"
#include "g_disptab.h"
#include "glapitable.h"
@ -63,7 +64,6 @@
typedef struct __GLXDRIscreen __GLXDRIscreen;
typedef struct __GLXDRIcontext __GLXDRIcontext;
typedef struct __GLXDRIdrawable __GLXDRIdrawable;
typedef struct __GLXDRIconfig __GLXDRIconfig;
struct __GLXDRIscreen {
__GLXscreen base;
@ -108,11 +108,6 @@ struct __GLXDRIdrawable {
#endif
};
struct __GLXDRIconfig {
__GLXconfig config;
__DRIconfig *driConfig;
};
static void
__glXDRIleaveServer(GLboolean rendering)
{
@ -797,22 +792,6 @@ getDrawableInfo(__DRIdrawable *driDrawable,
return retval;
}
static int
getUST(int64_t *ust)
{
struct timeval tv;
if (ust == NULL)
return -EFAULT;
if (gettimeofday(&tv, NULL) == 0) {
ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
return 0;
} else {
return -errno;
}
}
static void __glXReportDamage(__DRIdrawable *driDraw,
int x, int y,
drm_clip_rect_t *rects, int num_rects,
@ -833,12 +812,6 @@ static void __glXReportDamage(__DRIdrawable *driDraw,
__glXleaveServer(GL_FALSE);
}
static const __DRIsystemTimeExtension systemTimeExtension = {
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
getUST,
NULL,
};
static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
{ __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
getDrawableInfo

View File

@ -29,7 +29,6 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <dlfcn.h>
#include <drm.h>
@ -47,6 +46,7 @@
#include "glxserver.h"
#include "glxutil.h"
#include "glxdricommon.h"
#include "g_disptab.h"
#include "glapitable.h"
@ -58,7 +58,6 @@
typedef struct __GLXDRIscreen __GLXDRIscreen;
typedef struct __GLXDRIcontext __GLXDRIcontext;
typedef struct __GLXDRIdrawable __GLXDRIdrawable;
typedef struct __GLXDRIconfig __GLXDRIconfig;
struct __GLXDRIscreen {
__GLXscreen base;
@ -88,11 +87,6 @@ struct __GLXDRIdrawable {
__GLXDRIscreen *screen;
};
struct __GLXDRIconfig {
__GLXconfig config;
const __DRIconfig *driConfig;
};
static void
__glXDRIdrawableDestroy(__GLXdrawable *drawable)
{
@ -359,28 +353,6 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
return &private->base;
}
static int
getUST(int64_t *ust)
{
struct timeval tv;
if (ust == NULL)
return -EFAULT;
if (gettimeofday(&tv, NULL) == 0) {
ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
return 0;
} else {
return -errno;
}
}
static const __DRIsystemTimeExtension systemTimeExtension = {
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
getUST,
NULL,
};
static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail,
void *loaderPrivate)
{
@ -490,156 +462,6 @@ initializeExtensions(__GLXDRIscreen *screen)
/* Ignore unknown extensions */
}
}
#define __ATTRIB(attrib, field) \
{ attrib, offsetof(__GLXconfig, field) }
static const struct { unsigned int attrib, offset; } attribMap[] = {
__ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
__ATTRIB(__DRI_ATTRIB_LEVEL, level),
__ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
__ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
__ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
__ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
__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),
__ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
__ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
__ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
__ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
__ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
__ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
__ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
__ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
__ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
__ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
__ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
__ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
__ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
};
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
static void
setScalar(__GLXconfig *config, unsigned int attrib, unsigned int value)
{
int i;
for (i = 0; i < ARRAY_SIZE(attribMap); i++)
if (attribMap[i].attrib == attrib) {
*(unsigned int *) ((char *) config + attribMap[i].offset) = value;
return;
}
}
static __GLXconfig *
createModeFromConfig(const __DRIcoreExtension *core,
const __DRIconfig *driConfig,
unsigned int visualType)
{
__GLXDRIconfig *config;
unsigned int attrib, value;
int i;
config = xalloc(sizeof *config);
config->driConfig = driConfig;
i = 0;
while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
switch (attrib) {
case __DRI_ATTRIB_RENDER_TYPE:
if (value & __DRI_ATTRIB_RGBA_BIT) {
config->config.renderType |= GLX_RGBA_BIT;
config->config.rgbMode = GL_TRUE;
} else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
config->config.renderType |= GLX_COLOR_INDEX_BIT;
config->config.rgbMode = GL_FALSE;
} else {
config->config.renderType = 0;
config->config.rgbMode = GL_FALSE;
}
break;
case __DRI_ATTRIB_CONFIG_CAVEAT:
if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
config->config.visualRating = GLX_NON_CONFORMANT_CONFIG;
else if (value & __DRI_ATTRIB_SLOW_BIT)
config->config.visualRating = GLX_SLOW_CONFIG;
else
config->config.visualRating = GLX_NONE;
break;
case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
config->config.bindToTextureTargets = 0;
if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
config->config.bindToTextureTargets |= GLX_TEXTURE_1D_BIT_EXT;
if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
config->config.bindToTextureTargets |= GLX_TEXTURE_2D_BIT_EXT;
if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
config->config.bindToTextureTargets |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
break;
default:
setScalar(&config->config, attrib, value);
break;
}
}
config->config.next = NULL;
config->config.xRenderable = GL_TRUE;
config->config.visualType = visualType;
config->config.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
return &config->config;
}
__GLXconfig *
glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs);
__GLXconfig *
glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs)
{
__GLXconfig head, *tail;
int i;
tail = &head;
head.next = NULL;
for (i = 0; configs[i]; i++) {
tail->next = createModeFromConfig(core,
configs[i], GLX_TRUE_COLOR);
if (tail->next == NULL)
break;
tail = tail->next;
}
for (i = 0; configs[i]; i++) {
tail->next = createModeFromConfig(core,
configs[i], GLX_DIRECT_COLOR);
if (tail->next == NULL)
break;
tail = tail->next;
}
return head.next;
}
static __GLXscreen *
__glXDRIscreenProbe(ScreenPtr pScreen)

209
GL/glx/glxdricommon.c Normal file
View File

@ -0,0 +1,209 @@
/*
* Copyright © 2008 Red Hat, Inc
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdint.h>
#include <errno.h>
#include <sys/time.h>
#include <GL/gl.h>
#include <GL/glxtokens.h>
#include <GL/internal/dri_interface.h>
#include <os.h>
#include "glxserver.h"
#include "glxcontext.h"
#include "glxscreens.h"
#include "glxdricommon.h"
static int
getUST(int64_t *ust)
{
struct timeval tv;
if (ust == NULL)
return -EFAULT;
if (gettimeofday(&tv, NULL) == 0) {
ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
return 0;
} else {
return -errno;
}
}
const __DRIsystemTimeExtension systemTimeExtension = {
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
getUST,
NULL,
};
#define __ATTRIB(attrib, field) \
{ attrib, offsetof(__GLXconfig, field) }
static const struct { unsigned int attrib, offset; } attribMap[] = {
__ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
__ATTRIB(__DRI_ATTRIB_LEVEL, level),
__ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
__ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
__ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
__ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
__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),
__ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
__ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
__ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
__ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
__ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
__ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
__ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
__ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
__ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
__ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
__ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
__ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
__ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
__ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
__ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
};
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
static void
setScalar(__GLXconfig *config, unsigned int attrib, unsigned int value)
{
int i;
for (i = 0; i < ARRAY_SIZE(attribMap); i++)
if (attribMap[i].attrib == attrib) {
*(unsigned int *) ((char *) config + attribMap[i].offset) = value;
return;
}
}
static __GLXconfig *
createModeFromConfig(const __DRIcoreExtension *core,
const __DRIconfig *driConfig,
unsigned int visualType)
{
__GLXDRIconfig *config;
unsigned int attrib, value;
int i;
config = xalloc(sizeof *config);
config->driConfig = driConfig;
i = 0;
while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
switch (attrib) {
case __DRI_ATTRIB_RENDER_TYPE:
if (value & __DRI_ATTRIB_RGBA_BIT) {
config->config.renderType |= GLX_RGBA_BIT;
config->config.rgbMode = GL_TRUE;
} else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
config->config.renderType |= GLX_COLOR_INDEX_BIT;
config->config.rgbMode = GL_FALSE;
} else {
config->config.renderType = 0;
config->config.rgbMode = GL_FALSE;
}
break;
case __DRI_ATTRIB_CONFIG_CAVEAT:
if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
config->config.visualRating = GLX_NON_CONFORMANT_CONFIG;
else if (value & __DRI_ATTRIB_SLOW_BIT)
config->config.visualRating = GLX_SLOW_CONFIG;
else
config->config.visualRating = GLX_NONE;
break;
case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
config->config.bindToTextureTargets = 0;
if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
config->config.bindToTextureTargets |= GLX_TEXTURE_1D_BIT_EXT;
if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
config->config.bindToTextureTargets |= GLX_TEXTURE_2D_BIT_EXT;
if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
config->config.bindToTextureTargets |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
break;
default:
setScalar(&config->config, attrib, value);
break;
}
}
config->config.next = NULL;
config->config.xRenderable = GL_TRUE;
config->config.visualType = visualType;
config->config.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
return &config->config;
}
__GLXconfig *
glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs)
{
__GLXconfig head, *tail;
int i;
tail = &head;
head.next = NULL;
for (i = 0; configs[i]; i++) {
tail->next = createModeFromConfig(core,
configs[i], GLX_TRUE_COLOR);
if (tail->next == NULL)
break;
tail = tail->next;
}
for (i = 0; configs[i]; i++) {
tail->next = createModeFromConfig(core,
configs[i], GLX_DIRECT_COLOR);
if (tail->next == NULL)
break;
tail = tail->next;
}
return head.next;
}

40
GL/glx/glxdricommon.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright © 2008 Red Hat, Inc
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef _GLX_dri_common_h
#define _GLX_dri_common_h
typedef struct __GLXDRIconfig __GLXDRIconfig;
struct __GLXDRIconfig {
__GLXconfig config;
const __DRIconfig *driConfig;
};
__GLXconfig *
glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs);
extern const __DRIsystemTimeExtension systemTimeExtension;
#endif

547
GL/glx/glxdriswrast.c Normal file
View File

@ -0,0 +1,547 @@
/*
* Copyright © 2008 George Sapountzis <gsap7@yahoo.gr>
* Copyright © 2008 Red Hat, Inc
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <dlfcn.h>
#include <drm.h>
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
#include <GL/glxtokens.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "gcstruct.h"
#include "os.h"
#include "glxserver.h"
#include "glxutil.h"
#include "glxdricommon.h"
#include "g_disptab.h"
#include "glapitable.h"
#include "glapi.h"
#include "glthread.h"
#include "dispatch.h"
#include "extension_string.h"
typedef struct __GLXDRIscreen __GLXDRIscreen;
typedef struct __GLXDRIcontext __GLXDRIcontext;
typedef struct __GLXDRIdrawable __GLXDRIdrawable;
struct __GLXDRIscreen {
__GLXscreen base;
__DRIscreen *driScreen;
void *driver;
const __DRIcoreExtension *core;
const __DRIswrastExtension *swrast;
const __DRIcopySubBufferExtension *copySubBuffer;
const __DRItexBufferExtension *texBuffer;
};
struct __GLXDRIcontext {
__GLXcontext base;
__DRIcontext *driContext;
};
struct __GLXDRIdrawable {
__GLXdrawable base;
__DRIdrawable *driDrawable;
__GLXDRIscreen *screen;
GCPtr gc; /* scratch GC for span drawing */
GCPtr cleargc; /* GC for clearing the color buffer */
GCPtr swapgc; /* GC for swapping the color buffers */
};
static void
__glXDRIdrawableDestroy(__GLXdrawable *drawable)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
const __DRIcoreExtension *core = private->screen->core;
(*core->destroyDrawable)(private->driDrawable);
FreeScratchGC(private->gc);
FreeScratchGC(private->cleargc);
FreeScratchGC(private->swapgc);
xfree(private);
}
static GLboolean
__glXDRIdrawableResize(__GLXdrawable *glxPriv)
{
/* Nothing to do here, the DRI driver asks the server for drawable
* geometry when it sess the SAREA timestamps change.*/
return GL_TRUE;
}
static GLboolean
__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
const __DRIcoreExtension *core = private->screen->core;
(*core->swapBuffers)(private->driDrawable);
return TRUE;
}
static void
__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
int x, int y, int w, int h)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
const __DRIcopySubBufferExtension *copySubBuffer =
private->screen->copySubBuffer;
if (copySubBuffer)
(*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h);
}
static void
__glXDRIcontextDestroy(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
__GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
(*screen->core->destroyContext)(context->driContext);
__glXContextDestroy(&context->base);
xfree(context);
}
static int
__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
__GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
__GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
__GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
return (*screen->core->bindContext)(context->driContext,
draw->driDrawable,
read->driDrawable);
}
static int
__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
__GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
return (*screen->core->unbindContext)(context->driContext);
}
static int
__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
unsigned long mask)
{
__GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
__GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
__GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
return (*screen->core->copyContext)(dst->driContext,
src->driContext, mask);
}
static int
__glXDRIcontextForceCurrent(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
__GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
__GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
__GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
return (*screen->core->bindContext)(context->driContext,
draw->driDrawable,
read->driDrawable);
}
#ifdef __DRI_TEX_BUFFER
static int
__glXDRIbindTexImage(__GLXcontext *baseContext,
int buffer,
__GLXdrawable *glxPixmap)
{
__GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
if (texBuffer == NULL)
return Success;
texBuffer->setTexBuffer(context->driContext,
glxPixmap->target,
drawable->driDrawable);
return Success;
}
static int
__glXDRIreleaseTexImage(__GLXcontext *baseContext,
int buffer,
__GLXdrawable *pixmap)
{
/* FIXME: Just unbind the texture? */
return Success;
}
#else
static int
__glXDRIbindTexImage(__GLXcontext *baseContext,
int buffer,
__GLXdrawable *glxPixmap)
{
return Success;
}
static int
__glXDRIreleaseTexImage(__GLXcontext *baseContext,
int buffer,
__GLXdrawable *pixmap)
{
return Success;
}
#endif
static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
__glXDRIbindTexImage,
__glXDRIreleaseTexImage
};
static void
__glXDRIscreenDestroy(__GLXscreen *baseScreen)
{
__GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
(*screen->core->destroyScreen)(screen->driScreen);
dlclose(screen->driver);
__glXScreenDestroy(baseScreen);
xfree(screen);
}
static __GLXcontext *
__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
__GLXconfig *glxConfig,
__GLXcontext *baseShareContext)
{
__GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
__GLXDRIcontext *context, *shareContext;
__GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
const __DRIcoreExtension *core = screen->core;
__DRIcontext *driShare;
shareContext = (__GLXDRIcontext *) baseShareContext;
if (shareContext)
driShare = shareContext->driContext;
else
driShare = NULL;
context = xalloc(sizeof *context);
if (context == NULL)
return NULL;
memset(context, 0, sizeof *context);
context->base.destroy = __glXDRIcontextDestroy;
context->base.makeCurrent = __glXDRIcontextMakeCurrent;
context->base.loseCurrent = __glXDRIcontextLoseCurrent;
context->base.copy = __glXDRIcontextCopy;
context->base.forceCurrent = __glXDRIcontextForceCurrent;
context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
context->driContext =
(*core->createNewContext)(screen->driScreen,
config->driConfig, driShare, context);
return &context->base;
}
static void
glxChangeGC(GCPtr gc, BITS32 mask, CARD32 val)
{
CARD32 v[1];
v[0] = val;
dixChangeGC(NullClient, gc, mask, v, NULL);
}
static __GLXdrawable *
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
DrawablePtr pDraw,
int type,
XID drawId,
__GLXconfig *glxConfig)
{
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
__GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
__GLXDRIdrawable *private;
ScreenPtr pScreen = driScreen->base.pScreen;
private = xalloc(sizeof *private);
if (private == NULL)
return NULL;
memset(private, 0, sizeof *private);
private->screen = driScreen;
if (!__glXDrawableInit(&private->base, screen,
pDraw, type, drawId, glxConfig)) {
xfree(private);
return NULL;
}
private->base.destroy = __glXDRIdrawableDestroy;
private->base.resize = __glXDRIdrawableResize;
private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
private->gc = CreateScratchGC(pScreen, pDraw->depth);
private->cleargc = CreateScratchGC(pScreen, pDraw->depth);
private->swapgc = CreateScratchGC(pScreen, pDraw->depth);
glxChangeGC(private->gc, GCFunction, GXcopy);
glxChangeGC(private->cleargc, GCFunction, GXcopy);
glxChangeGC(private->swapgc, GCFunction, GXcopy);
glxChangeGC(private->swapgc, GCGraphicsExposures, FALSE);
private->driDrawable =
(*driScreen->swrast->createNewDrawable)(driScreen->driScreen,
config->driConfig,
private);
return &private->base;
}
static void
swrastGetDrawableInfo(__DRIdrawable *draw,
int *x, int *y, int *w, int *h,
void *loaderPrivate)
{
__GLXDRIdrawable *drawable = loaderPrivate;
DrawablePtr pDraw = drawable->base.pDraw;
*x = pDraw->x;
*y = pDraw->x;
*w = pDraw->width;
*h = pDraw->height;
}
static void
swrastPutImage(__DRIdrawable *draw, int op,
int x, int y, int w, int h, char *data,
void *loaderPrivate)
{
__GLXDRIdrawable *drawable = loaderPrivate;
DrawablePtr pDraw = drawable->base.pDraw;
GCPtr gc;
switch (op) {
case __DRI_SWRAST_IMAGE_OP_DRAW:
gc = drawable->gc;
break;
case __DRI_SWRAST_IMAGE_OP_CLEAR:
gc = drawable->cleargc;
break;
case __DRI_SWRAST_IMAGE_OP_SWAP:
gc = drawable->swapgc;
break;
default:
return;
}
ValidateGC(pDraw, gc);
gc->ops->PutImage(pDraw, gc, pDraw->depth,
x, y, w, h, 0, ZPixmap, data);
}
static void
swrastGetImage(__DRIdrawable *draw,
int x, int y, int w, int h, char *data,
void *loaderPrivate)
{
__GLXDRIdrawable *drawable = loaderPrivate;
DrawablePtr pDraw = drawable->base.pDraw;
ScreenPtr pScreen = pDraw->pScreen;
pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data);
}
static const __DRIswrastLoaderExtension swrastLoaderExtension = {
{ __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION },
swrastGetDrawableInfo,
swrastPutImage,
swrastGetImage
};
static const __DRIextension *loader_extensions[] = {
&systemTimeExtension.base,
&swrastLoaderExtension.base,
NULL
};
static void
initializeExtensions(__GLXDRIscreen *screen)
{
const __DRIextension **extensions;
int i;
extensions = screen->core->getExtensions(screen->driScreen);
for (i = 0; extensions[i]; i++) {
#ifdef __DRI_COPY_SUB_BUFFER
if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
screen->copySubBuffer =
(const __DRIcopySubBufferExtension *) extensions[i];
/* GLX_MESA_copy_sub_buffer is always enabled. */
}
#endif
#ifdef __DRI_TEX_BUFFER
if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
screen->texBuffer =
(const __DRItexBufferExtension *) extensions[i];
/* GLX_EXT_texture_from_pixmap is always enabled. */
}
#endif
/* Ignore unknown extensions */
}
}
static const char dri_driver_path[] = DRI_DRIVER_PATH;
static __GLXscreen *
__glXDRIscreenProbe(ScreenPtr pScreen)
{
const char *driverName = "swrast";
__GLXDRIscreen *screen;
char filename[128];
unsigned int sareaHandle;
const __DRIextension **extensions;
const __DRIconfig **driConfigs;
int i;
screen = xalloc(sizeof *screen);
if (screen == NULL)
return NULL;
memset(screen, 0, sizeof *screen);
screen->base.destroy = __glXDRIscreenDestroy;
screen->base.createContext = __glXDRIscreenCreateContext;
screen->base.createDrawable = __glXDRIscreenCreateDrawable;
screen->base.swapInterval = NULL;
screen->base.pScreen = pScreen;
snprintf(filename, sizeof filename,
"%s/%s_dri.so", dri_driver_path, driverName);
screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
if (screen->driver == NULL) {
LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
filename, dlerror());
goto handle_error;
}
extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
driverName, dlerror());
goto handle_error;
}
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
extensions[i]->version >= __DRI_CORE_VERSION) {
screen->core = (const __DRIcoreExtension *) extensions[i];
}
if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0 &&
extensions[i]->version >= __DRI_SWRAST_VERSION) {
screen->swrast = (const __DRIswrastExtension *) extensions[i];
}
}
if (screen->core == NULL || screen->swrast == NULL) {
LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
driverName);
goto handle_error;
}
sareaHandle = 0;
screen->driScreen =
(*screen->swrast->createNewScreen)(pScreen->myNum,
loader_extensions,
&driConfigs,
screen);
if (screen->driScreen == NULL) {
LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed");
goto handle_error;
}
initializeExtensions(screen);
screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs);
__glXScreenInit(&screen->base, pScreen);
LogMessage(X_INFO,
"AIGLX: Loaded and initialized %s\n", filename);
return &screen->base;
handle_error:
if (screen->driver)
dlclose(screen->driver);
xfree(screen);
LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n");
return NULL;
}
__GLXprovider __glXDRIswrastProvider = {
__glXDRIscreenProbe,
"DRISWRAST",
NULL
};

View File

@ -90,6 +90,10 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
return NULL;
GlxPushProvider(provider);
provider = LoaderSymbol("__glXDRIswrastProvider");
if (provider)
GlxPushProvider(provider);
xf86Msg(xf86Info.aiglxFrom, "AIGLX %s\n",
xf86Info.aiglx ? "enabled" : "disabled");
if (xf86Info.aiglx) {

View File

@ -288,6 +288,7 @@ extern void XFree86DGAExtensionInit(INITARGS);
#ifdef GLXEXT
typedef struct __GLXprovider __GLXprovider;
extern __GLXprovider __glXMesaProvider;
extern __GLXprovider __glXDRIswrastProvider;
extern void GlxPushProvider(__GLXprovider *impl);
extern void GlxExtensionInit(INITARGS);
#endif
@ -573,6 +574,7 @@ InitExtensions(argc, argv)
#ifdef GLXEXT
GlxPushProvider(&__glXMesaProvider);
GlxPushProvider(&__glXDRIswrastProvider);
if (!noGlxExtension) GlxExtensionInit();
#endif
}