made fxMesaCurrentCtx static
[mesa.git] / src / mesa / drivers / glide / fxapi.c
1 /* -*- mode: C; tab-width:8; -*- */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
28 * terms stated above.
29 *
30 * Thank you for your contribution, David!
31 *
32 * Please make note of the above copyright/license statement. If you
33 * contributed code or bug fixes to this code under the previous (GNU
34 * Library) license and object to the new license, your code will be
35 * removed at your request. Please see the Mesa docs/COPYRIGHT file
36 * for more information.
37 *
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
41 *
42 * See fxapi.h for more revision/author details.
43 */
44
45
46 /* fxapi.c - 3Dfx VooDoo/Mesa interface */
47
48
49 /********************************************************************
50 *
51 * Function names:
52 * fxMesa.... (The driver API)
53 * fxDD.... (Mesa device driver functions)
54 * fxTM.... (Texture manager functions)
55 * fxSetup.... (Voodoo units setup functions)
56 * fx.... (Internal driver functions)
57 *
58 * Data type names:
59 * fxMesa.... (Public driver data types)
60 * tfx.... (Private driver data types)
61 *
62 ********************************************************************
63 *
64 * V0.30 - David Bucciarelli (davibu@tin.it) Humanware s.r.l.
65 * - introduced a new MESA_GLX_FX related behavior
66 * - the Glide fog table was built in a wrong way (using
67 * gu* Glide function). Added the code for building the
68 * table following the OpenGL specs. Thanks to Steve Baker
69 * for highlighting the problem.
70 * - fixed few problems in my and Keith's fxDDClear code
71 * - merged my code with the Keith's one
72 * - used the new BlendFunc Mesa device driver function
73 * - used the new AlphaFunc Mesa device driver function
74 * - used the new Enable Mesa device driver function
75 * - fixed a bug related to fog in the Mesa core. Fog
76 * were applied two times: at vertex level and at fragment
77 * level (thanks to Steve Baker for reporting the problem)
78 * - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE) now works
79 * (thanks to Jiri Pop for reporting the problem)
80 * - the driver works fine with OpenGL Unreal
81 * - fixed a bug in the Mesa core clipping code (related
82 * to the q texture coordinate)
83 * - introduced the support for the q texture coordinate
84 *
85 * Keith Whitwell (keithw@cableinet.co.uk)
86 * - optimized the driver and written all the new code
87 * required by the new Mesa-3.1 device driver API
88 * and by the new Mesa-3.1 core changes
89 * - written the cva support and many other stuff
90 *
91 * Brian Paul (brian_paul@avid.com) Avid Technology
92 * - fixed display list share bug for MESA_GLX_FX = window/fullscreen
93 * - fixed glClear/gl...Mask related problem
94 *
95 * Bert Schoenwaelder (bert@prinz-atm.CS.Uni-Magdeburg.De)
96 * - the driver is now able to sleep when waiting for the completation
97 * of multiple swapbuffer operations instead of wasting
98 * CPU time (NOTE: you must uncomment the lines in the
99 * fxMesaSwapBuffers function in order to enable this option)
100 *
101 * Eero Pajarre (epajarre@koti.tpo.fi)
102 * - enabled the macro FLOAT_COLOR_TO_UBYTE_COLOR under
103 * windows
104 * - written an asm x86 optimized float->integer conversions
105 * for windows
106 *
107 * Theodore Jump (tjump@cais.com)
108 * - fixed a small problem in the __wglMonitor function of the
109 * wgl emulator
110 * - written the in-window-rendering hack support for windows
111 * and Vooodoo1/2 cards
112 *
113 * V0.29 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
114 * - included in Mesa-3.0
115 * - now glGetString(GL_RENDERER) returns more information
116 * about the hardware configuration: "Mesa Glide <version>
117 * <Voodoo_Graphics|Voodoo_Rush|UNKNOWN> <num> CARD/<num> FB/
118 * <num> TM/<num> TMU/<NOSLI|SLI>"
119 * where: <num> CARD is the card used for the current context,
120 * <num> FB is the number of MB for the framebuffer,
121 * <num> TM is the number of MB for the texture memory,
122 * <num> TMU is the number of TMU. You can try to run
123 * Mesa/demos/glinfo in order to have an example of the
124 * output
125 * - fixed a problem of the WGL emulator with the
126 * OpenGL Optimizer 1.1 (thanks to Erwin Coumans for
127 * the bug report)
128 * - fixed some bug in the fxwgl.c code (thanks to
129 * Peter Pettersson for a patch and a bug report)
130 *
131 * Theodore Jump (tjump@cais.com)
132 * - written the SST_DUALHEAD support in the WGL emulator
133 *
134 * Daryll Strauss (daryll@harlot.rb.ca.us)
135 * - fixed the Voodoo Rush support for the in window rendering
136 *
137 * V0.28 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
138 * - the only supported multitexture functions are GL_MODULATE
139 * for texture set 0 and GL_MODULATE for texture set 1. In
140 * all other cases, the driver falls back to pure software
141 * rendering
142 * - written the support for the new GL_EXT_multitexture
143 * - written the DD_MAX_TEXTURE_COORD_SETS support in the
144 * fxDDGetParameteri() function
145 * - the driver falls back to pure software rendering when
146 * texture mapping function is GL_BLEND
147 *
148 * V0.27 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
149 * - inluded in the Mesa-3.0beta5
150 * - written a smal extension (GL_FXMESA_global_texture_lod_bias) in
151 * order to expose the LOD bias related Glide function
152 * - fixed a bug fxDDWriteMonoRGBAPixels()
153 * - the driver is now able to fallback to software rendering in
154 * any case not directly supported by the hardware
155 * - written the support for enabling/disabling dithering
156 * - the in-window-rendering hack now works with any X11 screen
157 * depth
158 * - fixed a problem related to color/depth/alpha buffer clears
159 * - fixed a problem when clearing buffer for a context with the
160 * alpha buffer
161 * - fixed a problem in the fxTMReloadSubMipMapLevel() function,
162 * I have forget a "break;" (thanks to Joe Waters for the bug report)
163 * - fixed a problem in the color format for the in window
164 * rendering hack
165 * - written the fxDDReadRGBAPixels function
166 * - written the fxDDDepthTestPixelsGeneric function
167 * - written the fxDDDepthTestSpanGeneric function
168 * - written the fxDDWriteMonoRGBAPixels function
169 * - written the fxDDWriteRGBAPixels function
170 * - removed the multitexture emulation code for Voodoo board
171 * with only one TMU
172 *
173 * Chris Prince <cprince@cs.washington.edu>
174 * - fixed a new bug in the wglUseFontBitmaps code
175 *
176 * Ralf Knoesel (rknoesel@Stormfront.com)
177 * - fixed a bug in the wglUseFontBitmaps code
178 *
179 * Rune Hasvold (runeh@ifi.uio.no)
180 * - fixed a problem related to the aux usage in the fxBestResolution
181 * function
182 * - fixed the order of pixel formats in the WGL emulator
183 *
184 * Fredrik Hubinette (hubbe@hubbe.net)
185 * - the driver shutdown the Glide for most common signals
186 *
187 * V0.26 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
188 * - included in the Mesa-3.0beta4
189 * - fixed a problem related to a my optimization for the Rune's
190 * pixel-span optimization
191 * - fixed a problem related to fxDDSetNearFar() and ctx->ProjectionMatrixType
192 * (thanks to Ben "Ctrl-Alt-Delete" and the Raul Alonso's ssystem)
193 * - fixed a small bug in the Rune's pixel-span optimization
194 * - fixed a problem with GL_CCW (thanks to Curt Olson for and example
195 * of the problem)
196 * - grVertex setup code is now ready for the internal thread support
197 * - fixed a no used optimization with clipped vertices in
198 * grVertex setup code
199 * - fixed a problem in the GL_LIGHT_MODEL_TWO_SIDE support (thanks
200 * to Patrick H. Madden for a complete example of the bug)
201 *
202 * Rune Hasvold (runeh@ifi.uio.no)
203 * - highly optimized the driver functions for writing pixel
204 * span (2-3 times faster !)
205 *
206 * Axel W. Volley (volley@acm.org) Krauss-Maffei Wehrtechnik
207 * - written the fxDDReadDepthSpanFloat() and fxDDReadDepthSpanInt()
208 * functions
209 *
210 * V0.25 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
211 * - fixed a problem with Voodoo boards with only one TMU
212 * - fixed a bug in the fxMesaCreateContext()
213 * - now the GL_FRONT_AND_BACK works fine also with
214 * the alpha buffer and/or antialiasing
215 * - written the support for GL_FRONT_AND_BACK drawing but
216 * it doesn't works with the alpha buffer and/or antialiasing
217 * - fixed some bug in the Mesa core for glCopyTexSubImage
218 * and glCopyTexImage functions (thanks to Mike Connell
219 * for an example of the problem)
220 * - make some small optimizations in the Mesa core in order
221 * to save same driver call and state change for not very
222 * well written applications
223 * - introduced the NEW_DRVSTATE and make other optimizations
224 * for minimizing state changes
225 * - made a lot of optimizations in order to minimize state
226 * changes
227 * - it isn't more possible to create a context with the
228 * depth buffer and the stancil buffer (it isn't yet supported)
229 * - now the partial support for the Multitexture extension
230 * works with Quake2 for windows
231 * - vertex snap is not longer used for the Voodoo2 (FX_V2
232 * must be defined)
233 * - done a lot of cleanup in the fxsetup.c file
234 * - now the partial support for the Multitexture extension
235 * works with GLQuake for windows
236 *
237 * Dieter Nuetzel (nuetzel@kogs.informatik.uni-hamburg.de) University of Hamburg
238 * - fixed a problem in the asm code for Linux of the fxvsetup.c file
239 * highlighted by the binutils-2.8.1.0.29. 'fildw' asm instruction
240 * changed in 'fild'
241 *
242 * Kevin Hester (kevinh@glassworks.net)
243 * - written the wglUseFontBitmaps() function in the WGL emulator
244 *
245 * V0.24 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
246 * - now the drive always uses per fragment fog
247 * - written a small optimization in the points drawing function
248 * - written the support for trilinear filtering with 2 TMUs
249 * - written the first partial support for the Multitexture extension.
250 * This task is quite hard because the color combine units work after
251 * the two texture combine units and not before as required by the
252 * Multitexture extension
253 * - written a workaround in fxBestResolution() in order to solve a
254 * problem with bzflag (it asks for 1x1 window !)
255 * - changed the fxBestResolution() behavior. It now returns the larger
256 * screen resolution supported by the hardware (instead of 640x480)
257 * when it is unable to find an appropriate resolution that is large
258 * enough for the requested size
259 * - the driver is now able to use also the texture memory attached to
260 * second TMU
261 * - the texture memory manager is now able to work with two TMUs and
262 * store texture maps in the memory attached to TMU0, TMU1 or to split
263 * the mimpmap levels across TMUs in order to support trilinear filtering
264 * - I have bought a Voodoo2 board !
265 * - the amount of frambuffer ram is now doubled when an SLI configuration
266 * is detected
267 * - solved a problem related to the fxDDTexParam() and fxTexInvalidate()
268 * functions (thanks to Rune Hasvold for highlighting the problem)
269 * - done some cleanup in the fxvsetup.c file, written
270 * the FXVSETUP_FUNC macro
271 * - done a lot of cleanup in data types and field names
272 *
273 * Rune Hasvold (runeh@ifi.uio.no)
274 * - written the support for a right management of the auxiliary buffer.
275 * You can now use an 800x600 screen without the depth and alpha
276 * buffer
277 * - written the support for a new pixel format (without the depth
278 * and alpha buffer) in the WGL emulator
279 * - fixed a bug in the window version of the GLUT (it was ever asking
280 * for depth buffer)
281 *
282 * V0.23 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
283 * - included in the Mesa-3.0beta2 release
284 * - written the support for the OpenGL 1.2 GL_TEXTURE_BASE_LEVEL
285 * and GL_TEXTURE_MAX_LEVEL
286 * - rewritten several functions for a more clean support of texture
287 * mapping and in order to solve some bug
288 * - the accumulation buffer works (it is bit slow beacuase it requires
289 * to read/write from/to the Voodoo frame buffer but it works)
290 * - fixed a bug in the fxDDReadRGBASpan driver function (the R and
291 * B channels were read in the wrong order). Thanks to Jason Heym
292 * for highlighting the problem
293 * - written the support for multiple contexts on multiple boards.
294 * you can now use the Mesa/Voodoo with multiple Voodoo Graphics
295 * boards (for example with multiple screens or an HMD)
296 * - the fxBestResolution() now check all available resolutions
297 * and it is able to check the amount of framebuffer memory
298 * before return a resolution
299 * - modified the GLX/X11 driver in order to support all the
300 * resolution available
301 * - changed all function names. They should be now a bit more
302 * readable
303 * - written the Glide grVertex setup code for two TMU or
304 * for Multitexture support with emulationa dn one TMU
305 * - written the support for the new Mesa driver
306 * function GetParametri
307 * - small optimization/clean up in the texbind() function
308 * - fixed a FPU precision problem for glOrtho and texture
309 * mapping (thanks to Antti Juhani Huovilainen for an example
310 * of the problem)
311 * - written some small SGI OpenGL emulation code for the wgl,
312 * the OpenGL Optimizer and Cosmo3D work fine under windows !
313 * - moved the point/line/triangle/quad support in the fxmesa7.c
314 * - fixed a bug in the clear_color_depth() (thanks to Henk Kok
315 * for an example of the problem)
316 * - written a small workaround for Linux GLQuake, it asks
317 * for the alpha buffer and the depth buffer at the some time
318 * (but it never uses the alpha buffer)
319 * - checked the antialiasing points, lines and polygons support.
320 * It works fine
321 * - written the support for standard OpenGL antialiasing using
322 * blending. Lines support works fine (tested with BZflag)
323 * while I have still to check the polygons and points support
324 * - written the support for the alpha buffer. The driver is now
325 * able to use the Voodoo auxiliary buffer as an alpha buffer
326 * instead of a depth buffer. Also all the OpenGL blending
327 * modes are now supported. But you can't request a context
328 * with an alpha buffer AND a depth buffer at the some time
329 * (this is an hardware limitation)
330 * - written the support for switching between the fullscreen
331 * rendering and the in-window-rendering hack on the fly
332 *
333 * Rune Hasvold (runeh@ifi.uio.no)
334 * - fixed a bug in the texparam() function
335 *
336 * Brian Paul (brianp@elastic.avid.com) Avid Technology
337 * - sources accomodated for the new Mesa 3.0beta1
338 *
339 * V0.22 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
340 * - included with some v0.23 bug fix in the final release
341 * of the Mesa-2.6
342 * - written the support for the MESA_WGL_FX env. var. but
343 * not tested because I have only Voodoo Graphics boards
344 * - fixed a bug in the backface culling code
345 * (thanks to David Farrell for an example of the problem)
346 * - fixed the "Quake2 elevator" bug
347 * - GL_POLYGONS with 3/4 vertices are now drawn as
348 * GL_TRIANLGES/GL_QUADS (a small optimization for GLQuake)
349 * - fixed a bug in fxmesa6.h for GL_LINE_LOOP
350 * - fixed a NearFarStack bug in the Mesa when applications
351 * directly call glLoadMatrix to load a projection matrix
352 * - done some cleanup in the fxmesa2.c file
353 * - the driver no longer translates the texture maps
354 * when the Mesa internal format and the Voodoo
355 * format are the some (usefull for 1 byte texture maps
356 * where the driver can directly use the Mesa texture
357 * map). Also the amount of used memory is halfed
358 * - fixed a bug for GL_DECAL and GL_RGBA
359 * - fixed a bug in the clear_color_depth()
360 * - tested the v0.22 with the Mesa-2.6beta2. Impressive
361 * performances improvement thanks to the new Josh's
362 * asm code (+10fps in the isosurf demo, +5fps in GLQuake
363 * TIMEREFRESH)
364 * - written a optimized version of the RenderVB Mesa driver
365 * function. The Voodoo driver is now able to upload polygons
366 * in the most common cases at a very good speed. Good
367 * performance improvement for large set of small polygons
368 * - optimized the asm code for setting up the color information
369 * in the Glide grVertex structure
370 * - fixed a bug in the fxmesa2.c asm code (the ClipMask[]
371 * wasn't working)
372 *
373 * Josh Vanderhoof (joshv@planet.net)
374 * - removed the flush() function because it isn't required
375 * - limited the maximum number of swapbuffers in the Voodoo
376 * commands FIFO (controlled by the env. var. MESA_FX_SWAP_PENDING)
377 *
378 * Holger Kleemiss (holger.kleemiss@metronet.de) STN Atlas Elektronik GmbH
379 * - applied some patch for the Voodoo Rush
380 *
381 * V0.21 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
382 * - the driver is now able to take advantage of the ClipMask[],
383 * ClipOrMask and ClipAndMask information also under Windows
384 * - introduced a new function in the Mesa driver interface
385 * ClearColorAndDepth(). Now the glClear() function is
386 * 2 times faster (!) when you have to clear the color buffer
387 * and the depth buffer at some time
388 * - written the first version of the fxRenderVB() driver
389 * function
390 * - optimized the glTexImage() path
391 * - removed the fxMesaTextureUsePalette() support
392 * - fixed a bug in the points support (thanks to David Farrell
393 * for an example of the problem)
394 * - written the optimized path for glSubTexImage(),
395 * introduced a new function in the Mesa driver interface
396 * TexSubImage(...)
397 * - fixed a bug for glColorMask and glDepthMask
398 * - the wbuffer is not more used. The Voodoo driver uses
399 * a standard 16bit zbuffer in all cases. It is more consistent
400 * and now GLQuake and GLQuake2test work also with a GL_ZTRICK 0
401 * - the driver is now able to take advantage of the ClipMask[],
402 * ClipOrMask and ClipAndMask information (under Linux);
403 * - rewritten the setup_fx_units() function, now the texture
404 * mapping support is compliant to the OpenGL specs (GL_BLEND
405 * support is still missing). The LinuxGLQuake console correctly
406 * fade in/out and transparent water of GLQuake2test works fine
407 * - written the support for the env. var. FX_GLIDE_SWAPINTERVAL
408 * - found a bug in the Mesa core. There is a roundup problem for
409 * color values out of the [0.0,1.0] range
410 *
411 * Wonko <matt@khm.de>
412 * - fixed a Voodoo Rush related problem in the fxwgl.c
413 *
414 * Daryll Strauss <daryll@harlot.rb.ca.us>
415 * - written the scissor test support
416 *
417 * V0.20 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
418 * - written the closetmmanger() function in order to free all the memory
419 * allocated by the Texture Memory Manager (it will be useful
420 * when the support for multiple contexts/boards will be ready)
421 * - now the Voodoo driver runs without printing any information,
422 * define the env. var. MESA_FX_INFO if you want to read some
423 * information about the hardware and some statistic
424 * - written a small workaround for the "GLQuake multiplayer white box bug"
425 * in the setup_fx_units() funxtions. I'm already rewriting
426 * this function because it is the source of nearly all the current
427 * Voodoo driver problems
428 * - fixed the GLQuake texture misalignment problem (the texture
429 * coordinates must be scaled between 0.0 and 256.0 and not
430 * between 0.0 and 255.0)
431 * - written the support for the GL_EXT_shared_texture_palette
432 * - some small change for supporting the automatic building of the
433 * OpenGL32.dll under the Windows platform
434 * - the redefinition of a mipmap level is now a LOT faster. This path
435 * is used by GLQuake for dynamic lighting with some call to glTexSubImage2D()
436 * - the texture memory is now managed a set of 2MB blocks so
437 * texture maps can't be allocated on a 2MB boundary. The new Pure3D
438 * needs this kind of support (and probably any other Voodoo Graphics
439 * board with more than 2MB of texture memory)
440 *
441 * Brian Paul (brianp@elastic.avid.com) Avid Technology
442 * - added write_monocolor_span(), fixed bug in write_color_span()
443 * - added test for stenciling in choosepoint/line/triangle functions
444 *
445 * Joe Waters (falc@attila.aegistech.com) Aegis
446 * - written the support for the env. var. SST_SCREENREFRESH
447 *
448 * V0.19 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
449 * - written the 3Dfx Global Palette extension for GLQuake
450 * - written the support for the GL_EXT_paletted_texture (it works only with GL_RGBA
451 * palettes and the alpha value is ignored ... this is a limitation of the
452 * the current Glide version and Voodoo hardware)
453 * - fixed the amount of memory allocated for 8bit textures
454 * - merged the under construction v0.19 driver with the Mesa 2.5
455 * - finally written the support for deleting textures
456 * - introduced a new powerful texture memory manager: the texture memory
457 * is used as a cache of the set of all defined texture maps. You can
458 * now define several MB of texture maps also with a 2MB of texture memory
459 * (the texture memory manager will do automatically all the swap out/swap in
460 * work). The new texture memory manager has also
461 * solved a lot of other bugs/no specs compliance/problems
462 * related to the texture memory usage. The texture
463 * manager code is inside the new fxmesa3.c file
464 * - broken the fxmesa.c file in two files (fxmesa1.c and fxmesa2.c)
465 * and done some code cleanup
466 * - now is possible to redefine texture mipmap levels already defined
467 * - fixed a problem with the amount of texture memory allocated for textures
468 * with not all mipmap levels defined
469 * - fixed a small problem with single buffer rendering
470 *
471 * Brian Paul (brianp@elastic.avid.com) Avid Technology
472 * - read/write_color_span() now use front/back buffer correctly
473 * - create GLvisual with 5,6,5 bits per pixel, not 8,8,8
474 * - removed a few ^M characters from fxmesa2.c file
475 *
476 * V0.18 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
477 * - the Mesa-2.4beta3 is finally using the driver quads support (the
478 * previous Mesa versions have never taken any advantage from the quads support !)
479 * - tested with the Glide 2.4 for Win
480 * - ported all asm code to Linux
481 * - ported the v0.18 to Linux (without asm code)
482 * - back to Linux !!!
483 * - optimized the SETUP macro (no more vertex snap for points and lines)
484 * - optimized the SETUP macro (added one argument)
485 * - the Mesa/Voodoo is now 20/30% for points, lines and small triangles !
486 * - performance improvement setting VBSIZE to 72
487 * - the GrVertex texture code is now written in asm
488 * - the GrVertex zbuffer code is now written in asm
489 * - the GrVertex wbuffer code is now written in asm
490 * - the GrVertex gouraud code is now written in asm
491 * - the GrVertex snap code is now written in asm
492 * - changed the 8bit compressed texture maps in 8bit palette texture maps
493 * support (it has the some advantage of compressed texture maps without the
494 * problem of a fixed NCC table for all mipmap levels)
495 * - written the support for 8bit compressed texture maps (but texture maps with
496 * more than one mipmap level aren't working fine)
497 * - finnaly everthing is working fine in MesaQuake !
498 * - fixed a bug in the computation of texture mapping coordinates (I have found
499 * the bug thanks to MesaQuake !)
500 * - written the GL_REPLACE support (mainly for MesaQuake)
501 * - written the support for textures with not all mipmap levels defined
502 * - rewritten all the Texture memory stuff
503 * - written the MesaQuake support (define MESAQUAKE)
504 * - working with a ZBuffer if glOrtho or not int the default glDepthRange,
505 * otherwise working with the WBuffer
506 * written the glDepthRange support
507 *
508 * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
509 * - written the fxCloseHardware() and the fxQuaryHardware() (mainly
510 * for the VoodooWGL emulator)
511 *
512 * Brian Paul (brianp@elastic.avid.com) Avid Technology
513 * - implemented read/write_color_span() so glRead/DrawPixels() works
514 * - now needs Glide 2.3 or later. Removed GLIDE_FULL_SCREEN and call to grSstOpen()
515 *
516 * V0.17 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
517 * - optimized the bitmap support (66% faster)
518 * - tested with the Mesa 2.3beta2
519 *
520 * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
521 * - solved a problem with the drawbitmap() and the Voodoo Rush
522 * (GR_ORIGIN_LOWER_LEFT did not work with the Stingray)
523 *
524 * Brian Paul (brianp@elastic.avid.com) Avid Technology
525 * - linux stuff
526 * - general code clean-up
527 * - added attribList parameter to fxMesaCreateContext()
528 * - single buffering works now
529 * - VB colors are now GLubytes, removed ColorShift stuff
530 *
531 * Paul Metzger
532 * - linux stuff
533 *
534 * V0.16 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
535 * - written the quadfunc support (no performance improvement)
536 * - written the support for the new Mesa 2.3beta1 driver interface (Wow ! It is faaaster)
537 * - rewritten the glBitmap support for the Glide 2.3 (~35% slower !)
538 * - written the glBitmap support for the most common case (fonts)
539 *
540 * Jack Palevich
541 * - Glide 2.3 porting
542 *
543 * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
544 * - extended the fxMesaCreateContext() and fxMesaCreateBestContext()
545 * functions in order to support also the Voodoo Rush
546 * - tested with the Hercules Stingray 128/3D (The rendering in a window works !)
547 *
548 * V0.15 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
549 * - written the GL_LUMINANCE_ALPHA support
550 * - written the GL_ALPHA support
551 * - written the GL_LUMINANCE support
552 * - now SETUP correctly set color for mono color sequences
553 * - written the 9x1,10x1,...,1x9,1x10,... texture map ratio support
554 * - written the no square texture map support
555 * - the fog table is no more rebuilt inside setup_fx_units() each time
556 *
557 * Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
558 * - written (not yet finished: no texture mapping) support for glOrtho
559 * - some change to setup functions
560 * - the fog support is now fully compatible with the standard OpenGL
561 * - rewritten several parts of the driver in order to take
562 * advantage of meshes (40% faster !!!)
563 *
564 * V0.14 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
565 * - now glAlphaFunc() works
566 * - now glDepthMask() works
567 * - solved a mipmap problem when using more than one texture
568 * - moved ti, texid and wscale inside the fxMesaContext (now we can
569 * easy support more ctx and more boards)
570 * - the management of the fxMesaContext was completly broken !
571 * - solved several problems about Alpha and texture Alpha
572 * - 4 (RGBA) texture channels supported
573 * - setting the default color to white
574 *
575 * Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
576 * - small change to fxMesaCreateContext() and fxMesaMakeCurrent()
577 * - written the fog support
578 * - setting the default clear color to black
579 * - written cleangraphics() for the onexit() function
580 * - written fxMesaCreateBestContext()
581 *
582 * V0.13 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
583 * - now glBlendFunc() works for all glBlendFunc without DST_ALPHA
584 * (because the alpha buffer is not yet implemented)
585 * - now fxMesaCreateContext() accept resolution and refresh rate
586 * - fixed a bug for texture mapping: the w (alias z) must be set
587 * also without depth buffer
588 * - fixed a bug for texture image with width!=256
589 * - written texparam()
590 * - written all point, line and triangle functions for all possible supported
591 * contexts and the driver is slight faster with points, lines and small triangles
592 * - fixed a small bug in fx/fxmesa.h (glOrtho)
593 *
594 * V0.12 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
595 * - glDepthFunc supported
596 * - introduced a trick to discover the far plane distance
597 * (see fxMesaSetFar and fx/fxmesa.h)
598 * - now the wbuffer works with homogeneous coordinate (and it
599 * doesn't work with a glOrtho projection :)
600 * - solved several problems with homogeneous coordinate and texture mapping
601 * - fixed a bug in all line functions
602 * - fixed a clear framebuffer bug
603 * - solved a display list/teximg problem (but use
604 * glBindTexture: it is several times faster)
605 *
606 * V0.11 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
607 * - introduced texture mapping support (not yet finished !)
608 * - tested with Mesa2.2b6
609 * - the driver is faster
610 * - written glFlush/glFinish
611 * - the driver print a lot of info about the Glide lib
612 *
613 * v0.1 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
614 * - Initial revision
615 *
616 */
617
618
619 #ifdef HAVE_CONFIG_H
620 #include "conf.h"
621 #endif
622
623 #if defined(FX)
624 #include "fxdrv.h"
625
626 static fxMesaContext fxMesaCurrentCtx=NULL;
627
628 /*
629 * Status of 3Dfx hardware initialization
630 */
631
632 static int glbGlideInitialized=0;
633 static int glb3DfxPresent=0;
634 static int glbTotNumCtx=0;
635
636 GrHwConfiguration glbHWConfig;
637 int glbCurrentBoard=0;
638
639
640 #if defined(__WIN32__)
641 static int cleangraphics(void)
642 {
643 glbTotNumCtx=1;
644 fxMesaDestroyContext(fxMesaCurrentCtx);
645
646 return 0;
647 }
648 #elif defined(__linux__)
649 static void cleangraphics(void)
650 {
651 glbTotNumCtx=1;
652 fxMesaDestroyContext(fxMesaCurrentCtx);
653 }
654
655 static void cleangraphics_handler(int s)
656 {
657 fprintf(stderr,"fxmesa: Received a not handled signal %d\n",s);
658
659 cleangraphics();
660 /* abort(); */
661 exit(1);
662 }
663 #endif
664
665
666 /*
667 * Select the Voodoo board to use when creating
668 * a new context.
669 */
670 GLboolean GLAPIENTRY fxMesaSelectCurrentBoard(int n)
671 {
672 fxQueryHardware();
673
674 if((n<0) || (n>=glbHWConfig.num_sst))
675 return GL_FALSE;
676
677 glbCurrentBoard=n;
678
679 return GL_TRUE;
680 }
681
682
683 fxMesaContext GLAPIENTRY fxMesaGetCurrentContext(void)
684 {
685 return fxMesaCurrentCtx;
686 }
687
688
689 void GLAPIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f)
690 {
691 if(fxMesaCurrentCtx)
692 fxDDSetNearFar(fxMesaCurrentCtx->glCtx,n,f);
693 }
694
695
696 /*
697 * The 3Dfx Global Palette extension for GLQuake.
698 * More a trick than a real extesion, use the shared global
699 * palette extension.
700 */
701 extern void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *pal); /* silence warning */
702 void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *pal)
703 {
704 fxMesaContext fxMesa =fxMesaCurrentCtx;
705
706 if (MESA_VERBOSE&VERBOSE_DRIVER) {
707 int i;
708
709 fprintf(stderr,"fxmesa: gl3DfxSetPaletteEXT()\n");
710
711 for(i=0;i<256;i++)
712 fprintf(stderr,"%x\n",pal[i]);
713 }
714
715 if(fxMesa) {
716 fxMesa->haveGlobalPaletteTexture=1;
717
718 FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,(GuTexPalette *)pal);
719 if (fxMesa->haveTwoTMUs)
720 FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,(GuTexPalette *)pal);
721 }
722 }
723
724
725 static GrScreenResolution_t fxBestResolution(int width, int height, int aux)
726 {
727 static int resolutions[][5]={
728 { 512, 384, GR_RESOLUTION_512x384, 2, 2 },
729 { 640, 400, GR_RESOLUTION_640x400, 2, 2 },
730 { 640, 480, GR_RESOLUTION_640x480, 2, 2 },
731 { 800, 600, GR_RESOLUTION_800x600, 4, 2 },
732 { 960, 720, GR_RESOLUTION_960x720, 6, 4 }
733 #ifdef GR_RESOLUTION_1024x768
734 ,{ 1024, 768, GR_RESOLUTION_1024x768, 8, 4 }
735 #endif
736 #ifdef GR_RESOLUTION_1280x1024
737 ,{ 1024, 768, GR_RESOLUTION_1280x1024, 8, 8 }
738 #endif
739 #ifdef GR_RESOLUTION_1600x1200
740 ,{ 1024, 768, GR_RESOLUTION_1600x1200, 16, 8 }
741 #endif
742 };
743 int NUM_RESOLUTIONS = sizeof(resolutions) / (sizeof(int)*5);
744 int i,fbmem;
745 GrScreenResolution_t lastvalidres=resolutions[1][2];
746
747 fxQueryHardware();
748
749 if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
750 fbmem=glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam;
751
752 if(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect)
753 fbmem*=2;
754 } else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
755 fbmem=glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.fbRam;
756 else
757 fbmem=2;
758
759 /* A work around for BZFlag */
760
761 if((width==1) && (height==1)) {
762 width=640;
763 height=480;
764 }
765
766 for(i=0;i<NUM_RESOLUTIONS;i++)
767 if(resolutions[i][4-aux]<=fbmem) {
768 if((width<=resolutions[i][0]) && (height<=resolutions[i][1]))
769 return resolutions[i][2];
770
771 lastvalidres=resolutions[i][2];
772 }
773
774 return lastvalidres;
775 }
776
777
778 fxMesaContext GLAPIENTRY fxMesaCreateBestContext(GLuint win,GLint width, GLint height,
779 const GLint attribList[])
780 {
781 GrScreenRefresh_t refresh;
782 int i;
783 int res,aux;
784 refresh=GR_REFRESH_75Hz;
785
786 if(getenv("SST_SCREENREFRESH")) {
787 if(!strcmp(getenv("SST_SCREENREFRESH"),"60"))
788 refresh=GR_REFRESH_60Hz;
789 if(!strcmp(getenv("SST_SCREENREFRESH"),"70"))
790 refresh=GR_REFRESH_70Hz;
791 if(!strcmp(getenv("SST_SCREENREFRESH"),"72"))
792 refresh=GR_REFRESH_72Hz;
793 if(!strcmp(getenv("SST_SCREENREFRESH"),"75"))
794 refresh=GR_REFRESH_75Hz;
795 if(!strcmp(getenv("SST_SCREENREFRESH"),"80"))
796 refresh=GR_REFRESH_80Hz;
797 if(!strcmp(getenv("SST_SCREENREFRESH"),"85"))
798 refresh=GR_REFRESH_85Hz;
799 if(!strcmp(getenv("SST_SCREENREFRESH"),"90"))
800 refresh=GR_REFRESH_90Hz;
801 if(!strcmp(getenv("SST_SCREENREFRESH"),"100"))
802 refresh=GR_REFRESH_100Hz;
803 if(!strcmp(getenv("SST_SCREENREFRESH"),"120"))
804 refresh=GR_REFRESH_120Hz;
805 }
806
807 aux=0;
808 for(i=0;attribList[i]!=FXMESA_NONE;i++)
809 if((attribList[i]==FXMESA_ALPHA_SIZE) ||
810 (attribList[i]==FXMESA_DEPTH_SIZE)) {
811 if(attribList[++i]>0) {
812 aux=1;
813 break;
814 }
815 }
816
817 res=fxBestResolution(width,height,aux);
818
819 return fxMesaCreateContext(win,res,refresh,attribList);
820 }
821
822
823 #if 0
824 void fxsignals()
825 {
826 signal(SIGINT,SIG_IGN);
827 signal(SIGHUP,SIG_IGN);
828 signal(SIGPIPE,SIG_IGN);
829 signal(SIGFPE,SIG_IGN);
830 signal(SIGBUS,SIG_IGN);
831 signal(SIGILL,SIG_IGN);
832 signal(SIGSEGV,SIG_IGN);
833 signal(SIGTERM,SIG_IGN);
834 }
835 #endif
836
837 /*
838 * Create a new FX/Mesa context and return a handle to it.
839 */
840 fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win,
841 GrScreenResolution_t res,
842 GrScreenRefresh_t ref,
843 const GLint attribList[])
844 {
845 fxMesaContext fxMesa = NULL;
846 int i,type;
847 int aux;
848 GLboolean doubleBuffer=GL_FALSE;
849 GLboolean alphaBuffer=GL_FALSE;
850 GLboolean verbose=GL_FALSE;
851 GLint depthSize=0;
852 GLint stencilSize=0;
853 GLint accumSize=0;
854 GLcontext *shareCtx = NULL;
855 GLcontext *ctx = 0;
856 /*FX_GrContext_t glideContext = 0;*/
857 char *errorstr;
858 GLboolean useBGR;
859 char *system = NULL;
860
861 if (MESA_VERBOSE&VERBOSE_DRIVER) {
862 fprintf(stderr,"fxmesa: fxMesaCreateContext() Start\n");
863 }
864
865 if(getenv("MESA_FX_INFO"))
866 verbose=GL_TRUE;
867
868 aux=0;
869 i=0;
870 while(attribList[i]!=FXMESA_NONE) {
871 switch (attribList[i]) {
872 case FXMESA_DOUBLEBUFFER:
873 doubleBuffer=GL_TRUE;
874 break;
875 case FXMESA_ALPHA_SIZE:
876 i++;
877 alphaBuffer=attribList[i]>0;
878 if(alphaBuffer)
879 aux=1;
880 break;
881 case FXMESA_DEPTH_SIZE:
882 i++;
883 depthSize=attribList[i];
884 if(depthSize) {
885 aux=1;
886 depthSize = 16;
887 }
888 break;
889 case FXMESA_STENCIL_SIZE:
890 i++;
891 stencilSize=attribList[i];
892 break;
893 case FXMESA_ACCUM_SIZE:
894 i++;
895 accumSize=attribList[i];
896 break;
897 /* XXX ugly hack here for sharing display lists */
898 #define FXMESA_SHARE_CONTEXT 990099 /* keep in sync with xmesa1.c! */
899 case FXMESA_SHARE_CONTEXT:
900 i++;
901 {
902 const void *vPtr = &attribList[i];
903 GLcontext **ctx = (GLcontext **) vPtr;
904 shareCtx = *ctx;
905 }
906 break;
907 default:
908 if (MESA_VERBOSE&VERBOSE_DRIVER) {
909 fprintf(stderr,"fxmesa: fxMesaCreateContext() End (defualt)\n");
910 }
911 return NULL;
912 }
913 i++;
914 }
915
916 /* A workaround for Linux GLQuake */
917 if(depthSize && alphaBuffer)
918 alphaBuffer=0;
919
920 if ((type=fxQueryHardware()) < 0) {
921 fprintf(stderr,"fx Driver: ERROR no Voodoo1/2 Graphics or Voodoo Rush !\n");
922 return NULL;
923 }
924
925 if(type==GR_SSTTYPE_VOODOO)
926 win=0;
927
928 grSstSelect(glbCurrentBoard);
929
930 fxMesa=(fxMesaContext)calloc(1,sizeof(struct tfxMesaContext));
931 if(!fxMesa) {
932 errorstr = "malloc";
933 goto errorhandler;
934 }
935
936 if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO)
937 fxMesa->haveTwoTMUs=(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx > 1);
938 else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
939 fxMesa->haveTwoTMUs=(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.nTexelfx > 1);
940 else
941 fxMesa->haveTwoTMUs=GL_FALSE;
942
943 fxMesa->haveDoubleBuffer=doubleBuffer;
944 fxMesa->haveAlphaBuffer=alphaBuffer;
945 fxMesa->haveGlobalPaletteTexture=GL_FALSE;
946 fxMesa->haveZBuffer=depthSize ? 1 : 0;
947 fxMesa->verbose=verbose;
948 fxMesa->board=glbCurrentBoard;
949
950
951 fxMesa->glideContext = FX_grSstWinOpen((FxU32)win,res,ref,
952 #if FXMESA_USE_ARGB
953 GR_COLORFORMAT_ARGB,
954 #else
955 GR_COLORFORMAT_ABGR,
956 #endif
957 GR_ORIGIN_LOWER_LEFT,
958 2,aux);
959 if (!fxMesa->glideContext){
960 errorstr = "grSstWinOpen";
961 goto errorhandler;
962 }
963
964 /*
965 * Pixel tables are use during pixel read-back
966 * Either initialize them for RGB or BGR order.
967 */
968 #if FXMESA_USE_ARGB
969 useBGR = GL_FALSE; /* Force RGB pixel order */
970 system = "FXMESA_USE_ARGB";
971 #else
972 if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_VOODOO) {
973 /* jk991130 - Voodoo 3s don't use BGR. Query the # of TMUs
974 * as Voodoo3s have 2 TMUs on board, Banshee has only 1
975 * bk000413 - another suggestion from Joseph Kain is using
976 * VendorID 0x121a for all 3dfx boards
977 * DeviceID VG 1/V2 2/VB 3/V3 5
978 * For now we cehck for known BGR devices, and presume
979 * everything else to be a V3/RGB.
980 */
981 GrVoodooConfig_t *voodoo;
982 voodoo = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig;
983
984 if (voodoo->nTexelfx == 1) {
985 /* Voodoo1 or Banshee */
986 useBGR = GL_TRUE;
987 system = "Voodoo1";
988 }
989 else if (voodoo->nTexelfx == 2 &&
990 voodoo->fbiRev == 260 &&
991 voodoo->tmuConfig[0].tmuRev == 4 &&
992 voodoo->tmuConfig[0].tmuRam == 2) {
993 /* Voodoo 2 */
994 useBGR = GL_TRUE;
995 system = "Voodoo2";
996 }
997 else if (voodoo->nTexelfx == 2 &&
998 voodoo->fbiRev == 2 &&
999 voodoo->tmuConfig[0].tmuRev == 1 &&
1000 voodoo->tmuConfig[0].tmuRam == 4) {
1001 /* Quantum3D Obsidian 50/100 */
1002 useBGR = GL_TRUE;
1003 system = "Quantum3D Obsidian";
1004 }
1005 else
1006 /* Brian
1007 * (voodoo->nTexelfx == 2 &&
1008 * voodoo->fbiRev == 0 &&
1009 * voodoo->tmuConfig[0].tmuRev == 148441048 &&
1010 * voodoo->tmuConfig[0].tmuRam == 3)
1011 * Bernd
1012 * (voodoo->nTexelfx == 2 &&
1013 * voodoo->fbiRev == 69634 &&
1014 * voodoo->tmuConfig[0].tmuRev == 69634 &&
1015 * voodoo->tmuConfig[0].tmuRam == 2 )
1016 */
1017 {
1018 /* Presumed Voodoo3 */
1019 useBGR = GL_FALSE;
1020 system = "Voodoo3";
1021 }
1022 if (getenv("MESA_FX_INFO")) {
1023 printf("Voodoo: Texelfx: %d / FBI Rev.: %d / TMU Rev.: %d / TMU RAM: %d\n",
1024 voodoo->nTexelfx,
1025 voodoo->fbiRev,
1026 voodoo->tmuConfig[0].tmuRev,
1027 voodoo->tmuConfig[0].tmuRam );
1028 }
1029 }
1030 else {
1031 useBGR = GL_FALSE; /* use RGB pixel order otherwise */
1032 system = "non-voodoo";
1033 }
1034 #endif /*FXMESA_USE_ARGB*/
1035
1036 if (getenv("MESA_FX_INFO"))
1037 printf("Voodoo pixel order: %s (%s)\n", useBGR ? "BGR" : "RGB", system);
1038
1039 fxInitPixelTables(fxMesa, useBGR);
1040
1041 fxMesa->width=FX_grSstScreenWidth();
1042 fxMesa->height=FX_grSstScreenHeight();
1043
1044 fxMesa->clipMinX = 0;
1045 fxMesa->clipMaxX = fxMesa->width;
1046 fxMesa->clipMinY = 0;
1047 fxMesa->clipMaxY = fxMesa->height;
1048
1049 fxMesa->screen_width = fxMesa->width;
1050 fxMesa->screen_height = fxMesa->height;
1051 fxMesa->x_offset = 0;
1052 fxMesa->y_offset = 0;
1053 fxMesa->y_delta = 0;
1054
1055 fxMesa->needClip = 0;
1056
1057 if(verbose)
1058 fprintf(stderr,"Voodoo Glide screen size: %dx%d\n",
1059 (int)FX_grSstScreenWidth(),(int)FX_grSstScreenHeight());
1060
1061 fxMesa->glVis=gl_create_visual(GL_TRUE, /* RGB mode */
1062 alphaBuffer,
1063 doubleBuffer,
1064 GL_FALSE, /* stereo */
1065 depthSize, /* depth_size */
1066 stencilSize, /* stencil_size */
1067 accumSize, /* accum_size */
1068 0, /* index bits */
1069 5,6,5,0); /* RGBA bits */
1070 if (!fxMesa->glVis) {
1071 errorstr = "gl_create_visual";
1072 goto errorhandler;
1073 }
1074
1075 ctx = fxMesa->glCtx=gl_create_context(fxMesa->glVis,
1076 shareCtx, /* share list context */
1077 (void *) fxMesa, GL_TRUE);
1078 if (!ctx) {
1079 errorstr = "gl_create_context";
1080 goto errorhandler;
1081 }
1082
1083
1084 if (!fxDDInitFxMesaContext( fxMesa )) {
1085 errorstr = "fxDDInitFxMesaContext failed";
1086 goto errorhandler;
1087 }
1088
1089
1090 fxMesa->glBuffer=gl_create_framebuffer(fxMesa->glVis,
1091 GL_FALSE, /* no software depth */
1092 fxMesa->glVis->StencilBits > 0,
1093 fxMesa->glVis->AccumRedBits > 0,
1094 fxMesa->glVis->AlphaBits > 0 );
1095 if (!fxMesa->glBuffer) {
1096 errorstr = "gl_create_framebuffer";
1097 goto errorhandler;
1098 }
1099
1100 glbTotNumCtx++;
1101
1102 /* install signal handlers */
1103 #if defined(__linux__)
1104 /* Only install if environment var. is not set. */
1105 if (fxMesa->glCtx->CatchSignals && !getenv("MESA_FX_NO_SIGNALS")) {
1106 signal(SIGINT,cleangraphics_handler);
1107 signal(SIGHUP,cleangraphics_handler);
1108 signal(SIGPIPE,cleangraphics_handler);
1109 signal(SIGFPE,cleangraphics_handler);
1110 signal(SIGBUS,cleangraphics_handler);
1111 signal(SIGILL,cleangraphics_handler);
1112 signal(SIGSEGV,cleangraphics_handler);
1113 signal(SIGTERM,cleangraphics_handler);
1114 }
1115 #endif
1116
1117 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1118 fprintf(stderr,"fxmesa: fxMesaCreateContext() End\n");
1119 }
1120
1121 return fxMesa;
1122
1123 errorhandler:
1124 if (fxMesa) {
1125 if (fxMesa->glideContext)
1126 FX_grSstWinClose(fxMesa->glideContext);
1127 fxMesa->glideContext = 0;
1128
1129 if (fxMesa->state)
1130 free(fxMesa->state);
1131 if (fxMesa->fogTable)
1132 free(fxMesa->fogTable);
1133 if (fxMesa->glBuffer)
1134 gl_destroy_framebuffer(fxMesa->glBuffer);
1135 if (fxMesa->glVis)
1136 gl_destroy_visual(fxMesa->glVis);
1137 if (fxMesa->glCtx)
1138 gl_destroy_context(fxMesa->glCtx);
1139 free(fxMesa);
1140 }
1141
1142 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1143 fprintf(stderr,"fxmesa: fxMesaCreateContext() End (%s)\n",errorstr);
1144 }
1145 return NULL;
1146 }
1147
1148
1149 /*
1150 * Function to set the new window size in the context (mainly for the Voodoo Rush)
1151 */
1152 void GLAPIENTRY fxMesaUpdateScreenSize(fxMesaContext fxMesa)
1153 {
1154 fxMesa->width=FX_grSstScreenWidth();
1155 fxMesa->height=FX_grSstScreenHeight();
1156 }
1157
1158
1159 /*
1160 * Destroy the given FX/Mesa context.
1161 */
1162 void GLAPIENTRY fxMesaDestroyContext(fxMesaContext fxMesa)
1163 {
1164 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1165 fprintf(stderr,"fxmesa: fxMesaDestroyContext()\n");
1166 }
1167
1168 if(fxMesa) {
1169 gl_destroy_visual(fxMesa->glVis);
1170 gl_destroy_context(fxMesa->glCtx);
1171 gl_destroy_framebuffer(fxMesa->glBuffer);
1172
1173 glbTotNumCtx--;
1174
1175 fxCloseHardware();
1176 FX_grSstWinClose(fxMesa->glideContext);
1177
1178 if(fxMesa->verbose) {
1179 fprintf(stderr,"Misc Stats:\n");
1180 fprintf(stderr," # swap buffer: %u\n",fxMesa->stats.swapBuffer);
1181
1182 if(!fxMesa->stats.swapBuffer)
1183 fxMesa->stats.swapBuffer=1;
1184
1185 fprintf(stderr,"Textures Stats:\n");
1186 fprintf(stderr," Free texture memory on TMU0: %d:\n",fxMesa->freeTexMem[FX_TMU0]);
1187 if(fxMesa->haveTwoTMUs)
1188 fprintf(stderr," Free texture memory on TMU1: %d:\n",fxMesa->freeTexMem[FX_TMU1]);
1189 fprintf(stderr," # request to TMM to upload a texture objects: %u\n",
1190 fxMesa->stats.reqTexUpload);
1191 fprintf(stderr," # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
1192 fxMesa->stats.reqTexUpload/(float)fxMesa->stats.swapBuffer);
1193 fprintf(stderr," # texture objects uploaded: %u\n",
1194 fxMesa->stats.texUpload);
1195 fprintf(stderr," # texture objects uploaded per swapbuffer: %.2f\n",
1196 fxMesa->stats.texUpload/(float)fxMesa->stats.swapBuffer);
1197 fprintf(stderr," # MBs uploaded to texture memory: %.2f\n",
1198 fxMesa->stats.memTexUpload/(float)(1<<20));
1199 fprintf(stderr," # MBs uploaded to texture memory per swapbuffer: %.2f\n",
1200 (fxMesa->stats.memTexUpload/(float)fxMesa->stats.swapBuffer)/(float)(1<<20));
1201 }
1202 if (fxMesa->state)
1203 free(fxMesa->state);
1204 if (fxMesa->fogTable)
1205 free(fxMesa->fogTable);
1206 fxTMClose(fxMesa);
1207
1208 free(fxMesa);
1209 }
1210
1211 if(fxMesa==fxMesaCurrentCtx)
1212 fxMesaCurrentCtx=NULL;
1213 }
1214
1215
1216 /*
1217 * Make the specified FX/Mesa context the current one.
1218 */
1219 void GLAPIENTRY fxMesaMakeCurrent(fxMesaContext fxMesa)
1220 {
1221 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1222 fprintf(stderr,"fxmesa: fxMesaMakeCurrent(...) Start\n");
1223 }
1224
1225 if(!fxMesa) {
1226 gl_make_current(NULL,NULL);
1227 fxMesaCurrentCtx=NULL;
1228
1229 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1230 fprintf(stderr,"fxmesa: fxMesaMakeCurrent(NULL) End\n");
1231 }
1232
1233 return;
1234 }
1235
1236 /* if this context is already the current one, we can return early */
1237 if (fxMesaCurrentCtx == fxMesa
1238 && fxMesaCurrentCtx->glCtx == gl_get_current_context()) {
1239 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1240 fprintf(stderr,"fxmesa: fxMesaMakeCurrent(fxMesaCurrentCtx==fxMesa) End\n");
1241 }
1242
1243 return;
1244 }
1245
1246 if(fxMesaCurrentCtx)
1247 grGlideGetState((GrState*)fxMesaCurrentCtx->state);
1248
1249 fxMesaCurrentCtx=fxMesa;
1250
1251 grSstSelect(fxMesa->board);
1252 grGlideSetState((GrState*)fxMesa->state);
1253
1254 gl_make_current(fxMesa->glCtx,fxMesa->glBuffer);
1255
1256 fxSetupDDPointers(fxMesa->glCtx);
1257
1258 /* The first time we call MakeCurrent we set the initial viewport size */
1259 if(fxMesa->glCtx->Viewport.Width==0)
1260 gl_Viewport(fxMesa->glCtx,0,0,fxMesa->width,fxMesa->height);
1261
1262 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1263 fprintf(stderr,"fxmesa: fxMesaMakeCurrent(...) End\n");
1264 }
1265 }
1266
1267
1268 #if 0
1269 static void QueryCounters(void)
1270 {
1271 static GLuint prevPassed = 0;
1272 static GLuint prevFailed = 0;
1273 GLuint failed, passed;
1274 GrSstPerfStats_t st;
1275
1276 FX_grSstPerfStats(&st);
1277 failed = st.zFuncFail - st.aFuncFail - st.chromaFail;
1278 passed = st.pixelsIn - failed;
1279 printf("failed: %d passed: %d\n", failed - prevFailed, passed - prevPassed);
1280
1281 prevPassed = passed;
1282 prevFailed = failed;
1283 }
1284 #endif
1285
1286
1287 /*
1288 * Swap front/back buffers for current context if double buffered.
1289 */
1290 void GLAPIENTRY fxMesaSwapBuffers(void)
1291 {
1292 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1293 fprintf(stderr,"fxmesa: ------------------------------- fxMesaSwapBuffers() -------------------------------\n");
1294 }
1295
1296 if(fxMesaCurrentCtx) {
1297 FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" );
1298
1299 if(fxMesaCurrentCtx->haveDoubleBuffer) {
1300
1301 grBufferSwap(fxMesaCurrentCtx->swapInterval);
1302
1303 /*
1304 * Don't allow swap buffer commands to build up!
1305 */
1306 while(FX_grGetInteger(FX_PENDING_BUFFERSWAPS)>fxMesaCurrentCtx->maxPendingSwapBuffers)
1307 /* The driver is able to sleep when waiting for the completation
1308 of multiple swapbuffer operations instead of wasting
1309 CPU time (NOTE: you must uncomment the following line in the
1310 in order to enable this option) */
1311 /* usleep(10000); */
1312 ;
1313
1314 fxMesaCurrentCtx->stats.swapBuffer++;
1315 }
1316 }
1317 }
1318
1319
1320 /*
1321 * Query 3Dfx hardware presence/kind
1322 */
1323 int GLAPIENTRY fxQueryHardware(void)
1324 {
1325 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1326 fprintf(stderr,"fxmesa: fxQueryHardware() Start\n");
1327 }
1328
1329 if (!glbGlideInitialized) {
1330 grGlideInit();
1331 if (FX_grSstQueryHardware(&glbHWConfig)) {
1332 grSstSelect(glbCurrentBoard);
1333 glb3DfxPresent = 1;
1334
1335 if (getenv("MESA_FX_INFO")) {
1336 char buf[80];
1337
1338 FX_grGlideGetVersion(buf);
1339 fprintf(stderr, "Voodoo Using Glide V%s\n", buf);
1340 fprintf(stderr, "Voodoo Number of boards: %d\n", glbHWConfig.num_sst);
1341
1342 if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_VOODOO) {
1343 GrVoodooConfig_t *voodoo;
1344 voodoo = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig;
1345
1346 fprintf(stderr, "Voodoo Framebuffer RAM: %d\n",
1347 voodoo->sliDetect ? (voodoo->fbRam*2) : voodoo->fbRam);
1348 fprintf(stderr, "Voodoo Number of TMUs: %d\n", voodoo->nTexelfx);
1349 fprintf(stderr, "Voodoo fbRam: %d\n", voodoo->fbRam);
1350 fprintf(stderr, "Voodoo fbiRev: %d\n", voodoo->fbiRev);
1351
1352 fprintf(stderr,"Voodoo SLI detected: %d\n", voodoo->sliDetect);
1353 }
1354 else if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_SST96) {
1355 GrSst96Config_t *sst96;
1356 sst96 = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config;
1357 fprintf(stderr, "Voodoo Framebuffer RAM: %d\n", sst96->fbRam);
1358 fprintf(stderr, "Voodoo Number of TMUs: %d\n", sst96->nTexelfx);
1359 }
1360
1361 }
1362 }
1363 else {
1364 glb3DfxPresent = 0;
1365 }
1366
1367 glbGlideInitialized = 1;
1368
1369 #if defined(__WIN32__)
1370 onexit((_onexit_t)cleangraphics);
1371 #elif defined(__linux__)
1372 /* Only register handler if environment variable is not defined. */
1373 if (!getenv("MESA_FX_NO_SIGNALS")) {
1374 atexit(cleangraphics);
1375 }
1376 #endif
1377 }
1378
1379 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1380 fprintf(stderr,"fxmesa: fxQueryHardware() End (voodooo)\n");
1381 }
1382
1383 return glbHWConfig.SSTs[glbCurrentBoard].type;
1384 }
1385
1386
1387 /*
1388 * Shutdown Glide library
1389 */
1390 void GLAPIENTRY fxCloseHardware(void)
1391 {
1392 if (glbGlideInitialized) {
1393 if (getenv("MESA_FX_INFO")) {
1394 GrSstPerfStats_t st;
1395
1396 FX_grSstPerfStats(&st);
1397 fprintf(stderr,"Pixels Stats:\n");
1398 fprintf(stderr," # pixels processed (minus buffer clears): %u\n",(unsigned)st.pixelsIn);
1399 fprintf(stderr," # pixels not drawn due to chroma key test failure: %u\n",(unsigned)st.chromaFail);
1400 fprintf(stderr," # pixels not drawn due to depth test failure: %u\n",(unsigned)st.zFuncFail);
1401 fprintf(stderr," # pixels not drawn due to alpha test failure: %u\n",(unsigned)st.aFuncFail);
1402 fprintf(stderr," # pixels drawn (including buffer clears and LFB writes): %u\n",(unsigned)st.pixelsOut);
1403 }
1404
1405 if (glbTotNumCtx == 0) {
1406 grGlideShutdown();
1407 glbGlideInitialized = 0;
1408 }
1409 }
1410 }
1411
1412
1413 #else
1414
1415
1416 /*
1417 * Need this to provide at least one external definition.
1418 */
1419 extern int gl_fx_dummy_function_api(void);
1420 int gl_fx_dummy_function_api(void)
1421 {
1422 return 0;
1423 }
1424
1425 #endif /* FX */