@@ -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 |
@@ -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; | |||
} |
@@ -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) */ |
@@ -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); | |||
} | |||
@@ -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) */ |
@@ -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) */ |
@@ -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; | |||
} |
@@ -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) */ |
@@ -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; | |||
} |
@@ -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) */ |
@@ -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) */ |
@@ -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) | |||
*/ |
@@ -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]; | |||
} |
@@ -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) */ |
@@ -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 |
@@ -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) */ |
@@ -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]; | |||
} |
@@ -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) */ |
@@ -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 |
@@ -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 |
@@ -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; | |||
} |
@@ -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) */ |
@@ -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) */ |
@@ -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; | |||
} | |||
} |
@@ -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) */ |
@@ -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; | |||
} |
@@ -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) */ | |||
@@ -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; | |||
} |
@@ -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) */ |
@@ -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 |
@@ -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; | |||
} | |||
} |
@@ -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) */ |
@@ -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 |
@@ -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 ); | |||
} |
@@ -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) */ |
@@ -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 */ |
@@ -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) */ |