@@ -0,0 +1,64 @@ | |||
REMOVE THIS FILE BEFORE MERGING WITH TRUNK | |||
------------------------------------------ | |||
OUTSTANDING BUGS | |||
demos/reflect - reading back Z on Voodoo3, image offset to right | |||
Fixed in latest Glide. | |||
Q3 - some polygons drawn as vertical strips, similar to bug that was | |||
seen in demos/fire. Voodoo3 only. May be related to glDepthMask | |||
or glColorMask. | |||
book/fog - not fogging | |||
Fog in orthograph mode still not implemented. Checking with | |||
3dfx engineers for ideas. | |||
Q3 demo crashes after changing display settings | |||
but the full Q3 game version seems OK. | |||
MORE OUTSTANDING BUGS | |||
private context was NULL! causing immediate failure of any glx prog. cant | |||
reproduce after restarting the X server. putting it down as halluc. | |||
texture object image was NULL, causing segmentation failure. happens with | |||
prboom. ive put a check in tdfx_texstate.c but this isn't a fix. | |||
prboom, wall textures near first chainsaw aren't bound properly. sideways | |||
movements causes the wall textures to move with you. prboom busted? | |||
16bpp mode, quake3, windowed, q3dm1, floor under rocketlauncher bands. it | |||
looks like multitexturing gone wrong. i'll disable a tmu and test. | |||
sof, polygons appear at wrong x,y,z positions, intermittent, have not yet | |||
found reliable way of reproducing. culling? sometimes polys disappear. | |||
descent3 is all black in 16bpp mode - FIXED (palette problems) | |||
smeared pixels in quake3 - FIXED (texture memory overlapped FB) | |||
PERFORMANCE COMPARISON (Brian / Alan) | |||
V3/16 is Voodoo3 in 16bpp on a P3/500 | |||
V5/16 is Voodoo5 in 16bpp on a P3/600 | |||
V5/32 is Voodoo5 in 32bpp on a P3/600 | |||
V5A/16 is Voodoo5 in 16bpp on an Alpha AXP/600 | |||
V5A/32 is Voodoo5 in 32bpp on an Alpha AXP/600 | |||
tdfx-2-1-branch tdfx-3-0-0-branch | |||
demo V3/16 V5/16 V5/32 V3/16 V5/16 V5/32 V5A/16 V5A/32 | |||
------------------------------------------------------------------------ | |||
gloss 257 183 174 320 308 177 313 167 | |||
fire 42 39 52 41 | |||
fire (no help) 98 80 50 106 113 73 124 80 | |||
tunnel 61 50 70 58 | |||
tunnel (no help) 167 142 57 138 152 113 171 122 | |||
gears 663 554 540 881 1232 776 1484 830 | |||
teapot 20 21 37 36 | |||
teapot (no help) 22 14 14 24 30 30 43 42 | |||
@@ -0,0 +1,128 @@ | |||
# 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/tdfx_dri.c | |||
DRIVER_SOURCES = tdfx_context.c \ | |||
../common/mm.c \ | |||
../common/utils.c \ | |||
../common/texmem.c \ | |||
../common/vblank.c \ | |||
../common/xmlconfig.c \ | |||
tdfx_dd.c \ | |||
tdfx_lock.c \ | |||
tdfx_pixels.c \ | |||
tdfx_render.c \ | |||
tdfx_screen.c \ | |||
tdfx_span.c \ | |||
tdfx_state.c \ | |||
tdfx_tex.c \ | |||
tdfx_texman.c \ | |||
tdfx_texstate.c \ | |||
tdfx_tris.c \ | |||
tdfx_vb.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 tdfx_dri.so | |||
tdfx_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/tdfx_dri.so && \ | |||
install tdfx_dri.so $(TOP)/lib/tdfx_dri.so | |||
$(TOP)/lib/tdfx_dri.so: tdfx_dri.so | |||
rm -f $(TOP)/lib/tdfx_dri.so && \ | |||
install tdfx_dri.so $(TOP)/lib/tdfx_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,84 @@ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S,v 1.2 2000/09/26 15:56:51 tsi Exp $ */ | |||
#include "../../X86/assyntax.h" | |||
#define SETUP_RGBA 0x1 | |||
#define SETUP_TMU0 0x2 | |||
#define SETUP_TMU1 0x4 | |||
/* Pack either rgba or texture into the remaining half of a 32 byte vertex. | |||
*/ | |||
#define CLIP_R 24 | |||
#define CLIP_G 16 | |||
#define CLIP_B 20 | |||
#define CLIP_A 28 /* defined inf fxdrv.h */ | |||
#define CLIP_S0 16 | |||
#define CLIP_T0 20 | |||
#define CLIP_S1 24 | |||
#define CLIP_T1 28 | |||
#define SIZE 4 | |||
#define TYPE (0) | |||
#define TAG(x) x | |||
#include "fx_3dnow_fasttmp.h" | |||
#define SIZE 8 | |||
#define TYPE (SETUP_RGBA) | |||
#define TAG(x) x##_RGBA | |||
#include "fx_3dnow_fasttmp.h" | |||
#define SIZE 6 | |||
#define TYPE (SETUP_TMU0) | |||
#define TAG(x) x##_TMU0 | |||
#include "fx_3dnow_fasttmp.h" | |||
#define SIZE 8 | |||
#define TYPE (SETUP_TMU0|SETUP_TMU1) | |||
#define TAG(x) x##_TMU0_TMU1 | |||
#include "fx_3dnow_fasttmp.h" | |||
#undef CLIP_S1 | |||
#undef CLIP_T1 | |||
#define CLIP_S1 16 | |||
#define CLIP_T1 20 | |||
#define SIZE 6 | |||
#define TYPE (SETUP_TMU1) | |||
#define TAG(x) x##_TMU1 | |||
#include "fx_3dnow_fasttmp.h" | |||
/* These three need to use a full 64 byte clip-space vertex. | |||
*/ | |||
#undef CLIP_S0 | |||
#undef CLIP_T0 | |||
#undef CLIP_S1 | |||
#undef CLIP_T1 | |||
#define CLIP_S0 32 | |||
#define CLIP_T0 36 | |||
#define CLIP_S1 40 | |||
#define CLIP_T1 44 | |||
#define SIZE 10 | |||
#define TYPE (SETUP_RGBA|SETUP_TMU0) | |||
#define TAG(x) x##_RGBA_TMU0 | |||
#include "fx_3dnow_fasttmp.h" | |||
#define SIZE 12 | |||
#define TYPE (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) | |||
#define TAG(x) x##_RGBA_TMU0_TMU1 | |||
#include "fx_3dnow_fasttmp.h" | |||
#undef CLIP_S1 | |||
#undef CLIP_T1 | |||
#define CLIP_S1 32 | |||
#define CLIP_T1 36 | |||
#define SIZE 10 | |||
#define TYPE (SETUP_RGBA|SETUP_TMU1) | |||
#define TAG(x) x##_RGBA_TMU1 | |||
#include "fx_3dnow_fasttmp.h" | |||
@@ -0,0 +1,314 @@ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fasttmp.h,v 1.2 2000/09/26 15:56:51 tsi Exp $ */ | |||
#if !defined(NASM_ASSEMBLER) && !defined(MASM_ASSEMBLER) | |||
#define TAGLLBL(a) TAG(.L##a) | |||
#else | |||
#define TAGLLBL(a) TAG(a) | |||
#endif | |||
#if !GLIDE3 | |||
#define GR_VERTEX_X_OFFSET 0 | |||
#define GR_VERTEX_Y_OFFSET 4 | |||
#define GR_VERTEX_Z_OFFSET 8 | |||
#define GR_VERTEX_R_OFFSET 12 | |||
#define GR_VERTEX_G_OFFSET 16 | |||
#define GR_VERTEX_B_OFFSET 20 | |||
#define GR_VERTEX_OOZ_OFFSET 24 | |||
#define GR_VERTEX_A_OFFSET 28 | |||
#define GR_VERTEX_OOW_OFFSET 32 | |||
#else /* GLIDE3 */ | |||
#define GR_VERTEX_X_OFFSET 0 | |||
#define GR_VERTEX_Y_OFFSET 4 | |||
#define GR_VERTEX_OOZ_OFFSET 8 | |||
#define GR_VERTEX_OOW_OFFSET 12 | |||
#define GR_VERTEX_R_OFFSET 16 | |||
#define GR_VERTEX_G_OFFSET 20 | |||
#define GR_VERTEX_B_OFFSET 24 | |||
#define GR_VERTEX_A_OFFSET 28 | |||
#define GR_VERTEX_Z_OFFSET 32 | |||
#endif /* GLIDE3 */ | |||
#define GR_VERTEX_SOW_TMU0_OFFSET 36 | |||
#define GR_VERTEX_TOW_TMU0_OFFSET 40 | |||
#define GR_VERTEX_OOW_TMU0_OFFSET 44 | |||
#define GR_VERTEX_SOW_TMU1_OFFSET 48 | |||
#define GR_VERTEX_TOW_TMU1_OFFSET 52 | |||
#define GR_VERTEX_OOW_TMU1_OFFSET 56 | |||
/*#define MAT_SX 0 /* accessed by REGIND !! */ | |||
#define MAT_SY 20 | |||
#define MAT_SZ 40 | |||
#define MAT_TX 48 | |||
#define MAT_TY 52 | |||
#define MAT_TZ 56 | |||
/* Do viewport map, device scale and perspective projection. | |||
* | |||
* void project_verts( GLfloat *first, | |||
* GLfloat *last, | |||
* const GLfloat *m, | |||
* GLuint stride ) | |||
* | |||
* | |||
* Rearrange fxVertices to look like grVertices. | |||
*/ | |||
GLOBL GLNAME( TAG(fx_3dnow_project_vertices) ) | |||
GLNAME( TAG(fx_3dnow_project_vertices) ): | |||
PUSH_L ( EBP ) | |||
MOV_L ( REGOFF(8, ESP), ECX ) /* first_vert */ | |||
MOV_L ( REGOFF(12, ESP), EDX ) /* last_vert */ | |||
CMP_L ( ECX, EDX ) | |||
JE ( TAGLLBL(FXPV_end) ) | |||
FEMMS | |||
PREFETCH ( REGIND(ECX) ) /* fetch the first vertex */ | |||
MOV_L ( REGOFF(16, ESP), EBP ) /* matrix */ | |||
MOV_L ( REGOFF(20, ESP), EAX ) /* stride */ | |||
MOVD ( REGOFF(MAT_TX, EBP), MM6 ) /* | tx */ | |||
PUNPCKLDQ ( REGOFF(MAT_TY, EBP), MM6 ) /* ty | tx */ | |||
#if !defined(FX_V2) | |||
MOV_L ( CONST(0x49400000), REGOFF(-8, ESP) ) /* snapper */ | |||
MOV_L ( CONST(0x49400000), REGOFF(-4, ESP) ) /* snapper */ | |||
#endif | |||
MOVQ ( REGOFF(-8, ESP), MM4 ) /* snapper | snapper */ | |||
PFADD ( MM4, MM6 ) /* ty+snapper | tx+snapper */ | |||
MOVD ( REGIND(EBP), MM5 ) | |||
PUNPCKLDQ ( REGOFF(MAT_SY, EBP), MM5 ) /* vsy | vsx */ | |||
MOVD ( REGOFF(MAT_SZ, EBP), MM1 ) /* | vsz */ | |||
ALIGNTEXT32 | |||
TAGLLBL(FXPV_loop_start): | |||
PREFETCH ( REGOFF(64, ECX) ) /* fetch the next-ish vertex */ | |||
MOVD ( REGOFF(12, ECX), MM0 ) /* | f[3] */ | |||
PFRCP ( MM0, MM0 ) /* oow = 1/f[3] */ | |||
MOVD ( REGOFF(12, ECX), MM7 ) /* | f[3] */ | |||
PFRCPIT1 ( MM0, MM7 ) | |||
PFRCPIT2 ( MM0, MM7 ) /* oow | oow */ | |||
PUNPCKLDQ ( MM7, MM7 ) | |||
#if (TYPE & SETUP_RGBA) | |||
MOVD ( REGOFF(CLIP_R, ECX ), MM0 ) /* f[RCOORD] = f[CLIP_R]; */ | |||
MOVD ( MM0, REGOFF(GR_VERTEX_R_OFFSET, ECX) ) | |||
#endif | |||
#if (TYPE & SETUP_TMU1) | |||
MOVQ ( REGOFF(CLIP_S1, ECX), MM0 ) /* f[S1COORD] = f[CLIP_S1] * oow */ | |||
PFMUL ( MM7, MM0 ) /* f[T1COORD] = f[CLIP_T1] * oow */ | |||
MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU1_OFFSET, ECX) ) | |||
#endif | |||
#if (TYPE & SETUP_TMU0) | |||
MOVQ ( REGOFF(CLIP_S0, ECX), MM0 ) /* f[S0COORD] = f[CLIP_S0] * oow */ | |||
PFMUL ( MM7, MM0 ) /* f[T0COORD] = f[CLIP_T0] * oow */ | |||
MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU0_OFFSET, ECX) ) | |||
#endif | |||
/* DO_SETUP_XYZ */ | |||
MOVQ ( REGIND(ECX), MM2 ) /* f[1] | f[0] */ | |||
PFMUL ( MM7, MM2 ) /* f[1] * oow | f[0] * oow */ | |||
MOVD ( REGOFF(8, ECX), MM3 ) /* | f[2] */ | |||
PFMUL ( MM7, MM3 ) /* | f[2] * oow */ | |||
MOVD ( REGOFF(MAT_TZ, EBP), MM0 ) /* | vtz */ | |||
PFMUL ( MM1, MM3 ) /* | f[2] *= vsz */ | |||
PFADD ( MM0, MM3 ) /* | f[2] += vtz */ | |||
PFMUL ( MM5, MM2 ) /* f[1] *= vsy | f[0] *= vsx */ | |||
PFADD ( MM6, MM2 ) /* f[1] += vty | f[0] += vtx */ | |||
#if !defined(FX_V2) | |||
PFSUB ( MM4, MM2 ) /* f[0,1] -= snapper */ | |||
#endif | |||
MOVQ ( MM2, REGOFF(GR_VERTEX_X_OFFSET, ECX) ) | |||
MOVD ( MM3, REGOFF(GR_VERTEX_OOZ_OFFSET, ECX) ) | |||
/* end of DO_SETUP_XYZ */ | |||
MOVD ( MM7, REGOFF(GR_VERTEX_OOW_OFFSET, ECX) ) /* f[OOWCOORD] = oow */ | |||
ADD_L ( EAX, ECX ) /* f += stride */ | |||
CMP_L ( ECX, EDX ) /* stall??? */ | |||
JA ( TAGLLBL(FXPV_loop_start) ) | |||
TAGLLBL(FXPV_end): | |||
FEMMS | |||
POP_L ( EBP ) | |||
RET | |||
/* void project_verts( GLfloat *first, | |||
* GLfloat *last, | |||
* const GLfloat *m, | |||
* GLuint stride, | |||
* const GLubyte *mask ) | |||
* | |||
*/ | |||
GLOBL GLNAME( TAG(fx_3dnow_project_clipped_vertices) ) | |||
GLNAME( TAG(fx_3dnow_project_clipped_vertices) ): | |||
PUSH_L ( EBP ) | |||
MOV_L ( REGOFF(8, ESP), ECX ) /* first FXDRIVER(VB)->verts*/ | |||
MOV_L ( REGOFF(12, ESP), EDX ) /* last FXDRIVER(VB)->last_vert */ | |||
FEMMS | |||
PUSH_L ( EDI ) | |||
PUSH_L ( ESI ) | |||
PREFETCH ( REGIND(ECX) ) /* fetch the first vertex */ | |||
MOV_L ( REGOFF(24, ESP), EBP ) /* mat ctx->Viewport.WindowMap.M */ | |||
MOV_L ( REGOFF(28, ESP), EAX ) /* stride */ | |||
MOV_L ( REGOFF(32, ESP), ESI ) /* VB->ClipMask */ | |||
MOVD ( REGOFF(MAT_TX, EBP), MM6 ) /* | tx */ | |||
PUNPCKLDQ ( REGOFF(MAT_TY, EBP), MM6 ) /* ty | tx */ | |||
#if !defined(FX_V2) | |||
MOV_L ( CONST(0x49400000), REGOFF(-8, ESP) ) /* snapper */ | |||
MOV_L ( CONST(0x49400000), REGOFF(-4, ESP) ) /* snapper */ | |||
#endif | |||
MOVQ ( REGOFF(-8, ESP), MM4 ) /* snapper | snapper */ | |||
PFADD ( MM4, MM6 ) /* ty+snapper | tx+snapper */ | |||
MOVD ( REGIND(EBP), MM5 ) | |||
PUNPCKLDQ ( REGOFF(MAT_SY, EBP), MM5 ) /* vsy | vsx */ | |||
MOVD ( REGOFF(MAT_SZ, EBP), MM1 ) /* | vsz */ | |||
ALIGNTEXT32 | |||
TAGLLBL(FXPCV_loop_start): | |||
PREFETCH ( REGOFF(64, ECX) ) /* fetch the next-ish vertex */ | |||
CMP_B ( CONST(0), REGIND(ESI) ) | |||
JNE ( TAGLLBL(FXPCV_skip) ) | |||
MOVD ( REGOFF(12, ECX), MM0) /* | f[3] */ | |||
PFRCP ( MM0, MM0 ) /* oow = 1/f[3] */ | |||
MOVD ( REGOFF(12, ECX), MM7) /* | f[3] */ | |||
PFRCPIT1 ( MM0, MM7 ) | |||
PFRCPIT2 ( MM0, MM7 ) /* oow | oow */ | |||
PUNPCKLDQ ( MM7, MM7 ) | |||
#if (TYPE & SETUP_RGBA) | |||
MOVD ( REGOFF(CLIP_R, ECX ), MM0 ) /* f[RCOORD] = f[CLIP_R]; */ | |||
MOVD ( MM0, REGOFF(GR_VERTEX_R_OFFSET, ECX) ) | |||
#endif | |||
#if (TYPE & SETUP_TMU1) | |||
MOVQ ( REGOFF(CLIP_S1, ECX), MM0 ) /* f[S1COORD] = f[CLIP_S1] * oow */ | |||
PFMUL ( MM7, MM0 ) /* f[T1COORD] = f[CLIP_T1] * oow */ | |||
MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU1_OFFSET, ECX) ) | |||
#endif | |||
#if (TYPE & SETUP_TMU0) | |||
MOVQ ( REGOFF(CLIP_S0, ECX), MM0 ) /* f[S0COORD] = f[CLIP_S0] * oow */ | |||
PFMUL ( MM7, MM0 ) /* f[T0COORD] = f[CLIP_T0] * oow */ | |||
MOVQ ( MM0, REGOFF(GR_VERTEX_SOW_TMU0_OFFSET, ECX) ) | |||
#endif | |||
/* DO_SETUP_XYZ */ | |||
MOVQ ( REGIND(ECX), MM2 ) /* f[1] | f[0] */ | |||
PFMUL ( MM7, MM2 ) /* f[1] * oow | f[0] * oow */ | |||
MOVD ( REGOFF(8, ECX), MM3 ) /* | f[2] */ | |||
PFMUL ( MM7, MM3 ) /* | f[2] * oow */ | |||
MOVD ( REGOFF(MAT_TZ, EBP), MM0 ) /* | vtz */ | |||
PFMUL ( MM1, MM3 ) /* | f[2] *= vsz */ | |||
PFADD ( MM0, MM3 ) /* | f[2] += vtz */ | |||
PFMUL ( MM5, MM2 ) /* f[1] *= vsy | f[0] *= vsx */ | |||
PFADD ( MM6, MM2 ) /* f[1] += vty | f[0] += vtx */ | |||
#if !defined(FX_V2) | |||
PFSUB ( MM4, MM2 ) /* f[0,1] -= snapper */ | |||
#endif | |||
MOVQ ( MM2, REGOFF(GR_VERTEX_X_OFFSET, ECX) ) | |||
MOVD ( MM3, REGOFF(GR_VERTEX_OOZ_OFFSET, ECX) ) | |||
/* end of DO_SETUP_XYZ */ | |||
MOVD ( MM7, REGOFF(GR_VERTEX_OOW_OFFSET, ECX) ) /* f[OOWCOORD] = oow */ | |||
TAGLLBL(FXPCV_skip): | |||
ADD_L ( EAX, ECX ) /* f += stride */ | |||
INC_L ( ESI ) /* next ClipMask */ | |||
CMP_L ( ECX, EDX ) | |||
JA ( TAGLLBL(FXPCV_loop_start) ) | |||
POP_L ( ESI ) | |||
POP_L ( EDI ) | |||
TAGLLBL(FXPCV_end): | |||
FEMMS | |||
POP_L ( EBP ) | |||
RET | |||
#undef TYPE | |||
#undef TAG | |||
#undef SIZE | |||
@@ -0,0 +1,63 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/dri_glide.h,v 1.1 2001/03/21 16:14:26 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* | |||
*/ | |||
#ifndef __DRI_GLIDE_H__ | |||
#define __DRI_GLIDE_H__ | |||
#ifdef GLX_DIRECT_RENDERING | |||
#include <glide.h> | |||
#include "dri_mesaint.h" | |||
/* | |||
* This is the private interface between Glide and the DRI. | |||
*/ | |||
extern void grDRIOpen( char *pFB, char *pRegs, int deviceID, | |||
int width, int height, | |||
int mem, int cpp, int stride, | |||
int fifoOffset, int fifoSize, | |||
int fbOffset, int backOffset, int depthOffset, | |||
int textureOffset, int textureSize, | |||
volatile int *fifoPtr, volatile int *fifoRead ); | |||
extern void grDRIPosition( int x, int y, int w, int h, | |||
int numClip, XF86DRIClipRectPtr pClip ); | |||
extern void grDRILostContext( void ); | |||
extern void grDRIImportFifo( int fifoPtr, int fifoRead ); | |||
extern void grDRIInvalidateAll( void ); | |||
extern void grDRIResetSAREA( void ); | |||
extern void grDRIBufferSwap( FxU32 swapInterval ); | |||
#endif | |||
#endif |
@@ -0,0 +1,897 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c,v 1.12 2003/05/08 09:25:35 herrb Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#include <dlfcn.h> | |||
#include "tdfx_context.h" | |||
#include "tdfx_dd.h" | |||
#include "tdfx_state.h" | |||
#include "tdfx_vb.h" | |||
#include "tdfx_tris.h" | |||
#include "tdfx_render.h" | |||
#include "tdfx_span.h" | |||
#include "tdfx_texman.h" | |||
#include "extensions.h" | |||
#include "swrast/swrast.h" | |||
#include "swrast_setup/swrast_setup.h" | |||
#include "array_cache/acache.h" | |||
#include "tnl/tnl.h" | |||
#include "tnl/t_pipeline.h" | |||
/* | |||
* Enable/Disable the extensions for this context. | |||
*/ | |||
static void tdfxDDInitExtensions( GLcontext *ctx ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
_mesa_enable_extension( ctx, "GL_HP_occlusion_test" ); | |||
_mesa_enable_extension( ctx, "GL_EXT_paletted_texture" ); | |||
_mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); | |||
if ( fxMesa->haveTwoTMUs ) { | |||
_mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); | |||
_mesa_enable_extension( ctx, "GL_ARB_multitexture" ); | |||
} | |||
if ( TDFX_IS_NAPALM( fxMesa ) ) { | |||
#if 0 | |||
_mesa_enable_extension( ctx, "GL_ARB_texture_compression" ); | |||
_mesa_enable_extension( ctx, "GL_3DFX_texture_compression_FXT1" ); | |||
#endif | |||
_mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); | |||
} | |||
#if 0 | |||
_mesa_enable_extension( ctx, "GL_ARB_texture_cube_map"); | |||
_mesa_enable_extension( ctx, "GL_NV_texture_rectangle"); | |||
#endif | |||
if (fxMesa->haveHwStencil) { | |||
_mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); | |||
} | |||
} | |||
static const struct gl_pipeline_stage *tdfx_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, | |||
}; | |||
GLboolean tdfxCreateContext( const __GLcontextModes *mesaVis, | |||
__DRIcontextPrivate *driContextPriv, | |||
void *sharedContextPrivate ) | |||
{ | |||
tdfxContextPtr fxMesa; | |||
GLcontext *ctx, *shareCtx; | |||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; | |||
tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private; | |||
TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) ((char *) sPriv->pSAREA + | |||
sizeof(XF86DRISAREARec)); | |||
/* Allocate tdfx context */ | |||
fxMesa = (tdfxContextPtr) CALLOC( sizeof(tdfxContextRec) ); | |||
if (!fxMesa) | |||
return GL_FALSE; | |||
/* Allocate the Mesa context */ | |||
if (sharedContextPrivate) | |||
shareCtx = ((tdfxContextPtr) sharedContextPrivate)->glCtx; | |||
else | |||
shareCtx = NULL; | |||
fxMesa->glCtx = _mesa_create_context(mesaVis, shareCtx, (void *) fxMesa, GL_TRUE); | |||
if (!fxMesa->glCtx) { | |||
FREE(fxMesa); | |||
return GL_FALSE; | |||
} | |||
driContextPriv->driverPrivate = fxMesa; | |||
/* Mirror some important DRI state | |||
*/ | |||
fxMesa->hHWContext = driContextPriv->hHWContext; | |||
fxMesa->driHwLock = &sPriv->pSAREA->lock; | |||
fxMesa->driFd = sPriv->fd; | |||
fxMesa->driScreen = sPriv; | |||
fxMesa->driContext = driContextPriv; | |||
fxMesa->fxScreen = fxScreen; | |||
fxMesa->sarea = saPriv; | |||
fxMesa->haveHwStencil = ( TDFX_IS_NAPALM( fxMesa ) && | |||
mesaVis->stencilBits && | |||
mesaVis->depthBits == 24 ); | |||
fxMesa->screen_width = fxScreen->width; | |||
fxMesa->screen_height = fxScreen->height; | |||
fxMesa->new_gl_state = ~0; | |||
fxMesa->new_state = ~0; | |||
fxMesa->dirty = ~0; | |||
/* NOTE: This must be here before any Glide calls! */ | |||
if (!tdfxInitGlide( fxMesa )) { | |||
FREE(fxMesa); | |||
return GL_FALSE; | |||
} | |||
fxMesa->Glide.grDRIOpen( (char*) sPriv->pFB, fxScreen->regs.map, fxScreen->deviceID, | |||
fxScreen->width, fxScreen->height, fxScreen->mem, fxScreen->cpp, | |||
fxScreen->stride, fxScreen->fifoOffset, fxScreen->fifoSize, | |||
fxScreen->fbOffset, fxScreen->backOffset, fxScreen->depthOffset, | |||
fxScreen->textureOffset, fxScreen->textureSize, &saPriv->fifoPtr, | |||
&saPriv->fifoRead ); | |||
if ( getenv( "FX_GLIDE_SWAPINTERVAL" ) ) { | |||
fxMesa->Glide.SwapInterval = atoi( getenv( "FX_GLIDE_SWAPINTERVAL" ) ); | |||
} else { | |||
fxMesa->Glide.SwapInterval = 0; | |||
} | |||
if ( getenv( "FX_MAX_PENDING_SWAPS" ) ) { | |||
fxMesa->Glide.MaxPendingSwaps = atoi( getenv( "FX_MAX_PENDING_SWAPS" ) ); | |||
} else { | |||
fxMesa->Glide.MaxPendingSwaps = 2; | |||
} | |||
fxMesa->Glide.Initialized = GL_FALSE; | |||
fxMesa->Glide.Board = 0; | |||
if (getenv("FX_EMULATE_SINGLE_TMU")) { | |||
fxMesa->haveTwoTMUs = GL_FALSE; | |||
} | |||
else { | |||
if ( TDFX_IS_BANSHEE( fxMesa ) ) { | |||
fxMesa->haveTwoTMUs = GL_FALSE; | |||
} else { | |||
fxMesa->haveTwoTMUs = GL_TRUE; | |||
} | |||
} | |||
fxMesa->stats.swapBuffer = 0; | |||
fxMesa->stats.reqTexUpload = 0; | |||
fxMesa->stats.texUpload = 0; | |||
fxMesa->stats.memTexUpload = 0; | |||
fxMesa->tmuSrc = TDFX_TMU_NONE; | |||
ctx = fxMesa->glCtx; | |||
if ( TDFX_IS_NAPALM( fxMesa ) ) { | |||
ctx->Const.MaxTextureLevels = 12; | |||
} else { | |||
ctx->Const.MaxTextureLevels = 9; | |||
} | |||
ctx->Const.MaxTextureUnits = TDFX_IS_BANSHEE( fxMesa ) ? 1 : 2; | |||
/* 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; | |||
/* Initialize the software rasterizer and helper modules. | |||
*/ | |||
_swrast_CreateContext( ctx ); | |||
_ac_CreateContext( ctx ); | |||
_tnl_CreateContext( ctx ); | |||
_swsetup_CreateContext( ctx ); | |||
/* Install the customized pipeline: | |||
*/ | |||
_tnl_destroy_pipeline( ctx ); | |||
_tnl_install_pipeline( ctx, tdfx_pipeline ); | |||
/* Configure swrast to match hardware characteristics: | |||
*/ | |||
_swrast_allow_pixel_fog( ctx, GL_TRUE ); | |||
_swrast_allow_vertex_fog( ctx, GL_FALSE ); | |||
tdfxDDInitExtensions( ctx ); | |||
tdfxDDInitDriverFuncs( ctx ); | |||
tdfxDDInitStateFuncs( ctx ); | |||
tdfxDDInitRenderFuncs( ctx ); | |||
tdfxDDInitSpanFuncs( ctx ); | |||
tdfxDDInitTriFuncs( ctx ); | |||
tdfxInitVB( ctx ); | |||
tdfxInitState( fxMesa ); | |||
return GL_TRUE; | |||
} | |||
static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa ) | |||
{ | |||
FxI32 result; | |||
int i; | |||
LOCK_HARDWARE( fxMesa ); | |||
fxMesa->Glide.grGet( GR_GLIDE_VERTEXLAYOUT_SIZE, sizeof(FxI32), &result ); | |||
for ( i = 0 ; i < TDFX_NUM_LAYOUTS ; i++ ) { | |||
fxMesa->layout[i] = MALLOC( result ); | |||
if ( !fxMesa->layout[i] ) { | |||
UNLOCK_HARDWARE( fxMesa ); | |||
return GL_FALSE; | |||
} | |||
} | |||
/* Tiny vertex format - 16 bytes. | |||
*/ | |||
fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); | |||
fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_TINY] ); | |||
/* Non textured vertex format - 24 bytes (Need w for table fog) | |||
*/ | |||
fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); | |||
fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_NOTEX] ); | |||
/* Single textured vertex format - 32 bytes. | |||
*/ | |||
fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); | |||
fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); | |||
/*grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ | |||
fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_SINGLE] ); | |||
/* Multitextured vertex format - 40 bytes. | |||
*/ | |||
fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); | |||
fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE ); | |||
/*fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ | |||
fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_MULTI] ); | |||
/* Projected texture vertex format - 48 bytes. | |||
*/ | |||
fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); | |||
fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Q0, TDFX_Q0_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE ); | |||
fxMesa->Glide.grVertexLayout( GR_PARAM_Q1, TDFX_Q1_OFFSET, GR_PARAM_ENABLE ); | |||
/*fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ | |||
fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_PROJECT] ); | |||
UNLOCK_HARDWARE( fxMesa ); | |||
return GL_TRUE; | |||
} | |||
/* | |||
* Initialize the state in an tdfxContextPtr struct. | |||
*/ | |||
static GLboolean | |||
tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, tdfxContextPtr fxMesa ) | |||
{ | |||
/* KW: Would be nice to make one of these a member of the other. | |||
*/ | |||
FxI32 result[2]; | |||
if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { | |||
fprintf( stderr, "%s( %p )\n", __FUNCTION__, fxMesa ); | |||
} | |||
#if DEBUG_LOCKING | |||
fprintf(stderr, "Debug locking enabled\n"); | |||
#endif | |||
if ( fxMesa->Glide.Initialized ) | |||
return GL_TRUE; | |||
fxMesa->width = driDrawPriv->w; | |||
fxMesa->height = driDrawPriv->h; | |||
/* We have to use a light lock here, because we can't do any glide | |||
* operations yet. No use of FX_* functions in this function. | |||
*/ | |||
DRM_LIGHT_LOCK( fxMesa->driFd, fxMesa->driHwLock, fxMesa->hHWContext ); | |||
fxMesa->Glide.grGlideInit(); | |||
fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); | |||
fxMesa->Glide.Context = fxMesa->Glide.grSstWinOpen( (FxU32) -1, | |||
GR_RESOLUTION_NONE, | |||
GR_REFRESH_NONE, | |||
fxMesa->Glide.ColorFormat, | |||
fxMesa->Glide.Origin, | |||
2, 1 ); | |||
fxMesa->Glide.grDRIResetSAREA(); | |||
DRM_UNLOCK( fxMesa->driFd, fxMesa->driHwLock, fxMesa->hHWContext ); | |||
if ( !fxMesa->Glide.Context ) | |||
return GL_FALSE; | |||
/* Perform the Glide-dependant part of the context initialization. | |||
*/ | |||
FX_grColorMaskv( fxMesa->glCtx, true4 ); | |||
tdfxTMInit( fxMesa ); | |||
LOCK_HARDWARE( fxMesa ); | |||
if ( fxMesa->glCtx->Visual.depthBits > 0 ) { | |||
fxMesa->Glide.grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER); | |||
} else { | |||
fxMesa->Glide.grDepthBufferMode(GR_DEPTHBUFFER_DISABLE); | |||
} | |||
fxMesa->Glide.grLfbWriteColorFormat( GR_COLORFORMAT_ABGR ); | |||
fxMesa->Glide.grGet( GR_TEXTURE_ALIGN, sizeof(FxI32), result ); | |||
fxMesa->Glide.TextureAlign = result[0]; | |||
fxMesa->Glide.State = NULL; | |||
fxMesa->Glide.grGet( GR_GLIDE_STATE_SIZE, sizeof(FxI32), result ); | |||
fxMesa->Glide.State = MALLOC( result[0] ); | |||
fxMesa->Fog.Table = NULL; | |||
fxMesa->Glide.grGet( GR_FOG_TABLE_ENTRIES, sizeof(FxI32), result ); | |||
fxMesa->Fog.Table = MALLOC( result[0] * sizeof(GrFog_t) ); | |||
UNLOCK_HARDWARE( fxMesa ); | |||
if ( !fxMesa->Glide.State || !fxMesa->Fog.Table ) { | |||
if ( fxMesa->Glide.State ) | |||
FREE( fxMesa->Glide.State ); | |||
if ( fxMesa->Fog.Table ) | |||
FREE( fxMesa->Fog.Table ); | |||
return GL_FALSE; | |||
} | |||
if ( !tdfxInitVertexFormats( fxMesa ) ) { | |||
return GL_FALSE; | |||
} | |||
LOCK_HARDWARE( fxMesa ); | |||
fxMesa->Glide.grGlideGetState( fxMesa->Glide.State ); | |||
if ( getenv( "FX_GLIDE_INFO" ) ) { | |||
printf( "GR_RENDERER = %s\n", (char *) fxMesa->Glide.grGetString( GR_RENDERER ) ); | |||
printf( "GR_VERSION = %s\n", (char *) fxMesa->Glide.grGetString( GR_VERSION ) ); | |||
printf( "GR_VENDOR = %s\n", (char *) fxMesa->Glide.grGetString( GR_VENDOR ) ); | |||
printf( "GR_HARDWARE = %s\n", (char *) fxMesa->Glide.grGetString( GR_HARDWARE ) ); | |||
printf( "GR_EXTENSION = %s\n", (char *) fxMesa->Glide.grGetString( GR_EXTENSION ) ); | |||
} | |||
UNLOCK_HARDWARE( fxMesa ); | |||
{ | |||
const char *debug = getenv("LIBGL_DEBUG"); | |||
if (debug && strstr(debug, "fallbacks")) { | |||
fxMesa->debugFallbacks = GL_TRUE; | |||
} | |||
} | |||
fxMesa->numClipRects = 0; | |||
fxMesa->pClipRects = NULL; | |||
fxMesa->scissoredClipRects = GL_FALSE; | |||
fxMesa->Glide.Initialized = GL_TRUE; | |||
return GL_TRUE; | |||
} | |||
void | |||
tdfxDestroyContext( __DRIcontextPrivate *driContextPriv ) | |||
{ | |||
tdfxContextPtr fxMesa = (tdfxContextPtr) driContextPriv->driverPrivate; | |||
if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { | |||
fprintf( stderr, "%s( %p )\n", __FUNCTION__, fxMesa ); | |||
} | |||
if ( fxMesa ) { | |||
if (fxMesa->glCtx->Shared->RefCount == 1 && fxMesa->driDrawable) { | |||
/* This share group is about to go away, free our private | |||
* texture object data. | |||
*/ | |||
struct gl_texture_object *tObj; | |||
tObj = fxMesa->glCtx->Shared->TexObjectList; | |||
while (tObj) { | |||
tdfxTMFreeTexture(fxMesa, tObj); | |||
tObj = tObj->Next; | |||
} | |||
} | |||
tdfxTMClose(fxMesa); /* free texture memory */ | |||
_swsetup_DestroyContext( fxMesa->glCtx ); | |||
_tnl_DestroyContext( fxMesa->glCtx ); | |||
_ac_DestroyContext( fxMesa->glCtx ); | |||
_swrast_DestroyContext( fxMesa->glCtx ); | |||
tdfxFreeVB( fxMesa->glCtx ); | |||
/* Free Mesa context */ | |||
fxMesa->glCtx->DriverCtx = NULL; | |||
_mesa_destroy_context(fxMesa->glCtx); | |||
/* free the tdfx context */ | |||
XFree( fxMesa ); | |||
} | |||
} | |||
GLboolean | |||
tdfxUnbindContext( __DRIcontextPrivate *driContextPriv ) | |||
{ | |||
GET_CURRENT_CONTEXT(ctx); | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { | |||
fprintf( stderr, "%s( %p )\n", __FUNCTION__, driContextPriv ); | |||
} | |||
if ( driContextPriv && (tdfxContextPtr) driContextPriv == fxMesa ) { | |||
LOCK_HARDWARE(fxMesa); | |||
fxMesa->Glide.grGlideGetState(fxMesa->Glide.State); | |||
UNLOCK_HARDWARE(fxMesa); | |||
} | |||
return GL_TRUE; | |||
} | |||
GLboolean | |||
tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv, | |||
__DRIdrawablePrivate *driDrawPriv, | |||
__DRIdrawablePrivate *driReadPriv ) | |||
{ | |||
if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { | |||
fprintf( stderr, "%s( %p )\n", __FUNCTION__, driContextPriv ); | |||
} | |||
if ( driContextPriv ) { | |||
tdfxContextPtr newFx = (tdfxContextPtr) driContextPriv->driverPrivate; | |||
GLcontext *newCtx = newFx->glCtx; | |||
GET_CURRENT_CONTEXT(curCtx); | |||
if ( newFx->driDrawable != driDrawPriv ) { | |||
newFx->driDrawable = driDrawPriv; | |||
newFx->dirty = ~0; | |||
} | |||
else if (curCtx == newCtx) { | |||
/* same drawable, same context -> no-op */ | |||
/* Need to call _mesa_make_current2() in order to make sure API | |||
* dispatch is set correctly. | |||
*/ | |||
_mesa_make_current2( newCtx, | |||
(GLframebuffer *) driDrawPriv->driverPrivate, | |||
(GLframebuffer *) driReadPriv->driverPrivate ); | |||
return GL_TRUE; | |||
} | |||
if ( !newFx->Glide.Initialized ) { | |||
if ( !tdfxInitContext( driDrawPriv, newFx ) ) | |||
return GL_FALSE; | |||
LOCK_HARDWARE( newFx ); | |||
/* FIXME: Force loading of window information */ | |||
newFx->width = 0; | |||
tdfxUpdateClipping(newCtx); | |||
tdfxUploadClipping(newFx); | |||
UNLOCK_HARDWARE( newFx ); | |||
} else { | |||
LOCK_HARDWARE( newFx ); | |||
newFx->Glide.grSstSelect( newFx->Glide.Board ); | |||
newFx->Glide.grGlideSetState( newFx->Glide.State ); | |||
tdfxUpdateClipping(newCtx); | |||
tdfxUploadClipping(newFx); | |||
UNLOCK_HARDWARE( newFx ); | |||
} | |||
_mesa_make_current2( newCtx, | |||
(GLframebuffer *) driDrawPriv->driverPrivate, | |||
(GLframebuffer *) driReadPriv->driverPrivate ); | |||
if ( !newCtx->Viewport.Width ) { | |||
_mesa_set_viewport( newCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); | |||
} | |||
} else { | |||
_mesa_make_current( 0, 0 ); | |||
} | |||
return GL_TRUE; | |||
} | |||
/* | |||
* Enable this to trace calls to various Glide functions. | |||
*/ | |||
/*#define DEBUG_TRAP*/ | |||
#ifdef DEBUG_TRAP | |||
static void (*real_grDrawTriangle)( const void *a, const void *b, const void *c ); | |||
static void (*real_grDrawPoint)( const void *a ); | |||
static void (*real_grDrawVertexArray)(FxU32 mode, FxU32 Count, void *pointers); | |||
static void (*real_grDrawVertexArrayContiguous)(FxU32 mode, FxU32 Count, | |||
void *pointers, FxU32 stride); | |||
static void (*real_grClipWindow)( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ); | |||
static void (*real_grVertexLayout)(FxU32 param, FxI32 offset, FxU32 mode); | |||
static void (*real_grGlideGetVertexLayout)( void *layout ); | |||
static void (*real_grGlideSetVertexLayout)( const void *layout ); | |||
static void (*real_grTexDownloadMipMapLevel)( GrChipID_t tmu, | |||
FxU32 startAddress, | |||
GrLOD_t thisLod, | |||
GrLOD_t largeLod, | |||
GrAspectRatio_t aspectRatio, | |||
GrTextureFormat_t format, | |||
FxU32 evenOdd, | |||
void *data ); | |||
static void debug_grDrawTriangle( const void *a, const void *b, const void *c ) | |||
{ | |||
printf("%s\n", __FUNCTION__); | |||
(*real_grDrawTriangle)(a, b, c); | |||
} | |||
static void debug_grDrawPoint( const void *a ) | |||
{ | |||
const float *f = (const float *) a; | |||
printf("%s %g %g\n", __FUNCTION__, f[0], f[1]); | |||
(*real_grDrawPoint)(a); | |||
} | |||
static void debug_grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers) | |||
{ | |||
printf("%s count=%d\n", __FUNCTION__, (int) Count); | |||
(*real_grDrawVertexArray)(mode, Count, pointers); | |||
} | |||
static void debug_grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, | |||
void *pointers, FxU32 stride) | |||
{ | |||
printf("%s mode=0x%x count=%d\n", __FUNCTION__, (int) mode, (int) Count); | |||
(*real_grDrawVertexArrayContiguous)(mode, Count, pointers, stride); | |||
} | |||
static void debug_grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ) | |||
{ | |||
printf("%s %d,%d .. %d,%d\n", __FUNCTION__, | |||
(int) minx, (int) miny, (int) maxx, (int) maxy); | |||
(*real_grClipWindow)(minx, miny, maxx, maxy); | |||
} | |||
static void debug_grVertexLayout(FxU32 param, FxI32 offset, FxU32 mode) | |||
{ | |||
(*real_grVertexLayout)(param, offset, mode); | |||
} | |||
static void debug_grGlideGetVertexLayout( void *layout ) | |||
{ | |||
(*real_grGlideGetVertexLayout)(layout); | |||
} | |||
static void debug_grGlideSetVertexLayout( const void *layout ) | |||
{ | |||
(*real_grGlideSetVertexLayout)(layout); | |||
} | |||
static void debug_grTexDownloadMipMapLevel( GrChipID_t tmu, | |||
FxU32 startAddress, | |||
GrLOD_t thisLod, | |||
GrLOD_t largeLod, | |||
GrAspectRatio_t aspectRatio, | |||
GrTextureFormat_t format, | |||
FxU32 evenOdd, | |||
void *data ) | |||
{ | |||
(*real_grTexDownloadMipMapLevel)(tmu, startAddress, thisLod, largeLod, | |||
aspectRatio, format, evenOdd, data); | |||
} | |||
#endif | |||
/* | |||
* Examine the context's deviceID to determine what kind of 3dfx hardware | |||
* is installed. dlopen() the appropriate Glide library and initialize | |||
* this context's Glide function pointers. | |||
* Return: true/false = success/failure | |||
*/ | |||
GLboolean tdfxInitGlide(tdfxContextPtr tmesa) | |||
{ | |||
static const char *defaultGlide = "libglide3.so"; | |||
const char *libName; | |||
void *libHandle; | |||
/* | |||
* XXX this code which selects a Glide library filename given the | |||
* deviceID may need to be cleaned up a bit. | |||
* Non-Linux systems may have different filenames, for example. | |||
*/ | |||
switch (tmesa->fxScreen->deviceID) { | |||
case PCI_CHIP_BANSHEE: | |||
case PCI_CHIP_VOODOO3: | |||
libName = "libglide3-v3.so"; | |||
break; | |||
case PCI_CHIP_VOODOO5: /* same as PCI_CHIP_VOODOO4 */ | |||
libName = "libglide3-v5.so"; | |||
break; | |||
default: | |||
{ | |||
__driUtilMessage("unrecognized 3dfx deviceID: 0x%x", | |||
tmesa->fxScreen->deviceID); | |||
} | |||
return GL_FALSE; | |||
} | |||
libHandle = dlopen(libName, RTLD_NOW); | |||
if (!libHandle) { | |||
/* The device-specific Glide library filename didn't work, try the | |||
* old, generic libglide3.so library. | |||
*/ | |||
libHandle = dlopen(defaultGlide, RTLD_NOW); | |||
if (!libHandle) { | |||
__driUtilMessage( | |||
"can't find Glide library, dlopen(%s) and dlopen(%s) both failed.", | |||
libName, defaultGlide); | |||
__driUtilMessage("dlerror() message: %s", dlerror()); | |||
return GL_FALSE; | |||
} | |||
libName = defaultGlide; | |||
} | |||
{ | |||
const char *env = getenv("LIBGL_DEBUG"); | |||
if (env && strstr(env, "verbose")) { | |||
fprintf(stderr, "libGL: using Glide library %s\n", libName); | |||
} | |||
} | |||
#define GET_FUNCTION(PTR, NAME) \ | |||
tmesa->Glide.PTR = dlsym(libHandle, NAME); \ | |||
if (!tmesa->Glide.PTR) { \ | |||
__driUtilMessage("couldn't find Glide function %s in %s.", \ | |||
NAME, libName); \ | |||
} | |||
GET_FUNCTION(grDrawPoint, "grDrawPoint"); | |||
GET_FUNCTION(grDrawLine, "grDrawLine"); | |||
GET_FUNCTION(grDrawTriangle, "grDrawTriangle"); | |||
GET_FUNCTION(grVertexLayout, "grVertexLayout"); | |||
GET_FUNCTION(grDrawVertexArray, "grDrawVertexArray"); | |||
GET_FUNCTION(grDrawVertexArrayContiguous, "grDrawVertexArrayContiguous"); | |||
GET_FUNCTION(grBufferClear, "grBufferClear"); | |||
/*GET_FUNCTION(grBufferSwap, "grBufferSwap");*/ | |||
GET_FUNCTION(grRenderBuffer, "grRenderBuffer"); | |||
GET_FUNCTION(grErrorSetCallback, "grErrorSetCallback"); | |||
GET_FUNCTION(grFinish, "grFinish"); | |||
GET_FUNCTION(grFlush, "grFlush"); | |||
GET_FUNCTION(grSstWinOpen, "grSstWinOpen"); | |||
GET_FUNCTION(grSstWinClose, "grSstWinClose"); | |||
#if 0 | |||
/* Not in V3 lib, and not used anyway. */ | |||
GET_FUNCTION(grSetNumPendingBuffers, "grSetNumPendingBuffers"); | |||
#endif | |||
GET_FUNCTION(grSelectContext, "grSelectContext"); | |||
GET_FUNCTION(grSstOrigin, "grSstOrigin"); | |||
GET_FUNCTION(grSstSelect, "grSstSelect"); | |||
GET_FUNCTION(grAlphaBlendFunction, "grAlphaBlendFunction"); | |||
GET_FUNCTION(grAlphaCombine, "grAlphaCombine"); | |||
GET_FUNCTION(grAlphaControlsITRGBLighting, "grAlphaControlsITRGBLighting"); | |||
GET_FUNCTION(grAlphaTestFunction, "grAlphaTestFunction"); | |||
GET_FUNCTION(grAlphaTestReferenceValue, "grAlphaTestReferenceValue"); | |||
GET_FUNCTION(grChromakeyMode, "grChromakeyMode"); | |||
GET_FUNCTION(grChromakeyValue, "grChromakeyValue"); | |||
GET_FUNCTION(grClipWindow, "grClipWindow"); | |||
GET_FUNCTION(grColorCombine, "grColorCombine"); | |||
GET_FUNCTION(grColorMask, "grColorMask"); | |||
GET_FUNCTION(grCullMode, "grCullMode"); | |||
GET_FUNCTION(grConstantColorValue, "grConstantColorValue"); | |||
GET_FUNCTION(grDepthBiasLevel, "grDepthBiasLevel"); | |||
GET_FUNCTION(grDepthBufferFunction, "grDepthBufferFunction"); | |||
GET_FUNCTION(grDepthBufferMode, "grDepthBufferMode"); | |||
GET_FUNCTION(grDepthMask, "grDepthMask"); | |||
GET_FUNCTION(grDisableAllEffects, "grDisableAllEffects"); | |||
GET_FUNCTION(grDitherMode, "grDitherMode"); | |||
GET_FUNCTION(grFogColorValue, "grFogColorValue"); | |||
GET_FUNCTION(grFogMode, "grFogMode"); | |||
GET_FUNCTION(grFogTable, "grFogTable"); | |||
GET_FUNCTION(grLoadGammaTable, "grLoadGammaTable"); | |||
GET_FUNCTION(grSplash, "grSplash"); | |||
GET_FUNCTION(grGet, "grGet"); | |||
GET_FUNCTION(grGetString, "grGetString"); | |||
GET_FUNCTION(grQueryResolutions, "grQueryResolutions"); | |||
GET_FUNCTION(grReset, "grReset"); | |||
GET_FUNCTION(grGetProcAddress, "grGetProcAddress"); | |||
GET_FUNCTION(grEnable, "grEnable"); | |||
GET_FUNCTION(grDisable, "grDisable"); | |||
GET_FUNCTION(grCoordinateSpace, "grCoordinateSpace"); | |||
GET_FUNCTION(grDepthRange, "grDepthRange"); | |||
GET_FUNCTION(grStippleMode, "grStippleMode"); | |||
GET_FUNCTION(grStipplePattern, "grStipplePattern"); | |||
GET_FUNCTION(grViewport, "grViewport"); | |||
GET_FUNCTION(grTexCalcMemRequired, "grTexCalcMemRequired"); | |||
GET_FUNCTION(grTexTextureMemRequired, "grTexTextureMemRequired"); | |||
GET_FUNCTION(grTexMinAddress, "grTexMinAddress"); | |||
GET_FUNCTION(grTexMaxAddress, "grTexMaxAddress"); | |||
GET_FUNCTION(grTexNCCTable, "grTexNCCTable"); | |||
GET_FUNCTION(grTexSource, "grTexSource"); | |||
GET_FUNCTION(grTexClampMode, "grTexClampMode"); | |||
GET_FUNCTION(grTexCombine, "grTexCombine"); | |||
GET_FUNCTION(grTexDetailControl, "grTexDetailControl"); | |||
GET_FUNCTION(grTexFilterMode, "grTexFilterMode"); | |||
GET_FUNCTION(grTexLodBiasValue, "grTexLodBiasValue"); | |||
GET_FUNCTION(grTexDownloadMipMap, "grTexDownloadMipMap"); | |||
GET_FUNCTION(grTexDownloadMipMapLevel, "grTexDownloadMipMapLevel"); | |||
GET_FUNCTION(grTexDownloadMipMapLevelPartial, "grTexDownloadMipMapLevelPartial"); | |||
GET_FUNCTION(grTexDownloadTable, "grTexDownloadTable"); | |||
GET_FUNCTION(grTexDownloadTablePartial, "grTexDownloadTablePartial"); | |||
GET_FUNCTION(grTexMipMapMode, "grTexMipMapMode"); | |||
GET_FUNCTION(grTexMultibase, "grTexMultibase"); | |||
GET_FUNCTION(grTexMultibaseAddress, "grTexMultibaseAddress"); | |||
GET_FUNCTION(grLfbLock, "grLfbLock"); | |||
GET_FUNCTION(grLfbUnlock, "grLfbUnlock"); | |||
GET_FUNCTION(grLfbConstantAlpha, "grLfbConstantAlpha"); | |||
GET_FUNCTION(grLfbConstantDepth, "grLfbConstantDepth"); | |||
GET_FUNCTION(grLfbWriteColorSwizzle, "grLfbWriteColorSwizzle"); | |||
GET_FUNCTION(grLfbWriteColorFormat, "grLfbWriteColorFormat"); | |||
GET_FUNCTION(grLfbWriteRegion, "grLfbWriteRegion"); | |||
GET_FUNCTION(grLfbReadRegion, "grLfbReadRegion"); | |||
GET_FUNCTION(grGlideInit, "grGlideInit"); | |||
GET_FUNCTION(grGlideShutdown, "grGlideShutdown"); | |||
GET_FUNCTION(grGlideGetState, "grGlideGetState"); | |||
GET_FUNCTION(grGlideSetState, "grGlideSetState"); | |||
GET_FUNCTION(grGlideGetVertexLayout, "grGlideGetVertexLayout"); | |||
GET_FUNCTION(grGlideSetVertexLayout, "grGlideSetVertexLayout"); | |||
/* Glide utility functions */ | |||
GET_FUNCTION(guFogGenerateExp, "guFogGenerateExp"); | |||
GET_FUNCTION(guFogGenerateExp2, "guFogGenerateExp2"); | |||
GET_FUNCTION(guFogGenerateLinear, "guFogGenerateLinear"); | |||
/* DRI functions */ | |||
GET_FUNCTION(grDRIOpen, "grDRIOpen"); | |||
GET_FUNCTION(grDRIPosition, "grDRIPosition"); | |||
/*GET_FUNCTION(grDRILostContext, "grDRILostContext");*/ | |||
GET_FUNCTION(grDRIImportFifo, "grDRIImportFifo"); | |||
GET_FUNCTION(grDRIInvalidateAll, "grDRIInvalidateAll"); | |||
GET_FUNCTION(grDRIResetSAREA, "grDRIResetSAREA"); | |||
GET_FUNCTION(grDRIBufferSwap, "grDRIBufferSwap"); | |||
/* | |||
* Extension functions: | |||
* Just use dlysm() because we want a NULL pointer if the function is | |||
* not found. | |||
*/ | |||
/* PIXEXT extension */ | |||
tmesa->Glide.grStencilFunc = dlsym(libHandle, "grStencilFunc"); | |||
tmesa->Glide.grStencilMask = dlsym(libHandle, "grStencilMask"); | |||
tmesa->Glide.grStencilOp = dlsym(libHandle, "grStencilOp"); | |||
tmesa->Glide.grBufferClearExt = dlsym(libHandle, "grBufferClearExt"); | |||
tmesa->Glide.grColorMaskExt = dlsym(libHandle, "grColorMaskExt"); | |||
/* COMBINE extension */ | |||
tmesa->Glide.grColorCombineExt = dlsym(libHandle, "grColorCombineExt"); | |||
tmesa->Glide.grTexColorCombineExt = dlsym(libHandle, "grTexColorCombineExt"); | |||
tmesa->Glide.grAlphaCombineExt = dlsym(libHandle, "grAlphaCombineExt"); | |||
tmesa->Glide.grTexAlphaCombineExt = dlsym(libHandle, "grTexAlphaCombineExt"); | |||
tmesa->Glide.grAlphaBlendFunctionExt = dlsym(libHandle, "grAlphaBlendFunctionExt"); | |||
tmesa->Glide.grConstantColorValueExt = dlsym(libHandle, "grConstantColorValueExt"); | |||
/* Texus 2 */ | |||
tmesa->Glide.txImgQuantize = dlsym(libHandle, "txImgQuantize"); | |||
tmesa->Glide.txImgDequantizeFXT1 = dlsym(libHandle, "_txImgDequantizeFXT1"); | |||
tmesa->Glide.txErrorSetCallback = dlsym(libHandle, "txErrorSetCallback"); | |||
#ifdef DEBUG_TRAP | |||
/* wrap the drawing functions so we can trap them */ | |||
real_grDrawTriangle = tmesa->Glide.grDrawTriangle; | |||
tmesa->Glide.grDrawTriangle = debug_grDrawTriangle; | |||
real_grDrawPoint = tmesa->Glide.grDrawPoint; | |||
tmesa->Glide.grDrawPoint = debug_grDrawPoint; | |||
real_grDrawVertexArray = tmesa->Glide.grDrawVertexArray; | |||
tmesa->Glide.grDrawVertexArray = debug_grDrawVertexArray; | |||
real_grDrawVertexArrayContiguous = tmesa->Glide.grDrawVertexArrayContiguous; | |||
tmesa->Glide.grDrawVertexArrayContiguous = debug_grDrawVertexArrayContiguous; | |||
real_grClipWindow = tmesa->Glide.grClipWindow; | |||
tmesa->Glide.grClipWindow = debug_grClipWindow; | |||
real_grVertexLayout = tmesa->Glide.grVertexLayout; | |||
tmesa->Glide.grVertexLayout = debug_grVertexLayout; | |||
real_grGlideGetVertexLayout = tmesa->Glide.grGlideGetVertexLayout; | |||
tmesa->Glide.grGlideGetVertexLayout = debug_grGlideGetVertexLayout; | |||
real_grGlideSetVertexLayout = tmesa->Glide.grGlideSetVertexLayout; | |||
tmesa->Glide.grGlideSetVertexLayout = debug_grGlideSetVertexLayout; | |||
real_grTexDownloadMipMapLevel = tmesa->Glide.grTexDownloadMipMapLevel; | |||
tmesa->Glide.grTexDownloadMipMapLevel = debug_grTexDownloadMipMapLevel; | |||
#endif | |||
return GL_TRUE; | |||
} |
@@ -0,0 +1,330 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c,v 1.10 2002/10/30 12:52:00 alanh Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#include "tdfx_context.h" | |||
#include "tdfx_dd.h" | |||
#include "tdfx_lock.h" | |||
#include "tdfx_vb.h" | |||
#include "tdfx_pixels.h" | |||
#include "context.h" | |||
#include "enums.h" | |||
#include "swrast/swrast.h" | |||
#if defined(USE_X86_ASM) | |||
#include "X86/common_x86_asm.h" | |||
#endif | |||
#define TDFX_DATE "20021125" | |||
/* These are used in calls to FX_grColorMaskv() */ | |||
const GLboolean false4[4] = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE }; | |||
const GLboolean true4[4] = { GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE }; | |||
/* KW: Put the word Mesa in the render string because quakeworld | |||
* checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE). | |||
* Why? | |||
*/ | |||
static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name ) | |||
{ | |||
tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; | |||
switch ( name ) { | |||
case GL_RENDERER: | |||
{ | |||
/* The renderer string must be per-context state to handle | |||
* multihead correctly. | |||
*/ | |||
char *buffer = fxMesa->rendererString; | |||
char hardware[100]; | |||
LOCK_HARDWARE(fxMesa); | |||
strcpy( hardware, fxMesa->Glide.grGetString(GR_HARDWARE) ); | |||
UNLOCK_HARDWARE(fxMesa); | |||
strcpy( buffer, "Mesa DRI " ); | |||
strcat( buffer, TDFX_DATE ); | |||
strcat( buffer, " " ); | |||
if ( strcmp( hardware, "Voodoo3 (tm)" ) == 0 ) { | |||
strcat( buffer, "Voodoo3" ); | |||
} | |||
else if ( strcmp( hardware, "Voodoo Banshee (tm)" ) == 0 ) { | |||
strcat( buffer, "VoodooBanshee" ); | |||
} | |||
else if ( strcmp( hardware, "Voodoo4 (tm)" ) == 0 ) { | |||
strcat( buffer, "Voodoo4" ); | |||
} | |||
else if ( strcmp( hardware, "Voodoo5 (tm)" ) == 0 ) { | |||
strcat( buffer, "Voodoo5" ); | |||
} | |||
else { | |||
/* unexpected result: replace spaces with hyphens */ | |||
int i; | |||
for ( i = 0 ; hardware[i] && i < 60 ; i++ ) { | |||
if ( hardware[i] == ' ' || hardware[i] == '\t' ) | |||
hardware[i] = '-'; | |||
} | |||
strcat( buffer, hardware ); | |||
} | |||
/* Append any CPU-specific information. | |||
*/ | |||
#ifdef USE_X86_ASM | |||
if ( _mesa_x86_cpu_features ) { | |||
strncat( buffer, " x86", 4 ); | |||
} | |||
#endif | |||
#ifdef USE_MMX_ASM | |||
if ( cpu_has_mmx ) { | |||
strncat( buffer, "/MMX", 4 ); | |||
} | |||
#endif | |||
#ifdef USE_3DNOW_ASM | |||
if ( cpu_has_3dnow ) { | |||
strncat( buffer, "/3DNow!", 7 ); | |||
} | |||
#endif | |||
#ifdef USE_SSE_ASM | |||
if ( cpu_has_xmm ) { | |||
strncat( buffer, "/SSE", 4 ); | |||
} | |||
#endif | |||
return (const GLubyte *) buffer; | |||
} | |||
case GL_VENDOR: | |||
return (const GLubyte *)"VA Linux Systems, Inc."; | |||
default: | |||
return NULL; | |||
} | |||
} | |||
/* Return uptodate buffer size information. | |||
*/ | |||
static void tdfxDDGetBufferSize( GLframebuffer *buffer, | |||
GLuint *width, GLuint *height ) | |||
{ | |||
GET_CURRENT_CONTEXT(ctx); | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
LOCK_HARDWARE( fxMesa ); | |||
*width = fxMesa->width; | |||
*height = fxMesa->height; | |||
UNLOCK_HARDWARE( fxMesa ); | |||
} | |||
/* | |||
* Return the current value of the occlusion test flag and | |||
* reset the flag (hardware counters) to false. | |||
*/ | |||
static GLboolean get_occlusion_result( GLcontext *ctx ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
GLboolean result; | |||
LOCK_HARDWARE( fxMesa ); | |||
fxMesa->Glide.grFinish(); /* required to flush the FIFO - FB 21-01-2002 */ | |||
if (ctx->Depth.OcclusionTest) { | |||
if (ctx->OcclusionResult) { | |||
result = GL_TRUE; /* result of software rendering */ | |||
} | |||
else { | |||
FxI32 zfail, in; | |||
fxMesa->Glide.grGet(GR_STATS_PIXELS_DEPTHFUNC_FAIL, 4, &zfail); | |||
fxMesa->Glide.grGet(GR_STATS_PIXELS_IN, 4, &in); | |||
/* Geometry is occluded if there is no input (in == 0) */ | |||
/* or if all pixels failed the depth test (zfail == in) */ | |||
/* The < 1 is there because I have empirically seen cases where */ | |||
/* zfail > in.... go figure. FB - 21-01-2002. */ | |||
result = ((in - zfail) < 1 || in == 0) ? GL_FALSE : GL_TRUE; | |||
} | |||
} | |||
else { | |||
result = ctx->OcclusionResultSaved; | |||
} | |||
/* reset results now */ | |||
fxMesa->Glide.grReset(GR_STATS_PIXELS); | |||
ctx->OcclusionResult = GL_FALSE; | |||
ctx->OcclusionResultSaved = GL_FALSE; | |||
UNLOCK_HARDWARE( fxMesa ); | |||
return result; | |||
} | |||
/* | |||
* We're only implementing this function to handle the | |||
* GL_OCCLUSTION_TEST_RESULT_HP case. It's special because it | |||
* has a side-effect: resetting the occlustion result flag. | |||
*/ | |||
static GLboolean tdfxDDGetBooleanv( GLcontext *ctx, GLenum pname, | |||
GLboolean *result ) | |||
{ | |||
if ( pname == GL_OCCLUSION_TEST_RESULT_HP ) { | |||
*result = get_occlusion_result( ctx ); | |||
return GL_TRUE; | |||
} | |||
return GL_FALSE; | |||
} | |||
static GLboolean tdfxDDGetDoublev( GLcontext *ctx, GLenum pname, | |||
GLdouble *result ) | |||
{ | |||
if ( pname == GL_OCCLUSION_TEST_RESULT_HP ) { | |||
*result = (GLdouble) get_occlusion_result( ctx ); | |||
return GL_TRUE; | |||
} | |||
return GL_FALSE; | |||
} | |||
static GLboolean tdfxDDGetFloatv( GLcontext *ctx, GLenum pname, | |||
GLfloat *result ) | |||
{ | |||
if ( pname == GL_OCCLUSION_TEST_RESULT_HP ) { | |||
*result = (GLfloat) get_occlusion_result( ctx ); | |||
return GL_TRUE; | |||
} | |||
return GL_FALSE; | |||
} | |||
static GLboolean tdfxDDGetIntegerv( GLcontext *ctx, GLenum pname, | |||
GLint *result ) | |||
{ | |||
if ( pname == GL_OCCLUSION_TEST_RESULT_HP ) { | |||
*result = (GLint) get_occlusion_result( ctx ); | |||
return GL_TRUE; | |||
} | |||
return GL_FALSE; | |||
} | |||
#define VISUAL_EQUALS_RGBA(vis, r, g, b, a) \ | |||
((vis.redBits == r) && \ | |||
(vis.greenBits == g) && \ | |||
(vis.blueBits == b) && \ | |||
(vis.alphaBits == a)) | |||
void tdfxDDInitDriverFuncs( GLcontext *ctx ) | |||
{ | |||
if ( MESA_VERBOSE & VERBOSE_DRIVER ) { | |||
fprintf( stderr, "tdfx: %s()\n", __FUNCTION__ ); | |||
} | |||
ctx->Driver.GetString = tdfxDDGetString; | |||
ctx->Driver.GetBufferSize = tdfxDDGetBufferSize; | |||
ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; | |||
ctx->Driver.Error = NULL; | |||
/* Pixel path fallbacks. | |||
*/ | |||
ctx->Driver.Accum = _swrast_Accum; | |||
ctx->Driver.Bitmap = _swrast_Bitmap; | |||
ctx->Driver.CopyPixels = _swrast_CopyPixels; | |||
ctx->Driver.DrawPixels = _swrast_DrawPixels; | |||
ctx->Driver.ReadPixels = _swrast_ReadPixels; | |||
/* Accelerated paths | |||
*/ | |||
if ( VISUAL_EQUALS_RGBA(ctx->Visual, 8, 8, 8, 8) ) | |||
{ | |||
ctx->Driver.DrawPixels = tdfx_drawpixels_R8G8B8A8; | |||
ctx->Driver.ReadPixels = tdfx_readpixels_R8G8B8A8; | |||
} | |||
else if ( VISUAL_EQUALS_RGBA(ctx->Visual, 5, 6, 5, 0) ) | |||
{ | |||
ctx->Driver.ReadPixels = tdfx_readpixels_R5G6B5; | |||
} | |||
ctx->Driver.GetBooleanv = tdfxDDGetBooleanv; | |||
ctx->Driver.GetDoublev = tdfxDDGetDoublev; | |||
ctx->Driver.GetFloatv = tdfxDDGetFloatv; | |||
ctx->Driver.GetIntegerv = tdfxDDGetIntegerv; | |||
ctx->Driver.GetPointerv = NULL; | |||
} | |||
/* | |||
* These are here for lack of a better place. | |||
*/ | |||
void | |||
FX_grColorMaskv(GLcontext *ctx, const GLboolean rgba[4]) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
LOCK_HARDWARE(fxMesa); | |||
if (ctx->Visual.redBits == 8) { | |||
/* 32bpp mode */ | |||
ASSERT( fxMesa->Glide.grColorMaskExt ); | |||
fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP], | |||
rgba[BCOMP], rgba[ACOMP]); | |||
} | |||
else { | |||
/* 16 bpp mode */ | |||
/* we never have an alpha buffer */ | |||
fxMesa->Glide.grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], | |||
GL_FALSE); | |||
} | |||
UNLOCK_HARDWARE(fxMesa); | |||
} | |||
void | |||
FX_grColorMaskv_NoLock(GLcontext *ctx, const GLboolean rgba[4]) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
if (ctx->Visual.redBits == 8) { | |||
/* 32bpp mode */ | |||
ASSERT( fxMesa->Glide.grColorMaskExt ); | |||
fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP], | |||
rgba[BCOMP], rgba[ACOMP]); | |||
} | |||
else { | |||
/* 16 bpp mode */ | |||
/* we never have an alpha buffer */ | |||
fxMesa->Glide.grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], | |||
GL_FALSE); | |||
} | |||
} |
@@ -0,0 +1,47 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.h,v 1.1 2001/03/21 16:14:27 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_DD_H__ | |||
#define __TDFX_DD_H__ | |||
#ifdef GLX_DIRECT_RENDERING | |||
#include "context.h" | |||
extern void tdfxDDInitDriverFuncs( GLcontext *ctx ); | |||
#endif | |||
#endif |
@@ -0,0 +1,606 @@ | |||
/* | |||
* This file defines macros and types necessary for accessing glide3. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_glide.h,v 1.1 2002/02/22 21:45:03 dawes Exp $ */ | |||
#ifndef NEWGLIDE_H | |||
#define NEWGLIDE_H | |||
#define FX_CALL | |||
typedef unsigned char FxU8; | |||
typedef signed char FxI8; | |||
typedef unsigned short FxU16; | |||
typedef signed short FxI16; | |||
#if defined(__alpha__) || defined (__LP64__) | |||
typedef signed int FxI32; | |||
typedef unsigned int FxU32; | |||
#else | |||
typedef signed long FxI32; | |||
typedef unsigned long FxU32; | |||
#endif | |||
typedef unsigned long AnyPtr; | |||
typedef int FxBool; | |||
typedef float FxFloat; | |||
typedef double FxDouble; | |||
typedef unsigned long FxColor_t; | |||
typedef struct | |||
{ | |||
float r, g, b, a; | |||
} | |||
FxColor4; | |||
typedef FxU32 GrColor_t; | |||
typedef FxU8 GrAlpha_t; | |||
typedef FxU32 GrMipMapId_t; | |||
typedef FxU32 GrStipplePattern_t; | |||
typedef FxU8 GrFog_t; | |||
typedef FxU32 GrContext_t; | |||
typedef int (FX_CALL * GrProc) (void); | |||
#define FXTRUE 1 | |||
#define FXFALSE 0 | |||
#define FXBIT(i) (1L << (i)) | |||
#define GR_NULL_MIPMAP_HANDLE ((GrMipMapId_t) -1) | |||
#define GR_MIPMAPLEVELMASK_EVEN FXBIT(0) | |||
#define GR_MIPMAPLEVELMASK_ODD FXBIT(1) | |||
#define GR_MIPMAPLEVELMASK_BOTH (GR_MIPMAPLEVELMASK_EVEN | GR_MIPMAPLEVELMASK_ODD ) | |||
typedef FxI32 GrChipID_t; | |||
#define GR_TMU0 0x0 | |||
#define GR_TMU1 0x1 | |||
#define GR_TMU2 0x2 | |||
#define GR_FBI 0x0 | |||
typedef FxI32 GrCombineFunction_t; | |||
#define GR_COMBINE_FUNCTION_ZERO 0x0 | |||
#define GR_COMBINE_FUNCTION_NONE GR_COMBINE_FUNCTION_ZERO | |||
#define GR_COMBINE_FUNCTION_LOCAL 0x1 | |||
#define GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2 | |||
#define GR_COMBINE_FUNCTION_SCALE_OTHER 0x3 | |||
#define GR_COMBINE_FUNCTION_BLEND_OTHER GR_COMBINE_FUNCTION_SCALE_OTHER | |||
#define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4 | |||
#define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5 | |||
#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6 | |||
#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7 | |||
#define GR_COMBINE_FUNCTION_BLEND GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL | |||
#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8 | |||
#define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9 | |||
#define GR_COMBINE_FUNCTION_BLEND_LOCAL GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL | |||
#define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10 | |||
typedef FxI32 GrCombineFactor_t; | |||
#define GR_COMBINE_FACTOR_ZERO 0x0 | |||
#define GR_COMBINE_FACTOR_NONE GR_COMBINE_FACTOR_ZERO | |||
#define GR_COMBINE_FACTOR_LOCAL 0x1 | |||
#define GR_COMBINE_FACTOR_OTHER_ALPHA 0x2 | |||
#define GR_COMBINE_FACTOR_LOCAL_ALPHA 0x3 | |||
#define GR_COMBINE_FACTOR_TEXTURE_ALPHA 0x4 | |||
#define GR_COMBINE_FACTOR_TEXTURE_RGB 0x5 | |||
#define GR_COMBINE_FACTOR_DETAIL_FACTOR GR_COMBINE_FACTOR_TEXTURE_ALPHA | |||
#define GR_COMBINE_FACTOR_LOD_FRACTION 0x5 | |||
#define GR_COMBINE_FACTOR_ONE 0x8 | |||
#define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL 0x9 | |||
#define GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA 0xa | |||
#define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA 0xb | |||
#define GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA 0xc | |||
#define GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA | |||
#define GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION 0xd | |||
typedef FxI32 GrCombineLocal_t; | |||
#define GR_COMBINE_LOCAL_ITERATED 0x0 | |||
#define GR_COMBINE_LOCAL_CONSTANT 0x1 | |||
#define GR_COMBINE_LOCAL_NONE GR_COMBINE_LOCAL_CONSTANT | |||
#define GR_COMBINE_LOCAL_DEPTH 0x2 | |||
typedef FxI32 GrCombineOther_t; | |||
#define GR_COMBINE_OTHER_ITERATED 0x0 | |||
#define GR_COMBINE_OTHER_TEXTURE 0x1 | |||
#define GR_COMBINE_OTHER_CONSTANT 0x2 | |||
#define GR_COMBINE_OTHER_NONE GR_COMBINE_OTHER_CONSTANT | |||
typedef FxI32 GrAlphaSource_t; | |||
#define GR_ALPHASOURCE_CC_ALPHA 0x0 | |||
#define GR_ALPHASOURCE_ITERATED_ALPHA 0x1 | |||
#define GR_ALPHASOURCE_TEXTURE_ALPHA 0x2 | |||
#define GR_ALPHASOURCE_TEXTURE_ALPHA_TIMES_ITERATED_ALPHA 0x3 | |||
typedef FxI32 GrColorCombineFnc_t; | |||
#define GR_COLORCOMBINE_ZERO 0x0 | |||
#define GR_COLORCOMBINE_CCRGB 0x1 | |||
#define GR_COLORCOMBINE_ITRGB 0x2 | |||
#define GR_COLORCOMBINE_ITRGB_DELTA0 0x3 | |||
#define GR_COLORCOMBINE_DECAL_TEXTURE 0x4 | |||
#define GR_COLORCOMBINE_TEXTURE_TIMES_CCRGB 0x5 | |||
#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB 0x6 | |||
#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_DELTA0 0x7 | |||
#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_ADD_ALPHA 0x8 | |||
#define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA 0x9 | |||
#define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA_ADD_ITRGB 0xa | |||
#define GR_COLORCOMBINE_TEXTURE_ADD_ITRGB 0xb | |||
#define GR_COLORCOMBINE_TEXTURE_SUB_ITRGB 0xc | |||
#define GR_COLORCOMBINE_CCRGB_BLEND_ITRGB_ON_TEXALPHA 0xd | |||
#define GR_COLORCOMBINE_DIFF_SPEC_A 0xe | |||
#define GR_COLORCOMBINE_DIFF_SPEC_B 0xf | |||
#define GR_COLORCOMBINE_ONE 0x10 | |||
typedef FxI32 GrAlphaBlendFnc_t; | |||
#define GR_BLEND_ZERO 0x0 | |||
#define GR_BLEND_SRC_ALPHA 0x1 | |||
#define GR_BLEND_SRC_COLOR 0x2 | |||
#define GR_BLEND_DST_COLOR GR_BLEND_SRC_COLOR | |||
#define GR_BLEND_DST_ALPHA 0x3 | |||
#define GR_BLEND_ONE 0x4 | |||
#define GR_BLEND_ONE_MINUS_SRC_ALPHA 0x5 | |||
#define GR_BLEND_ONE_MINUS_SRC_COLOR 0x6 | |||
#define GR_BLEND_ONE_MINUS_DST_COLOR GR_BLEND_ONE_MINUS_SRC_COLOR | |||
#define GR_BLEND_ONE_MINUS_DST_ALPHA 0x7 | |||
#define GR_BLEND_RESERVED_8 0x8 | |||
#define GR_BLEND_RESERVED_9 0x9 | |||
#define GR_BLEND_RESERVED_A 0xa | |||
#define GR_BLEND_RESERVED_B 0xb | |||
#define GR_BLEND_RESERVED_C 0xc | |||
#define GR_BLEND_RESERVED_D 0xd | |||
#define GR_BLEND_RESERVED_E 0xe | |||
#define GR_BLEND_ALPHA_SATURATE 0xf | |||
#define GR_BLEND_PREFOG_COLOR GR_BLEND_ALPHA_SATURATE | |||
#define GR_BLEND_SAME_COLOR_EXT 0x08 | |||
#define GR_BLEND_ONE_MINUS_SAME_COLOR_EXT 0x09 | |||
typedef FxI32 GrAspectRatio_t; | |||
#define GR_ASPECT_LOG2_8x1 3 | |||
#define GR_ASPECT_LOG2_4x1 2 | |||
#define GR_ASPECT_LOG2_2x1 1 | |||
#define GR_ASPECT_LOG2_1x1 0 | |||
#define GR_ASPECT_LOG2_1x2 -1 | |||
#define GR_ASPECT_LOG2_1x4 -2 | |||
#define GR_ASPECT_LOG2_1x8 -3 | |||
typedef FxI32 GrBuffer_t; | |||
#define GR_BUFFER_FRONTBUFFER 0x0 | |||
#define GR_BUFFER_BACKBUFFER 0x1 | |||
#define GR_BUFFER_AUXBUFFER 0x2 | |||
#define GR_BUFFER_DEPTHBUFFER 0x3 | |||
#define GR_BUFFER_ALPHABUFFER 0x4 | |||
#define GR_BUFFER_TRIPLEBUFFER 0x5 | |||
typedef FxI32 GrChromakeyMode_t; | |||
#define GR_CHROMAKEY_DISABLE 0x0 | |||
#define GR_CHROMAKEY_ENABLE 0x1 | |||
typedef FxI32 GrChromaRangeMode_t; | |||
#define GR_CHROMARANGE_RGB_ALL_EXT 0x0 | |||
#define GR_CHROMARANGE_DISABLE_EXT 0x00 | |||
#define GR_CHROMARANGE_ENABLE_EXT 0x01 | |||
typedef FxI32 GrTexChromakeyMode_t; | |||
#define GR_TEXCHROMA_DISABLE_EXT 0x0 | |||
#define GR_TEXCHROMA_ENABLE_EXT 0x1 | |||
#define GR_TEXCHROMARANGE_RGB_ALL_EXT 0x0 | |||
typedef FxI32 GrCmpFnc_t; | |||
#define GR_CMP_NEVER 0x0 | |||
#define GR_CMP_LESS 0x1 | |||
#define GR_CMP_EQUAL 0x2 | |||
#define GR_CMP_LEQUAL 0x3 | |||
#define GR_CMP_GREATER 0x4 | |||
#define GR_CMP_NOTEQUAL 0x5 | |||
#define GR_CMP_GEQUAL 0x6 | |||
#define GR_CMP_ALWAYS 0x7 | |||
typedef FxI32 GrColorFormat_t; | |||
#define GR_COLORFORMAT_ARGB 0x0 | |||
#define GR_COLORFORMAT_ABGR 0x1 | |||
#define GR_COLORFORMAT_RGBA 0x2 | |||
#define GR_COLORFORMAT_BGRA 0x3 | |||
typedef FxI32 GrCullMode_t; | |||
#define GR_CULL_DISABLE 0x0 | |||
#define GR_CULL_NEGATIVE 0x1 | |||
#define GR_CULL_POSITIVE 0x2 | |||
typedef FxI32 GrDepthBufferMode_t; | |||
#define GR_DEPTHBUFFER_DISABLE 0x0 | |||
#define GR_DEPTHBUFFER_ZBUFFER 0x1 | |||
#define GR_DEPTHBUFFER_WBUFFER 0x2 | |||
#define GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS 0x3 | |||
#define GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS 0x4 | |||
typedef FxI32 GrDitherMode_t; | |||
#define GR_DITHER_DISABLE 0x0 | |||
#define GR_DITHER_2x2 0x1 | |||
#define GR_DITHER_4x4 0x2 | |||
typedef FxI32 GrStippleMode_t; | |||
#define GR_STIPPLE_DISABLE 0x0 | |||
#define GR_STIPPLE_PATTERN 0x1 | |||
#define GR_STIPPLE_ROTATE 0x2 | |||
typedef FxI32 GrFogMode_t; | |||
#define GR_FOG_DISABLE 0x0 | |||
#define GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT 0x1 | |||
#define GR_FOG_WITH_TABLE_ON_Q 0x2 | |||
#define GR_FOG_WITH_TABLE_ON_W GR_FOG_WITH_TABLE_ON_Q | |||
#define GR_FOG_WITH_ITERATED_Z 0x3 | |||
#define GR_FOG_WITH_ITERATED_ALPHA_EXT 0x4 | |||
#define GR_FOG_MULT2 0x100 | |||
#define GR_FOG_ADD2 0x200 | |||
typedef FxU32 GrLock_t; | |||
#define GR_LFB_READ_ONLY 0x00 | |||
#define GR_LFB_WRITE_ONLY 0x01 | |||
#define GR_LFB_IDLE 0x00 | |||
#define GR_LFB_NOIDLE 0x10 | |||
typedef FxI32 GrLfbBypassMode_t; | |||
#define GR_LFBBYPASS_DISABLE 0x0 | |||
#define GR_LFBBYPASS_ENABLE 0x1 | |||
typedef FxI32 GrLfbWriteMode_t; | |||
#define GR_LFBWRITEMODE_565 0x0 | |||
#define GR_LFBWRITEMODE_555 0x1 | |||
#define GR_LFBWRITEMODE_1555 0x2 | |||
#define GR_LFBWRITEMODE_RESERVED1 0x3 | |||
#define GR_LFBWRITEMODE_888 0x4 | |||
#define GR_LFBWRITEMODE_8888 0x5 | |||
#define GR_LFBWRITEMODE_RESERVED2 0x6 | |||
#define GR_LFBWRITEMODE_RESERVED3 0x7 | |||
#define GR_LFBWRITEMODE_RESERVED4 0x8 | |||
#define GR_LFBWRITEMODE_RESERVED5 0x9 | |||
#define GR_LFBWRITEMODE_RESERVED6 0xa | |||
#define GR_LFBWRITEMODE_RESERVED7 0xb | |||
#define GR_LFBWRITEMODE_565_DEPTH 0xc | |||
#define GR_LFBWRITEMODE_555_DEPTH 0xd | |||
#define GR_LFBWRITEMODE_1555_DEPTH 0xe | |||
#define GR_LFBWRITEMODE_ZA16 0xf | |||
#define GR_LFBWRITEMODE_ANY 0xFF | |||
typedef FxI32 GrOriginLocation_t; | |||
#define GR_ORIGIN_UPPER_LEFT 0x0 | |||
#define GR_ORIGIN_LOWER_LEFT 0x1 | |||
#define GR_ORIGIN_ANY 0xFF | |||
typedef struct | |||
{ | |||
int size; | |||
void *lfbPtr; | |||
FxU32 strideInBytes; | |||
GrLfbWriteMode_t writeMode; | |||
GrOriginLocation_t origin; | |||
} | |||
GrLfbInfo_t; | |||
typedef FxI32 GrLOD_t; | |||
#define GR_LOD_LOG2_2048 0xb | |||
#define GR_LOD_LOG2_1024 0xa | |||
#define GR_LOD_LOG2_512 0x9 | |||
#define GR_LOD_LOG2_256 0x8 | |||
#define GR_LOD_LOG2_128 0x7 | |||
#define GR_LOD_LOG2_64 0x6 | |||
#define GR_LOD_LOG2_32 0x5 | |||
#define GR_LOD_LOG2_16 0x4 | |||
#define GR_LOD_LOG2_8 0x3 | |||
#define GR_LOD_LOG2_4 0x2 | |||
#define GR_LOD_LOG2_2 0x1 | |||
#define GR_LOD_LOG2_1 0x0 | |||
typedef FxI32 GrMipMapMode_t; | |||
#define GR_MIPMAP_DISABLE 0x0 | |||
#define GR_MIPMAP_NEAREST 0x1 | |||
#define GR_MIPMAP_NEAREST_DITHER 0x2 | |||
typedef FxI32 GrSmoothingMode_t; | |||
#define GR_SMOOTHING_DISABLE 0x0 | |||
#define GR_SMOOTHING_ENABLE 0x1 | |||
typedef FxI32 GrTextureClampMode_t; | |||
#define GR_TEXTURECLAMP_WRAP 0x0 | |||
#define GR_TEXTURECLAMP_CLAMP 0x1 | |||
#define GR_TEXTURECLAMP_MIRROR_EXT 0x2 | |||
typedef FxI32 GrTextureCombineFnc_t; | |||
#define GR_TEXTURECOMBINE_ZERO 0x0 | |||
#define GR_TEXTURECOMBINE_DECAL 0x1 | |||
#define GR_TEXTURECOMBINE_OTHER 0x2 | |||
#define GR_TEXTURECOMBINE_ADD 0x3 | |||
#define GR_TEXTURECOMBINE_MULTIPLY 0x4 | |||
#define GR_TEXTURECOMBINE_SUBTRACT 0x5 | |||
#define GR_TEXTURECOMBINE_DETAIL 0x6 | |||
#define GR_TEXTURECOMBINE_DETAIL_OTHER 0x7 | |||
#define GR_TEXTURECOMBINE_TRILINEAR_ODD 0x8 | |||
#define GR_TEXTURECOMBINE_TRILINEAR_EVEN 0x9 | |||
#define GR_TEXTURECOMBINE_ONE 0xa | |||
typedef FxI32 GrTextureFilterMode_t; | |||
#define GR_TEXTUREFILTER_POINT_SAMPLED 0x0 | |||
#define GR_TEXTUREFILTER_BILINEAR 0x1 | |||
typedef FxI32 GrTextureFormat_t; | |||
#define GR_TEXFMT_8BIT 0x0 | |||
#define GR_TEXFMT_RGB_332 GR_TEXFMT_8BIT | |||
#define GR_TEXFMT_YIQ_422 0x1 | |||
#define GR_TEXFMT_ALPHA_8 0x2 | |||
#define GR_TEXFMT_INTENSITY_8 0x3 | |||
#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4 | |||
#define GR_TEXFMT_P_8 0x5 | |||
#define GR_TEXFMT_RSVD0 0x6 | |||
#define GR_TEXFMT_RSVD1 0x7 | |||
#define GR_TEXFMT_16BIT 0x8 | |||
#define GR_TEXFMT_ARGB_8332 GR_TEXFMT_16BIT | |||
#define GR_TEXFMT_AYIQ_8422 0x9 | |||
#define GR_TEXFMT_RGB_565 0xa | |||
#define GR_TEXFMT_ARGB_1555 0xb | |||
#define GR_TEXFMT_ARGB_4444 0xc | |||
#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd | |||
#define GR_TEXFMT_AP_88 0xe | |||
#define GR_TEXFMT_RSVD2 0xf | |||
#define GR_TEXFMT_ARGB_CMP_FXT1 0x11 | |||
#define GR_TEXFMT_ARGB_8888 0x12 | |||
#define GR_TEXFMT_YUYV_422 0x13 | |||
#define GR_TEXFMT_UYVY_422 0x14 | |||
#define GR_TEXFMT_AYUV_444 0x15 | |||
#define GR_TEXFMT_ARGB_CMP_DXT1 0x16 | |||
#define GR_TEXFMT_ARGB_CMP_DXT2 0x17 | |||
#define GR_TEXFMT_ARGB_CMP_DXT3 0x18 | |||
#define GR_TEXFMT_ARGB_CMP_DXT4 0x19 | |||
#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A | |||
typedef FxU32 GrTexTable_t; | |||
#define GR_TEXTABLE_NCC0 0x0 | |||
#define GR_TEXTABLE_NCC1 0x1 | |||
#define GR_TEXTABLE_PALETTE 0x2 | |||
#define GR_TEXTABLE_PALETTE_6666_EXT 0x3 | |||
typedef FxU32 GrNCCTable_t; | |||
#define GR_NCCTABLE_NCC0 0x0 | |||
#define GR_NCCTABLE_NCC1 0x1 | |||
typedef FxU32 GrTexBaseRange_t; | |||
#define GR_TEXBASE_256 0x3 | |||
#define GR_TEXBASE_128 0x2 | |||
#define GR_TEXBASE_64 0x1 | |||
#define GR_TEXBASE_32_TO_1 0x0 | |||
#define GR_TEXBASE_2048 0x7 | |||
#define GR_TEXBASE_1024 0x6 | |||
#define GR_TEXBASE_512 0x5 | |||
#define GR_TEXBASE_256_TO_1 0x4 | |||
typedef FxU32 GrEnableMode_t; | |||
#define GR_MODE_DISABLE 0x0 | |||
#define GR_MODE_ENABLE 0x1 | |||
#define GR_AA_ORDERED 0x01 | |||
#define GR_ALLOW_MIPMAP_DITHER 0x02 | |||
#define GR_PASSTHRU 0x03 | |||
#define GR_SHAMELESS_PLUG 0x04 | |||
#define GR_VIDEO_SMOOTHING 0x05 | |||
typedef FxU32 GrCoordinateSpaceMode_t; | |||
#define GR_WINDOW_COORDS 0x00 | |||
#define GR_CLIP_COORDS 0x01 | |||
/* Parameters for strips */ | |||
#define GR_PARAM_XY 0x01 | |||
#define GR_PARAM_Z 0x02 | |||
#define GR_PARAM_W 0x03 | |||
#define GR_PARAM_Q 0x04 | |||
#define GR_PARAM_FOG_EXT 0x05 | |||
#define GR_PARAM_A 0x10 | |||
#define GR_PARAM_RGB 0x20 | |||
#define GR_PARAM_PARGB 0x30 | |||
#define GR_PARAM_ST0 0x40 | |||
#define GR_PARAM_ST1 GR_PARAM_ST0+1 | |||
#define GR_PARAM_ST2 GR_PARAM_ST0+2 | |||
#define GR_PARAM_Q0 0x50 | |||
#define GR_PARAM_Q1 GR_PARAM_Q0+1 | |||
#define GR_PARAM_Q2 GR_PARAM_Q0+2 | |||
#define GR_PARAM_DISABLE 0x00 | |||
#define GR_PARAM_ENABLE 0x01 | |||
/* grDrawVertexArray/grDrawVertexArrayContiguous */ | |||
#define GR_POINTS 0 | |||
#define GR_LINE_STRIP 1 | |||
#define GR_LINES 2 | |||
#define GR_POLYGON 3 | |||
#define GR_TRIANGLE_STRIP 4 | |||
#define GR_TRIANGLE_FAN 5 | |||
#define GR_TRIANGLES 6 | |||
#define GR_TRIANGLE_STRIP_CONTINUE 7 | |||
#define GR_TRIANGLE_FAN_CONTINUE 8 | |||
/* grGet/grReset */ | |||
#define GR_BITS_DEPTH 0x01 | |||
#define GR_BITS_RGBA 0x02 | |||
#define GR_FIFO_FULLNESS 0x03 | |||
#define GR_FOG_TABLE_ENTRIES 0x04 | |||
#define GR_GAMMA_TABLE_ENTRIES 0x05 | |||
#define GR_GLIDE_STATE_SIZE 0x06 | |||
#define GR_GLIDE_VERTEXLAYOUT_SIZE 0x07 | |||
#define GR_IS_BUSY 0x08 | |||
#define GR_LFB_PIXEL_PIPE 0x09 | |||
#define GR_MAX_TEXTURE_SIZE 0x0a | |||
#define GR_MAX_TEXTURE_ASPECT_RATIO 0x0b | |||
#define GR_MEMORY_FB 0x0c | |||
#define GR_MEMORY_TMU 0x0d | |||
#define GR_MEMORY_UMA 0x0e | |||
#define GR_NUM_BOARDS 0x0f | |||
#define GR_NON_POWER_OF_TWO_TEXTURES 0x10 | |||
#define GR_NUM_FB 0x11 | |||
#define GR_NUM_SWAP_HISTORY_BUFFER 0x12 | |||
#define GR_NUM_TMU 0x13 | |||
#define GR_PENDING_BUFFERSWAPS 0x14 | |||
#define GR_REVISION_FB 0x15 | |||
#define GR_REVISION_TMU 0x16 | |||
#define GR_STATS_LINES 0x17 | |||
#define GR_STATS_PIXELS_AFUNC_FAIL 0x18 | |||
#define GR_STATS_PIXELS_CHROMA_FAIL 0x19 | |||
#define GR_STATS_PIXELS_DEPTHFUNC_FAIL 0x1a | |||
#define GR_STATS_PIXELS_IN 0x1b | |||
#define GR_STATS_PIXELS_OUT 0x1c | |||
#define GR_STATS_PIXELS 0x1d | |||
#define GR_STATS_POINTS 0x1e | |||
#define GR_STATS_TRIANGLES_IN 0x1f | |||
#define GR_STATS_TRIANGLES_OUT 0x20 | |||
#define GR_STATS_TRIANGLES 0x21 | |||
#define GR_SWAP_HISTORY 0x22 | |||
#define GR_SUPPORTS_PASSTHRU 0x23 | |||
#define GR_TEXTURE_ALIGN 0x24 | |||
#define GR_VIDEO_POSITION 0x25 | |||
#define GR_VIEWPORT 0x26 | |||
#define GR_WDEPTH_MIN_MAX 0x27 | |||
#define GR_ZDEPTH_MIN_MAX 0x28 | |||
#define GR_VERTEX_PARAMETER 0x29 | |||
#define GR_BITS_GAMMA 0x2a | |||
#define GR_GET_RESERVED_1 0x1000 | |||
/* grGetString types */ | |||
#define GR_EXTENSION 0xa0 | |||
#define GR_HARDWARE 0xa1 | |||
#define GR_RENDERER 0xa2 | |||
#define GR_VENDOR 0xa3 | |||
#define GR_VERSION 0xa4 | |||
typedef FxI32 GrScreenRefresh_t; | |||
#define GR_REFRESH_NONE 0xff | |||
typedef FxI32 GrScreenResolution_t; | |||
#define GR_RESOLUTION_NONE 0xff | |||
typedef struct | |||
{ | |||
GrLOD_t smallLodLog2; | |||
GrLOD_t largeLodLog2; | |||
GrAspectRatio_t aspectRatioLog2; | |||
GrTextureFormat_t format; | |||
void *data; | |||
} | |||
GrTexInfo; | |||
typedef struct GrSstPerfStats_s | |||
{ | |||
FxU32 pixelsIn; | |||
FxU32 chromaFail; | |||
FxU32 zFuncFail; | |||
FxU32 aFuncFail; | |||
FxU32 pixelsOut; | |||
} | |||
GrSstPerfStats_t; | |||
typedef struct | |||
{ | |||
GrScreenResolution_t resolution; | |||
GrScreenRefresh_t refresh; | |||
int numColorBuffers; | |||
int numAuxBuffers; | |||
} | |||
GrResolution; | |||
typedef GrResolution GlideResolution; | |||
#define GR_QUERY_ANY ((FxU32)(~0)) | |||
typedef FxU32 GrLfbSrcFmt_t; | |||
#define GR_LFB_SRC_FMT_565 0x00 | |||
#define GR_LFB_SRC_FMT_555 0x01 | |||
#define GR_LFB_SRC_FMT_1555 0x02 | |||
#define GR_LFB_SRC_FMT_888 0x04 | |||
#define GR_LFB_SRC_FMT_8888 0x05 | |||
#define GR_LFB_SRC_FMT_565_DEPTH 0x0c | |||
#define GR_LFB_SRC_FMT_555_DEPTH 0x0d | |||
#define GR_LFB_SRC_FMT_1555_DEPTH 0x0e | |||
#define GR_LFB_SRC_FMT_ZA16 0x0f | |||
#define GR_LFB_SRC_FMT_RLE16 0x80 | |||
typedef FxU32 GrPixelFormat_t; | |||
#define GR_PIXFMT_I_8 0x0001 | |||
#define GR_PIXFMT_AI_88 0x0002 | |||
#define GR_PIXFMT_RGB_565 0x0003 | |||
#define GR_PIXFMT_ARGB_1555 0x0004 | |||
#define GR_PIXFMT_ARGB_8888 0x0005 | |||
#define GR_PIXFMT_AA_2_RGB_565 0x0006 | |||
#define GR_PIXFMT_AA_2_ARGB_1555 0x0007 | |||
#define GR_PIXFMT_AA_2_ARGB_8888 0x0008 | |||
#define GR_PIXFMT_AA_4_RGB_565 0x0009 | |||
#define GR_PIXFMT_AA_4_ARGB_1555 0x000a | |||
#define GR_PIXFMT_AA_4_ARGB_8888 0x000b | |||
#define GR_LFBWRITEMODE_Z32 0x0008 | |||
typedef FxU32 GrAAMode_t; | |||
#define GR_AA_NONE 0x0000 | |||
#define GR_AA_4SAMPLES 0x0001 | |||
typedef FxU8 GrStencil_t; | |||
typedef FxU32 GrStencilOp_t; | |||
#define GR_STENCILOP_KEEP 0x00 | |||
#define GR_STENCILOP_ZERO 0x01 | |||
#define GR_STENCILOP_REPLACE 0x02 | |||
#define GR_STENCILOP_INCR_CLAMP 0x03 | |||
#define GR_STENCILOP_DECR_CLAMP 0x04 | |||
#define GR_STENCILOP_INVERT 0x05 | |||
#define GR_STENCILOP_INCR_WRAP 0x06 | |||
#define GR_STENCILOP_DECR_WRAP 0x07 | |||
#define GR_TEXTURE_UMA_EXT 0x06 | |||
#define GR_STENCIL_MODE_EXT 0x07 | |||
#define GR_OPENGL_MODE_EXT 0x08 | |||
typedef FxU32 GrCCUColor_t; | |||
typedef FxU32 GrACUColor_t; | |||
typedef FxU32 GrTCCUColor_t; | |||
typedef FxU32 GrTACUColor_t; | |||
#define GR_CMBX_ZERO 0x00 | |||
#define GR_CMBX_TEXTURE_ALPHA 0x01 | |||
#define GR_CMBX_ALOCAL 0x02 | |||
#define GR_CMBX_AOTHER 0x03 | |||
#define GR_CMBX_B 0x04 | |||
#define GR_CMBX_CONSTANT_ALPHA 0x05 | |||
#define GR_CMBX_CONSTANT_COLOR 0x06 | |||
#define GR_CMBX_DETAIL_FACTOR 0x07 | |||
#define GR_CMBX_ITALPHA 0x08 | |||
#define GR_CMBX_ITRGB 0x09 | |||
#define GR_CMBX_LOCAL_TEXTURE_ALPHA 0x0a | |||
#define GR_CMBX_LOCAL_TEXTURE_RGB 0x0b | |||
#define GR_CMBX_LOD_FRAC 0x0c | |||
#define GR_CMBX_OTHER_TEXTURE_ALPHA 0x0d | |||
#define GR_CMBX_OTHER_TEXTURE_RGB 0x0e | |||
#define GR_CMBX_TEXTURE_RGB 0x0f | |||
#define GR_CMBX_TMU_CALPHA 0x10 | |||
#define GR_CMBX_TMU_CCOLOR 0x11 | |||
typedef FxU32 GrCombineMode_t; | |||
#define GR_FUNC_MODE_ZERO 0x00 | |||
#define GR_FUNC_MODE_X 0x01 | |||
#define GR_FUNC_MODE_ONE_MINUS_X 0x02 | |||
#define GR_FUNC_MODE_NEGATIVE_X 0x03 | |||
#define GR_FUNC_MODE_X_MINUS_HALF 0x04 | |||
typedef FxU32 GrAlphaBlendOp_t; | |||
#define GR_BLEND_OP_ADD 0x00 | |||
#define GR_BLEND_OP_SUB 0x01 | |||
#define GR_BLEND_OP_REVSUB 0x02 | |||
typedef struct | |||
{ | |||
FxU32 data[256]; | |||
} | |||
GuTexPalette; | |||
typedef void (*GrErrorCallbackFnc_t) (const char *string, FxBool fatal); | |||
#endif |
@@ -0,0 +1,90 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c,v 1.5 2002/12/16 16:19:00 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* | |||
*/ | |||
#include "tdfx_context.h" | |||
#include "tdfx_lock.h" | |||
#include "tdfx_state.h" | |||
#include "tdfx_render.h" | |||
#include "tdfx_texman.h" | |||
#include "tdfx_tris.h" | |||
void tdfxGetLock( tdfxContextPtr fxMesa ) | |||
{ | |||
__DRIcontextPrivate *cPriv = fxMesa->driContext; | |||
__DRIdrawablePrivate *dPriv = cPriv->driDrawablePriv; | |||
__DRIscreenPrivate *sPriv = dPriv->driScreenPriv; | |||
TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) + | |||
fxMesa->fxScreen->sarea_priv_offset); | |||
unsigned int stamp = dPriv->lastStamp; | |||
drmGetLock( fxMesa->driFd, fxMesa->hHWContext, 0 ); | |||
/* This macro will update dPriv's cliprects if needed */ | |||
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); | |||
if ( saPriv->fifoOwner != fxMesa->hHWContext ) { | |||
fxMesa->Glide.grDRIImportFifo( saPriv->fifoPtr, saPriv->fifoRead ); | |||
} | |||
if ( saPriv->ctxOwner != fxMesa->hHWContext ) { | |||
/* This sequence looks a little odd. Glide mirrors the state, and | |||
* when you get the state you are forcing the mirror to be up to | |||
* date, and then getting a copy from the mirror. You can then force | |||
* that state onto the hardware when you set the state. | |||
*/ | |||
void *state; | |||
FxI32 stateSize; | |||
fxMesa->Glide.grGet(GR_GLIDE_STATE_SIZE, 4, &stateSize); | |||
state = malloc(stateSize); | |||
fxMesa->Glide.grGlideGetState( state ); | |||
fxMesa->Glide.grGlideSetState( state ); | |||
free( state ); | |||
} | |||
#if 0 | |||
if ( saPriv->texOwner != fxMesa->hHWContext ) { | |||
tdfxTMRestoreTextures_NoLock( fxMesa ); | |||
} | |||
#endif | |||
if ( *dPriv->pStamp != stamp || saPriv->ctxOwner != fxMesa->hHWContext ) { | |||
tdfxUpdateClipping(fxMesa->glCtx); | |||
tdfxUploadClipping(fxMesa); | |||
} | |||
DEBUG_LOCK(); | |||
} |
@@ -0,0 +1,149 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.h,v 1.3 2002/02/22 21:45:03 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_LOCK_H__ | |||
#define __TDFX_LOCK_H__ | |||
#ifdef GLX_DIRECT_RENDERING | |||
/* You can turn this on to find locking conflicts. | |||
*/ | |||
#define DEBUG_LOCKING 0 | |||
#if DEBUG_LOCKING | |||
extern char *prevLockFile; | |||
extern int prevLockLine; | |||
#define DEBUG_LOCK() \ | |||
do { \ | |||
prevLockFile = (__FILE__); \ | |||
prevLockLine = (__LINE__); \ | |||
} while (0) | |||
#define DEBUG_RESET() \ | |||
do { \ | |||
prevLockFile = 0; \ | |||
prevLockLine = 0; \ | |||
} while (0) | |||
#define DEBUG_CHECK_LOCK() \ | |||
do { \ | |||
if ( prevLockFile ) { \ | |||
fprintf( stderr, \ | |||
"LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ | |||
prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ | |||
exit( 1 ); \ | |||
} \ | |||
} while (0) | |||
#else | |||
#define DEBUG_LOCK() | |||
#define DEBUG_RESET() | |||
#define DEBUG_CHECK_LOCK() | |||
#endif /* DEBUG_LOCKING */ | |||
extern void tdfxGetLock( tdfxContextPtr fxMesa ); | |||
/* !!! We may want to separate locks from locks with validation. | |||
This could be used to improve performance for those things | |||
commands that do not do any drawing !!! */ | |||
#define DRM_LIGHT_LOCK_RETURN(fd,lock,context,__ret) \ | |||
do { \ | |||
DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ | |||
if (__ret) drmGetLock(fd,context,0); \ | |||
} while(0) | |||
#define LOCK_HARDWARE( fxMesa ) \ | |||
do { \ | |||
char __ret = 0; \ | |||
\ | |||
DEBUG_CHECK_LOCK(); \ | |||
DRM_CAS( fxMesa->driHwLock, fxMesa->hHWContext, \ | |||
DRM_LOCK_HELD | fxMesa->hHWContext, __ret ); \ | |||
if ( __ret ) { \ | |||
tdfxGetLock( fxMesa ); \ | |||
} \ | |||
DEBUG_LOCK(); \ | |||
} while (0) | |||
/* Unlock the hardware using the global current context */ | |||
#define UNLOCK_HARDWARE( fxMesa ) \ | |||
do { \ | |||
DRM_UNLOCK( fxMesa->driFd, fxMesa->driHwLock, fxMesa->hHWContext ); \ | |||
DEBUG_RESET(); \ | |||
} while (0) | |||
/* | |||
* This pair of macros makes a loop over the drawing operations | |||
* so it is not self contained and doesn't have the nice single | |||
* statement semantics of most macros. | |||
*/ | |||
#define BEGIN_CLIP_LOOP(fxMesa) \ | |||
do { \ | |||
LOCK_HARDWARE( fxMesa ); \ | |||
BEGIN_CLIP_LOOP_LOCKED( fxMesa ) | |||
#define BEGIN_CLIP_LOOP_LOCKED(fxMesa) \ | |||
do { \ | |||
int _nc = fxMesa->numClipRects; \ | |||
while (_nc--) { \ | |||
if (fxMesa->numClipRects > 1) { \ | |||
int _height = fxMesa->screen_height; \ | |||
fxMesa->Glide.grClipWindow(fxMesa->pClipRects[_nc].x1, \ | |||
_height - fxMesa->pClipRects[_nc].y2, \ | |||
fxMesa->pClipRects[_nc].x2, \ | |||
_height - fxMesa->pClipRects[_nc].y1); \ | |||
} | |||
#define END_CLIP_LOOP_LOCKED( fxMesa ) \ | |||
} \ | |||
} while (0) | |||
#define END_CLIP_LOOP( fxMesa ) \ | |||
END_CLIP_LOOP_LOCKED( fxMesa ); \ | |||
UNLOCK_HARDWARE( fxMesa ); \ | |||
} while (0) | |||
#endif /* GLX_DIRECT_RENDERING */ | |||
#endif /* __TDFX_LOCK_H__ */ |
@@ -0,0 +1,689 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.c,v 1.4 2002/02/22 21:45:03 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* Nathan Hand <nhand@valinux.com> | |||
* | |||
*/ | |||
#include "tdfx_context.h" | |||
#include "tdfx_dd.h" | |||
#include "tdfx_lock.h" | |||
#include "tdfx_vb.h" | |||
#include "tdfx_pixels.h" | |||
#include "tdfx_render.h" | |||
#include "swrast/swrast.h" | |||
#include "image.h" | |||
#define FX_grLfbWriteRegion(fxMesa,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \ | |||
do { \ | |||
LOCK_HARDWARE(fxMesa); \ | |||
fxMesa->Glide.grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,FXFALSE,src_stride,src_data); \ | |||
UNLOCK_HARDWARE(fxMesa); \ | |||
} while(0) | |||
#define FX_grLfbReadRegion(fxMesa,src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data) \ | |||
do { \ | |||
LOCK_HARDWARE(fxMesa); \ | |||
fxMesa->Glide.grLfbReadRegion(src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data); \ | |||
UNLOCK_HARDWARE(fxMesa); \ | |||
} while (0); | |||
#if 0 | |||
static FxBool | |||
FX_grLfbLock(tdfxContextPtr fxMesa, GrLock_t type, GrBuffer_t buffer, | |||
GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, | |||
FxBool pixelPipeline, GrLfbInfo_t * info) | |||
{ | |||
FxBool result; | |||
LOCK_HARDWARE(fxMesa); | |||
result = fxMesa->Glide.grLfbLock(type, buffer, writeMode, origin, pixelPipeline, info); | |||
UNLOCK_HARDWARE(fxMesa); | |||
return result; | |||
} | |||
#endif | |||
#define FX_grLfbUnlock(fxMesa, t, b) \ | |||
do { \ | |||
LOCK_HARDWARE(fxMesa); \ | |||
fxMesa->Glide.grLfbUnlock(t, b); \ | |||
UNLOCK_HARDWARE(fxMesa); \ | |||
} while (0) | |||
#if 0 | |||
/* test if window coord (px,py) is visible */ | |||
static GLboolean | |||
inClipRects(tdfxContextPtr fxMesa, int px, int py) | |||
{ | |||
int i; | |||
for (i = 0; i < fxMesa->numClipRects; i++) { | |||
if ((px >= fxMesa->pClipRects[i].x1) && | |||
(px < fxMesa->pClipRects[i].x2) && | |||
(py >= fxMesa->pClipRects[i].y1) && | |||
(py < fxMesa->pClipRects[i].y2)) return GL_TRUE; | |||
} | |||
return GL_FALSE; | |||
} | |||
#endif | |||
/* test if rectangle of pixels (px,py) (px+width,py+height) is visible */ | |||
static GLboolean | |||
inClipRects_Region(tdfxContextPtr fxMesa, int x, int y, int width, int height) | |||
{ | |||
int i; | |||
int x1, y1, x2, y2; | |||
int xmin, xmax, ymin, ymax, pixelsleft; | |||
y1 = y - height + 1; y2 = y; | |||
x1 = x; x2 = x + width - 1; | |||
pixelsleft = width * height; | |||
for (i = 0; i < fxMesa->numClipRects; i++) | |||
{ | |||
/* algorithm requires x1 < x2 and y1 < y2 */ | |||
if ((fxMesa->pClipRects[i].x1 < fxMesa->pClipRects[i].x2)) { | |||
xmin = fxMesa->pClipRects[i].x1; | |||
xmax = fxMesa->pClipRects[i].x2-1; | |||
} else { | |||
xmin = fxMesa->pClipRects[i].x2; | |||
xmax = fxMesa->pClipRects[i].x1-1; | |||
} | |||
if ((fxMesa->pClipRects[i].y1 < fxMesa->pClipRects[i].y2)) { | |||
ymin = fxMesa->pClipRects[i].y1; | |||
ymax = fxMesa->pClipRects[i].y2-1; | |||
} else { | |||
ymin = fxMesa->pClipRects[i].y2; | |||
ymax = fxMesa->pClipRects[i].y1-1; | |||
} | |||
/* reject trivial cases */ | |||
if (xmax < x1) continue; | |||
if (ymax < y1) continue; | |||
if (xmin > x2) continue; | |||
if (ymin > y2) continue; | |||
/* find the intersection */ | |||
if (xmin < x1) xmin = x1; | |||
if (ymin < y1) ymin = y1; | |||
if (xmax > x2) xmax = x2; | |||
if (ymax > y2) ymax = y2; | |||
pixelsleft -= (xmax-xmin+1) * (ymax-ymin+1); | |||
} | |||
return pixelsleft == 0; | |||
} | |||
#if 0 | |||
GLboolean | |||
tdfx_bitmap_R5G6B5(GLcontext * ctx, GLint px, GLint py, | |||
GLsizei width, GLsizei height, | |||
const struct gl_pixelstore_attrib *unpack, | |||
const GLubyte * bitmap) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
GrLfbInfo_t info; | |||
TdfxU16 color; | |||
const struct gl_pixelstore_attrib *finalUnpack; | |||
struct gl_pixelstore_attrib scissoredUnpack; | |||
/* check if there's any raster operations enabled which we can't handle */ | |||
if (ctx->RasterMask & (ALPHATEST_BIT | | |||
BLEND_BIT | | |||
DEPTH_BIT | | |||
FOG_BIT | | |||
LOGIC_OP_BIT | | |||
SCISSOR_BIT | | |||
STENCIL_BIT | | |||
MASKING_BIT | | |||
ALPHABUF_BIT | MULTI_DRAW_BIT)) return GL_FALSE; | |||
if (ctx->Scissor.Enabled) { | |||
/* This is a bit tricky, but by carefully adjusting the px, py, | |||
* width, height, skipPixels and skipRows values we can do | |||
* scissoring without special code in the rendering loop. | |||
*/ | |||
/* we'll construct a new pixelstore struct */ | |||
finalUnpack = &scissoredUnpack; | |||
scissoredUnpack = *unpack; | |||
if (scissoredUnpack.RowLength == 0) | |||
scissoredUnpack.RowLength = width; | |||
/* clip left */ | |||
if (px < ctx->Scissor.X) { | |||
scissoredUnpack.SkipPixels += (ctx->Scissor.X - px); | |||
width -= (ctx->Scissor.X - px); | |||
px = ctx->Scissor.X; | |||
} | |||
/* clip right */ | |||
if (px + width >= ctx->Scissor.X + ctx->Scissor.Width) { | |||
width -= (px + width - (ctx->Scissor.X + ctx->Scissor.Width)); | |||
} | |||
/* clip bottom */ | |||
if (py < ctx->Scissor.Y) { | |||
scissoredUnpack.SkipRows += (ctx->Scissor.Y - py); | |||
height -= (ctx->Scissor.Y - py); | |||
py = ctx->Scissor.Y; | |||
} | |||
/* clip top */ | |||
if (py + height >= ctx->Scissor.Y + ctx->Scissor.Height) { | |||
height -= (py + height - (ctx->Scissor.Y + ctx->Scissor.Height)); | |||
} | |||
if (width <= 0 || height <= 0) | |||
return GL_TRUE; /* totally scissored away */ | |||
} | |||
else { | |||
finalUnpack = unpack; | |||
} | |||
/* compute pixel value */ | |||
{ | |||
GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0f); | |||
GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0f); | |||
GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0f); | |||
/*GLint a = (GLint)(ctx->Current.RasterColor[3]*255.0f); */ | |||
if (fxMesa->bgrOrder) { | |||
color = (TdfxU16) | |||
(((TdfxU16) 0xf8 & b) << (11 - 3)) | | |||
(((TdfxU16) 0xfc & g) << (5 - 3 + 1)) | | |||
(((TdfxU16) 0xf8 & r) >> 3); | |||
} | |||
else | |||
color = (TdfxU16) | |||
(((TdfxU16) 0xf8 & r) << (11 - 3)) | | |||
(((TdfxU16) 0xfc & g) << (5 - 3 + 1)) | | |||
(((TdfxU16) 0xf8 & b) >> 3); | |||
} | |||
info.size = sizeof(info); | |||
if (!TDFX_grLfbLock(fxMesa, | |||
GR_LFB_WRITE_ONLY, | |||
fxMesa->currentFB, | |||
GR_LFBWRITEMODE_565, | |||
GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { | |||
#ifndef TDFX_SILENT | |||
fprintf(stderr, "tdfx Driver: error locking the linear frame buffer\n"); | |||
#endif | |||
return GL_TRUE; | |||
} | |||
{ | |||
const GLint winX = fxMesa->x_offset; | |||
const GLint winY = fxMesa->y_offset + fxMesa->height - 1; | |||
/* The dest stride depends on the hardware and whether we're drawing | |||
* to the front or back buffer. This compile-time test seems to do | |||
* the job for now. | |||
*/ | |||
const GLint dstStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) | |||
? (fxMesa->screen_width) : (info.strideInBytes / 2); | |||
GLint row; | |||
/* compute dest address of bottom-left pixel in bitmap */ | |||
GLushort *dst = (GLushort *) info.lfbPtr | |||
+ (winY - py) * dstStride + (winX + px); | |||
for (row = 0; row < height; row++) { | |||
const GLubyte *src = | |||
(const GLubyte *) _mesa_image_address(finalUnpack, | |||
bitmap, width, height, | |||
GL_COLOR_INDEX, | |||
GL_BITMAP, 0, row, 0); | |||
if (finalUnpack->LsbFirst) { | |||
/* least significan bit first */ | |||
GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7); | |||
GLint col; | |||
for (col = 0; col < width; col++) { | |||
if (*src & mask) { | |||
if (inClipRects(fxMesa, winX + px + col, winY - py - row)) | |||
dst[col] = color; | |||
} | |||
if (mask == 128U) { | |||
src++; | |||
mask = 1U; | |||
} | |||
else { | |||
mask = mask << 1; | |||
} | |||
} | |||
if (mask != 1) | |||
src++; | |||
} | |||
else { | |||
/* most significan bit first */ | |||
GLubyte mask = 128U >> (finalUnpack->SkipPixels & 0x7); | |||
GLint col; | |||
for (col = 0; col < width; col++) { | |||
if (*src & mask) { | |||
if (inClipRects(fxMesa, winX + px + col, winY - py - row)) | |||
dst[col] = color; | |||
} | |||
if (mask == 1U) { | |||
src++; | |||
mask = 128U; | |||
} | |||
else { | |||
mask = mask >> 1; | |||
} | |||
} | |||
if (mask != 128) | |||
src++; | |||
} | |||
dst -= dstStride; | |||
} | |||
} | |||
TDFX_grLfbUnlock(fxMesa, GR_LFB_WRITE_ONLY, fxMesa->currentFB); | |||
return GL_TRUE; | |||
} | |||
#endif | |||
#if 0 | |||
GLboolean | |||
tdfx_bitmap_R8G8B8A8(GLcontext * ctx, GLint px, GLint py, | |||
GLsizei width, GLsizei height, | |||
const struct gl_pixelstore_attrib *unpack, | |||
const GLubyte * bitmap) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
GrLfbInfo_t info; | |||
GLuint color; | |||
const struct gl_pixelstore_attrib *finalUnpack; | |||
struct gl_pixelstore_attrib scissoredUnpack; | |||
/* check if there's any raster operations enabled which we can't handle */ | |||
if (ctx->RasterMask & (ALPHATEST_BIT | | |||
BLEND_BIT | | |||
DEPTH_BIT | | |||
FOG_BIT | | |||
LOGIC_OP_BIT | | |||
SCISSOR_BIT | | |||
STENCIL_BIT | | |||
MASKING_BIT | | |||
ALPHABUF_BIT | MULTI_DRAW_BIT)) return GL_FALSE; | |||
if (ctx->Scissor.Enabled) { | |||
/* This is a bit tricky, but by carefully adjusting the px, py, | |||
* width, height, skipPixels and skipRows values we can do | |||
* scissoring without special code in the rendering loop. | |||
*/ | |||
/* we'll construct a new pixelstore struct */ | |||
finalUnpack = &scissoredUnpack; | |||
scissoredUnpack = *unpack; | |||
if (scissoredUnpack.RowLength == 0) | |||
scissoredUnpack.RowLength = width; | |||
/* clip left */ | |||
if (px < ctx->Scissor.X) { | |||
scissoredUnpack.SkipPixels += (ctx->Scissor.X - px); | |||
width -= (ctx->Scissor.X - px); | |||
px = ctx->Scissor.X; | |||
} | |||
/* clip right */ | |||
if (px + width >= ctx->Scissor.X + ctx->Scissor.Width) { | |||
width -= (px + width - (ctx->Scissor.X + ctx->Scissor.Width)); | |||
} | |||
/* clip bottom */ | |||
if (py < ctx->Scissor.Y) { | |||
scissoredUnpack.SkipRows += (ctx->Scissor.Y - py); | |||
height -= (ctx->Scissor.Y - py); | |||
py = ctx->Scissor.Y; | |||
} | |||
/* clip top */ | |||
if (py + height >= ctx->Scissor.Y + ctx->Scissor.Height) { | |||
height -= (py + height - (ctx->Scissor.Y + ctx->Scissor.Height)); | |||
} | |||
if (width <= 0 || height <= 0) | |||
return GL_TRUE; /* totally scissored away */ | |||
} | |||
else { | |||
finalUnpack = unpack; | |||
} | |||
/* compute pixel value */ | |||
{ | |||
GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0f); | |||
GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0f); | |||
GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0f); | |||
GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0f); | |||
color = PACK_BGRA32(r, g, b, a); | |||
} | |||
info.size = sizeof(info); | |||
if (!TDFX_grLfbLock(fxMesa, GR_LFB_WRITE_ONLY, | |||
fxMesa->currentFB, GR_LFBWRITEMODE_8888, | |||
GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { | |||
#ifndef TDFX_SILENT | |||
fprintf(stderr, "tdfx Driver: error locking the linear frame buffer\n"); | |||
#endif | |||
return GL_TRUE; | |||
} | |||
{ | |||
const GLint winX = fxMesa->x_offset; | |||
const GLint winY = fxMesa->y_offset + fxMesa->height - 1; | |||
GLint dstStride; | |||
GLuint *dst; | |||
GLint row; | |||
if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { | |||
dstStride = fxMesa->screen_width; | |||
dst = | |||
(GLuint *) info.lfbPtr + (winY - py) * dstStride + (winX + | |||
px); | |||
} | |||
else { | |||
dstStride = info.strideInBytes / 4; | |||
dst = | |||
(GLuint *) info.lfbPtr + (winY - py) * dstStride + (winX + | |||
px); | |||
} | |||
/* compute dest address of bottom-left pixel in bitmap */ | |||
for (row = 0; row < height; row++) { | |||
const GLubyte *src = | |||
(const GLubyte *) _mesa_image_address(finalUnpack, | |||
bitmap, width, height, | |||
GL_COLOR_INDEX, | |||
GL_BITMAP, 0, row, 0); | |||
if (finalUnpack->LsbFirst) { | |||
/* least significan bit first */ | |||
GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7); | |||
GLint col; | |||
for (col = 0; col < width; col++) { | |||
if (*src & mask) { | |||
if (inClipRects(fxMesa, winX + px + col, winY - py - row)) | |||
dst[col] = color; | |||
} | |||
if (mask == 128U) { | |||
src++; | |||
mask = 1U; | |||
} | |||
else { | |||
mask = mask << 1; | |||
} | |||
} | |||
if (mask != 1) | |||
src++; | |||
} | |||
else { | |||
/* most significan bit first */ | |||
GLubyte mask = 128U >> (finalUnpack->SkipPixels & 0x7); | |||
GLint col; | |||
for (col = 0; col < width; col++) { | |||
if (*src & mask) { | |||
if (inClipRects(fxMesa, winX + px + col, winY - py - row)) | |||
dst[col] = color; | |||
} | |||
if (mask == 1U) { | |||
src++; | |||
mask = 128U; | |||
} | |||
else { | |||
mask = mask >> 1; | |||
} | |||
} | |||
if (mask != 128) | |||
src++; | |||
} | |||
dst -= dstStride; | |||
} | |||
} | |||
TDFX_grLfbUnlock(fxMesa, GR_LFB_WRITE_ONLY, fxMesa->currentFB); | |||
return GL_TRUE; | |||
} | |||
#endif | |||
void | |||
tdfx_readpixels_R5G6B5(GLcontext * ctx, GLint x, GLint y, | |||
GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const struct gl_pixelstore_attrib *packing, | |||
GLvoid * dstImage) | |||
{ | |||
if (format != GL_RGB || | |||
type != GL_UNSIGNED_SHORT_5_6_5 || | |||
(ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| | |||
IMAGE_MAP_COLOR_BIT))) | |||
{ | |||
_swrast_ReadPixels( ctx, x, y, width, height, format, type, packing, | |||
dstImage ); | |||
return; | |||
} | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
GrLfbInfo_t info; | |||
const GLint winX = fxMesa->x_offset; | |||
const GLint winY = fxMesa->y_offset + fxMesa->height - 1; | |||
const GLint scrX = winX + x; | |||
const GLint scrY = winY - y; | |||
LOCK_HARDWARE( fxMesa ); | |||
info.size = sizeof(info); | |||
if (fxMesa->Glide.grLfbLock(GR_LFB_READ_ONLY, | |||
fxMesa->ReadBuffer, | |||
GR_LFBWRITEMODE_ANY, | |||
GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { | |||
const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == | |||
GL_FRONT) ? (fxMesa->screen_width) : (info.strideInBytes / 2); | |||
const GLushort *src = (const GLushort *) info.lfbPtr | |||
+ scrY * srcStride + scrX; | |||
GLubyte *dst = (GLubyte *) _mesa_image_address(packing, | |||
dstImage, width, height, format, type, 0, 0, 0); | |||
const GLint dstStride = _mesa_image_row_stride(packing, | |||
width, format, type); | |||
/* directly memcpy 5R6G5B pixels into client's buffer */ | |||
const GLint widthInBytes = width * 2; | |||
GLint row; | |||
for (row = 0; row < height; row++) { | |||
MEMCPY(dst, src, widthInBytes); | |||
dst += dstStride; | |||
src -= srcStride; | |||
} | |||
fxMesa->Glide.grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->ReadBuffer); | |||
} | |||
UNLOCK_HARDWARE( fxMesa ); | |||
return; | |||
} | |||
} | |||
void | |||
tdfx_readpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, | |||
GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const struct gl_pixelstore_attrib *packing, | |||
GLvoid * dstImage) | |||
{ | |||
if ((!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) && | |||
!(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) || | |||
(ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| | |||
IMAGE_MAP_COLOR_BIT))) | |||
{ | |||
_swrast_ReadPixels( ctx, x, y, width, height, format, type, packing, | |||
dstImage ); | |||
return; | |||
} | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
GrLfbInfo_t info; | |||
const GLint winX = fxMesa->x_offset; | |||
const GLint winY = fxMesa->y_offset + fxMesa->height - 1; | |||
const GLint scrX = winX + x; | |||
const GLint scrY = winY - y; | |||
LOCK_HARDWARE(fxMesa); | |||
info.size = sizeof(info); | |||
if (fxMesa->Glide.grLfbLock(GR_LFB_READ_ONLY, | |||
fxMesa->ReadBuffer, | |||
GR_LFBWRITEMODE_ANY, | |||
GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) | |||
{ | |||
const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) | |||
? (fxMesa->screen_width) : (info.strideInBytes / 4); | |||
const GLuint *src = (const GLuint *) info.lfbPtr | |||
+ scrY * srcStride + scrX; | |||
const GLint dstStride = | |||
_mesa_image_row_stride(packing, width, format, type); | |||
GLubyte *dst = (GLubyte *) _mesa_image_address(packing, | |||
dstImage, width, height, format, type, 0, 0, 0); | |||
const GLint widthInBytes = width * 4; | |||
{ | |||
GLint row; | |||
for (row = 0; row < height; row++) { | |||
MEMCPY(dst, src, widthInBytes); | |||
dst += dstStride; | |||
src -= srcStride; | |||
} | |||
} | |||
fxMesa->Glide.grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->ReadBuffer); | |||
} | |||
UNLOCK_HARDWARE(fxMesa); | |||
} | |||
} | |||
void | |||
tdfx_drawpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, | |||
GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const struct gl_pixelstore_attrib *unpack, | |||
const GLvoid * pixels) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
if ((!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) && | |||
!(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) || | |||
ctx->Pixel.ZoomX != 1.0F || | |||
ctx->Pixel.ZoomY != 1.0F || | |||
(ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| | |||
IMAGE_MAP_COLOR_BIT)) || | |||
ctx->Color.AlphaEnabled || | |||
ctx->Depth.Test || | |||
ctx->Fog.Enabled || | |||
ctx->Scissor.Enabled || | |||
ctx->Stencil.Enabled || | |||
!ctx->Color.ColorMask[0] || | |||
!ctx->Color.ColorMask[1] || | |||
!ctx->Color.ColorMask[2] || | |||
!ctx->Color.ColorMask[3] || | |||
ctx->Color.ColorLogicOpEnabled || | |||
ctx->Texture._EnabledUnits || | |||
ctx->Depth.OcclusionTest || | |||
fxMesa->Fallback) | |||
{ | |||
_swrast_DrawPixels( ctx, x, y, width, height, format, type, | |||
unpack, pixels ); | |||
return; | |||
} | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
GrLfbInfo_t info; | |||
GLboolean result = GL_FALSE; | |||
const GLint winX = fxMesa->x_offset; | |||
const GLint winY = fxMesa->y_offset + fxMesa->height - 1; | |||
const GLint scrX = winX + x; | |||
const GLint scrY = winY - y; | |||
/* lock early to make sure cliprects are right */ | |||
LOCK_HARDWARE(fxMesa); | |||
/* make sure hardware has latest blend funcs */ | |||
if (ctx->Color.BlendEnabled) { | |||
fxMesa->dirty |= TDFX_UPLOAD_BLEND_FUNC; | |||
tdfxEmitHwStateLocked( fxMesa ); | |||
} | |||
/* look for clipmasks, giveup if region obscured */ | |||
if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { | |||
if (!inClipRects_Region(fxMesa, scrX, scrY, width, height)) { | |||
UNLOCK_HARDWARE(fxMesa); | |||
_swrast_DrawPixels( ctx, x, y, width, height, format, type, | |||
unpack, pixels ); | |||
return; | |||
} | |||
} | |||
info.size = sizeof(info); | |||
if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, | |||
fxMesa->DrawBuffer, | |||
GR_LFBWRITEMODE_8888, | |||
GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) | |||
{ | |||
const GLint dstStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) | |||
? (fxMesa->screen_width * 4) : (info.strideInBytes); | |||
GLubyte *dst = (GLubyte *) info.lfbPtr | |||
+ scrY * dstStride + scrX * 4; | |||
const GLint srcStride = | |||
_mesa_image_row_stride(unpack, width, format, type); | |||
const GLubyte *src = (GLubyte *) _mesa_image_address(unpack, | |||
pixels, width, height, format, type, 0, 0, 0); | |||
const GLint widthInBytes = width * 4; | |||
if ((format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) || | |||
(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { | |||
GLint row; | |||
for (row = 0; row < height; row++) { | |||
MEMCPY(dst, src, widthInBytes); | |||
dst -= dstStride; | |||
src += srcStride; | |||
} | |||
result = GL_TRUE; | |||
} | |||
fxMesa->Glide.grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer); | |||
} | |||
UNLOCK_HARDWARE(fxMesa); | |||
} | |||
} |
@@ -0,0 +1,80 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.h,v 1.2 2002/02/22 21:45:03 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* Nathan Hand <nhand@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_PIXELS_H__ | |||
#define __TDFX_PIXELS_H__ | |||
#ifdef GLX_DIRECT_RENDERING | |||
#include "context.h" | |||
extern void | |||
tdfx_bitmap_R5G6B5( GLcontext *ctx, GLint px, GLint py, | |||
GLsizei width, GLsizei height, | |||
const struct gl_pixelstore_attrib *unpack, | |||
const GLubyte *bitmap ); | |||
extern void | |||
tdfx_bitmap_R8G8B8A8( GLcontext *ctx, GLint px, GLint py, | |||
GLsizei width, GLsizei height, | |||
const struct gl_pixelstore_attrib *unpack, | |||
const GLubyte *bitmap ); | |||
extern void | |||
tdfx_readpixels_R5G6B5( GLcontext *ctx, GLint x, GLint y, | |||
GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const struct gl_pixelstore_attrib *packing, | |||
GLvoid *dstImage ); | |||
extern void | |||
tdfx_readpixels_R8G8B8A8( GLcontext *ctx, GLint x, GLint y, | |||
GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const struct gl_pixelstore_attrib *packing, | |||
GLvoid *dstImage ); | |||
extern void | |||
tdfx_drawpixels_R8G8B8A8( GLcontext *ctx, GLint x, GLint y, | |||
GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const struct gl_pixelstore_attrib *unpack, | |||
const GLvoid *pixels ); | |||
#endif | |||
#endif |
@@ -0,0 +1,802 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c,v 1.4 2002/02/22 21:45:03 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#include "tdfx_context.h" | |||
#include "tdfx_render.h" | |||
#include "tdfx_state.h" | |||
#include "tdfx_texman.h" | |||
#include "swrast/swrast.h" | |||
/* Clear the color and/or depth buffers. | |||
*/ | |||
static void tdfxDDClear( GLcontext *ctx, | |||
GLbitfield mask, GLboolean all, | |||
GLint x, GLint y, GLint width, GLint height ) | |||
{ | |||
tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; | |||
GLbitfield softwareMask = mask & (DD_ACCUM_BIT); | |||
const GLuint stencil_size = | |||
fxMesa->haveHwStencil ? fxMesa->glCtx->Visual.stencilBits : 0; | |||
if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { | |||
fprintf( stderr, "%s( %d, %d, %d, %d )\n", | |||
__FUNCTION__, (int) x, (int) y, (int) width, (int) height ); | |||
} | |||
/* Need this check to respond to glScissor and clipping updates */ | |||
if ((fxMesa->new_state & (TDFX_NEW_CLIP | TDFX_NEW_DEPTH)) || | |||
(fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK)) { | |||
tdfxDDUpdateHwState(ctx); | |||
} | |||
/* we can't clear accum buffers */ | |||
mask &= ~(DD_ACCUM_BIT); | |||
if (mask & DD_STENCIL_BIT) { | |||
if (!fxMesa->haveHwStencil || ctx->Stencil.WriteMask[0] != 0xff) { | |||
/* Napalm seems to have trouble with stencil write masks != 0xff */ | |||
/* do stencil clear in software */ | |||
mask &= ~(DD_STENCIL_BIT); | |||
softwareMask |= DD_STENCIL_BIT; | |||
} | |||
} | |||
if (fxMesa->glCtx->Visual.redBits != 8) { | |||
/* can only do color masking if running in 24/32bpp on Napalm */ | |||
if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] || | |||
ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) { | |||
softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)); | |||
mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); | |||
} | |||
} | |||
if (fxMesa->haveHwStencil) { | |||
/* | |||
* If we want to clear stencil, it must be enabled | |||
* in the HW, even if the stencil test is not enabled | |||
* in the OGL state. | |||
*/ | |||
LOCK_HARDWARE(fxMesa); | |||
if (mask & DD_STENCIL_BIT) { | |||
fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff); | |||
/* set stencil ref value = desired clear value */ | |||
fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS, | |||
ctx->Stencil.Clear, 0xff); | |||
fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE, | |||
GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE); | |||
fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT); | |||
} | |||
else { | |||
fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT); | |||
} | |||
UNLOCK_HARDWARE(fxMesa); | |||
} | |||
/* | |||
* This may be ugly, but it's needed in order to work around a number | |||
* of Glide bugs. | |||
*/ | |||
BEGIN_CLIP_LOOP(fxMesa); | |||
{ | |||
/* | |||
* This could probably be done fancier but doing each possible case | |||
* explicitly is less error prone. | |||
*/ | |||
switch (mask & ~DD_STENCIL_BIT) { | |||
case DD_BACK_LEFT_BIT | DD_DEPTH_BIT: | |||
/* back buffer & depth */ | |||
FX_grColorMaskv_NoLock(ctx, true4); /* work around Voodoo3 bug */ | |||
fxMesa->Glide.grDepthMask(FXTRUE); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); | |||
if (stencil_size > 0) { | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
} | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
if (!ctx->Depth.Mask || !ctx->Depth.Test) { | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
} | |||
break; | |||
case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT: | |||
/* XXX it appears that the depth buffer isn't cleared when | |||
* glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set. | |||
* This is a work-around/ | |||
*/ | |||
/* clear depth */ | |||
fxMesa->Glide.grDepthMask(FXTRUE); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); | |||
FX_grColorMaskv_NoLock(ctx, false4); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
/* clear front */ | |||
FX_grColorMaskv_NoLock(ctx, true4); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
if (!ctx->Depth.Mask || !ctx->Depth.Test) { | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
} | |||
break; | |||
case DD_BACK_LEFT_BIT: | |||
/* back buffer only */ | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
if (ctx->Depth.Mask && ctx->Depth.Test) { | |||
fxMesa->Glide.grDepthMask(FXTRUE); | |||
} | |||
break; | |||
case DD_FRONT_LEFT_BIT: | |||
/* front buffer only */ | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
if (ctx->Depth.Mask && ctx->Depth.Test) { | |||
fxMesa->Glide.grDepthMask(FXTRUE); | |||
} | |||
break; | |||
case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT: | |||
/* front and back */ | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
if (ctx->Depth.Mask && ctx->Depth.Test) { | |||
fxMesa->Glide.grDepthMask(FXTRUE); | |||
} | |||
break; | |||
case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT: | |||
/* clear front */ | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
/* clear back and depth */ | |||
fxMesa->Glide.grDepthMask(FXTRUE); | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
if (!ctx->Depth.Mask || !ctx->Depth.Mask) { | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
} | |||
break; | |||
case DD_DEPTH_BIT: | |||
/* just the depth buffer */ | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); | |||
FX_grColorMaskv_NoLock(ctx, false4); | |||
fxMesa->Glide.grDepthMask(FXTRUE); | |||
if (stencil_size > 0) | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
else | |||
fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear); | |||
FX_grColorMaskv_NoLock(ctx, true4); | |||
if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); | |||
if (!ctx->Depth.Test || !ctx->Depth.Mask) | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
break; | |||
default: | |||
/* clear no color buffers or depth buffer but might clear stencil */ | |||
if (stencil_size > 0 && (mask & DD_STENCIL_BIT)) { | |||
/* XXX need this RenderBuffer call to work around Glide bug */ | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); | |||
fxMesa->Glide.grDepthMask(FXFALSE); | |||
FX_grColorMaskv_NoLock(ctx, false4); | |||
fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, | |||
fxMesa->Color.ClearAlpha, | |||
fxMesa->Depth.Clear, | |||
(FxU32) ctx->Stencil.Clear); | |||
if (ctx->Depth.Mask && ctx->Depth.Test) { | |||
fxMesa->Glide.grDepthMask(FXTRUE); | |||
} | |||
FX_grColorMaskv_NoLock(ctx, true4); | |||
if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) | |||
fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); | |||
} | |||
} | |||
} | |||
END_CLIP_LOOP(fxMesa); | |||
if (fxMesa->haveHwStencil && (mask & DD_STENCIL_BIT)) { | |||
/* We changed the stencil state above. Signal that we need to | |||
* upload it again. | |||
*/ | |||
fxMesa->dirty |= TDFX_UPLOAD_STENCIL; | |||
} | |||
if (softwareMask) | |||
_swrast_Clear( ctx, softwareMask, all, x, y, width, height ); | |||
} | |||
static void tdfxDDFinish( GLcontext *ctx ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
FLUSH_BATCH( fxMesa ); | |||
LOCK_HARDWARE( fxMesa ); | |||
fxMesa->Glide.grFinish(); | |||
UNLOCK_HARDWARE( fxMesa ); | |||
} | |||
static void tdfxDDFlush( GLcontext *ctx ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
FLUSH_BATCH( fxMesa ); | |||
LOCK_HARDWARE( fxMesa ); | |||
fxMesa->Glide.grFlush(); | |||
UNLOCK_HARDWARE( fxMesa ); | |||
} | |||
#if 0 | |||
static const char *texSource(int k) | |||
{ | |||
switch (k) { | |||
case GR_CMBX_ZERO: | |||
return "GR_CMBX_ZERO"; | |||
case GR_CMBX_TEXTURE_ALPHA: | |||
return "GR_CMBX_TEXTURE_ALPHA"; | |||
case GR_CMBX_ALOCAL: | |||
return "GR_CMBX_ALOCAL"; | |||
case GR_CMBX_AOTHER: | |||
return "GR_CMBX_AOTHER"; | |||
case GR_CMBX_B: | |||
return "GR_CMBX_B"; | |||
case GR_CMBX_CONSTANT_ALPHA: | |||
return "GR_CMBX_CONSTANT_ALPHA"; | |||
case GR_CMBX_CONSTANT_COLOR: | |||
return "GR_CMBX_CONSTANT_COLOR"; | |||
case GR_CMBX_DETAIL_FACTOR: | |||
return "GR_CMBX_DETAIL_FACTOR"; | |||
case GR_CMBX_ITALPHA: | |||
return "GR_CMBX_ITALPHA"; | |||
case GR_CMBX_ITRGB: | |||
return "GR_CMBX_ITRGB"; | |||
case GR_CMBX_LOCAL_TEXTURE_ALPHA: | |||
return "GR_CMBX_LOCAL_TEXTURE_ALPHA"; | |||
case GR_CMBX_LOCAL_TEXTURE_RGB: | |||
return "GR_CMBX_LOCAL_TEXTURE_RGB"; | |||
case GR_CMBX_LOD_FRAC: | |||
return "GR_CMBX_LOD_FRAC"; | |||
case GR_CMBX_OTHER_TEXTURE_ALPHA: | |||
return "GR_CMBX_OTHER_TEXTURE_ALPHA"; | |||
case GR_CMBX_OTHER_TEXTURE_RGB: | |||
return "GR_CMBX_OTHER_TEXTURE_RGB"; | |||
case GR_CMBX_TEXTURE_RGB: | |||
return "GR_CMBX_TEXTURE_RGB"; | |||
case GR_CMBX_TMU_CALPHA: | |||
return "GR_CMBX_TMU_CALPHA"; | |||
case GR_CMBX_TMU_CCOLOR: | |||
return "GR_CMBX_TMU_CCOLOR"; | |||
default: | |||
return ""; | |||
} | |||
} | |||
#endif | |||
#if 0 | |||
static const char *texMode(int k) | |||
{ | |||
switch (k) { | |||
case GR_FUNC_MODE_ZERO: | |||
return "GR_FUNC_MODE_ZERO"; | |||
case GR_FUNC_MODE_X: | |||
return "GR_FUNC_MODE_X"; | |||
case GR_FUNC_MODE_ONE_MINUS_X: | |||
return "GR_FUNC_MODE_ONE_MINUS_X"; | |||
case GR_FUNC_MODE_NEGATIVE_X: | |||
return "GR_FUNC_MODE_NEGATIVE_X"; | |||
case GR_FUNC_MODE_X_MINUS_HALF: | |||
return "GR_FUNC_MODE_X_MINUS_HALF"; | |||
default: | |||
return ""; | |||
} | |||
} | |||
#endif | |||
#if 0 | |||
static const char *texInvert(int k) | |||
{ | |||
return k ? "FXTRUE" : "FXFALSE"; | |||
} | |||
#endif | |||
static void uploadTextureEnv( tdfxContextPtr fxMesa ) | |||
{ | |||
if (TDFX_IS_NAPALM(fxMesa)) { | |||
int unit; | |||
for (unit = 0; unit < TDFX_NUM_TMU; unit++) { | |||
#if 0 | |||
printf("upload env %d\n", unit); | |||
printf(" cSourceA = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceA)); | |||
printf(" cModeA = %s\n", texMode(fxMesa->TexCombineExt[unit].Color.ModeA)); | |||
printf(" cSourceB = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceB)); | |||
printf(" cModeB = %s\n", texMode(fxMesa->TexCombineExt[unit].Color.ModeB)); | |||
printf(" cSourceC = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceC)); | |||
printf(" cInvertC = %s\n", texInvert(fxMesa->TexCombineExt[unit].Color.InvertC)); | |||
printf(" cSourceD = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceD)); | |||
printf(" cInvertD = %s\n", texInvert(fxMesa->TexCombineExt[unit].Color.InvertD)); | |||
printf(" cShift = %d\t", fxMesa->TexCombineExt[unit].Color.Shift); | |||
printf(" cInvert = %d\n", fxMesa->TexCombineExt[unit].Color.Invert); | |||
printf(" aSourceA = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceA)); | |||
printf(" aModeA = %s\n", texMode(fxMesa->TexCombineExt[unit].Alpha.ModeA)); | |||
printf(" aSourceB = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceB)); | |||
printf(" aModeB = %s\n", texMode(fxMesa->TexCombineExt[unit].Alpha.ModeB)); | |||
printf(" aSourceC = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceC)); | |||
printf(" aInvertC = %s\n", texInvert(fxMesa->TexCombineExt[unit].Alpha.InvertC)); | |||
printf(" aSourceD = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceD)); | |||
printf(" aInvertD = %s\n", texInvert(fxMesa->TexCombineExt[unit].Alpha.InvertD)); | |||
printf(" aShift = %d\t", fxMesa->TexCombineExt[unit].Alpha.Shift); | |||
printf(" aInvert = %d\n", fxMesa->TexCombineExt[unit].Alpha.Invert); | |||
printf(" Color = 0x%08x\n", fxMesa->TexCombineExt[unit].EnvColor); | |||
#endif | |||
fxMesa->Glide.grTexColorCombineExt(TDFX_TMU0 + unit, | |||
fxMesa->TexCombineExt[unit].Color.SourceA, | |||
fxMesa->TexCombineExt[unit].Color.ModeA, | |||
fxMesa->TexCombineExt[unit].Color.SourceB, | |||
fxMesa->TexCombineExt[unit].Color.ModeB, | |||
fxMesa->TexCombineExt[unit].Color.SourceC, | |||
fxMesa->TexCombineExt[unit].Color.InvertC, | |||
fxMesa->TexCombineExt[unit].Color.SourceD, | |||
fxMesa->TexCombineExt[unit].Color.InvertD, | |||
fxMesa->TexCombineExt[unit].Color.Shift, | |||
fxMesa->TexCombineExt[unit].Color.Invert); | |||
fxMesa->Glide.grTexAlphaCombineExt(TDFX_TMU0 + unit, | |||
fxMesa->TexCombineExt[unit].Alpha.SourceA, | |||
fxMesa->TexCombineExt[unit].Alpha.ModeA, | |||
fxMesa->TexCombineExt[unit].Alpha.SourceB, | |||
fxMesa->TexCombineExt[unit].Alpha.ModeB, | |||
fxMesa->TexCombineExt[unit].Alpha.SourceC, | |||
fxMesa->TexCombineExt[unit].Alpha.InvertC, | |||
fxMesa->TexCombineExt[unit].Alpha.SourceD, | |||
fxMesa->TexCombineExt[unit].Alpha.InvertD, | |||
fxMesa->TexCombineExt[unit].Alpha.Shift, | |||
fxMesa->TexCombineExt[unit].Alpha.Invert); | |||
fxMesa->Glide.grConstantColorValueExt(TDFX_TMU0 + unit, | |||
fxMesa->TexCombineExt[unit].EnvColor); | |||
} | |||
} | |||
else { | |||
/* Voodoo3 */ | |||
int unit; | |||
for (unit = 0; unit < TDFX_NUM_TMU; unit++) { | |||
struct tdfx_texcombine *comb = &fxMesa->TexCombine[unit]; | |||
fxMesa->Glide.grTexCombine(TDFX_TMU0 + unit, | |||
comb->FunctionRGB, | |||
comb->FactorRGB, | |||
comb->FunctionAlpha, | |||
comb->FactorAlpha, | |||
comb->InvertRGB, | |||
comb->InvertAlpha); | |||
} | |||
} | |||
} | |||
static void uploadTextureParams( tdfxContextPtr fxMesa ) | |||
{ | |||
int unit; | |||
for (unit = 0; unit < TDFX_NUM_TMU; unit++) { | |||
const struct tdfx_texparams *p = &fxMesa->TexParams[unit]; | |||
/* | |||
printf("upload params %d\n", unit); | |||
printf(" clamp %x %x\n", env->sClamp, env->tClamp); | |||
printf(" filter %x %x\n", env->minFilt, env->magFilt); | |||
printf(" mipmap %x %x\n", env->mmMode, env->LODblend); | |||
printf(" lod bias %f\n", env->LodBias); | |||
*/ | |||
fxMesa->Glide.grTexClampMode(GR_TMU0 + unit, p->sClamp, p->tClamp); | |||
fxMesa->Glide.grTexFilterMode(GR_TMU0 + unit, p->minFilt, p->magFilt); | |||
fxMesa->Glide.grTexMipMapMode(GR_TMU0 + unit, p->mmMode, p->LODblend); | |||
fxMesa->Glide.grTexLodBiasValue(GR_TMU0 + unit, p->LodBias); | |||
} | |||
} | |||
static void uploadTextureSource( tdfxContextPtr fxMesa ) | |||
{ | |||
int unit; | |||
for (unit = 0; unit < TDFX_NUM_TMU; unit++) { | |||
const struct tdfx_texsource *src = &fxMesa->TexSource[unit]; | |||
/* | |||
printf("upload source %d @ %d %p\n", unit, src->StartAddress, src->Info); | |||
*/ | |||
if (src->Info) { | |||
/* | |||
printf(" smallLodLog2=%d largeLodLog2=%d ar=%d format=%d data=%p\n", | |||
src->Info->smallLodLog2, src->Info->largeLodLog2, | |||
src->Info->aspectRatioLog2, src->Info->format, | |||
src->Info->data); | |||
*/ | |||
fxMesa->Glide.grTexSource(GR_TMU0 + unit, | |||
src->StartAddress, | |||
src->EvenOdd, | |||
src->Info); | |||
} | |||
} | |||
} | |||
static void uploadTextureImages( tdfxContextPtr fxMesa ) | |||
{ | |||
GLcontext *ctx = fxMesa->glCtx; | |||
int unit; | |||
for (unit = 0; unit < TDFX_NUM_TMU; unit++) { | |||
if (ctx->Texture.Unit[unit]._ReallyEnabled == TEXTURE_2D_BIT) { | |||
struct gl_texture_object *tObj = ctx->Texture.Unit[unit].Current2D; | |||
tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); | |||
if (ti && ti->reloadImages && ti->whichTMU != TDFX_TMU_NONE) { | |||
/* | |||
printf("download texture image on unit %d\n", unit); | |||
*/ | |||
tdfxTMDownloadTexture(fxMesa, tObj); | |||
ti->reloadImages = GL_FALSE; | |||
} | |||
} | |||
} | |||
} | |||
/* | |||
* If scissoring is enabled, compute intersection of scissor region | |||
* with all X clip rects, resulting in new cliprect list. | |||
* If number of cliprects is zero or one, call grClipWindow to setup | |||
* the clip region. Otherwise we'll call grClipWindow inside the | |||
* BEGIN_CLIP_LOOP macro. | |||
*/ | |||
void tdfxUploadClipping( tdfxContextPtr fxMesa ) | |||
{ | |||
__DRIdrawablePrivate *dPriv = fxMesa->driDrawable; | |||
assert(dPriv); | |||
if (fxMesa->numClipRects == 0) { | |||
/* all drawing clipped away */ | |||
fxMesa->Glide.grClipWindow(0, 0, 0, 0); | |||
} | |||
else if (fxMesa->numClipRects == 1) { | |||
fxMesa->Glide.grClipWindow(fxMesa->pClipRects[0].x1, | |||
fxMesa->screen_height - fxMesa->pClipRects[0].y2, | |||
fxMesa->pClipRects[0].x2, | |||
fxMesa->screen_height - fxMesa->pClipRects[0].y1); | |||
} | |||
/* else, we'll do a cliprect loop around all drawing */ | |||
fxMesa->Glide.grDRIPosition( dPriv->x, dPriv->y, dPriv->w, dPriv->h, | |||
fxMesa->numClipRects, fxMesa->pClipRects ); | |||
} | |||
void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ) | |||
{ | |||
if ( !fxMesa->dirty ) | |||
return; | |||
if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_COMBINE ) { | |||
if (TDFX_IS_NAPALM(fxMesa)) { | |||
fxMesa->Glide.grColorCombineExt(fxMesa->ColorCombineExt.SourceA, | |||
fxMesa->ColorCombineExt.ModeA, | |||
fxMesa->ColorCombineExt.SourceB, | |||
fxMesa->ColorCombineExt.ModeB, | |||
fxMesa->ColorCombineExt.SourceC, | |||
fxMesa->ColorCombineExt.InvertC, | |||
fxMesa->ColorCombineExt.SourceD, | |||
fxMesa->ColorCombineExt.InvertD, | |||
fxMesa->ColorCombineExt.Shift, | |||
fxMesa->ColorCombineExt.Invert); | |||
} | |||
else { | |||
/* Voodoo 3 */ | |||
fxMesa->Glide.grColorCombine( fxMesa->ColorCombine.Function, | |||
fxMesa->ColorCombine.Factor, | |||
fxMesa->ColorCombine.Local, | |||
fxMesa->ColorCombine.Other, | |||
fxMesa->ColorCombine.Invert ); | |||
} | |||
fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_COMBINE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_COMBINE ) { | |||
if (TDFX_IS_NAPALM(fxMesa)) { | |||
fxMesa->Glide.grAlphaCombineExt(fxMesa->AlphaCombineExt.SourceA, | |||
fxMesa->AlphaCombineExt.ModeA, | |||
fxMesa->AlphaCombineExt.SourceB, | |||
fxMesa->AlphaCombineExt.ModeB, | |||
fxMesa->AlphaCombineExt.SourceC, | |||
fxMesa->AlphaCombineExt.InvertC, | |||
fxMesa->AlphaCombineExt.SourceD, | |||
fxMesa->AlphaCombineExt.InvertD, | |||
fxMesa->AlphaCombineExt.Shift, | |||
fxMesa->AlphaCombineExt.Invert); | |||
} | |||
else { | |||
/* Voodoo 3 */ | |||
fxMesa->Glide.grAlphaCombine( fxMesa->AlphaCombine.Function, | |||
fxMesa->AlphaCombine.Factor, | |||
fxMesa->AlphaCombine.Local, | |||
fxMesa->AlphaCombine.Other, | |||
fxMesa->AlphaCombine.Invert ); | |||
} | |||
fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_COMBINE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_RENDER_BUFFER ) { | |||
fxMesa->Glide.grRenderBuffer( fxMesa->DrawBuffer ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_RENDER_BUFFER; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE) { | |||
fxMesa->Glide.grStipplePattern( fxMesa->Stipple.Pattern ); | |||
fxMesa->Glide.grStippleMode( fxMesa->Stipple.Mode ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_TEST ) { | |||
fxMesa->Glide.grAlphaTestFunction( fxMesa->Color.AlphaFunc ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_TEST; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_REF ) { | |||
fxMesa->Glide.grAlphaTestReferenceValue( fxMesa->Color.AlphaRef ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_REF; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_BLEND_FUNC ) { | |||
if (fxMesa->Glide.grAlphaBlendFunctionExt) { | |||
fxMesa->Glide.grAlphaBlendFunctionExt( fxMesa->Color.BlendSrcRGB, | |||
fxMesa->Color.BlendDstRGB, | |||
GR_BLEND_OP_ADD, | |||
fxMesa->Color.BlendSrcA, | |||
fxMesa->Color.BlendDstA, | |||
GR_BLEND_OP_ADD ); | |||
} | |||
else { | |||
fxMesa->Glide.grAlphaBlendFunction( fxMesa->Color.BlendSrcRGB, | |||
fxMesa->Color.BlendDstRGB, | |||
fxMesa->Color.BlendSrcA, | |||
fxMesa->Color.BlendDstA ); | |||
} | |||
fxMesa->dirty &= ~TDFX_UPLOAD_BLEND_FUNC; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_MODE ) { | |||
fxMesa->Glide.grDepthBufferMode( fxMesa->Depth.Mode ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_MODE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_BIAS ) { | |||
fxMesa->Glide.grDepthBiasLevel( fxMesa->Depth.Bias ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_BIAS; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_FUNC ) { | |||
fxMesa->Glide.grDepthBufferFunction( fxMesa->Depth.Func ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_FUNC; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_MASK ) { | |||
fxMesa->Glide.grDepthMask( fxMesa->Depth.Mask ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_MASK; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_DITHER) { | |||
fxMesa->Glide.grDitherMode( fxMesa->Color.Dither ); | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_FOG_MODE ) { | |||
fxMesa->Glide.grFogMode( fxMesa->Fog.Mode ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_FOG_MODE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_FOG_COLOR ) { | |||
fxMesa->Glide.grFogColorValue( fxMesa->Fog.Color ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_FOG_COLOR; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_FOG_TABLE ) { | |||
fxMesa->Glide.grFogTable( fxMesa->Fog.Table ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_FOG_TABLE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_CULL ) { | |||
fxMesa->Glide.grCullMode( fxMesa->CullMode ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_CULL; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_CLIP ) { | |||
tdfxUploadClipping( fxMesa ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_CLIP; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK ) { | |||
if ( fxMesa->Glide.grColorMaskExt | |||
&& fxMesa->glCtx->Visual.redBits == 8) { | |||
fxMesa->Glide.grColorMaskExt( fxMesa->Color.ColorMask[RCOMP], | |||
fxMesa->Color.ColorMask[GCOMP], | |||
fxMesa->Color.ColorMask[BCOMP], | |||
fxMesa->Color.ColorMask[ACOMP] ); | |||
} else { | |||
fxMesa->Glide.grColorMask( fxMesa->Color.ColorMask[RCOMP] || | |||
fxMesa->Color.ColorMask[GCOMP] || | |||
fxMesa->Color.ColorMask[BCOMP], | |||
fxMesa->Color.ColorMask[ACOMP] ); | |||
} | |||
fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_MASK; | |||
} | |||
/* if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) { */ | |||
/* grConstantColorValue( fxMesa->Color.MonoColor ); */ | |||
/* fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR; */ | |||
/* } */ | |||
if ( fxMesa->dirty & TDFX_UPLOAD_LINE ) { | |||
if (fxMesa->glCtx->Line.SmoothFlag && fxMesa->glCtx->Line.Width == 1.0) | |||
fxMesa->Glide.grEnable(GR_AA_ORDERED); | |||
else | |||
fxMesa->Glide.grDisable(GR_AA_ORDERED); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_LINE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_STENCIL ) { | |||
if (fxMesa->glCtx->Stencil.Enabled) { | |||
fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT); | |||
fxMesa->Glide.grStencilOp(fxMesa->Stencil.FailFunc, | |||
fxMesa->Stencil.ZFailFunc, | |||
fxMesa->Stencil.ZPassFunc); | |||
fxMesa->Glide.grStencilFunc(fxMesa->Stencil.Function, | |||
fxMesa->Stencil.RefValue, | |||
fxMesa->Stencil.ValueMask); | |||
fxMesa->Glide.grStencilMask(fxMesa->Stencil.WriteMask); | |||
} | |||
else { | |||
fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT); | |||
} | |||
fxMesa->dirty &= ~TDFX_UPLOAD_STENCIL; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_VERTEX_LAYOUT ) { | |||
fxMesa->Glide.grGlideSetVertexLayout( fxMesa->layout[fxMesa->vertexFormat] ); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_VERTEX_LAYOUT; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_ENV ) { | |||
uploadTextureEnv(fxMesa); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_ENV; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_PARAMS ) { | |||
uploadTextureParams(fxMesa); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_PARAMS; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_PALETTE ) { | |||
if (fxMesa->TexPalette.Data) { | |||
fxMesa->Glide.grTexDownloadTable(fxMesa->TexPalette.Type, fxMesa->TexPalette.Data); | |||
} | |||
fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_PALETTE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_SOURCE ) { | |||
uploadTextureSource(fxMesa); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_SOURCE; | |||
} | |||
if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_IMAGES ) { | |||
uploadTextureImages(fxMesa); | |||
fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_IMAGES; | |||
} | |||
fxMesa->dirty = 0; | |||
} | |||
void tdfxDDInitRenderFuncs( GLcontext *ctx ) | |||
{ | |||
ctx->Driver.Clear = tdfxDDClear; | |||
ctx->Driver.Finish = tdfxDDFinish; | |||
ctx->Driver.Flush = tdfxDDFlush; | |||
} |
@@ -0,0 +1,54 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_RENDER_H__ | |||
#define __TDFX_RENDER_H__ | |||
#ifdef GLX_DIRECT_RENDERING | |||
#include "tdfx_context.h" | |||
extern void tdfxDDInitRenderFuncs( GLcontext *ctx ); | |||
extern void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ); | |||
extern void tdfxUploadClipping( tdfxContextPtr fxMesa ); | |||
#define FLUSH_BATCH( fxMesa ) | |||
#endif | |||
#endif |
@@ -0,0 +1,331 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c,v 1.3 2002/02/22 21:45:03 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* | |||
*/ | |||
#include "tdfx_dri.h" | |||
#include "tdfx_context.h" | |||
#include "tdfx_lock.h" | |||
#include "tdfx_vb.h" | |||
#include "tdfx_tris.h" | |||
#ifdef DEBUG_LOCKING | |||
char *prevLockFile = 0; | |||
int prevLockLine = 0; | |||
#endif | |||
#ifndef TDFX_DEBUG | |||
int TDFX_DEBUG = (0 | |||
/* | DEBUG_ALWAYS_SYNC */ | |||
/* | DEBUG_VERBOSE_API */ | |||
/* | DEBUG_VERBOSE_MSG */ | |||
/* | DEBUG_VERBOSE_LRU */ | |||
/* | DEBUG_VERBOSE_DRI */ | |||
/* | DEBUG_VERBOSE_IOCTL */ | |||
/* | DEBUG_VERBOSE_2D */ | |||
); | |||
#endif | |||
static GLboolean | |||
tdfxCreateScreen( __DRIscreenPrivate *sPriv ) | |||
{ | |||
tdfxScreenPrivate *fxScreen; | |||
TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv; | |||
/* Allocate the private area */ | |||
fxScreen = (tdfxScreenPrivate *) Xmalloc( sizeof(tdfxScreenPrivate) ); | |||
if ( !fxScreen ) | |||
return GL_FALSE; | |||
fxScreen->driScrnPriv = sPriv; | |||
sPriv->private = (void *) fxScreen; | |||
fxScreen->regs.handle = fxDRIPriv->regs; | |||
fxScreen->regs.size = fxDRIPriv->regsSize; | |||
fxScreen->deviceID = fxDRIPriv->deviceID; | |||
fxScreen->width = fxDRIPriv->width; | |||
fxScreen->height = fxDRIPriv->height; | |||
fxScreen->mem = fxDRIPriv->mem; | |||
fxScreen->cpp = fxDRIPriv->cpp; | |||
fxScreen->stride = fxDRIPriv->stride; | |||
fxScreen->fifoOffset = fxDRIPriv->fifoOffset; | |||
fxScreen->fifoSize = fxDRIPriv->fifoSize; | |||
fxScreen->fbOffset = fxDRIPriv->fbOffset; | |||
fxScreen->backOffset = fxDRIPriv->backOffset; | |||
fxScreen->depthOffset = fxDRIPriv->depthOffset; | |||
fxScreen->textureOffset = fxDRIPriv->textureOffset; | |||
fxScreen->textureSize = fxDRIPriv->textureSize; | |||
fxScreen->sarea_priv_offset = fxDRIPriv->sarea_priv_offset; | |||
if ( drmMap( sPriv->fd, fxScreen->regs.handle, | |||
fxScreen->regs.size, &fxScreen->regs.map ) ) { | |||
return GL_FALSE; | |||
} | |||
return GL_TRUE; | |||
} | |||
static void | |||
tdfxDestroyScreen( __DRIscreenPrivate *sPriv ) | |||
{ | |||
tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private; | |||
if ( fxScreen ) { | |||
drmUnmap( fxScreen->regs.map, fxScreen->regs.size ); | |||
Xfree( fxScreen ); | |||
sPriv->private = NULL; | |||
} | |||
} | |||
static GLboolean | |||
tdfxInitDriver( __DRIscreenPrivate *sPriv ) | |||
{ | |||
if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { | |||
fprintf( stderr, "%s( %p )\n", __FUNCTION__, sPriv ); | |||
} | |||
/* Check the DRI externsion version */ | |||
if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) { | |||
__driUtilMessage( "tdfx DRI driver expected DRI version 4.0.x " | |||
"but got version %d.%d.%d", | |||
sPriv->driMajor, sPriv->driMinor, sPriv->driPatch ); | |||
return GL_FALSE; | |||
} | |||
/* Check that the DDX driver version is compatible */ | |||
if ( sPriv->ddxMajor != 1 || | |||
sPriv->ddxMinor < 0 ) { | |||
__driUtilMessage( | |||
"3dfx DRI driver expected DDX driver version 1.0.x " | |||
"but got version %d.%d.%d", | |||
sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); | |||
return GL_FALSE; | |||
} | |||
/* Check that the DRM driver version is compatible */ | |||
if ( sPriv->drmMajor != 1 || | |||
sPriv->drmMinor < 0 ) { | |||
__driUtilMessage( | |||
"3dfx DRI driver expected DRM driver version 1.0.x " | |||
"but got version %d.%d.%d", | |||
sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); | |||
return GL_FALSE; | |||
} | |||
if ( !tdfxCreateScreen( sPriv ) ) { | |||
tdfxDestroyScreen( sPriv ); | |||
return GL_FALSE; | |||
} | |||
return GL_TRUE; | |||
} | |||
static GLboolean | |||
tdfxCreateBuffer( __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, | |||
GL_FALSE /* software alpha channel? */ ); | |||
return (driDrawPriv->driverPrivate != NULL); | |||
} | |||
} | |||
static void | |||
tdfxDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) | |||
{ | |||
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); | |||
} | |||
static void | |||
tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) | |||
{ | |||
GET_CURRENT_CONTEXT(ctx); | |||
tdfxContextPtr fxMesa = 0; | |||
GLframebuffer *mesaBuffer; | |||
if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { | |||
fprintf( stderr, "%s( %p )\n", __FUNCTION__, driDrawPriv ); | |||
} | |||
mesaBuffer = (GLframebuffer *) driDrawPriv->driverPrivate; | |||
if ( !mesaBuffer->Visual.doubleBufferMode ) | |||
return; /* can't swap a single-buffered window */ | |||
/* If the current context's drawable matches the given drawable | |||
* we have to do a glFinish (per the GLX spec). | |||
*/ | |||
if ( ctx ) { | |||
__DRIdrawablePrivate *curDrawPriv; | |||
fxMesa = TDFX_CONTEXT(ctx); | |||
curDrawPriv = fxMesa->driContext->driDrawablePriv; | |||
if ( curDrawPriv == driDrawPriv ) { | |||
/* swapping window bound to current context, flush first */ | |||
_mesa_notifySwapBuffers( ctx ); | |||
LOCK_HARDWARE( fxMesa ); | |||
} | |||
else { | |||
/* find the fxMesa context previously bound to the window */ | |||
fxMesa = (tdfxContextPtr) driDrawPriv->driContextPriv->driverPrivate; | |||
if (!fxMesa) | |||
return; | |||
LOCK_HARDWARE( fxMesa ); | |||
fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); | |||
printf("SwapBuf SetState 1\n"); | |||
fxMesa->Glide.grGlideSetState(fxMesa->Glide.State ); | |||
} | |||
} | |||
#ifdef STATS | |||
{ | |||
int stalls; | |||
static int prevStalls = 0; | |||
stalls = fxMesa->Glide.grFifoGetStalls(); | |||
fprintf( stderr, "%s:\n", __FUNCTION__ ); | |||
if ( stalls != prevStalls ) { | |||
fprintf( stderr, " %d stalls occurred\n", | |||
stalls - prevStalls ); | |||
prevStalls = stalls; | |||
} | |||
if ( fxMesa && fxMesa->texSwaps ) { | |||
fprintf( stderr, " %d texture swaps occurred\n", | |||
fxMesa->texSwaps ); | |||
fxMesa->texSwaps = 0; | |||
} | |||
} | |||
#endif | |||
if (fxMesa->scissoredClipRects) { | |||
/* restore clip rects without scissor box */ | |||
fxMesa->Glide.grDRIPosition( driDrawPriv->x, driDrawPriv->y, | |||
driDrawPriv->w, driDrawPriv->h, | |||
driDrawPriv->numClipRects, | |||
driDrawPriv->pClipRects ); | |||
} | |||
fxMesa->Glide.grDRIBufferSwap( fxMesa->Glide.SwapInterval ); | |||
if (fxMesa->scissoredClipRects) { | |||
/* restore clip rects WITH scissor box */ | |||
fxMesa->Glide.grDRIPosition( driDrawPriv->x, driDrawPriv->y, | |||
driDrawPriv->w, driDrawPriv->h, | |||
fxMesa->numClipRects, fxMesa->pClipRects ); | |||
} | |||
#if 0 | |||
{ | |||
FxI32 result; | |||
do { | |||
FxI32 result; | |||
fxMesa->Glide.grGet(GR_PENDING_BUFFERSWAPS, 4, &result); | |||
} while ( result > fxMesa->maxPendingSwapBuffers ); | |||
} | |||
#endif | |||
fxMesa->stats.swapBuffer++; | |||
if (ctx) { | |||
if (ctx->DriverCtx != fxMesa) { | |||
fxMesa = TDFX_CONTEXT(ctx); | |||
fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); | |||
printf("SwapBuf SetState 2\n"); | |||
fxMesa->Glide.grGlideSetState(fxMesa->Glide.State ); | |||
} | |||
UNLOCK_HARDWARE( fxMesa ); | |||
} | |||
} | |||
static GLboolean | |||
tdfxOpenCloseFullScreen(__DRIcontextPrivate *driContextPriv) | |||
{ | |||
return GL_TRUE; | |||
} | |||
static const struct __DriverAPIRec tdfxAPI = { | |||
.InitDriver = tdfxInitDriver, | |||
.DestroyScreen = tdfxDestroyScreen, | |||
.CreateContext = tdfxCreateContext, | |||
.DestroyContext = tdfxDestroyContext, | |||
.CreateBuffer = tdfxCreateBuffer, | |||
.DestroyBuffer = tdfxDestroyBuffer, | |||
.SwapBuffers = tdfxSwapBuffers, | |||
.MakeCurrent = tdfxMakeCurrent, | |||
.UnbindContext = tdfxUnbindContext, | |||
.OpenFullScreen = tdfxOpenCloseFullScreen, | |||
.CloseFullScreen = tdfxOpenCloseFullScreen, | |||
.GetSwapInfo = NULL, | |||
.GetMSC = NULL, | |||
.WaitForMSC = NULL, | |||
.WaitForSBC = NULL, | |||
.SwapBuffersMSC = NULL | |||
}; | |||
/* | |||
* 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, &tdfxAPI); | |||
return (void *) psp; | |||
} |
@@ -0,0 +1,73 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h,v 1.2 2002/02/22 21:45:03 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_SCREEN_H__ | |||
#define __TDFX_SCREEN_H__ | |||
#ifdef GLX_DIRECT_RENDERING | |||
typedef struct { | |||
drmHandle handle; | |||
drmSize size; | |||
drmAddress map; | |||
} tdfxRegion, *tdfxRegionPtr; | |||
typedef struct { | |||
tdfxRegion regs; | |||
int deviceID; | |||
int width; | |||
int height; | |||
int mem; | |||
int cpp; | |||
int stride; | |||
int fifoOffset; | |||
int fifoSize; | |||
int fbOffset; | |||
int backOffset; | |||
int depthOffset; | |||
int textureOffset; | |||
int textureSize; | |||
__DRIscreenPrivate *driScrnPriv; | |||
unsigned int sarea_priv_offset; | |||
} tdfxScreenPrivate; | |||
#endif | |||
#endif |
@@ -0,0 +1,48 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_SPAN_H__ | |||
#define __TDFX_SPAN_H__ | |||
#ifdef GLX_DIRECT_RENDERING | |||
#include "context.h" | |||
extern void tdfxDDInitSpanFuncs( GLcontext *ctx ); | |||
#endif | |||
#endif |
@@ -0,0 +1,64 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.h,v 1.2 2002/02/22 21:45:04 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_STATE_H__ | |||
#define __TDFX_STATE_H__ | |||
#ifdef GLX_DIRECT_RENDERING | |||
#include "context.h" | |||
#include "tdfx_context.h" | |||
extern void tdfxDDInitStateFuncs( GLcontext *ctx ); | |||
extern void tdfxDDUpdateHwState( GLcontext *ctx ); | |||
extern void tdfxInitState( tdfxContextPtr fxMesa ); | |||
extern void tdfxUpdateClipping( GLcontext *ctx ); | |||
extern void tdfxFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); | |||
#define FALLBACK( rmesa, bit, mode ) tdfxFallback( rmesa->glCtx, bit, mode ) | |||
extern void tdfxUpdateCull( GLcontext *ctx ); | |||
extern void tdfxUpdateStipple( GLcontext *ctx ); | |||
extern void tdfxUpdateViewport( GLcontext *ctx ); | |||
#endif | |||
#endif |
@@ -0,0 +1,165 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h,v 1.2 2002/02/22 21:45:04 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#ifndef _TDFX_TEX_H_ | |||
#define _TDFX_TEX_H_ | |||
#include "texutil.h" | |||
#define tdfxDDIsCompressedFormatMacro(internalFormat) \ | |||
(((internalFormat) == GL_COMPRESSED_RGB_FXT1_3DFX) || \ | |||
((internalFormat) == GL_COMPRESSED_RGBA_FXT1_3DFX)) | |||
#define tdfxDDIsCompressedGlideFormatMacro(internalFormat) \ | |||
((internalFormat) == GR_TEXFMT_ARGB_CMP_FXT1) | |||
extern void | |||
tdfxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj); | |||
extern void | |||
tdfxDDBindTexture(GLcontext * ctx, GLenum target, | |||
struct gl_texture_object *tObj); | |||
extern void | |||
tdfxDDDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj); | |||
extern GLboolean | |||
tdfxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj); | |||
extern void | |||
tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj); | |||
#if 000 /* DEAD? */ | |||
extern void | |||
fxDDTexUseGlobalPalette(GLcontext * ctx, GLboolean state); | |||
#endif | |||
extern void | |||
tdfxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname, | |||
const GLfloat * param); | |||
extern void | |||
tdfxDDTexParameter(GLcontext * ctx, GLenum target, | |||
struct gl_texture_object *tObj, | |||
GLenum pname, const GLfloat * params); | |||
extern const struct gl_texture_format * | |||
tdfxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, | |||
GLenum srcFormat, GLenum srcType ); | |||
extern void | |||
tdfxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, | |||
GLint internalFormat, GLint width, GLint height, | |||
GLint border, | |||
GLenum format, GLenum type, const GLvoid * pixels, | |||
const struct gl_pixelstore_attrib * packing, | |||
struct gl_texture_object * texObj, | |||
struct gl_texture_image * texImage); | |||
extern void | |||
tdfxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, | |||
GLint xoffset, GLint yoffset, | |||
GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const GLvoid *pixels, | |||
const struct gl_pixelstore_attrib *packing, | |||
struct gl_texture_object *texObj, | |||
struct gl_texture_image *texImage ); | |||
#if 000 | |||
extern GLboolean | |||
tdfxDDCompressedTexImage2D( GLcontext *ctx, GLenum target, | |||
GLint level, GLsizei imageSize, | |||
const GLvoid *data, | |||
struct gl_texture_object *texObj, | |||
struct gl_texture_image *texImage, | |||
GLboolean *retainInternalCopy); | |||
extern GLboolean | |||
tdfxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target, | |||
GLint level, GLint xoffset, | |||
GLint yoffset, GLsizei width, | |||
GLint height, GLenum format, | |||
GLsizei imageSize, const GLvoid *data, | |||
struct gl_texture_object *texObj, | |||
struct gl_texture_image *texImage ); | |||
#endif | |||
extern GLboolean | |||
tdfxDDTestProxyTexImage(GLcontext *ctx, GLenum target, | |||
GLint level, GLint internalFormat, | |||
GLenum format, GLenum type, | |||
GLint width, GLint height, | |||
GLint depth, GLint border); | |||
extern GLvoid * | |||
tdfxDDGetTexImage(GLcontext * ctx, GLenum target, GLint level, | |||
const struct gl_texture_object *texObj, | |||
GLenum * formatOut, GLenum * typeOut, | |||
GLboolean * freeImageOut); | |||
extern void | |||
tdfxDDGetCompressedTexImage( GLcontext *ctx, GLenum target, | |||
GLint lod, void *image, | |||
const struct gl_texture_object *texObj, | |||
struct gl_texture_image *texImage ); | |||
extern GLint | |||
tdfxDDSpecificCompressedTexFormat(GLcontext *ctx, | |||
GLint internalFormat, | |||
GLint numDimensions); | |||
extern GLint | |||
tdfxDDBaseCompressedTexFormat(GLcontext *ctx, | |||
GLint internalFormat); | |||
extern GLboolean | |||
tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat); | |||
extern GLsizei | |||
tdfxDDCompressedImageSize(GLcontext *ctx, | |||
GLenum intFormat, | |||
GLuint numDimensions, | |||
GLuint width, | |||
GLuint height, | |||
GLuint depth); | |||
#endif |
@@ -0,0 +1,970 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c,v 1.5 2002/02/22 21:45:04 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#include "tdfx_context.h" | |||
#include "tdfx_tex.h" | |||
#include "tdfx_texman.h" | |||
#define BAD_ADDRESS ((FxU32) -1) | |||
#if 0 /* DEBUG use */ | |||
/* | |||
* Verify the consistancy of the texture memory manager. | |||
* This involves: | |||
* Traversing all texture objects and computing total memory used. | |||
* Traverse the free block list and computing total memory free. | |||
* Compare the total free and total used amounts to the total memory size. | |||
* Make various assertions about the results. | |||
*/ | |||
static void | |||
VerifyFreeList(tdfxContextPtr fxMesa, FxU32 tmu) | |||
{ | |||
struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; | |||
struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; | |||
tdfxMemRange *block; | |||
int prevStart = -1, prevEnd = -1; | |||
int totalFree = 0; | |||
int numObj = 0, numRes = 0; | |||
int totalUsed = 0; | |||
for (block = shared->tmFree[tmu]; block; block = block->next) { | |||
assert( block->endAddr > 0 ); | |||
assert( block->startAddr <= shared->totalTexMem[tmu] ); | |||
assert( block->endAddr <= shared->totalTexMem[tmu] ); | |||
assert( (int) block->startAddr > prevStart ); | |||
assert( (int) block->startAddr >= prevEnd ); | |||
prevStart = (int) block->startAddr; | |||
prevEnd = (int) block->endAddr; | |||
totalFree += (block->endAddr - block->startAddr); | |||
} | |||
assert(totalFree == shared->freeTexMem[tmu]); | |||
{ | |||
struct gl_texture_object *obj; | |||
for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { | |||
tdfxTexInfo *ti = TDFX_TEXTURE_DATA(obj); | |||
numObj++; | |||
if (ti) { | |||
if (ti->isInTM) { | |||
numRes++; | |||
assert(ti->tm[0]); | |||
if (ti->tm[tmu]) | |||
totalUsed += (ti->tm[tmu]->endAddr - ti->tm[tmu]->startAddr); | |||
} | |||
else { | |||
assert(!ti->tm[0]); | |||
} | |||
} | |||
} | |||
} | |||
printf("totalFree: %d totalUsed: %d totalMem: %d #objs=%d #res=%d\n", | |||
shared->freeTexMem[tmu], totalUsed, shared->totalTexMem[tmu], | |||
numObj, numRes); | |||
assert(totalUsed + totalFree == shared->totalTexMem[tmu]); | |||
} | |||
static void | |||
dump_texmem(tdfxContextPtr fxMesa) | |||
{ | |||
struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; | |||
struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; | |||
struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj; | |||
tdfxMemRange *r; | |||
FxU32 prev; | |||
printf("DUMP Objects:\n"); | |||
for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { | |||
tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj); | |||
if (info && info->isInTM) { | |||
printf("Obj %8p: %4d info = %p\n", obj, obj->Name, info); | |||
printf(" isInTM=%d whichTMU=%d lastTimeUsed=%d\n", | |||
info->isInTM, info->whichTMU, info->lastTimeUsed); | |||
printf(" tm[0] = %p", info->tm[0]); | |||
assert(info->tm[0]); | |||
if (info->tm[0]) { | |||
printf(" tm startAddr = %d endAddr = %d", | |||
info->tm[0]->startAddr, | |||
info->tm[0]->endAddr); | |||
} | |||
printf("\n"); | |||
printf(" tm[1] = %p", info->tm[1]); | |||
if (info->tm[1]) { | |||
printf(" tm startAddr = %d endAddr = %d", | |||
info->tm[1]->startAddr, | |||
info->tm[1]->endAddr); | |||
} | |||
printf("\n"); | |||
} | |||
} | |||
VerifyFreeList(fxMesa, 0); | |||
VerifyFreeList(fxMesa, 1); | |||
printf("Free memory unit 0: %d bytes\n", shared->freeTexMem[0]); | |||
prev = 0; | |||
for (r = shared->tmFree[0]; r; r = r->next) { | |||
printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev); | |||
prev = r->endAddr; | |||
} | |||
printf("Free memory unit 1: %d bytes\n", shared->freeTexMem[1]); | |||
prev = 0; | |||
for (r = shared->tmFree[1]; r; r = r->next) { | |||
printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev); | |||
prev = r->endAddr; | |||
} | |||
} | |||
#endif | |||
#ifdef TEXSANITY | |||
static void | |||
fubar(void) | |||
{ | |||
} | |||
/* | |||
* Sanity Check | |||
*/ | |||
static void | |||
sanity(tdfxContextPtr fxMesa) | |||
{ | |||
tdfxMemRange *tmp, *prev, *pos; | |||
prev = 0; | |||
tmp = fxMesa->tmFree[0]; | |||
while (tmp) { | |||
if (!tmp->startAddr && !tmp->endAddr) { | |||
fprintf(stderr, "Textures fubar\n"); | |||
fubar(); | |||
} | |||
if (tmp->startAddr >= tmp->endAddr) { | |||
fprintf(stderr, "Node fubar\n"); | |||
fubar(); | |||
} | |||
if (prev && (prev->startAddr >= tmp->startAddr || | |||
prev->endAddr > tmp->startAddr)) { | |||
fprintf(stderr, "Sorting fubar\n"); | |||
fubar(); | |||
} | |||
prev = tmp; | |||
tmp = tmp->next; | |||
} | |||
prev = 0; | |||
tmp = fxMesa->tmFree[1]; | |||
while (tmp) { | |||
if (!tmp->startAddr && !tmp->endAddr) { | |||
fprintf(stderr, "Textures fubar\n"); | |||
fubar(); | |||
} | |||
if (tmp->startAddr >= tmp->endAddr) { | |||
fprintf(stderr, "Node fubar\n"); | |||
fubar(); | |||
} | |||
if (prev && (prev->startAddr >= tmp->startAddr || | |||
prev->endAddr > tmp->startAddr)) { | |||
fprintf(stderr, "Sorting fubar\n"); | |||
fubar(); | |||
} | |||
prev = tmp; | |||
tmp = tmp->next; | |||
} | |||
} | |||
#endif | |||
/* | |||
* Allocate and initialize a new MemRange struct. | |||
* Try to allocate it from the pool of free MemRange nodes rather than malloc. | |||
*/ | |||
static tdfxMemRange * | |||
NewRangeNode(tdfxContextPtr fxMesa, FxU32 start, FxU32 end) | |||
{ | |||
struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; | |||
struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; | |||
tdfxMemRange *result; | |||
_glthread_LOCK_MUTEX(mesaShared->Mutex); | |||
if (shared && shared->tmPool) { | |||
result = shared->tmPool; | |||
shared->tmPool = shared->tmPool->next; | |||
} | |||
else { | |||
result = MALLOC(sizeof(tdfxMemRange)); | |||
} | |||
_glthread_UNLOCK_MUTEX(mesaShared->Mutex); | |||
if (!result) { | |||
/*fprintf(stderr, "fxDriver: out of memory!\n");*/ | |||
return NULL; | |||
} | |||
result->startAddr = start; | |||
result->endAddr = end; | |||
result->next = NULL; | |||
return result; | |||
} | |||
/* | |||
* Initialize texture memory. | |||
* We take care of one or both TMU's here. | |||
*/ | |||
void | |||
tdfxTMInit(tdfxContextPtr fxMesa) | |||
{ | |||
if (!fxMesa->glCtx->Shared->DriverData) { | |||
const char *extensions; | |||
struct tdfxSharedState *shared = CALLOC_STRUCT(tdfxSharedState); | |||
if (!shared) | |||
return; | |||
LOCK_HARDWARE(fxMesa); | |||
extensions = fxMesa->Glide.grGetString(GR_EXTENSION); | |||
UNLOCK_HARDWARE(fxMesa); | |||
if (strstr(extensions, "TEXUMA")) { | |||
FxU32 start, end; | |||
shared->umaTexMemory = GL_TRUE; | |||
LOCK_HARDWARE(fxMesa); | |||
fxMesa->Glide.grEnable(GR_TEXTURE_UMA_EXT); | |||
start = fxMesa->Glide.grTexMinAddress(0); | |||
end = fxMesa->Glide.grTexMaxAddress(0); | |||
UNLOCK_HARDWARE(fxMesa); | |||
shared->totalTexMem[0] = end - start; | |||
shared->totalTexMem[1] = 0; | |||
shared->freeTexMem[0] = end - start; | |||
shared->freeTexMem[1] = 0; | |||
shared->tmFree[0] = NewRangeNode(fxMesa, start, end); | |||
shared->tmFree[1] = NULL; | |||
/*printf("UMA tex memory: %d\n", (int) (end - start));*/ | |||
} | |||
else { | |||
const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; | |||
int tmu; | |||
shared->umaTexMemory = GL_FALSE; | |||
LOCK_HARDWARE(fxMesa); | |||
for (tmu = 0; tmu < numTMUs; tmu++) { | |||
FxU32 start = fxMesa->Glide.grTexMinAddress(tmu); | |||
FxU32 end = fxMesa->Glide.grTexMaxAddress(tmu); | |||
shared->totalTexMem[tmu] = end - start; | |||
shared->freeTexMem[tmu] = end - start; | |||
shared->tmFree[tmu] = NewRangeNode(fxMesa, start, end); | |||
/*printf("Split tex memory: %d\n", (int) (end - start));*/ | |||
} | |||
UNLOCK_HARDWARE(fxMesa); | |||
} | |||
shared->tmPool = NULL; | |||
fxMesa->glCtx->Shared->DriverData = shared; | |||
/*printf("Texture memory init UMA: %d\n", shared->umaTexMemory);*/ | |||
} | |||
} | |||
/* | |||
* Clean-up texture memory before destroying context. | |||
*/ | |||
void | |||
tdfxTMClose(tdfxContextPtr fxMesa) | |||
{ | |||
if (fxMesa->glCtx->Shared->RefCount == 1 && fxMesa->driDrawable) { | |||
/* refcount will soon go to zero, free our 3dfx stuff */ | |||
struct tdfxSharedState *shared = (struct tdfxSharedState *) fxMesa->glCtx->Shared->DriverData; | |||
const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; | |||
int tmu; | |||
tdfxMemRange *tmp, *next; | |||
/* Deallocate the pool of free tdfxMemRange nodes */ | |||
tmp = shared->tmPool; | |||
while (tmp) { | |||
next = tmp->next; | |||
FREE(tmp); | |||
tmp = next; | |||
} | |||
/* Delete the texture memory block tdfxMemRange nodes */ | |||
for (tmu = 0; tmu < numTMUs; tmu++) { | |||
tmp = shared->tmFree[tmu]; | |||
while (tmp) { | |||
next = tmp->next; | |||
FREE(tmp); | |||
tmp = next; | |||
} | |||
} | |||
FREE(shared); | |||
fxMesa->glCtx->Shared->DriverData = NULL; | |||
} | |||
} | |||
/* | |||
* Delete a tdfxMemRange struct. | |||
* We keep a linked list of free/available tdfxMemRange structs to | |||
* avoid extra malloc/free calls. | |||
*/ | |||
#if 0 | |||
static void | |||
DeleteRangeNode_NoLock(struct TdfxSharedState *shared, tdfxMemRange *range) | |||
{ | |||
/* insert at head of list */ | |||
range->next = shared->tmPool; | |||
shared->tmPool = range; | |||
} | |||
#endif | |||
#define DELETE_RANGE_NODE(shared, range) \ | |||
(range)->next = (shared)->tmPool; \ | |||
(shared)->tmPool = (range) | |||
/* | |||
* When we've run out of texture memory we have to throw out an | |||
* existing texture to make room for the new one. This function | |||
* determins the texture to throw out. | |||
*/ | |||
static struct gl_texture_object * | |||
FindOldestObject(tdfxContextPtr fxMesa, FxU32 tmu) | |||
{ | |||
const GLuint bindnumber = fxMesa->texBindNumber; | |||
struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj; | |||
GLfloat lowestPriority; | |||
GLuint oldestAge; | |||
oldestObj = NULL; | |||
oldestAge = 0; | |||
lowestPriority = 1.0F; | |||
lowestPriorityObj = NULL; | |||
for (obj = fxMesa->glCtx->Shared->TexObjectList; obj; obj = obj->Next) { | |||
tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj); | |||
if (info && info->isInTM && | |||
((info->whichTMU == tmu) || (info->whichTMU == TDFX_TMU_BOTH) || | |||
(info->whichTMU == TDFX_TMU_SPLIT))) { | |||
GLuint age, lasttime; | |||
assert(info->tm[0]); | |||
lasttime = info->lastTimeUsed; | |||
if (lasttime > bindnumber) | |||
age = bindnumber + (UINT_MAX - lasttime + 1); /* TO DO: check wrap around */ | |||
else | |||
age = bindnumber - lasttime; | |||
if (age >= oldestAge) { | |||
oldestAge = age; | |||
oldestObj = obj; | |||
} | |||
/* examine priority */ | |||
if (obj->Priority < lowestPriority) { | |||
lowestPriority = obj->Priority; | |||
lowestPriorityObj = obj; | |||
} | |||
} | |||
} | |||
if (lowestPriority < 1.0) { | |||
ASSERT(lowestPriorityObj); | |||
/* | |||
printf("discard %d pri=%f\n", lowestPriorityObj->Name, lowestPriority); | |||
*/ | |||
return lowestPriorityObj; | |||
} | |||
else { | |||
/* | |||
printf("discard %d age=%d\n", oldestObj->Name, oldestAge); | |||
*/ | |||
return oldestObj; | |||
} | |||
} | |||
#if 0 | |||
static void | |||
FlushTexMemory(tdfxContextPtr fxMesa) | |||
{ | |||
struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; | |||
struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; | |||
struct gl_texture_object *obj; | |||
for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { | |||
if (obj->RefCount < 2) { | |||
/* don't flush currently bound textures */ | |||
tdfxTMMoveOutTM_NoLock(fxMesa, obj); | |||
} | |||
} | |||
} | |||
#endif | |||
/* | |||
* Find the address (offset?) at which we can store a new texture. | |||
* <tmu> is the texture unit. | |||
* <size> is the texture size in bytes. | |||
*/ | |||
static FxU32 | |||
FindStartAddr(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 size) | |||
{ | |||
struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; | |||
struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; | |||
tdfxMemRange *prev, *block; | |||
FxU32 result; | |||
#if 0 | |||
int discardedCount = 0; | |||
#define MAX_DISCARDS 10 | |||
#endif | |||
if (shared->umaTexMemory) { | |||
assert(tmu == TDFX_TMU0); | |||
} | |||
_glthread_LOCK_MUTEX(mesaShared->Mutex); | |||
while (1) { | |||
prev = NULL; | |||
block = shared->tmFree[tmu]; | |||
while (block) { | |||
if (block->endAddr - block->startAddr >= size) { | |||
/* The texture will fit here */ | |||
result = block->startAddr; | |||
block->startAddr += size; | |||
if (block->startAddr == block->endAddr) { | |||
/* Remove this node since it's empty */ | |||
if (prev) { | |||
prev->next = block->next; | |||
} | |||
else { | |||
shared->tmFree[tmu] = block->next; | |||
} | |||
DELETE_RANGE_NODE(shared, block); | |||
} | |||
shared->freeTexMem[tmu] -= size; | |||
_glthread_UNLOCK_MUTEX(mesaShared->Mutex); | |||
return result; | |||
} | |||
prev = block; | |||
block = block->next; | |||
} | |||
/* We failed to find a block large enough to accomodate <size> bytes. | |||
* Find the oldest texObject and free it. | |||
*/ | |||
#if 0 | |||
discardedCount++; | |||
if (discardedCount > MAX_DISCARDS + 1) { | |||
_mesa_problem(NULL, "%s: extreme texmem fragmentation", __FUNCTION__); | |||
_glthread_UNLOCK_MUTEX(mesaShared->Mutex); | |||
return BAD_ADDRESS; | |||
} | |||
else if (discardedCount > MAX_DISCARDS) { | |||
/* texture memory is probably really fragmented, flush it */ | |||
FlushTexMemory(fxMesa); | |||
} | |||
else | |||
#endif | |||
{ | |||
struct gl_texture_object *obj = FindOldestObject(fxMesa, tmu); | |||
if (obj) { | |||
tdfxTMMoveOutTM_NoLock(fxMesa, obj); | |||
fxMesa->stats.texSwaps++; | |||
} | |||
else { | |||
_mesa_problem(NULL, "%s: extreme texmem fragmentation", __FUNCTION__); | |||
_glthread_UNLOCK_MUTEX(mesaShared->Mutex); | |||
return BAD_ADDRESS; | |||
} | |||
} | |||
} | |||
/* never get here, but play it safe */ | |||
_glthread_UNLOCK_MUTEX(mesaShared->Mutex); | |||
return BAD_ADDRESS; | |||
} | |||
/* | |||
* Remove the given tdfxMemRange node from hardware texture memory. | |||
*/ | |||
static void | |||
RemoveRange_NoLock(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range) | |||
{ | |||
struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; | |||
struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; | |||
tdfxMemRange *block, *prev; | |||
if (shared->umaTexMemory) { | |||
assert(tmu == TDFX_TMU0); | |||
} | |||
if (!range) | |||
return; | |||
if (range->startAddr == range->endAddr) { | |||
DELETE_RANGE_NODE(shared, range); | |||
return; | |||
} | |||
shared->freeTexMem[tmu] += range->endAddr - range->startAddr; | |||
/* find position in linked list to insert this tdfxMemRange node */ | |||
prev = NULL; | |||
block = shared->tmFree[tmu]; | |||
while (block) { | |||
assert(range->startAddr != block->startAddr); | |||
if (range->startAddr > block->startAddr) { | |||
prev = block; | |||
block = block->next; | |||
} | |||
else { | |||
break; | |||
} | |||
} | |||
/* Insert the free block, combine with adjacent blocks when possible */ | |||
range->next = block; | |||
if (block) { | |||
if (range->endAddr == block->startAddr) { | |||
/* Combine */ | |||
block->startAddr = range->startAddr; | |||
DELETE_RANGE_NODE(shared, range); | |||
range = block; | |||
} | |||
} | |||
if (prev) { | |||
if (prev->endAddr == range->startAddr) { | |||
/* Combine */ | |||
prev->endAddr = range->endAddr; | |||
prev->next = range->next; | |||
DELETE_RANGE_NODE(shared, range); | |||
} | |||
else { | |||
prev->next = range; | |||
} | |||
} | |||
else { | |||
shared->tmFree[tmu] = range; | |||
} | |||
} | |||
#if 0 /* NOT USED */ | |||
static void | |||
RemoveRange(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range) | |||
{ | |||
struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; | |||
_glthread_LOCK_MUTEX(mesaShared->Mutex); | |||
RemoveRange_NoLock(fxMesa, tmu, range); | |||
_glthread_UNLOCK_MUTEX(mesaShared->Mutex); | |||
} | |||
#endif | |||
/* | |||
* Allocate space for a texture image. | |||
* <tmu> is the texture unit | |||
* <texmemsize> is the number of bytes to allocate | |||
*/ | |||
static tdfxMemRange * | |||
AllocTexMem(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 texmemsize) | |||
{ | |||
FxU32 startAddr; | |||
startAddr = FindStartAddr(fxMesa, tmu, texmemsize); | |||
if (startAddr == BAD_ADDRESS) { | |||
_mesa_problem(fxMesa->glCtx, "%s returned NULL! tmu=%d texmemsize=%d", | |||
__FUNCTION__, (int) tmu, (int) texmemsize); | |||
return NULL; | |||
} | |||
else { | |||
tdfxMemRange *range; | |||
range = NewRangeNode(fxMesa, startAddr, startAddr + texmemsize); | |||
return range; | |||
} | |||
} | |||
/* | |||
* Download (copy) the given texture data (all mipmap levels) into the | |||
* Voodoo's texture memory. | |||
* The texture memory must have already been allocated. | |||
*/ | |||
void | |||
tdfxTMDownloadTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) | |||
{ | |||
tdfxTexInfo *ti; | |||
GLint l; | |||
FxU32 targetTMU; | |||
assert(tObj); | |||
ti = TDFX_TEXTURE_DATA(tObj); | |||
assert(ti); | |||
targetTMU = ti->whichTMU; | |||
switch (targetTMU) { | |||
case TDFX_TMU0: | |||
case TDFX_TMU1: | |||
if (ti->tm[targetTMU]) { | |||
for (l = ti->minLevel; l <= ti->maxLevel | |||
&& tObj->Image[l]->Data; l++) { | |||
GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; | |||
fxMesa->Glide.grTexDownloadMipMapLevel(targetTMU, | |||
ti->tm[targetTMU]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_BOTH, | |||
tObj->Image[l]->Data); | |||
} | |||
} | |||
break; | |||
case TDFX_TMU_SPLIT: | |||
if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) { | |||
for (l = ti->minLevel; l <= ti->maxLevel | |||
&& tObj->Image[l]->Data; l++) { | |||
GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; | |||
fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, | |||
ti->tm[TDFX_TMU0]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_ODD, | |||
tObj->Image[l]->Data); | |||
fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, | |||
ti->tm[TDFX_TMU1]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_EVEN, | |||
tObj->Image[l]->Data); | |||
} | |||
} | |||
break; | |||
case TDFX_TMU_BOTH: | |||
if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) { | |||
for (l = ti->minLevel; l <= ti->maxLevel | |||
&& tObj->Image[l]->Data; l++) { | |||
GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; | |||
fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, | |||
ti->tm[TDFX_TMU0]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_BOTH, | |||
tObj->Image[l]->Data); | |||
fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, | |||
ti->tm[TDFX_TMU1]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_BOTH, | |||
tObj->Image[l]->Data); | |||
} | |||
} | |||
break; | |||
default: | |||
_mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)targetTMU); | |||
return; | |||
} | |||
} | |||
void | |||
tdfxTMReloadMipMapLevel(GLcontext *ctx, struct gl_texture_object *tObj, | |||
GLint level) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); | |||
GrLOD_t glideLod; | |||
FxU32 tmu; | |||
tmu = ti->whichTMU; | |||
glideLod = ti->info.largeLodLog2 - level + tObj->BaseLevel; | |||
ASSERT(ti->isInTM); | |||
LOCK_HARDWARE(fxMesa); | |||
switch (tmu) { | |||
case TDFX_TMU0: | |||
case TDFX_TMU1: | |||
fxMesa->Glide.grTexDownloadMipMapLevel(tmu, | |||
ti->tm[tmu]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_BOTH, | |||
tObj->Image[level]->Data); | |||
break; | |||
case TDFX_TMU_SPLIT: | |||
fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, | |||
ti->tm[GR_TMU0]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_ODD, | |||
tObj->Image[level]->Data); | |||
fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, | |||
ti->tm[GR_TMU1]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_EVEN, | |||
tObj->Image[level]->Data); | |||
break; | |||
case TDFX_TMU_BOTH: | |||
fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, | |||
ti->tm[GR_TMU0]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_BOTH, | |||
tObj->Image[level]->Data); | |||
fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, | |||
ti->tm[GR_TMU1]->startAddr, | |||
glideLod, | |||
ti->info.largeLodLog2, | |||
ti->info.aspectRatioLog2, | |||
ti->info.format, | |||
GR_MIPMAPLEVELMASK_BOTH, | |||
tObj->Image[level]->Data); | |||
break; | |||
default: | |||
_mesa_problem(ctx, "%s: bad tmu (%d)", __FUNCTION__, (int)tmu); | |||
break; | |||
} | |||
UNLOCK_HARDWARE(fxMesa); | |||
} | |||
/* | |||
* Allocate space for the given texture in texture memory then | |||
* download (copy) it into that space. | |||
*/ | |||
void | |||
tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj, | |||
FxU32 targetTMU ) | |||
{ | |||
tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); | |||
FxU32 texmemsize; | |||
fxMesa->stats.reqTexUpload++; | |||
if (ti->isInTM) { | |||
if (ti->whichTMU == targetTMU) | |||
return; | |||
if (targetTMU == TDFX_TMU_SPLIT || ti->whichTMU == TDFX_TMU_SPLIT) { | |||
tdfxTMMoveOutTM_NoLock(fxMesa, tObj); | |||
} | |||
else { | |||
if (ti->whichTMU == TDFX_TMU_BOTH) | |||
return; | |||
targetTMU = TDFX_TMU_BOTH; | |||
} | |||
} | |||
ti->whichTMU = targetTMU; | |||
switch (targetTMU) { | |||
case TDFX_TMU0: | |||
case TDFX_TMU1: | |||
texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, | |||
&(ti->info)); | |||
ti->tm[targetTMU] = AllocTexMem(fxMesa, targetTMU, texmemsize); | |||
break; | |||
case TDFX_TMU_SPLIT: | |||
texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD, | |||
&(ti->info)); | |||
ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize); | |||
if (ti->tm[TDFX_TMU0]) | |||
fxMesa->stats.memTexUpload += texmemsize; | |||
texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN, | |||
&(ti->info)); | |||
ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); | |||
break; | |||
case TDFX_TMU_BOTH: | |||
texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, | |||
&(ti->info)); | |||
ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize); | |||
if (ti->tm[TDFX_TMU0]) | |||
fxMesa->stats.memTexUpload += texmemsize; | |||
texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, | |||
&(ti->info)); | |||
ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); | |||
break; | |||
default: | |||
_mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)targetTMU); | |||
return; | |||
} | |||
ti->reloadImages = GL_TRUE; | |||
ti->isInTM = GL_TRUE; | |||
fxMesa->stats.texUpload++; | |||
} | |||
/* | |||
* Move the given texture out of hardware texture memory. | |||
* This deallocates the texture's memory space. | |||
*/ | |||
void | |||
tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj ) | |||
{ | |||
struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; | |||
struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; | |||
tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); | |||
if (MESA_VERBOSE & VERBOSE_DRIVER) { | |||
fprintf(stderr, "fxmesa: %s(%p (%d))\n", __FUNCTION__, tObj, tObj->Name); | |||
} | |||
/* | |||
VerifyFreeList(fxMesa, 0); | |||
VerifyFreeList(fxMesa, 1); | |||
*/ | |||
if (!ti || !ti->isInTM) | |||
return; | |||
switch (ti->whichTMU) { | |||
case TDFX_TMU0: | |||
case TDFX_TMU1: | |||
RemoveRange_NoLock(fxMesa, ti->whichTMU, ti->tm[ti->whichTMU]); | |||
break; | |||
case TDFX_TMU_SPLIT: | |||
case TDFX_TMU_BOTH: | |||
assert(!shared->umaTexMemory); | |||
RemoveRange_NoLock(fxMesa, TDFX_TMU0, ti->tm[TDFX_TMU0]); | |||
RemoveRange_NoLock(fxMesa, TDFX_TMU1, ti->tm[TDFX_TMU1]); | |||
break; | |||
default: | |||
_mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)ti->whichTMU); | |||
return; | |||
} | |||
ti->isInTM = GL_FALSE; | |||
ti->tm[0] = NULL; | |||
ti->tm[1] = NULL; | |||
ti->whichTMU = TDFX_TMU_NONE; | |||
/* | |||
VerifyFreeList(fxMesa, 0); | |||
VerifyFreeList(fxMesa, 1); | |||
*/ | |||
} | |||
/* | |||
* Called via glDeleteTexture to delete a texture object. | |||
*/ | |||
void | |||
tdfxTMFreeTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) | |||
{ | |||
tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); | |||
if (ti) { | |||
tdfxTMMoveOutTM(fxMesa, tObj); | |||
FREE(ti); | |||
tObj->DriverData = NULL; | |||
} | |||
/* | |||
VerifyFreeList(fxMesa, 0); | |||
VerifyFreeList(fxMesa, 1); | |||
*/ | |||
} | |||
/* | |||
* After a context switch this function will be called to restore | |||
* texture memory for the new context. | |||
*/ | |||
void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa ) | |||
{ | |||
GLcontext *ctx = fxMesa->glCtx; | |||
struct gl_texture_object *tObj; | |||
int i; | |||
for ( tObj = ctx->Shared->TexObjectList ; tObj ; tObj = tObj->Next ) { | |||
tdfxTexInfo *ti = TDFX_TEXTURE_DATA( tObj ); | |||
if ( ti && ti->isInTM ) { | |||
for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) { | |||
if ( ctx->Texture.Unit[i]._Current == tObj ) { | |||
tdfxTMDownloadTexture( fxMesa, tObj ); | |||
break; | |||
} | |||
} | |||
if ( i == MAX_TEXTURE_UNITS ) { | |||
tdfxTMMoveOutTM_NoLock( fxMesa, tObj ); | |||
} | |||
} | |||
} | |||
/* | |||
VerifyFreeList(fxMesa, 0); | |||
VerifyFreeList(fxMesa, 1); | |||
*/ | |||
} |
@@ -0,0 +1,84 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h,v 1.2 2002/02/22 21:45:04 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_TEXMAN_H__ | |||
#define __TDFX_TEXMAN_H__ | |||
#include "tdfx_lock.h" | |||
extern void tdfxTMInit( tdfxContextPtr fxMesa ); | |||
extern void tdfxTMClose( tdfxContextPtr fxMesa ); | |||
extern void tdfxTMDownloadTexture(tdfxContextPtr fxMesa, | |||
struct gl_texture_object *tObj); | |||
extern void tdfxTMReloadMipMapLevel( GLcontext *ctx, | |||
struct gl_texture_object *tObj, | |||
GLint level ); | |||
extern void tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, | |||
struct gl_texture_object *tObj, | |||
FxU32 targetTMU ); | |||
extern void tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, | |||
struct gl_texture_object *tObj ); | |||
extern void tdfxTMFreeTexture( tdfxContextPtr fxMesa, | |||
struct gl_texture_object *tObj ); | |||
extern void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa ); | |||
#define tdfxTMMoveInTM( fxMesa, tObj, targetTMU ) \ | |||
do { \ | |||
LOCK_HARDWARE( fxMesa ); \ | |||
tdfxTMMoveInTM_NoLock( fxMesa, tObj, targetTMU ); \ | |||
UNLOCK_HARDWARE( fxMesa ); \ | |||
} while (0) | |||
#define tdfxTMMoveOutTM( fxMesa, tObj ) \ | |||
do { \ | |||
LOCK_HARDWARE( fxMesa ); \ | |||
tdfxTMMoveOutTM_NoLock( fxMesa, tObj ); \ | |||
UNLOCK_HARDWARE( fxMesa ); \ | |||
} while (0) | |||
#endif |
@@ -0,0 +1,44 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h,v 1.1 2002/02/22 21:45:04 dawes Exp $ */ | |||
/* | |||
* Original rewrite: | |||
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 | |||
* | |||
* Authors: | |||
* Gareth Hughes <gareth@valinux.com> | |||
* Brian Paul <brianp@valinux.com> | |||
* | |||
*/ | |||
#ifndef __TDFX_TEXSTATE_H__ | |||
#define __TDFX_TEXSTATE_H__ | |||
extern void tdfxUpdateTextureState( GLcontext *ctx ); | |||
extern void tdfxUpdateTextureBinding( GLcontext *ctx ); | |||
#endif |
@@ -0,0 +1,42 @@ | |||
/* -*- mode: c; c-basic-offset: 3 -*- | |||
* | |||
* Copyright 2000 VA Linux Systems Inc., Fremont, California. | |||
* | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) 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 | |||
* VA LINUX SYSTEMS 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. | |||
*/ | |||
/* | |||
* Authors: | |||
* Keith Whitwell <keith@tungstengraphics.com> | |||
* | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h,v 1.5 2002/10/30 12:52:01 alanh Exp $ */ | |||
#ifndef TDFX_TRIS_INC | |||
#define TDFX_TRIS_INC | |||
#include "mtypes.h" | |||
extern void tdfxDDInitTriFuncs( GLcontext *ctx ); | |||
#endif |
@@ -0,0 +1,365 @@ | |||
/* | |||
* GLX Hardware Device Driver for Intel i810 | |||
* Copyright (C) 1999 Keith Whitwell | |||
* | |||
* 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 | |||
* KEITH WHITWELL, 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. | |||
* | |||
* | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c,v 1.3 2002/10/30 12:52:01 alanh Exp $ */ | |||
#include "glheader.h" | |||
#include "mtypes.h" | |||
#include "imports.h" | |||
#include "macros.h" | |||
#include "colormac.h" | |||
#include "math/m_translate.h" | |||
#include "swrast_setup/swrast_setup.h" | |||
#include "tdfx_context.h" | |||
#include "tdfx_vb.h" | |||
#include "tdfx_tris.h" | |||
#include "tdfx_state.h" | |||
#include "tdfx_render.h" | |||
static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); | |||
GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; | |||
GLuint shift = fxMesa->vertex_stride_shift; | |||
tdfxVertex *dst = (tdfxVertex *)(tdfxverts + (edst << shift)); | |||
tdfxVertex *src = (tdfxVertex *)(tdfxverts + (esrc << shift)); | |||
dst->ui[4] = src->ui[4]; | |||
} | |||
static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); | |||
GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; | |||
GLuint shift = fxMesa->vertex_stride_shift; | |||
tdfxVertex *dst = (tdfxVertex *)(tdfxverts + (edst << shift)); | |||
tdfxVertex *src = (tdfxVertex *)(tdfxverts + (esrc << shift)); | |||
dst->ui[3] = src->ui[3]; | |||
} | |||
typedef void (*emit_func)( GLcontext *, GLuint, GLuint, void *, GLuint ); | |||
static struct { | |||
emit_func emit; | |||
interp_func interp; | |||
copy_pv_func copy_pv; | |||
GLboolean (*check_tex_sizes)( GLcontext *ctx ); | |||
GLuint vertex_size; | |||
GLuint vertex_stride_shift; | |||
GLuint vertex_format; | |||
} setup_tab[TDFX_MAX_SETUP]; | |||
static void import_float_colors( GLcontext *ctx ) | |||
{ | |||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | |||
struct gl_client_array *from = VB->ColorPtr[0]; | |||
struct gl_client_array *to = &TDFX_CONTEXT(ctx)->UbyteColor; | |||
GLuint count = VB->Count; | |||
if (!to->Ptr) { | |||
to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLubyte), 32 ); | |||
to->Type = GL_UNSIGNED_BYTE; | |||
} | |||
/* No need to transform the same value 3000 times. | |||
*/ | |||
if (!from->StrideB) { | |||
to->StrideB = 0; | |||
count = 1; | |||
} | |||
else | |||
to->StrideB = 4 * sizeof(GLubyte); | |||
_math_trans_4ub( (GLubyte (*)[4]) to->Ptr, | |||
from->Ptr, | |||
from->StrideB, | |||
from->Type, | |||
from->Size, | |||
0, | |||
count); | |||
VB->ColorPtr[0] = to; | |||
} | |||
#define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx]) | |||
static void interp_extras( GLcontext *ctx, | |||
GLfloat t, | |||
GLuint dst, GLuint out, GLuint in, | |||
GLboolean force_boundary ) | |||
{ | |||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | |||
/*fprintf(stderr, "%s\n", __FUNCTION__);*/ | |||
if (VB->ColorPtr[1]) { | |||
INTERP_4CHAN( t, | |||
GET_COLOR(VB->ColorPtr[1], dst), | |||
GET_COLOR(VB->ColorPtr[1], out), | |||
GET_COLOR(VB->ColorPtr[1], in) ); | |||
} | |||
if (VB->EdgeFlag) { | |||
VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; | |||
} | |||
setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].interp(ctx, t, dst, out, in, | |||
force_boundary); | |||
} | |||
static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) | |||
{ | |||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | |||
if (VB->ColorPtr[1]) { | |||
COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst), | |||
GET_COLOR(VB->ColorPtr[1], src) ); | |||
} | |||
setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].copy_pv(ctx, dst, src); | |||
} | |||
#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT) | |||
#define TAG(x) x##_wg | |||
#include "tdfx_vbtmp.h" | |||
/* Special for tdfx: fog requires w | |||
*/ | |||
#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT) | |||
#define TAG(x) x##_wg_fog | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT) | |||
#define TAG(x) x##_wgt0 | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT) | |||
#define TAG(x) x##_wgt0t1 | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT) | |||
#define TAG(x) x##_wgpt0 | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\ | |||
TDFX_PTEX_BIT) | |||
#define TAG(x) x##_wgpt0t1 | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_RGBA_BIT) | |||
#define TAG(x) x##_g | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_TEX0_BIT) | |||
#define TAG(x) x##_t0 | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_TEX0_BIT|TDFX_TEX1_BIT) | |||
#define TAG(x) x##_t0t1 | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT) | |||
#define TAG(x) x##_gt0 | |||
#include "tdfx_vbtmp.h" | |||
#define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT) | |||
#define TAG(x) x##_gt0t1 | |||
#include "tdfx_vbtmp.h" | |||
static void init_setup_tab( void ) | |||
{ | |||
init_wg(); | |||
init_wg_fog(); | |||
init_wgt0(); | |||
init_wgt0t1(); | |||
init_wgpt0(); | |||
init_wgpt0t1(); | |||
init_g(); | |||
init_t0(); | |||
init_t0t1(); | |||
init_gt0(); | |||
init_gt0t1(); | |||
} | |||
void tdfxPrintSetupFlags(char *msg, GLuint flags ) | |||
{ | |||
fprintf(stderr, "%s(%x): %s%s%s%s%s\n", | |||
msg, | |||
(int)flags, | |||
(flags & TDFX_XYZ_BIT) ? " xyz," : "", | |||
(flags & TDFX_W_BIT) ? " w," : "", | |||
(flags & TDFX_RGBA_BIT) ? " rgba," : "", | |||
(flags & TDFX_TEX0_BIT) ? " tex-0," : "", | |||
(flags & TDFX_TEX1_BIT) ? " tex-1," : ""); | |||
} | |||
void tdfxCheckTexSizes( GLcontext *ctx ) | |||
{ | |||
TNLcontext *tnl = TNL_CONTEXT(ctx); | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); | |||
if (!setup_tab[fxMesa->SetupIndex].check_tex_sizes(ctx)) { | |||
GLuint ind = fxMesa->SetupIndex |= (TDFX_PTEX_BIT|TDFX_RGBA_BIT); | |||
/* Tdfx handles projective textures nicely; just have to change | |||
* up to the new vertex format. | |||
*/ | |||
if (setup_tab[ind].vertex_format != fxMesa->vertexFormat) { | |||
FLUSH_BATCH(fxMesa); | |||
fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT; | |||
fxMesa->vertexFormat = setup_tab[ind].vertex_format; | |||
fxMesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; | |||
/* This is required as we have just changed the vertex | |||
* format, so the interp and copy routines must also change. | |||
* In the unfilled and twosided cases we are using the | |||
* swrast_setup ones anyway, so leave them in place. | |||
*/ | |||
if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { | |||
tnl->Driver.Render.Interp = setup_tab[fxMesa->SetupIndex].interp; | |||
tnl->Driver.Render.CopyPV = setup_tab[fxMesa->SetupIndex].copy_pv; | |||
} | |||
} | |||
} | |||
} | |||
void tdfxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, | |||
GLuint newinputs ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); | |||
GLubyte *v = (fxMesa->verts + (start<<fxMesa->vertex_stride_shift)); | |||
GLuint stride = 1<<fxMesa->vertex_stride_shift; | |||
newinputs |= fxMesa->SetupNewInputs; | |||
fxMesa->SetupNewInputs = 0; | |||
if (!newinputs) | |||
return; | |||
if (newinputs & VERT_BIT_CLIP) { | |||
setup_tab[fxMesa->SetupIndex].emit( ctx, start, count, v, stride ); | |||
} else { | |||
GLuint ind = 0; | |||
if (newinputs & VERT_BIT_COLOR0) | |||
ind |= TDFX_RGBA_BIT; | |||
if (newinputs & VERT_BIT_TEX0) | |||
ind |= TDFX_TEX0_BIT; | |||
if (newinputs & VERT_BIT_TEX1) | |||
ind |= TDFX_TEX0_BIT|TDFX_TEX1_BIT; | |||
if (fxMesa->SetupIndex & TDFX_PTEX_BIT) | |||
ind = ~0; | |||
ind &= fxMesa->SetupIndex; | |||
if (ind) { | |||
setup_tab[ind].emit( ctx, start, count, v, stride ); | |||
} | |||
} | |||
} | |||
void tdfxChooseVertexState( GLcontext *ctx ) | |||
{ | |||
TNLcontext *tnl = TNL_CONTEXT(ctx); | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); | |||
GLuint ind = TDFX_XYZ_BIT|TDFX_RGBA_BIT; | |||
if (ctx->Texture._EnabledUnits & 0x2) | |||
/* unit 1 enabled */ | |||
ind |= TDFX_W_BIT|TDFX_TEX1_BIT|TDFX_TEX0_BIT; | |||
else if (ctx->Texture._EnabledUnits & 0x1) | |||
/* unit 0 enabled */ | |||
ind |= TDFX_W_BIT|TDFX_TEX0_BIT; | |||
else if (ctx->Fog.Enabled) | |||
ind |= TDFX_W_BIT; | |||
fxMesa->SetupIndex = ind; | |||
if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { | |||
tnl->Driver.Render.Interp = interp_extras; | |||
tnl->Driver.Render.CopyPV = copy_pv_extras; | |||
} else { | |||
tnl->Driver.Render.Interp = setup_tab[ind].interp; | |||
tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; | |||
} | |||
if (setup_tab[ind].vertex_format != fxMesa->vertexFormat) { | |||
FLUSH_BATCH(fxMesa); | |||
fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT; | |||
fxMesa->vertexFormat = setup_tab[ind].vertex_format; | |||
fxMesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; | |||
} | |||
} | |||
void tdfxInitVB( GLcontext *ctx ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
GLuint size = TNL_CONTEXT(ctx)->vb.Size; | |||
static int firsttime = 1; | |||
if (firsttime) { | |||
init_setup_tab(); | |||
firsttime = 0; | |||
} | |||
fxMesa->verts = (GLubyte *)ALIGN_MALLOC(size * sizeof(tdfxVertex), 32); | |||
fxMesa->vertexFormat = setup_tab[TDFX_XYZ_BIT|TDFX_RGBA_BIT].vertex_format; | |||
fxMesa->vertex_stride_shift = setup_tab[(TDFX_XYZ_BIT| | |||
TDFX_RGBA_BIT)].vertex_stride_shift; | |||
fxMesa->SetupIndex = TDFX_XYZ_BIT|TDFX_RGBA_BIT; | |||
} | |||
void tdfxFreeVB( GLcontext *ctx ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
if (fxMesa->verts) { | |||
ALIGN_FREE(fxMesa->verts); | |||
fxMesa->verts = 0; | |||
} | |||
if (fxMesa->UbyteColor.Ptr) { | |||
ALIGN_FREE(fxMesa->UbyteColor.Ptr); | |||
fxMesa->UbyteColor.Ptr = 0; | |||
} | |||
} |
@@ -0,0 +1,68 @@ | |||
/* | |||
* GLX Hardware Device Driver for Intel tdfx | |||
* Copyright (C) 1999 Keith Whitwell | |||
* | |||
* 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 | |||
* KEITH WHITWELL, 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. | |||
* | |||
* | |||
*/ | |||
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.h,v 1.2 2002/02/22 21:45:04 dawes Exp $ */ | |||
#ifndef TDFXVB_INC | |||
#define TDFXVB_INC | |||
#include "mtypes.h" | |||
#include "tnl/tnl.h" | |||
#include "tnl/t_context.h" | |||
#include "math/m_xform.h" | |||
#define TDFX_XYZ_BIT 0x1 | |||
#define TDFX_W_BIT 0x2 | |||
#define TDFX_RGBA_BIT 0x4 | |||
#define TDFX_TEX1_BIT 0x8 | |||
#define TDFX_TEX0_BIT 0x10 | |||
#define TDFX_PTEX_BIT 0x20 | |||
#define TDFX_MAX_SETUP 0x40 | |||
#define _TDFX_NEW_RASTERSETUP (_NEW_TEXTURE | \ | |||
_DD_NEW_SEPARATE_SPECULAR | \ | |||
_DD_NEW_TRI_UNFILLED | \ | |||
_DD_NEW_TRI_LIGHT_TWOSIDE | \ | |||
_NEW_FOG) | |||
extern void tdfxValidateBuildProjVerts(GLcontext *ctx, | |||
GLuint start, GLuint count, | |||
GLuint newinputs ); | |||
extern void tdfxPrintSetupFlags(char *msg, GLuint flags ); | |||
extern void tdfxInitVB( GLcontext *ctx ); | |||
extern void tdfxFreeVB( GLcontext *ctx ); | |||
extern void tdfxCheckTexSizes( GLcontext *ctx ); | |||
extern void tdfxChooseVertexState( GLcontext *ctx ); | |||
extern void tdfxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, | |||
GLuint newinputs ); | |||
#endif |
@@ -0,0 +1,442 @@ | |||
#if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) | |||
static void TAG(emit)( GLcontext *ctx, | |||
GLuint start, GLuint end, | |||
void *dest, | |||
GLuint stride ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | |||
GLfloat (*tc0)[4], (*tc1)[4]; | |||
GLubyte (*col)[4]; | |||
GLuint tc0_stride, tc1_stride, col_stride; | |||
GLuint tc0_size, tc1_size; | |||
GLfloat (*proj)[4] = VB->NdcPtr->data; | |||
GLuint proj_stride = VB->NdcPtr->stride; | |||
tdfxVertex *v = (tdfxVertex *)dest; | |||
GLfloat u0scale,v0scale,u1scale,v1scale; | |||
const GLubyte *mask = VB->ClipMask; | |||
const GLfloat *s = fxMesa->hw_viewport; | |||
int i; | |||
/* fprintf(stderr, "%s\n", __FUNCTION__); */ | |||
ASSERT(stride > 16); | |||
if (IND & TDFX_TEX0_BIT) { | |||
tc0_stride = VB->TexCoordPtr[0]->stride; | |||
tc0 = VB->TexCoordPtr[0]->data; | |||
u0scale = fxMesa->sScale0; | |||
v0scale = fxMesa->tScale0; | |||
if (IND & TDFX_PTEX_BIT) | |||
tc0_size = VB->TexCoordPtr[0]->size; | |||
} | |||
if (IND & TDFX_TEX1_BIT) { | |||
tc1 = VB->TexCoordPtr[1]->data; | |||
tc1_stride = VB->TexCoordPtr[1]->stride; | |||
u1scale = fxMesa->sScale1; | |||
v1scale = fxMesa->tScale1; | |||
if (IND & TDFX_PTEX_BIT) | |||
tc1_size = VB->TexCoordPtr[1]->size; | |||
} | |||
if (IND & TDFX_RGBA_BIT) { | |||
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) | |||
import_float_colors( ctx ); | |||
col = VB->ColorPtr[0]->Ptr; | |||
col_stride = VB->ColorPtr[0]->StrideB; | |||
} | |||
if (VB->importable_data) { | |||
/* May have nonstandard strides: | |||
*/ | |||
if (start) { | |||
proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride); | |||
if (IND & TDFX_TEX0_BIT) | |||
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride); | |||
if (IND & TDFX_TEX1_BIT) | |||
tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride); | |||
if (IND & TDFX_RGBA_BIT) | |||
STRIDE_4UB(col, start * col_stride); | |||
} | |||
for (i=start; i < end; i++, v = (tdfxVertex *)((GLubyte *)v + stride)) { | |||
if (IND & TDFX_XYZ_BIT) { | |||
if (mask[i] == 0) { | |||
/* unclipped */ | |||
v->v.x = s[0] * proj[0][0] + s[12]; | |||
v->v.y = s[5] * proj[0][1] + s[13]; | |||
v->v.z = s[10] * proj[0][2] + s[14]; | |||
v->v.rhw = proj[0][3]; | |||
} else { | |||
/* clipped */ | |||
v->v.rhw = 1.0; | |||
} | |||
proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride); | |||
} | |||
if (IND & TDFX_RGBA_BIT) { | |||
#if 0 | |||
*(GLuint *)&v->v.color = *(GLuint *)col; | |||
#else | |||
GLubyte *b = (GLubyte *) &v->v.color; | |||
b[0] = col[0][2]; | |||
b[1] = col[0][1]; | |||
b[2] = col[0][0]; | |||
b[3] = col[0][3]; | |||
#endif | |||
STRIDE_4UB(col, col_stride); | |||
} | |||
if (IND & TDFX_TEX0_BIT) { | |||
GLfloat w = v->v.rhw; | |||
if (IND & TDFX_PTEX_BIT) { | |||
v->pv.tu0 = tc0[0][0] * u0scale * w; | |||
v->pv.tv0 = tc0[0][1] * v0scale * w; | |||
v->pv.tq0 = w; | |||
if (tc0_size == 4) | |||
v->pv.tq0 = tc0[0][3] * w; | |||
} | |||
else { | |||
v->v.tu0 = tc0[0][0] * u0scale * w; | |||
v->v.tv0 = tc0[0][1] * v0scale * w; | |||
} | |||
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride); | |||
} | |||
if (IND & TDFX_TEX1_BIT) { | |||
GLfloat w = v->v.rhw; | |||
if (IND & TDFX_PTEX_BIT) { | |||
v->pv.tu1 = tc1[0][0] * u1scale * w; | |||
v->pv.tv1 = tc1[0][1] * v1scale * w; | |||
v->pv.tq1 = w; | |||
if (tc1_size == 4) | |||
v->pv.tq1 = tc1[0][3] * w; | |||
} | |||
else { | |||
v->v.tu1 = tc1[0][0] * u1scale * w; | |||
v->v.tv1 = tc1[0][1] * v1scale * w; | |||
} | |||
tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride); | |||
} | |||
} | |||
} | |||
else { | |||
for (i=start; i < end; i++, v = (tdfxVertex *)((GLubyte *)v + stride)) { | |||
if (IND & TDFX_XYZ_BIT) { | |||
if (mask[i] == 0) { | |||
v->v.x = s[0] * proj[i][0] + s[12]; | |||
v->v.y = s[5] * proj[i][1] + s[13]; | |||
v->v.z = s[10] * proj[i][2] + s[14]; | |||
v->v.rhw = proj[i][3]; | |||
} else { | |||
v->v.rhw = 1.0; | |||
} | |||
} | |||
if (IND & TDFX_RGBA_BIT) { | |||
#if 0 | |||
*(GLuint *)&v->v.color = *(GLuint *)&col[i]; | |||
#else | |||
GLubyte *b = (GLubyte *) &v->v.color; | |||
b[0] = col[i][2]; | |||
b[1] = col[i][1]; | |||
b[2] = col[i][0]; | |||
b[3] = col[i][3]; | |||
#endif | |||
} | |||
if (IND & TDFX_TEX0_BIT) { | |||
GLfloat w = v->v.rhw; | |||
if (IND & TDFX_PTEX_BIT) { | |||
v->pv.tu0 = tc0[i][0] * u0scale * w; | |||
v->pv.tv0 = tc0[i][1] * v0scale * w; | |||
v->pv.tq0 = w; | |||
if (tc0_size == 4) | |||
v->pv.tq0 = tc0[i][3] * w; | |||
} | |||
else { | |||
v->v.tu0 = tc0[i][0] * u0scale * w; | |||
v->v.tv0 = tc0[i][1] * v0scale * w; | |||
} | |||
} | |||
if (IND & TDFX_TEX1_BIT) { | |||
GLfloat w = v->v.rhw; | |||
if (IND & TDFX_PTEX_BIT) { | |||
v->pv.tu1 = tc1[i][0] * u1scale * w; | |||
v->pv.tv1 = tc1[i][1] * v1scale * w; | |||
v->pv.tq1 = w; | |||
if (tc1_size == 4) | |||
v->pv.tq1 = tc1[i][3] * w; | |||
} | |||
else { | |||
v->v.tu1 = tc1[i][0] * u1scale * w; | |||
v->v.tv1 = tc1[i][1] * v1scale * w; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
#else | |||
#if (IND & TDFX_XYZ_BIT) | |||
static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, | |||
void *dest, GLuint stride ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | |||
GLubyte (*col)[4]; | |||
GLuint col_stride; | |||
GLfloat (*proj)[4] = VB->NdcPtr->data; | |||
GLuint proj_stride = VB->NdcPtr->stride; | |||
GLfloat *v = (GLfloat *)dest; | |||
const GLubyte *mask = VB->ClipMask; | |||
const GLfloat *s = fxMesa->hw_viewport; | |||
int i; | |||
/* fprintf(stderr, "%s %d..%d dest %p stride %d\n", __FUNCTION__, */ | |||
/* start, end, dest, stride); */ | |||
ASSERT(fxMesa->SetupIndex == (TDFX_XYZ_BIT|TDFX_RGBA_BIT)); | |||
ASSERT(stride == 16); | |||
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) | |||
import_float_colors( ctx ); | |||
col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr; | |||
col_stride = VB->ColorPtr[0]->StrideB; | |||
ASSERT(VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE); | |||
/* Pack what's left into a 4-dword vertex. Color is in a different | |||
* place, and there is no 'w' coordinate. | |||
*/ | |||
if (VB->importable_data) { | |||
if (start) { | |||
proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride); | |||
STRIDE_4UB(col, start * col_stride); | |||
} | |||
for (i=start; i < end; i++, v+=4) { | |||
if (mask[i] == 0) { | |||
v[0] = s[0] * proj[0][0] + s[12]; | |||
v[1] = s[5] * proj[0][1] + s[13]; | |||
v[2] = s[10] * proj[0][2] + s[14]; | |||
} | |||
proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride); | |||
{ | |||
GLubyte *b = (GLubyte *)&v[3]; | |||
b[0] = col[0][2]; | |||
b[1] = col[0][1]; | |||
b[2] = col[0][0]; | |||
b[3] = col[0][3]; | |||
STRIDE_4UB(col, col_stride); | |||
} | |||
} | |||
} | |||
else { | |||
for (i=start; i < end; i++, v+=4) { | |||
if (mask[i] == 0) { | |||
v[0] = s[0] * proj[i][0] + s[12]; | |||
v[1] = s[5] * proj[i][1] + s[13]; | |||
v[2] = s[10] * proj[i][2] + s[14]; | |||
} | |||
{ | |||
GLubyte *b = (GLubyte *)&v[3]; | |||
b[0] = col[i][2]; | |||
b[1] = col[i][1]; | |||
b[2] = col[i][0]; | |||
b[3] = col[i][3]; | |||
} | |||
} | |||
} | |||
} | |||
#else | |||
static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, | |||
void *dest, GLuint stride ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); | |||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | |||
GLubyte (*col)[4]; | |||
GLuint col_stride; | |||
GLfloat *v = (GLfloat *)dest; | |||
int i; | |||
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) | |||
import_float_colors( ctx ); | |||
col = VB->ColorPtr[0]->Ptr; | |||
col_stride = VB->ColorPtr[0]->StrideB; | |||
if (start) | |||
STRIDE_4UB(col, col_stride * start); | |||
/* Need to figure out where color is: | |||
*/ | |||
if (fxMesa->SetupIndex & TDFX_W_BIT ) | |||
v += 4; | |||
else | |||
v += 3; | |||
for (i=start; i < end; i++, STRIDE_F(v, stride)) { | |||
GLubyte *b = (GLubyte *)v; | |||
b[0] = col[0][2]; | |||
b[1] = col[0][1]; | |||
b[2] = col[0][0]; | |||
b[3] = col[0][3]; | |||
STRIDE_4UB( col, col_stride ); | |||
} | |||
} | |||
#endif | |||
#endif | |||
#if (IND & TDFX_XYZ_BIT) && (IND & TDFX_RGBA_BIT) | |||
static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) | |||
{ | |||
/* fprintf(stderr, "%s\n", __FUNCTION__); */ | |||
if (IND & TDFX_PTEX_BIT) | |||
return GL_TRUE; | |||
if (IND & TDFX_TEX0_BIT) { | |||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | |||
if (IND & TDFX_TEX1_BIT) { | |||
if (VB->TexCoordPtr[0] == 0) | |||
VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; | |||
if (VB->TexCoordPtr[1]->size == 4) | |||
return GL_FALSE; | |||
} | |||
if (VB->TexCoordPtr[0]->size == 4) | |||
return GL_FALSE; | |||
} | |||
return GL_TRUE; | |||
} | |||
static void TAG(interp)( GLcontext *ctx, | |||
GLfloat t, | |||
GLuint edst, GLuint eout, GLuint ein, | |||
GLboolean force_boundary ) | |||
{ | |||
tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); | |||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; | |||
const GLuint shift = fxMesa->vertex_stride_shift; | |||
const GLfloat *dstclip = VB->ClipPtr->data[edst]; | |||
const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]); | |||
const GLfloat *s = fxMesa->hw_viewport; | |||
GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; | |||
tdfxVertex *dst = (tdfxVertex *) (tdfxverts + (edst << shift)); | |||
const tdfxVertex *out = (const tdfxVertex *) (tdfxverts + (eout << shift)); | |||
const tdfxVertex *in = (const tdfxVertex *) (tdfxverts + (ein << shift)); | |||
const GLfloat wout = 1.0F / out->v.rhw; | |||
const GLfloat win = 1.0F / in->v.rhw; | |||
dst->v.x = s[0] * dstclip[0] * oow + s[12]; | |||
dst->v.y = s[5] * dstclip[1] * oow + s[13]; | |||
dst->v.z = s[10] * dstclip[2] * oow + s[14]; | |||
if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) { | |||
dst->v.rhw = oow; | |||
INTERP_UB( t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0] ); | |||
INTERP_UB( t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1] ); | |||
INTERP_UB( t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2] ); | |||
INTERP_UB( t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3] ); | |||
if (IND & TDFX_TEX0_BIT) { | |||
if (IND & TDFX_PTEX_BIT) { | |||
INTERP_F( t, dst->pv.tu0, out->pv.tu0 * wout, in->pv.tu0 * win ); | |||
INTERP_F( t, dst->pv.tv0, out->pv.tv0 * wout, in->pv.tv0 * win ); | |||
INTERP_F( t, dst->pv.tq0, out->pv.tq0 * wout, in->pv.tq0 * win ); | |||
dst->pv.tu0 *= oow; | |||
dst->pv.tv0 *= oow; | |||
dst->pv.tq0 *= oow; | |||
} else { | |||
INTERP_F( t, dst->v.tu0, out->v.tu0 * wout, in->v.tu0 * win ); | |||
INTERP_F( t, dst->v.tv0, out->v.tv0 * wout, in->v.tv0 * win ); | |||
dst->v.tu0 *= oow; | |||
dst->v.tv0 *= oow; | |||
} | |||
} | |||
if (IND & TDFX_TEX1_BIT) { | |||
if (IND & TDFX_PTEX_BIT) { | |||
INTERP_F( t, dst->pv.tu1, out->pv.tu1 * wout, in->pv.tu1 * win ); | |||
INTERP_F( t, dst->pv.tv1, out->pv.tv1 * wout, in->pv.tv1 * win ); | |||
INTERP_F( t, dst->pv.tq1, out->pv.tq1 * wout, in->pv.tq1 * win ); | |||
dst->pv.tu1 *= oow; | |||
dst->pv.tv1 *= oow; | |||
dst->pv.tq1 *= oow; | |||
} else { | |||
INTERP_F( t, dst->v.tu1, out->v.tu1 * wout, in->v.tu1 * win ); | |||
INTERP_F( t, dst->v.tv1, out->v.tv1 * wout, in->v.tv1 * win ); | |||
dst->v.tu1 *= oow; | |||
dst->v.tv1 *= oow; | |||
} | |||
} | |||
} else { | |||
/* 4-dword vertex. Color is in v[3] and there is no oow coordinate. | |||
*/ | |||
INTERP_UB( t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0] ); | |||
INTERP_UB( t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1] ); | |||
INTERP_UB( t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2] ); | |||
INTERP_UB( t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3] ); | |||
} | |||
} | |||
#endif | |||
static void TAG(init)( void ) | |||
{ | |||
/* fprintf(stderr, "%s\n", __FUNCTION__); */ | |||
setup_tab[IND].emit = TAG(emit); | |||
#if ((IND & TDFX_XYZ_BIT) && (IND & TDFX_RGBA_BIT)) | |||
setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes); | |||
setup_tab[IND].interp = TAG(interp); | |||
if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) | |||
setup_tab[IND].copy_pv = copy_pv_rgba4; | |||
else | |||
setup_tab[IND].copy_pv = copy_pv_rgba3; | |||
if (IND & TDFX_TEX1_BIT) { | |||
if (IND & TDFX_PTEX_BIT) { | |||
setup_tab[IND].vertex_format = TDFX_LAYOUT_PROJECT; | |||
setup_tab[IND].vertex_size = 12; | |||
setup_tab[IND].vertex_stride_shift = 6; | |||
} | |||
else { | |||
setup_tab[IND].vertex_format = TDFX_LAYOUT_MULTI; | |||
setup_tab[IND].vertex_size = 10; | |||
setup_tab[IND].vertex_stride_shift = 6; | |||
} | |||
} | |||
else if (IND & TDFX_TEX0_BIT) { | |||
if (IND & TDFX_PTEX_BIT) { | |||
setup_tab[IND].vertex_format = TDFX_LAYOUT_PROJECT; | |||
setup_tab[IND].vertex_size = 12; | |||
setup_tab[IND].vertex_stride_shift = 6; | |||
} else { | |||
setup_tab[IND].vertex_format = TDFX_LAYOUT_SINGLE; | |||
setup_tab[IND].vertex_size = 8; | |||
setup_tab[IND].vertex_stride_shift = 5; | |||
} | |||
} | |||
else if (IND & TDFX_W_BIT) { | |||
setup_tab[IND].vertex_format = TDFX_LAYOUT_NOTEX; | |||
setup_tab[IND].vertex_size = 6; | |||
setup_tab[IND].vertex_stride_shift = 5; | |||
} else { | |||
setup_tab[IND].vertex_format = TDFX_LAYOUT_TINY; | |||
setup_tab[IND].vertex_size = 4; | |||
setup_tab[IND].vertex_stride_shift = 4; | |||
} | |||
#endif | |||
} | |||
#undef IND | |||
#undef TAG |