add SPARC ffb DRI driver

This commit is contained in:
Alan Hourihane 2003-12-04 13:38:06 +00:00
parent 15af25aca0
commit 13e6a4849c
38 changed files with 6958 additions and 0 deletions

View File

@ -0,0 +1,130 @@
# Mesa 3-D graphics library
# Version: 5.0
# Copyright (C) 1995-2002 Brian Paul
TOP = ../../../../..
default: linux-solo
SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver
MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini
DEFINES += \
-D_HAVE_SWRAST=1 \
-D_HAVE_SWTNL=1 \
-D_HAVE_SANITY=1 \
-D_HAVE_CODEGEN=1 \
-D_HAVE_LIGHTING=1 \
-D_HAVE_TEXGEN=1 \
-D_HAVE_USERCLIP=1 \
-DGLX_DIRECT_RENDERING
# not yet
# MINIGLX_SOURCES = server/ffb_dri.c
DRIVER_SOURCES = ffb_bitmap.c \
../common/mm.c \
../common/utils.c \
../common/texmem.c \
../common/vblank.c \
../common/xmlconfig.c \
ffb_clear.c \
ffb_dd.c \
ffb_depth.c \
ffb_fog.c \
ffb_lines.c \
ffb_points.c \
ffb_span.c \
ffb_state.c \
ffb_stencil.c \
ffb_tex.c \
ffb_tris.c \
ffb_vb.c \
ffb_vtxfmt.c \
ffb_xmesa.c
INCLUDES = $(MINIGLX_INCLUDES) \
$(SHARED_INCLUDES)
C_SOURCES = $(DRIVER_SOURCES) \
$(MINIGLX_SOURCES)
MESA_MODULES = $(TOP)/src/mesa/mesa.a
ifeq ($(WINDOW_SYSTEM),dri)
WINOBJ=$(MESABUILDDIR)/dri/dri.a
WINLIB=
else
WINOBJ=
WINLIB=-L$(MESA)/src/glx/mini
endif
ASM_SOURCES =
OBJECTS = $(C_SOURCES:.c=.o) \
$(ASM_SOURCES:.S=.o)
$(SYMLINKS):
mkdir -p server
cd server
rm -f $@ && ln -s ../../radeon/$@ $@
### 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: depend ffb_dri.so
ffb_dri.so: $(SYMLINKS) $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc $(GL_LIB_DEPS)
rm -f $(TOP)/lib/ffb_dri.so && \
install ffb_dri.so $(TOP)/lib/ffb_dri.so
$(TOP)/lib/ffb_dri.so: ffb_dri.so
rm -f $(TOP)/lib/ffb_dri.so && \
install ffb_dri.so $(TOP)/lib/ffb_dri.so
# Run 'make -f Makefile.X11 dep' to update the dependencies if you change
# what's included by any source file.
depend: $(C_SOURCES) $(ASM_SOURCES)
makedepend -fdepend -Y $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) \
$(C_SOURCES) $(ASM_SOURCES)
# Emacs tags
tags:
etags `find . -name \*.[ch]` `find ../include`
# Remove .o and backup files
clean:
-rm -f *.o */*.o *~ *.o *~ *.so server/*.o
-rm -f $(SYMLINKS)
include $(TOP)/Make-config
include depend

View File

@ -0,0 +1,156 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_bitmap.c,v 1.1 2002/02/22 21:32:58 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "ffb_context.h"
#include "ffb_state.h"
#include "ffb_lock.h"
#include "ffb_bitmap.h"
#include "swrast/swrast.h"
#include "image.h"
#include "macros.h"
#undef FFB_BITMAP_TRACE
static void
ffb_bitmap(GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_fbcPtr ffb = fmesa->regs;
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
unsigned int ppc, pixel;
GLint row, col, row_stride;
const GLubyte *src;
char *buf;
if (fmesa->bad_fragment_attrs != 0)
_swrast_Bitmap(ctx, px, py, width,
height, unpack, bitmap);
pixel = (((((GLuint)(ctx->Current.RasterColor[0] * 255.0f)) & 0xff) << 0) |
((((GLuint)(ctx->Current.RasterColor[1] * 255.0f)) & 0xff) << 8) |
((((GLuint)(ctx->Current.RasterColor[2] * 255.0f)) & 0xff) << 16) |
((((GLuint)(ctx->Current.RasterColor[3] * 255.0f)) & 0xff) << 24));
#ifdef FFB_BITMAP_TRACE
fprintf(stderr, "ffb_bitmap: ppc(%08x) fbc(%08x) cmp(%08x) pixel(%08x)\n",
fmesa->ppc, fmesa->fbc, fmesa->cmp, pixel);
#endif
LOCK_HARDWARE(fmesa);
fmesa->hw_locked = 1;
if (fmesa->state_dirty)
ffbSyncHardware(fmesa);
ppc = fmesa->ppc;
FFBFifo(fmesa, 4);
ffb->ppc = ((ppc &
~(FFB_PPC_TBE_MASK | FFB_PPC_ZS_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK))
| (FFB_PPC_TBE_TRANSPARENT | FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST |
(ctx->Color.BlendEnabled ? FFB_PPC_XS_CONST : FFB_PPC_XS_WID)));
ffb->constz = ((GLuint) (ctx->Current.RasterPos[2] * 0x0fffffff));
ffb->fg = pixel;
ffb->fontinc = (0 << 16) | 32;
buf = (char *)(fmesa->sfb32 + (dPriv->x << 2) + (dPriv->y << 13));
row_stride = (unpack->Alignment * CEILING(width, 8 * unpack->Alignment));
src = (const GLubyte *) (bitmap +
(unpack->SkipRows * row_stride) +
(unpack->SkipPixels / 8));
if (unpack->LsbFirst == GL_TRUE) {
for (row = 0; row < height; row++, src += row_stride) {
const GLubyte *row_src = src;
GLuint base_x, base_y;
base_x = dPriv->x + px;
base_y = dPriv->y + (dPriv->h - (py + row));
FFBFifo(fmesa, 1);
ffb->fontxy = (base_y << 16) | base_x;
for (col = 0; col < width; col += 32, row_src += 4) {
GLint bitnum, font_w = (width - col);
GLuint font_data;
if (font_w > 32)
font_w = 32;
font_data = 0;
for (bitnum = 0; bitnum < 32; bitnum++) {
const GLubyte val = row_src[bitnum >> 3];
if (val & (1 << (bitnum & (8 - 1))))
font_data |= (1 << (31 - bitnum));
}
FFBFifo(fmesa, 2);
ffb->fontw = font_w;
ffb->font = font_data;
}
}
} else {
for (row = 0; row < height; row++, src += row_stride) {
const GLubyte *row_src = src;
GLuint base_x, base_y;
base_x = dPriv->x + px;
base_y = dPriv->y + (dPriv->h - (py + row));
FFBFifo(fmesa, 1);
ffb->fontxy = (base_y << 16) | base_x;
for (col = 0; col < width; col += 32, row_src += 4) {
GLint font_w = (width - col);
if (font_w > 32)
font_w = 32;
FFBFifo(fmesa, 2);
ffb->fontw = font_w;
ffb->font = (((unsigned int)row_src[0]) << 24 |
((unsigned int)row_src[1]) << 16 |
((unsigned int)row_src[2]) << 8 |
((unsigned int)row_src[3]) << 0);
}
}
}
FFBFifo(fmesa, 1);
ffb->ppc = ppc;
fmesa->ffbScreen->rp_active = 1;
UNLOCK_HARDWARE(fmesa);
fmesa->hw_locked = 0;
}
void ffbDDInitBitmapFuncs(GLcontext *ctx)
{
ctx->Driver.Bitmap = ffb_bitmap;
}

View File

@ -0,0 +1,8 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_bitmap.h,v 1.1 2002/02/22 21:32:58 dawes Exp $ */
#ifndef _FFB_BITMAP_H
#define _FFB_BITMAP_H
extern void ffbDDInitBitmapFuncs(GLcontext *);
#endif /* !(_FFB_BITMAP_H) */

View File

@ -0,0 +1,354 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_clear.c,v 1.2 2002/02/22 21:32:58 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "mtypes.h"
#include "extensions.h"
#include "mm.h"
#include "ffb_dd.h"
#include "ffb_span.h"
#include "ffb_depth.h"
#include "ffb_context.h"
#include "ffb_vb.h"
#include "ffb_tris.h"
#include "ffb_clear.h"
#include "ffb_lock.h"
#undef CLEAR_TRACE
#define BOX_AREA(__w, __h) ((int)(__w) * (int)(__h))
/* Compute the page aligned box for a page mode fast fill.
* In 'ework' this returns greater than zero if there are some odd
* edges to take care of which are outside of the page aligned area.
* It will place less than zero there if the box is too small,
* indicating that a different method must be used to fill it.
*/
#define CreatorPageFillParms(ffp, x, y, w, h, px, py, pw, ph, ework) \
do { int xdiff, ydiff; \
int pf_bh = ffp->pagefill_height; \
int pf_bw = ffp->pagefill_width; \
py = ((y + (pf_bh - 1)) & ~(pf_bh - 1)); \
ydiff = py - y; \
px = ffp->Pf_AlignTab[x + (pf_bw - 1)]; \
xdiff = px - x; \
ph = ((h - ydiff) & ~(pf_bh - 1)); \
if(ph <= 0) \
ework = -1; \
else { \
pw = ffp->Pf_AlignTab[w - xdiff]; \
if(pw <= 0) { \
ework = -1; \
} else { \
ework = (((xdiff > 0) || \
(ydiff > 0) || \
((w - pw) > 0) || \
((h - ph) > 0))) ? 1 : 0; \
} \
} \
} while(0);
struct ff_fixups {
int x, y, width, height;
};
/* Compute fixups of non-page aligned areas after a page fill.
* Return the number of fixups needed.
*/
static __inline__ int
CreatorComputePageFillFixups(struct ff_fixups *fixups,
int x, int y, int w, int h,
int paligned_x, int paligned_y,
int paligned_w, int paligned_h)
{
int nfixups = 0;
/* FastFill Left */
if(paligned_x != x) {
fixups[nfixups].x = x;
fixups[nfixups].y = paligned_y;
fixups[nfixups].width = paligned_x - x;
fixups[nfixups].height = paligned_h;
nfixups++;
}
/* FastFill Top */
if(paligned_y != y) {
fixups[nfixups].x = x;
fixups[nfixups].y = y;
fixups[nfixups].width = w;
fixups[nfixups].height = paligned_y - y;
nfixups++;
}
/* FastFill Right */
if((x+w) != (paligned_x+paligned_w)) {
fixups[nfixups].x = (paligned_x+paligned_w);
fixups[nfixups].y = paligned_y;
fixups[nfixups].width = (x+w) - fixups[nfixups].x;
fixups[nfixups].height = paligned_h;
nfixups++;
}
/* FastFill Bottom */
if((y+h) != (paligned_y+paligned_h)) {
fixups[nfixups].x = x;
fixups[nfixups].y = (paligned_y+paligned_h);
fixups[nfixups].width = w;
fixups[nfixups].height = (y+h) - fixups[nfixups].y;
nfixups++;
}
return nfixups;
}
static void
ffb_do_clear(ffbContextPtr fmesa, __DRIdrawablePrivate *dPriv,
GLboolean all, GLint cx, GLint cy, GLint cwidth,
GLint cheight)
{
FFBDRIPtr gDRIPriv = (FFBDRIPtr) fmesa->driScreen->pDevPriv;
ffb_fbcPtr ffb = fmesa->regs;
XF86DRIClipRectPtr box = dPriv->pClipRects;
int nc = dPriv->numClipRects;
cy = dPriv->h - cy - cheight;
cx += dPriv->x;
cy += dPriv->y;
while (nc--) {
GLint x = box[nc].x1;
GLint y = box[nc].y1;
GLint width = box[nc].x2 - x;
GLint height = box[nc].y2 - y;
int paligned_y, paligned_x;
int paligned_h, paligned_w = 0;
int extra_work;
if (!all) {
if (x < cx) {
width -= cx - x;
x = cx;
}
if (y < cy) {
height -= cy - y;
y = cy;
}
if (x + width > cx + cwidth)
width = cx + cwidth - x;
if (y + height > cy + cheight)
height = cy + cheight - y;
if (width <= 0)
continue;
if (height <= 0)
continue;
}
if (BOX_AREA(width, height) < gDRIPriv->fastfill_small_area) {
FFBFifo(fmesa, 5);
ffb->drawop = FFB_DRAWOP_RECTANGLE;
ffb->by = y;
ffb->bx = x;
ffb->bh = height;
ffb->bw = width;
continue;
}
FFBFifo(fmesa, 1);
ffb->drawop = FFB_DRAWOP_FASTFILL;
if (gDRIPriv->disable_pagefill ||
(width < (gDRIPriv->pagefill_width<<1)) ||
(height < (gDRIPriv->pagefill_height<<1)))
goto do_fastfill;
CreatorPageFillParms(gDRIPriv,
x, y, width, height,
paligned_x, paligned_y,
paligned_w, paligned_h, extra_work);
if (extra_work < 0 ||
BOX_AREA(paligned_w, paligned_h) < gDRIPriv->pagefill_small_area) {
do_fastfill:
FFBFifo(fmesa, 10);
ffb->by = FFB_FASTFILL_COLOR_BLK;
ffb->dy = 0;
ffb->dx = 0;
ffb->bh = gDRIPriv->fastfill_height;
ffb->bw = (gDRIPriv->fastfill_width * 4);
ffb->by = FFB_FASTFILL_BLOCK;
ffb->dy = y;
ffb->dx = x;
ffb->bh = (height + (y & (gDRIPriv->fastfill_height - 1)));
ffb->bx = (width + (x & (gDRIPriv->fastfill_width - 1)));
continue;
}
/* Ok, page fill is possible and worth it. */
FFBFifo(fmesa, 15);
ffb->by = FFB_FASTFILL_COLOR_BLK;
ffb->dy = 0;
ffb->dx = 0;
ffb->bh = gDRIPriv->fastfill_height;
ffb->bw = gDRIPriv->fastfill_width * 4;
ffb->by = FFB_FASTFILL_BLOCK_X;
ffb->dy = 0;
ffb->dx = 0;
ffb->bh = gDRIPriv->pagefill_height;
ffb->bw = gDRIPriv->pagefill_width * 4;
ffb->by = FFB_FASTFILL_PAGE;
ffb->dy = paligned_y;
ffb->dx = paligned_x;
ffb->bh = paligned_h;
ffb->bx = paligned_w;
if (extra_work) {
struct ff_fixups local_fixups[4];
int nfixups;
nfixups = CreatorComputePageFillFixups(local_fixups,
x, y, width, height,
paligned_x, paligned_y,
paligned_w, paligned_h);
FFBFifo(fmesa, 5 + (nfixups * 5));
ffb->by = FFB_FASTFILL_COLOR_BLK;
ffb->dy = 0;
ffb->dx = 0;
ffb->bh = gDRIPriv->fastfill_height;
ffb->bw = gDRIPriv->fastfill_width * 4;
while (--nfixups >= 0) {
int xx, yy, ww, hh;
xx = local_fixups[nfixups].x;
yy = local_fixups[nfixups].y;
ffb->dy = yy;
ffb->dx = xx;
ww = (local_fixups[nfixups].width +
(xx & (gDRIPriv->fastfill_width - 1)));
hh = (local_fixups[nfixups].height +
(yy & (gDRIPriv->fastfill_height - 1)));
if (nfixups != 0) {
ffb->by = FFB_FASTFILL_BLOCK;
ffb->bh = hh;
ffb->bw = ww;
} else {
ffb->bh = hh;
ffb->by = FFB_FASTFILL_BLOCK;
ffb->bx = ww;
}
}
}
}
}
void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cwidth, GLint cheight)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
unsigned int stcmask = DD_STENCIL_BIT;
#ifdef CLEAR_TRACE
fprintf(stderr, "ffbDDClear: mask(%08x) all(%d) "
"[x(%x)y(%x)w(%x)h(%x)]\n",
mask, (int) all, cx, cy, cwidth, cheight);
#endif
if (!(fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS))
stcmask = 0;
if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT | stcmask)) {
ffb_fbcPtr ffb = fmesa->regs;
unsigned int fbc, ppc;
fbc = (FFB_FBC_XE_ON);
ppc = (FFB_PPC_ACE_DISABLE | FFB_PPC_DCE_DISABLE |
FFB_PPC_ABE_DISABLE | FFB_PPC_VCE_DISABLE |
FFB_PPC_APE_DISABLE | FFB_PPC_XS_WID |
FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST);
/* Y/X enables must be both on or both off. */
if (mask & (DD_DEPTH_BIT | stcmask)) {
fbc |= (FFB_FBC_ZE_ON | FFB_FBC_YE_ON | FFB_FBC_WB_C);
} else
fbc |= FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF;
/* All RGB enables must be both on or both off. */
if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
if (mask & DD_FRONT_LEFT_BIT) {
if (fmesa->back_buffer == 0)
fbc |= FFB_FBC_WB_B;
else
fbc |= FFB_FBC_WB_A;
}
if (mask & DD_BACK_LEFT_BIT) {
if (fmesa->back_buffer == 0)
fbc |= FFB_FBC_WB_A;
else
fbc |= FFB_FBC_WB_B;
}
fbc |= FFB_FBC_RGBE_ON;
} else
fbc |= FFB_FBC_RGBE_OFF;
LOCK_HARDWARE(fmesa);
if (dPriv->numClipRects) {
FFBFifo(fmesa, 8);
ffb->fbc = fbc;
ffb->ppc = ppc;
ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
ffb->cmp = 0x80808080;
ffb->rop = FFB_ROP_NEW;
if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT))
ffb->fg = fmesa->clear_pixel;
if (mask & DD_DEPTH_BIT)
ffb->constz = fmesa->clear_depth;
if (mask & stcmask)
ffb->consty = fmesa->clear_stencil;
ffb_do_clear(fmesa, dPriv, all, cx, cy, cwidth, cheight);
FFBFifo(fmesa, 6);
ffb->ppc = fmesa->ppc;
ffb->fbc = fmesa->fbc;
ffb->xclip = fmesa->xclip;
ffb->cmp = fmesa->cmp;
ffb->rop = fmesa->rop;
ffb->drawop = fmesa->drawop;
if (mask & stcmask)
ffb->consty = fmesa->consty;
fmesa->ffbScreen->rp_active = 1;
}
UNLOCK_HARDWARE(fmesa);
mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT |
DD_DEPTH_BIT | stcmask);
}
if (mask)
_swrast_Clear(ctx, mask, all, cx, cy, cwidth, cheight);
}

View File

@ -0,0 +1,9 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_clear.h,v 1.2 2002/02/22 21:32:58 dawes Exp $ */
#ifndef _FFB_CLEAR_H
#define _FFB_CLEAR_H
extern void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cwidth, GLint cheight);
#endif /* !(_FFB_CLEAR_H) */

View File

