diff options
author | Keith Whitwell <[email protected]> | 2003-08-06 18:11:57 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2003-08-06 18:11:57 +0000 |
commit | b32a036059932fa5000e63a2ecb6d90d98864eb5 (patch) | |
tree | 208e12c407f72cbc3eedacbb543099e6b178d2d0 /src | |
parent | b93652d67ed976562edc121b319b0594f79cc00a (diff) |
Not-quite-functional swrast-only dri driver
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/fb/Doxyfile | 232 | ||||
-rw-r--r-- | src/mesa/drivers/dri/fb/Makefile.X11 | 83 | ||||
-rw-r--r-- | src/mesa/drivers/dri/fb/fb_dri.c | 729 |
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 +}; + |