From 4d6f05c971a042eed200984233e33522ca3ed4e7 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 3 May 2004 23:33:21 +0000 Subject: Skeletal fallback-only DRI driver. Initial checkin, not quite working yet. --- src/mesa/drivers/dri/x11/Makefile | 89 +++++++ src/mesa/drivers/dri/x11/x11_dri.c | 505 +++++++++++++++++++++++++++++++++++++ src/mesa/drivers/dri/x11/x11_dri.h | 12 + 3 files changed, 606 insertions(+) create mode 100644 src/mesa/drivers/dri/x11/Makefile create mode 100644 src/mesa/drivers/dri/x11/x11_dri.c create mode 100644 src/mesa/drivers/dri/x11/x11_dri.h diff --git a/src/mesa/drivers/dri/x11/Makefile b/src/mesa/drivers/dri/x11/Makefile new file mode 100644 index 0000000000..b98441a299 --- /dev/null +++ b/src/mesa/drivers/dri/x11/Makefile @@ -0,0 +1,89 @@ +# src/mesa/drivers/dri/x11/Makefile + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = x11_dri.so + +DRIVER_SOURCES = x11_dri.c \ + $(TOP)/src/mesa/drivers/common/driverfuncs.c \ + ../dri_client/dri_util.c \ + ../../x11/xm_api.c \ + ../../x11/xm_dd.c \ + ../../x11/xm_line.c \ + ../../x11/xm_span.c \ + ../../x11/xm_tri.c + +C_SOURCES = \ + $(DRIVER_SOURCES) \ + $(DRI_SOURCES) + + +# Include directories +INCLUDE_DIRS = \ + -I. \ + -I../common \ + -I../../x11 \ + -I../dri_client \ + -I../dri_client/imports \ + -Iserver \ + -I$(TOP)/include \ + -I$(DRM_SOURCE_PATH)/shared \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup + +# Core Mesa objects +MESA_MODULES = $(TOP)/src/mesa/mesa.a + +# Libraries that the driver shared lib depends on +LIB_DEPS = -lm -lpthread -lc +# LIB_DEPS = -lGL -lm -lpthread -lc + + +ASM_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend $(LIB_DIR)/$(LIBNAME) + + +$(LIB_DIR)/$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile + $(TOP)/bin/mklib -o $(LIBNAME) -noprefix -install $(LIB_DIR) \ + $(OBJECTS) $(WINLIB) $(LIB_DEPS) $(WINOBJ) $(MESA_MODULES) + + +depend: $(C_SOURCES) $(ASM_SOURCES) + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDE_DIRS) $(C_SOURCES) $(ASM_SOURCES) \ + >& /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +clean: + -rm -f *.o server/*.o + + +include depend diff --git a/src/mesa/drivers/dri/x11/x11_dri.c b/src/mesa/drivers/dri/x11/x11_dri.c new file mode 100644 index 0000000000..5ea3f1a1c4 --- /dev/null +++ b/src/mesa/drivers/dri/x11/x11_dri.c @@ -0,0 +1,505 @@ +/* + * Mesa 3-D graphics library + * Version: 0.1 + * + * Copyright (C) 1999-2002 Brian Paul 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +/* Minimal swrast-based DRI-loadable driver. + * + * Derived from fb_dri.c, the difference being that one works for + * framebuffers without X, whereas this points Mesa at an X surface + * to draw on. + * + * This is basically just a wrapper around src/mesa/drivers/x11 to make it + * look like a DRI driver. + */ + +#define GLX_DIRECT_RENDERING + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dri_util.h" + +#include "GL/xmesa.h" +#include "xmesaP.h" + +#include "mtypes.h" +#include "context.h" +#include "extensions.h" +#include "imports.h" +#include "matrix.h" +#include "texformat.h" +#include "texstore.h" +#include "teximage.h" +#include "array_cache/acache.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "drivers/common/driverfuncs.h" + +#include "x11_dri.h" + +typedef struct { + GLcontext *glCtx; /* Mesa context */ + + struct { + __DRIcontextPrivate *context; + __DRIscreenPrivate *screen; + __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */ + } dri; +} x11Context, *x11ContextPtr; + +#define X11_CONTEXT(ctx) ((x11ContextPtr)(ctx->DriverCtx)) + +static const GLubyte * +get_string(GLcontext *ctx, GLenum pname) +{ + (void) ctx; + switch (pname) { + case GL_RENDERER: + return (const GLubyte *) "Mesa X11 hack"; + default: + return NULL; + } +} + +static void +update_state(GLcontext *ctx, GLuint new_state) +{ + /* not much to do here - pass it on */ + _swrast_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + _ac_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); +} + +/** + * Called by ctx->Driver.GetBufferSize from in core Mesa to query the + * current framebuffer size. + */ +static void +get_buffer_size(GLframebuffer *buffer, GLuint *width, GLuint *height) +{ + GET_CURRENT_CONTEXT(ctx); + x11ContextPtr x11mesa = X11_CONTEXT(ctx); + + *width = x11mesa->dri.drawable->w; + *height = x11mesa->dri.drawable->h; +} + +static void +init_core_functions(struct dd_function_table *functions) +{ + functions->GetString = get_string; + functions->UpdateState = update_state; + functions->ResizeBuffers = _swrast_alloc_buffers; + functions->GetBufferSize = get_buffer_size; + + functions->Clear = _swrast_Clear; /* could accelerate with blits */ +} + +/* Initialize the driver specific screen private data. + */ +static GLboolean +x11InitDriver(__DRIscreenPrivate *sPriv) +{ + sPriv->private = NULL; + return GL_TRUE; +} + +static void +x11DestroyScreen(__DRIscreenPrivate *sPriv) +{ +} + +/* placeholders, disables rendering */ +static void +nullwrite(void *a, int b, int c, int d, void *e, void *f) +{ +} + +static void +set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit ) +{ +} + +/* Create the device specific context. */ +static GLboolean +x11CreateContext(const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate) +{ + x11ContextPtr x11mesa; + GLcontext *ctx, *shareCtx; + struct dd_function_table functions; + + assert(glVisual); + assert(driContextPriv); + + /* Allocate the Fb context */ + x11mesa = (x11ContextPtr) CALLOC(sizeof(*x11mesa)); + if (!x11mesa) + return GL_FALSE; + + /* Init default driver functions then plug in our own functions */ + _mesa_init_driver_functions(&functions); + init_core_functions(&functions); + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((x11ContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + + ctx = x11mesa->glCtx = _mesa_create_context(glVisual, shareCtx, + &functions, (void *) x11mesa); + if (!x11mesa->glCtx) { + FREE(x11mesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = x11mesa; + + /* Create module contexts */ + _swrast_CreateContext(ctx); + _ac_CreateContext(ctx); + _tnl_CreateContext(ctx); + _swsetup_CreateContext(ctx); + _swsetup_Wakeup(ctx); + + /* swrast init */ + { + struct swrast_device_driver *swdd; + swdd = _swrast_GetDeviceDriverReference(ctx); + swdd->SetBuffer = set_buffer; + if (!glVisual->rgbMode) { + swdd->WriteCI32Span = + swdd->WriteCI32Span = + swdd->WriteCI8Span = + swdd->WriteMonoCISpan = + swdd->WriteCI32Pixels = + swdd->WriteMonoCIPixels = + swdd->ReadCI32Span = + swdd->ReadCI32Pixels = nullwrite; + } + else if (glVisual->rgbBits == 24 && + glVisual->alphaBits == 0) { + swdd->WriteRGBASpan = + swdd->WriteRGBSpan = + swdd->WriteMonoRGBASpan = + swdd->WriteRGBAPixels = + swdd->WriteMonoRGBAPixels = + swdd->ReadRGBASpan = + swdd->ReadRGBAPixels = nullwrite; + } + else if (glVisual->rgbBits == 32 && + glVisual->alphaBits == 8) { + swdd->WriteRGBASpan = + swdd->WriteRGBSpan = + swdd->WriteMonoRGBASpan = + swdd->WriteRGBAPixels = + swdd->WriteMonoRGBAPixels = + swdd->ReadRGBASpan = + swdd->ReadRGBAPixels = nullwrite; + } + else if (glVisual->rgbBits == 16 && + glVisual->alphaBits == 0) { + swdd->WriteRGBASpan = + swdd->WriteRGBSpan = + swdd->WriteMonoRGBASpan = + swdd->WriteRGBAPixels = + swdd->WriteMonoRGBAPixels = + swdd->ReadRGBASpan = + swdd->ReadRGBAPixels = nullwrite; + } + else if (glVisual->rgbBits == 15 && + glVisual->alphaBits == 0) { + swdd->WriteRGBASpan = + swdd->WriteRGBSpan = + swdd->WriteMonoRGBASpan = + swdd->WriteRGBAPixels = + swdd->WriteMonoRGBAPixels = + swdd->ReadRGBASpan = + swdd->ReadRGBAPixels = nullwrite; + } + else { + _mesa_printf("bad pixelformat rgb %d alpha %d\n", + glVisual->rgbBits, + glVisual->alphaBits ); + } + } + + /* use default TCL pipeline */ + { + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.RunPipeline = _tnl_run_pipeline; + } + + _mesa_enable_sw_extensions(ctx); + + return GL_TRUE; +} + + +static void +x11DestroyContext(__DRIcontextPrivate *driContextPriv) +{ + GET_CURRENT_CONTEXT(ctx); + x11ContextPtr x11mesa = (x11ContextPtr) driContextPriv->driverPrivate; + x11ContextPtr current = ctx ? X11_CONTEXT(ctx) : NULL; + + /* check if we're deleting the currently bound context */ + if (x11mesa == current) { + _mesa_make_current2(NULL, NULL, NULL); + } + + /* Free x11 context resources */ + if (x11mesa) { + _swsetup_DestroyContext(x11mesa->glCtx); + _tnl_DestroyContext(x11mesa->glCtx); + _ac_DestroyContext(x11mesa->glCtx); + _swrast_DestroyContext(x11mesa->glCtx); + + /* free the Mesa context */ + x11mesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context(x11mesa->glCtx); + + FREE(x11mesa); + } +} + + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +static GLboolean +x11CreateBuffer(__DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + const GLboolean swDepth = mesaVis->depthBits > 0; + const GLboolean swAlpha = mesaVis->alphaBits > 0; + const GLboolean swAccum = mesaVis->accumRedBits > 0; + const GLboolean swStencil = mesaVis->stencilBits > 0; + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer(mesaVis, + swDepth, + swStencil, + swAccum, + swAlpha); + + if (!driDrawPriv->driverPrivate) + return 0; + + /* Replace the framebuffer back buffer with a malloc'ed one -- + * big speedup. + */ +/* + if (driDrawPriv->backBuffer) + driDrawPriv->backBuffer = malloc(driDrawPriv->currentPitch * driDrawPriv->h); +*/ + + return 1; + } +} + + +static void +x11DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +/* free(driDrawPriv->backBuffer); */ +} + + + +/* If the backbuffer is on a videocard, this is extraordinarily slow! + */ +static void +x11SwapBuffers(__DRIdrawablePrivate *dPriv) +{ + + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + x11ContextPtr x11mesa; + GLcontext *ctx; + x11mesa = (x11ContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = x11mesa->glCtx; + if (ctx->Visual.doubleBufferMode) { + int i; + int offset = 0; + char *tmp /*= malloc(dPriv->currentPitch) */ ; + + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + +/* + ASSERT(dPriv->frontBuffer); + ASSERT(dPriv->backBuffer); + + for (i = 0 ; i < dPriv->h ; i++ ) { + memcpy(tmp, (char *)dPriv->frontBuffer + offset, dPriv->currentPitch); + memcpy((char *)dPriv->backBuffer + offset, tmp, dPriv->currentPitch); + offset += dPriv->currentPitch; + } + + free(tmp); +*/ + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "x11SwapBuffers: drawable has no context!\n"); + } +} + + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +static GLboolean +x11MakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + if (driContextPriv) { + x11ContextPtr newFbCtx = + (x11ContextPtr) driContextPriv->driverPrivate; + + newFbCtx->dri.drawable = driDrawPriv; + + _mesa_make_current2(newFbCtx->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate); + + if (!newFbCtx->glCtx->Viewport.Width) { + _mesa_set_viewport(newFbCtx->glCtx, 0, 0, + driDrawPriv->w, driDrawPriv->h); + } + } else { + _mesa_make_current(0, 0); + } + + return GL_TRUE; +} + + +/* Force the context `c' to be unbound from its buffer. + */ +static GLboolean +x11UnbindContext(__DRIcontextPrivate *driContextPriv) +{ + return GL_TRUE; +} + +static GLboolean +x11OpenCloseFullScreen(__DRIcontextPrivate *driContextPriv) +{ + return GL_TRUE; +} + +static struct __DriverAPIRec x11API = { + x11InitDriver, + x11DestroyScreen, + x11CreateContext, + x11DestroyContext, + x11CreateBuffer, + x11DestroyBuffer, + x11SwapBuffers, + x11MakeCurrent, + x11UnbindContext, + x11OpenCloseFullScreen, + x11OpenCloseFullScreen +}; + +void +__driRegisterExtensions(void) +{ +} + +/* + * This is the bootstrap function for the driver. + * The __driCreateScreen name is the symbol that libGL.so fetches. + * Return: pointer to a __DRIscreenPrivate. + */ +void * +__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &x11API); + return (void *) psp; +} + +/** + * \brief Establish the set of modes available for the display. + * + * \param ctx display handle. + * \param numModes will receive the number of supported modes. + * \param modes will point to the list of supported modes. + * + * \return one on success, or zero on failure. + * + * Allocates a single visual and fills it with information according to the + * display bit depth. Supports only 16 and 32 bpp bit depths, aborting + * otherwise. + */ +const __GLcontextModes __glModes[] = { + /* 32 bit, RGBA Depth=24 Stencil=8 */ + {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, + .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE, + .redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8, + .redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000, + .rgbBits = 32, .indexBits = 0, + .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, + .depthBits = 24, .stencilBits = 8, + .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, + + /* 16 bit, RGB Depth=16 */ + {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, + .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE, + .redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0, + .redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0, + .rgbBits = 16, .indexBits = 0, + .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, + .depthBits = 16, .stencilBits = 0, + .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, +}; diff --git a/src/mesa/drivers/dri/x11/x11_dri.h b/src/mesa/drivers/dri/x11/x11_dri.h new file mode 100644 index 0000000000..fd1e64f456 --- /dev/null +++ b/src/mesa/drivers/dri/x11/x11_dri.h @@ -0,0 +1,12 @@ +typedef struct { + + void *frontBuffer; + void *backBuffer; + void *currentBuffer; + int currentPitch; + + int depthCpp; + void *depthBuffer; + int depthPitch; + +} x11ScreenPrivate; -- cgit v1.2.3