@ -0,0 +1,309 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_context.h,v 1.2 2002/02/22 21:32:58 dawes Exp $ */
#ifndef _FFB_CONTEXT_H
#define _FFB_CONTEXT_H
#include "dri_util.h"
#include "mtypes.h"
#include "ffb_xmesa.h"
typedef struct {
GLfloat alpha;
GLfloat red;
GLfloat green;
GLfloat blue;
} ffb_color;
#define FFB_GET_ALPHA(VTX) \
FFB_COLOR_FROM_FLOAT((VTX)->color[0].alpha)
#define FFB_GET_RED(VTX) \
FFB_COLOR_FROM_FLOAT((VTX)->color[0].red)
#define FFB_GET_GREEN(VTX) \
FFB_COLOR_FROM_FLOAT((VTX)->color[0].green)
#define FFB_GET_BLUE(VTX) \
FFB_COLOR_FROM_FLOAT((VTX)->color[0].blue)
typedef struct {
GLfloat x, y, z;
ffb_color color[2];
} ffb_vertex;
#define FFB_DELAYED_VIEWPORT_VARS \
GLfloat VP_SX = fmesa->hw_viewport[MAT_SX]; \
GLfloat VP_TX = fmesa->hw_viewport[MAT_TX]; \
GLfloat VP_SY = fmesa->hw_viewport[MAT_SY]; \
GLfloat VP_TY = fmesa->hw_viewport[MAT_TY]; \
GLfloat VP_SZ = fmesa->hw_viewport[MAT_SZ]; \
GLfloat VP_TZ = fmesa->hw_viewport[MAT_TZ]; \
(void) VP_SX; (void) VP_SY; (void) VP_SZ; \
(void) VP_TX; (void) VP_TY; (void) VP_TZ
#define FFB_GET_Z(VTX) \
FFB_Z_FROM_FLOAT(VP_SZ * (VTX)->z + VP_TZ)
#define FFB_GET_Y(VTX) \
FFB_XY_FROM_FLOAT(VP_SY * (VTX)->y + VP_TY)
#define FFB_GET_X(VTX) \
FFB_XY_FROM_FLOAT(VP_SX * (VTX)->x + VP_TX)
typedef void (*ffb_point_func)(GLcontext *, ffb_vertex *);
typedef void (*ffb_line_func)(GLcontext *, ffb_vertex *, ffb_vertex *);
typedef void (*ffb_tri_func)(GLcontext *, ffb_vertex *, ffb_vertex *,
ffb_vertex *);
typedef void (*ffb_quad_func)(GLcontext *, ffb_vertex *, ffb_vertex *,
ffb_vertex *, ffb_vertex *);
/* Immediate mode fast-path support. */
typedef struct {
GLfloat obj[4];
GLfloat normal[4];
GLfloat clip[4];
GLuint mask;
GLfloat color[4];
GLfloat win[4];
GLfloat eye[4];
} ffbTnlVertex, *ffbTnlVertexPtr;
typedef void (*ffb_interp_func)(GLfloat t,
ffbTnlVertex *O,
const ffbTnlVertex *I,
const ffbTnlVertex *J);
struct ffb_current_state {
GLfloat color[4];
GLfloat normal[4];
GLfloat specular[4];
};
struct ffb_light_state {
GLfloat base_color[3];
GLfloat base_alpha;
};
struct ffb_vertex_state {
struct ffb_current_state current;
struct ffb_light_state light;
};
struct ffb_imm_vertex {
ffbTnlVertex vertices[8];
ffbTnlVertex *v0;
ffbTnlVertex *v1;
ffbTnlVertex *v2;
ffbTnlVertex *v3;
void (*save_vertex)(GLcontext *ctx, ffbTnlVertex *v);
void (*flush_vertex)(GLcontext *ctx, ffbTnlVertex *v);
ffb_interp_func interp;
GLuint prim, format;
GLvertexformat vtxfmt;
};
typedef struct ffb_context_t {
GLcontext *glCtx;
GLframebuffer *glBuffer;
/* Temporaries for translating to float colors. */
struct gl_client_array FloatColor;
struct gl_client_array FloatSecondaryColor;
ffb_fbcPtr regs;
volatile char *sfb32;
int hw_locked;
int back_buffer; /* 0 = bufferA, 1 = bufferB */
/* Viewport matrix. */
GLfloat hw_viewport[16];
#define SUBPIXEL_X (-0.5F)
#define SUBPIXEL_Y (-0.5F + 0.125)
/* Vertices in driver format. */
ffb_vertex *verts;
/* Rasterization functions. */
ffb_point_func draw_point;
ffb_line_func draw_line;
ffb_tri_func draw_tri;
ffb_quad_func draw_quad;
GLenum raster_primitive;
GLenum render_primitive;
GLfloat backface_sign;
GLfloat depth_scale;
GLfloat ffb_2_30_fixed_scale;
GLfloat ffb_one_over_2_30_fixed_scale;
GLfloat ffb_16_16_fixed_scale;
GLfloat ffb_one_over_16_16_fixed_scale;
GLfloat ffb_ubyte_color_scale;
GLfloat ffb_zero;
/* Immediate mode state. */
struct ffb_vertex_state vtx_state;
struct ffb_imm_vertex imm;
/* Debugging knobs. */
GLboolean debugFallbacks;
/* This records state bits when a per-fragment attribute has
* been set which prevents us from rendering in hardware.
*
* As attributes change, some of these bits may clear as
* we move back within the chips capabilities. If they
* all clear, we return to full hw rendering.
*/
unsigned int bad_fragment_attrs;
#define FFB_BADATTR_FOG 0x00000001 /* Bad fog possible only when < FFB2 */
#define FFB_BADATTR_BLENDFUNC 0x00000002 /* Any non-const func based upon dst alpha */
#define FFB_BADATTR_BLENDROP 0x00000004 /* Blend enabled and LogicOP != GL_COPY */
#define FFB_BADATTR_BLENDEQN 0x00000008 /* Blend equation other than ADD */
#define FFB_BADATTR_STENCIL 0x00000010 /* Stencil enabled when < FFB2+ */
#define FFB_BADATTR_TEXTURE 0x00000020 /* Texture enabled */
#define FFB_BADATTR_SWONLY 0x00000040 /* Environment var set */
unsigned int state_dirty;
unsigned int state_fifo_ents;
#define FFB_STATE_FBC 0x00000001
#define FFB_STATE_PPC 0x00000002
#define FFB_STATE_DRAWOP 0x00000004
#define FFB_STATE_ROP 0x00000008
#define FFB_STATE_LPAT 0x00000010
#define FFB_STATE_PMASK 0x00000020
#define FFB_STATE_XPMASK 0x00000040
#define FFB_STATE_YPMASK 0x00000080
#define FFB_STATE_ZPMASK 0x00000100
#define FFB_STATE_XCLIP 0x00000200
#define FFB_STATE_CMP 0x00000400
#define FFB_STATE_MATCHAB 0x00000800
#define FFB_STATE_MAGNAB 0x00001000
#define FFB_STATE_MATCHC 0x00002000
#define FFB_STATE_MAGNC 0x00004000
#define FFB_STATE_DCUE 0x00008000
#define FFB_STATE_BLEND 0x00010000
#define FFB_STATE_CLIP 0x00020000
#define FFB_STATE_STENCIL 0x00040000
#define FFB_STATE_APAT 0x00080000
#define FFB_STATE_WID 0x00100000
#define FFB_STATE_ALL 0x001fffff
unsigned int state_all_fifo_ents;
#define FFB_MAKE_DIRTY(FMESA, STATE_MASK, FIFO_ENTS) \
do { if ((STATE_MASK) & ~((FMESA)->state_dirty)) { \
(FMESA)->state_dirty |= (STATE_MASK); \
(FMESA)->state_fifo_ents += FIFO_ENTS; \
} \
} while (0)
/* General hw reg state. */
unsigned int fbc;
unsigned int ppc;
unsigned int drawop;
unsigned int rop;
unsigned int lpat;
#define FFB_LPAT_BAD 0xffffffff
unsigned int wid;
unsigned int pmask;
unsigned int xpmask;
unsigned int ypmask;
unsigned int zpmask;
unsigned int xclip;
unsigned int cmp;
unsigned int matchab;
unsigned int magnab;
unsigned int matchc;
unsigned int magnc;
/* Depth cue unit hw reg state. */
unsigned int dcss; /* All FFB */
unsigned int dcsf; /* All FFB */
unsigned int dcsb; /* All FFB */
unsigned int dczf; /* All FFB */
unsigned int dczb; /* All FFB */
unsigned int dcss1; /* >=FFB2 only */
unsigned int dcss2; /* >=FFB2 only */
unsigned int dcss3; /* >=FFB2 only */
unsigned int dcs2; /* >=FFB2 only */
unsigned int dcs3; /* >=FFB2 only */
unsigned int dcs4; /* >=FFB2 only */
unsigned int dcd2; /* >=FFB2 only */
unsigned int dcd3; /* >=FFB2 only */
unsigned int dcd4; /* >=FFB2 only */
/* Blend unit hw reg state. */
unsigned int blendc;
unsigned int blendc1;
unsigned int blendc2;
/* ViewPort clipping hw reg state. */
unsigned int vclipmin;
unsigned int vclipmax;
unsigned int vclipzmin;
unsigned int vclipzmax;
struct {
unsigned int min;
unsigned int max;
} aux_clips[4];
/* Stencil control hw reg state. >=FFB2+ only. */
unsigned int stencil;
unsigned int stencilctl;
unsigned int consty; /* Stencil Ref */
/* Area pattern (used for polygon stipples). */
unsigned int pattern[32];
/* Fog state. */
float Znear, Zfar;
drmContext hHWContext;
drmLock *driHwLock;
int driFd;
unsigned int clear_pixel;
unsigned int clear_depth;
unsigned int clear_stencil;
unsigned int setupindex;
unsigned int setupnewinputs;
unsigned int new_gl_state;
__DRIdrawablePrivate *driDrawable;
__DRIscreenPrivate *driScreen;
ffbScreenPrivate *ffbScreen;
ffb_dri_state_t *ffb_sarea;
} ffbContextRec, *ffbContextPtr;
#define FFB_CONTEXT(ctx) ((ffbContextPtr)((ctx)->DriverCtx))
/* We want the depth values written during software rendering
* to match what the hardware is going to put there when we
* hw render.
*
* The Z buffer is 28 bits deep. Smooth shaded primitives
* specify a 2:30 signed fixed point Z value in the range 0.0
* to 1.0 inclusive.
*
* So for example, when hw rendering, the largest Z value of
* 1.0 would produce a value of 0x0fffffff in the actual Z
* buffer, which is the maximum value.
*
* Mesa's depth type is a 32-bit int, so we use the following macro
* to convert to/from FFB hw Z values. Note we also have to clear
* out the top bits as that is where the Y (stencil) buffer is stored
* and during hw Z buffer reads it is always there. (During writes
* we tell the hw to discard those top 4 bits).
*/
#define Z_TO_MESA(VAL) ((GLdepth)(((VAL) & 0x0fffffff) << (32 - 28)))
#define Z_FROM_MESA(VAL) (((GLuint)((GLdouble)(VAL))) >> (32 - 28))
#endif /* !(_FFB_CONTEXT_H) */

View File

@ -0,0 +1,116 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_dd.c,v 1.4 2002/09/11 19:49:07 tsi Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000, 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "mtypes.h"
#include "mm.h"
#include "ffb_dd.h"
#include "ffb_span.h"
#include "ffb_depth.h"
#include "ffb_context.h"
#include "ffb_vb.h"
#include "ffb_tris.h"
#include "ffb_clear.h"
#include "ffb_lock.h"
#include "extensions.h"
#define FFB_DATE "20021125"
/* Mesa's Driver Functions */
static const GLubyte *ffbDDGetString(GLcontext *ctx, GLenum name)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
static char buffer[128];
switch (name) {
case GL_VENDOR:
return (GLubyte *) "David S. Miller";
case GL_RENDERER:
sprintf(buffer, "Mesa DRI FFB " FFB_DATE);
if (fmesa->ffb_sarea->flags & FFB_DRI_FFB2)
strncat(buffer, " FFB2", 5);
if (fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS)
strncat(buffer, " FFB2PLUS", 9);
if (fmesa->ffb_sarea->flags & FFB_DRI_PAC1)
strncat(buffer, " PAC1", 5);
if (fmesa->ffb_sarea->flags & FFB_DRI_PAC2)
strncat(buffer, " PAC2", 5);
#ifdef USE_SPARC_ASM
strncat(buffer, " Sparc", 6);
#endif
return (GLubyte *) buffer;
default:
return NULL;
};
}
static void ffbBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
{
GET_CURRENT_CONTEXT(ctx);
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
LOCK_HARDWARE(fmesa);
*width = fmesa->driDrawable->w;
*height = fmesa->driDrawable->h;
UNLOCK_HARDWARE(fmesa);
}
void ffbDDExtensionsInit(GLcontext *ctx)
{
/* Nothing for now until we start to add
* real acceleration. -DaveM
*/
/* XXX Need to turn off GL_EXT_blend_func_separate for one.
* XXX Also BlendEquation should be turned off too, what
* XXX EXT is that assosciated with?
*/
}
static void ffbDDFinish(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
LOCK_HARDWARE(fmesa);
FFBWait(fmesa, fmesa->regs);
UNLOCK_HARDWARE(fmesa);
}
void ffbDDInitDriverFuncs(GLcontext *ctx)
{
ctx->Driver.GetBufferSize = ffbBufferSize;
ctx->Driver.GetString = ffbDDGetString;
ctx->Driver.Clear = ffbDDClear;
ctx->Driver.Finish = ffbDDFinish;
}

View File

@ -0,0 +1,36 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_dd.h,v 1.1 2000/06/20 05:08:38 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D.
* Copyright (C) 2000 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#ifndef _FFB_DD_H
#define _FFB_DD_H
#include "context.h"
void ffbDDInitDriverFuncs(GLcontext *ctx);
void ffbDDExtensionsInit(GLcontext *ctx);
#endif /* !(_FFB_DD_H) */

View File

@ -0,0 +1,214 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_depth.c,v 1.2 2002/02/22 21:32:58 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "mtypes.h"
#include "swrast/swrast.h"
#include "ffb_dd.h"
#include "ffb_span.h"
#include "ffb_context.h"
#include "ffb_depth.h"
#include "ffb_lock.h"
#include "swrast/swrast.h"
#undef DEPTH_TRACE
static void
FFBWriteDepthSpan(GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLdepth depth[], const GLubyte mask[])
{
#ifdef DEPTH_TRACE
fprintf(stderr, "FFBWriteDepthSpan: n(%d) x(%d) y(%d)\n",
(int) n, x, y);
#endif
if (ctx->Depth.Mask) {
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
GLuint *zptr;
GLuint i;
if (!fmesa->hw_locked)
LOCK_HARDWARE(fmesa);
FFBFifo(fmesa, 2);
fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_ON |
FFB_FBC_YE_OFF | FFB_FBC_RGBE_OFF);
fmesa->regs->ppc = FFB_PPC_ZS_VAR;
FFBWait(fmesa, fmesa->regs);
y = (dPriv->h - y);
zptr = (GLuint *)
((char *)fmesa->sfb32 +
((dPriv->x + x) << 2) +
((dPriv->y + y) << 13));
for (i = 0; i < n; i++) {
if (mask[i]) {
*zptr = Z_FROM_MESA(depth[i]);
}
zptr++;
}
FFBFifo(fmesa, 2);
fmesa->regs->fbc = fmesa->fbc;
fmesa->regs->ppc = fmesa->ppc;
fmesa->ffbScreen->rp_active = 1;
if (!fmesa->hw_locked)
UNLOCK_HARDWARE(fmesa);
}
}
static void
FFBWriteDepthPixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
const GLdepth depth[], const GLubyte mask[])
{
#ifdef DEPTH_TRACE
fprintf(stderr, "FFBWriteDepthPixels: n(%d)\n", (int) n);
#endif
if (ctx->Depth.Mask) {
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
char *zbase;
GLuint i;
if (!fmesa->hw_locked)
LOCK_HARDWARE(fmesa);
FFBFifo(fmesa, 2);
fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_ON |
FFB_FBC_YE_OFF | FFB_FBC_RGBE_OFF);
fmesa->regs->ppc = FFB_PPC_ZS_VAR;
fmesa->ffbScreen->rp_active = 1;
FFBWait(fmesa, fmesa->regs);
zbase = ((char *)fmesa->sfb32 +
(dPriv->x << 2) + (dPriv->y << 13));
for (i = 0; i < n; i++) {
GLint y1 = (dPriv->h - y[i]);
GLint x1 = x[i];
GLuint *zptr;
zptr = (GLuint *)
(zbase + (x1 << 2) + (y1 << 13));
if (mask[i])
*zptr = Z_FROM_MESA(depth[i]);
}
FFBFifo(fmesa, 2);
fmesa->regs->fbc = fmesa->fbc;
fmesa->regs->ppc = fmesa->ppc;
fmesa->ffbScreen->rp_active = 1;
if (!fmesa->hw_locked)
UNLOCK_HARDWARE(fmesa);
}
}
static void
FFBReadDepthSpan(GLcontext *ctx, GLuint n, GLint x, GLint y, GLdepth depth[])
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
GLuint *zptr;
GLuint i;
#ifdef DEPTH_TRACE
fprintf(stderr, "FFBReadDepthSpan: n(%d) x(%d) y(%d)\n",
(int) n, x, y);
#endif
if (!fmesa->hw_locked)
LOCK_HARDWARE(fmesa);
FFBFifo(fmesa, 1);
fmesa->regs->fbc = FFB_FBC_RB_C;
fmesa->ffbScreen->rp_active = 1;
FFBWait(fmesa, fmesa->regs);
y = (dPriv->h - y);
zptr = (GLuint *)
((char *)fmesa->sfb32 +
((dPriv->x + x) << 2) +
((dPriv->y + y) << 13));
for (i = 0; i < n; i++) {
depth[i] = Z_TO_MESA(*zptr);
zptr++;
}
FFBFifo(fmesa, 1);
fmesa->regs->fbc = fmesa->fbc;
fmesa->ffbScreen->rp_active = 1;
if (!fmesa->hw_locked)
UNLOCK_HARDWARE(fmesa);
}
static void
FFBReadDepthPixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
GLdepth depth[])
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
char *zbase;
GLuint i;
#ifdef DEPTH_TRACE
fprintf(stderr, "FFBReadDepthPixels: n(%d)\n", (int) n);
#endif
if (!fmesa->hw_locked)
LOCK_HARDWARE(fmesa);
FFBFifo(fmesa, 1);
fmesa->regs->fbc = FFB_FBC_RB_C;
fmesa->ffbScreen->rp_active = 1;
FFBWait(fmesa, fmesa->regs);
zbase = ((char *)fmesa->sfb32 +
(dPriv->x << 2) + (dPriv->y << 13));
for (i = 0; i < n; i++) {
GLint y1 = (dPriv->h - y[i]);
GLint x1 = x[i];
GLuint *zptr;
zptr = (GLuint *)
(zbase + (x1 << 2) + (y1 << 13));
depth[i] = Z_TO_MESA(*zptr);
}
FFBFifo(fmesa, 1);
fmesa->regs->fbc = fmesa->fbc;
fmesa->ffbScreen->rp_active = 1;
if (!fmesa->hw_locked)
UNLOCK_HARDWARE(fmesa);
}
void ffbDDInitDepthFuncs(GLcontext *ctx)
{
struct swrast_device_driver *swdd =
_swrast_GetDeviceDriverReference(ctx);
swdd->WriteDepthSpan = FFBWriteDepthSpan;
swdd->ReadDepthSpan = FFBReadDepthSpan;
swdd->WriteDepthPixels = FFBWriteDepthPixels;
swdd->ReadDepthPixels = FFBReadDepthPixels;
}

View File

@ -0,0 +1,8 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_depth.h,v 1.1 2000/06/20 05:08:38 dawes Exp $ */
#ifndef _FFB_DEPTH_H
#define _FFB_DEPTH_H
extern void ffbDDInitDepthFuncs(GLcontext *ctx);
#endif /* !(_FFB_DEPTH_H) */

View File

@ -0,0 +1,28 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_fifo.h,v 1.2 2002/02/22 21:32:58 dawes Exp $ */
#ifndef _FFB_FIFO_H
#define _FFB_FIFO_H
#define FFBFifo(__fmesa, __n) \
do { ffbScreenPrivate *__fScrn = (__fmesa)->ffbScreen; \
int __cur_slots = __fScrn->fifo_cache; \
if ((__cur_slots - (__n)) < 0) { \
ffb_fbcPtr __ffb = __fmesa->regs; \
do { __cur_slots = (((int)__ffb->ucsr & FFB_UCSR_FIFO_MASK) - 4); \
} while ((__cur_slots - (__n)) < 0); \
} (__fScrn)->fifo_cache = (__cur_slots - (__n)); \
} while(0)
#define FFBWait(__fmesa, __ffb) \
do { ffbScreenPrivate *__fScrn = (__fmesa)->ffbScreen; \
if (__fScrn->rp_active) { \
unsigned int __regval = (__ffb)->ucsr; \
while((__regval & FFB_UCSR_ALL_BUSY) != 0) { \
__regval = (__ffb)->ucsr; \
} \
__fScrn->fifo_cache = ((int)(__regval & FFB_UCSR_FIFO_MASK)) - 4; \
__fScrn->rp_active = 0; \
} \
} while(0)
#endif /* !(_FFB_FIFO_H) */

View File

@ -0,0 +1,73 @@
/* FFB fog support:
*
* There are two levels of support for FOG in the Creator3D series.
* Both involve a depth cue unit and 1 or 4 slope factors and scales
* for varying the pixel intensity.
*
* Chips prior to FFB2 only have a single set of such settings, FFB2
* and later have 4 settings.
*
* The basic depth cueing equation is:
*
* C_final = dcsf(z) * C_orig + (1 - dcsf(z)) * C_fog
*
* C_final -- The final color passed to blend unit or frame
* buffer (if blending is disabled).
*
* C_orig -- The color we start with, which comes either from
* the raster processor or cpu writes to the smart
* framebuffer aperture.
*
* C_fog -- This is the "fog" color, ie. the desired color
* at the deepest Z.
*
* dcsf(z) -- The depth cue scale as a function of Z.
*
* With pre-FFB2 chips there are four parameters to control the depth
* cue scaling. Here is a diagram:
*
* 1.0 -------------
* | | | |
* | | | |
* Sfront XXXXX---+---+
* | |X | |
* dcsf(z) | | X | |
* | | X| |
* Sback +---+---XXXXX
* | | | |
* 0.0 -------------
* 0.0 Zf Zb 1.0
*
* z
* Therefore:
*
* for Zf < z < Zb
*
* dcsf(z) = Sback + ((Sfront - Sback) / (Zf - Zb)) * (Zb - z)
*
* for z <= Zf
*
* dcsf(z) = Sfront
*
* for z >= Zb
*
* dcsf(z) = Sback
*
* With FFB2 and later, 3 more slope regions are provided, the first of
* them starts at the end of the region defined above and ends at a
* specified depth value, the next slop region starts there and ends
* at the next specified depth value, and so on. Each of the 3 slope
* regions also have scale and slope settings of their own.
*
* The C_fog color is programmed into the alpha blending unit color1
* and color2 registers as follows:
*
* color1: -(C_fog)
* color2: C_fog - bg
*
* If alpha blending is disabled, the bg factor is zero. Note that
* the alpha blending color registers specify each of the RGB values
* as 9 bit 1:8 signed numbers in the range -1.00 to 0.ff inclusive.
* (ie. 0x100 == -1.00 and 0x0ff == +0.ff)
*/

