mesa: Remove obsolete linux-fbdev software driver

Acked-by: Kristian Høgsberg <krh@bitplanet.net>
Acked-by: Marek Olšák <maraeo@gmail.com>
Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Acked-by: Jakob Bornecrantz <jakob@vmware.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Build-Tested-by: Jakob Bornecrantz <jakob@vmware.com>
Tested-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
This commit is contained in:
Ian Romanick
2011-08-24 14:50:12 -07:00
parent 5070903653
commit 17645103aa
7 changed files with 1 additions and 1337 deletions

View File

@@ -1,16 +0,0 @@
# Configuration for Linux fbdev interface
include $(TOP)/configs/linux
CONFIG_NAME = linux-fbdev
CFLAGS += -DUSE_GLFBDEV_DRIVER
# Work around aliasing bugs - developers should comment this out
CFLAGS += -fno-strict-aliasing
DRIVER_DIRS = fbdev osmesa
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lm -lpthread
OSMESA_LIB_DEPS = -lm -lpthread

View File

@@ -76,9 +76,7 @@ a:visited {
<li><a href="helpwanted.html" target="MainFrame">Help Wanted</a>
<li><a href="devinfo.html" target="MainFrame">Development Notes</a>
<li><a href="sourcedocs.html" target="MainFrame">Source Documentation</a>
<li><a href="fbdev-dri.html" target="MainFrame">fbdev/DRI Environment</a>
<li><a href="subset.html" target="MainFrame">Mesa Subset Driver</a>
<li><a href="glfbdev-driver.html" target="MainFrame">glFBDev Driver</a>
<LI><A HREF="dispatch.html" target="MainFrame">GL Dispatch</A>
<li><a href="cell.html" target="MainFrame">Cell Driver</A>
</ul>

View File

@@ -1,343 +0,0 @@
<html><head><title>Mesa fbdev/DRI Environment</title>
<link rel="stylesheet" type="text/css" href="mesa.css"></head>
<body>
<center><h1>Mesa fbdev/DRI Drivers</h1></center>
<br>
<h1><center>NOTE: this information is obsolete and will be removed at
a future date</center></h1>
<h1>1. Introduction</h1>
<p>
The fbdev/DRI environment supports hardware-accelerated 3D rendering without
the X window system. This is typically used for embedded applications.
</p>
<p>
Contributors to this project include Jon Smirl, Keith Whitwell and Dave Airlie.
</p>
<p>
Applications in the fbdev/DRI environment use
the MiniGLX interface to choose pixel
formats, create rendering contexts, etc. It's a subset of the GLX and
Xlib interfaces allowing some degree of application portability between
the X and X-less environments.
</p>
<p>
Note that this environment is not well-supported and these instructions
may not be completely up to date.
</p>
<br>
<h1>2. Compilation</h1>
<p>
<h2>2.1 glxproto</h2>
Get <a href="http://cvsweb.xfree86.org/cvsweb/*checkout*/xc/include/GL/glxproto.h?rev=1.9">glxproto.h</a>. Copy it to the /mesa/include/GL/ directory.
</p>
<h2>2.2 libpciaccess</h2>
<p>
Check if you have libpciaccess installed:
</p>
<pre>pkg-config --modversion pciaccess
</pre>
<p>
If not you can download the latest code from:
</p>
<pre> git clone git://anongit.freedesktop.org/git/xorg/lib/libpciaccess
</pre>
<p>
Run autogen.sh to generate a configure file. autogen.sh uses autoconf
utility. This utility may not be installed with your linux distro,
check if it is available. if not you can use your package manager or
type:
</p>
<pre>sudo apt-get install autoconf
</pre>
The next step is to install the libpciaccess library.
<pre>make
make install
</pre>
<p> Now your libpciaccess.a file is saved into /usr/local/lib
directory. If you have a libpciaccess.a in /usr/lib you may simply copy
and overwrite these files. Don't forget to copy libpciaccess.pc file to
/usr/lib/pkgconfig, which is also located in /usr/local/lib/pkgconfig/.
Or you may use the following system variables:
</p>
<pre>export LD_LIBRARY_PATH=/usr/local/lib
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
</pre>
<h2>2.3 drm</h2>
<p>The next step is to compile the drm. DRM consists of two seperate parts,
the DRM client library(lindrm.so) and kernel device module(such as
radeon.ko). We need to make a small change in kernel device module. So
you need to download the kernel source. You may choose the nearest
mirror from www.kernel.org, or you are using Fedora Core 5, for
example, you may need to install RPMs such as:
kernel-smp-devel-2.16.15-1.2054_FC5.i686.rpm
kernel-devel-2.6.15-1.2054_FC5.i686.rpm
etc. You can find a detailed information <a href="http://www.howtoforge.com/kernel_compilation_fedora">here.</a>
</p>
<p>You will find drm_drv.c at /usr/src/LINUX-VERSION/drivers/char/drm/. Edit this code and comment out the following part:
</p>
<pre>
/* ||
((ioctl-&gt;flags &amp; DRM_MASTER) &amp;&amp; !priv-&gt;master)*/
</pre>
Now you are ready to compile your kernel. If your kernel version is
identical to the version you have compiled, you can simply over write
your new "ko" files over older ones. If you have compiled a different
kernel, you must configure your grub or lilo to be able to boot your
new kernel. <p>
You'll need fbdev header files. Check with:
</p>
<pre>
ls -l /usr/include/linux/fb.
</pre>
<p>This file may be missing if you have not installed linux header files.
<h2>2.4 Mesa</h2>
</p><p>Get latest development Mesa sources from git repository
(currently 7.1-prerelease)
</p>
<pre>
git clone git://anongit.freedesktop.org/git/mesa/mesa
</pre>
<p>You will need the makedepend utility which is a part of mesa project
to build your linux-solo. You probably wont have this utility. You can
download its source from following git repulsitory:
</p>
<pre>
git clone git://anongit.freedesktop.org/git/xorg/util/makedepend
</pre>
<p>Get the latest stable mesa version from SourceForge (currently 7.0.3)
<a href="http://sourceforge.net/project/showfiles.php?group_id=3">http://sourceforge.net/project/showfiles.php?group_id=3</a>
</p>
<p>Copy the miniglx folder from 7.1-prerelease to 7.0.3.
You may also extract GLUT to 7.0.3 version at this step.
</p>
<p>Edit linux-solo.conf at /conf directory, just only compile the
graphics driver you need, delete the unwanted drivers names from the
list(some drivers are causing problems...)
</p>
<pre>
while(build==0)
{
make linux-solo
There will be some missing header files, copy them from 7.1-prerelease
}
</pre>
<p>
When complete you should have the following:
</p>
<ul>
<li>lib/libGL.so - the GL library which applications link with
</li><li>lib/*_dri_so - DRI drivers
</li><li>lib/miniglx.conf - sample MiniGLX config file
</li><li>progs/miniglx/* - several MiniGLX sample programs
</li></ul>
To install these files into appropriate locations in system:
<pre>
make install
</pre>
Now your openGL libraries are copied to /usr/local/lib and
miniglx.conf is copied to /etc. You may copy them to /usr/lib and
overwrite your old GL libraries. Or you may export following variable:
<pre>
export LIBGL_DRIVERS_PATH=/usr/local/lib
</pre>
<br>
<h1>3. Using fbdev/DRI</h1>
<p>
If an X server currently running, exit/stop it so you're working from
the console. Following command shuts down the x window and also the multi user support.
</p>
<pre>
init 1
</pre>
<p>Also you may define the runlevel as 1 in "/etc/inittab". Your system
will always start in single user mode and without x-window with this
option set.
</p><h2>3.1 Load Kernel Modules</h2>
<p>
You'll need to load the kernel modules specific to your graphics hardware.
Typically, this consists of the agpgart module, an fbdev driver module
and the DRM kernel module.
</p>
<p>
As root, the kernel modules can be loaded as follows:
</p>
<p>
If you have Intel i915/i945 hardware:
</p>
<pre> modprobe agpgart # the AGP GART module
modprobe intelfb # the Intel fbdev driver
modprobe i915 # the i915/945 DRI kernel module
</pre>
<p>
If you have ATI Radeon/R200 hardware:
</p>
<pre> modprobe agpgart # the AGP GART module
modprobe radeonfb # the Radeon fbdev driver
modprobe radeon # the Radeon DRI kernel module
</pre>
<p>
If you have ATI Rage 128 hardware:
</p>
<pre> modprobe agpgart # the AGP GART module
modprobe aty128fb # the Rage 128 fbdev driver
modprobe r128 # the Rage 128 DRI kernel module
</pre>
<p>
If you have Matrox G200/G400 hardware:
</p>
<pre> modprobe agpgart # the AGP GART module
modprobe mgafb # the Matrox fbdev driver
modprobe mga # the Matrox DRI kernel module
</pre>
<p>
To verify that the agpgart, fbdev and drm modules are loaded:
</p>
<pre> ls -l /dev/agpgart /dev/fb* /dev/dri
</pre>
<p>
Alternately, use lsmod to inspect the currently installed modules.
If you have problems, look at the output of dmesg.
</p>
<h2>3.2 Configuration File</h2>
<p>
review/edit /etc/miniglx.conf.
Alternately, the MINIGLX_CONF environment variable can be used to
indicate the location of miniglx.conf
</p>
To determine the pciBusID value, run lspci and examine the output.
For example:
<p></p>
<pre> /sbin/lspci:
00:02.0 VGA compatible controller: Intel Corporation 82915G/GV/910GL Express Chipset Family Graphics Controller (rev 04)
</pre>
<p>
00:02.0 indicates that pciBusID should be PCI:0:2:0
</p>
<h2>3.3 Running fbdev/DRI Programs</h2>
<p>
Make sure your LD_LIBRARY_PATH environment variable is set to the
location of the libGL.so library. You may need to append other paths
to LD_LIBRARY_PATH if libpciaccess.so is in a non-standard location,
for example.
</p>
<p>
Change to the <code>Mesa/progs/miniglx/</code> directory and
start the sample_server program in the background:
</p>
<pre> ./sample_server &amp;
</pre>
<p>
Then try running the <code>miniglxtest</code> program:
</p>
<pre> ./miniglxtest
</pre>
<p>
You should see a rotating quadrilateral which changes color as it rotates.
It will exit automatically after a bit.
</p>
<p>
If you run other tests in the miniglx/ directory, you may want to run
them from a remote shell so that you can stop them with ctrl-C.
</p>
<br>
<h1>4.0 Troubleshooting</h1>
<ol>
<li>
If you try to run miniglxtest and get the following:
<br>
<pre> [miniglx] failed to probe chipset
connect: Connection refused
server connection lost
</pre>
It means that the sample_server process is not running.
<br>
<br>
</li>
</ol>
<h1>5.0 Programming Information</h1>
<p>
OpenGL/Mesa is interfaced to fbdev via the MiniGLX interface.
MiniGLX is a subset of Xlib and GLX API functions which provides just
enough functionality to setup OpenGL rendering and respond to simple
input events.
</p>
<p>
Since MiniGLX is a subset of the usual Xlib and GLX APIs, programs written
to the MiniGLX API can also be run on full Xlib/GLX implementations.
This allows some degree of flexibility for software development and testing.
</p>
<p>
However, the MiniGLX API is not binary-compatible with full Xlib/GLX.
Some of the structures are different and some macros/functions work
differently.
See the GL/miniglx.h header file for details.
</p>
</body>
</html>

View File

@@ -1,111 +0,0 @@
<HTML>
<TITLE>Mesa glFBDev Driver</TITLE>
<link rel="stylesheet" type="text/css" href="mesa.css"></head>
<BODY>
<center><H1>Mesa glFBDev Driver</H1></center>
<H1>1. Introduction</H1>
<p>
The GLFBDev driver interface allows one to do OpenGL rendering into a
framebuffer managed with the Linux's fbdev interface.
</p>
<p>
Basically, the programmer uses the fbdev functions to initialize the
graphics hardware and setup the framebuffer.
Then, using a calls to Mesa's glFBDev API functions, one can render
into the framebuffer with the OpenGL API functions.
</p>
<p>
Note, only software rendering is supported; there is no hardware
acceleration.
</p>
<p>
The GL/glfbdev.h header file defines the glFBDev interface.
</p>
<p>
The progs/fbdev/glfbdevtest.c demonstrates how to use the glFBDev interface.
</p>
<p>
For more information about fbdev, see the
<a href="http://www.tldp.org/HOWTO/Framebuffer-HOWTO.html" target="_parent">
Framebuffer Howto</a>
</p>
<p>
You will need at minimum, a framebuffer device, check /dev/fb0
</p>
<h1>2. Compilation</h1>
<p>
To compile Mesa with support for the glFBDev interface:
<pre>
make realclean
make linux-fbdev
</pre>
<p>
When compilation is finished look in progs/glfbdev/ for the glfbdevtest demo.
</p>
<h1>3. Permissions</h1>
<p>
Typically /dev/fb/0 is grouped to the video group. It may be useful to add
your user to the video group so the demos will not have to be run as root.
To use fbdevglut with the prefered tty input, you should add the user to the
tty group as well
<p>
<h1>4. Using fbdevglut</h1>
Almost all of the programs in the progs directory use glut, and they compile with fbdevglut.
<p>
To compile the redbook sample programs:
<pre>
cd progs/redbook
make
</pre>
</p>
<p>glut features not supported:
<li>Overlays
<li>Subwindows
<li>Input devices other than Keyboard/Mouse
<li>No support for GLUT_MULTISAMPLE, GLUT_STEREO, or GLUT_LUMINANCE
<li>Cursor and Menu Support will flicker in GLUT_SINGLE mode
<p>Keyboard input is read by opening /dev/tty and reading keycodes in medium raw mode.
<p>Mouse input is read from env var MOUSE, or /dev/gpmdata and should be in ms3 format.
To forward data in this format to /dev/gpmdata, run gpm with the -Rms3 option.
<p> glutInit allows glut programs to pass parameters to the glut library, currently the
following options are supported for fbdevglut:
<p><li>-geometry widthxheight -- This will force the resolution to be widthxheight instead of autodetecting.
The modes are read from /etc/fb.modes
<p><li>-bpp -- This will force the bitdepth to the one specified
<p><li>-vt -- This allows you to specify the virtual terminal to attach keyboard input to. It is useful to specify when running inside screen.
<p><li>-mousespeed -- A floating point multiplication factor to increase mouse speed
<p><li>-nomouse -- Disable mouse support
<p><li>-nokeyboard -- Disable keyboard support (this will probably break mouse support as well)
<p><li>-stdin -- Use stdin for input instead of attaching to kbd in medium-raw mode.
This will make it impossible to detect keypresses like Shift+Tab, you will also need to specify -gpmmouse for mouse support. This option can be used with a debugger, and it is possible to single step a program with gdb and set the FRAMEBUFFER environment variable to a different framebuffer for display. The program will not be able to handle vt switching on it's own, so it will always display.
<p><li>-gpmmouse -- This will attempt to connect to the /dev/gpmctl socket using liblow
for mouse data. Gpm does not provide this data when in graphics mode, so vt switching
will briefly display text. This mode typically has no initial mouse delay.
<p><li>-- Ignore any additional arguments
<p>Notes:
<p>
1. The mouse pointer flickers in single buffering mode, as it must be rendered in software. Hopefully in the future there will be a way to access hardware cursors in fbdev devices.
</p>
</body>
</html>

View File

@@ -12,7 +12,7 @@
In 2002/2003 Tungsten Graphics was contracted to develop a subset Mesa/Radeon
driver for an embedded environment. The result is a reduced-size DRI driver
for the ATI R200 chip, for use with
<a href="fbdev-dri.html">fbdev/DRI environment</a>.
fbdev/DRI environment.
</p>
<p>

View File

@@ -1,36 +0,0 @@
# src/mesa/drivers/fbdev/Makefile for libGL.so
TOP = ../../../..
include $(TOP)/configs/current
SOURCES = glfbdev.c
OBJECTS = $(SOURCES:.c=.o)
INCLUDE_DIRS = \
-I$(TOP)/include \
-I$(TOP)/src/mapi \
-I$(TOP)/src/mesa \
-I$(TOP)/src/mesa/main
CORE_MESA = $(TOP)/src/mesa/libmesa.a $(TOP)/src/mapi/glapi/libglapi.a
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(CORE_MESA) $(OBJECTS)
@ $(MKLIB) -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
$(CORE_MESA) $(OBJECTS) $(GL_LIB_DEPS)
clean:
-rm -f $(OBJECTS)

View File

@@ -1,828 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 7.1
*
* Copyright (C) 1999-2007 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.
*/
/*
* OpenGL (Mesa) interface for fbdev.
* For info about fbdev:
* http://www.tldp.org/HOWTO/Framebuffer-HOWTO.html
*
* known VGA modes
* Colours 640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
* --------+--------------------------------------------------------------
* 4 bits | ? ? 0x302 ? ? ? ?
* 8 bits | 0x300 0x301 0x303 0x305 0x161 0x307 0x31C
* 15 bits | ? 0x310 0x313 0x316 0x162 0x319 0x31D
* 16 bits | ? 0x311 0x314 0x317 0x163 0x31A 0x31E
* 24 bits | ? 0x312 0x315 0x318 ? 0x31B 0x31F
* 32 bits | ? ? ? ? 0x164 ?
*/
#ifdef USE_GLFBDEV_DRIVER
#include "GL/glfbdev.h"
#include <linux/fb.h>
#include "main/glheader.h"
#include "main/buffers.h"
#include "main/context.h"
#include "main/extensions.h"
#include "main/fbobject.h"
#include "main/framebuffer.h"
#include "main/imports.h"
#include "main/renderbuffer.h"
#include "main/texformat.h"
#include "main/teximage.h"
#include "main/texstore.h"
#include "vbo/vbo.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "drivers/common/driverfuncs.h"
/**
* Pixel formats we support:
*/
#define PF_B8G8R8 1
#define PF_B8G8R8A8 2
#define PF_B5G6R5 3
#define PF_B5G5R5 4
/**
* Derived from Mesa's struct gl_config class.
*/
struct GLFBDevVisualRec {
struct gl_config glvisual; /* base class */
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;
int pixelFormat;
};
/**
* Derived from Mesa's struct gl_framebuffer class.
*/
struct GLFBDevBufferRec {
struct gl_framebuffer glframebuffer; /* base class */
GLFBDevVisualPtr visual;
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;
size_t size; /* color buffer size in bytes */
GLuint bytesPerPixel;
};
/**
* Derived from Mesa's struct gl_context class.
*/
struct GLFBDevContextRec {
struct gl_context glcontext; /* base class */
GLFBDevVisualPtr visual;
GLFBDevBufferPtr drawBuffer;
GLFBDevBufferPtr readBuffer;
GLFBDevBufferPtr curBuffer;
};
/**
* Derived from Mesa's gl_renderbuffer class.
*/
struct GLFBDevRenderbufferRec {
struct gl_renderbuffer Base;
GLubyte *bottom; /* pointer to last row */
GLuint rowStride; /* in bytes */
GLboolean mallocedBuffer;
};
/**********************************************************************/
/* Internal device driver functions */
/**********************************************************************/
static const GLubyte *
get_string(struct gl_context *ctx, GLenum pname)
{
(void) ctx;
switch (pname) {
case GL_RENDERER:
return (const GLubyte *) "Mesa glfbdev";
default:
return NULL;
}
}
static void
update_state( struct gl_context *ctx, GLuint new_state )
{
/* not much to do here - pass it on */
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
_vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
}
static void
get_buffer_size( struct gl_framebuffer *buffer, GLuint *width, GLuint *height )
{
const GLFBDevBufferPtr fbdevbuffer = (GLFBDevBufferPtr) buffer;
*width = fbdevbuffer->var.xres;
*height = fbdevbuffer->var.yres;
}
/**
* We only implement this function as a mechanism to check if the
* framebuffer size has changed (and update corresponding state).
*/
static void
viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
{
GLuint newWidth, newHeight;
struct gl_framebuffer *buffer;
buffer = ctx->WinSysDrawBuffer;
get_buffer_size( buffer, &newWidth, &newHeight );
if (buffer->Width != newWidth || buffer->Height != newHeight) {
_mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
}
buffer = ctx->WinSysReadBuffer;
get_buffer_size( buffer, &newWidth, &newHeight );
if (buffer->Width != newWidth || buffer->Height != newHeight) {
_mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
}
}
/*
* Generate code for span functions.
*/
/* 24-bit BGR */
#define NAME(PREFIX) PREFIX##_B8G8R8
#define RB_TYPE GLubyte
#define SPAN_VARS \
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
#define INIT_PIXEL_PTR(P, X, Y) \
GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 3
#define INC_PIXEL_PTR(P) P += 3
#define STORE_PIXEL(DST, X, Y, VALUE) \
DST[0] = VALUE[BCOMP]; \
DST[1] = VALUE[GCOMP]; \
DST[2] = VALUE[RCOMP]
#define FETCH_PIXEL(DST, SRC) \
DST[RCOMP] = SRC[2]; \
DST[GCOMP] = SRC[1]; \
DST[BCOMP] = SRC[0]; \
DST[ACOMP] = CHAN_MAX
#include "swrast/s_spantemp.h"
/* 32-bit BGRA */
#define NAME(PREFIX) PREFIX##_B8G8R8A8
#define RB_TYPE GLubyte
#define SPAN_VARS \
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
#define INIT_PIXEL_PTR(P, X, Y) \
GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 4
#define INC_PIXEL_PTR(P) P += 4
#define STORE_PIXEL(DST, X, Y, VALUE) \
DST[0] = VALUE[BCOMP]; \
DST[1] = VALUE[GCOMP]; \
DST[2] = VALUE[RCOMP]; \
DST[3] = VALUE[ACOMP]
#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
DST[0] = VALUE[BCOMP]; \
DST[1] = VALUE[GCOMP]; \
DST[2] = VALUE[RCOMP];
#define FETCH_PIXEL(DST, SRC) \
DST[RCOMP] = SRC[2]; \
DST[GCOMP] = SRC[1]; \
DST[BCOMP] = SRC[0]; \
DST[ACOMP] = SRC[3]
#include "swrast/s_spantemp.h"
/* 16-bit BGR (XXX implement dithering someday) */
#define NAME(PREFIX) PREFIX##_B5G6R5
#define RB_TYPE GLubyte
#define SPAN_VARS \
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
#define INIT_PIXEL_PTR(P, X, Y) \
GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
#define INC_PIXEL_PTR(P) P += 1
#define STORE_PIXEL(DST, X, Y, VALUE) \
DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
#define FETCH_PIXEL(DST, SRC) \
DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >> 5) & 0x3) ); \
DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
DST[ACOMP] = CHAN_MAX
#include "swrast/s_spantemp.h"
/* 15-bit BGR (XXX implement dithering someday) */
#define NAME(PREFIX) PREFIX##_B5G5R5
#define RB_TYPE GLubyte
#define SPAN_VARS \
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
#define INIT_PIXEL_PTR(P, X, Y) \
GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
#define INC_PIXEL_PTR(P) P += 1
#define STORE_PIXEL(DST, X, Y, VALUE) \
DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
#define FETCH_PIXEL(DST, SRC) \
DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >> 5) & 0x7) ); \
DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
DST[ACOMP] = CHAN_MAX
#include "swrast/s_spantemp.h"
/**********************************************************************/
/* Public API functions */
/**********************************************************************/
const char *
glFBDevGetString( int str )
{
switch (str) {
case GLFBDEV_VENDOR:
return "Mesa Project";
case GLFBDEV_VERSION:
return "1.0.1";
default:
return NULL;
}
}
GLFBDevProc
glFBDevGetProcAddress( const char *procName )
{
struct name_address {
const char *name;
const GLFBDevProc func;
};
static const struct name_address functions[] = {
{ "glFBDevGetString", (GLFBDevProc) glFBDevGetString },
{ "glFBDevGetProcAddress", (GLFBDevProc) glFBDevGetProcAddress },
{ "glFBDevCreateVisual", (GLFBDevProc) glFBDevCreateVisual },
{ "glFBDevDestroyVisual", (GLFBDevProc) glFBDevDestroyVisual },
{ "glFBDevGetVisualAttrib", (GLFBDevProc) glFBDevGetVisualAttrib },
{ "glFBDevCreateBuffer", (GLFBDevProc) glFBDevCreateBuffer },
{ "glFBDevDestroyBuffer", (GLFBDevProc) glFBDevDestroyBuffer },
{ "glFBDevGetBufferAttrib", (GLFBDevProc) glFBDevGetBufferAttrib },
{ "glFBDevGetCurrentDrawBuffer", (GLFBDevProc) glFBDevGetCurrentDrawBuffer },
{ "glFBDevGetCurrentReadBuffer", (GLFBDevProc) glFBDevGetCurrentReadBuffer },
{ "glFBDevSwapBuffers", (GLFBDevProc) glFBDevSwapBuffers },
{ "glFBDevCreateContext", (GLFBDevProc) glFBDevCreateContext },
{ "glFBDevDestroyContext", (GLFBDevProc) glFBDevDestroyContext },
{ "glFBDevGetContextAttrib", (GLFBDevProc) glFBDevGetContextAttrib },
{ "glFBDevGetCurrentContext", (GLFBDevProc) glFBDevGetCurrentContext },
{ "glFBDevMakeCurrent", (GLFBDevProc) glFBDevMakeCurrent },
{ NULL, NULL }
};
const struct name_address *entry;
for (entry = functions; entry->name; entry++) {
if (strcmp(entry->name, procName) == 0) {
return entry->func;
}
}
return _glapi_get_proc_address(procName);
}
GLFBDevVisualPtr
glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
const struct fb_var_screeninfo *varInfo,
const int *attribs )
{
GLFBDevVisualPtr vis;
const int *attrib;
GLboolean dbFlag = GL_FALSE, stereoFlag = GL_FALSE;
GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0;
GLint depthBits = 0, stencilBits = 0;
GLint accumRedBits = 0, accumGreenBits = 0;
GLint accumBlueBits = 0, accumAlphaBits = 0;
GLint numSamples = 0;
ASSERT(fixInfo);
ASSERT(varInfo);
vis = CALLOC_STRUCT(GLFBDevVisualRec);
if (!vis)
return NULL;
vis->fix = *fixInfo; /* struct assignment */
vis->var = *varInfo; /* struct assignment */
for (attrib = attribs; attrib && *attrib != GLFBDEV_NONE; attrib++) {
switch (*attrib) {
case GLFBDEV_DOUBLE_BUFFER:
dbFlag = GL_TRUE;
break;
case GLFBDEV_DEPTH_SIZE:
depthBits = attrib[1];
attrib++;
break;
case GLFBDEV_STENCIL_SIZE:
stencilBits = attrib[1];
attrib++;
break;
case GLFBDEV_ACCUM_SIZE:
accumRedBits = accumGreenBits = accumBlueBits = accumAlphaBits
= attrib[1];
attrib++;
break;
case GLFBDEV_LEVEL:
/* ignored for now */
break;
case GLFBDEV_MULTISAMPLE:
numSamples = attrib[1];
attrib++;
break;
case GLFBDEV_COLOR_INDEX:
/* Mesa no longer supports color-index rendering. */
default:
/* unexpected token */
free(vis);
return NULL;
}
}
redBits = varInfo->red.length;
greenBits = varInfo->green.length;
blueBits = varInfo->blue.length;
alphaBits = varInfo->transp.length;
if (fixInfo->visual == FB_VISUAL_TRUECOLOR ||
fixInfo->visual == FB_VISUAL_DIRECTCOLOR) {
if (varInfo->bits_per_pixel == 24
&& varInfo->red.offset == 16
&& varInfo->green.offset == 8
&& varInfo->blue.offset == 0) {
vis->pixelFormat = PF_B8G8R8;
}
else if (varInfo->bits_per_pixel == 32
&& varInfo->red.offset == 16
&& varInfo->green.offset == 8
&& varInfo->blue.offset == 0) {
vis->pixelFormat = PF_B8G8R8A8;
}
else if (varInfo->bits_per_pixel == 16
&& varInfo->red.offset == 11
&& varInfo->green.offset == 5
&& varInfo->blue.offset == 0) {
vis->pixelFormat = PF_B5G6R5;
}
else if (varInfo->bits_per_pixel == 16
&& varInfo->red.offset == 10
&& varInfo->green.offset == 5
&& varInfo->blue.offset == 0) {
vis->pixelFormat = PF_B5G5R5;
}
else {
_mesa_problem(NULL, "Unsupported fbdev RGB visual/bitdepth!\n");
free(vis);
return NULL;
}
}
if (!_mesa_initialize_visual(&vis->glvisual, dbFlag, stereoFlag,
redBits, greenBits, blueBits, alphaBits,
depthBits, stencilBits,
accumRedBits, accumGreenBits,
accumBlueBits, accumAlphaBits,
numSamples)) {
/* something was invalid */
free(vis);
return NULL;
}
return vis;
}
void
glFBDevDestroyVisual( GLFBDevVisualPtr visual )
{
if (visual)
free(visual);
}
int
glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual, int attrib)
{
/* XXX unfinished */
(void) visual;
(void) attrib;
return -1;
}
static void
delete_renderbuffer(struct gl_renderbuffer *rb)
{
struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
if (frb->mallocedBuffer) {
free(frb->Base.Data);
}
free(frb);
}
static GLboolean
renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
GLenum internalFormat, GLuint width, GLuint height)
{
/* no-op: the renderbuffer storage is allocated just once when it's
* created. Never resized or reallocated.
*/
return GL_TRUE;
}
static struct GLFBDevRenderbufferRec *
new_glfbdev_renderbuffer(void *bufferStart, const GLFBDevVisualPtr visual)
{
struct GLFBDevRenderbufferRec *rb = CALLOC_STRUCT(GLFBDevRenderbufferRec);
if (rb) {
GLuint name = 0;
int pixelFormat = visual->pixelFormat;
_mesa_init_renderbuffer(&rb->Base, name);
rb->Base.Delete = delete_renderbuffer;
rb->Base.AllocStorage = renderbuffer_storage;
if (pixelFormat == PF_B8G8R8) {
rb->Base.GetRow = get_row_B8G8R8;
rb->Base.GetValues = get_values_B8G8R8;
rb->Base.PutRow = put_row_B8G8R8;
rb->Base.PutRowRGB = put_row_rgb_B8G8R8;
rb->Base.PutMonoRow = put_mono_row_B8G8R8;
rb->Base.PutValues = put_values_B8G8R8;
rb->Base.PutMonoValues = put_mono_values_B8G8R8;
}
else if (pixelFormat == PF_B8G8R8A8) {
rb->Base.GetRow = get_row_B8G8R8A8;
rb->Base.GetValues = get_values_B8G8R8A8;
rb->Base.PutRow = put_row_B8G8R8A8;
rb->Base.PutRowRGB = put_row_rgb_B8G8R8A8;
rb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
rb->Base.PutValues = put_values_B8G8R8A8;
rb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
}
else if (pixelFormat == PF_B5G6R5) {
rb->Base.GetRow = get_row_B5G6R5;
rb->Base.GetValues = get_values_B5G6R5;
rb->Base.PutRow = put_row_B5G6R5;
rb->Base.PutRowRGB = put_row_rgb_B5G6R5;
rb->Base.PutMonoRow = put_mono_row_B5G6R5;
rb->Base.PutValues = put_values_B5G6R5;
rb->Base.PutMonoValues = put_mono_values_B5G6R5;
}
else if (pixelFormat == PF_B5G5R5) {
rb->Base.GetRow = get_row_B5G5R5;
rb->Base.GetValues = get_values_B5G5R5;
rb->Base.PutRow = put_row_B5G5R5;
rb->Base.PutRowRGB = put_row_rgb_B5G5R5;
rb->Base.PutMonoRow = put_mono_row_B5G5R5;
rb->Base.PutValues = put_values_B5G5R5;
rb->Base.PutMonoValues = put_mono_values_B5G5R5;
}
rb->Base.InternalFormat = GL_RGBA;
rb->Base._BaseFormat = GL_RGBA;
rb->Base.DataType = GL_UNSIGNED_BYTE;
rb->Base.Data = bufferStart;
rb->rowStride = visual->var.xres_virtual * visual->var.bits_per_pixel / 8;
rb->bottom = (GLubyte *) bufferStart
+ (visual->var.yres - 1) * rb->rowStride;
rb->Base.Width = visual->var.xres;
rb->Base.Height = visual->var.yres;
/*
rb->Base.RedBits = visual->var.red.length;
rb->Base.GreenBits = visual->var.green.length;
rb->Base.BlueBits = visual->var.blue.length;
rb->Base.AlphaBits = visual->var.transp.length;
*/
rb->Base.InternalFormat = pixelFormat;
}
return rb;
}
GLFBDevBufferPtr
glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
const struct fb_var_screeninfo *varInfo,
const GLFBDevVisualPtr visual,
void *frontBuffer, void *backBuffer, size_t size )
{
struct GLFBDevRenderbufferRec *frontrb, *backrb;
GLFBDevBufferPtr buf;
ASSERT(visual);
ASSERT(frontBuffer);
ASSERT(size > 0);
/* this is to update the visual if there was a resize and the
buffer is created again */
visual->var = *varInfo;
visual->fix = *fixInfo;
if (visual->fix.visual != fixInfo->visual ||
visual->fix.type != fixInfo->type ||
visual->var.bits_per_pixel != varInfo->bits_per_pixel ||
visual->var.grayscale != varInfo->grayscale ||
visual->var.red.offset != varInfo->red.offset ||
visual->var.green.offset != varInfo->green.offset ||
visual->var.blue.offset != varInfo->blue.offset ||
visual->var.transp.offset != varInfo->transp.offset) {
/* visual mismatch! */
return NULL;
}
buf = CALLOC_STRUCT(GLFBDevBufferRec);
if (!buf)
return NULL;
/* basic framebuffer setup */
_mesa_initialize_window_framebuffer(&buf->glframebuffer, &visual->glvisual);
/* add front renderbuffer */
frontrb = new_glfbdev_renderbuffer(frontBuffer, visual);
_mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT,
&frontrb->Base);
/* add back renderbuffer */
if (visual->glvisual.doubleBufferMode) {
const int malloced = !backBuffer;
if (malloced) {
/* malloc a back buffer */
backBuffer = malloc(size);
if (!backBuffer) {
_mesa_free_framebuffer_data(&buf->glframebuffer);
free(buf);
return NULL;
}
}
backrb = new_glfbdev_renderbuffer(backBuffer, visual);
if (!backrb) {
/* out of mem */
return NULL;
}
backrb->mallocedBuffer = malloced;
_mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT,
&backrb->Base);
}
/* add software renderbuffers */
_mesa_add_soft_renderbuffers(&buf->glframebuffer,
GL_FALSE, /* color */
visual->glvisual.haveDepthBuffer,
visual->glvisual.haveStencilBuffer,
visual->glvisual.haveAccumBuffer,
GL_FALSE, /* alpha */
GL_FALSE /* aux bufs */);
buf->fix = *fixInfo; /* struct assignment */
buf->var = *varInfo; /* struct assignment */
buf->visual = visual; /* ptr assignment */
buf->size = size;
buf->bytesPerPixel = visual->var.bits_per_pixel / 8;
return buf;
}
void
glFBDevDestroyBuffer( GLFBDevBufferPtr buffer )
{
if (buffer) {
/* check if destroying the current buffer */
GLFBDevBufferPtr curDraw = glFBDevGetCurrentDrawBuffer();
GLFBDevBufferPtr curRead = glFBDevGetCurrentReadBuffer();
if (buffer == curDraw || buffer == curRead) {
glFBDevMakeCurrent( NULL, NULL, NULL);
}
{
struct gl_framebuffer *fb = &buffer->glframebuffer;
_mesa_reference_framebuffer(&fb, NULL);
}
}
}
int
glFBDevGetBufferAttrib( const GLFBDevBufferPtr buffer, int attrib)
{
(void) buffer;
(void) attrib;
return -1;
}
GLFBDevBufferPtr
glFBDevGetCurrentDrawBuffer( void )
{
GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
if (fbdevctx)
return fbdevctx->drawBuffer;
else
return NULL;
}
GLFBDevBufferPtr
glFBDevGetCurrentReadBuffer( void )
{
GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
if (fbdevctx)
return fbdevctx->readBuffer;
else
return NULL;
}
void
glFBDevSwapBuffers( GLFBDevBufferPtr buffer )
{
GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
struct GLFBDevRenderbufferRec *frontrb = (struct GLFBDevRenderbufferRec *)
buffer->glframebuffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
struct GLFBDevRenderbufferRec *backrb = (struct GLFBDevRenderbufferRec *)
buffer->glframebuffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
if (!buffer || !buffer->visual->glvisual.doubleBufferMode)
return;
/* check if swapping currently bound buffer */
if (fbdevctx->drawBuffer == buffer) {
/* flush pending rendering */
_mesa_notifySwapBuffers(&fbdevctx->glcontext);
}
ASSERT(frontrb->Base.Data);
ASSERT(backrb->Base.Data);
memcpy(frontrb->Base.Data, backrb->Base.Data, buffer->size);
}
GLFBDevContextPtr
glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share )
{
GLFBDevContextPtr ctx;
struct gl_context *glctx;
struct dd_function_table functions;
ASSERT(visual);
ctx = CALLOC_STRUCT(GLFBDevContextRec);
if (!ctx)
return NULL;
/* build table of device driver functions */
_mesa_init_driver_functions(&functions);
functions.GetString = get_string;
functions.UpdateState = update_state;
functions.GetBufferSize = get_buffer_size;
functions.Viewport = viewport;
if (!_mesa_initialize_context(&ctx->glcontext, API_OPENGL, &visual->glvisual,
share ? &share->glcontext : NULL,
&functions, (void *) ctx)) {
free(ctx);
return NULL;
}
ctx->visual = visual;
/* Create module contexts */
glctx = (struct gl_context *) &ctx->glcontext;
_swrast_CreateContext( glctx );
_vbo_CreateContext( glctx );
_tnl_CreateContext( glctx );
_swsetup_CreateContext( glctx );
_swsetup_Wakeup( glctx );
/* use default TCL pipeline */
{
TNLcontext *tnl = TNL_CONTEXT(glctx);
tnl->Driver.RunPipeline = _tnl_run_pipeline;
}
_mesa_enable_sw_extensions(glctx);
_mesa_enable_1_3_extensions(glctx);
_mesa_enable_1_4_extensions(glctx);
_mesa_enable_1_5_extensions(glctx);
_mesa_enable_2_0_extensions(glctx);
_mesa_enable_2_1_extensions(glctx);
return ctx;
}
void
glFBDevDestroyContext( GLFBDevContextPtr context )
{
GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
if (context) {
struct gl_context *mesaCtx = &context->glcontext;
_swsetup_DestroyContext( mesaCtx );
_swrast_DestroyContext( mesaCtx );
_tnl_DestroyContext( mesaCtx );
_vbo_DestroyContext( mesaCtx );
if (fbdevctx == context) {
/* destroying current context */
_mesa_make_current(NULL, NULL, NULL);
}
_mesa_free_context_data(&context->glcontext);
free(context);
}
}
int
glFBDevGetContextAttrib( const GLFBDevContextPtr context, int attrib)
{
(void) context;
(void) attrib;
return -1;
}
GLFBDevContextPtr
glFBDevGetCurrentContext( void )
{
GET_CURRENT_CONTEXT(ctx);
return (GLFBDevContextPtr) ctx;
}
int
glFBDevMakeCurrent( GLFBDevContextPtr context,
GLFBDevBufferPtr drawBuffer,
GLFBDevBufferPtr readBuffer )
{
if (context && drawBuffer && readBuffer) {
/* Make sure the context's visual and the buffers' visuals match.
* XXX we might do this by comparing specific fields like bits_per_pixel,
* visual, etc. in the future.
*/
if (context->visual != drawBuffer->visual ||
context->visual != readBuffer->visual) {
return 0;
}
_mesa_make_current( &context->glcontext,
&drawBuffer->glframebuffer,
&readBuffer->glframebuffer );
context->drawBuffer = drawBuffer;
context->readBuffer = readBuffer;
context->curBuffer = drawBuffer;
}
else {
/* unbind */
_mesa_make_current( NULL, NULL, NULL );
}
return 1;
}
#endif /* USE_GLFBDEV_DRIVER */