summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/fb
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2003-08-06 18:11:57 +0000
committerKeith Whitwell <[email protected]>2003-08-06 18:11:57 +0000
commitb32a036059932fa5000e63a2ecb6d90d98864eb5 (patch)
tree208e12c407f72cbc3eedacbb543099e6b178d2d0 /src/mesa/drivers/dri/fb
parentb93652d67ed976562edc121b319b0594f79cc00a (diff)
Not-quite-functional swrast-only dri driver
Diffstat (limited to 'src/mesa/drivers/dri/fb')
-rw-r--r--src/mesa/drivers/dri/fb/Doxyfile232
-rw-r--r--src/mesa/drivers/dri/fb/Makefile.X1183
-rw-r--r--src/mesa/drivers/dri/fb/fb_dri.c729
3 files changed, 1044 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/fb/Doxyfile b/src/mesa/drivers/dri/fb/Doxyfile
new file mode 100644
index 00000000000..31256db834a
--- /dev/null
+++ b/src/mesa/drivers/dri/fb/Doxyfile
@@ -0,0 +1,232 @@
+# Doxyfile 1.3.2-Gideon
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = fb
+PROJECT_NUMBER = $VERSION$
+OUTPUT_DIRECTORY =
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+SHORT_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 8
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ALIASES =
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SHOW_USED_FILES = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = /home/temp/Mesa/src/drv/fb
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.C \
+ *.H \
+ *.tlh \
+ *.diff \
+ *.patch \
+ *.moc \
+ *.xpm
+RECURSIVE = yes
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = YES
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = yes
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 1000
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
+CGI_NAME = search.cgi
+CGI_URL =
+DOC_URL =
+DOC_ABSPATH =
+BIN_ABSPATH = /usr/local/bin/
+EXT_DOC_PATHS =
diff --git a/src/mesa/drivers/dri/fb/Makefile.X11 b/src/mesa/drivers/dri/fb/Makefile.X11
new file mode 100644
index 00000000000..feca4e957ac
--- /dev/null
+++ b/src/mesa/drivers/dri/fb/Makefile.X11
@@ -0,0 +1,83 @@
+# $Id: Makefile.X11,v 1.1 2003/08/06 18:11:57 keithw Exp $
+
+# Mesa 3-D graphics library
+# Version: 5.0
+# Copyright (C) 1995-2002 Brian Paul
+
+TOP = ../../../../..
+
+SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver
+MINIGLX_INCLUDES = -I$(TOP)/src/miniglx
+
+MESA_MODULES = $(TOP)/src/mesa/mesa.a
+
+DRIVER_SOURCES = fb_dri.c
+
+
+C_SOURCES = $(DRIVER_SOURCES) \
+ $(DRI_SOURCES)
+
+ASM_SOURCES =
+
+OBJECTS = $(C_SOURCES:.c=.o) \
+ $(ASM_SOURCES:.S=.o)
+
+
+ifeq ($(WINDOW_SYSTEM),dri)
+default2: clean
+else
+default2: fb_dri.so
+endif
+
+
+### Include directories
+
+INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -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/swrast \
+ -I$(TOP)/src/mesa/swrast_setup
+
+
+##### RULES #####
+
+.c.o:
+ $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+.S.o:
+ $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+
+##### TARGETS #####
+
+targets: fb_dri.so
+
+fb_dri.so: $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11
+ rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc -lm
+ rm -f $(TOP)/lib/fb_dri.so && \
+ install fb_dri.so $(TOP)/lib/fb_dri.so
+
+# Run 'make -f Makefile.X11 dep' to update the dependencies if you change
+# what's included by any source file.
+dep: $(C_SOURCES) $(ASM_SOURCES)
+ makedepend -fdepend -Y $(SHARED_INCLUDES) \
+ $(C_SOURCES) $(ASM_SOURCES)
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` `find ../include`
+
+
+# Remove .o and backup files
+clean:
+ -rm -f *.o *~ *.o *~ *.so
+
+
+include $(TOP)/Make-config
+
+include depend
diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c
new file mode 100644
index 00000000000..945a78f2d0f
--- /dev/null
+++ b/src/mesa/drivers/dri/fb/fb_dri.c
@@ -0,0 +1,729 @@
+/* $Id: fb_dri.c,v 1.1 2003/08/06 18:11:57 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.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.
+ *
+ * Todo:
+ * -- Use malloced (rather than framebuffer) memory for backbuffer
+ * -- 32bpp is hardwared -- fix
+ *
+ * NOTES:
+ * -- No mechanism for cliprects or resize notification --
+ * assumes this is a fullscreen device.
+ * -- No locking -- assumes this is the only driver accessing this
+ * device.
+ * -- Doesn't (yet) make use of any acceleration or other interfaces
+ * provided by fb. Would be entirely happy working against any
+ * fullscreen interface.
+ * -- HOWEVER: only a small number of pixelformats are supported, and
+ * the mechanism for choosing between them makes some assumptions
+ * that may not be valid everywhere.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+
+#include "GL/miniglx.h" /* window-system-specific */
+#include "miniglxP.h" /* window-system-specific */
+#include "dri_util.h" /* window-system-specific-ish */
+
+#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"
+
+
+
+typedef struct {
+ GLcontext *glCtx; /* Mesa context */
+
+ struct {
+ __DRIcontextPrivate *context;
+ __DRIscreenPrivate *screen;
+ __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */
+ } dri;
+} fbContext, *fbContextPtr;
+
+
+#define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx))
+
+
+static const GLubyte *
+get_string(GLcontext *ctx, GLenum pname)
+{
+ (void) ctx;
+ switch (pname) {
+ case GL_RENDERER:
+ return (const GLubyte *) "Mesa dumb framebuffer";
+ 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 );
+}
+
+
+static void
+get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ fbContextPtr fbmesa = FB_CONTEXT(ctx);
+
+ *width = fbmesa->dri.drawable->w;
+ *height = fbmesa->dri.drawable->h;
+}
+
+
+/* specifies the buffer for swrast span rendering/reading */
+static void
+set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
+{
+ fbContextPtr fbdevctx = FB_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
+
+ /* What a twisted mess of private structs
+ */
+ assert(buffer == dPriv->driverPrivate);
+
+
+ switch (bufferBit) {
+ case FRONT_LEFT_BIT:
+ dPriv->currentBuffer = dPriv->frontBuffer;
+ break;
+ case BACK_LEFT_BIT:
+ dPriv->currentBuffer = dPriv->backBuffer;
+ break;
+ default:
+ /* This happens a lot if the client renders to the frontbuffer */
+ if (0) _mesa_problem(ctx, "bad bufferBit in set_buffer()");
+ }
+}
+
+
+static void
+init_core_functions( GLcontext *ctx )
+{
+ ctx->Driver.GetString = get_string;
+ ctx->Driver.UpdateState = update_state;
+ ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+ ctx->Driver.GetBufferSize = get_buffer_size;
+
+ ctx->Driver.Accum = _swrast_Accum;
+ ctx->Driver.Bitmap = _swrast_Bitmap;
+ ctx->Driver.Clear = _swrast_Clear; /* could accelerate with blits */
+ ctx->Driver.CopyPixels = _swrast_CopyPixels;
+ ctx->Driver.DrawPixels = _swrast_DrawPixels;
+ ctx->Driver.ReadPixels = _swrast_ReadPixels;
+ ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
+
+ ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
+ ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+ ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+ ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+ ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
+ ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+ ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
+ ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+ ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+ ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
+ ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
+ ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+ ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
+
+ ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+ ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+ ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+ ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+ ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+ ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+ ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+ ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
+
+
+/*
+ * Generate code for span functions.
+ */
+
+/* 24-bit BGR */
+#define NAME(PREFIX) PREFIX##_B8G8R8
+#define SPAN_VARS \
+ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (char *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X) * 3
+#define INC_PIXEL_PTR(P) P += 3
+#define STORE_RGB_PIXEL(P, R, G, B) \
+ P[0] = B; P[1] = G; P[2] = R
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ P[0] = B; P[1] = G; P[2] = R
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = P[2]; G = P[1]; B = P[0]; A = CHAN_MAX
+
+#include "swrast/s_spantemp.h"
+
+
+/* 32-bit BGRA */
+#define NAME(PREFIX) PREFIX##_B8G8R8A8
+#define SPAN_VARS \
+ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (char *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X) * 4;
+#define INC_PIXEL_PTR(P) P += 4
+#define STORE_RGB_PIXEL(P, R, G, B) \
+ P[0] = B; P[1] = G; P[2] = R; P[3] = 255
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ P[0] = B; P[1] = G; P[2] = R; P[3] = A
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = P[2]; G = P[1]; B = P[0]; A = P[3]
+
+#include "swrast/s_spantemp.h"
+
+
+/* 16-bit BGR (XXX implement dithering someday) */
+#define NAME(PREFIX) PREFIX##_B5G6R5
+#define SPAN_VARS \
+ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLushort *P = (GLushort *) ((char *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X) * 2)
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_RGB_PIXEL(P, R, G, B) \
+ *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = ( (((*P) >> 8) & 0xf8) | (((*P) >> 11) & 0x7) ); \
+ G = ( (((*P) >> 3) & 0xfc) | (((*P) >> 5) & 0x3) ); \
+ B = ( (((*P) << 3) & 0xf8) | (((*P) ) & 0x7) ); \
+ A = CHAN_MAX
+
+#include "swrast/s_spantemp.h"
+
+
+/* 15-bit BGR (XXX implement dithering someday) */
+#define NAME(PREFIX) PREFIX##_B5G5R5
+#define SPAN_VARS \
+ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLushort *P = (GLushort *) ((char *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X) * 2)
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_RGB_PIXEL(P, R, G, B) \
+ *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = ( (((*P) >> 7) & 0xf8) | (((*P) >> 10) & 0x7) ); \
+ G = ( (((*P) >> 2) & 0xf8) | (((*P) >> 5) & 0x7) ); \
+ B = ( (((*P) << 3) & 0xf8) | (((*P) ) & 0x7) ); \
+ A = CHAN_MAX
+
+#include "swrast/s_spantemp.h"
+
+
+/* 8-bit color index */
+#define NAME(PREFIX) PREFIX##_CI8
+#define SPAN_VARS \
+ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (char *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X)
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_CI_PIXEL(P, CI) \
+ P[0] = CI
+#define FETCH_CI_PIXEL(CI, P) \
+ CI = P[0]
+
+#include "swrast/s_spantemp.h"
+
+
+
+/* Initialize the driver specific screen private data.
+ */
+static GLboolean
+fbInitDriver( __DRIscreenPrivate *sPriv )
+{
+ sPriv->private = NULL;
+ return GL_TRUE;
+}
+
+static void
+fbDestroyScreen( __DRIscreenPrivate *sPriv )
+{
+}
+
+/* Create the device specific context.
+ */
+static GLboolean
+fbCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate)
+{
+ fbContextPtr fbmesa;
+ GLcontext *ctx, *shareCtx;
+
+ assert(glVisual);
+ assert(driContextPriv);
+
+ /* Allocate the Fb context */
+ fbmesa = (fbContextPtr) CALLOC( sizeof(*fbmesa) );
+ if ( !fbmesa )
+ return GL_FALSE;
+
+ /* Allocate the Mesa context */
+ if (sharedContextPrivate)
+ shareCtx = ((fbContextPtr) sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+
+ ctx = fbmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
+ (void *) fbmesa,
+ GL_TRUE);
+ if (!fbmesa->glCtx) {
+ FREE(fbmesa);
+ return GL_FALSE;
+ }
+ driContextPriv->driverPrivate = fbmesa;
+
+ /* Create module contexts */
+ init_core_functions( ctx );
+ _swrast_CreateContext( ctx );
+ _ac_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+ _swsetup_Wakeup( ctx );
+
+
+
+ /* swrast init -- need to verify these tests - I just plucked the
+ * numbers out of the air. (KW)
+ */
+ {
+ struct swrast_device_driver *swdd;
+ swdd = _swrast_GetDeviceDriverReference( ctx );
+ swdd->SetBuffer = set_buffer;
+ if (!glVisual->rgbMode) {
+ swdd->WriteCI32Span = write_index32_span_CI8;
+ swdd->WriteCI8Span = write_index8_span_CI8;
+ swdd->WriteMonoCISpan = write_monoindex_span_CI8;
+ swdd->WriteCI32Pixels = write_index_pixels_CI8;
+ swdd->WriteMonoCIPixels = write_monoindex_pixels_CI8;
+ swdd->ReadCI32Span = read_index_span_CI8;
+ swdd->ReadCI32Pixels = read_index_pixels_CI8;
+ }
+ else if (glVisual->rgbBits == 24 &&
+ glVisual->alphaBits == 0) {
+ swdd->WriteRGBASpan = write_rgba_span_B8G8R8;
+ swdd->WriteRGBSpan = write_rgb_span_B8G8R8;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_B8G8R8;
+ swdd->WriteRGBAPixels = write_rgba_pixels_B8G8R8;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_B8G8R8;
+ swdd->ReadRGBASpan = read_rgba_span_B8G8R8;
+ swdd->ReadRGBAPixels = read_rgba_pixels_B8G8R8;
+ }
+ else if (glVisual->rgbBits == 32 &&
+ glVisual->alphaBits == 8) {
+ swdd->WriteRGBASpan = write_rgba_span_B8G8R8A8;
+ swdd->WriteRGBSpan = write_rgb_span_B8G8R8A8;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_B8G8R8A8;
+ swdd->WriteRGBAPixels = write_rgba_pixels_B8G8R8A8;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_B8G8R8A8;
+ swdd->ReadRGBASpan = read_rgba_span_B8G8R8A8;
+ swdd->ReadRGBAPixels = read_rgba_pixels_B8G8R8A8;
+ }
+ else if (glVisual->rgbBits == 16 &&
+ glVisual->alphaBits == 0) {
+ swdd->WriteRGBASpan = write_rgba_span_B5G6R5;
+ swdd->WriteRGBSpan = write_rgb_span_B5G6R5;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_B5G6R5;
+ swdd->WriteRGBAPixels = write_rgba_pixels_B5G6R5;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_B5G6R5;
+ swdd->ReadRGBASpan = read_rgba_span_B5G6R5;
+ swdd->ReadRGBAPixels = read_rgba_pixels_B5G6R5;
+ }
+ else if (glVisual->rgbBits == 15 &&
+ glVisual->alphaBits == 0) {
+ swdd->WriteRGBASpan = write_rgba_span_B5G5R5;
+ swdd->WriteRGBSpan = write_rgb_span_B5G5R5;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_B5G5R5;
+ swdd->WriteRGBAPixels = write_rgba_pixels_B5G5R5;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_B5G5R5;
+ swdd->ReadRGBASpan = read_rgba_span_B5G5R5;
+ swdd->ReadRGBAPixels = read_rgba_pixels_B5G5R5;
+ }
+ 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
+fbDestroyContext( __DRIcontextPrivate *driContextPriv )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ fbContextPtr fbmesa = (fbContextPtr) driContextPriv->driverPrivate;
+ fbContextPtr current = ctx ? FB_CONTEXT(ctx) : NULL;
+
+ /* check if we're deleting the currently bound context */
+ if (fbmesa == current) {
+ _mesa_make_current2(NULL, NULL, NULL);
+ }
+
+ /* Free fb context resources */
+ if ( fbmesa ) {
+ _swsetup_DestroyContext( fbmesa->glCtx );
+ _tnl_DestroyContext( fbmesa->glCtx );
+ _ac_DestroyContext( fbmesa->glCtx );
+ _swrast_DestroyContext( fbmesa->glCtx );
+
+ /* free the Mesa context */
+ fbmesa->glCtx->DriverCtx = NULL;
+ _mesa_destroy_context( fbmesa->glCtx );
+
+ FREE( fbmesa );
+ }
+}
+
+
+/* Create and initialize the Mesa and driver specific pixmap buffer
+ * data.
+ */
+static GLboolean
+fbCreateBuffer( __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
+fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+ _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+ free(driDrawPriv->backBuffer);
+}
+
+
+
+/* If the backbuffer is on a videocard, this is extraordinarily slow!
+ */
+static void
+fbSwapBuffers( __DRIdrawablePrivate *dPriv )
+{
+
+ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+ fbContextPtr fbmesa;
+ GLcontext *ctx;
+ fbmesa = (fbContextPtr) dPriv->driContextPriv->driverPrivate;
+ ctx = fbmesa->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, "fbSwapBuffers: drawable has no context!\n");
+ }
+}
+
+
+/* Force the context `c' to be the current context and associate with it
+ * buffer `b'.
+ */
+static GLboolean
+fbMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv )
+{
+ if ( driContextPriv ) {
+ fbContextPtr newFbCtx =
+ (fbContextPtr) 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
+fbUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+static GLboolean
+fbOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+static struct __DriverAPIRec fbAPI = {
+ fbInitDriver,
+ fbDestroyScreen,
+ fbCreateContext,
+ fbDestroyContext,
+ fbCreateBuffer,
+ fbDestroyBuffer,
+ fbSwapBuffers,
+ fbMakeCurrent,
+ fbUnbindContext,
+ fbOpenCloseFullScreen,
+ fbOpenCloseFullScreen
+};
+
+
+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(struct DRIDriverRec *driver,
+ struct DRIDriverContextRec *driverContext)
+{
+ __DRIscreenPrivate *psp;
+ psp = __driUtilCreateScreenNoDRM(driver, driverContext, &fbAPI);
+ 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, },
+};
+static int __driInitScreenModes( const DRIDriverContext *ctx,
+ int *numModes, const __GLcontextModes **modes)
+{
+ *numModes = sizeof(__glModes)/sizeof(__GLcontextModes *);
+ *modes = &__glModes[0];
+ return 1;
+}
+
+
+
+static int __driValidateMode(const DRIDriverContext *ctx )
+{
+ return 1;
+}
+
+/* HACK - for now, put this here... */
+/* Alpha - this may need to be a variable to handle UP1x00 vs TITAN */
+#if defined(__alpha__)
+# define DRM_PAGE_SIZE 8192
+#elif defined(__ia64__)
+# define DRM_PAGE_SIZE getpagesize()
+#else
+# define DRM_PAGE_SIZE 4096
+#endif
+
+
+static int __driInitFBDev( struct DRIDriverContextRec *ctx )
+{
+ int id;
+ ctx->shared.hFrameBuffer = ctx->FBStart;
+ ctx->shared.fbSize = ctx->FBSize;
+ ctx->shared.hSAREA = 0xB37D;
+ ctx->shared.SAREASize = DRM_PAGE_SIZE;
+ id = shmget(ctx->shared.hSAREA, ctx->shared.SAREASize, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
+ if (id == -1) {
+ /* segment will already exist if previous server segfaulted */
+ id = shmget(ctx->shared.hSAREA, ctx->shared.SAREASize, 0);
+ if (id == -1) {
+ fprintf(stderr, "fb: shmget failed\n");
+ return 0;
+ }
+ }
+ ctx->pSAREA = shmat(id, NULL, 0);
+ if (ctx->pSAREA == (void *)-1) {
+ fprintf(stderr, "fb: shmat failed\n");
+ return 0;
+ }
+ memset(ctx->pSAREA, 0, DRM_PAGE_SIZE);
+ return 1;
+}
+
+static void __driHaltFBDev( struct DRIDriverContextRec *ctx )
+{
+}
+
+
+
+struct DRIDriverRec __driDriver = {
+ __driInitScreenModes,
+ __driValidateMode,
+ __driValidateMode,
+ __driInitFBDev,
+ __driHaltFBDev
+};
+