View File

@ -0,0 +1,112 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_lines.c,v 1.2 2002/02/22 21:32:58 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000, 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "mtypes.h"
#include "mm.h"
#include "mmath.h"
#include "ffb_dd.h"
#include "ffb_span.h"
#include "ffb_depth.h"
#include "ffb_context.h"
#include "ffb_vb.h"
#include "ffb_lines.h"
#include "ffb_tris.h"
#include "ffb_lock.h"
#include "extensions.h"
#undef FFB_LINE_TRACE
#define FFB_LINE_FLAT_BIT 0x01
#define FFB_LINE_ALPHA_BIT 0x02
#define MAX_FFB_LINE_FUNCS 0x04
static ffb_line_func ffb_line_tab[MAX_FFB_LINE_FUNCS];
/* If the line is not wide, we can support all of the line
* patterning and smooth shading features of OpenGL fully.
*/
#define IND (0)
#define TAG(x) x
#include "ffb_linetmp.h"
#define IND (FFB_LINE_FLAT_BIT)
#define TAG(x) x##_flat
#include "ffb_linetmp.h"
#define IND (FFB_LINE_ALPHA_BIT)
#define TAG(x) x##_alpha
#include "ffb_linetmp.h"
#define IND (FFB_LINE_ALPHA_BIT|FFB_LINE_FLAT_BIT)
#define TAG(x) x##_alpha_flat
#include "ffb_linetmp.h"
void ffbDDLinefuncInit(void)
{
init();
init_flat();
init_alpha();
init_alpha_flat();
}
static void ffb_dd_line( GLcontext *ctx, GLuint e0, GLuint e1 )
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_vertex *v0 = &fmesa->verts[e0];
ffb_vertex *v1 = &fmesa->verts[e1];
fmesa->draw_line( ctx, v0, v1 );
}
void ffbChooseLineState(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
GLuint ind = 0;
tnl->Driver.Render.Line = ffb_dd_line;
if (flags & DD_FLATSHADE)
ind |= FFB_LINE_FLAT_BIT;
if ((flags & DD_LINE_STIPPLE) != 0 &&
fmesa->lpat == FFB_LPAT_BAD) {
fmesa->draw_line = ffb_fallback_line;
return;
}
/* If blending or the alpha test is enabled we need to
* provide alpha components to the chip, else we can
* do without it and thus feed vertex data to the chip
* more efficiently.
*/
if (ctx->Color.BlendEnabled || ctx->Color.AlphaEnabled)
ind |= FFB_LINE_ALPHA_BIT;
fmesa->draw_line = ffb_line_tab[ind];
}

View File

@ -0,0 +1,18 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_lines.h,v 1.2 2002/02/22 21:32:58 dawes Exp $ */
#ifndef _FFB_LINES_H
#define _FFB_LINES_H
#include "ffb_context.h"
#define _FFB_NEW_LINE (_DD_NEW_FLATSHADE | \
_DD_NEW_LINE_WIDTH | \
_DD_NEW_LINE_STIPPLE | \
_DD_NEW_LINE_SMOOTH | \
_NEW_COLOR)
extern void ffbDDLinefuncInit(void);
extern void ffbChooseLineState(GLcontext *);
extern void ffb_fallback_line( GLcontext *ctx, ffb_vertex *v0, ffb_vertex *v1 );
#endif /* !(_FFB_LINES_H) */

View File

@ -0,0 +1,81 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_linetmp.h,v 1.2 2002/02/22 21:32:58 dawes Exp $ */
static __inline void TAG(ffb_line)(GLcontext *ctx, ffb_vertex *v0,
ffb_vertex *v1 )
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_fbcPtr ffb = fmesa->regs;
#if (IND & FFB_LINE_FLAT_BIT)
const GLuint const_fg = FFB_PACK_CONST_UBYTE_ARGB_COLOR( v1->color[0] );
#endif
FFB_DELAYED_VIEWPORT_VARS;
#ifdef FFB_LINE_TRACE
fprintf(stderr, "FFB: ffb_line ["
#if (IND & FFB_LINE_FLAT_BIT)
" FLAT"
#endif
#if (IND & FFB_LINE_ALPHA_BIT)
" ALPHA"
#endif
" ]\n");
#endif
#if (IND & FFB_LINE_FLAT_BIT)
FFBFifo(fmesa, 1);
ffb->fg = const_fg;
#ifdef FFB_LINE_TRACE
fprintf(stderr, "FFB: ffb_line confg_fg[%08x]\n", const_fg);
#endif
#endif
#if (IND & FFB_LINE_FLAT_BIT)
/* (2 * 3) + 1 */
FFBFifo(fmesa, 7);
#else
#if (IND & FFB_LINE_ALPHA_BIT)
/* (2 * 7) + 1 */
FFBFifo(fmesa, 15);
#else
/* (2 * 6) + 1 */
FFBFifo(fmesa, 13);
#endif
#endif
/* Using DDLINE or AALINE, init the line pattern state. */
ffb->lpat = fmesa->lpat;
#if !(IND & FFB_LINE_FLAT_BIT)
#if (IND & FFB_LINE_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v0);
#endif
ffb->red = FFB_GET_RED(v0);
ffb->green = FFB_GET_GREEN(v0);
ffb->blue = FFB_GET_BLUE(v0);
#endif
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
#if !(IND & FFB_LINE_FLAT_BIT)
#if (IND & FFB_LINE_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v1);
#endif
ffb->red = FFB_GET_RED(v1);
ffb->green = FFB_GET_GREEN(v1);
ffb->blue = FFB_GET_BLUE(v1);
#endif
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(init)(void)
{
ffb_line_tab[IND] = TAG(ffb_line);
}
#undef IND
#undef TAG

View File

@ -0,0 +1,33 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_lock.h,v 1.2 2002/02/22 21:32:59 dawes Exp $ */
#ifndef _FFB_LOCK_H
#define _FFB_LOCK_H
#include "ffb_context.h"
extern void ffbXMesaUpdateState(ffbContextPtr fmesa);
#define FFB_UPDATE_STATE(fmesa) ffbXMesaUpdateState(fmesa)
/* Lock the hardware and validate our state. */
#if defined(__i386__)
#define LOCK_HARDWARE(fmesa)
#define UNLOCK_HARDWARE(fmesa)
#else
#define LOCK_HARDWARE(fmesa) \
do { \
int __ret=0; \
DRM_CAS(fmesa->driHwLock, fmesa->hHWContext, \
(DRM_LOCK_HELD | fmesa->hHWContext), __ret);\
if (__ret) { \
drmGetLock(fmesa->driFd, fmesa->hHWContext, 0); \
FFB_UPDATE_STATE(fmesa); \
} \
} while (0)
/* Unlock the hardware. */
#define UNLOCK_HARDWARE(fmesa) \
DRM_UNLOCK(fmesa->driFd, fmesa->driHwLock, fmesa->hHWContext);
#endif
#endif /* !(_FFB_LOCK_H) */

View File

@ -0,0 +1,94 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_points.c,v 1.2 2002/02/22 21:32:59 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000, 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "mtypes.h"
#include "mmath.h"
#include "ffb_dd.h"
#include "ffb_context.h"
#include "ffb_vb.h"
#include "ffb_points.h"
#include "ffb_tris.h"
#include "ffb_lock.h"
#undef FFB_POINT_TRACE
#define FFB_POINT_AA_BIT 0x01
static ffb_point_func ffb_point_tab[0x08];
#define IND (0)
#define TAG(x) x
#include "ffb_pointtmp.h"
#define IND (FFB_POINT_AA_BIT)
#define TAG(x) x##_aa
#include "ffb_pointtmp.h"
void ffbDDPointfuncInit(void)
{
init();
init_aa();
}
static void ffb_dd_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_vertex *fverts = fmesa->verts;
int i;
if (VB->Elts == 0) {
for ( i = first ; i < last ; i++ ) {
if ( VB->ClipMask[i] == 0 ) {
fmesa->draw_point( ctx, &fverts[i] );
}
}
} else {
for ( i = first ; i < last ; i++ ) {
GLuint e = VB->Elts[i];
if ( VB->ClipMask[e] == 0 ) {
fmesa->draw_point( ctx, &fverts[e] );
}
}
}
}
void ffbChoosePointState(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
GLuint ind = 0;
tnl->Driver.Render.Points = ffb_dd_points;
if (flags & DD_POINT_SMOOTH)
ind |= FFB_POINT_AA_BIT;
fmesa->draw_point = ffb_point_tab[ind];
}

View File

@ -0,0 +1,15 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_points.h,v 1.2 2002/02/22 21:32:59 dawes Exp $ */
#ifndef _FFB_POINTS_H
#define _FFB_POINTS_H
extern void ffbDDPointfuncInit(void);
#define _FFB_NEW_POINT (_DD_NEW_POINT_SIZE | \
_DD_NEW_POINT_SMOOTH | \
_NEW_COLOR)
extern void ffbChoosePointState(GLcontext *);
extern void ffb_fallback_point( GLcontext *ctx, ffb_vertex *v0 );
#endif /* !(_FFB_POINTS_H) */

View File

@ -0,0 +1,55 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_pointtmp.h,v 1.3 2002/02/22 21:32:59 dawes Exp $ */
static __inline void TAG(ffb_draw_point)(GLcontext *ctx, ffb_vertex *tmp )
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_fbcPtr ffb = fmesa->regs;
FFB_DELAYED_VIEWPORT_VARS;
#ifdef FFB_POINT_TRACE
fprintf(stderr, "FFB: ffb_point ["
#if (IND & FFB_POINT_AA_BIT)
"AA"
#endif
"] X(%f) Y(%f) Z(%f)\n",
tmp->x, tmp->y, tmp->z);
#endif
#if (IND & FFB_POINT_AA_BIT)
FFBFifo(fmesa, 4);
ffb->fg = FFB_PACK_CONST_UBYTE_ARGB_COLOR( tmp->color[0] );
ffb->z = FFB_GET_Z(tmp);
ffb->y = FFB_GET_Y(tmp) + 0x8000 /* FIX ME */;
ffb->x = FFB_GET_X(tmp) + 0x8000 /* FIX ME */;
#else
{
unsigned int const_fg, const_z, h, w;
const_fg = FFB_PACK_CONST_UBYTE_ARGB_COLOR( tmp->color[0] );
const_z = Z_FROM_MESA(FFB_Z_TO_FLOAT(FFB_GET_Z(tmp)));
h = FFB_GET_Y(tmp) >> 16;
w = FFB_GET_X(tmp) >> 16;
#ifdef FFB_POINT_TRACE
fprintf(stderr, "FFB: ffb_point fg(%08x) z(%08x) h(%08x) w(%08x)\n",
const_fg, const_z, h, w);
#endif
FFBFifo(fmesa, 4);
ffb->fg = const_fg;
ffb->constz = const_z;
ffb->bh = h;
ffb->bw = w;
}
#endif
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(init)(void)
{
ffb_point_tab[IND] = TAG(ffb_draw_point);
}
#undef IND
#undef TAG

View File

@ -0,0 +1,648 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_rendertmp.h,v 1.2 2003/01/29 23:00:40 dawes Exp $ */
#define IMPL_LOCAL_VARS \
ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
ffb_fbcPtr ffb = fmesa->regs; \
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
FFB_DELAYED_VIEWPORT_VARS; \
(void) fmesa; (void) ffb; (void) elt
#if (IND & FFB_FLAT_BIT)
#define FFB_DECLARE_CACHED_COLOR(NAME) \
unsigned int NAME;
#define FFB_COMPUTE_CACHED_COLOR(NAME, VTX) \
NAME = FFB_PACK_CONST_UBYTE_ARGB_COLOR((VTX)->color[0])
#define FFB_CACHED_COLOR_SAME(NAME1, NAME2) \
((NAME1) == (NAME2))
#define FFB_CACHED_COLOR_SET(NAME) \
ffb->fg = (NAME)
#define FFB_CACHED_COLOR_UPDATE(NAME1, NAME2) \
ffb->fg = (NAME1) = (NAME2)
#define FFB_SET_PRIM_COLOR(COLOR_VERTEX) \
ffb->fg = FFB_PACK_CONST_UBYTE_ARGB_COLOR((COLOR_VERTEX)->color[0])
#define FFB_PRIM_COLOR_COST 1
#define FFB_SET_VERTEX_COLOR(VTX) /**/
#define FFB_VERTEX_COLOR_COST 0
#else
#define FFB_DECLARE_CACHED_COLOR(NAME) /**/
#define FFB_COMPUTE_CACHED_COLOR(NAME, VTX) /**/
#define FFB_CACHED_COLOR_SAME(NAME1, NAME2) 0
#define FFB_CACHED_COLOR_SET(NAME1) /**/
#define FFB_CACHED_COLOR_UPDATE(NAME1, NAME2) /**/
#define FFB_SET_PRIM_COLOR(COLOR_VERTEX) /**/
#define FFB_PRIM_COLOR_COST 0
#if (IND & FFB_ALPHA_BIT)
#define FFB_SET_VERTEX_COLOR(VTX) \
ffb->alpha = FFB_GET_ALPHA(VTX); \
ffb->red = FFB_GET_RED(VTX); \
ffb->green = FFB_GET_GREEN(VTX); \
ffb->blue = FFB_GET_BLUE(VTX)
#define FFB_VERTEX_COLOR_COST 4
#else
#define FFB_SET_VERTEX_COLOR(VTX) \
ffb->red = FFB_GET_RED(VTX); \
ffb->green = FFB_GET_GREEN(VTX); \
ffb->blue = FFB_GET_BLUE(VTX)
#define FFB_VERTEX_COLOR_COST 3
#endif
#endif
#define RESET_STIPPLE ffb->lpat = fmesa->lpat;
#if !(IND & (FFB_TRI_CULL_BIT))
static void TAG(ffb_vb_points)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_POINTS);
if (ctx->_TriangleCaps & DD_POINT_SMOOTH) {
for (i = start; i < count; i++) {
ffb_vertex *v0 = &fmesa->verts[ELT(i)];
FFBFifo(fmesa, 4);
ffb->fg = FFB_PACK_CONST_UBYTE_ARGB_COLOR(v0->color[0]);
ffb->z = FFB_GET_Z(v0);
ffb->y = FFB_GET_Y(v0) + 0x8000 /* FIX ME */;
ffb->x = FFB_GET_X(v0) + 0x8000 /* FIX ME */;
}
} else {
for (i = start; i < count; i++) {
ffb_vertex *v0 = &fmesa->verts[ELT(i)];
FFBFifo(fmesa, 4);
ffb->fg = FFB_PACK_CONST_UBYTE_ARGB_COLOR(v0->color[0]);
ffb->constz = Z_FROM_MESA(FFB_Z_TO_FLOAT(FFB_GET_Z(v0)));
ffb->bh = FFB_GET_Y(v0) >> 16;
ffb->bw = FFB_GET_X(v0) >> 16;
}
}
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_vb_lines)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_LINES);
for (i = start + 1; i < count; i += 2) {
ffb_vertex *v0 = &fmesa->verts[i - 1];
ffb_vertex *v1 = &fmesa->verts[i - 0];
FFBFifo(fmesa, (1 + FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 2) + 6));
RESET_STIPPLE;
FFB_SET_PRIM_COLOR(v1);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
}
}
static void TAG(ffb_vb_line_loop)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_LINE_LOOP);
if ((flags & PRIM_BEGIN) != 0) {
ffb_vertex *v0 = &fmesa->verts[ELT(start + 0)];
ffb_vertex *v1 = &fmesa->verts[ELT(start + 1)];
FFBFifo(fmesa, (1 + FFB_PRIM_COLOR_COST +
((FFB_VERTEX_COLOR_COST * 2) + (3 * 2))));
RESET_STIPPLE;
FFB_SET_PRIM_COLOR(v1);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
}
for (i = start + 2; i < count; i++) {
ffb_vertex *v0 = &fmesa->verts[ELT(i)];
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST + 3)));
FFB_SET_PRIM_COLOR(v0);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->y = FFB_GET_Y(v0);
ffb->x = FFB_GET_X(v0);
}
if ((flags & PRIM_END) != 0) {
ffb_vertex *v0 = &fmesa->verts[ELT(start)];
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST + 3)));
FFB_SET_PRIM_COLOR(v0);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->y = FFB_GET_Y(v0);
ffb->x = FFB_GET_X(v0);
}
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_vb_line_strip)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
FFB_DECLARE_CACHED_COLOR(cached_fg)
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_LINE_STRIP);
FFBFifo(fmesa, (1 + FFB_PRIM_COLOR_COST +
((FFB_VERTEX_COLOR_COST * 2) + (3 * 2))));
RESET_STIPPLE;
{
ffb_vertex *v0 = &fmesa->verts[ELT(start + 0)];
ffb_vertex *v1 = &fmesa->verts[ELT(start + 1)];
FFB_COMPUTE_CACHED_COLOR(cached_fg, v0);
FFB_CACHED_COLOR_SET(cached_fg);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
}
for (i = start + 2; i < count; i++) {
ffb_vertex *v1 = &fmesa->verts[ELT(i - 0)];
FFB_DECLARE_CACHED_COLOR(new_fg)
FFB_COMPUTE_CACHED_COLOR(new_fg, v1);
if (FFB_CACHED_COLOR_SAME(cached_fg, new_fg)) {
FFBFifo(fmesa, ((FFB_VERTEX_COLOR_COST * 1) + (3 * 1)));
} else {
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 1) + (3 * 1)));
FFB_CACHED_COLOR_UPDATE(cached_fg, new_fg);
}
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
}
fmesa->ffbScreen->rp_active = 1;
}
#endif /* !(IND & (FFB_TRI_CULL_BIT)) */
/* OK, now things start getting fun :-) */
#if (IND & (FFB_TRI_CULL_BIT))
#define FFB_AREA_DECLARE GLfloat cc, ex, ey, fx, fy;
#define FFB_COMPUTE_AREA_TRI(V0, V1, V2) \
{ ex = (V1)->x - (V0)->x; \
ey = (V1)->y - (V0)->y; \
fx = (V2)->x - (V0)->x; \
fy = (V2)->y - (V0)->y; \
cc = ex*fy-ey*fx; \
}
#define FFB_COMPUTE_AREA_QUAD(V0, V1, V2, V3) \
{ ex = (V2)->x - (V0)->x; \
ey = (V2)->y - (V0)->y; \
fx = (V3)->x - (V1)->x; \
fy = (V3)->y - (V1)->y; \
cc = ex*fy-ey*fx; \
}
#else
#define FFB_AREA_DECLARE /**/
#define FFB_COMPUTE_AREA_TRI(V0, V1, V2) do { } while(0)
#define FFB_COMPUTE_AREA_QUAD(V0, V1, V2, V3) do { } while(0)
#endif
#if (IND & FFB_TRI_CULL_BIT)
#define FFB_CULL_TRI(CULL_ACTION) \
if (cc * fmesa->backface_sign > fmesa->ffb_zero) { \
CULL_ACTION \
}
#define FFB_CULL_QUAD(CULL_ACTION) \
if (cc * fmesa->backface_sign > fmesa->ffb_zero) { \
CULL_ACTION \
}
#else
#define FFB_CULL_TRI(CULL_ACTION) do { } while (0)
#define FFB_CULL_QUAD(CULL_ACTION) do { } while (0)
#endif
static void TAG(ffb_vb_triangles)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_TRIANGLES);
for (i = start + 2; i < count; i += 3) {
ffb_vertex *v0 = &fmesa->verts[ELT(i - 2)];
ffb_vertex *v1 = &fmesa->verts[ELT(i - 1)];
ffb_vertex *v2 = &fmesa->verts[ELT(i - 0)];
FFB_AREA_DECLARE
FFB_COMPUTE_AREA_TRI(v0, v1, v2);
FFB_CULL_TRI(continue;);
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 3) + 9));
FFB_SET_PRIM_COLOR(v2);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
FFB_SET_VERTEX_COLOR(v2);
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
}
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_vb_tri_strip)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
GLint parity = 0;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_TRIANGLE_STRIP);
if ((flags & PRIM_PARITY) != 0)
parity = 1;
i = start + 2;
goto something_clipped;
something_clipped:
for (; i < count; i++, parity ^= 1) {
ffb_vertex *v0 = &fmesa->verts[ELT(i - 2 + parity)];
ffb_vertex *v1 = &fmesa->verts[ELT(i - 1 - parity)];
ffb_vertex *v2 = &fmesa->verts[ELT(i - 0)];
FFB_AREA_DECLARE
FFB_COMPUTE_AREA_TRI(v0, v1, v2);
FFB_CULL_TRI(continue;);
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 3) + 9));
FFB_SET_PRIM_COLOR(v2);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
FFB_SET_VERTEX_COLOR(v2);
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
i++;
parity ^= 1;
break;
}
for (; i < count; i++, parity ^= 1) {
ffb_vertex *v0 = &fmesa->verts[ELT(i - 2 + parity)];
ffb_vertex *v1 = &fmesa->verts[ELT(i - 1 - parity)];
ffb_vertex *v2 = &fmesa->verts[ELT(i - 0)];
FFB_AREA_DECLARE
(void) v0; (void) v1;
FFB_COMPUTE_AREA_TRI(v0, v1, v2);
FFB_CULL_TRI(i++; parity^=1; goto something_clipped;);
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 1) + 3));
FFB_SET_PRIM_COLOR(v2);
FFB_SET_VERTEX_COLOR(v2);
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
}
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_vb_tri_fan)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_TRIANGLE_FAN);
i = start + 2;
goto something_clipped;
something_clipped:
for ( ; i < count; i++) {
ffb_vertex *v0 = &fmesa->verts[ELT(start)];
ffb_vertex *v1 = &fmesa->verts[ELT(i - 1)];
ffb_vertex *v2 = &fmesa->verts[ELT(i - 0)];
FFB_AREA_DECLARE
FFB_COMPUTE_AREA_TRI(v0, v1, v2);
FFB_CULL_TRI(continue;);
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 3) + 9));
FFB_SET_PRIM_COLOR(v2);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
FFB_SET_VERTEX_COLOR(v2);
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
i++;
break;
}
for (; i < count; i++) {
ffb_vertex *v0 = &fmesa->verts[ELT(start)];
ffb_vertex *v1 = &fmesa->verts[ELT(i - 1)];
ffb_vertex *v2 = &fmesa->verts[ELT(i - 0)];
FFB_AREA_DECLARE
(void) v0; (void) v1;
FFB_COMPUTE_AREA_TRI(v0, v1, v2);
FFB_CULL_TRI(i++; goto something_clipped;);
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 1) + 3));
FFB_SET_PRIM_COLOR(v2);
FFB_SET_VERTEX_COLOR(v2);
ffb->z = FFB_GET_Z(v2);
ffb->dmyf = FFB_GET_Y(v2);
ffb->dmxf = FFB_GET_X(v2);
}
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_vb_poly)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_POLYGON);
/* XXX Optimize XXX */
for (i = start + 2; i < count; i++) {
ffb_vertex *v0 = &fmesa->verts[ELT(i - 1)];
ffb_vertex *v1 = &fmesa->verts[ELT(i)];
ffb_vertex *v2 = &fmesa->verts[ELT(start)];
FFB_AREA_DECLARE
FFB_COMPUTE_AREA_TRI(v0, v1, v2);
FFB_CULL_TRI(continue;);
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 3) + 9));
FFB_SET_PRIM_COLOR(v2);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
FFB_SET_VERTEX_COLOR(v2);
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
}
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_vb_quads)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_QUADS);
for (i = start + 3; i < count; i += 4) {
ffb_vertex *v0 = &fmesa->verts[ELT(i - 3)];
ffb_vertex *v1 = &fmesa->verts[ELT(i - 2)];
ffb_vertex *v2 = &fmesa->verts[ELT(i - 1)];
ffb_vertex *v3 = &fmesa->verts[ELT(i - 0)];
FFB_AREA_DECLARE
FFB_COMPUTE_AREA_QUAD(v0, v1, v2, v3);
FFB_CULL_QUAD(continue;);
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 4) + 12));
FFB_SET_PRIM_COLOR(v3);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
FFB_SET_VERTEX_COLOR(v2);
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
FFB_SET_VERTEX_COLOR(v3);
ffb->z = FFB_GET_Z(v3);
ffb->dmyf = FFB_GET_Y(v3);
ffb->dmxf = FFB_GET_X(v3);
}
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_vb_quad_strip)(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
GLint i;
IMPL_LOCAL_VARS;
#ifdef FFB_RENDER_TRACE
fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n",
__FUNCTION__, start, count, flags);
#endif
ffbRenderPrimitive(ctx, GL_QUAD_STRIP);
/* XXX Optimize XXX */
for (i = start + 3; i < count; i += 2) {
ffb_vertex *v0 = &fmesa->verts[ELT(i - 1)];
ffb_vertex *v1 = &fmesa->verts[ELT(i - 3)];
ffb_vertex *v2 = &fmesa->verts[ELT(i - 2)];
ffb_vertex *v3 = &fmesa->verts[ELT(i - 0)];
FFB_AREA_DECLARE
FFB_COMPUTE_AREA_QUAD(v0, v1, v2, v3);
FFB_CULL_QUAD(continue;);
FFBFifo(fmesa, (FFB_PRIM_COLOR_COST +
(FFB_VERTEX_COLOR_COST * 4) + 12));
FFB_SET_PRIM_COLOR(v3);
FFB_DUMP_VERTEX(v0);
FFB_SET_VERTEX_COLOR(v0);
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_DUMP_VERTEX(v1);
FFB_SET_VERTEX_COLOR(v1);
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
FFB_DUMP_VERTEX(v2);
FFB_SET_VERTEX_COLOR(v2);
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
FFB_DUMP_VERTEX(v3);
FFB_SET_VERTEX_COLOR(v3);
ffb->z = FFB_GET_Z(v3);
ffb->dmyf = FFB_GET_Y(v3);
ffb->dmxf = FFB_GET_X(v3);
}
fmesa->ffbScreen->rp_active = 1;
}
static void (*TAG(render_tab)[GL_POLYGON + 2])(GLcontext *, GLuint, GLuint, GLuint) =
{
#if !(IND & (FFB_TRI_CULL_BIT))
TAG(ffb_vb_points),
TAG(ffb_vb_lines),
TAG(ffb_vb_line_loop),
TAG(ffb_vb_line_strip),
#else
NULL,
NULL,
NULL,
NULL,
#endif
TAG(ffb_vb_triangles),
TAG(ffb_vb_tri_strip),
TAG(ffb_vb_tri_fan),
TAG(ffb_vb_quads),
TAG(ffb_vb_quad_strip),
TAG(ffb_vb_poly),
ffb_vb_noop,
};
#undef IND
#undef TAG
#undef IMPL_LOCAL_VARS
#undef FFB_DECLARE_CACHED_COLOR
#undef FFB_COMPUTE_CACHED_COLOR
#undef FFB_CACHED_COLOR_SAME
#undef FFB_CACHED_COLOR_SET
#undef FFB_CACHED_COLOR_UPDATE
#undef FFB_SET_PRIM_COLOR
#undef FFB_PRIM_COLOR_COST
#undef FFB_SET_VERTEX_COLOR
#undef FFB_VERTEX_COLOR_COST
#undef RESET_STIPPLE
#undef FFB_AREA_DECLARE
#undef FFB_COMPUTE_AREA_TRI
#undef FFB_COMPUTE_AREA_QUAD
#undef FFB_CULL_TRI
#undef FFB_CULL_QUAD

