Not-quite-functional swrast-only dri driver

This commit is contained in:
Keith Whitwell
2003-08-06 18:11:57 +00:00
parent b93652d67e
commit b32a036059
3 changed files with 1044 additions and 0 deletions
+232
View File
@@ -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 =
+83
View File
@@ -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
+729
View File
@@ -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
};