View File

@ -0,0 +1,142 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_span.c,v 1.2 2002/02/22 21:32:59 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "mtypes.h"
#include "ffb_dd.h"
#include "ffb_span.h"
#include "ffb_context.h"
#include "ffb_lock.h"
#include "swrast/swrast.h"
#define DBG 0
#define HW_LOCK() \
ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
if (!fmesa->hw_locked) \
LOCK_HARDWARE(fmesa);
#define HW_UNLOCK() \
if (!fmesa->hw_locked) \
UNLOCK_HARDWARE(fmesa); \
#define LOCAL_VARS \
__DRIdrawablePrivate *dPriv = fmesa->driDrawable; \
GLuint height = dPriv->h; \
GLuint p; \
char *buf; \
(void) p
#define INIT_MONO_PIXEL(p, color) \
p = ((color[0] << 0) | \
(color[1] << 8) | \
(color[2] << 16))
/* We use WID clipping, so this test always passes. */
#define CLIPPIXEL(__x, __y) (1)
/* And also, due to WID clipping, we need not do anything
* special here.
*/
#define CLIPSPAN(__x,__y,__n,__x1,__n1,__i) \
__n1 = __n; \
__x1 = __x; \
#define HW_CLIPLOOP() \
do { unsigned int fbc, ppc, cmp; \
FFBWait(fmesa, fmesa->regs); \
fbc = fmesa->regs->fbc; ppc = fmesa->regs->ppc; cmp = fmesa->regs->cmp; \
fmesa->regs->fbc = ((fbc & \
~(FFB_FBC_WB_C | FFB_FBC_ZE_MASK | FFB_FBC_RGBE_MASK)) \
| (FFB_FBC_ZE_OFF | FFB_FBC_RGBE_MASK)); \
fmesa->regs->ppc = ((ppc & \
~(FFB_PPC_XS_MASK | FFB_PPC_ABE_MASK | FFB_PPC_DCE_MASK | \
FFB_PPC_APE_MASK | FFB_PPC_CS_MASK)) \
| (FFB_PPC_XS_WID | FFB_PPC_ABE_DISABLE | \
FFB_PPC_DCE_DISABLE | FFB_PPC_APE_DISABLE | \
FFB_PPC_CS_VAR)); \
fmesa->regs->cmp = ((cmp & ~(0xff << 16)) | (0x80 << 16)); \
fmesa->ffbScreen->rp_active = 1; \
FFBWait(fmesa, fmesa->regs); \
buf = (char *)(fmesa->sfb32 + (dPriv->x << 2) + (dPriv->y << 13));\
if (dPriv->numClipRects) {
#define HW_ENDCLIPLOOP() \
} \
fmesa->regs->fbc = fbc; \
fmesa->regs->ppc = ppc; \
fmesa->regs->cmp = cmp; \
fmesa->ffbScreen->rp_active = 1; \
} while(0)
#define Y_FLIP(__y) (height - __y)
#define READ_RGBA(rgba,__x,__y) \
do { GLuint p = *(GLuint *)(buf + ((__x)<<2) + ((__y)<<13)); \
rgba[0] = (p >> 0) & 0xff; \
rgba[1] = (p >> 8) & 0xff; \
rgba[2] = (p >> 16) & 0xff; \
rgba[3] = 0xff; \
} while(0)
#define WRITE_RGBA(__x, __y, __r, __g, __b, __a) \
*(GLuint *)(buf + ((__x)<<2) + ((__y)<<13)) = \
((((__r) & 0xff) << 0) | \
(((__g) & 0xff) << 8) | \
(((__b) & 0xff) << 16))
#define WRITE_PIXEL(__x, __y, __p) \
*(GLuint *)(buf + ((__x)<<2) + ((__y)<<13)) = (__p)
#define TAG(x) ffb##x##_888
#include <spantmp.h>
void ffbDDInitSpanFuncs(GLcontext *ctx)
{
struct swrast_device_driver *swdd =
_swrast_GetDeviceDriverReference(ctx);
swdd->WriteRGBASpan = ffbWriteRGBASpan_888;
swdd->WriteRGBSpan = ffbWriteRGBSpan_888;
swdd->WriteRGBAPixels = ffbWriteRGBAPixels_888;
swdd->WriteMonoRGBASpan = ffbWriteMonoRGBASpan_888;
swdd->WriteMonoRGBAPixels = ffbWriteMonoRGBAPixels_888;
swdd->ReadRGBASpan = ffbReadRGBASpan_888;
swdd->ReadRGBAPixels = ffbReadRGBAPixels_888;
/* We don't support color index mode yet, but it will be
* very easy to do. -DaveM
*/
swdd->WriteCI8Span = NULL;
swdd->WriteCI32Span = NULL;
swdd->WriteMonoCISpan = NULL;
swdd->WriteCI32Pixels = NULL;
swdd->WriteMonoCIPixels = NULL;
swdd->ReadCI32Span = NULL;
swdd->ReadCI32Pixels = NULL;
}

View File

@ -0,0 +1,8 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_span.h,v 1.1 2000/06/20 05:08:39 dawes Exp $ */
#ifndef _FFB_SPAN_H
#define _FFB_SPAN_H
extern void ffbDDInitSpanFuncs(GLcontext *ctx);
#endif /* !(_FFB_SPAN_H) */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_state.h,v 1.2 2002/02/22 21:32:59 dawes Exp $ */
#ifndef _FFB_STATE_H
#define _FFB_STATE_H
extern void ffbDDInitStateFuncs(GLcontext *);
extern void ffbDDInitContextHwState(GLcontext *);
extern void ffbCalcViewport(GLcontext *);
extern void ffbXformAreaPattern(ffbContextPtr, const GLubyte *);
extern void ffbSyncHardware(ffbContextPtr fmesa);
#endif /* !(_FFB_STATE_H) */

View File

@ -0,0 +1,221 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_stencil.c,v 1.2 2002/02/22 21:32:59 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "mtypes.h"
#include "ffb_dd.h"
#include "ffb_span.h"
#include "ffb_context.h"
#include "ffb_stencil.h"
#include "ffb_lock.h"
#include "swrast/swrast.h"
#undef STENCIL_TRACE
static void
FFBWriteStencilSpan(GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLstencil stencil[], const GLubyte mask[])
{
#ifdef STENCIL_TRACE
fprintf(stderr, "FFBWriteStencilSpan: n(%d) x(%d) y(%d)\n",
(int) n, x, y);
#endif
if (ctx->Depth.Mask) {
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
GLuint *zptr;
GLuint i;
if (!fmesa->hw_locked)
LOCK_HARDWARE(fmesa);
FFBFifo(fmesa, 2);
fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_OFF |
FFB_FBC_YE_ON | FFB_FBC_RGBE_OFF);
fmesa->regs->ppc = FFB_PPC_YS_VAR;
FFBWait(fmesa, fmesa->regs);
y = (dPriv->h - y);
zptr = (GLuint *)
((char *)fmesa->sfb32 +
((dPriv->x + x) << 2) +
((dPriv->y + y) << 13));
for (i = 0; i < n; i++) {
if (mask[i])
*zptr = (stencil[i] & 0xf) << 28;
zptr++;
}
FFBFifo(fmesa, 2);
fmesa->regs->fbc = fmesa->fbc;
fmesa->regs->ppc = fmesa->ppc;
fmesa->ffbScreen->rp_active = 1;
if (!fmesa->hw_locked)
UNLOCK_HARDWARE(fmesa);
}
}
static void
FFBWriteStencilPixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
const GLstencil stencil[], const GLubyte mask[])
{
#ifdef STENCIL_TRACE
fprintf(stderr, "FFBWriteStencilPixels: n(%d)\n", (int) n);
#endif
if (ctx->Depth.Mask) {
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
char *zbase;
GLuint i;
if (!fmesa->hw_locked)
LOCK_HARDWARE(fmesa);
FFBFifo(fmesa, 2);
fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_OFF |
FFB_FBC_YE_ON | FFB_FBC_RGBE_OFF);
fmesa->regs->ppc = FFB_PPC_YS_VAR;
fmesa->ffbScreen->rp_active = 1;
FFBWait(fmesa, fmesa->regs);
zbase = ((char *)fmesa->sfb32 +
(dPriv->x << 2) + (dPriv->y << 13));
for (i = 0; i < n; i++) {
GLint y1 = (dPriv->h - y[i]);
GLint x1 = x[i];
GLuint *zptr;
zptr = (GLuint *)
(zbase + (x1 << 2) + (y1 << 13));
if (mask[i])
*zptr = (stencil[i] & 0xf) << 28;
}
FFBFifo(fmesa, 2);
fmesa->regs->fbc = fmesa->fbc;
fmesa->regs->ppc = fmesa->ppc;
fmesa->ffbScreen->rp_active = 1;
if (!fmesa->hw_locked)
UNLOCK_HARDWARE(fmesa);
}
}
static void
FFBReadStencilSpan(GLcontext *ctx, GLuint n, GLint x, GLint y, GLstencil stencil[])
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
GLuint *zptr;
GLuint i;
#ifdef STENCIL_TRACE
fprintf(stderr, "FFBReadStencilSpan: n(%d) x(%d) y(%d)\n",
(int) n, x, y);
#endif
if (!fmesa->hw_locked)
LOCK_HARDWARE(fmesa);
FFBFifo(fmesa, 1);
fmesa->regs->fbc = FFB_FBC_RB_C;
fmesa->ffbScreen->rp_active = 1;
FFBWait(fmesa, fmesa->regs);
y = (dPriv->h - y);
zptr = (GLuint *)
((char *)fmesa->sfb32 +
((dPriv->x + x) << 2) +
((dPriv->y + y) << 13));
for (i = 0; i < n; i++) {
stencil[i] = (*zptr >> 28) & 0xf;
zptr++;
}
FFBFifo(fmesa, 1);
fmesa->regs->fbc = fmesa->fbc;
fmesa->ffbScreen->rp_active = 1;
if (!fmesa->hw_locked)
UNLOCK_HARDWARE(fmesa);
}
static void
FFBReadStencilPixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
GLstencil stencil[])
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
char *zbase;
GLuint i;
#ifdef STENCIL_TRACE
fprintf(stderr, "FFBReadStencilPixels: n(%d)\n", (int) n);
#endif
if (!fmesa->hw_locked)
LOCK_HARDWARE(fmesa);
FFBFifo(fmesa, 1);
fmesa->regs->fbc = FFB_FBC_RB_C;
fmesa->ffbScreen->rp_active = 1;
FFBWait(fmesa, fmesa->regs);
zbase = ((char *)fmesa->sfb32 +
(dPriv->x << 2) + (dPriv->y << 13));
for (i = 0; i < n; i++) {
GLint y1 = (dPriv->h - y[i]);
GLint x1 = x[i];
GLuint *zptr;
zptr = (GLuint *)
(zbase + (x1 << 2) + (y1 << 13));
stencil[i] = (*zptr >> 28) & 0xf;
}
FFBFifo(fmesa, 1);
fmesa->regs->fbc = fmesa->fbc;
fmesa->ffbScreen->rp_active = 1;
if (!fmesa->hw_locked)
UNLOCK_HARDWARE(fmesa);
}
void ffbDDInitStencilFuncs(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
struct swrast_device_driver *swdd =
_swrast_GetDeviceDriverReference(ctx);
if (fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS) {
swdd->WriteStencilSpan = FFBWriteStencilSpan;
swdd->ReadStencilSpan = FFBReadStencilSpan;
swdd->WriteStencilPixels = FFBWriteStencilPixels;
swdd->ReadStencilPixels = FFBReadStencilPixels;
} else {
swdd->WriteStencilSpan = NULL;
swdd->ReadStencilSpan = NULL;
swdd->WriteStencilPixels = NULL;
swdd->ReadStencilPixels = NULL;
}
}

View File

@ -0,0 +1,8 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_stencil.h,v 1.1 2000/06/20 05:08:39 dawes Exp $ */
#ifndef _FFB_STENCIL_H
#define _FFB_STENCIL_H
extern void ffbDDInitStencilFuncs(GLcontext *ctx);
#endif /* !(_FFB_STENCIL_H) */

View File

@ -0,0 +1,51 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_tex.c,v 1.1 2002/02/22 21:32:59 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include <GL/gl.h>
#include "texformat.h"
#include "texstore.h"
#include "swrast/swrast.h"
#include "ffb_tex.h"
/* No texture unit, all software. */
void ffbDDInitTexFuncs(GLcontext *ctx)
{
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.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.TestProxyTexImage = _mesa_test_proxy_teximage;
}

View File

@ -0,0 +1,34 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_tex.h,v 1.1 2002/02/22 21:32:59 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D.
* Copyright (C) 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#ifndef _FFB_TEX_H
#define _FFB_TEX_H
extern void ffbDDInitTexFuncs(GLcontext *ctx);
#endif /* !(_FFB_DD_H) */

View File

@ -0,0 +1,946 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_tris.c,v 1.3 2002/10/30 12:51:28 alanh Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000, 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "glheader.h"
#include "mtypes.h"
#include "macros.h"
#include "mmath.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "swrast/s_context.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "ffb_context.h"
#include "ffb_tris.h"
#include "ffb_lines.h"
#include "ffb_lock.h"
#include "ffb_points.h"
#include "ffb_state.h"
#include "ffb_vb.h"
#undef TRI_DEBUG
#undef FFB_RENDER_TRACE
#undef STATE_TRACE
#ifdef TRI_DEBUG
static void ffb_print_vertex(const ffb_vertex *v)
{
fprintf(stderr, "Vertex @(%p): "
"X[%f] Y[%f] Z[%f]\n",
v, v->x, v->y, v->z);
fprintf(stderr, "Vertex @(%p): "
"A[%f] R[%f] G[%f] B[%f]\n",
v,
v->color[0].alpha,
v->color[0].red,
v->color[0].green,
v->color[0].blue);
}
#define FFB_DUMP_VERTEX(V) ffb_print_vertex(V)
#else
#define FFB_DUMP_VERTEX(V) do { } while(0)
#endif
#define FFB_ALPHA_BIT 0x01
#define FFB_FLAT_BIT 0x02
#define FFB_TRI_CULL_BIT 0x04
#define MAX_FFB_RENDER_FUNCS 0x08
/***********************************************************************
* Build low-level triangle/quad rasterize functions *
***********************************************************************/
#define FFB_TRI_FLAT_BIT 0x01
#define FFB_TRI_ALPHA_BIT 0x02
/*#define FFB_TRI_CULL_BIT 0x04*/
static ffb_tri_func ffb_tri_tab[0x8];
static ffb_quad_func ffb_quad_tab[0x8];
#define IND (0)
#define TAG(x) x
#include "ffb_tritmp.h"
#define IND (FFB_TRI_FLAT_BIT)
#define TAG(x) x##_flat
#include "ffb_tritmp.h"
#define IND (FFB_TRI_CULL_BIT)
#define TAG(x) x##_cull
#include "ffb_tritmp.h"
#define IND (FFB_TRI_CULL_BIT|FFB_TRI_FLAT_BIT)
#define TAG(x) x##_cull_flat
#include "ffb_tritmp.h"
#define IND (FFB_TRI_ALPHA_BIT)
#define TAG(x) x##_alpha
#include "ffb_tritmp.h"
#define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_FLAT_BIT)
#define TAG(x) x##_alpha_flat
#include "ffb_tritmp.h"
#define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_CULL_BIT)
#define TAG(x) x##_alpha_cull
#include "ffb_tritmp.h"
#define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_CULL_BIT|FFB_TRI_FLAT_BIT)
#define TAG(x) x##_alpha_cull_flat
#include "ffb_tritmp.h"
static void init_tri_tab(void)
{
ffb_init();
ffb_init_flat();
ffb_init_cull();
ffb_init_cull_flat();
ffb_init_alpha();
ffb_init_alpha_flat();
ffb_init_alpha_cull();
ffb_init_alpha_cull_flat();
}
/* Build a SWvertex from a hardware vertex. */
static void ffb_translate_vertex(GLcontext *ctx, const ffb_vertex *src,
SWvertex *dst)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
GLfloat *m = ctx->Viewport._WindowMap.m;
const GLfloat sx = m[0];
const GLfloat sy = m[5];
const GLfloat sz = m[10];
const GLfloat tx = m[12];
const GLfloat ty = m[13];
const GLfloat tz = m[14];
dst->win[0] = sx * src->x + tx;
dst->win[1] = sy * src->y + ty;
dst->win[2] = sz * src->z + tz;
dst->win[3] = 1.0;
dst->color[0] = FFB_UBYTE_FROM_COLOR(src->color[0].red);
dst->color[1] = FFB_UBYTE_FROM_COLOR(src->color[0].green);
dst->color[2] = FFB_UBYTE_FROM_COLOR(src->color[0].blue);
dst->color[3] = FFB_UBYTE_FROM_COLOR(src->color[0].alpha);
}
/***********************************************************************
* Build fallback triangle/quad rasterize functions *
***********************************************************************/
static void ffb_fallback_triangle(GLcontext *ctx, ffb_vertex *v0,
ffb_vertex *v1, ffb_vertex *v2)
{
SWvertex v[3];
ffb_translate_vertex(ctx, v0, &v[0]);
ffb_translate_vertex(ctx, v1, &v[1]);
ffb_translate_vertex(ctx, v2, &v[2]);
_swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
}
static void ffb_fallback_quad(GLcontext *ctx,
ffb_vertex *v0, ffb_vertex *v1,
ffb_vertex *v2, ffb_vertex *v3)
{
SWvertex v[4];
ffb_translate_vertex(ctx, v0, &v[0]);
ffb_translate_vertex(ctx, v1, &v[1]);
ffb_translate_vertex(ctx, v2, &v[2]);
ffb_translate_vertex(ctx, v3, &v[3]);
_swrast_Quad(ctx, &v[0], &v[1], &v[2], &v[3]);
}
void ffb_fallback_line(GLcontext *ctx, ffb_vertex *v0, ffb_vertex *v1)
{
SWvertex v[2];
ffb_translate_vertex(ctx, v0, &v[0]);
ffb_translate_vertex(ctx, v1, &v[1]);
_swrast_Line(ctx, &v[0], &v[1]);
}
void ffb_fallback_point(GLcontext *ctx, ffb_vertex *v0)
{
SWvertex v[1];
ffb_translate_vertex(ctx, v0, &v[0]);
_swrast_Point(ctx, &v[0]);
}
/***********************************************************************
* Rasterization functions for culled tris/quads *
***********************************************************************/
static void ffb_nodraw_triangle(GLcontext *ctx, ffb_vertex *v0,
ffb_vertex *v1, ffb_vertex *v2)
{
(void) (ctx && v0 && v1 && v2);
}
static void ffb_nodraw_quad(GLcontext *ctx,
ffb_vertex *v0, ffb_vertex *v1,
ffb_vertex *v2, ffb_vertex *v3)
{
(void) (ctx && v0 && v1 && v2 && v3);
}
static void ffb_update_cullsign(GLcontext *ctx)
{
GLfloat backface_sign = 1;
switch (ctx->Polygon.CullFaceMode) {
case GL_BACK:
if (ctx->Polygon.FrontFace==GL_CCW)
backface_sign = -1;
break;
case GL_FRONT:
if (ctx->Polygon.FrontFace!=GL_CCW)
backface_sign = -1;
break;
default:
break;
};
FFB_CONTEXT(ctx)->backface_sign = backface_sign;
}
/***********************************************************************
* Choose triangle/quad rasterize functions *
***********************************************************************/
void ffbChooseTriangleState(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
GLuint ind = 0;
if (flags & DD_TRI_SMOOTH) {
fmesa->draw_tri = ffb_fallback_triangle;
fmesa->draw_quad = ffb_fallback_quad;
return;
}
if (flags & DD_FLATSHADE)
ind |= FFB_TRI_FLAT_BIT;
if (ctx->Polygon.CullFlag) {
if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
fmesa->draw_tri = ffb_nodraw_triangle;
fmesa->draw_quad = ffb_nodraw_quad;
return;
}
ind |= FFB_TRI_CULL_BIT;
ffb_update_cullsign(ctx);
} else
FFB_CONTEXT(ctx)->backface_sign = 0;
/* If blending or the alpha test is enabled we need to
* provide alpha components to the chip, else we can
* do without it and thus feed vertex data to the chip
* more efficiently.
*/
if (ctx->Color.BlendEnabled || ctx->Color.AlphaEnabled)
ind |= FFB_TRI_ALPHA_BIT;
fmesa->draw_tri = ffb_tri_tab[ind];
fmesa->draw_quad = ffb_quad_tab[ind];
}
static const GLenum reduced_prim[GL_POLYGON+1] = {
GL_POINTS,
GL_LINES,
GL_LINES,
GL_LINES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES
};
static void ffbRenderPrimitive(GLcontext *ctx, GLenum prim);
static void ffbRasterPrimitive(GLcontext *ctx, GLenum rprim);
/***********************************************************************
* Build render functions from dd templates *
***********************************************************************/
#define FFB_OFFSET_BIT 0x01
#define FFB_TWOSIDE_BIT 0x02
#define FFB_UNFILLED_BIT 0x04
#define FFB_MAX_TRIFUNC 0x08
static struct {
triangle_func triangle;
quad_func quad;
} rast_tab[FFB_MAX_TRIFUNC];
#define DO_OFFSET (IND & FFB_OFFSET_BIT)
#define DO_UNFILLED (IND & FFB_UNFILLED_BIT)
#define DO_TWOSIDE (IND & FFB_TWOSIDE_BIT)
#define DO_FLAT 0
#define DO_QUAD 1
#define DO_FULL_QUAD 1
#define DO_TRI 1
#define DO_LINE 0
#define DO_POINTS 0
#define QUAD( a, b, c, d ) fmesa->draw_quad( ctx, a, b, c, d )
#define TRI( a, b, c ) fmesa->draw_tri( ctx, a, b, c )
#define LINE( a, b ) fmesa->draw_line( ctx, a, b )
#define POINT( a ) fmesa->draw_point( ctx, a )
#define HAVE_BACK_COLORS 1
#define HAVE_RGBA 1
#define HAVE_SPEC 0
#define HAVE_HW_FLATSHADE 1
#define VERTEX ffb_vertex
#define TAB rast_tab
#define UNFILLED_TRI unfilled_tri
#define UNFILLED_QUAD unfilled_quad
#define DEPTH_SCALE (fmesa->depth_scale)
#define VERT_X(_v) (_v->x)
#define VERT_Y(_v) (_v->y)
#define VERT_Z(_v) (_v->z)
#define AREA_IS_CCW( a ) (a < fmesa->ffb_zero)
#define GET_VERTEX(e) (&fmesa->verts[e])
#define INSANE_VERTICES
#define VERT_SET_Z(v,val) ((v)->z = (val))
#define VERT_Z_ADD(v,val) ((v)->z += (val))
#define VERT_COPY_RGBA1( _v ) _v->color[0] = _v->color[1]
#define VERT_COPY_RGBA( v0, v1 ) v0->color[0] = v1->color[0]
#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->color[0]
#define VERT_RESTORE_RGBA( idx ) v[idx]->color[0] = color[idx]
#define LOCAL_VARS(n) \
ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = fmesa->driDrawable; \
ffb_color color[n]; \
(void) color; (void) dPriv;
/***********************************************************************
* Helpers for rendering unfilled primitives *
***********************************************************************/
#define RASTERIZE(x) if (fmesa->raster_primitive != reduced_prim[x]) \
ffbRasterPrimitive( ctx, reduced_prim[x] )
#define RENDER_PRIMITIVE fmesa->render_primitive
#define TAG(x) x
#include "tnl_dd/t_dd_unfilled.h"
/***********************************************************************
* Generate GL render functions *
***********************************************************************/
#define IND (0)
#define TAG(x) x
#include "tnl_dd/t_dd_tritmp.h"
#define IND (FFB_OFFSET_BIT)
#define TAG(x) x##_offset
#include "tnl_dd/t_dd_tritmp.h"
#define IND (FFB_TWOSIDE_BIT)
#define TAG(x) x##_twoside
#include "tnl_dd/t_dd_tritmp.h"
#define IND (FFB_TWOSIDE_BIT|FFB_OFFSET_BIT)
#define TAG(x) x##_twoside_offset
#include "tnl_dd/t_dd_tritmp.h"
#define IND (FFB_UNFILLED_BIT)
#define TAG(x) x##_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (FFB_OFFSET_BIT|FFB_UNFILLED_BIT)
#define TAG(x) x##_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (FFB_TWOSIDE_BIT|FFB_UNFILLED_BIT)
#define TAG(x) x##_twoside_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (FFB_TWOSIDE_BIT|FFB_OFFSET_BIT|FFB_UNFILLED_BIT)
#define TAG(x) x##_twoside_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"
static void init_rast_tab( void )
{
init();
init_offset();
init_twoside();
init_twoside_offset();
init_unfilled();
init_offset_unfilled();
init_twoside_unfilled();
init_twoside_offset_unfilled();
}
/**********************************************************************/
/* Render clipped primitives */
/**********************************************************************/
static void ffbRenderClippedPolygon(GLcontext *ctx, const GLuint *elts, GLuint n)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint prim = fmesa->render_primitive;
/* Render the new vertices as an unclipped polygon. */
{
GLuint *tmp = VB->Elts;
VB->Elts = (GLuint *)elts;
tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n, PRIM_BEGIN|PRIM_END);
VB->Elts = tmp;
}
/* Restore the render primitive. */
if (prim != GL_POLYGON)
tnl->Driver.Render.PrimitiveNotify(ctx, prim);
}
static void ffbRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.Line(ctx, ii, jj);
}
/**********************************************************************/
/* Render unclipped begin/end objects */
/**********************************************************************/
static void ffb_vb_noop(GLcontext *ctx, GLuint start, GLuint count, GLuint flags)
{
(void)(ctx && start && count && flags);
}
#define ELT(x) x
#define IND 0
#define TAG(x) x
#include "ffb_rendertmp.h"
#define IND (FFB_FLAT_BIT)
#define TAG(x) x##_flat
#include "ffb_rendertmp.h"
#define IND (FFB_ALPHA_BIT)
#define TAG(x) x##_alpha
#include "ffb_rendertmp.h"
#define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT)
#define TAG(x) x##_flat_alpha
#include "ffb_rendertmp.h"
#define IND (FFB_TRI_CULL_BIT)
#define TAG(x) x##_tricull
#include "ffb_rendertmp.h"
#define IND (FFB_FLAT_BIT | FFB_TRI_CULL_BIT)
#define TAG(x) x##_flat_tricull
#include "ffb_rendertmp.h"
#define IND (FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
#define TAG(x) x##_alpha_tricull
#include "ffb_rendertmp.h"
#define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
#define TAG(x) x##_flat_alpha_tricull
#include "ffb_rendertmp.h"
#undef ELT
#define ELT(x) elt[x]
#define IND 0
#define TAG(x) x##_elt
#include "ffb_rendertmp.h"
#define IND (FFB_FLAT_BIT)
#define TAG(x) x##_flat_elt
#include "ffb_rendertmp.h"
#define IND (FFB_ALPHA_BIT)
#define TAG(x) x##_alpha_elt
#include "ffb_rendertmp.h"
#define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT)
#define TAG(x) x##_flat_alpha_elt
#include "ffb_rendertmp.h"
#define IND (FFB_TRI_CULL_BIT)
#define TAG(x) x##_tricull_elt
#include "ffb_rendertmp.h"
#define IND (FFB_FLAT_BIT | FFB_TRI_CULL_BIT)
#define TAG(x) x##_flat_tricull_elt
#include "ffb_rendertmp.h"
#define IND (FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
#define TAG(x) x##_alpha_tricull_elt
#include "ffb_rendertmp.h"
#define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
#define TAG(x) x##_flat_alpha_tricull_elt
#include "ffb_rendertmp.h"
static void *render_tabs[MAX_FFB_RENDER_FUNCS];
static void *render_tabs_elt[MAX_FFB_RENDER_FUNCS];
static void init_render_tab(void)
{
int i;
render_tabs[0] = render_tab;
render_tabs[FFB_FLAT_BIT] = render_tab_flat;
render_tabs[FFB_ALPHA_BIT] = render_tab_alpha;
render_tabs[FFB_FLAT_BIT|FFB_ALPHA_BIT] = render_tab_flat_alpha;
render_tabs[FFB_TRI_CULL_BIT] = render_tab_tricull;
render_tabs[FFB_FLAT_BIT|FFB_TRI_CULL_BIT] = render_tab_flat_tricull;
render_tabs[FFB_ALPHA_BIT|FFB_TRI_CULL_BIT] = render_tab_alpha_tricull;
render_tabs[FFB_FLAT_BIT|FFB_ALPHA_BIT|FFB_TRI_CULL_BIT] =
render_tab_flat_alpha_tricull;
render_tabs_elt[0] = render_tab_elt;
render_tabs_elt[FFB_FLAT_BIT] = render_tab_flat_elt;
render_tabs_elt[FFB_ALPHA_BIT] = render_tab_alpha_elt;
render_tabs_elt[FFB_FLAT_BIT|FFB_ALPHA_BIT] = render_tab_flat_alpha_elt;
render_tabs_elt[FFB_TRI_CULL_BIT] = render_tab_tricull_elt;
render_tabs_elt[FFB_FLAT_BIT|FFB_TRI_CULL_BIT] = render_tab_flat_tricull_elt;
render_tabs_elt[FFB_ALPHA_BIT|FFB_TRI_CULL_BIT] = render_tab_alpha_tricull_elt;
render_tabs_elt[FFB_FLAT_BIT|FFB_ALPHA_BIT|FFB_TRI_CULL_BIT] =
render_tab_flat_alpha_tricull_elt;
for (i = 0; i < MAX_FFB_RENDER_FUNCS; i++) {
render_func *rf = render_tabs[i];
render_func *rfe = render_tabs_elt[i];
if (i & FFB_TRI_CULL_BIT) {
int from_idx = (i & ~FFB_TRI_CULL_BIT);
render_func *rf_from = render_tabs[from_idx];
render_func *rfe_from = render_tabs_elt[from_idx];
int j;
for (j = GL_POINTS; j < GL_TRIANGLES; j++) {
rf[j] = rf_from[j];
rfe[j] = rfe_from[j];
}
}
}
}
/**********************************************************************/
/* Choose render functions */
/**********************************************************************/
#ifdef FFB_RENDER_TRACE
static void ffbPrintRenderFlags(GLuint index, GLuint render_index)
{
fprintf(stderr,
"ffbChooseRenderState: "
"index(%s%s%s) "
"render_index(%s%s%s)\n",
((index & FFB_TWOSIDE_BIT) ? "twoside " : ""),
((index & FFB_OFFSET_BIT) ? "offset " : ""),
((index & FFB_UNFILLED_BIT) ? "unfilled " : ""),
((render_index & FFB_FLAT_BIT) ? "flat " : ""),
((render_index & FFB_ALPHA_BIT) ? "alpha " : ""),
((render_index & FFB_TRI_CULL_BIT) ? "tricull " : ""));
}
#endif
void ffbChooseRenderState(GLcontext *ctx)
{
GLuint flags = ctx->_TriangleCaps;
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint index = 0;
/* Per-primitive fallbacks and the selection of fmesa->draw_* are
* handled elsewhere.
*/
if (flags & DD_TRI_LIGHT_TWOSIDE)
index |= FFB_TWOSIDE_BIT;
if (flags & DD_TRI_OFFSET)
index |= FFB_OFFSET_BIT;
if (flags & DD_TRI_UNFILLED)
index |= FFB_UNFILLED_BIT;
tnl->Driver.Render.Triangle = rast_tab[index].triangle;
tnl->Driver.Render.Quad = rast_tab[index].quad;
if (index == 0) {
GLuint render_index = 0;
if (flags & DD_FLATSHADE)
render_index |= FFB_FLAT_BIT;
if (ctx->Color.BlendEnabled || ctx->Color.AlphaEnabled)
render_index |= FFB_ALPHA_BIT;
if (ctx->Polygon.CullFlag)
render_index |= FFB_TRI_CULL_BIT;
#ifdef FFB_RENDER_TRACE
ffbPrintRenderFlags(index, render_index);
#endif
tnl->Driver.Render.PrimTabVerts = render_tabs[render_index];
tnl->Driver.Render.PrimTabElts = render_tabs_elt[render_index];
} else {
#ifdef FFB_RENDER_TRACE
ffbPrintRenderFlags(index, 0);
#endif
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
}
tnl->Driver.Render.ClippedPolygon = ffbRenderClippedPolygon;
tnl->Driver.Render.ClippedLine = ffbRenderClippedLine;
}
static void ffbRunPipeline(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
if (fmesa->bad_fragment_attrs == 0 &&
fmesa->new_gl_state) {
if (fmesa->new_gl_state & _FFB_NEW_TRIANGLE)
ffbChooseTriangleState(ctx);
if (fmesa->new_gl_state & _FFB_NEW_LINE)
ffbChooseLineState(ctx);
if (fmesa->new_gl_state & _FFB_NEW_POINT)
ffbChoosePointState(ctx);
if (fmesa->new_gl_state & _FFB_NEW_RENDER)
ffbChooseRenderState(ctx);
if (fmesa->new_gl_state & _FFB_NEW_VERTEX)
ffbChooseVertexState(ctx);
fmesa->new_gl_state = 0;
}
_tnl_run_pipeline(ctx);
}
static void ffbRenderStart(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
LOCK_HARDWARE(fmesa);
fmesa->hw_locked = 1;
if (fmesa->state_dirty != 0)
ffbSyncHardware(fmesa);
}
static void ffbRenderFinish(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
UNLOCK_HARDWARE(fmesa);
fmesa->hw_locked = 0;
}
/* Even when doing full software rendering we need to
* wrap render{start,finish} so that the hardware is kept
* in sync (because multipass rendering changes the write
* buffer etc.)
*/
static void ffbSWRenderStart(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
LOCK_HARDWARE(fmesa);
fmesa->hw_locked = 1;
if (fmesa->state_dirty != 0)
ffbSyncHardware(fmesa);
}
static void ffbSWRenderFinish(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
UNLOCK_HARDWARE(fmesa);
fmesa->hw_locked = 0;
}
static void ffbRasterPrimitive(GLcontext *ctx, GLenum rprim)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
GLuint drawop, fbc, ppc;
int do_sw = 0;
fmesa->raster_primitive = rprim;
drawop = fmesa->drawop;
fbc = fmesa->fbc;
ppc = fmesa->ppc & ~(FFB_PPC_ZS_MASK | FFB_PPC_CS_MASK);
#ifdef STATE_TRACE
fprintf(stderr,
"ffbReducedPrimitiveChange: rprim(%d) ", rprim);
#endif
switch(rprim) {
case GL_POINTS:
#ifdef STATE_TRACE
fprintf(stderr, "GL_POINTS ");
#endif
if (fmesa->draw_point == ffb_fallback_point) {
do_sw = 1;
break;
}
if (ctx->Point.SmoothFlag) {
ppc |= (FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST);
drawop = FFB_DRAWOP_AADOT;
} else {
ppc |= (FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST);
drawop = FFB_DRAWOP_DOT;
}
break;
case GL_LINES:
#ifdef STATE_TRACE
fprintf(stderr, "GL_LINES ");
#endif
if (fmesa->draw_line == ffb_fallback_line) {
do_sw = 1;
break;
}
if (ctx->_TriangleCaps & DD_FLATSHADE) {
ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST;
} else {
ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR;
}
if (ctx->Line.SmoothFlag)
drawop = FFB_DRAWOP_AALINE;
else
drawop = FFB_DRAWOP_DDLINE;
break;
case GL_TRIANGLES:
#ifdef STATE_TRACE
fprintf(stderr, "GL_POLYGON ");
#endif
if (fmesa->draw_tri == ffb_fallback_triangle) {
do_sw = 1;
break;
}
ppc &= ~FFB_PPC_APE_MASK;
if (ctx->Polygon.StippleFlag)
ppc |= FFB_PPC_APE_ENABLE;
else
ppc |= FFB_PPC_APE_DISABLE;
if (ctx->_TriangleCaps & DD_FLATSHADE) {
ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST;
} else {
ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR;
}
drawop = FFB_DRAWOP_TRIANGLE;
break;
default:
#ifdef STATE_TRACE
fprintf(stderr, "unknown %d!\n", rprim);
#endif
return;
};
#ifdef STATE_TRACE
fprintf(stderr, "do_sw(%d) ", do_sw);
#endif
if (do_sw != 0) {
fbc &= ~(FFB_FBC_WB_C);
fbc &= ~(FFB_FBC_ZE_MASK | FFB_FBC_RGBE_MASK);
fbc |= FFB_FBC_ZE_OFF | FFB_FBC_RGBE_MASK;
ppc &= ~(FFB_PPC_XS_MASK | FFB_PPC_ABE_MASK |
FFB_PPC_DCE_MASK | FFB_PPC_APE_MASK);
ppc |= (FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR | FFB_PPC_XS_WID |
FFB_PPC_ABE_DISABLE | FFB_PPC_DCE_DISABLE |
FFB_PPC_APE_DISABLE);
} else {
fbc |= FFB_FBC_WB_C;
fbc &= ~(FFB_FBC_RGBE_MASK);
fbc |= FFB_FBC_RGBE_MASK;
ppc &= ~(FFB_PPC_ABE_MASK | FFB_PPC_XS_MASK);
if (ctx->Color.BlendEnabled) {
if ((rprim == GL_POINTS && !ctx->Point.SmoothFlag) ||
(rprim != GL_POINTS && ctx->_TriangleCaps & DD_FLATSHADE))
ppc |= FFB_PPC_ABE_ENABLE | FFB_PPC_XS_CONST;
else
ppc |= FFB_PPC_ABE_ENABLE | FFB_PPC_XS_VAR;
} else {
ppc |= FFB_PPC_ABE_DISABLE | FFB_PPC_XS_WID;
}
}
#ifdef STATE_TRACE
fprintf(stderr, "fbc(%08x) ppc(%08x)\n", fbc, ppc);
#endif
FFBFifo(fmesa, 4);
if (fmesa->drawop != drawop)
fmesa->regs->drawop = fmesa->drawop = drawop;
if (fmesa->fbc != fbc)
fmesa->regs->fbc = fmesa->fbc = fbc;
if (fmesa->ppc != ppc)
fmesa->regs->ppc = fmesa->ppc = ppc;
if (do_sw != 0) {
fmesa->regs->cmp =
(fmesa->cmp & ~(0xff<<16)) | (0x80 << 16);
} else
fmesa->regs->cmp = fmesa->cmp;
}
static void ffbRenderPrimitive(GLcontext *ctx, GLenum prim)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
GLuint rprim = reduced_prim[prim];
fmesa->render_primitive = prim;
if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
return;
if (fmesa->raster_primitive != rprim) {
ffbRasterPrimitive( ctx, rprim );
}
}
/**********************************************************************/
/* Transition to/from hardware rasterization. */
/**********************************************************************/
static char *fallbackStrings[] = {
"Fog enabled",
"Blend function",
"Blend ROP",
"Blend equation",
"Stencil",
"Texture",
"LIBGL_SOFTWARE_RENDERING"
};
static char *getFallbackString(GLuint bit)
{
int i = 0;
while (bit > 1) {
i++;
bit >>= 1;
}
return fallbackStrings[i];
}
void ffbFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint oldfallback = fmesa->bad_fragment_attrs;
if (mode) {
fmesa->bad_fragment_attrs |= bit;
if (oldfallback == 0) {
/* FFB_FIREVERTICES(fmesa); */
_swsetup_Wakeup( ctx );
if (fmesa->debugFallbacks)
fprintf(stderr, "FFB begin software fallback: 0x%x %s\n",
bit, getFallbackString(bit));
}
} else {
fmesa->bad_fragment_attrs &= ~bit;
if (oldfallback == bit) {
_swrast_flush( ctx );
tnl->Driver.Render.Start = ffbRenderStart;
tnl->Driver.Render.PrimitiveNotify = ffbRenderPrimitive;
tnl->Driver.Render.Finish = ffbRenderFinish;
fmesa->new_gl_state = ~0;
/* Just re-choose everything:
*/
ffbChooseVertexState(ctx);
ffbChooseRenderState(ctx);
ffbChooseTriangleState(ctx);
ffbChooseLineState(ctx);
ffbChoosePointState(ctx);
if (fmesa->debugFallbacks)
fprintf(stderr, "FFB end software fallback: 0x%x %s\n",
bit, getFallbackString(bit));
}
}
}
/**********************************************************************/
/* Initialization. */
/**********************************************************************/
void ffbDDInitRenderFuncs( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
SWcontext *swrast = SWRAST_CONTEXT(ctx);
static int firsttime = 1;
if (firsttime) {
init_rast_tab();
init_tri_tab();
init_render_tab();
firsttime = 0;
}
tnl->Driver.RunPipeline = ffbRunPipeline;
tnl->Driver.Render.Start = ffbRenderStart;
tnl->Driver.Render.Finish = ffbRenderFinish;
tnl->Driver.Render.PrimitiveNotify = ffbRenderPrimitive;
tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
swrast->Driver.SpanRenderStart = ffbSWRenderStart;
swrast->Driver.SpanRenderFinish = ffbSWRenderFinish;
}

View File

@ -0,0 +1,29 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_tris.h,v 1.2 2002/02/22 21:32:59 dawes Exp $ */
#ifndef _FFB_TRIS_H
#define _FFB_TRIS_H
extern void ffbDDInitRenderFuncs( GLcontext *ctx );
#define _FFB_NEW_RENDER (_DD_NEW_TRI_LIGHT_TWOSIDE | \
_DD_NEW_TRI_OFFSET | \
_DD_NEW_TRI_UNFILLED)
extern void ffbChooseRenderState(GLcontext *ctx);
#define _FFB_NEW_TRIANGLE (_DD_NEW_TRI_SMOOTH | \
_DD_NEW_FLATSHADE | \
_NEW_POLYGON | \
_NEW_COLOR)
extern void ffbChooseTriangleState(GLcontext *ctx);
extern void ffbFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
#define FALLBACK( ctx, bit, mode ) ffbFallback( ctx, bit, mode )
extern void ffb_fallback_line(GLcontext *, ffb_vertex *, ffb_vertex *);
extern void ffb_fallback_point(GLcontext *, ffb_vertex *);
#endif /* !(_FFB_TRIS_H) */

View File

@ -0,0 +1,239 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_tritmp.h,v 1.2 2002/02/22 21:32:59 dawes Exp $ */
static void TAG(ffb_triangle)( GLcontext *ctx,
ffb_vertex *v0,
ffb_vertex *v1,
ffb_vertex *v2 )
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_fbcPtr ffb = fmesa->regs;
#if (IND & FFB_TRI_FLAT_BIT)
GLuint const_fg;
#endif
FFB_DELAYED_VIEWPORT_VARS;
#ifdef TRI_DEBUG
fprintf(stderr, "FFB: ffb_triangle ["
#if (IND & FFB_TRI_CULL_BIT)
" CULL"
#endif
#if (IND & FFB_TRI_FLAT_BIT)
" FLAT"
#endif
#if (IND & FFB_TRI_ALPHA_BIT)
" ALPHA"
#endif
" ]\n");
#endif
#if (IND & FFB_TRI_CULL_BIT)
{ /* NOTE: These are not viewport transformed yet. */
GLfloat ex = v1->x - v0->x;
GLfloat ey = v1->y - v0->y;
GLfloat fx = v2->x - v0->x;
GLfloat fy = v2->y - v0->y;
GLfloat c = ex*fy-ey*fx;
/* Culled... */
if (c * fmesa->backface_sign > fmesa->ffb_zero)
return;
}
#endif
#if (IND & FFB_TRI_FLAT_BIT)
const_fg = FFB_PACK_CONST_UBYTE_ARGB_COLOR( v2->color[0] );
#ifdef TRI_DEBUG
fprintf(stderr, "FFB_tri: const_fg %08x (B[%f] G[%f] R[%f])\n",
const_fg,
FFB_2_30_FIXED_TO_FLOAT(v2->color[0].blue),
FFB_2_30_FIXED_TO_FLOAT(v2->color[0].green),
FFB_2_30_FIXED_TO_FLOAT(v2->color[0].red));
#endif
#endif
#if (IND & FFB_TRI_FLAT_BIT)
FFBFifo(fmesa, 1);
ffb->fg = const_fg;
#endif
#if (IND & FFB_TRI_FLAT_BIT)
FFBFifo(fmesa, 9);
#else
#if (IND & FFB_TRI_ALPHA_BIT)
FFBFifo(fmesa, 21);
#else
FFBFifo(fmesa, 18);
#endif
#endif
FFB_DUMP_VERTEX(v0);
#if !(IND & FFB_TRI_FLAT_BIT)
#if (IND & FFB_TRI_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v0);
#endif
ffb->red = FFB_GET_RED(v0);
ffb->green = FFB_GET_GREEN(v0);
ffb->blue = FFB_GET_BLUE(v0);
#endif
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_DUMP_VERTEX(v1);
#if !(IND & FFB_TRI_FLAT_BIT)
#if (IND & FFB_TRI_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v1);
#endif
ffb->red = FFB_GET_RED(v1);
ffb->green = FFB_GET_GREEN(v1);
ffb->blue = FFB_GET_BLUE(v1);
#endif
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
FFB_DUMP_VERTEX(v2);
#if !(IND & FFB_TRI_FLAT_BIT)
#if (IND & FFB_TRI_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v2);
#endif
ffb->red = FFB_GET_RED(v2);
ffb->green = FFB_GET_GREEN(v2);
ffb->blue = FFB_GET_BLUE(v2);
#endif
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_quad)(GLcontext *ctx,
ffb_vertex *v0,
ffb_vertex *v1,
ffb_vertex *v2,
ffb_vertex *v3 )
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_fbcPtr ffb = fmesa->regs;
#if (IND & FFB_TRI_FLAT_BIT)
GLuint const_fg;
#endif
FFB_DELAYED_VIEWPORT_VARS;
#ifdef TRI_DEBUG
fprintf(stderr, "FFB: ffb_quad ["
#if (IND & FFB_TRI_CULL_BIT)
" CULL"
#endif
#if (IND & FFB_TRI_FLAT_BIT)
" FLAT"
#endif
#if (IND & FFB_TRI_ALPHA_BIT)
" ALPHA"
#endif
" ]\n");
#endif /* TRI_DEBUG */
#if (IND & FFB_TRI_CULL_BIT)
{ /* NOTE: These are not viewport transformed yet. */
GLfloat ex = v2->x - v0->x;
GLfloat ey = v2->y - v0->y;
GLfloat fx = v3->x - v1->x;
GLfloat fy = v3->y - v1->y;
GLfloat c = ex*fy-ey*fx;
/* Culled... */
if (c * fmesa->backface_sign > fmesa->ffb_zero)
return;
}
#endif
#if (IND & FFB_TRI_FLAT_BIT)
const_fg = FFB_PACK_CONST_UBYTE_ARGB_COLOR( v3->color[0] );
#ifdef TRI_DEBUG
fprintf(stderr, "FFB_quad: const_fg %08x (B[%f] G[%f] R[%f])\n",
const_fg,
FFB_2_30_FIXED_TO_FLOAT(v3->color[0].blue),
FFB_2_30_FIXED_TO_FLOAT(v3->color[0].green),
FFB_2_30_FIXED_TO_FLOAT(v3->color[0].red));
#endif
#endif
#if (IND & FFB_TRI_FLAT_BIT)
FFBFifo(fmesa, 13);
ffb->fg = const_fg;
#else
#if (IND & FFB_TRI_ALPHA_BIT)
FFBFifo(fmesa, 28);
#else
FFBFifo(fmesa, 24);
#endif
#endif
FFB_DUMP_VERTEX(v0);
#if !(IND & FFB_TRI_FLAT_BIT)
#if (IND & FFB_TRI_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v0);
#endif
ffb->red = FFB_GET_RED(v0);
ffb->green = FFB_GET_GREEN(v0);
ffb->blue = FFB_GET_BLUE(v0);
#endif
ffb->z = FFB_GET_Z(v0);
ffb->ryf = FFB_GET_Y(v0);
ffb->rxf = FFB_GET_X(v0);
FFB_DUMP_VERTEX(v1);
#if !(IND & FFB_TRI_FLAT_BIT)
#if (IND & FFB_TRI_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v1);
#endif
ffb->red = FFB_GET_RED(v1);
ffb->green = FFB_GET_GREEN(v1);
ffb->blue = FFB_GET_BLUE(v1);
#endif
ffb->z = FFB_GET_Z(v1);
ffb->y = FFB_GET_Y(v1);
ffb->x = FFB_GET_X(v1);
FFB_DUMP_VERTEX(v2);
#if !(IND & FFB_TRI_FLAT_BIT)
#if (IND & FFB_TRI_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v2);
#endif
ffb->red = FFB_GET_RED(v2);
ffb->green = FFB_GET_GREEN(v2);
ffb->blue = FFB_GET_BLUE(v2);
#endif
ffb->z = FFB_GET_Z(v2);
ffb->y = FFB_GET_Y(v2);
ffb->x = FFB_GET_X(v2);
FFB_DUMP_VERTEX(v3);
#if !(IND & FFB_TRI_FLAT_BIT)
#if (IND & FFB_TRI_ALPHA_BIT)
ffb->alpha = FFB_GET_ALPHA(v3);
#endif
ffb->red = FFB_GET_RED(v3);
ffb->green = FFB_GET_GREEN(v3);
ffb->blue = FFB_GET_BLUE(v3);
#endif
ffb->z = FFB_GET_Z(v3);
ffb->dmyf = FFB_GET_Y(v3);
ffb->dmxf = FFB_GET_X(v3);
fmesa->ffbScreen->rp_active = 1;
}
static void TAG(ffb_init)(void)
{
ffb_tri_tab[IND] = TAG(ffb_triangle);
ffb_quad_tab[IND] = TAG(ffb_quad);
}
#undef IND
#undef TAG

View File

@ -0,0 +1,241 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vb.c,v 1.4 2002/02/22 21:32:59 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000, 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "ffb_xmesa.h"
#include "ffb_context.h"
#include "ffb_vb.h"
#include "mmath.h"
#include "imports.h"
#include "tnl/t_context.h"
#include "swrast_setup/swrast_setup.h"
#include "math/m_translate.h"
#undef VB_DEBUG
static void ffb_copy_pv_oneside(GLcontext *ctx, GLuint edst, GLuint esrc)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_vertex *dst = &fmesa->verts[edst];
ffb_vertex *src = &fmesa->verts[esrc];
#ifdef VB_DEBUG
fprintf(stderr, "ffb_copy_pv_oneside: edst(%d) esrc(%d)\n", edst, esrc);
#endif
dst->color[0].alpha = src->color[0].alpha;
dst->color[0].red = src->color[0].red;
dst->color[0].green = src->color[0].green;
dst->color[0].blue = src->color[0].blue;
}
static void ffb_copy_pv_twoside(GLcontext *ctx, GLuint edst, GLuint esrc)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
ffb_vertex *dst = &fmesa->verts[edst];
ffb_vertex *src = &fmesa->verts[esrc];
#ifdef VB_DEBUG
fprintf(stderr, "ffb_copy_pv_twoside: edst(%d) esrc(%d)\n", edst, esrc);
#endif
dst->color[0].alpha = src->color[0].alpha;
dst->color[0].red = src->color[0].red;
dst->color[0].green = src->color[0].green;
dst->color[0].blue = src->color[0].blue;
dst->color[1].alpha = src->color[1].alpha;
dst->color[1].red = src->color[1].red;
dst->color[1].green = src->color[1].green;
dst->color[1].blue = src->color[1].blue;
}
#define FFB_VB_RGBA_BIT 0x01
#define FFB_VB_XYZ_BIT 0x02
#define FFB_VB_TWOSIDE_BIT 0x04
#define FFB_VB_MAX 0x08
typedef void (*emit_func)(GLcontext *, GLuint, GLuint);
static struct {
emit_func emit;
interp_func interp;
} setup_tab[FFB_VB_MAX];
static void do_import(struct vertex_buffer *VB,
struct gl_client_array *to,
struct gl_client_array *from)
{
GLuint count = VB->Count;
if (!to->Ptr) {
to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLfloat), 32 );
to->Type = GL_FLOAT;
}
/* No need to transform the same value 3000 times. */
if (!from->StrideB) {
to->StrideB = 0;
count = 1;
} else
to->StrideB = 4 * sizeof(GLfloat);
_math_trans_4f((GLfloat (*)[4]) to->Ptr,
from->Ptr, from->StrideB,
from->Type, from->Size,
0, count);
}
static __inline__ void ffbImportColors(ffbContextPtr fmesa, GLcontext *ctx, int index)
{
struct gl_client_array *to = &fmesa->FloatColor;
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
do_import(VB, to, VB->ColorPtr[index]);
VB->ColorPtr[index] = to;
}
#define IND (FFB_VB_XYZ_BIT)
#define TAG(x) x##_w
#include "ffb_vbtmp.h"
#define IND (FFB_VB_RGBA_BIT)
#define TAG(x) x##_g
#include "ffb_vbtmp.h"
#define IND (FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT)
#define TAG(x) x##_wg
#include "ffb_vbtmp.h"
#define IND (FFB_VB_TWOSIDE_BIT)
#define TAG(x) x##_t
#include "ffb_vbtmp.h"
#define IND (FFB_VB_XYZ_BIT | FFB_VB_TWOSIDE_BIT)
#define TAG(x) x##_wt
#include "ffb_vbtmp.h"
#define IND (FFB_VB_RGBA_BIT | FFB_VB_TWOSIDE_BIT)
#define TAG(x) x##_gt
#include "ffb_vbtmp.h"
#define IND (FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT | FFB_VB_TWOSIDE_BIT)
#define TAG(x) x##_wgt
#include "ffb_vbtmp.h"
static void init_setup_tab( void )
{
init_w();
init_g();
init_wg();
init_t();
init_wt();
init_gt();
init_wgt();
}
#ifdef VB_DEBUG
static void ffbPrintSetupFlags(char *msg, GLuint flags)
{
fprintf(stderr, "%s(%x): %s%s%s\n",
msg,
(int)flags,
(flags & FFB_VB_XYZ_BIT) ? " xyz," : "",
(flags & FFB_VB_RGBA_BIT) ? " rgba," : "",
(flags & FFB_VB_TWOSIDE_BIT) ? " twoside," : "");
}
#endif
static void ffbDDBuildVertices(GLcontext *ctx, GLuint start, GLuint count,
GLuint newinputs)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
newinputs |= fmesa->setupnewinputs;
fmesa->setupnewinputs = 0;
if (!newinputs)
return;
if (newinputs & VERT_BIT_CLIP) {
setup_tab[fmesa->setupindex].emit(ctx, start, count);
} else {
GLuint ind = 0;
if (newinputs & VERT_BIT_COLOR0)
ind |= (FFB_VB_RGBA_BIT | FFB_VB_TWOSIDE_BIT);
ind &= fmesa->setupindex;
if (ind)
setup_tab[ind].emit(ctx, start, count);
}
}
void ffbChooseVertexState( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
int ind = FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT;
if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE)
ind |= FFB_VB_TWOSIDE_BIT;
#ifdef VB_DEBUG
ffbPrintSetupFlags("ffb: full setup function", ind);
#endif
fmesa->setupindex = ind;
tnl->Driver.Render.BuildVertices = ffbDDBuildVertices;
tnl->Driver.Render.Interp = setup_tab[ind].interp;
if (ind & FFB_VB_TWOSIDE_BIT)
tnl->Driver.Render.CopyPV = ffb_copy_pv_twoside;
else
tnl->Driver.Render.CopyPV = ffb_copy_pv_oneside;
}
void ffbInitVB( GLcontext *ctx )
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
GLuint size = TNL_CONTEXT(ctx)->vb.Size;
fmesa->verts = (ffb_vertex *)ALIGN_MALLOC(size * sizeof(ffb_vertex), 32);
{
static int firsttime = 1;
if (firsttime) {
init_setup_tab();
firsttime = 0;
}
}
}
void ffbFreeVB( GLcontext *ctx )
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
if (fmesa->verts) {
ALIGN_FREE(fmesa->verts);
fmesa->verts = 0;
}
}

View File

@ -0,0 +1,45 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vb.h,v 1.2 2002/02/22 21:32:59 dawes Exp $ */
#ifndef _FFB_VB_H
#define _FFB_VB_H
#include "mtypes.h"
#include "macros.h"
#include "tnl/t_context.h"
#include "swrast/swrast.h"
#define __FFB_2_30_FIXED_SCALE 1073741824.0f
#define FFB_2_30_FLOAT_TO_FIXED(X) \
(IROUND((X) * fmesa->ffb_2_30_fixed_scale))
#define FFB_2_30_FIXED_TO_FLOAT(X) \
(((GLfloat)(X)) * fmesa->ffb_one_over_2_30_fixed_scale)
#define __FFB_16_16_FIXED_SCALE 65536.0f
#define FFB_16_16_FLOAT_TO_FIXED(X) \
(IROUND((X) * fmesa->ffb_16_16_fixed_scale))
#define FFB_16_16_FIXED_TO_FLOAT(X) \
(((GLfloat)(X)) * fmesa->ffb_one_over_16_16_fixed_scale)
#define FFB_Z_FROM_FLOAT(VAL) FFB_2_30_FLOAT_TO_FIXED(VAL)
#define FFB_Z_TO_FLOAT(VAL) FFB_2_30_FIXED_TO_FLOAT(VAL)
#define FFB_XY_FROM_FLOAT(VAL) FFB_16_16_FLOAT_TO_FIXED(VAL)
#define FFB_XY_TO_FLOAT(VAL) FFB_16_16_FIXED_TO_FLOAT(VAL)
#define FFB_UBYTE_FROM_COLOR(VAL) ((IROUND((VAL) * fmesa->ffb_ubyte_color_scale)))
#define FFB_PACK_CONST_UBYTE_ARGB_COLOR(C) \
((FFB_UBYTE_FROM_COLOR(C.alpha) << 24) | \
(FFB_UBYTE_FROM_COLOR(C.blue) << 16) | \
(FFB_UBYTE_FROM_COLOR(C.green) << 8) | \
(FFB_UBYTE_FROM_COLOR(C.red) << 0))
#define FFB_COLOR_FROM_FLOAT(VAL) FFB_2_30_FLOAT_TO_FIXED(VAL)
#define _FFB_NEW_VERTEX (_DD_NEW_TRI_LIGHT_TWOSIDE)
extern void ffbDDSetupInit(void);
extern void ffbChooseVertexState(GLcontext *);
extern void ffbInitVB( GLcontext *ctx );
extern void ffbFreeVB( GLcontext *ctx );
#endif /* !(_FFB_VB_H) */

View File

@ -0,0 +1,177 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vbtmp.h,v 1.1 2002/02/22 21:32:59 dawes Exp $ */
static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
#if (IND & (FFB_VB_RGBA_BIT))
GLfloat (*col0)[4];
GLuint col0_stride;
#if (IND & (FFB_VB_TWOSIDE_BIT))
GLfloat (*col1)[4];
GLuint col1_stride;
#endif
#endif
#if (IND & FFB_VB_XYZ_BIT)
GLfloat (*proj)[4] = VB->NdcPtr->data;
GLuint proj_stride = VB->NdcPtr->stride;
const GLubyte *mask = VB->ClipMask;
#endif
ffb_vertex *v = &fmesa->verts[start];
int i;
#ifdef VB_DEBUG
fprintf(stderr, "FFB: ffb_emit ["
#if (IND & (FFB_VB_XYZ_BIT))
" XYZ"
#endif
#if (IND & (FFB_VB_RGBA_BIT))
" RGBA"
#endif
#if (IND & (FFB_VB_TWOSIDE_BIT))
" TWOSIDE"
#endif
"] start(%d) end(%d) import(%d)\n",
start, end,
VB->importable_data);
#endif
#if (IND & (FFB_VB_RGBA_BIT))
if (VB->ColorPtr[0]->Type != GL_FLOAT)
ffbImportColors(fmesa, ctx, 0);
#if (IND & (FFB_VB_TWOSIDE_BIT))
if (VB->ColorPtr[1]->Type != GL_FLOAT)
ffbImportColors(fmesa, ctx, 1);
#endif
col0 = (GLfloat (*)[4]) VB->ColorPtr[0]->Ptr;
col0_stride = VB->ColorPtr[0]->StrideB;
#if (IND & (FFB_VB_TWOSIDE_BIT))
col1 = (GLfloat (*)[4]) VB->ColorPtr[1]->Ptr;
col1_stride = VB->ColorPtr[1]->StrideB;
#endif
#endif
if (VB->importable_data) {
if (start) {
#if (IND & (FFB_VB_XYZ_BIT))
proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride);
#endif
#if (IND & (FFB_VB_RGBA_BIT))
col0 = (GLfloat (*)[4])((GLubyte *)col0 + start * col0_stride);
#if (IND & (FFB_VB_TWOSIDE_BIT))
col1 = (GLfloat (*)[4])((GLubyte *)col1 + start * col1_stride);
#endif
#endif
}
for (i = start; i < end; i++, v++) {
#if (IND & (FFB_VB_XYZ_BIT))
if (mask[i] == 0) {
v->x = proj[0][0];
v->y = proj[0][1];
v->z = proj[0][2];
}
proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride);
#endif
#if (IND & (FFB_VB_RGBA_BIT))
v->color[0].alpha = CLAMP(col0[0][3], 0.0f, 1.0f);
v->color[0].red = CLAMP(col0[0][0], 0.0f, 1.0f);
v->color[0].green = CLAMP(col0[0][1], 0.0f, 1.0f);
v->color[0].blue = CLAMP(col0[0][2], 0.0f, 1.0f);
col0 = (GLfloat (*)[4])((GLubyte *)col0 + col0_stride);
#if (IND & (FFB_VB_TWOSIDE_BIT))
v->color[1].alpha = CLAMP(col1[0][3], 0.0f, 1.0f);
v->color[1].red = CLAMP(col1[0][0], 0.0f, 1.0f);
v->color[1].green = CLAMP(col1[0][1], 0.0f, 1.0f);
v->color[1].blue = CLAMP(col1[0][2], 0.0f, 1.0f);
col1 = (GLfloat (*)[4])((GLubyte *)col1 + col1_stride);
#endif
#endif
}
} else {
for (i = start; i < end; i++, v++) {
#if (IND & (FFB_VB_XYZ_BIT))
if (mask[i] == 0) {
v->x = proj[i][0];
v->y = proj[i][1];
v->z = proj[i][2];
}
#endif
#if (IND & (FFB_VB_RGBA_BIT))
v->color[0].alpha = CLAMP(col0[i][3], 0.0f, 1.0f);
v->color[0].red = CLAMP(col0[i][0], 0.0f, 1.0f);
v->color[0].green = CLAMP(col0[i][1], 0.0f, 1.0f);
v->color[0].blue = CLAMP(col0[i][2], 0.0f, 1.0f);
#if (IND & (FFB_VB_TWOSIDE_BIT))
v->color[1].alpha = CLAMP(col1[i][3], 0.0f, 1.0f);
v->color[1].red = CLAMP(col1[i][0], 0.0f, 1.0f);
v->color[1].green = CLAMP(col1[i][1], 0.0f, 1.0f);
v->color[1].blue = CLAMP(col1[i][2], 0.0f, 1.0f);
#endif
#endif
}
}
}
static void TAG(interp)(GLcontext *ctx, GLfloat t,
GLuint edst, GLuint eout, GLuint ein,
GLboolean force_boundary)
{
#if (IND & (FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT))
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
#endif
#if (IND & (FFB_VB_XYZ_BIT))
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
const GLfloat *dstclip = VB->ClipPtr->data[edst];
GLfloat oow = 1.0 / dstclip[3];
#endif
#if (IND & (FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT))
ffb_vertex *dst = &fmesa->verts[edst];
#endif
#if (IND & (FFB_VB_RGBA_BIT))
ffb_vertex *in = &fmesa->verts[eout];
ffb_vertex *out = &fmesa->verts[ein];
#endif
#ifdef VB_DEBUG
fprintf(stderr, "FFB: ffb_interp ["
#if (IND & (FFB_VB_XYZ_BIT))
" XYZ"
#endif
#if (IND & (FFB_VB_RGBA_BIT))
" RGBA"
#endif
#if (IND & (FFB_VB_TWOSIDE_BIT))
" TWOSIDE"
#endif
"] edst(%d) eout(%d) ein(%d)\n",
edst, eout, ein);
#endif
#if (IND & (FFB_VB_XYZ_BIT))
dst->x = dstclip[0] * oow;
dst->y = dstclip[1] * oow;
dst->z = dstclip[2] * oow;
#endif
#if (IND & (FFB_VB_RGBA_BIT))
INTERP_F(t, dst->color[0].alpha, out->color[0].alpha, in->color[0].alpha);
INTERP_F(t, dst->color[0].red, out->color[0].red, in->color[0].red);
INTERP_F(t, dst->color[0].green, out->color[0].green, in->color[0].green);
INTERP_F(t, dst->color[0].blue, out->color[0].blue, in->color[0].blue);
#if (IND & (FFB_VB_TWOSIDE_BIT))
INTERP_F(t, dst->color[1].alpha, out->color[1].alpha, in->color[1].alpha);
INTERP_F(t, dst->color[1].red, out->color[1].red, in->color[1].red);
INTERP_F(t, dst->color[1].green, out->color[1].green, in->color[1].green);
INTERP_F(t, dst->color[1].blue, out->color[1].blue, in->color[1].blue);
#endif
#endif
}
static void TAG(init)(void)
{
setup_tab[IND].emit = TAG(emit);
setup_tab[IND].interp = TAG(interp);
}
#undef IND
#undef TAG

View File

@ -0,0 +1,429 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vtxfmt.c,v 1.1 2002/02/22 21:32:59 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#include "glheader.h"
#include "api_noop.h"
#include "context.h"
#include "light.h"
#include "macros.h"
#include "imports.h"
#include "mmath.h"
#include "mtypes.h"
#include "simple_list.h"
#include "vtxfmt.h"
#include "ffb_xmesa.h"
#include "ffb_context.h"
#include "ffb_vb.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "ffb_vtxfmt.h"
#ifndef __GNUC__
#define __inline /**/
#endif
#define TNL_VERTEX ffbTnlVertex
#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A)))
#define INTERP_RGBA(t, out, a, b) \
do { \
GLint i; \
for ( i = 0 ; i < 4 ; i++ ) { \
GLfloat fa = a[i]; \
GLfloat fb = b[i]; \
out[i] = LINTERP( t, fa, fb ); \
} \
} while (0)
/* Color functions: */
static __inline void ffb_recalc_base_color(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
struct gl_light *light;
COPY_3V(fmesa->vtx_state.light.base_color, ctx->Light._BaseColor[0]);
foreach (light, &ctx->Light.EnabledList) {
ACC_3V(fmesa->vtx_state.light.base_color,
light->_MatAmbient[0]);
}
fmesa->vtx_state.light.base_alpha = ctx->Light._BaseAlpha[0];
}
#define GET_CURRENT \
GET_CURRENT_CONTEXT(ctx); \
ffbContextPtr fmesa = FFB_CONTEXT(ctx)
#define CURRENT_COLOR(COMP) fmesa->vtx_state.current.color[COMP]
#define CURRENT_SPECULAR(COMP) fmesa->vtx_state.current.specular[COMP]
#define COLOR_IS_FLOAT
#define RECALC_BASE_COLOR(ctx) ffb_recalc_base_color(ctx)
#define TAG(x) ffb_##x
#include "tnl_dd/t_dd_imm_capi.h"
/* Normal functions: */
struct ffb_norm_tab {
void (*normal3f_multi)(GLfloat x, GLfloat y, GLfloat z);
void (*normal3fv_multi)(const GLfloat *v);
void (*normal3f_single)(GLfloat x, GLfloat y, GLfloat z);
void (*normal3fv_single)(const GLfloat *v);
};
static struct ffb_norm_tab norm_tab[0x4];
#define HAVE_HW_LIGHTING 0
#define GET_CURRENT_VERTEX \
GET_CURRENT_CONTEXT(ctx); \
ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
ffbTnlVertexPtr v = fmesa->imm.v0
#define CURRENT_NORMAL fmesa->vtx_state.current.normal
#define BASE_COLOR fmesa->vtx_state.light.base_color
#define BASE_ALPHA fmesa->vtx_state.light.base_alpha
#define VERT_COLOR( COMP ) v->color[COMP]
#define VERT_COLOR_IS_FLOAT
#define IND (0)
#define TAG(x) ffb_##x
#define PRESERVE_NORMAL_DEFS
#include "tnl_dd/t_dd_imm_napi.h"
#define IND (NORM_RESCALE)
#define TAG(x) ffb_##x##_rescale
#define PRESERVE_NORMAL_DEFS
#include "tnl_dd/t_dd_imm_napi.h"
#define IND (NORM_NORMALIZE)
#define TAG(x) ffb_##x##_normalize
#include "tnl_dd/t_dd_imm_napi.h"
static void ffb_init_norm_funcs(void)
{
ffb_init_norm();
ffb_init_norm_rescale();
ffb_init_norm_normalize();
}
static void choose_normals(void)
{
GET_CURRENT_CONTEXT(ctx);
GLuint index;
if (ctx->Light.Enabled) {
if (ctx->Transform.Normalize) {
index = NORM_NORMALIZE;
} else if (!ctx->Transform.RescaleNormals &&
ctx->_ModelViewInvScale != 1.0) {
index = NORM_RESCALE;
} else {
index = 0;
}
if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev) {
ctx->Exec->Normal3f = norm_tab[index].normal3f_single;
ctx->Exec->Normal3fv = norm_tab[index].normal3fv_single;
} else {
ctx->Exec->Normal3f = norm_tab[index].normal3f_multi;
ctx->Exec->Normal3fv = norm_tab[index].normal3fv_multi;
}
} else {
ctx->Exec->Normal3f = _mesa_noop_Normal3f;
ctx->Exec->Normal3fv = _mesa_noop_Normal3fv;
}
}
static void ffb_choose_Normal3f(GLfloat x, GLfloat y, GLfloat z)
{
choose_normals();
glNormal3f(x, y, z);
}
static void ffb_choose_Normal3fv(const GLfloat *v)
{
choose_normals();
glNormal3fv(v);
}
/* Vertex functions: */
#define GET_CURRENT_VERTEX \
GET_CURRENT_CONTEXT(ctx); \
ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
ffbTnlVertexPtr v = fmesa->imm.v0
#define CURRENT_VERTEX v->obj
#define SAVE_VERTEX fmesa->imm.save_vertex(ctx, v)
#define TAG(x) ffb_##x
#include "tnl_dd/t_dd_imm_vapi.h"
struct ffb_vert_tab {
void (*save_vertex)(GLcontext *ctx, ffbTnlVertexPtr v);
void (*interpolate_vertex)(GLfloat t,
ffbTnlVertex *O,
const ffbTnlVertex *I,
const ffbTnlVertex *J);
};
static struct ffb_vert_tab vert_tab[0xf];
#define VTX_NORMAL 0x0
#define VTX_RGBA 0x1
#define LOCAL_VARS \
ffbContextPtr fmesa = FFB_CONTEXT(ctx)
#define CURRENT_COLOR fmesa->vtx_state.current.color
#define COLOR_IS_FLOAT
#define FLUSH_VERTEX fmesa->imm.flush_vertex( ctx, v );
#define IND (VTX_NORMAL)
#define TAG(x) ffb_##x##_NORMAL
#define PRESERVE_VERTEX_DEFS
#include "tnl_dd/t_dd_imm_vertex.h"
#define IND (VTX_RGBA)
#define TAG(x) ffb_##x##_RGBA
#include "tnl_dd/t_dd_imm_vertex.h"
static void ffb_init_vert_funcs( void )
{
ffb_init_vert_NORMAL();
ffb_init_vert_RGBA();
}
#define LOCAL_VARS \
ffbContextPtr fmesa = FFB_CONTEXT(ctx)
#define GET_INTERP_FUNC \
ffb_interp_func interp = fmesa->imm.interp
#define FLUSH_VERTEX fmesa->imm.flush_vertex
#define IMM_VERTEX( V ) fmesa->imm.V
#define IMM_VERTICES( n ) fmesa->imm.vertices[n]
#define EMIT_VERTEX_USES_HWREGS
/* XXX Implement me XXX */
#define EMIT_VERTEX_TRI(VTX0, VTX1, VTX2) \
do { } while (0)
#define EMIT_VERTEX_LINE(VTX0, VTX1) \
do { } while (0)
#define EMIT_VERTEX_POINT(VTX0) \
do { } while (0)
#define TAG(x) ffb_##x
#include "tnl_dd/t_dd_imm_primtmp.h"
/* Bzzt: Material changes are lost on fallback. */
static void ffb_Materialfv(GLenum face, GLenum pname,
const GLfloat *params)
{
GET_CURRENT_CONTEXT(ctx);
_mesa_noop_Materialfv( face, pname, params );
ffb_recalc_base_color( ctx );
}
/* Fallback functions: */
static void ffb_do_fallback(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
struct ffb_current_state *current = &fmesa->vtx_state.current;
/* Tell tnl to restore its exec vtxfmt, rehook its driver callbacks
* and revive internal state that depended on those callbacks:
*/
_tnl_wakeup_exec(ctx);
/* Replay enough vertices that the current primitive is continued
* correctly:
*/
if (fmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END )
glBegin(fmesa->imm.prim);
if (ctx->Light.Enabled) {
glColor4fv(ctx->Current.Color); /* Catch ColorMaterial */
glNormal3fv(current->normal);
} else {
glColor4fv(current->color);
}
}
#define PRE_LOOPBACK( FUNC ) do { \
GET_CURRENT_CONTEXT(ctx); \
ffb_do_fallback( ctx ); \
} while (0)
#define TAG(x) ffb_fallback_##x
#include "vtxfmt_tmp.h"
static void ffb_Begin(GLenum prim)
{
GET_CURRENT_CONTEXT(ctx);
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
if (prim > GL_POLYGON) {
_mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
return;
}
if (fmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
return;
}
ctx->Driver.NeedFlush |= (FLUSH_STORED_VERTICES |
FLUSH_UPDATE_CURRENT);
fmesa->imm.prim = prim;
fmesa->imm.v0 = &fmesa->imm.vertices[0];
fmesa->imm.save_vertex = ffb_save_vertex_RGBA;
fmesa->imm.flush_vertex = ffb_flush_tab[prim];
/* XXX Lock hardware, update FBC, PPC, DRAWOP, etc. XXX */
}
static void ffb_End(void)
{
GET_CURRENT_CONTEXT(ctx);
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
if (fmesa->imm.prim == PRIM_OUTSIDE_BEGIN_END) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
return;
}
fmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END;
ctx->Driver.NeedFlush &= ~(FLUSH_STORED_VERTICES |
FLUSH_UPDATE_CURRENT);
/* XXX Unlock hardware, etc. */
}
void ffbInitTnlModule(GLcontext *ctx)
{
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
GLvertexformat *vfmt = &(fmesa->imm.vtxfmt);
/* Work in progress... */
return;
ffb_init_norm_funcs();
ffb_init_vert_funcs();
MEMSET(vfmt, 0, sizeof(GLvertexformat));
/* Handled fully in supported states: */
vfmt->ArrayElement = NULL; /* FIXME: ... */
vfmt->Color3f = ffb_choose_Color3f;
vfmt->Color3fv = ffb_choose_Color3fv;
vfmt->Color3ub = ffb_choose_Color3ub;
vfmt->Color3ubv = ffb_choose_Color3ubv;
vfmt->Color4f = ffb_choose_Color4f;
vfmt->Color4fv = ffb_choose_Color4fv;
vfmt->Color4ub = ffb_choose_Color4ub;
vfmt->Color4ubv = ffb_choose_Color4ubv;
vfmt->FogCoordfvEXT = ffb_FogCoordfvEXT;
vfmt->FogCoordfEXT = ffb_FogCoordfEXT;
vfmt->Materialfv = ffb_Materialfv;
vfmt->MultiTexCoord1fARB = ffb_fallback_MultiTexCoord1fARB;
vfmt->MultiTexCoord1fvARB = ffb_fallback_MultiTexCoord1fvARB;
vfmt->MultiTexCoord2fARB = ffb_fallback_MultiTexCoord2fARB;
vfmt->MultiTexCoord2fvARB = ffb_fallback_MultiTexCoord2fvARB;
vfmt->MultiTexCoord3fARB = ffb_fallback_MultiTexCoord3fARB;
vfmt->MultiTexCoord3fvARB = ffb_fallback_MultiTexCoord3fvARB;
vfmt->MultiTexCoord4fARB = ffb_fallback_MultiTexCoord4fARB;
vfmt->MultiTexCoord4fvARB = ffb_fallback_MultiTexCoord4fvARB;
vfmt->Normal3f = ffb_choose_Normal3f;
vfmt->Normal3fv = ffb_choose_Normal3fv;
vfmt->SecondaryColor3ubEXT = ffb_SecondaryColor3ubEXT;
vfmt->SecondaryColor3ubvEXT = ffb_SecondaryColor3ubvEXT;
vfmt->SecondaryColor3fEXT = ffb_SecondaryColor3fEXT;
vfmt->SecondaryColor3fvEXT = ffb_SecondaryColor3fvEXT;
vfmt->TexCoord1f = ffb_fallback_TexCoord1f;
vfmt->TexCoord1fv = ffb_fallback_TexCoord1fv;
vfmt->TexCoord2f = ffb_fallback_TexCoord2f;
vfmt->TexCoord2fv = ffb_fallback_TexCoord2fv;
vfmt->TexCoord3f = ffb_fallback_TexCoord3f;
vfmt->TexCoord3fv = ffb_fallback_TexCoord3fv;
vfmt->TexCoord4f = ffb_fallback_TexCoord4f;
vfmt->TexCoord4fv = ffb_fallback_TexCoord4fv;
vfmt->Vertex2f = ffb_Vertex2f;
vfmt->Vertex2fv = ffb_Vertex2fv;
vfmt->Vertex3f = ffb_Vertex3f;
vfmt->Vertex3fv = ffb_Vertex3fv;
vfmt->Vertex4f = ffb_Vertex4f;
vfmt->Vertex4fv = ffb_Vertex4fv;
vfmt->Begin = ffb_Begin;
vfmt->End = ffb_End;
vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
vfmt->DrawArrays = NULL;
vfmt->DrawElements = NULL;
vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements; /* discard range */
/* Not active in supported states; just keep ctx->Current uptodate: */
vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
vfmt->Indexi = _mesa_noop_Indexi;
vfmt->Indexiv = _mesa_noop_Indexiv;
/* Active but unsupported -- fallback if we receive these:
*
* All of these fallbacks can be fixed with additional code, except
* CallList, unless we build a play_immediate_noop() command which
* turns an immediate back into glBegin/glEnd commands...
*/
vfmt->CallList = ffb_fallback_CallList;
vfmt->EvalCoord1f = ffb_fallback_EvalCoord1f;
vfmt->EvalCoord1fv = ffb_fallback_EvalCoord1fv;
vfmt->EvalCoord2f = ffb_fallback_EvalCoord2f;
vfmt->EvalCoord2fv = ffb_fallback_EvalCoord2fv;
vfmt->EvalMesh1 = ffb_fallback_EvalMesh1;
vfmt->EvalMesh2 = ffb_fallback_EvalMesh2;
vfmt->EvalPoint1 = ffb_fallback_EvalPoint1;
vfmt->EvalPoint2 = ffb_fallback_EvalPoint2;
vfmt->prefer_float_colors = GL_TRUE;
fmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END;
/* THIS IS A HACK! */
_mesa_install_exec_vtxfmt( ctx, vfmt );
}

View File

@ -0,0 +1,8 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_vtxfmt.h,v 1.1 2002/02/22 21:32:59 dawes Exp $ */
#ifndef _FFB_VTXFMT_H
#define _FFB_VTXFMT_H
extern void ffbInitTnlModule(GLcontext *);
#endif /* !(_FFB_VTXFMT_H) */

View File

@ -0,0 +1,593 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_xmesa.c,v 1.4 2002/02/22 21:32:59 dawes Exp $
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000, 2001 David S. Miller
*
* 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
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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.
*
*
* David S. Miller <davem@redhat.com>
*/
#ifdef GLX_DIRECT_RENDERING
#include "ffb_xmesa.h"
#include "context.h"
#include "matrix.h"
#include "simple_list.h"
#include "imports.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "array_cache/acache.h"
#include "ffb_context.h"
#include "ffb_dd.h"
#include "ffb_span.h"
#include "ffb_depth.h"
#include "ffb_stencil.h"
#include "ffb_clear.h"
#include "ffb_vb.h"
#include "ffb_tris.h"
#include "ffb_lines.h"
#include "ffb_points.h"
#include "ffb_state.h"
#include "ffb_tex.h"
#include "ffb_lock.h"
#include "ffb_vtxfmt.h"
#include "ffb_bitmap.h"
static GLboolean
ffbInitDriver(__DRIscreenPrivate *sPriv)
{
ffbScreenPrivate *ffbScreen;
FFBDRIPtr gDRIPriv = (FFBDRIPtr) sPriv->pDevPriv;
if (getenv("LIBGL_FORCE_XSERVER"))
return GL_FALSE;
/* Allocate the private area. */
ffbScreen = (ffbScreenPrivate *) Xmalloc(sizeof(ffbScreenPrivate));
if (!ffbScreen)
return GL_FALSE;
/* Map FBC registers. */
if (drmMap(sPriv->fd,
gDRIPriv->hFbcRegs,
gDRIPriv->sFbcRegs,
&gDRIPriv->mFbcRegs)) {
Xfree(ffbScreen);
return GL_FALSE;
}
ffbScreen->regs = (ffb_fbcPtr) gDRIPriv->mFbcRegs;
/* Map ramdac registers. */
if (drmMap(sPriv->fd,
gDRIPriv->hDacRegs,
gDRIPriv->sDacRegs,
&gDRIPriv->mDacRegs)) {
drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
Xfree(ffbScreen);
return GL_FALSE;
}
ffbScreen->dac = (ffb_dacPtr) gDRIPriv->mDacRegs;
/* Map "Smart" framebuffer views. */
if (drmMap(sPriv->fd,
gDRIPriv->hSfb8r,
gDRIPriv->sSfb8r,
&gDRIPriv->mSfb8r)) {
drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
drmUnmap(gDRIPriv->mDacRegs, gDRIPriv->sDacRegs);
Xfree(ffbScreen);
return GL_FALSE;
}
ffbScreen->sfb8r = (volatile char *) gDRIPriv->mSfb8r;
if (drmMap(sPriv->fd,
gDRIPriv->hSfb32,
gDRIPriv->sSfb32,
&gDRIPriv->mSfb32)) {
drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
drmUnmap(gDRIPriv->mDacRegs, gDRIPriv->sDacRegs);
drmUnmap(gDRIPriv->mSfb8r, gDRIPriv->sSfb8r);
Xfree(ffbScreen);
return GL_FALSE;
}
ffbScreen->sfb32 = (volatile char *) gDRIPriv->mSfb32;
if (drmMap(sPriv->fd,
gDRIPriv->hSfb64,
gDRIPriv->sSfb64,
&gDRIPriv->mSfb64)) {
drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
drmUnmap(gDRIPriv->mDacRegs, gDRIPriv->sDacRegs);
drmUnmap(gDRIPriv->mSfb8r, gDRIPriv->sSfb8r);
drmUnmap(gDRIPriv->mSfb32, gDRIPriv->sSfb32);
Xfree(ffbScreen);
return GL_FALSE;
}
ffbScreen->sfb64 = (volatile char *) gDRIPriv->mSfb64;
ffbScreen->fifo_cache = 0;
ffbScreen->rp_active = 0;
ffbScreen->sPriv = sPriv;
sPriv->private = (void *) ffbScreen;
ffbDDLinefuncInit();
ffbDDPointfuncInit();
return GL_TRUE;
}
static void
ffbDestroyScreen(__DRIscreenPrivate *sPriv)
{
ffbScreenPrivate *ffbScreen = sPriv->private;
FFBDRIPtr gDRIPriv = (FFBDRIPtr) sPriv->pDevPriv;
drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
drmUnmap(gDRIPriv->mDacRegs, gDRIPriv->sDacRegs);
drmUnmap(gDRIPriv->mSfb8r, gDRIPriv->sSfb8r);
drmUnmap(gDRIPriv->mSfb32, gDRIPriv->sSfb32);
drmUnmap(gDRIPriv->mSfb64, gDRIPriv->sSfb64);
Xfree(ffbScreen);
}
static const struct gl_pipeline_stage *ffb_pipeline[] = {
&_tnl_vertex_transform_stage,
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
/* REMOVE: fog coord stage */
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
/* REMOVE: point attenuation stage */
&_tnl_render_stage,
0,
};
/* Create and initialize the Mesa and driver specific context data */
static GLboolean
ffbCreateContext(const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate)
{
ffbContextPtr fmesa;
GLcontext *ctx, *shareCtx;
__DRIscreenPrivate *sPriv;
ffbScreenPrivate *ffbScreen;
char *debug;
/* Allocate ffb context */
fmesa = (ffbContextPtr) CALLOC(sizeof(ffbContextRec));
if (!fmesa)
return GL_FALSE;
/* Allocate Mesa context */
if (sharedContextPrivate)
shareCtx = ((ffbContextPtr) sharedContextPrivate)->glCtx;
else
shareCtx = NULL;
fmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, fmesa, GL_TRUE);
if (!fmesa->glCtx) {
FREE(fmesa);
return GL_FALSE;
}
driContextPriv->driverPrivate = fmesa;
ctx = fmesa->glCtx;
sPriv = driContextPriv->driScreenPriv;
ffbScreen = (ffbScreenPrivate *) sPriv->private;
/* Dri stuff. */
fmesa->hHWContext = driContextPriv->hHWContext;
fmesa->driFd = sPriv->fd;
fmesa->driHwLock = &sPriv->pSAREA->lock;
fmesa->ffbScreen = ffbScreen;
fmesa->driScreen = sPriv;
fmesa->ffb_sarea = FFB_DRISHARE(sPriv->pSAREA);
/* Register and framebuffer hw pointers. */
fmesa->regs = ffbScreen->regs;
fmesa->sfb32 = ffbScreen->sfb32;
ffbDDInitContextHwState(ctx);
/* Default clear and depth colors. */
{
GLubyte r = (GLint) (ctx->Color.ClearColor[0] * 255.0F);
GLubyte g = (GLint) (ctx->Color.ClearColor[1] * 255.0F);
GLubyte b = (GLint) (ctx->Color.ClearColor[2] * 255.0F);
fmesa->clear_pixel = ((r << 0) |
(g << 8) |
(b << 16));
}
fmesa->clear_depth = Z_FROM_MESA(ctx->Depth.Clear * 4294967295.0f);
fmesa->clear_stencil = ctx->Stencil.Clear & 0xf;
/* No wide points. */
ctx->Const.MinPointSize = 1.0;
ctx->Const.MinPointSizeAA = 1.0;
ctx->Const.MaxPointSize = 1.0;
ctx->Const.MaxPointSizeAA = 1.0;
/* Disable wide lines as we can't antialias them correctly in
* hardware.
*/
ctx->Const.MinLineWidth = 1.0;
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = 1.0;
ctx->Const.MaxLineWidthAA = 1.0;
ctx->Const.LineWidthGranularity = 1.0;
/* Instead of having GCC emit these constants a zillion times
* everywhere in the driver, put them here.
*/
fmesa->ffb_2_30_fixed_scale = __FFB_2_30_FIXED_SCALE;
fmesa->ffb_one_over_2_30_fixed_scale = (1.0 / __FFB_2_30_FIXED_SCALE);
fmesa->ffb_16_16_fixed_scale = __FFB_16_16_FIXED_SCALE;
fmesa->ffb_one_over_16_16_fixed_scale = (1.0 / __FFB_16_16_FIXED_SCALE);
fmesa->ffb_ubyte_color_scale = 255.0f;
fmesa->ffb_zero = 0.0f;
fmesa->debugFallbacks = GL_FALSE;
debug = getenv("LIBGL_DEBUG");
if (debug && strstr(debug, "fallbacks"))
fmesa->debugFallbacks = GL_TRUE;
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext( ctx );
_ac_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
/* All of this need only be done once for a new context. */
ffbDDExtensionsInit(ctx);
ffbDDInitDriverFuncs(ctx);
ffbDDInitStateFuncs(ctx);
ffbDDInitSpanFuncs(ctx);
ffbDDInitDepthFuncs(ctx);
ffbDDInitStencilFuncs(ctx);
ffbDDInitRenderFuncs(ctx);
ffbDDInitTexFuncs(ctx);
ffbDDInitBitmapFuncs(ctx);
ffbInitVB(ctx);
ffbInitTnlModule(ctx);
_tnl_destroy_pipeline(ctx);
_tnl_install_pipeline(ctx, ffb_pipeline);
return GL_TRUE;
}
static void
ffbDestroyContext(__DRIcontextPrivate *driContextPriv)
{
ffbContextPtr fmesa = (ffbContextPtr) driContextPriv->driverPrivate;
if (fmesa) {
ffbFreeVB(fmesa->glCtx);
_swsetup_DestroyContext( fmesa->glCtx );
_tnl_DestroyContext( fmesa->glCtx );
_ac_DestroyContext( fmesa->glCtx );
_swrast_DestroyContext( fmesa->glCtx );
/* free the Mesa context */
fmesa->glCtx->DriverCtx = NULL;
_mesa_destroy_context(fmesa->glCtx);
FREE(fmesa);
}
}
/* Create and initialize the Mesa and driver specific pixmap buffer data */
static GLboolean
ffbCreateBuffer(__DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
if (isPixmap) {
return GL_FALSE; /* not implemented */
}
else {
driDrawPriv->driverPrivate = (void *)
_mesa_create_framebuffer(mesaVis,
GL_FALSE, /* software depth buffer? */
mesaVis->stencilBits > 0,
mesaVis->accumRedBits > 0,
mesaVis->alphaBits > 0);
return (driDrawPriv->driverPrivate != NULL);
}
}
static void
ffbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
}
#define USE_FAST_SWAP
static void
ffbSwapBuffers( __DRIdrawablePrivate *dPriv )
{
ffbContextPtr fmesa = (ffbContextPtr) dPriv->driContextPriv->driverPrivate;
unsigned int fbc, wid, wid_reg_val, dac_db_bit;
unsigned int shadow_dac_addr, active_dac_addr;
ffb_fbcPtr ffb;
ffb_dacPtr dac;
if (fmesa == NULL ||
fmesa->glCtx->Visual.doubleBufferMode == 0)
return;
/* Flush pending rendering commands */
_mesa_notifySwapBuffers(fmesa->glCtx);
ffb = fmesa->regs;
dac = fmesa->ffbScreen->dac;
fbc = fmesa->fbc;
wid = fmesa->wid;
/* Swap the buffer we render into and read pixels from. */
fmesa->back_buffer ^= 1;
/* If we are writing into both buffers, don't mess with
* the WB setting.
*/
if ((fbc & FFB_FBC_WB_AB) != FFB_FBC_WB_AB) {
if ((fbc & FFB_FBC_WB_A) != 0)
fbc = (fbc & ~FFB_FBC_WB_A) | FFB_FBC_WB_B;
else
fbc = (fbc & ~FFB_FBC_WB_B) | FFB_FBC_WB_A;
}
/* But either way, we must flip the read buffer setting. */
if ((fbc & FFB_FBC_RB_A) != 0)
fbc = (fbc & ~FFB_FBC_RB_A) | FFB_FBC_RB_B;
else
fbc = (fbc & ~FFB_FBC_RB_B) | FFB_FBC_RB_A;
LOCK_HARDWARE(fmesa);
if (fmesa->fbc != fbc) {
FFBFifo(fmesa, 1);
ffb->fbc = fmesa->fbc = fbc;
fmesa->ffbScreen->rp_active = 1;
}
/* And swap the buffer displayed in the WID. */
if (fmesa->ffb_sarea->flags & FFB_DRI_PAC1) {
shadow_dac_addr = FFBDAC_PAC1_SPWLUT(wid);
active_dac_addr = FFBDAC_PAC1_APWLUT(wid);
dac_db_bit = FFBDAC_PAC1_WLUT_DB;
} else {
shadow_dac_addr = FFBDAC_PAC2_SPWLUT(wid);
active_dac_addr = FFBDAC_PAC2_APWLUT(wid);
dac_db_bit = FFBDAC_PAC2_WLUT_DB;
}
FFBWait(fmesa, ffb);
wid_reg_val = DACCFG_READ(dac, active_dac_addr);
if (fmesa->back_buffer == 0)
wid_reg_val |= dac_db_bit;
else
wid_reg_val &= ~dac_db_bit;
#ifdef USE_FAST_SWAP
DACCFG_WRITE(dac, active_dac_addr, wid_reg_val);
#else
DACCFG_WRITE(dac, shadow_dac_addr, wid_reg_val);
/* Schedule the window transfer. */
DACCFG_WRITE(dac, FFBDAC_CFG_WTCTRL,
(FFBDAC_CFG_WTCTRL_TCMD | FFBDAC_CFG_WTCTRL_TE));
{
int limit = 1000000;
while (limit--) {
unsigned int wtctrl = DACCFG_READ(dac, FFBDAC_CFG_WTCTRL);
if ((wtctrl & FFBDAC_CFG_WTCTRL_DS) == 0)
break;
}
}
#endif
UNLOCK_HARDWARE(fmesa);
}
static void ffb_init_wid(ffbContextPtr fmesa, unsigned int wid)
{
ffb_dacPtr dac = fmesa->ffbScreen->dac;
unsigned int wid_reg_val, dac_db_bit, active_dac_addr;
unsigned int shadow_dac_addr;
if (fmesa->ffb_sarea->flags & FFB_DRI_PAC1) {
shadow_dac_addr = FFBDAC_PAC1_SPWLUT(wid);
active_dac_addr = FFBDAC_PAC1_APWLUT(wid);
dac_db_bit = FFBDAC_PAC1_WLUT_DB;
} else {
shadow_dac_addr = FFBDAC_PAC2_SPWLUT(wid);
active_dac_addr = FFBDAC_PAC2_APWLUT(wid);
dac_db_bit = FFBDAC_PAC2_WLUT_DB;
}
wid_reg_val = DACCFG_READ(dac, active_dac_addr);
wid_reg_val &= ~dac_db_bit;
#ifdef USE_FAST_SWAP
DACCFG_WRITE(dac, active_dac_addr, wid_reg_val);
#else
DACCFG_WRITE(dac, shadow_dac_addr, wid_reg_val);
/* Schedule the window transfer. */
DACCFG_WRITE(dac, FFBDAC_CFG_WTCTRL,
(FFBDAC_CFG_WTCTRL_TCMD | FFBDAC_CFG_WTCTRL_TE));
{
int limit = 1000000;
while (limit--) {
unsigned int wtctrl = DACCFG_READ(dac, FFBDAC_CFG_WTCTRL);
if ((wtctrl & FFBDAC_CFG_WTCTRL_DS) == 0)
break;
}
}
#endif
}
/* Force the context `c' to be the current context and associate with it
buffer `b' */
static GLboolean
ffbMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv)
{
if (driContextPriv) {
ffbContextPtr fmesa = (ffbContextPtr) driContextPriv->driverPrivate;
int first_time;
fmesa->driDrawable = driDrawPriv;
_mesa_make_current2(fmesa->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate);
if (!fmesa->glCtx->Viewport.Width)
_mesa_set_viewport(fmesa->glCtx,
0, 0,
driDrawPriv->w,
driDrawPriv->h);
first_time = 0;
if (fmesa->wid == ~0) {
first_time = 1;
if (getenv("LIBGL_SOFTWARE_RENDERING"))
FALLBACK( fmesa->glCtx, FFB_BADATTR_SWONLY, GL_TRUE );
}
LOCK_HARDWARE(fmesa);
if (first_time) {
fmesa->wid = fmesa->ffb_sarea->wid_table[driDrawPriv->index];
ffb_init_wid(fmesa, fmesa->wid);
}
fmesa->state_dirty |= FFB_STATE_ALL;
fmesa->state_fifo_ents = fmesa->state_all_fifo_ents;
ffbSyncHardware(fmesa);
UNLOCK_HARDWARE(fmesa);
if (first_time) {
/* Also, at the first switch to a new context,
* we need to clear all the hw buffers.
*/
ffbDDClear(fmesa->glCtx,
(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT |
DD_DEPTH_BIT | DD_STENCIL_BIT),
1, 0, 0, 0, 0);
}
} else {
_mesa_make_current(NULL, NULL);
}
return GL_TRUE;
}
/* Force the context `c' to be unbound from its buffer */
static GLboolean
ffbUnbindContext(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
static GLboolean
ffbOpenFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
static GLboolean
ffbCloseFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
void ffbXMesaUpdateState(ffbContextPtr fmesa)
{
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
__DRIscreenPrivate *sPriv = fmesa->driScreen;
int stamp = dPriv->lastStamp;
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
if (dPriv->lastStamp != stamp) {
GLcontext *ctx = fmesa->glCtx;
ffbCalcViewport(ctx);
if (ctx->Polygon.StippleFlag)
ffbXformAreaPattern(fmesa,
(const GLubyte *)ctx->PolygonStipple);
}
}
static struct __DriverAPIRec ffbAPI = {
ffbInitDriver,
ffbDestroyScreen,
ffbCreateContext,
ffbDestroyContext,
ffbCreateBuffer,
ffbDestroyBuffer,
ffbSwapBuffers,
ffbMakeCurrent,
ffbUnbindContext,
ffbOpenFullScreen,
ffbCloseFullScreen
};
/*
* This is the bootstrap function for the driver.
* The __driCreateScreen name is the symbol that libGL.so fetches.
* Return: pointer to a __DRIscreenPrivate.
*/
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config)
{
__DRIscreenPrivate *psp;
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &ffbAPI);
return (void *) psp;
}
#endif /* GLX_DIRECT_RENDERING */

View File

@ -0,0 +1,30 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_xmesa.h,v 1.2 2002/02/22 21:32:59 dawes Exp $ */
#ifndef _FFB_XMESA_H_
#define _FFB_XMESA_H_
#ifdef GLX_DIRECT_RENDERING
#include <sys/time.h>
#include "dri_util.h"
#include "mtypes.h"
#include "ffb_drishare.h"
#include "ffb_regs.h"
#include "ffb_dac.h"
#include "ffb_fifo.h"
typedef struct {
__DRIscreenPrivate *sPriv;
ffb_fbcPtr regs;
ffb_dacPtr dac;
volatile char *sfb8r;
volatile char *sfb32;
volatile char *sfb64;
int fifo_cache;
int rp_active;
} ffbScreenPrivate;
#endif /* GLX_DIRECT_RENDERING */
#endif /* !(_FFB_XMESA_H) */