Move the transform and lighting code to two new directories
authorKeith Whitwell <keith@tungstengraphics.com>
Thu, 16 Nov 2000 21:05:34 +0000 (21:05 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Thu, 16 Nov 2000 21:05:34 +0000 (21:05 +0000)
math:  Provides basic matrix and vector functionality that
               might be useful to multiple software t&l
       implementations, and is used by core mesa to
       manage the Model, Project, etc matrices.

tnl:   The real transform & lighting code from core mesa,
       including everything from glVertex3f through vertex
       buffer handling, transformation, clipping, lighting
       and handoff to a driver for rasterization.

The interfaces of these can be further tightened up, but the basic
splitting up of state and code move is done.

77 files changed:
src/mesa/Makefile.X11
src/mesa/drivers/ggi/ggimesa.c
src/mesa/drivers/glide/fxapi.c
src/mesa/drivers/glide/fxdd.c
src/mesa/drivers/glide/fxdrv.h
src/mesa/drivers/glide/fxsetup.c
src/mesa/drivers/osmesa/osmesa.c
src/mesa/drivers/svga/svgamesa.c
src/mesa/drivers/x11/xm_api.c
src/mesa/drivers/x11/xm_dd.c
src/mesa/drivers/x11/xm_line.c
src/mesa/drivers/x11/xm_span.c
src/mesa/drivers/x11/xm_tri.c
src/mesa/main/Makefile.X11
src/mesa/main/attrib.c
src/mesa/main/clip.c
src/mesa/main/clip.h
src/mesa/main/colormac.h
src/mesa/main/context.c
src/mesa/main/context.h
src/mesa/main/dd.h
src/mesa/main/debug.c [new file with mode: 0644]
src/mesa/main/debug.h [new file with mode: 0644]
src/mesa/main/dlist.c
src/mesa/main/dlist.h
src/mesa/main/drawpix.c
src/mesa/main/enable.c
src/mesa/main/eval.c
src/mesa/main/eval.h
src/mesa/main/fog.c
src/mesa/main/fog.h
src/mesa/main/get.c
src/mesa/main/light.c
src/mesa/main/light.h
src/mesa/main/lines.c
src/mesa/main/macros.h
src/mesa/main/matrix.c
src/mesa/main/matrix.h
src/mesa/main/points.c
src/mesa/main/rastpos.c
src/mesa/main/state.c
src/mesa/main/texstate.c
src/mesa/main/texstate.h
src/mesa/main/varray.c
src/mesa/main/varray.h
src/mesa/math/m_clip_tmp.h [new file with mode: 0644]
src/mesa/math/m_copy_tmp.h [new file with mode: 0644]
src/mesa/math/m_debug_xform.c [new file with mode: 0644]
src/mesa/math/m_dotprod_tmp.h [new file with mode: 0644]
src/mesa/math/m_matrix.c [new file with mode: 0644]
src/mesa/math/m_matrix.h [new file with mode: 0644]
src/mesa/math/m_norm_tmp.h [new file with mode: 0644]
src/mesa/math/m_trans_tmp.h [new file with mode: 0644]
src/mesa/math/m_translate.c [new file with mode: 0644]
src/mesa/math/m_translate.h [new file with mode: 0644]
src/mesa/math/m_vector.c [new file with mode: 0644]
src/mesa/math/m_vector.h [new file with mode: 0644]
src/mesa/math/m_xform.c [new file with mode: 0644]
src/mesa/math/m_xform.h [new file with mode: 0644]
src/mesa/math/m_xform_tmp.h [new file with mode: 0644]
src/mesa/swrast/s_bitmap.c
src/mesa/swrast/s_lines.c
src/mesa/swrast/s_points.c
src/mesa/swrast_setup/ss_context.c
src/mesa/swrast_setup/ss_triangle.c
src/mesa/swrast_setup/ss_tritmp.h
src/mesa/swrast_setup/ss_vb.c
src/mesa/swrast_setup/ss_vbtmp.h
src/mesa/tnl/t_context.c [new file with mode: 0644]
src/mesa/tnl/t_context.h [new file with mode: 0644]
src/mesa/tnl/t_pipeline.c [new file with mode: 0644]
src/mesa/tnl/t_pipeline.h [new file with mode: 0644]
src/mesa/tnl/tnl.h [new file with mode: 0644]
src/mesa/x86/3dnow.c
src/mesa/x86/3dnow.h
src/mesa/x86/common_x86_asm.h
src/mesa/x86/x86.c

index 533e0c32d9509717950b5252b43fbe9c367b8028..acec47b09ca90489b8ce05e4366b86429abfd3a6 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.32 2000/11/11 19:09:29 brianp Exp $
+# $Id: Makefile.X11,v 1.33 2000/11/16 21:05:34 keithw Exp $
 
 # Mesa 3-D graphics library
 # Version:  3.5
@@ -21,10 +21,31 @@ LIBDIR = ../lib
 
 
 CORE_SOURCES = \
+       tnl/t_bbox.c \
+       tnl/t_clip.c \
+       tnl/t_context.c \
+       tnl/t_cva.c \
+       tnl/t_debug.c \
+       tnl/t_dlist.c \
+       tnl/t_eval.c \
+       tnl/t_fog.c \
+       tnl/t_light.c \
+       tnl/t_pipeline.c \
+       tnl/t_rect.c \
+       tnl/t_shade.c \
+       tnl/t_stages.c \
+       tnl/t_texture.c \
+       tnl/t_trans_elt.c \
+       tnl/t_varray.c \
+       tnl/t_vb.c \
+       tnl/t_vbcull.c \
+       tnl/t_vbfill.c \
+       tnl/t_vbindirect.c \
+       tnl/t_vbrender.c \
+       tnl/t_vbxform.c \
        accum.c \
        alpha.c \
        attrib.c \
-       bbox.c \
        bitmap.c \
        blend.c \
        buffers.c \
@@ -34,8 +55,7 @@ CORE_SOURCES = \
        context.c \
        convolve.c \
        copypix.c \
-       cva.c \
-       debug_xform.c \
+       debug.c \
        depth.c \
        dispatch.c \
        dlist.c \
@@ -64,7 +84,6 @@ CORE_SOURCES = \
        matrix.c \
        mem.c \
        mmath.c \
-       pipeline.c \
        pixel.c \
        pixeltex.c \
        points.c \
@@ -73,8 +92,6 @@ CORE_SOURCES = \
        readpix.c \
        rect.c \
        scissor.c \
-       shade.c \
-       stages.c \
        state.c \
        stencil.c \
        teximage.c \
@@ -82,18 +99,8 @@ CORE_SOURCES = \
        texstate.c \
        texture.c \
        texutil.c \
-       translate.c \
        varray.c \
-       vb.c \
-       vbcull.c \
-       vbfill.c \
-       vbindirect.c \
-       vbrender.c \
-       vbxform.c \
-       vector.c \
-       vertices.c \
        winpos.c \
-       xform.c \
        X86/x86.c \
        X86/common_x86.c \
        X86/3dnow.c \
@@ -129,9 +136,13 @@ CORE_SOURCES = \
        swrast/s_zoom.c \
        swrast_setup/ss_context.c \
        swrast_setup/ss_triangle.c \
-       swrast_setup/ss_vb.c 
-
-
+       swrast_setup/ss_vb.c \
+       math/m_debug_xform.c \
+       math/m_matrix.c \
+       math/m_translate.c \
+       math/m_vector.c \
+       math/m_vertices.c \
+       math/m_xform.c  
 
 
 
index 125aefcfb679d498d9b3613214745f3972e2037c..764ccba803e74a6d58a2075514b434d559169294 100644 (file)
@@ -508,7 +508,7 @@ void GGIMesaSwapBuffers(void)
 {
        GGIMESADPRINT_CORE("GGIMesaSwapBuffers\n");
        
-       FLUSH_VB(GGIMesa->gl_ctx, "swap buffers");
+       _mesa_swapbuffers( GGIMesa->gl_ctx );
        gl_ggiFlush(GGIMesa->gl_ctx);
        
        if (GGIMesa->gl_vis->DBflag)
index ea5f816258e224d5acba79e316d1ba9fb3d75e64..f3a6431aec5e7cd04ae16eddee65070fd6d32217 100644 (file)
  */
 
 
-/* fxapi.c - 3Dfx VooDoo/Mesa interface */
-
-
-/********************************************************************
- *
- * Function names:
- *  fxMesa....     (The driver API)
- *  fxDD....       (Mesa device driver functions)
- *  fxTM....       (Texture manager functions)
- *  fxSetup....    (Voodoo units setup functions)
- *  fx....         (Internal driver functions)
- *
- * Data type names:
- *  fxMesa....     (Public driver data types)
- *  tfx....        (Private driver data types)
- *
- ********************************************************************
- *
- * V0.30 - David Bucciarelli (davibu@tin.it) Humanware s.r.l.
- *         - introduced a new MESA_GLX_FX related behavior
- *         - the Glide fog table was built in a wrong way (using
- *           gu* Glide function). Added the code for building the
- *           table following the OpenGL specs. Thanks to Steve Baker
- *           for highlighting the problem.
- *         - fixed few problems in my and Keith's fxDDClear code
- *         - merged my code with the Keith's one
- *         - used the new BlendFunc Mesa device driver function 
- *         - used the new AlphaFunc Mesa device driver function 
- *         - used the new Enable Mesa device driver function 
- *         - fixed a bug related to fog in the Mesa core. Fog
- *           were applied two times: at vertex level and at fragment
- *           level (thanks to Steve Baker for reporting the problem)
- *         - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE) now works
- *           (thanks to Jiri Pop for reporting the problem)
- *         - the driver works fine with OpenGL Unreal
- *         - fixed a bug in the Mesa core clipping code (related
- *           to the q texture coordinate)
- *         - introduced the support for the q texture coordinate
- *
- *         Keith Whitwell (keithw@cableinet.co.uk)
- *         - optimized the driver and written all the new code
- *           required by the new Mesa-3.1 device driver API
- *           and by the new Mesa-3.1 core changes
- *         - written the cva support and many other stuff
- *
- *         Brian Paul (brian_paul@avid.com) Avid Technology
- *         - fixed display list share bug for MESA_GLX_FX = window/fullscreen
- *         - fixed glClear/gl...Mask related problem
- *
- *         Bert Schoenwaelder (bert@prinz-atm.CS.Uni-Magdeburg.De)
- *         - the driver is now able to sleep when waiting for the completation
- *           of multiple swapbuffer operations instead of wasting
- *           CPU time (NOTE: you must uncomment the lines in the
- *           fxMesaSwapBuffers function in order to enable this option)
- *
- *         Eero Pajarre (epajarre@koti.tpo.fi)
- *         - enabled the macro FLOAT_COLOR_TO_UBYTE_COLOR under
- *           windows
- *         - written an asm x86 optimized float->integer conversions
- *           for windows
- *
- *         Theodore Jump (tjump@cais.com)
- *         - fixed a small problem in the __wglMonitor function of the
- *           wgl emulator
- *         - written the in-window-rendering hack support for windows
- *           and Vooodoo1/2 cards
- *
- * V0.29 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - included in Mesa-3.0
- *         - now glGetString(GL_RENDERER) returns more information
- *           about the hardware configuration: "Mesa Glide <version>
- *           <Voodoo_Graphics|Voodoo_Rush|UNKNOWN> <num> CARD/<num> FB/
- *           <num> TM/<num> TMU/<NOSLI|SLI>"
- *           where: <num> CARD is the card used for the current context,
- *           <num> FB is the number of MB for the framebuffer,
- *           <num> TM is the number of MB for the texture memory,
- *           <num> TMU is the number of TMU. You can try to run
- *           Mesa/demos/glinfo in order to have an example of the
- *           output
- *         - fixed a problem of the WGL emulator with the
- *           OpenGL Optimizer 1.1 (thanks to Erwin Coumans for
- *           the bug report)
- *         - fixed some bug in the fxwgl.c code (thanks to  
- *           Peter Pettersson for a patch and a bug report)
- *
- *         Theodore Jump (tjump@cais.com)
- *         - written the SST_DUALHEAD support in the WGL emulator
- *
- *         Daryll Strauss (daryll@harlot.rb.ca.us)
- *         - fixed the Voodoo Rush support for the in window rendering
- *
- * V0.28 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - the only supported multitexture functions are GL_MODULATE
- *           for texture set 0 and GL_MODULATE for texture set 1. In
- *           all other cases, the driver falls back to pure software
- *           rendering
- *         - written the support for the new  GL_EXT_multitexture
- *         - written the DD_MAX_TEXTURE_COORD_SETS support in the
- *           fxDDGetParameteri() function
- *         - the driver falls back to pure software rendering when
- *           texture mapping function is GL_BLEND
- *
- * V0.27 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - inluded in the Mesa-3.0beta5
- *         - written a smal extension (GL_FXMESA_global_texture_lod_bias) in
- *           order to expose the LOD bias related Glide function
- *         - fixed a bug fxDDWriteMonoRGBAPixels()
- *         - the driver is now able to fallback to software rendering in
- *           any case not directly supported by the hardware
- *         - written the support for enabling/disabling dithering
- *         - the in-window-rendering hack now works with any X11 screen
- *           depth
- *         - fixed a problem related to color/depth/alpha buffer clears
- *         - fixed a problem when clearing buffer for a context with the
- *           alpha buffer
- *         - fixed a problem in the fxTMReloadSubMipMapLevel() function,
- *           I have forget a "break;" (thanks to Joe Waters for the bug report)
- *         - fixed a problem in the color format for the in window
- *           rendering hack
- *         - written the fxDDReadRGBAPixels function
- *         - written the fxDDDepthTestPixelsGeneric function
- *         - written the fxDDDepthTestSpanGeneric function
- *         - written the fxDDWriteMonoRGBAPixels function
- *         - written the fxDDWriteRGBAPixels function
- *         - removed the multitexture emulation code for Voodoo board
- *         with only one TMU
- *
- *         Chris Prince <cprince@cs.washington.edu>
- *         - fixed a new bug in the wglUseFontBitmaps code
- *
- *         Ralf Knoesel (rknoesel@Stormfront.com)
- *         - fixed a bug in the wglUseFontBitmaps code
- *
- *         Rune Hasvold (runeh@ifi.uio.no)
- *         - fixed a problem related to the aux usage in the fxBestResolution
- *           function
- *         - fixed the order of pixel formats in the WGL emulator
- *
- *         Fredrik Hubinette (hubbe@hubbe.net)
- *         - the driver shutdown the Glide for most common signals
- *
- * V0.26 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - included in the Mesa-3.0beta4
- *         - fixed a problem related to a my optimization for the Rune's
- *           pixel-span optimization
- *         - fixed a problem related to fxDDSetNearFar() and ctx->ProjectionMatrixType
- *           (thanks to Ben "Ctrl-Alt-Delete" and the Raul Alonso's ssystem)
- *         - fixed a small bug in the Rune's pixel-span optimization
- *         - fixed a problem with GL_CCW (thanks to Curt Olson for and example
- *           of the problem)
- *         - grVertex setup code is now ready for the internal thread support
- *         - fixed a no used optimization with clipped vertices in
- *           grVertex setup code
- *         - fixed a problem in the GL_LIGHT_MODEL_TWO_SIDE support (thanks
- *           to Patrick H. Madden for a complete example of the bug)
- *
- *         Rune Hasvold (runeh@ifi.uio.no)
- *         - highly optimized the driver functions for writing pixel
- *           span (2-3 times faster !)
- *
- *         Axel W. Volley (volley@acm.org) Krauss-Maffei Wehrtechnik
- *         - written the fxDDReadDepthSpanFloat() and fxDDReadDepthSpanInt()
- *           functions
- *
- * V0.25 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - fixed a problem with Voodoo boards with only one TMU
- *         - fixed a bug in the fxMesaCreateContext()
- *         - now the GL_FRONT_AND_BACK works fine also with
- *           the alpha buffer and/or antialiasing
- *         - written the support for GL_FRONT_AND_BACK drawing but
- *           it doesn't works with the alpha buffer and/or antialiasing
- *         - fixed some bug in the Mesa core for glCopyTexSubImage
- *           and glCopyTexImage functions (thanks to Mike Connell
- *           for an example of the problem)
- *         - make some small optimizations in the Mesa core in order
- *           to save same driver call and state change for not very
- *           well written applications
- *         - introduced the NEW_DRVSTATE and make other optimizations
- *           for minimizing state changes
- *         - made a lot of optimizations in order to minimize state
- *           changes
- *         - it isn't more possible to create a context with the
- *           depth buffer and the stancil buffer (it isn't yet supported)
- *         - now the partial support for the Multitexture extension
- *           works with Quake2 for windows
- *         - vertex snap is not longer used for the Voodoo2 (FX_V2
- *           must be defined)
- *         - done a lot of cleanup in the fxsetup.c file
- *         - now the partial support for the Multitexture extension
- *           works with GLQuake for windows
- *
- *         Dieter Nuetzel (nuetzel@kogs.informatik.uni-hamburg.de) University of Hamburg
- *         - fixed a problem in the asm code for Linux of the fxvsetup.c file
- *           highlighted by the binutils-2.8.1.0.29. 'fildw' asm instruction
- *           changed in 'fild'
- *
- *         Kevin Hester (kevinh@glassworks.net)
- *         - written the wglUseFontBitmaps() function in the WGL emulator
- *
- * V0.24 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - now the drive always uses per fragment fog
- *         - written a small optimization in the points drawing function
- *         - written the support for trilinear filtering with 2 TMUs
- *         - written the first partial support for the Multitexture extension.
- *           This task is quite hard because the color combine units work after
- *           the two texture combine units and not before as required by the 
- *           Multitexture extension
- *         - written a workaround in fxBestResolution() in order to solve a
- *           problem with bzflag (it asks for 1x1 window !)
- *         - changed the fxBestResolution() behavior. It now returns the larger
- *           screen resolution supported by the hardware (instead of 640x480)
- *           when it is unable to find an appropriate resolution that is large
- *           enough for the requested size 
- *         - the driver is now able to use also the texture memory attached to
- *           second TMU
- *         - the texture memory manager is now able to work with two TMUs and
- *           store texture maps in the memory attached to TMU0, TMU1 or to split
- *           the mimpmap levels across TMUs in order to support trilinear filtering
- *         - I have bought a Voodoo2 board !
- *         - the amount of frambuffer ram is now doubled when an SLI configuration
- *           is detected
- *         - solved a problem related to the fxDDTexParam() and fxTexInvalidate()
- *           functions (thanks to Rune Hasvold for highlighting the problem)
- *         - done some cleanup in the fxvsetup.c file, written
- *           the FXVSETUP_FUNC macro
- *         - done a lot of cleanup in data types and field names
- *
- *         Rune Hasvold (runeh@ifi.uio.no)
- *         - written the support for a right management of the auxiliary buffer.
- *           You can now use an 800x600 screen without the depth and alpha
- *           buffer
- *         - written the support for a new pixel format (without the depth
- *           and alpha buffer) in the WGL emulator
- *         - fixed a bug in the window version of the GLUT (it was ever asking
- *           for depth buffer)
- *
- * V0.23 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - included in the Mesa-3.0beta2 release
- *         - written the support for the OpenGL 1.2 GL_TEXTURE_BASE_LEVEL
- *           and GL_TEXTURE_MAX_LEVEL
- *         - rewritten several functions for a more clean support of texture
- *           mapping and in order to solve some bug
- *         - the accumulation buffer works (it is  bit slow beacuase it requires
- *           to read/write from/to the Voodoo frame buffer but it works)
- *         - fixed a bug in the fxDDReadRGBASpan driver function (the R and
- *           B channels were read in the wrong order). Thanks to Jason Heym
- *           for highlighting the problem
- *         - written the support for multiple contexts on multiple boards.
- *           you can now use the Mesa/Voodoo with multiple Voodoo Graphics
- *           boards (for example with multiple screens or an HMD)
- *         - the fxBestResolution() now check all available resolutions
- *           and it is able to check the amount of framebuffer memory
- *           before return a resolution
- *         - modified the GLX/X11 driver in order to support all the
- *           resolution available
- *         - changed all function names. They should be now a bit more
- *           readable
- *         - written the Glide grVertex setup code for two TMU or
- *           for Multitexture support with emulationa dn one TMU
- *         - written the support for the new Mesa driver
- *           function GetParametri
- *         - small optimization/clean up in the texbind() function
- *         - fixed a FPU precision problem for glOrtho and texture
- *           mapping (thanks to Antti Juhani Huovilainen for an example
- *           of the problem)
- *         - written some small SGI OpenGL emulation code for the wgl,
- *           the OpenGL Optimizer and Cosmo3D work fine under windows !
- *         - moved the point/line/triangle/quad support in the fxmesa7.c
- *         - fixed a bug in the clear_color_depth() (thanks to Henk Kok
- *           for an example of the problem)
- *         - written a small workaround for Linux GLQuake, it asks
- *           for the alpha buffer and the depth buffer at the some time
- *           (but it never uses the alpha buffer)
- *         - checked the antialiasing points, lines and polygons support.
- *           It works fine
- *         - written the support for standard OpenGL antialiasing using
- *           blending. Lines support works fine (tested with BZflag)
- *           while I have still to check the polygons and points support
- *         - written the support for the alpha buffer. The driver is now
- *           able to use the Voodoo auxiliary buffer as an alpha buffer
- *           instead of a depth buffer. Also all the OpenGL blending
- *           modes are now supported. But you can't request a context
- *           with an alpha buffer AND a depth buffer at the some time
- *           (this is an hardware limitation)
- *         - written the support for switching between the fullscreen
- *           rendering and the in-window-rendering hack on the fly
- *
- *         Rune Hasvold (runeh@ifi.uio.no)
- *         - fixed a bug in the texparam() function
- *
- *         Brian Paul (brianp@elastic.avid.com) Avid Technology
- *         - sources accomodated for the new Mesa 3.0beta1
- *
- * V0.22 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - included with some v0.23 bug fix in the final release
- *           of the Mesa-2.6
- *         - written the support for the MESA_WGL_FX env. var. but
- *           not tested because I have only Voodoo Graphics boards
- *         - fixed a bug in the backface culling code
- *           (thanks to David Farrell for an example of the problem)
- *         - fixed the "Quake2 elevator" bug
- *         - GL_POLYGONS with 3/4 vertices are now drawn as
- *           GL_TRIANLGES/GL_QUADS (a small optimization for GLQuake)
- *         - fixed a bug in fxmesa6.h for GL_LINE_LOOP
- *         - fixed a NearFarStack bug in the Mesa when applications
- *           directly call glLoadMatrix to load a projection matrix 
- *         - done some cleanup in the fxmesa2.c file
- *         - the driver no longer translates the texture maps
- *           when the Mesa internal format and the Voodoo
- *           format are the some (usefull for 1 byte texture maps
- *           where the driver can directly use the Mesa texture
- *           map). Also the amount of used memory is halfed
- *         - fixed a bug for GL_DECAL and GL_RGBA
- *         - fixed a bug in the clear_color_depth()
- *         - tested the v0.22 with the Mesa-2.6beta2. Impressive
- *           performances improvement thanks to the new Josh's
- *           asm code (+10fps in the isosurf demo, +5fps in GLQuake
- *           TIMEREFRESH)
- *         - written a optimized version of the RenderVB Mesa driver
- *           function. The Voodoo driver is now able to upload polygons
- *           in the most common cases at a very good speed. Good
- *           performance improvement for large set of small polygons
- *         - optimized the asm code for setting up the color information
- *           in the Glide grVertex structure
- *         - fixed a bug in the fxmesa2.c asm code (the ClipMask[]
- *           wasn't working)
- *
- *         Josh Vanderhoof (joshv@planet.net)
- *         - removed the flush() function because it isn't required
- *         - limited the maximum number of swapbuffers in the Voodoo
- *           commands FIFO (controlled by the env. var. MESA_FX_SWAP_PENDING)
- *
- *         Holger Kleemiss (holger.kleemiss@metronet.de) STN Atlas Elektronik GmbH
- *         - applied some patch for the Voodoo Rush
- *
- * V0.21 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - the driver is now able to take advantage of the ClipMask[],
- *           ClipOrMask and ClipAndMask information also under Windows
- *         - introduced a new function in the Mesa driver interface
- *           ClearColorAndDepth(). Now the glClear() function is
- *           2 times faster (!) when you have to clear the color buffer
- *           and the depth buffer at some time
- *         - written the first version of the fxRenderVB() driver
- *           function
- *         - optimized the glTexImage() path
- *         - removed the fxMesaTextureUsePalette() support
- *         - fixed a bug in the points support (thanks to David Farrell
- *           for an example of the problem)
- *         - written the optimized path for glSubTexImage(),
- *           introduced a new function in the Mesa driver interface
- *           TexSubImage(...)
- *         - fixed a bug for glColorMask and glDepthMask
- *         - the wbuffer is not more used. The Voodoo driver uses
- *           a standard 16bit zbuffer in all cases. It is more consistent
- *           and now GLQuake and GLQuake2test work also with a GL_ZTRICK 0
- *         - the driver is now able to take advantage of the ClipMask[],
- *           ClipOrMask and ClipAndMask information (under Linux);
- *         - rewritten the setup_fx_units() function, now the texture
- *           mapping support is compliant to the OpenGL specs (GL_BLEND
- *           support is still missing). The LinuxGLQuake console correctly
- *           fade in/out and transparent water of GLQuake2test works fine
- *         - written the support for the env. var. FX_GLIDE_SWAPINTERVAL
- *         - found a bug in the Mesa core. There is a roundup problem for
- *           color values out of the [0.0,1.0] range
- *
- *         Wonko <matt@khm.de>
- *         - fixed a Voodoo Rush related problem in the fxwgl.c
- *
- *         Daryll Strauss <daryll@harlot.rb.ca.us>
- *         - written the scissor test support
- *
- * V0.20 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - written the closetmmanger() function in order to free all the memory
- *           allocated by the Texture Memory Manager (it will be useful
- *           when the support for multiple contexts/boards will be ready)
- *         - now the Voodoo driver runs without printing any information,
- *           define the env. var. MESA_FX_INFO if you want to read some
- *           information about the hardware and some statistic
- *         - written a small workaround for the "GLQuake multiplayer white box bug"
- *           in the setup_fx_units() funxtions. I'm already rewriting
- *           this function because it is the source of nearly all the current
- *           Voodoo driver problems
- *         - fixed the GLQuake texture misalignment problem (the texture
- *           coordinates must be scaled between 0.0 and 256.0 and not
- *           between 0.0 and 255.0)
- *         - written the support for the GL_EXT_shared_texture_palette
- *         - some small change for supporting the automatic building of the
- *           OpenGL32.dll under the Windows platform
- *         - the redefinition of a mipmap level is now a LOT faster. This path
- *           is used by GLQuake for dynamic lighting with some call to glTexSubImage2D()
- *         - the texture memory is now managed a set of 2MB blocks so
- *           texture maps can't be allocated on a 2MB boundary. The new Pure3D
- *           needs this kind of support (and probably any other Voodoo Graphics
- *           board with more than 2MB of texture memory)
- *
- *         Brian Paul (brianp@elastic.avid.com) Avid Technology
- *         - added write_monocolor_span(), fixed bug in write_color_span()
- *         - added test for stenciling in choosepoint/line/triangle functions
- *
- *         Joe Waters (falc@attila.aegistech.com) Aegis
- *         - written the support for the env. var. SST_SCREENREFRESH
- *
- * V0.19 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - written the 3Dfx Global Palette extension for GLQuake
- *         - written the support for the GL_EXT_paletted_texture (it works only with GL_RGBA
- *           palettes and the alpha value is ignored ... this is a limitation of the
- *           the current Glide version and Voodoo hardware)
- *         - fixed the amount of memory allocated for 8bit textures
- *         - merged the under construction v0.19 driver with the Mesa 2.5
- *         - finally written the support for deleting textures
- *         - introduced a new powerful texture memory manager: the texture memory
- *           is used as a cache of the set of all defined texture maps. You can
- *           now define several MB of texture maps also with a 2MB of texture memory
- *           (the texture memory manager will do automatically all the swap out/swap in
- *           work). The new texture memory manager has also
- *           solved a lot of other bugs/no specs compliance/problems
- *           related to the texture memory usage. The texture
- *           manager code is inside the new fxmesa3.c file
- *         - broken the fxmesa.c file in two files (fxmesa1.c and fxmesa2.c)
- *           and done some code cleanup
- *         - now is possible to redefine texture mipmap levels already defined
- *         - fixed a problem with the amount of texture memory allocated for textures
- *           with not all mipmap levels defined
- *         - fixed a small problem with single buffer rendering
- *
- *         Brian Paul (brianp@elastic.avid.com) Avid Technology
- *         - read/write_color_span() now use front/back buffer correctly
- *         - create GLvisual with 5,6,5 bits per pixel, not 8,8,8
- *         - removed a few ^M characters from fxmesa2.c file
- *
- * V0.18 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - the Mesa-2.4beta3 is finally using the driver quads support (the
- *           previous Mesa versions have never taken any advantage from the quads support !)
- *         - tested with the Glide 2.4 for Win
- *         - ported all asm code to Linux
- *         - ported the v0.18 to Linux (without asm code)
- *         - back to Linux !!!
- *         - optimized the SETUP macro (no more vertex snap for points and lines)
- *         - optimized the SETUP macro (added one argument)
- *         - the Mesa/Voodoo is now 20/30% for points, lines and small triangles !
- *         - performance improvement setting VBSIZE to 72 
- *         - the GrVertex texture code is now written in asm
- *         - the GrVertex zbuffer code is now written in asm
- *         - the GrVertex wbuffer code is now written in asm
- *         - the GrVertex gouraud code is now written in asm
- *         - the GrVertex snap code is now written in asm
- *         - changed the 8bit compressed texture maps in 8bit palette texture maps
- *           support (it has the some advantage of compressed texture maps without the
- *           problem of a fixed NCC table for all mipmap levels)
- *         - written the support for 8bit compressed texture maps (but texture maps with
- *           more than one mipmap level aren't working fine)
- *         - finnaly everthing is working fine in MesaQuake !
- *         - fixed a bug in the computation of texture mapping coordinates (I have found
- *           the bug thanks to MesaQuake !)
- *         - written the GL_REPLACE support (mainly for MesaQuake)
- *         - written the support for textures with not all mipmap levels defined
- *         - rewritten all the Texture memory stuff
- *         - written the MesaQuake support (define MESAQUAKE)
- *         - working with a ZBuffer if glOrtho or not int the default glDepthRange,
- *           otherwise working with the WBuffer
- *         written the glDepthRange support
- *
- *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
- *         - written the fxCloseHardware() and the fxQuaryHardware() (mainly
- *           for the VoodooWGL emulator)
- *
- *         Brian Paul (brianp@elastic.avid.com) Avid Technology
- *         - implemented read/write_color_span() so glRead/DrawPixels() works
- *         - now needs Glide 2.3 or later.  Removed GLIDE_FULL_SCREEN and call to grSstOpen()
- *
- * V0.17 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - optimized the bitmap support (66% faster)
- *         - tested with the Mesa 2.3beta2
- *
- *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
- *         - solved a problem with the drawbitmap() and the Voodoo Rush
- *           (GR_ORIGIN_LOWER_LEFT did not work with the Stingray)
- *
- *         Brian Paul (brianp@elastic.avid.com) Avid Technology
- *         - linux stuff
- *         - general code clean-up
- *         - added attribList parameter to fxMesaCreateContext()
- *         - single buffering works now
- *         - VB colors are now GLubytes, removed ColorShift stuff
- *
- *         Paul Metzger
- *         - linux stuff
- *
- * V0.16 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - written the quadfunc support (no performance improvement)
- *         - written the support for the new Mesa 2.3beta1 driver interface (Wow ! It is faaaster)
- *         - rewritten the glBitmap support for the Glide 2.3 (~35% slower !)
- *         - written the glBitmap support for the most common case (fonts)
- *
- *         Jack Palevich
- *         - Glide 2.3 porting
- *
- *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
- *         - extended the fxMesaCreateContext() and fxMesaCreateBestContext()
- *           functions in order to support also the Voodoo Rush
- *         - tested with the Hercules Stingray 128/3D (The rendering in a window works !)
- *
- * V0.15 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - written the GL_LUMINANCE_ALPHA support
- *         - written the GL_ALPHA support
- *         - written the GL_LUMINANCE support
- *         - now SETUP correctly set color for mono color sequences
- *         - written the 9x1,10x1,...,1x9,1x10,... texture map ratio support
- *         - written the no square texture map support
- *         - the fog table is no more rebuilt inside setup_fx_units() each time
- *
- *         Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
- *         - written (not yet finished: no texture mapping) support for glOrtho
- *         - some change to setup functions
- *         - the fog support is now fully compatible with the standard OpenGL
- *         - rewritten several parts of the driver in order to take
- *           advantage of meshes (40% faster !!!)
- *
- * V0.14 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - now glAlphaFunc() works
- *         - now glDepthMask() works
- *         - solved a mipmap problem when using more than one texture
- *         - moved ti, texid and wscale inside the fxMesaContext (now we can
- *           easy support more ctx and more boards)
- *         - the management of the fxMesaContext was completly broken !
- *         - solved several problems about Alpha and texture Alpha
- *         - 4 (RGBA) texture channels supported
- *         - setting the default color to white
- *
- *         Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
- *         - small change to fxMesaCreateContext() and fxMesaMakeCurrent()
- *         - written the fog support
- *         - setting the default clear color to black
- *         - written cleangraphics() for the onexit() function
- *         - written fxMesaCreateBestContext()
- *
- * V0.13 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - now glBlendFunc() works for all glBlendFunc without DST_ALPHA
- *           (because the alpha buffer is not yet implemented) 
- *         - now fxMesaCreateContext() accept resolution and refresh rate
- *         - fixed a bug for texture mapping: the w (alias z) must be set
- *           also without depth buffer
- *         - fixed a bug for texture image with width!=256
- *         - written texparam()
- *         - written all point, line and triangle functions for all possible supported
- *           contexts and the driver is slight faster with points, lines and small triangles
- *         - fixed a small bug in fx/fxmesa.h (glOrtho)
- *
- * V0.12 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - glDepthFunc supported
- *         - introduced a trick to discover the far plane distance
- *           (see fxMesaSetFar and fx/fxmesa.h)
- *         - now the wbuffer works with homogeneous coordinate (and it
- *           doesn't work with a glOrtho projection :)
- *         - solved several problems with homogeneous coordinate and texture mapping
- *         - fixed a bug in all line functions
- *         - fixed a clear framebuffer bug
- *         - solved a display list/teximg problem (but use
- *           glBindTexture: it is several times faster)
- *
- * V0.11 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - introduced texture mapping support (not yet finished !)
- *         - tested with Mesa2.2b6
- *         - the driver is faster 
- *         - written glFlush/glFinish
- *         - the driver print a lot of info about the Glide lib
- *
- * v0.1  - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
- *         - Initial revision
- *
- */
-
-
 #ifdef HAVE_CONFIG_H
 #include "conf.h"
 #endif
@@ -686,13 +113,6 @@ fxMesaContext GLAPIENTRY fxMesaGetCurrentContext(void)
 }
 
 
-void GLAPIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f)
-{
-  if(fxMesaCurrentCtx)
-    fxDDSetNearFar(fxMesaCurrentCtx->glCtx,n,f);
-}
-
-
 /*
  * The 3Dfx Global Palette extension for GLQuake.
  * More a trick than a real extesion, use the shared global
@@ -1294,7 +714,7 @@ void GLAPIENTRY fxMesaSwapBuffers(void)
   }
 
   if(fxMesaCurrentCtx) {
-   FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" );
+     _mesa_swapbuffers( fxMesaCurrentCtx->glCtx );
 
     if(fxMesaCurrentCtx->haveDoubleBuffer) {
 
index e70be6cd6b0163d2140b9b720ad355e309a96973..178fa192ac0f3c3c970df55c9960173725c4e474 100644 (file)
@@ -58,6 +58,7 @@
 #include "extensions.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
 
 /* These lookup table are used to extract RGB values in [0,255] from
  * 16-bit pixel values.
@@ -611,11 +612,6 @@ static void fxDDFinish(GLcontext *ctx)
 
 
 
-void fxDDSetNearFar(GLcontext *ctx, GLfloat n, GLfloat f)
-{
-   FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
-   ctx->Driver.RenderStart = fxSetupFXUnits;
-}
 
 /* KW: Put the word Mesa in the render string because quakeworld
  * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE).
@@ -763,35 +759,28 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa )
 
    /* Initialize the software rasterizer and helper modules.
     */
+   fxMesa->glCtx->Driver.RegisterVB = fxDDRegisterVB;
+
    _swrast_CreateContext( fxMesa->glCtx );
    _swsetup_CreateContext( fxMesa->glCtx );
+   _tnl_CreateContext( fxMesa->glCtx );
+
+   fxSetupDDPointers(fxMesa->glCtx);
 
    /* Tell the software rasterizer to use pixel fog always.
     */
    _swrast_allow_vertex_fog( fxMesa->glCtx, GL_FALSE );
    _swrast_allow_pixel_fog( fxMesa->glCtx, GL_TRUE );
 
-   fxSetupDDPointers(fxMesa->glCtx);
    fxDDInitExtensions(fxMesa->glCtx);  
 
-   fxDDSetNearFar(fxMesa->glCtx,1.0,100.0);
-  
    FX_grGlideGetState((GrState*)fxMesa->state);
 
-   /* XXX Fix me: callback not registered when main VB is created.
-    */
-   if (fxMesa->glCtx->VB) 
-      fxDDRegisterVB( fxMesa->glCtx->VB );
-  
    /* XXX Fix me too: need to have the 'struct dd' prepared prior to
     * creating the context... The below is broken if you try to insert
     * new stages.  
     */
-   if (fxMesa->glCtx->NrPipelineStages)
-      fxMesa->glCtx->NrPipelineStages = fxDDRegisterPipelineStages( 
-        fxMesa->glCtx->PipelineStage,
-        fxMesa->glCtx->PipelineStage,
-        fxMesa->glCtx->NrPipelineStages);
+   fxDDRegisterPipelineStages( fxMesa->glCtx );
 
    /* Run the config file */
    _mesa_context_initialize( fxMesa->glCtx );
@@ -936,6 +925,15 @@ static void fxDDUpdateDDPointers(GLcontext *ctx)
 
   _swrast_InvalidateState( ctx, new_state );
   _swsetup_InvalidateState( ctx, new_state );
+  _tnl_InvalidateState( ctx, new_state );
+
+  /* Recalculate fog table on projection matrix changes.  This used to
+   * be triggered by the NearFar callback.
+   */
+  if (new_state & _NEW_PROJECTION) {
+     FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
+     ctx->Driver.RenderStart = fxSetupFXUnits;
+  }
 
   if (new_state & (_FX_NEW_IS_IN_HARDWARE |
                   _FX_NEW_RENDERSTATE |
@@ -965,7 +963,6 @@ void fxSetupDDPointers(GLcontext *ctx)
     fprintf(stderr,"fxmesa: fxSetupDDPointers()\n");
   }
 
-  ctx->Driver.UpdateStateNotify = ~0;
   ctx->Driver.UpdateState=fxDDUpdateDDPointers;
 
   ctx->Driver.WriteDepthSpan=fxDDWriteDepthSpan;
@@ -975,8 +972,6 @@ void fxSetupDDPointers(GLcontext *ctx)
          
   ctx->Driver.GetString=fxDDGetString;
 
-  ctx->Driver.NearFar=fxDDSetNearFar;
-
   ctx->Driver.ClearIndex=NULL;
   ctx->Driver.ClearColor=fxDDClearColor;
   ctx->Driver.Clear=fxDDClear;
@@ -1009,8 +1004,6 @@ void fxSetupDDPointers(GLcontext *ctx)
   ctx->Driver.DeleteTexture=fxDDTexDel;
   ctx->Driver.UpdateTexturePalette=fxDDTexPalette;
 
-  ctx->Driver.RectFunc=NULL;
-
   ctx->Driver.AlphaFunc=fxDDAlphaFunc;
   ctx->Driver.BlendFunc=fxDDBlendFunc;
   ctx->Driver.DepthFunc=fxDDDepthFunc;
@@ -1026,8 +1019,6 @@ void fxSetupDDPointers(GLcontext *ctx)
   ctx->Driver.RegisterVB=fxDDRegisterVB;
   ctx->Driver.UnregisterVB=fxDDUnregisterVB;
 
-  ctx->Driver.RegisterPipelineStages = fxDDRegisterPipelineStages;
-
   if (!getenv("FX_NO_FAST")) 
       ctx->Driver.BuildPrecalcPipeline = fxDDBuildPrecalcPipeline; 
 
index 833abceb34f49298507d058368ead710f08fa59b..04049f091fab570ee3e91d3bc141e11634277a29 100644 (file)
 #include "mem.h"
 #include "texture.h"
 #include "types.h"
-#include "vb.h"
-#include "xform.h"
-#include "clip.h"
-#include "vbrender.h"
 
 #include "GL/fxmesa.h"
 #include "fxglidew.h"
 
+#include "math/m_vector.h"
+
 /* use gl/gl.h GLAPI/GLAPIENTRY/GLCALLBACK in place of
  * WINGDIAPI/APIENTRY/CALLBACK, these are defined in mesa gl/gl.h -
  * tjump@spgs.com 
@@ -476,7 +474,6 @@ extern int glbCurrentBoard;
 extern void fxPrintSetupFlags( const char *msg, GLuint flags );
 extern void fxSetupFXUnits(GLcontext *);
 extern void fxSetupDDPointers(GLcontext *);
-extern void fxDDSetNearFar(GLcontext *, GLfloat, GLfloat);
 
 extern void fxDDSetupInit(void);
 extern void fxDDCvaInit(void);
@@ -533,9 +530,7 @@ extern void fxDDPartialRasterSetup( struct vertex_buffer *VB );
 
 extern void fxDDDoRasterSetup( struct vertex_buffer *VB );
 
-extern GLuint fxDDRegisterPipelineStages( struct gl_pipeline_stage *out,
-                                         const struct gl_pipeline_stage *in,
-                                         GLuint nr );
+extern void fxDDRegisterPipelineStages( GLcontext *ctx );
 
 extern GLboolean fxDDBuildPrecalcPipeline( GLcontext *ctx );
 
index 5d5cd1129240395a3aed8285041c4843e44b77c2..2cc6add1d28b0d57524924116e12a8ac61ea9c49 100644 (file)
@@ -54,6 +54,8 @@
 #include "fxdrv.h"
 #include "enums.h"
 
+#include "tnl/t_context.h"
+
 static GLuint fxGetTexSetConfiguration(GLcontext *ctx,
                                struct gl_texture_object *tObj0,
                                struct gl_texture_object *tObj1);
index 39d256a77f3431c9d1ae78b59e0a42e8721d2935..74850556a76b147ae73116f0e718ef5d677c543d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: osmesa.c,v 1.30 2000/11/14 17:50:07 brianp Exp $ */
+/* $Id: osmesa.c,v 1.31 2000/11/16 21:05:38 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -311,11 +311,11 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
       {
         GLcontext *ctx = &osmesa->gl_ctx;
 
+        ctx->Driver.RegisterVB = _swsetup_RegisterVB;
+
         _swrast_CreateContext( ctx );
         _swsetup_CreateContext( ctx );
-
-        if (ctx->VB) 
-           _swsetup_RegisterVB( ctx->VB );
+        _tnl_CreateContext( ctx );
         
         osmesa_register_swrast_functions( ctx );
       }
@@ -1690,7 +1690,6 @@ static void osmesa_update_state( GLcontext *ctx )
    ASSERT((void *) osmesa == (void *) ctx->DriverCtx);
 
    ctx->Driver.GetString = get_string;
-   ctx->Driver.UpdateStateNotify = ~0;
    ctx->Driver.UpdateState = osmesa_update_state;
 
    ctx->Driver.SetDrawBuffer = set_draw_buffer;
@@ -1747,4 +1746,8 @@ static void osmesa_update_state( GLcontext *ctx )
    ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels;
    ctx->Driver.ReadCI32Span = read_index_span;
    ctx->Driver.ReadCI32Pixels = read_index_pixels;
+
+   _swrast_InvalidateState( ctx, ctx->NewState );
+   _swsetup_InvalidateState( ctx, ctx->NewState );
+   _tnl_InvalidateState( ctx, ctx->NewState );
 }
index daa660e434b96add87c122cd9c090bc4c7c8117e..5163e08ece6eaddbe05415a4754e44996096ffc2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: svgamesa.c,v 1.7 2000/11/14 17:40:14 brianp Exp $ */
+/* $Id: svgamesa.c,v 1.8 2000/11/16 21:05:39 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -487,7 +487,7 @@ void SVGAMesaSwapBuffers( void )
    copy_buffer(SVGABuffer.BackBuffer);
 
 #ifndef DEV
-   FLUSH_VB( SVGAMesa->gl_ctx, "swap buffers" );
+   _mesa_swapbuffers( SVGAMesa->gl_ctx );
    if (SVGAMesa->gl_vis->DBflag) 
 #endif /* DEV */   
    {
index 9fa029cd48598901fb94a8c2381b68fe67fdfa47..f48da3bbfe52c3e681d53e6d7bcfdbc5807916dc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: xm_api.c,v 1.7 2000/11/14 17:40:15 brianp Exp $ */
+/* $Id: xm_api.c,v 1.8 2000/11/16 21:05:40 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -78,6 +78,7 @@
 #include "macros.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
 
 #ifndef GLX_NONE_EXT
 #define GLX_NONE_EXT 0x8000
@@ -1654,7 +1655,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    c->pixelformat = v->dithered_pf;      /* Dithering is enabled by default */
 
    ctx->Driver.UpdateState = xmesa_update_state;
-   ctx->Driver.UpdateStateNotify = ~0;
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(XFree86Server)
    c->driContextPriv = driContextPriv;
@@ -1664,14 +1664,11 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
     */
    xmesa_init_pointers( ctx );
 
-   if (ctx->VB) 
-      _swsetup_RegisterVB( ctx->VB );
-
-
    /* Initialize the software rasterizer and helper modules.
     */
    _swrast_CreateContext( ctx );
    _swsetup_CreateContext( ctx );
+   _tnl_CreateContext( ctx );
 
    xmesa_register_swrast_functions( ctx );
 
index 81700b5a52f957d364300193883ab78f69ea3379..21c984d310ce80f74674331a05cbaf33b385d254 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: xm_dd.c,v 1.5 2000/11/14 17:40:15 brianp Exp $ */
+/* $Id: xm_dd.c,v 1.6 2000/11/16 21:05:40 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "state.h"
 #include "depth.h"
 #include "macros.h"
-#include "vb.h"
 #include "types.h"
 #include "xmesaP.h"
 #include "extensions.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
 
 /*
  * Return the size (width,height of the current color buffer.
@@ -871,6 +871,7 @@ void xmesa_update_state( GLcontext *ctx )
     */
    _swrast_InvalidateState( ctx, ctx->NewState );
    _swsetup_InvalidateState( ctx, ctx->NewState );
+   _tnl_InvalidateState( ctx, ctx->NewState );
 
 
    /* setup pointers to front and back buffer clear functions */
index 9b5386caa6e26af7bd9649b0b1adf51a7e10ddc1..0513d045abc1859280e6842511b16c068616e316 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: xm_line.c,v 1.9 2000/11/14 17:40:15 brianp Exp $ */
+/* $Id: xm_line.c,v 1.10 2000/11/16 21:05:40 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -35,7 +35,6 @@
 #include "glxheader.h"
 #include "depth.h"
 #include "macros.h"
-#include "vb.h"
 #include "types.h"
 #include "xmesaP.h"
 
index 18f7de4f385223aeea9f23d2df139a8227b4aa8f..0d4eaab1c6d17b71f6ae74a3b647402b46d8b05f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: xm_span.c,v 1.2 2000/11/14 17:40:15 brianp Exp $ */
+/* $Id: xm_span.c,v 1.3 2000/11/16 21:05:40 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -32,7 +32,6 @@
 #include "state.h"
 #include "depth.h"
 #include "macros.h"
-#include "vb.h"
 #include "types.h"
 #include "xmesaP.h"
 #include "extensions.h"
index a25d58092b8dfb2ed6c957f10018cd36202d327e..0badaede8c61422ecb298ab9738c86b53271a3b5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: xm_tri.c,v 1.9 2000/11/14 17:40:15 brianp Exp $ */
+/* $Id: xm_tri.c,v 1.10 2000/11/16 21:05:40 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -35,7 +35,6 @@
 #include "glxheader.h"
 #include "depth.h"
 #include "macros.h"
-#include "vb.h"
 #include "types.h"
 #include "xmesaP.h"
 
@@ -1411,7 +1410,7 @@ static void flat_LOOKUP8_triangle( GLcontext *ctx,
 
 
 #ifdef DEBUG
-void
+static void
 _xmesa_print_triangle_func( swrast_tri_func triFunc )
 {
    printf("XMesa tri func = ");
index 533e0c32d9509717950b5252b43fbe9c367b8028..acec47b09ca90489b8ce05e4366b86429abfd3a6 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.32 2000/11/11 19:09:29 brianp Exp $
+# $Id: Makefile.X11,v 1.33 2000/11/16 21:05:34 keithw Exp $
 
 # Mesa 3-D graphics library
 # Version:  3.5
@@ -21,10 +21,31 @@ LIBDIR = ../lib
 
 
 CORE_SOURCES = \
+       tnl/t_bbox.c \
+       tnl/t_clip.c \
+       tnl/t_context.c \
+       tnl/t_cva.c \
+       tnl/t_debug.c \
+       tnl/t_dlist.c \
+       tnl/t_eval.c \
+       tnl/t_fog.c \
+       tnl/t_light.c \
+       tnl/t_pipeline.c \
+       tnl/t_rect.c \
+       tnl/t_shade.c \
+       tnl/t_stages.c \
+       tnl/t_texture.c \
+       tnl/t_trans_elt.c \
+       tnl/t_varray.c \
+       tnl/t_vb.c \
+       tnl/t_vbcull.c \
+       tnl/t_vbfill.c \
+       tnl/t_vbindirect.c \
+       tnl/t_vbrender.c \
+       tnl/t_vbxform.c \
        accum.c \
        alpha.c \
        attrib.c \
-       bbox.c \
        bitmap.c \
        blend.c \
        buffers.c \
@@ -34,8 +55,7 @@ CORE_SOURCES = \
        context.c \
        convolve.c \
        copypix.c \
-       cva.c \
-       debug_xform.c \
+       debug.c \
        depth.c \
        dispatch.c \
        dlist.c \
@@ -64,7 +84,6 @@ CORE_SOURCES = \
        matrix.c \
        mem.c \
        mmath.c \
-       pipeline.c \
        pixel.c \
        pixeltex.c \
        points.c \
@@ -73,8 +92,6 @@ CORE_SOURCES = \
        readpix.c \
        rect.c \
        scissor.c \
-       shade.c \
-       stages.c \
        state.c \
        stencil.c \
        teximage.c \
@@ -82,18 +99,8 @@ CORE_SOURCES = \
        texstate.c \
        texture.c \
        texutil.c \
-       translate.c \
        varray.c \
-       vb.c \
-       vbcull.c \
-       vbfill.c \
-       vbindirect.c \
-       vbrender.c \
-       vbxform.c \
-       vector.c \
-       vertices.c \
        winpos.c \
-       xform.c \
        X86/x86.c \
        X86/common_x86.c \
        X86/3dnow.c \
@@ -129,9 +136,13 @@ CORE_SOURCES = \
        swrast/s_zoom.c \
        swrast_setup/ss_context.c \
        swrast_setup/ss_triangle.c \
-       swrast_setup/ss_vb.c 
-
-
+       swrast_setup/ss_vb.c \
+       math/m_debug_xform.c \
+       math/m_matrix.c \
+       math/m_translate.c \
+       math/m_vector.c \
+       math/m_vertices.c \
+       math/m_xform.c  
 
 
 
index 66557b1066baf03b02af4401ea2bb1e935e283a0..b6c5174def79a6e5d892fb20815d85042d395e34 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: attrib.c,v 1.33 2000/11/05 18:40:57 keithw Exp $ */
+/* $Id: attrib.c,v 1.34 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -136,6 +136,9 @@ _mesa_PushAttrib(GLbitfield mask)
 
    if (mask & GL_CURRENT_BIT) {
       struct gl_current_attrib *attr;
+
+      FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
+
       attr = MALLOC_STRUCT( gl_current_attrib );
       MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
       newnode = new_attrib_node( GL_CURRENT_BIT );
@@ -612,6 +615,7 @@ _mesa_PopAttrib(void)
             }
             break;
          case GL_CURRENT_BIT:
+           FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
             MEMCPY( &ctx->Current, attr->data,
                    sizeof(struct gl_current_attrib) );
             break;
index 244753020b161f9d272c41dd6cf8bf2d2e8c6ad2..77d1281405595bac2c44abcca013350c370a2fa7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: clip.c,v 1.14 2000/11/13 20:02:56 keithw Exp $ */
+/* $Id: clip.c,v 1.15 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #else
 #include "glheader.h"
 #include "clip.h"
-#include "colormac.h"
 #include "context.h"
 #include "macros.h"
-#include "matrix.h"
 #include "mmath.h"
 #include "types.h"
-#include "vb.h"
-#include "xform.h"
-#endif
-
-
-
-
-#define CLIP_RGBA0    0x1
-#define CLIP_RGBA1    0x2
-#define CLIP_TEX0     0x4
-#define CLIP_TEX1     0x8
-#define CLIP_INDEX0   0x10
-#define CLIP_INDEX1   0x20
-#define CLIP_FOG_COORD 0x40
-
-
-/* Linear interpolation between A and B: */
-#define LINTERP( T, A, B )   ( (A) + (T) * ( (B) - (A) ) )
-
-
-
-#define INTERP_SZ( t, vec, to, a, b, sz )                      \
-do {                                                           \
-   switch (sz) {                                               \
-   case 4: vec[to][3] = LINTERP( t, vec[a][3], vec[b][3] );    \
-   case 3: vec[to][2] = LINTERP( t, vec[a][2], vec[b][2] );    \
-   case 2: vec[to][1] = LINTERP( t, vec[a][1], vec[b][1] );    \
-   case 1: vec[to][0] = LINTERP( t, vec[a][0], vec[b][0] );    \
-   }                                                           \
-} while(0)
-   
-
-static clip_interp_func clip_interp_tab[0x80]; 
-
-#define IND 0
-#define NAME clip_nil
-#include "interp_tmp.h"
-
-#define IND (CLIP_RGBA0)
-#define NAME clipRGBA0
-#include "interp_tmp.h"
-
-#define IND (CLIP_RGBA0|CLIP_RGBA1)
-#define NAME clipRGBA0_RGBA1
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX0|CLIP_RGBA0)
-#define NAME clipTEX0_RGBA0
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1)
-#define NAME clipTEX0_RGBA0_RGBA1
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0)
-#define NAME clipTEX1_TEX0_RGBA0
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX0)
-#define NAME clipTEX0
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX1|CLIP_TEX0)
-#define NAME clipTEX1_TEX0
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1)
-#define NAME clipTEX1_TEX0_RGBA0_RGBA1
-#include "interp_tmp.h"
-
-#define IND (CLIP_INDEX0)
-#define NAME clipINDEX0
-#include "interp_tmp.h"
-
-#define IND (CLIP_INDEX0|CLIP_INDEX1)
-#define NAME clipINDEX0_INDEX1
-#include "interp_tmp.h"
-
-#define IND (CLIP_FOG_COORD)
-#define NAME clip_FOG
-#include "interp_tmp.h"
-
-#define IND (CLIP_RGBA0|CLIP_FOG_COORD)
-#define NAME clipRGBA0_FOG
-#include "interp_tmp.h"
-
-#define IND (CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD)
-#define NAME clipRGBA0_RGBA1_FOG
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD)
-#define NAME clipTEX0_RGBA0_FOG
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD)
-#define NAME clipTEX0_RGBA0_RGBA1_FOG
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD)
-#define NAME clipTEX1_TEX0_RGBA0_FOG
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX0|CLIP_FOG_COORD)
-#define NAME clipTEX0_FOG
-#include "interp_tmp.h"
 
-#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_FOG_COORD)
-#define NAME clipTEX1_TEX0_FOG
-#include "interp_tmp.h"
-
-#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD)
-#define NAME clipTEX1_TEX0_RGBA0_RGBA1_FOG
-#include "interp_tmp.h"
+#include "math/m_xform.h"
+#include "math/m_matrix.h"
+#endif
 
-#define IND (CLIP_INDEX0|CLIP_FOG_COORD)
-#define NAME clipINDEX0_FOG
-#include "interp_tmp.h"
 
-#define IND (CLIP_INDEX0|CLIP_INDEX1|CLIP_FOG_COORD)
-#define NAME clipINDEX0_INDEX1_FOG
-#include "interp_tmp.h"
 
 
 
@@ -173,12 +56,6 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq )
    GET_CURRENT_CONTEXT(ctx);
    GLint p;
    GLfloat equation[4];
-
-   equation[0] = eq[0];
-   equation[1] = eq[1];
-   equation[2] = eq[2];
-   equation[3] = eq[3];
-
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClipPlane");
 
    p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
@@ -187,6 +64,11 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq )
       return;
    }
 
+   equation[0] = eq[0];
+   equation[1] = eq[1];
+   equation[2] = eq[2];
+   equation[3] = eq[3];
+
    /*
     * The equation is transformed by the transpose of the inverse of the
     * current modelview matrix and stored in the resulting eye coordinates.
@@ -195,17 +77,21 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq )
     * clipping now takes place.  The clip-space equations are recalculated
     * whenever the projection matrix changes.
     */
-   if (ctx->ModelView.flags & MAT_DIRTY_ALL_OVER) {
-      gl_matrix_analyze( &ctx->ModelView );
-   }
+   if (ctx->ModelView.flags & MAT_DIRTY
+      _math_matrix_analyze( &ctx->ModelView );
+
    gl_transform_vector( ctx->Transform.EyeUserPlane[p], equation,
                        ctx->ModelView.inv );
 
 
+   /* Update derived state.  This state also depends on the projection
+    * matrix, and is recalculated on changes to the projection matrix by
+    * code in gl_update_state().
+    */
    if (ctx->Transform.ClipEnabled[p]) {
-      if (ctx->ProjectionMatrix.flags & MAT_DIRTY_ALL_OVER) {
-        gl_matrix_analyze( &ctx->ProjectionMatrix );
-      }
+      if (ctx->ProjectionMatrix.flags & MAT_DIRTY
+        _math_matrix_analyze( &ctx->ProjectionMatrix );
+      
       gl_transform_vector( ctx->Transform._ClipUserPlane[p], 
                           ctx->Transform.EyeUserPlane[p], 
                           ctx->ProjectionMatrix.inv );
@@ -235,268 +121,3 @@ _mesa_GetClipPlane( GLenum plane, GLdouble *equation )
    equation[2] = (GLdouble) ctx->Transform.EyeUserPlane[p][2];
    equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3];
 }
-
-
-
-
-/**********************************************************************/
-/*                         View volume clipping.                      */
-/**********************************************************************/
-
-
-/*
- * Clip a point against the view volume.
- * Input:  v - vertex-vector describing the point to clip
- * Return:  0 = outside view volume
- *          1 = inside view volume
- */
-GLuint gl_viewclip_point( const GLfloat v[] )
-{
-   if (   v[0] > v[3] || v[0] < -v[3]
-       || v[1] > v[3] || v[1] < -v[3]
-       || v[2] > v[3] || v[2] < -v[3] ) {
-      return 0;
-   }
-   else {
-      return 1;
-   }
-}
-
-/*
- * Clip a point against the user clipping planes.
- * Input:  v - vertex-vector describing the point to clip.
- * Return:  0 = point was clipped
- *          1 = point not clipped
- */
-GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] )
-{
-   GLuint p;
-
-   for (p=0;p<MAX_CLIP_PLANES;p++) {
-      if (ctx->Transform.ClipEnabled[p]) {
-        GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0]
-                    + v[1] * ctx->Transform._ClipUserPlane[p][1]
-                    + v[2] * ctx->Transform._ClipUserPlane[p][2]
-                    + v[3] * ctx->Transform._ClipUserPlane[p][3];
-         if (dot < 0.0F) {
-            return 0;
-         }
-      }
-   }
-
-   return 1;
-}
-
-
-
-
-#if 0
-#define NEGATIVE(x) ((*(int *)&x)<0)
-#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
-#else
-#define NEGATIVE(x) (x < 0)
-#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
-#endif
-
-
-static clip_poly_func gl_poly_clip_tab[2][5];
-static clip_line_func gl_line_clip_tab[2][5];
-
-#define W(i) coord[i][3]
-#define Z(i) coord[i][2]
-#define Y(i) coord[i][1]
-#define X(i) coord[i][0]
-#define SIZE 4
-#define IND 0
-#define TAG(x) x##_4
-#include "clip_funcs.h"
-
-#define W(i) 1.0
-#define Z(i) coord[i][2]
-#define Y(i) coord[i][1]
-#define X(i) coord[i][0]
-#define SIZE 3
-#define IND 0
-#define TAG(x) x##_3
-#include "clip_funcs.h"
-
-#define W(i) 1.0
-#define Z(i) 0.0
-#define Y(i) coord[i][1]
-#define X(i) coord[i][0]
-#define SIZE 2
-#define IND 0
-#define TAG(x) x##_2
-#include "clip_funcs.h"
-
-#define W(i) coord[i][3]
-#define Z(i) coord[i][2]
-#define Y(i) coord[i][1]
-#define X(i) coord[i][0]
-#define SIZE 4
-#define IND CLIP_TAB_EDGEFLAG
-#define TAG(x) x##_4_edgeflag
-#include "clip_funcs.h"
-
-#define W(i) 1.0
-#define Z(i) coord[i][2]
-#define Y(i) coord[i][1]
-#define X(i) coord[i][0]
-#define SIZE 3
-#define IND CLIP_TAB_EDGEFLAG
-#define TAG(x) x##_3_edgeflag
-#include "clip_funcs.h"
-
-#define W(i) 1.0
-#define Z(i) 0.0
-#define Y(i) coord[i][1]
-#define X(i) coord[i][0]
-#define SIZE 2
-#define IND CLIP_TAB_EDGEFLAG
-#define TAG(x) x##_2_edgeflag
-#include "clip_funcs.h"
-
-
-
-
-void gl_update_clipmask( GLcontext *ctx )
-{
-   GLuint mask = 0;
-
-   if (ctx->Visual.RGBAflag) 
-   {
-      mask |= CLIP_RGBA0;
-      
-      if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_SEPERATE_SPECULAR))
-         mask |= CLIP_RGBA1;
-
-      if (ctx->Texture._ReallyEnabled & 0xf0)
-        mask |= CLIP_TEX1|CLIP_TEX0;
-
-      if (ctx->Texture._ReallyEnabled & 0xf)
-        mask |= CLIP_TEX0;
-   }
-   else if (ctx->Light.ShadeModel==GL_SMOOTH) 
-   {
-      mask |= CLIP_INDEX0;
-      
-      if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) 
-        mask |= CLIP_INDEX1;
-   }
-
-   if (ctx->Fog.Enabled)
-      mask |= CLIP_FOG_COORD;
-   
-   ctx->_ClipInterpFunc = clip_interp_tab[mask];
-   ctx->_poly_clip_tab = gl_poly_clip_tab[0];
-   ctx->_line_clip_tab = gl_line_clip_tab[0];
-
-   if (ctx->_TriangleCaps & DD_TRI_UNFILLED) {
-      ctx->_poly_clip_tab = gl_poly_clip_tab[1];
-      ctx->_line_clip_tab = gl_line_clip_tab[0];
-   } 
-}
-
-
-#define USER_CLIPTEST(NAME, SZ)                                                \
-static void NAME( struct vertex_buffer *VB )                           \
-{                                                                      \
-   GLcontext *ctx = VB->ctx;                                           \
-   GLubyte *clipMask = VB->ClipMask;                                   \
-   GLubyte *userClipMask = VB->UserClipMask;                           \
-   GLuint start = VB->Start;                                           \
-   GLuint count = VB->Count;                                           \
-   GLuint p, i;                                                                \
-   GLubyte bit;                                                                \
-                                                                       \
-                                                                       \
-   for (bit = 1, p = 0; p < MAX_CLIP_PLANES ; p++, bit *=2)            \
-      if (ctx->Transform.ClipEnabled[p]) {                             \
-        GLuint nr = 0;                                                 \
-        const GLfloat a = ctx->Transform._ClipUserPlane[p][0];         \
-        const GLfloat b = ctx->Transform._ClipUserPlane[p][1];         \
-        const GLfloat c = ctx->Transform._ClipUserPlane[p][2];         \
-        const GLfloat d = ctx->Transform._ClipUserPlane[p][3];         \
-         GLfloat *coord = VB->ClipPtr->start;                          \
-         GLuint stride = VB->ClipPtr->stride;                          \
-                                                                       \
-        for (i = start ; i < count ; i++, STRIDE_F(coord, stride)) {   \
-           GLfloat dp = coord[0] * a + coord[1] * b;                   \
-           if (SZ > 2) dp += coord[2] * c;                             \
-           if (SZ > 3) dp += coord[3] * d; else dp += d;               \
-                                                                       \
-           if (dp < 0) {                                               \
-              clipMask[i] |= CLIP_USER_BIT;                            \
-              userClipMask[i] |= bit;                                  \
-              nr++;                                                    \
-           }                                                           \
-        }                                                              \
-                                                                       \
-        if (nr > 0) {                                                  \
-           VB->ClipOrMask |= CLIP_USER_BIT;                            \
-           VB->CullMode |= CLIP_MASK_ACTIVE;                           \
-           if (nr == count - start) {                                  \
-              VB->ClipAndMask |= CLIP_USER_BIT;                        \
-              VB->Culled = 1;                                          \
-              return;                                                  \
-           }                                                           \
-        }                                                              \
-      }                                                                        \
-}
-
-
-USER_CLIPTEST(userclip2, 2)                   
-USER_CLIPTEST(userclip3, 3)                   
-USER_CLIPTEST(userclip4, 4)                   
-
-static void (*(usercliptab[5]))( struct vertex_buffer * ) = {
-   0,
-   0,
-   userclip2,
-   userclip3,
-   userclip4
-};
-
-void gl_user_cliptest( struct vertex_buffer *VB )
-{
-   usercliptab[VB->ClipPtr->size]( VB );
-}
-
-
-void gl_init_clip(void)
-{
-   init_clip_funcs_4();
-   init_clip_funcs_3();
-   init_clip_funcs_2();
-
-   init_clip_funcs_4_edgeflag();
-   init_clip_funcs_3_edgeflag();
-   init_clip_funcs_2_edgeflag();
-
-   clip_interp_tab[0] = clip_nil;
-   clip_interp_tab[CLIP_RGBA0] = clipRGBA0;
-   clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1] = clipRGBA0_RGBA1;
-   clip_interp_tab[CLIP_TEX0|CLIP_RGBA0] = clipTEX0_RGBA0;
-   clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = clipTEX0_RGBA0_RGBA1;
-   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0] = clipTEX1_TEX0_RGBA0;
-   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = 
-      clipTEX1_TEX0_RGBA0_RGBA1;
-   clip_interp_tab[CLIP_TEX0] = clipTEX0;
-   clip_interp_tab[CLIP_TEX1|CLIP_TEX0] = clipTEX1_TEX0;
-   clip_interp_tab[CLIP_INDEX0] = clipINDEX0;
-   clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1] = clipINDEX0_INDEX1;
-
-   clip_interp_tab[CLIP_FOG_COORD] = clip_FOG;
-   clip_interp_tab[CLIP_RGBA0|CLIP_FOG_COORD] = clipRGBA0_FOG;
-   clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = clipRGBA0_RGBA1_FOG;
-   clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD] = clipTEX0_RGBA0_FOG;
-   clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = clipTEX0_RGBA0_RGBA1_FOG;
-   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD] = clipTEX1_TEX0_RGBA0_FOG;
-   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = 
-      clipTEX1_TEX0_RGBA0_RGBA1_FOG;
-   clip_interp_tab[CLIP_TEX0|CLIP_FOG_COORD] = clipTEX0_FOG;
-   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_FOG_COORD] = clipTEX1_TEX0_FOG;
-   clip_interp_tab[CLIP_INDEX0|CLIP_FOG_COORD] = clipINDEX0_FOG;
-   clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1|CLIP_FOG_COORD] = clipINDEX0_INDEX1_FOG;
-}
-
index abf2f7e9ce0abb99d8135b01e4a3e17300bf8322..a44d6d0fe12c2f5bb2410be90c7f553d1da52d06 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: clip.h,v 1.3 1999/11/11 01:22:25 brianp Exp $ */
+/* $Id: clip.h,v 1.4 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #ifndef CLIP_H
 #define CLIP_H
 
-
 #include "types.h"
 
-
-
-#ifdef DEBUG
-#  define GL_VIEWCLIP_POINT( V )   gl_viewclip_point( V )
-#else
-#  define GL_VIEWCLIP_POINT( V )                       \
-     (    (V)[0] <= (V)[3] && (V)[0] >= -(V)[3]                \
-       && (V)[1] <= (V)[3] && (V)[1] >= -(V)[3]                \
-       && (V)[2] <= (V)[3] && (V)[2] >= -(V)[3] )
-#endif
-
-
-
-
-#define CLIP_TAB_EDGEFLAG 1
-
-extern void gl_init_clip(void);
-
-
-extern GLuint gl_viewclip_point( const GLfloat v[] );
-
-
-
-extern GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] );
-
-
-extern void gl_user_cliptest( struct vertex_buffer *VB );
-
-
 extern void _mesa_ClipPlane( GLenum plane, const GLdouble *equation );
 
 extern void _mesa_GetClipPlane( GLenum plane, GLdouble *equation );
 
-
-/*
- * Clipping interpolation functions
- */
-
-extern void gl_clip_interp_all( struct vertex_buffer *VB, 
-                                GLuint dst, GLfloat t, GLuint in, GLuint out );
-
-extern void gl_clip_interp_color_tex( struct vertex_buffer *VB,
-                                GLuint dst, GLfloat t, GLuint in, GLuint out );
-
-extern void gl_clip_interp_tex( struct vertex_buffer *VB, 
-                                GLuint dst, GLfloat t, GLuint in, GLuint out );
-
-extern void gl_clip_interp_color( struct vertex_buffer *VB,
-                                GLuint dst, GLfloat t, GLuint in, GLuint out );
-
-extern void gl_clip_interp_none( struct vertex_buffer *VB,
-                                GLuint dst, GLfloat t, GLuint in, GLuint out );
-
-
-extern void gl_update_userclip( GLcontext *ctx );
-
-extern void gl_update_clipmask( GLcontext *ctx );
-
 #endif
index b69f52fbbbf94d15ff75707d521e871706d94119..57d4350cc49b714b08740e2a7348a6d5b904d385 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: colormac.h,v 1.2 2000/10/29 18:12:14 brianp Exp $ */
+/* $Id: colormac.h,v 1.3 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -38,7 +38,8 @@
 #include "config.h"
 #include "macros.h"
 #include "mmath.h"
-
+/* Do not reference types.h from this file.
+ */
 
 
 /*
index aff60fb5073e3078b7680b9715737fffff0dd459..c0e75e929848570293f9369defaac812f1ae63f2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: context.c,v 1.105 2000/11/15 16:38:40 brianp Exp $ */
+/* $Id: context.c,v 1.106 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -33,7 +33,6 @@
 #include "clip.h"
 #include "colortab.h"
 #include "context.h"
-#include "cva.h"
 #include "dlist.h"
 #include "eval.h"
 #include "enums.h"
 #include "imports.h"
 #include "light.h"
 #include "macros.h"
-#include "matrix.h"
 #include "mem.h"
 #include "mmath.h"
-#include "pipeline.h"
-#include "shade.h"
 #include "simple_list.h"
-#include "stages.h"
 #include "state.h"
-#include "translate.h"
 #include "teximage.h"
 #include "texobj.h"
 #include "texture.h"
 #include "types.h"
 #include "varray.h"
-#include "vb.h"
-#include "vbrender.h"
-#include "vbxform.h"
-#include "vertices.h"
-#include "xform.h"
+
+#include "math/m_translate.h"
+#include "math/m_vertices.h"
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
+#include "math/math.h"
 #endif
 
 #if defined(MESA_TRACE)
 #endif
 
 
+#ifndef MESA_VERBOSE
+int MESA_VERBOSE = 0 
+/*                 | VERBOSE_PIPELINE */
+/*                 | VERBOSE_IMMEDIATE */
+/*                 | VERBOSE_VARRAY */
+/*                 | VERBOSE_TEXTURE */
+/*                 | VERBOSE_API */
+/*                 | VERBOSE_DRIVER */
+/*                 | VERBOSE_STATE */
+/*                 | VERBOSE_CULL */
+/*                 | VERBOSE_DISPLAY_LIST */
+;
+#endif
+
+#ifndef MESA_DEBUG_FLAGS
+int MESA_DEBUG_FLAGS = 0 
+/*                 | DEBUG_ALWAYS_FLUSH */
+;
+#endif
 
 /**********************************************************************/
 /*****       OpenGL SI-style interface (new in Mesa 3.5)          *****/
@@ -145,12 +159,6 @@ __glCoreNopDispatch(void)
 /**********************************************************************/
 
 
-#if !defined(THREADS)
-
-struct immediate *_mesa_CurrentInput = NULL;
-
-#endif
-
 
 /**********************************************************************/
 /***** GL Visual allocation/destruction                           *****/
@@ -442,17 +450,10 @@ one_time_init( void )
       assert( sizeof(GLushort) >= 2 );
       assert( sizeof(GLuint) >= 4 );
 
-      gl_init_clip();
-      gl_init_eval();
-      _mesa_init_math();
       gl_init_lists();
-      gl_init_shade();
-      gl_init_texture();
-      gl_init_transformation();
-      gl_init_translate();
-      gl_init_vbrender();
-      gl_init_vbxform();
-      gl_init_vertices();
+
+      _mesa_init_math();
+      _math_init();
 
       if (getenv("MESA_DEBUG")) {
          _glapi_noop_enable_warnings(GL_TRUE);
@@ -809,45 +810,43 @@ init_attrib_groups( GLcontext *ctx )
    ctx->Const.NumCompressedTextureFormats = 0;
 
    /* Modelview matrix */
-   gl_matrix_ctr( &ctx->ModelView );
-   gl_matrix_alloc_inv( &ctx->ModelView );
+   _math_matrix_ctr( &ctx->ModelView );
+   _math_matrix_alloc_inv( &ctx->ModelView );
 
    ctx->ModelViewStackDepth = 0;
    for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) {
-      gl_matrix_ctr( &ctx->ModelViewStack[i] );
-      gl_matrix_alloc_inv( &ctx->ModelViewStack[i] );
+      _math_matrix_ctr( &ctx->ModelViewStack[i] );
+      _math_matrix_alloc_inv( &ctx->ModelViewStack[i] );
    }
 
    /* Projection matrix - need inv for user clipping in clip space*/
-   gl_matrix_ctr( &ctx->ProjectionMatrix );
-   gl_matrix_alloc_inv( &ctx->ProjectionMatrix );
-
-   gl_matrix_ctr( &ctx->_ModelProjectMatrix );
+   _math_matrix_ctr( &ctx->ProjectionMatrix );
+   _math_matrix_alloc_inv( &ctx->ProjectionMatrix );
 
    ctx->ProjectionStackDepth = 0;
-   ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */
-   ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */
-
    for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) {
-      gl_matrix_ctr( &ctx->ProjectionStack[i] );
-      gl_matrix_alloc_inv( &ctx->ProjectionStack[i] );
+      _math_matrix_ctr( &ctx->ProjectionStack[i] );
+      _math_matrix_alloc_inv( &ctx->ProjectionStack[i] );
    }
 
+   /* Derived ModelProject matrix */
+   _math_matrix_ctr( &ctx->_ModelProjectMatrix );
+
    /* Texture matrix */
    for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-      gl_matrix_ctr( &ctx->TextureMatrix[i] );
+      _math_matrix_ctr( &ctx->TextureMatrix[i] );
       ctx->TextureStackDepth[i] = 0;
       for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) {
-         gl_matrix_ctr( &ctx->TextureStack[i][j] );
+         _math_matrix_ctr( &ctx->TextureStack[i][j] );
          ctx->TextureStack[i][j].inv = 0;
       }
    }
 
    /* Color matrix */
-   gl_matrix_ctr(&ctx->ColorMatrix);
+   _math_matrix_ctr(&ctx->ColorMatrix);
    ctx->ColorStackDepth = 0;
    for (j = 0; j < MAX_COLOR_STACK_DEPTH - 1; j++) {
-      gl_matrix_ctr(&ctx->ColorStack[j]);
+      _math_matrix_ctr(&ctx->ColorStack[j]);
    }
 
    /* Accumulate buffer group */
@@ -893,19 +892,6 @@ init_attrib_groups( GLcontext *ctx )
    ctx->Current.RasterPosValid = GL_TRUE;
    ctx->Current.EdgeFlag = GL_TRUE;
    ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 );
-   ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1);
-
-   ctx->Current.Flag = (VERT_NORM |
-                        VERT_INDEX |
-                        VERT_RGBA |
-                        VERT_SPEC_RGB |
-                        VERT_FOG_COORD |
-                        VERT_EDGE |
-                        VERT_TEX0_12 |
-                        VERT_TEX1_12 |
-                        VERT_TEX2_12 |
-                        VERT_TEX3_12 |
-                        VERT_MATERIAL);
 
    init_fallback_arrays( ctx );
 
@@ -1023,15 +1009,9 @@ init_attrib_groups( GLcontext *ctx )
    ctx->MinMax.Min[BCOMP] = 1000;    ctx->MinMax.Max[BCOMP] = -1000;
    ctx->MinMax.Min[ACOMP] = 1000;    ctx->MinMax.Max[ACOMP] = -1000;
 
-   /* Pipeline */
-   gl_pipeline_init( ctx );
-   gl_cva_init( ctx );
-
    /* Extensions */
    gl_extensions_ctr( ctx );
 
-   ctx->AllowVertexCull = CLIP_CULLED_BIT;
-
    /* Lighting group */
    for (i=0;i<MAX_LIGHTS;i++) {
       init_light( &ctx->Light.Light[i], i );
@@ -1227,7 +1207,7 @@ init_attrib_groups( GLcontext *ctx )
    ctx->Viewport.Height = 0;
    ctx->Viewport.Near = 0.0;
    ctx->Viewport.Far = 1.0;
-   gl_matrix_ctr(&ctx->Viewport._WindowMap);
+   _math_matrix_ctr(&ctx->Viewport._WindowMap);
 
 #define Sz 10
 #define Tz 14
@@ -1454,12 +1434,6 @@ _mesa_initialize_context( GLcontext *ctx,
    ctx->Visual = *visual;
    ctx->DrawBuffer = NULL;
    ctx->ReadBuffer = NULL;
-
-   ctx->VB = gl_vb_create_for_immediate( ctx );
-   if (!ctx->VB) {
-      return GL_FALSE;
-   }
-   ctx->input = ctx->VB->IM;
    
    if (share_list) {
       /* share the group of display lists of another context */
@@ -1469,7 +1443,6 @@ _mesa_initialize_context( GLcontext *ctx,
       /* allocate new group of display lists */
       ctx->Shared = alloc_shared_state();
       if (!ctx->Shared) {
-         ALIGN_FREE( ctx->VB );
          return GL_FALSE;
       }
    }
@@ -1479,9 +1452,6 @@ _mesa_initialize_context( GLcontext *ctx,
 
    init_attrib_groups( ctx );
 
-   gl_reset_vb( ctx->VB );
-   gl_reset_input( ctx );
-
    if (visual->DBflag) {
       ctx->Color.DrawBuffer = GL_BACK;
       ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
@@ -1499,7 +1469,6 @@ _mesa_initialize_context( GLcontext *ctx,
 
    if (!alloc_proxy_textures(ctx)) {
       free_shared_state(ctx, ctx->Shared);
-      ALIGN_FREE( ctx->VB );
       return GL_FALSE;
    }
 
@@ -1526,7 +1495,6 @@ _mesa_initialize_context( GLcontext *ctx,
    ctx->Save = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
    if (!ctx->Exec || !ctx->Save) {
       free_shared_state(ctx, ctx->Shared);
-      ALIGN_FREE( ctx->VB );
       if (ctx->Exec)
          FREE( ctx->Exec );
    }
@@ -1541,7 +1509,6 @@ _mesa_initialize_context( GLcontext *ctx,
        or should we just trap in NewTrace (currently done)? */
    if (!(ctx->TraceCtx)) {
       free_shared_state(ctx, ctx->Shared);
-      ALIGN_FREE( ctx->VB );
       FREE( ctx->Exec );
       FREE( ctx->Save );
       return GL_FALSE;
@@ -1554,7 +1521,6 @@ _mesa_initialize_context( GLcontext *ctx,
 #if 0
    if (!(ctx->TraceCtx)) {
       free_shared_state(ctx, ctx->Shared);
-      ALIGN_FREE( ctx->VB );
       FREE( ctx->Exec );
       FREE( ctx->Save );
       FREE( ctx->TraceCtx );
@@ -1613,26 +1579,21 @@ _mesa_free_context_data( GLcontext *ctx )
       _mesa_make_current(NULL, NULL);
    }
 
-   gl_matrix_dtr( &ctx->ModelView );
+   _math_matrix_dtr( &ctx->ModelView );
    for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) {
-      gl_matrix_dtr( &ctx->ModelViewStack[i] );
+      _math_matrix_dtr( &ctx->ModelViewStack[i] );
    }
-   gl_matrix_dtr( &ctx->ProjectionMatrix );
+   _math_matrix_dtr( &ctx->ProjectionMatrix );
    for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) {
-      gl_matrix_dtr( &ctx->ProjectionStack[i] );
+      _math_matrix_dtr( &ctx->ProjectionStack[i] );
    }
    for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-      gl_matrix_dtr( &ctx->TextureMatrix[i] );
+      _math_matrix_dtr( &ctx->TextureMatrix[i] );
       for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) {
-         gl_matrix_dtr( &ctx->TextureStack[i][j] );
+         _math_matrix_dtr( &ctx->TextureStack[i][j] );
       }
    }
 
-   if (ctx->input != ctx->VB->IM)
-      gl_immediate_free( ctx->input );
-
-   gl_vb_free( ctx->VB );
-
    _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
    ctx->Shared->RefCount--;
    assert(ctx->Shared->RefCount >= 0);
@@ -1696,12 +1657,6 @@ _mesa_free_context_data( GLcontext *ctx )
    _mesa_free_colortable_data( &ctx->PostColorMatrixColorTable );
    _mesa_free_colortable_data( &ctx->Texture.Palette );
 
-   /* Free cache of immediate buffers. */
-   while (ctx->nr_im_queued-- > 0) {
-      struct immediate * next = ctx->freed_im_queue->next;
-      ALIGN_FREE( ctx->freed_im_queue );
-      ctx->freed_im_queue = next;
-   }
    gl_extensions_dtr(ctx);
 
    FREE(ctx->Exec);
@@ -1828,6 +1783,29 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer )
 }
 
 
+static void print_info( void )
+{
+   fprintf(stderr, "Mesa GL_VERSION = %s\n", 
+          (char *) _mesa_GetString(GL_VERSION));
+   fprintf(stderr, "Mesa GL_RENDERER = %s\n", 
+          (char *) _mesa_GetString(GL_RENDERER));
+   fprintf(stderr, "Mesa GL_VENDOR = %s\n", 
+          (char *) _mesa_GetString(GL_VENDOR));
+   fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", 
+          (char *) _mesa_GetString(GL_EXTENSIONS));
+#if defined(THREADS)
+   fprintf(stderr, "Mesa thread-safe: YES\n");
+#else
+   fprintf(stderr, "Mesa thread-safe: NO\n");
+#endif
+#if defined(USE_X86_ASM)
+   fprintf(stderr, "Mesa x86-optimized: YES\n");
+#else
+   fprintf(stderr, "Mesa x86-optimized: NO\n");
+#endif
+}
+
+
 /*
  * Bind the given context to the given draw-buffer and read-buffer
  * and make it the current context for this thread.
@@ -1836,23 +1814,8 @@ void
 _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
                      GLframebuffer *readBuffer )
 {
-#if 0
-   GLcontext *oldCtx = gl_get_context();
-
-   /* Flush the old context
-    */
-   if (oldCtx) {
-      ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "_mesa_make_current");
-
-      /* unbind frame buffers from context */
-      if (oldCtx->DrawBuffer) {
-         oldCtx->DrawBuffer = NULL;
-      }
-      if (oldCtx->ReadBuffer) {
-         oldCtx->ReadBuffer = NULL;
-      }
-   }
-#endif
+   if (MESA_VERBOSE) 
+      fprintf(stderr, "_mesa_make_current2()\n");
 
    /* We call this function periodically (just here for now) in
     * order to detect when multithreading has begun.
@@ -1861,47 +1824,36 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
 
    _glapi_set_context((void *) newCtx);
    ASSERT(_mesa_get_current_context() == newCtx);
-   if (newCtx) {
-      SET_IMMEDIATE(newCtx, newCtx->input);
-      _glapi_set_dispatch(newCtx->CurrentDispatch);
-   }
-   else {
+
+
+   if (!newCtx) {
       _glapi_set_dispatch(NULL);  /* none current */
    }
+   else {
+      _glapi_set_dispatch(newCtx->CurrentDispatch);
 
-   if (MESA_VERBOSE) fprintf(stderr, "_mesa_make_current()\n");
+      if (drawBuffer && readBuffer) {
+        /* TODO: check if newCtx and buffer's visual match??? */
+        newCtx->DrawBuffer = drawBuffer;
+        newCtx->ReadBuffer = readBuffer;
+        newCtx->NewState |= _NEW_BUFFERS;
+        /* gl_update_state( newCtx ); */
+      }
 
-   if (newCtx && drawBuffer && readBuffer) {
-      /* TODO: check if newCtx and buffer's visual match??? */
-      newCtx->DrawBuffer = drawBuffer;
-      newCtx->ReadBuffer = readBuffer;
-      newCtx->NewState |= _NEW_BUFFERS;
-      gl_update_state( newCtx );
-   }
+      if (newCtx->Driver.MakeCurrent) 
+        newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer );
 
-   /* We can use this to help debug user's problems.  Tell the to set
-    * the MESA_INFO env variable before running their app.  Then the
-    * first time each context is made current we'll print some useful
-    * information.
-    */
-   if (newCtx && newCtx->FirstTimeCurrent) {
-      if (getenv("MESA_INFO")) {
-         fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION));
-         fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER));
-         fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR));
-         fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS));
-#if defined(THREADS)
-         fprintf(stderr, "Mesa thread-safe: YES\n");
-#else
-         fprintf(stderr, "Mesa thread-safe: NO\n");
-#endif
-#if defined(USE_X86_ASM)
-         fprintf(stderr, "Mesa x86-optimized: YES\n");
-#else
-         fprintf(stderr, "Mesa x86-optimized: NO\n");
-#endif
+      /* We can use this to help debug user's problems.  Tell them to set
+       * the MESA_INFO env variable before running their app.  Then the
+       * first time each context is made current we'll print some useful
+       * information.
+       */
+      if (newCtx->FirstTimeCurrent) {
+        if (getenv("MESA_INFO")) {
+           print_info();
+        }
+        newCtx->FirstTimeCurrent = GL_FALSE;
       }
-      newCtx->FirstTimeCurrent = GL_FALSE;
    }
 }
 
@@ -1927,7 +1879,7 @@ _mesa_get_current_context( void )
 void
 _mesa_swapbuffers(GLcontext *ctx)
 {
-   FLUSH_VB( ctx, "swap buffers" );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
 }
 
 
index fe058c69d36328a1f2fdbea46c4d2149a24d5c5b..71ed19119ce3587fd85eb68427c3225c435e06be 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: context.h,v 1.20 2000/10/29 18:12:14 brianp Exp $ */
+/* $Id: context.h,v 1.21 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -169,33 +169,16 @@ _mesa_get_current_context(void);
 
 
 /*
- * Macros for fetching current context, input buffer, etc.
+ * Macros for fetching current context.
  */
 #ifdef THREADS
 
 #define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context())
 
-#define GET_IMMEDIATE  struct immediate *IM = ((GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()))->input
-
-#define SET_IMMEDIATE(ctx, im)         \
-do {                                   \
-   ctx->input = im;                    \
-} while (0)
-
 #else
 
-extern struct immediate *_mesa_CurrentInput;
-
 #define GET_CURRENT_CONTEXT(C)  GLcontext *C = (GLcontext *) _glapi_Context
 
-#define GET_IMMEDIATE struct immediate *IM = _mesa_CurrentInput
-
-#define SET_IMMEDIATE(ctx, im)         \
-do {                                   \
-   ctx->input = im;                    \
-   _mesa_CurrentInput = im;            \
-} while (0)
-
 #endif
 
 
index 9452a0e86c084a5f38162b878a5423947303072f..2c9a024842c3939b32803ffda77070092907c043 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dd.h,v 1.41 2000/11/14 17:40:13 brianp Exp $ */
+/* $Id: dd.h,v 1.42 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -34,7 +34,6 @@
 
 struct gl_pixelstore_attrib;
 struct vertex_buffer;
-struct immediate;
 struct gl_pipeline;
 struct gl_pipeline_stage;
 
@@ -122,6 +121,30 @@ struct gl_pipeline_stage;
 
 
 
+
+
+
+
+/* Point, line, triangle, quadrilateral and rectangle rasterizer
+ * functions.  These are specific to the tnl module and will shortly
+ * move to a driver interface specific to that module.
+ */
+typedef void (*points_func)( GLcontext *ctx, GLuint first, GLuint last );
+
+typedef void (*line_func)( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv );
+
+typedef void (*triangle_func)( GLcontext *ctx,
+                               GLuint v1, GLuint v2, GLuint v3, GLuint pv );
+
+typedef void (*quad_func)( GLcontext *ctx, GLuint v1, GLuint v2,
+                           GLuint v3, GLuint v4, GLuint pv );
+
+typedef void (*render_func)( struct vertex_buffer *VB, 
+                            GLuint start,
+                            GLuint count,
+                            GLuint parity );
+
+
 /*
  * Device Driver function table.
  */
@@ -138,12 +161,6 @@ struct dd_function_table {
     * NULL can be returned.
     */
 
-   GLuint UpdateStateNotify;
-   /*
-    * Tell mesa exactly when to call UpdateState.  This is a bitwise
-    * or of the _NEW_* flags defined in types.h. 
-    */
-   
    void (*UpdateState)( GLcontext *ctx );
    /*
     * UpdateState() is called whenver Mesa thinks the device driver should
@@ -327,13 +344,6 @@ struct dd_function_table {
     * the error value.
     */
 
-   void (*NearFar)( GLcontext *ctx, GLfloat nearVal, GLfloat farVal );
-   /*
-    * Called from glFrustum and glOrtho to tell device driver the
-    * near and far clipping plane Z values.  The 3Dfx driver, for example,
-    * uses this.
-    */
-
 
    /***
     *** For supporting hardware Z buffers:
@@ -744,14 +754,13 @@ struct dd_function_table {
 
 
    /***
-    *** Accelerated point, line, polygon, quad and rect functions:
+    *** Accelerated point, line, polygon and quad functions:
     ***/
 
    points_func   PointsFunc;
    line_func     LineFunc;
    triangle_func TriangleFunc;
    quad_func     QuadFunc;
-   rect_func     RectFunc;    
    
 
    /***
@@ -798,12 +807,7 @@ struct dd_function_table {
    /***
     *** NEW in Mesa 3.x
     ***/
-   void (*LightingSpaceChange)( GLcontext *ctx );
-   /* Notify driver that the special derived value _NeedEyeCoords has
-    * changed.  
-    */
    
-
    void (*RegisterVB)( struct vertex_buffer *VB );
    void (*UnregisterVB)( struct vertex_buffer *VB );
    /* When Mesa creates a new vertex buffer it calls Driver.RegisterVB()
@@ -814,35 +818,57 @@ struct dd_function_table {
     */
 
 
-   void (*ResetVB)( struct vertex_buffer *VB );
-   void (*ResetCvaVB)( struct vertex_buffer *VB, GLuint stages );
-   /* Do any reset operations necessary to the driver data associated
-    * with these vertex buffers.
-    */
 
-   GLuint RenderVectorFlags;
-   /* What do the render tables require of the vectors they deal
-    * with?  
+   GLboolean (*BuildPrecalcPipeline)( GLcontext *ctx );
+   GLboolean (*BuildEltPipeline)( GLcontext *ctx );
+   /* Perform the full pipeline build, or return false.
     */
 
-   GLuint (*RegisterPipelineStages)( struct gl_pipeline_stage *out,
-                                    const struct gl_pipeline_stage *in,
-                                    GLuint nr );
-   /* Register new pipeline stages, or modify existing ones.  See also
-    * the OptimizePipeline() functions.
+
+   /***
+    *** Support for multiple t&l engines
+    ***/
+
+#define FLUSH_INSIDE_BEGIN_END 0x1
+#define FLUSH_STORED_VERTICES  0x2
+#define FLUSH_UPDATE_CURRENT   0x4
+
+   GLuint NeedFlush;
+   /* Set by the driver-supplied t&l engine.  
+    * Bitflags defined above are set whenever 
+    *     - the engine *might* be inside a begin/end object.
+    *     - there *might* be buffered vertices to be flushed.
+    *     - the ctx->Current values *might* not be uptodate.
+    *
+    * The FlushVertices() call below may be used to resolve 
+    * these conditions.
     */
 
+   GLboolean (*FlushVertices)( GLcontext *ctx, GLuint flags );
+   /* If inside begin/end, returns GL_FALSE.  
+    * Otherwise, 
+    *   if (flags & FLUSH_STORED_VERTICES) flushes any buffered vertices,
+    *   if (flags & FLUSH_UPDATE_CURRENT) updates ctx->Current,
+    *   returns GL_TRUE. 
+    *
+    * Note that the default t&l engine never clears the
+    * FLUSH_UPDATE_CURRENT bit, even after performing the update.
+    */
 
-   GLboolean (*BuildPrecalcPipeline)( GLcontext *ctx );
-   GLboolean (*BuildEltPipeline)( GLcontext *ctx );
-   /* Perform the full pipeline build, or return false.
+   void (*LightingSpaceChange)( GLcontext *ctx );
+   /* Notify driver that the special derived value _NeedEyeCoords has
+    * changed.  
     */
 
+   void (*NewList)( GLcontext *ctx, GLuint list, GLenum mode );
+   void (*EndList)( GLcontext *ctx );
+   /* Let the t&l component know what is going on with display lists
+    * in time to make changes to dispatch tables, etc.
+    */
 
-   void (*OptimizePrecalcPipeline)( GLcontext *ctx, struct gl_pipeline *pipe );
-   void (*OptimizeImmediatePipeline)( GLcontext *ctx, struct gl_pipeline *pipe);
-   /* Check to see if a fast path exists for this combination of stages 
-    * in the precalc and immediate (elt) pipelines.
+   void (*MakeCurrent)( GLcontext *ctx, GLframebuffer *drawBuffer, 
+                       GLframebuffer *readBuffer );
+   /* Let the t&l component know when the context becomes current.
     */
 
 
@@ -898,6 +924,23 @@ struct dd_function_table {
    GLboolean (*GetFloatv)(GLcontext *ctx, GLenum pname, GLfloat *result);
    GLboolean (*GetIntegerv)(GLcontext *ctx, GLenum pname, GLint *result);
    GLboolean (*GetPointerv)(GLcontext *ctx, GLenum pname, GLvoid **result);
+
+
+   void (*VertexPointer)(GLcontext *ctx, GLint size, GLenum type, 
+                        GLsizei stride, const GLvoid *ptr);
+   void (*NormalPointer)(GLcontext *ctx, GLenum type, 
+                        GLsizei stride, const GLvoid *ptr);
+   void (*ColorPointer)(GLcontext *ctx, GLint size, GLenum type, 
+                       GLsizei stride, const GLvoid *ptr);
+   void (*FogCoordPointer)(GLcontext *ctx, GLenum type, 
+                          GLsizei stride, const GLvoid *ptr);
+   void (*IndexPointer)(GLcontext *ctx, GLenum type, 
+                       GLsizei stride, const GLvoid *ptr);
+   void (*SecondaryColorPointer)(GLcontext *ctx, GLint size, GLenum type, 
+                                GLsizei stride, const GLvoid *ptr);
+   void (*TexCoordPointer)(GLcontext *ctx, GLint size, GLenum type, 
+                          GLsizei stride, const GLvoid *ptr);
+   void (*EdgeFlagPointer)(GLcontext *ctx, GLsizei stride, const GLvoid *ptr);
 };
 
 
diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c
new file mode 100644 (file)
index 0000000..b467499
--- /dev/null
@@ -0,0 +1,89 @@
+#include "types.h"
+#include "debug.h"
+
+void gl_print_state( const char *msg, GLuint state )
+{
+   fprintf(stderr,
+          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+          msg,
+          state,
+          (state & _NEW_MODELVIEW)       ? "ctx->ModelView, " : "",
+          (state & _NEW_PROJECTION)      ? "ctx->Projection, " : "",
+          (state & _NEW_TEXTURE_MATRIX)  ? "ctx->TextureMatrix, " : "",
+          (state & _NEW_COLOR_MATRIX)    ? "ctx->ColorMatrix, " : "",
+          (state & _NEW_ACCUM)           ? "ctx->Accum, " : "",
+          (state & _NEW_COLOR)           ? "ctx->Color, " : "",
+          (state & _NEW_DEPTH)           ? "ctx->Depth, " : "",
+          (state & _NEW_EVAL)            ? "ctx->Eval/EvalMap, " : "",
+          (state & _NEW_FOG)             ? "ctx->Fog, " : "",
+          (state & _NEW_HINT)            ? "ctx->Hint, " : "",
+          (state & _NEW_LIGHT)           ? "ctx->Light, " : "",
+          (state & _NEW_LINE)            ? "ctx->Line, " : "",
+          (state & _NEW_FEEDBACK_SELECT) ? "ctx->Feedback/Select, " : "",
+          (state & _NEW_PIXEL)           ? "ctx->Pixel, " : "",
+          (state & _NEW_POINT)           ? "ctx->Point, " : "",
+          (state & _NEW_POLYGON)         ? "ctx->Polygon, " : "",
+          (state & _NEW_POLYGONSTIPPLE)  ? "ctx->PolygonStipple, " : "",
+          (state & _NEW_SCISSOR)         ? "ctx->Scissor, " : "",
+          (state & _NEW_TEXTURE)         ? "ctx->Texture, " : "",
+          (state & _NEW_TRANSFORM)       ? "ctx->Transform, " : "",
+          (state & _NEW_VIEWPORT)        ? "ctx->Viewport, " : "",
+          (state & _NEW_PACKUNPACK)      ? "ctx->Pack/Unpack, " : "",
+          (state & _NEW_ARRAY)           ? "ctx->Array, " : "",
+          (state & _NEW_COLORTABLE)      ? "ctx->{*}ColorTable, " : "",
+          (state & _NEW_RENDERMODE)      ? "ctx->RenderMode, " : "",
+          (state & _NEW_BUFFERS)         ? "ctx->Visual, ctx->DrawBuffer,, " : "");
+}
+
+
+void gl_print_enable_flags( const char *msg, GLuint flags )
+{
+   fprintf(stderr,
+          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+          msg,
+          flags,
+          (flags & ENABLE_TEX0)       ? "tex-0, " : "",
+          (flags & ENABLE_TEX1)       ? "tex-1, " : "",
+          (flags & ENABLE_LIGHT)      ? "light, " : "",
+          (flags & ENABLE_FOG)        ? "fog, " : "",
+          (flags & ENABLE_USERCLIP)   ? "userclip, " : "",
+          (flags & ENABLE_TEXGEN0)    ? "tex-gen-0, " : "",
+          (flags & ENABLE_TEXGEN1)    ? "tex-gen-1, " : "",
+          (flags & ENABLE_TEXGEN2)    ? "tex-gen-2, " : "",
+          (flags & ENABLE_TEXGEN3)    ? "tex-gen-3, " : "",
+          (flags & ENABLE_TEXMAT0)    ? "tex-mat-0, " : "",
+          (flags & ENABLE_TEXMAT1)    ? "tex-mat-1, " : "",
+          (flags & ENABLE_TEXMAT2)    ? "tex-mat-2, " : "",
+          (flags & ENABLE_TEXMAT3)    ? "tex-mat-3, " : "",
+          (flags & ENABLE_NORMALIZE)  ? "normalize, " : "",
+          (flags & ENABLE_RESCALE)    ? "rescale, " : "");
+}
+
+void gl_print_tri_caps( const char *name, GLuint flags ) 
+{
+   fprintf(stderr, 
+          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+          name,
+          flags,
+          (flags & DD_FEEDBACK)            ? "feedback, " : "",
+          (flags & DD_SELECT)              ? "select, " : "",
+          (flags & DD_FLATSHADE)           ? "flat-shade, " : "",
+          (flags & DD_MULTIDRAW)           ? "multidraw, " : "",
+          (flags & DD_SEPERATE_SPECULAR)   ? "seperate-specular, " : "",
+          (flags & DD_TRI_LIGHT_TWOSIDE)   ? "tri-light-twoside, " : "",
+          (flags & DD_TRI_UNFILLED)        ? "tri-unfilled, " : "",
+          (flags & DD_TRI_STIPPLE)         ? "tri-stipple, " : "",
+          (flags & DD_TRI_OFFSET)          ? "tri-offset, " : "",
+          (flags & DD_TRI_CULL)            ? "tri-bf-cull, " : "",
+          (flags & DD_TRI_SMOOTH)          ? "tri-smooth, " : "",
+          (flags & DD_LINE_SMOOTH)         ? "line-smooth, " : "",
+          (flags & DD_LINE_STIPPLE)        ? "line-stipple, " : "",
+          (flags & DD_LINE_WIDTH)          ? "line-wide, " : "",
+          (flags & DD_POINT_SMOOTH)        ? "point-smooth, " : "", 
+          (flags & DD_POINT_SIZE)          ? "point-size, " : "", 
+          (flags & DD_POINT_ATTEN)         ? "point-atten, " : "", 
+          (flags & DD_LIGHTING_CULL)       ? "lighting-cull, " : "", 
+          (flags & DD_TRI_CULL_FRONT_BACK) ? "cull-all, " : "",
+          (flags & DD_STENCIL)             ? "stencil, " : ""
+      );
+}
diff --git a/src/mesa/main/debug.h b/src/mesa/main/debug.h
new file mode 100644 (file)
index 0000000..1fff954
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+void gl_print_tri_caps( const char *name, GLuint flags );
+void gl_print_enable_flags( const char *msg, GLuint flags );
+void gl_print_state( const char *msg, GLuint state );
+
+#endif
index e3475bb5cb1d1cc2fa2e3ee7dcec857bafa202b2..d66c0745a86657d2bd3da823682e909a4a042bd4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dlist.c,v 1.50 2000/11/10 18:06:14 brianp Exp $ */
+/* $Id: dlist.c,v 1.51 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -32,7 +32,6 @@
 #include "accum.h"
 #include "attrib.h"
 #include "bitmap.h"
-#include "bbox.h"
 #include "blend.h"
 #include "buffers.h"
 #include "clip.h"
@@ -41,7 +40,6 @@
 #include "context.h"
 #include "convolve.h"
 #include "copypix.h"
-#include "cva.h"
 #include "depth.h"
 #include "enable.h"
 #include "enums.h"
@@ -59,7 +57,6 @@
 #include "macros.h"
 #include "matrix.h"
 #include "mem.h"
-#include "pipeline.h"
 #include "pixel.h"
 #include "pixeltex.h"
 #include "points.h"
 #include "texstate.h"
 #include "types.h"
 #include "varray.h"
-#include "vb.h"
-#include "vbfill.h"
-#include "vbxform.h"
-#include "xform.h"
+
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
+
+#include "tnl/t_vbfill.h"
+#include "tnl/t_eval.h"
+#include "tnl/t_varray.h"
 #endif
 
 
@@ -121,7 +121,6 @@ Functions which cause errors if called while compiling a display list:
  * The fact that these identifiers are assigned consecutive
  * integer values starting at 0 is very important, see InstSize array usage)
  *
- * KW: Commented out opcodes now handled by vertex-cassettes.
  */
 typedef enum {
        OPCODE_ACCUM,
@@ -221,6 +220,7 @@ typedef enum {
        OPCODE_READ_BUFFER,
         OPCODE_RESET_HISTOGRAM,
         OPCODE_RESET_MIN_MAX,
+        OPCODE_ROTATE,
         OPCODE_SCALE,
        OPCODE_SCISSOR,
        OPCODE_SELECT_TEXTURE_SGIS,
@@ -256,9 +256,9 @@ typedef enum {
         OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D,
        /* The following three are meta instructions */
        OPCODE_ERROR,           /* raise compiled-in error */
-       OPCODE_VERTEX_CASSETTE, /* render prebuilt vertex buffer */
        OPCODE_CONTINUE,
-       OPCODE_END_OF_LIST
+       OPCODE_END_OF_LIST,
+       OPCODE_DRV_0
 } OpCode;
 
 
@@ -284,7 +284,9 @@ union node {
 
 
 
-/* Number of nodes of storage needed for each instruction: */
+/* Number of nodes of storage needed for each instruction.  Sizes for
+ * dynamically allocated opcodes are stored in the context struct.
+ */
 static GLuint InstSize[ OPCODE_END_OF_LIST+1 ];
 
 void mesa_print_display_list( GLuint list );
@@ -295,40 +297,6 @@ void mesa_print_display_list( GLuint list );
 /**********************************************************************/
 
 
-/*
- * Allocate space for a display list instruction.
- * Input:  opcode - type of instruction
- *         argcount - number of arguments following the instruction
- * Return: pointer to first node in the instruction
- */
-static Node *alloc_instruction( GLcontext *ctx, OpCode opcode, GLint argcount )
-{
-   Node *n, *newblock;
-   GLuint count = InstSize[opcode];
-
-   assert( (GLint) count == argcount+1 );
-
-   if (ctx->CurrentPos + count + 2 > BLOCK_SIZE) {
-      /* This block is full.  Allocate a new block and chain to it */
-      n = ctx->CurrentBlock + ctx->CurrentPos;
-      n[0].opcode = OPCODE_CONTINUE;
-      newblock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE );
-      if (!newblock) {
-         gl_error( ctx, GL_OUT_OF_MEMORY, "Building display list" );
-         return NULL;
-      }
-      n[1].next = (Node *) newblock;
-      ctx->CurrentBlock = newblock;
-      ctx->CurrentPos = 0;
-   }
-
-   n = ctx->CurrentBlock + ctx->CurrentPos;
-   ctx->CurrentPos += count;
-
-   n[0].opcode = opcode;
-
-   return n;
-}
 
 
 
@@ -362,13 +330,16 @@ void gl_destroy_list( GLcontext *ctx, GLuint list )
 
    done = block ? GL_FALSE : GL_TRUE;
    while (!done) {
-      switch (n[0].opcode) {
-        /* special cases first */
-         case OPCODE_VERTEX_CASSETTE: 
-           if ( ! -- ((struct immediate *) n[1].data)->ref_count )
-              gl_immediate_free( (struct immediate *) n[1].data );
-           n += InstSize[n[0].opcode];
-           break;
+
+      /* check for extension opcodes first */
+
+      int i = (int)n[0].opcode - (int)OPCODE_DRV_0;
+      if (i >= 0 && i < ctx->listext.nr_opcodes) {
+        ctx->listext.opcode[i].destroy(ctx, &n[1]);
+        n += ctx->listext.opcode[i].size;
+      }
+      else {
+        switch (n[0].opcode) {
         case OPCODE_MAP1:
             FREE(n[6].data);
            n += InstSize[n[0].opcode];
@@ -466,9 +437,10 @@ void gl_destroy_list( GLcontext *ctx, GLuint list )
            /* Most frequent case */
            n += InstSize[n[0].opcode];
            break;
+        }
       }
    }
-
+   
    _mesa_HashRemove(ctx->Shared->DisplayList, list);
 }
 
@@ -637,6 +609,7 @@ void gl_init_lists( void )
       InstSize[OPCODE_READ_BUFFER] = 2;
       InstSize[OPCODE_RESET_HISTOGRAM] = 2;
       InstSize[OPCODE_RESET_MIN_MAX] = 2;
+      InstSize[OPCODE_ROTATE] = 5;
       InstSize[OPCODE_SCALE] = 4;
       InstSize[OPCODE_SCISSOR] = 5;
       InstSize[OPCODE_STENCIL_FUNC] = 4;
@@ -657,7 +630,6 @@ void gl_init_lists( void )
       InstSize[OPCODE_WINDOW_POS] = 5;
       InstSize[OPCODE_CONTINUE] = 2;
       InstSize[OPCODE_ERROR] = 3;
-      InstSize[OPCODE_VERTEX_CASSETTE] = 9;
       InstSize[OPCODE_END_OF_LIST] = 1;
       /* GL_SGIX/SGIS_pixel_texture */
       InstSize[OPCODE_PIXEL_TEXGEN_SGIX] = 2;
@@ -678,17 +650,88 @@ void gl_init_lists( void )
 
 
 /*
- * Display List compilation functions
+ * Allocate space for a display list instruction.
+ * Input:  opcode - type of instruction
+ *         argcount - size in bytes of data required.
+ * Return: pointer to the usable data area (not including the internal
+ *         opcode).
  */
+void *
+_mesa_alloc_instruction( GLcontext *ctx, int opcode, GLint sz )
+{
+   Node *n, *newblock;
+   GLuint count = 1 + (sz + sizeof(Node) - 1) / sizeof(Node);
 
+#ifdef DEBUG
+   if (opcode < (int) OPCODE_DRV_0) {
+      assert( (GLint) count == InstSize[opcode] );
+   }
+#endif
 
+   if (ctx->CurrentPos + count + 2 > BLOCK_SIZE) {
+      /* This block is full.  Allocate a new block and chain to it */
+      n = ctx->CurrentBlock + ctx->CurrentPos;
+      n[0].opcode = OPCODE_CONTINUE;
+      newblock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE );
+      if (!newblock) {
+         gl_error( ctx, GL_OUT_OF_MEMORY, "Building display list" );
+         return NULL;
+      }
+      n[1].next = (Node *) newblock;
+      ctx->CurrentBlock = newblock;
+      ctx->CurrentPos = 0;
+   }
 
+   n = ctx->CurrentBlock + ctx->CurrentPos;
+   ctx->CurrentPos += count;
+
+   n[0].opcode = (OpCode) opcode;
+
+   return (void *)&n[1];
+}
+
+
+/* Allow modules and drivers to get their own opcodes.
+ */
+int
+_mesa_alloc_opcode( GLcontext *ctx,
+                   GLuint sz, 
+                   void (*execute)( GLcontext *, void * ),
+                   void (*destroy)( GLcontext *, void * ),
+                   void (*print)( GLcontext *, void * ) )
+{
+   if (ctx->listext.nr_opcodes < GL_MAX_EXT_OPCODES) {
+      GLuint i = ctx->listext.nr_opcodes++;
+      ctx->listext.opcode[i].size = 1 + (sz + sizeof(Node) - 1)/sizeof(Node);
+      ctx->listext.opcode[i].execute = execute;
+      ctx->listext.opcode[i].destroy = destroy;
+      ctx->listext.opcode[i].print = print;
+      return i + OPCODE_DRV_0;
+   }
+   return -1;
+}
+
+
+
+/* Mimic the old behaviour of alloc_instruction:  
+ *   - sz is in units of sizeof(Node)
+ *   - return value a pointer to sizeof(Node) before the actual
+ *     usable data area.
+ */
+#define ALLOC_INSTRUCTION(ctx, opcode, sz) \
+        ((Node *)_mesa_alloc_instruction(ctx, opcode, sz*sizeof(Node)) - 1)
+
+
+
+/*
+ * Display List compilation functions
+ */
 static void save_Accum( GLenum op, GLfloat value )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_ACCUM, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ACCUM, 2 );
    if (n) {
       n[1].e = op;
       n[2].f = value;
@@ -703,8 +746,8 @@ static void save_AlphaFunc( GLenum func, GLclampf ref )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_ALPHA_FUNC, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ALPHA_FUNC, 2 );
    if (n) {
       n[1].e = func;
       n[2].f = (GLfloat) ref;
@@ -715,18 +758,12 @@ static void save_AlphaFunc( GLenum func, GLclampf ref )
 }
 
 
-static void save_Begin( GLenum mode )
-{
-   _mesa_Begin(mode);  /* special case */
-}
-
-
 static void save_BindTexture( GLenum target, GLuint texture )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_BIND_TEXTURE, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_BIND_TEXTURE, 2 );
    if (n) {
       n[1].e = target;
       n[2].ui = texture;
@@ -745,8 +782,8 @@ static void save_Bitmap( GLsizei width, GLsizei height,
    GET_CURRENT_CONTEXT(ctx);
    GLvoid *image = _mesa_unpack_bitmap( width, height, pixels, &ctx->Unpack );
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_BITMAP, 7 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_BITMAP, 7 );
    if (n) {
       n[1].i = (GLint) width;
       n[2].i = (GLint) height;
@@ -770,8 +807,8 @@ static void save_BlendEquation( GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_BLEND_EQUATION, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_EQUATION, 1 );
    if (n) {
       n[1].e = mode;
    }
@@ -785,8 +822,8 @@ static void save_BlendFunc( GLenum sfactor, GLenum dfactor )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_BLEND_FUNC, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_FUNC, 2 );
    if (n) {
       n[1].e = sfactor;
       n[2].e = dfactor;
@@ -802,8 +839,8 @@ static void save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_BLEND_FUNC_SEPARATE, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_FUNC_SEPARATE, 4 );
    if (n) {
       n[1].e = sfactorRGB;
       n[2].e = dfactorRGB;
@@ -822,8 +859,8 @@ static void save_BlendColor( GLfloat red, GLfloat green,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_BLEND_COLOR, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_COLOR, 4 );
    if (n) {
       n[1].f = red;
       n[2].f = green;
@@ -840,8 +877,8 @@ static void save_CallList( GLuint list )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CALL_LIST, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CALL_LIST, 1 );
    if (n) {
       n[1].ui = list;
    }
@@ -855,11 +892,11 @@ static void save_CallLists( GLsizei n, GLenum type, const GLvoid *lists )
 {
    GET_CURRENT_CONTEXT(ctx);
    GLint i;
-   FLUSH_VB(ctx, "dlist");
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
 
    for (i=0;i<n;i++) {
       GLuint list = translate_id( i, type, lists );
-      Node *n = alloc_instruction( ctx, OPCODE_CALL_LIST_OFFSET, 1 );
+      Node *n = ALLOC_INSTRUCTION( ctx, OPCODE_CALL_LIST_OFFSET, 1 );
       if (n) {
          n[1].ui = list;
       }
@@ -874,8 +911,8 @@ static void save_Clear( GLbitfield mask )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CLEAR, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR, 1 );
    if (n) {
       n[1].bf = mask;
    }
@@ -890,8 +927,8 @@ static void save_ClearAccum( GLfloat red, GLfloat green,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CLEAR_ACCUM, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_ACCUM, 4 );
    if (n) {
       n[1].f = red;
       n[2].f = green;
@@ -909,8 +946,8 @@ static void save_ClearColor( GLclampf red, GLclampf green,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CLEAR_COLOR, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_COLOR, 4 );
    if (n) {
       n[1].f = red;
       n[2].f = green;
@@ -927,8 +964,8 @@ static void save_ClearDepth( GLclampd depth )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CLEAR_DEPTH, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_DEPTH, 1 );
    if (n) {
       n[1].f = (GLfloat) depth;
    }
@@ -942,8 +979,8 @@ static void save_ClearIndex( GLfloat c )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CLEAR_INDEX, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_INDEX, 1 );
    if (n) {
       n[1].f = c;
    }
@@ -957,8 +994,8 @@ static void save_ClearStencil( GLint s )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CLEAR_STENCIL, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_STENCIL, 1 );
    if (n) {
       n[1].i = s;
    }
@@ -972,8 +1009,8 @@ static void save_ClipPlane( GLenum plane, const GLdouble *equ )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CLIP_PLANE, 5 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CLIP_PLANE, 5 );
    if (n) {
       n[1].e = plane;
       n[2].f = equ[0];
@@ -993,8 +1030,8 @@ static void save_ColorMask( GLboolean red, GLboolean green,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COLOR_MASK, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_MASK, 4 );
    if (n) {
       n[1].b = red;
       n[2].b = green;
@@ -1011,8 +1048,8 @@ static void save_ColorMaterial( GLenum face, GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COLOR_MATERIAL, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_MATERIAL, 2 );
    if (n) {
       n[1].e = face;
       n[2].e = mode;
@@ -1039,8 +1076,8 @@ static void save_ColorTable( GLenum target, GLenum internalFormat,
       GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, table,
                                          &ctx->Unpack);
       Node *n;
-      FLUSH_VB(ctx, "dlist");
-      n = alloc_instruction( ctx, OPCODE_COLOR_TABLE, 6 );
+      FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+      n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE, 6 );
       if (n) {
          n[1].e = target;
          n[2].e = internalFormat;
@@ -1068,9 +1105,9 @@ save_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
    Node *n;
 
    ASSERT_OUTSIDE_BEGIN_END(ctx, "glColorTableParameterfv");
-   FLUSH_VB(ctx, "dlist");
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
 
-   n = alloc_instruction( ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6 );
    if (n) {
       n[1].e = target;
       n[2].e = pname;
@@ -1097,9 +1134,9 @@ save_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
    Node *n;
 
    ASSERT_OUTSIDE_BEGIN_END(ctx, "glColorTableParameterfv");
-   FLUSH_VB(ctx, "dlist");
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
 
-   n = alloc_instruction( ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6 );
    if (n) {
       n[1].e = target;
       n[2].e = pname;
@@ -1128,8 +1165,8 @@ static void save_ColorSubTable( GLenum target, GLsizei start, GLsizei count,
    GLvoid *image = _mesa_unpack_image(count, 1, 1, format, type, table,
                                       &ctx->Unpack);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COLOR_SUB_TABLE, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_SUB_TABLE, 6 );
    if (n) {
       n[1].e = target;
       n[2].i = start;
@@ -1154,8 +1191,8 @@ save_CopyColorSubTable(GLenum target, GLsizei start,
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
 
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COPY_COLOR_SUB_TABLE, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_COLOR_SUB_TABLE, 6 );
    if (n) {
       n[1].e = target;
       n[2].i = start;
@@ -1176,8 +1213,8 @@ save_CopyColorTable(GLenum target, GLenum internalformat,
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
 
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COPY_COLOR_TABLE, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_COLOR_TABLE, 6 );
    if (n) {
       n[1].e = target;
       n[2].e = internalformat;
@@ -1199,8 +1236,8 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
    GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, filter,
                                       &ctx->Unpack);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CONVOLUTION_FILTER_1D, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_FILTER_1D, 6 );
    if (n) {
       n[1].e = target;
       n[2].e = internalFormat;
@@ -1228,8 +1265,8 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
    GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, filter,
                                       &ctx->Unpack);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CONVOLUTION_FILTER_2D, 7 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_FILTER_2D, 7 );
    if (n) {
       n[1].e = target;
       n[2].e = internalFormat;
@@ -1254,8 +1291,8 @@ save_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3 );
    if (n) {
       n[1].e = target;
       n[2].e = pname;
@@ -1272,8 +1309,8 @@ save_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 );
    if (n) {
       n[1].e = target;
       n[2].e = pname;
@@ -1300,8 +1337,8 @@ save_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3 );
    if (n) {
       n[1].e = target;
       n[2].e = pname;
@@ -1318,8 +1355,8 @@ save_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 );
    if (n) {
       n[1].e = target;
       n[2].e = pname;
@@ -1346,8 +1383,8 @@ static void save_CopyPixels( GLint x, GLint y,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COPY_PIXELS, 5 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_PIXELS, 5 );
    if (n) {
       n[1].i = x;
       n[2].i = y;
@@ -1368,8 +1405,8 @@ save_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COPY_TEX_IMAGE1D, 7 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_IMAGE1D, 7 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -1394,8 +1431,8 @@ save_CopyTexImage2D( GLenum target, GLint level,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COPY_TEX_IMAGE2D, 8 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_IMAGE2D, 8 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -1421,8 +1458,8 @@ save_CopyTexSubImage1D( GLenum target, GLint level,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -1445,8 +1482,8 @@ save_CopyTexSubImage2D( GLenum target, GLint level,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -1472,8 +1509,8 @@ save_CopyTexSubImage3D( GLenum target, GLint level,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -1497,8 +1534,8 @@ static void save_CullFace( GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CULL_FACE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CULL_FACE, 1 );
    if (n) {
       n[1].e = mode;
    }
@@ -1512,8 +1549,8 @@ static void save_DepthFunc( GLenum func )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_DEPTH_FUNC, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_FUNC, 1 );
    if (n) {
       n[1].e = func;
    }
@@ -1527,8 +1564,8 @@ static void save_DepthMask( GLboolean mask )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_DEPTH_MASK, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_MASK, 1 );
    if (n) {
       n[1].b = mask;
    }
@@ -1542,8 +1579,8 @@ static void save_DepthRange( GLclampd nearval, GLclampd farval )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_DEPTH_RANGE, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_RANGE, 2 );
    if (n) {
       n[1].f = (GLfloat) nearval;
       n[2].f = (GLfloat) farval;
@@ -1558,8 +1595,8 @@ static void save_Disable( GLenum cap )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_DISABLE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_DISABLE, 1 );
    if (n) {
       n[1].e = cap;
    }
@@ -1573,8 +1610,8 @@ static void save_DrawBuffer( GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_DRAW_BUFFER, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_DRAW_BUFFER, 1 );
    if (n) {
       n[1].e = mode;
    }
@@ -1592,8 +1629,8 @@ static void save_DrawPixels( GLsizei width, GLsizei height,
    GLvoid *image = _mesa_unpack_image(width, height, 1, format, type,
                                       pixels, &ctx->Unpack);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_DRAW_PIXELS, 5 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_DRAW_PIXELS, 5 );
    if (n) {
       n[1].i = width;
       n[2].i = height;
@@ -1615,8 +1652,8 @@ static void save_Enable( GLenum cap )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_ENABLE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ENABLE, 1 );
    if (n) {
       n[1].e = cap;
    }
@@ -1631,8 +1668,8 @@ static void save_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_EVALMESH1, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_EVALMESH1, 3 );
    if (n) {
       n[1].e = mode;
       n[2].i = i1;
@@ -1649,8 +1686,8 @@ static void save_EvalMesh2(
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_EVALMESH2, 5 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_EVALMESH2, 5 );
    if (n) {
       n[1].e = mode;
       n[2].i = i1;
@@ -1670,8 +1707,8 @@ static void save_Fogfv( GLenum pname, const GLfloat *params )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_FOG, 5 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_FOG, 5 );
    if (n) {
       n[1].e = pname;
       n[2].f = params[0];
@@ -1726,8 +1763,8 @@ static void save_FrontFace( GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_FRONT_FACE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_FRONT_FACE, 1 );
    if (n) {
       n[1].e = mode;
    }
@@ -1743,8 +1780,8 @@ static void save_Frustum( GLdouble left, GLdouble right,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_FRUSTUM, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_FRUSTUM, 6 );
    if (n) {
       n[1].f = left;
       n[2].f = right;
@@ -1763,8 +1800,8 @@ static void save_Hint( GLenum target, GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_HINT, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_HINT, 2 );
    if (n) {
       n[1].e = target;
       n[2].e = mode;
@@ -1780,8 +1817,8 @@ static void save_HintPGI( GLenum target, GLint mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_HINT_PGI, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_HINT_PGI, 2 );
    if (n) {
       n[1].e = target;
       n[2].i = mode;
@@ -1798,8 +1835,8 @@ save_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean si
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
 
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_HISTOGRAM, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_HISTOGRAM, 4 );
    if (n) {
       n[1].e = target;
       n[2].i = width;
@@ -1816,8 +1853,8 @@ static void save_IndexMask( GLuint mask )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_INDEX_MASK, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_INDEX_MASK, 1 );
    if (n) {
       n[1].ui = mask;
    }
@@ -1830,8 +1867,8 @@ static void save_IndexMask( GLuint mask )
 static void save_InitNames( void )
 {
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
-   (void) alloc_instruction( ctx, OPCODE_INIT_NAMES, 0 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   (void) ALLOC_INSTRUCTION( ctx, OPCODE_INIT_NAMES, 0 );
    if (ctx->ExecuteFlag) {
       (*ctx->Exec->InitNames)();
    }
@@ -1842,8 +1879,8 @@ static void save_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_LIGHT, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_LIGHT, 6 );
    if (OPCODE_LIGHT) {
       GLint i, nParams;
       n[1].e = light;
@@ -1946,8 +1983,8 @@ static void save_LightModelfv( GLenum pname, const GLfloat *params )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_LIGHT_MODEL, 5 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_LIGHT_MODEL, 5 );
    if (n) {
       n[1].e = pname;
       n[2].f = params[0];
@@ -2000,8 +2037,8 @@ static void save_LineStipple( GLint factor, GLushort pattern )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_LINE_STIPPLE, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_LINE_STIPPLE, 2 );
    if (n) {
       n[1].i = factor;
       n[2].us = pattern;
@@ -2016,8 +2053,8 @@ static void save_LineWidth( GLfloat width )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_LINE_WIDTH, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_LINE_WIDTH, 1 );
    if (n) {
       n[1].f = width;
    }
@@ -2031,8 +2068,8 @@ static void save_ListBase( GLuint base )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_LIST_BASE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_LIST_BASE, 1 );
    if (n) {
       n[1].ui = base;
    }
@@ -2045,8 +2082,8 @@ static void save_ListBase( GLuint base )
 static void save_LoadIdentity( void )
 {
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
-   (void) alloc_instruction( ctx, OPCODE_LOAD_IDENTITY, 0 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   (void) ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_IDENTITY, 0 );
    if (ctx->ExecuteFlag) {
       (*ctx->Exec->LoadIdentity)();
    }
@@ -2057,8 +2094,8 @@ static void save_LoadMatrixf( const GLfloat *m )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_LOAD_MATRIX, 16 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_MATRIX, 16 );
    if (n) {
       GLuint i;
       for (i=0;i<16;i++) {
@@ -2086,8 +2123,8 @@ static void save_LoadName( GLuint name )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_LOAD_NAME, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_NAME, 1 );
    if (n) {
       n[1].ui = name;
    }
@@ -2101,8 +2138,8 @@ static void save_LogicOp( GLenum opcode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_LOGIC_OP, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_LOGIC_OP, 1 );
    if (n) {
       n[1].e = opcode;
    }
@@ -2117,8 +2154,8 @@ static void save_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MAP1, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP1, 6 );
    if (n) {
       GLfloat *pnts = gl_copy_map_points1d( target, stride, order, points );
       n[1].e = target;
@@ -2138,8 +2175,8 @@ static void save_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MAP1, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP1, 6 );
    if (n) {
       GLfloat *pnts = gl_copy_map_points1f( target, stride, order, points );
       n[1].e = target;
@@ -2162,8 +2199,8 @@ static void save_Map2d( GLenum target,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MAP2, 10 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP2, 10 );
    if (n) {
       GLfloat *pnts = gl_copy_map_points2d( target, ustride, uorder,
                                             vstride, vorder, points );
@@ -2194,8 +2231,8 @@ static void save_Map2f( GLenum target,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MAP2, 10 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP2, 10 );
    if (n) {
       GLfloat *pnts = gl_copy_map_points2f( target, ustride, uorder,
                                             vstride, vorder, points );
@@ -2222,8 +2259,8 @@ static void save_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MAPGRID1, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MAPGRID1, 3 );
    if (n) {
       n[1].i = un;
       n[2].f = u1;
@@ -2246,8 +2283,8 @@ static void save_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MAPGRID2, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MAPGRID2, 6 );
    if (n) {
       n[1].i = un;
       n[2].f = u1;
@@ -2274,8 +2311,8 @@ static void save_MatrixMode( GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MATRIX_MODE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MATRIX_MODE, 1 );
    if (n) {
       n[1].e = mode;
    }
@@ -2291,8 +2328,8 @@ save_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
 
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MIN_MAX, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MIN_MAX, 3 );
    if (n) {
       n[1].e = target;
       n[2].e = internalFormat;
@@ -2308,8 +2345,8 @@ static void save_MultMatrixf( const GLfloat *m )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_MULT_MATRIX, 16 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_MULT_MATRIX, 16 );
    if (n) {
       GLuint i;
       for (i=0;i<16;i++) {
@@ -2350,8 +2387,8 @@ static void save_Ortho( GLdouble left, GLdouble right,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_ORTHO, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ORTHO, 6 );
    if (n) {
       n[1].f = left;
       n[2].f = right;
@@ -2370,8 +2407,8 @@ static void save_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_PIXEL_MAP, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_MAP, 3 );
    if (n) {
       n[1].e = map;
       n[2].i = mapsize;
@@ -2424,8 +2461,8 @@ static void save_PixelTransferf( GLenum pname, GLfloat param )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_PIXEL_TRANSFER, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_TRANSFER, 2 );
    if (n) {
       n[1].e = pname;
       n[2].f = param;
@@ -2446,8 +2483,8 @@ static void save_PixelZoom( GLfloat xfactor, GLfloat yfactor )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_PIXEL_ZOOM, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_ZOOM, 2 );
    if (n) {
       n[1].f = xfactor;
       n[2].f = yfactor;
@@ -2462,8 +2499,8 @@ static void save_PointParameterfvEXT( GLenum pname, const GLfloat *params )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_POINT_PARAMETERS, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_POINT_PARAMETERS, 4 );
    if (n) {
       n[1].e = pname;
       n[2].f = params[0];
@@ -2486,8 +2523,8 @@ static void save_PointSize( GLfloat size )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_POINT_SIZE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_POINT_SIZE, 1 );
    if (n) {
       n[1].f = size;
    }
@@ -2501,8 +2538,8 @@ static void save_PolygonMode( GLenum face, GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_POLYGON_MODE, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_MODE, 2 );
    if (n) {
       n[1].e = face;
       n[2].e = mode;
@@ -2520,8 +2557,8 @@ static void save_PolygonStipple( const GLubyte *pattern )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_POLYGON_STIPPLE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_STIPPLE, 1 );
    if (n) {
       void *data;
       n[1].data = MALLOC( 32 * 4 );
@@ -2538,8 +2575,8 @@ static void save_PolygonOffset( GLfloat factor, GLfloat units )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_POLYGON_OFFSET, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_OFFSET, 2 );
    if (n) {
       n[1].f = factor;
       n[2].f = units;
@@ -2560,8 +2597,8 @@ static void save_PolygonOffsetEXT( GLfloat factor, GLfloat bias )
 static void save_PopAttrib( void )
 {
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
-   (void) alloc_instruction( ctx, OPCODE_POP_ATTRIB, 0 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_ATTRIB, 0 );
    if (ctx->ExecuteFlag) {
       (*ctx->Exec->PopAttrib)();
    }
@@ -2571,8 +2608,8 @@ static void save_PopAttrib( void )
 static void save_PopMatrix( void )
 {
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
-   (void) alloc_instruction( ctx, OPCODE_POP_MATRIX, 0 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_MATRIX, 0 );
    if (ctx->ExecuteFlag) {
       (*ctx->Exec->PopMatrix)();
    }
@@ -2582,8 +2619,8 @@ static void save_PopMatrix( void )
 static void save_PopName( void )
 {
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
-   (void) alloc_instruction( ctx, OPCODE_POP_NAME, 0 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_NAME, 0 );
    if (ctx->ExecuteFlag) {
       (*ctx->Exec->PopName)();
    }
@@ -2595,11 +2632,11 @@ static void save_PrioritizeTextures( GLsizei num, const GLuint *textures,
 {
    GET_CURRENT_CONTEXT(ctx);
    GLint i;
-   FLUSH_VB(ctx, "dlist");
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
 
    for (i=0;i<num;i++) {
       Node *n;
-      n = alloc_instruction( ctx,  OPCODE_PRIORITIZE_TEXTURE, 2 );
+      n = ALLOC_INSTRUCTION( ctx,  OPCODE_PRIORITIZE_TEXTURE, 2 );
       if (n) {
          n[1].ui = textures[i];
          n[2].f = priorities[i];
@@ -2615,8 +2652,8 @@ static void save_PushAttrib( GLbitfield mask )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_PUSH_ATTRIB, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_ATTRIB, 1 );
    if (n) {
       n[1].bf = mask;
    }
@@ -2629,8 +2666,8 @@ static void save_PushAttrib( GLbitfield mask )
 static void save_PushMatrix( void )
 {
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
-   (void) alloc_instruction( ctx, OPCODE_PUSH_MATRIX, 0 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   (void) ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_MATRIX, 0 );
    if (ctx->ExecuteFlag) {
       (*ctx->Exec->PushMatrix)();
    }
@@ -2641,8 +2678,8 @@ static void save_PushName( GLuint name )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_PUSH_NAME, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_NAME, 1 );
    if (n) {
       n[1].ui = name;
    }
@@ -2656,8 +2693,8 @@ static void save_RasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_RASTER_POS, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_RASTER_POS, 4 );
    if (n) {
       n[1].f = x;
       n[2].f = y;
@@ -2789,8 +2826,8 @@ static void save_PassThrough( GLfloat token )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_PASSTHROUGH, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_PASSTHROUGH, 1 );
    if (n) {
       n[1].f = token;
    }
@@ -2804,8 +2841,8 @@ static void save_ReadBuffer( GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_READ_BUFFER, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_READ_BUFFER, 1 );
    if (n) {
       n[1].e = mode;
    }
@@ -2819,8 +2856,8 @@ static void save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_RECTF, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_RECTF, 4 );
    if (n) {
       n[1].f = x1;
       n[2].f = y1;
@@ -2873,8 +2910,8 @@ save_ResetHistogram(GLenum target)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_RESET_HISTOGRAM, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_RESET_HISTOGRAM, 1 );
    if (n) {
       n[1].e = target;
    }
@@ -2889,8 +2926,8 @@ save_ResetMinmax(GLenum target)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_RESET_MIN_MAX, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_RESET_MIN_MAX, 1 );
    if (n) {
       n[1].e = target;
    }
@@ -2902,9 +2939,19 @@ save_ResetMinmax(GLenum target)
 
 static void save_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
 {
-   GLfloat m[16];
-   gl_rotation_matrix( angle, x, y, z, m );
-   save_MultMatrixf( m );  /* save and maybe execute */
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ROTATE, 4 );
+   if (n) {
+      n[1].f = angle;
+      n[2].f = x;
+      n[3].f = y;
+      n[4].f = z;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec->Rotatef)( angle, x, y, z );
+   }
 }
 
 
@@ -2918,8 +2965,8 @@ static void save_Scalef( GLfloat x, GLfloat y, GLfloat z )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_SCALE, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_SCALE, 3 );
    if (n) {
       n[1].f = x;
       n[2].f = y;
@@ -2941,8 +2988,8 @@ static void save_Scissor( GLint x, GLint y, GLsizei width, GLsizei height )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_SCISSOR, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_SCISSOR, 4 );
    if (n) {
       n[1].i = x;
       n[2].i = y;
@@ -2959,8 +3006,8 @@ static void save_ShadeModel( GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_SHADE_MODEL, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_SHADE_MODEL, 1 );
    if (n) {
       n[1].e = mode;
    }
@@ -2974,8 +3021,8 @@ static void save_StencilFunc( GLenum func, GLint ref, GLuint mask )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_STENCIL_FUNC, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_FUNC, 3 );
    if (n) {
       n[1].e = func;
       n[2].i = ref;
@@ -2991,8 +3038,8 @@ static void save_StencilMask( GLuint mask )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_STENCIL_MASK, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_MASK, 1 );
    if (n) {
       n[1].ui = mask;
    }
@@ -3006,8 +3053,8 @@ static void save_StencilOp( GLenum fail, GLenum zfail, GLenum zpass )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_STENCIL_OP, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_OP, 3 );
    if (n) {
       n[1].e = fail;
       n[2].e = zfail;
@@ -3023,8 +3070,8 @@ static void save_TexEnvfv( GLenum target, GLenum pname, const GLfloat *params )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_TEXENV, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXENV, 6 );
    if (n) {
       n[1].e = target;
       n[2].e = pname;
@@ -3069,8 +3116,8 @@ static void save_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_TEXGEN, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXGEN, 6 );
    if (n) {
       n[1].e = coord;
       n[2].e = pname;
@@ -3131,8 +3178,8 @@ static void save_TexParameterfv( GLenum target,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_TEXPARAMETER, 6 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXPARAMETER, 6 );
    if (n) {
       n[1].e = target;
       n[2].e = pname;
@@ -3187,8 +3234,8 @@ static void save_TexImage1D( GLenum target,
       GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type,
                                          pixels, &ctx->Unpack);
       Node *n;
-      FLUSH_VB(ctx, "dlist");
-      n = alloc_instruction( ctx, OPCODE_TEX_IMAGE1D, 8 );
+      FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+      n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE1D, 8 );
       if (n) {
          n[1].e = target;
          n[2].i = level;
@@ -3226,8 +3273,8 @@ static void save_TexImage2D( GLenum target,
       GLvoid *image = _mesa_unpack_image(width, height, 1, format, type,
                                          pixels, &ctx->Unpack);
       Node *n;
-      FLUSH_VB(ctx, "dlist");
-      n = alloc_instruction( ctx, OPCODE_TEX_IMAGE2D, 9 );
+      FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+      n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE2D, 9 );
       if (n) {
          n[1].e = target;
          n[2].i = level;
@@ -3267,8 +3314,8 @@ static void save_TexImage3D( GLenum target,
       Node *n;
       GLvoid *image = _mesa_unpack_image(width, height, depth, format, type,
                                          pixels, &ctx->Unpack);
-      FLUSH_VB(ctx, "dlist");
-      n = alloc_instruction( ctx, OPCODE_TEX_IMAGE3D, 10 );
+      FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+      n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE3D, 10 );
       if (n) {
          n[1].e = target;
          n[2].i = level;
@@ -3300,8 +3347,8 @@ static void save_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
    Node *n;
    GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type,
                                       pixels, &ctx->Unpack);
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE1D, 7 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE1D, 7 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -3331,8 +3378,8 @@ static void save_TexSubImage2D( GLenum target, GLint level,
    Node *n;
    GLvoid *image = _mesa_unpack_image(width, height, 1, format, type,
                                       pixels, &ctx->Unpack);
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE2D, 9 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE2D, 9 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -3364,8 +3411,8 @@ static void save_TexSubImage3D( GLenum target, GLint level,
    Node *n;
    GLvoid *image = _mesa_unpack_image(width, height, depth, format, type,
                                       pixels, &ctx->Unpack);
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE3D, 11 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE3D, 11 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -3394,8 +3441,8 @@ static void save_Translatef( GLfloat x, GLfloat y, GLfloat z )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx,  OPCODE_TRANSLATE, 3 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx,  OPCODE_TRANSLATE, 3 );
    if (n) {
       n[1].f = x;
       n[2].f = y;
@@ -3418,8 +3465,8 @@ static void save_Viewport( GLint x, GLint y, GLsizei width, GLsizei height )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx,  OPCODE_VIEWPORT, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx,  OPCODE_VIEWPORT, 4 );
    if (n) {
       n[1].i = x;
       n[2].i = y;
@@ -3436,8 +3483,8 @@ static void save_WindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx,  OPCODE_WINDOW_POS, 4 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx,  OPCODE_WINDOW_POS, 4 );
    if (n) {
       n[1].f = x;
       n[2].f = y;
@@ -3571,8 +3618,8 @@ static void save_ActiveTextureARB( GLenum target )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_ACTIVE_TEXTURE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ACTIVE_TEXTURE, 1 );
    if (n) {
       n[1].e = target;
    }
@@ -3587,8 +3634,8 @@ static void save_ClientActiveTextureARB( GLenum target )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_CLIENT_ACTIVE_TEXTURE, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_CLIENT_ACTIVE_TEXTURE, 1 );
    if (n) {
       n[1].e = target;
    }
@@ -3603,32 +3650,32 @@ static void save_ClientActiveTextureARB( GLenum target )
 
 static void save_LoadTransposeMatrixdARB( const GLdouble m[16] )
 {
-   GLdouble tm[16];
-   gl_matrix_transposed(tm, m);
-   save_LoadMatrixd(tm);
+   GLfloat tm[16];
+   _math_transposefd(tm, m);
+   save_LoadMatrixf(tm);
 }
 
 
 static void save_LoadTransposeMatrixfARB( const GLfloat m[16] )
 {
    GLfloat tm[16];
-   gl_matrix_transposef(tm, m);
+   _math_transposef(tm, m);
    save_LoadMatrixf(tm);
 }
 
 
 static void save_MultTransposeMatrixdARB( const GLdouble m[16] )
 {
-   GLdouble tm[16];
-   gl_matrix_transposed(tm, m);
-   save_MultMatrixd(tm);
+   GLfloat tm[16];
+   _math_transposefd(tm, m);
+   save_MultMatrixf(tm);
 }
 
 
 static void save_MultTransposeMatrixfARB( const GLfloat m[16] )
 {
    GLfloat tm[16];
-   gl_matrix_transposef(tm, m);
+   _math_transposef(tm, m);
    save_MultMatrixf(tm);
 }
 
@@ -3637,8 +3684,8 @@ static void save_PixelTexGenSGIX(GLenum mode)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_PIXEL_TEXGEN_SGIX, 1 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_TEXGEN_SGIX, 1 );
    if (n) {
       n[1].e = mode;
    }
@@ -3664,7 +3711,7 @@ save_CompressedTexImage1DARB(GLenum target, GLint level,
    else {
       Node *n;
       GLvoid *image;
-      FLUSH_VB(ctx, "dlist");
+      FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
       /* make copy of image */
       image = MALLOC(imageSize);
       if (!image) {
@@ -3672,7 +3719,7 @@ save_CompressedTexImage1DARB(GLenum target, GLint level,
          return;
       }
       MEMCPY(image, data, imageSize);
-      n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 8 );
+      n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 8 );
       if (n) {
          n[1].e = target;
          n[2].i = level;
@@ -3708,7 +3755,7 @@ save_CompressedTexImage2DARB(GLenum target, GLint level,
    else {
       Node *n;
       GLvoid *image;
-      FLUSH_VB(ctx, "dlist");
+      FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
       /* make copy of image */
       image = MALLOC(imageSize);
       if (!image) {
@@ -3716,7 +3763,7 @@ save_CompressedTexImage2DARB(GLenum target, GLint level,
          return;
       }
       MEMCPY(image, data, imageSize);
-      n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 9 );
+      n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 9 );
       if (n) {
          n[1].e = target;
          n[2].i = level;
@@ -3753,7 +3800,7 @@ save_CompressedTexImage3DARB(GLenum target, GLint level,
    else {
       Node *n;
       GLvoid *image;
-      FLUSH_VB(ctx, "dlist");
+      FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
       /* make copy of image */
       image = MALLOC(imageSize);
       if (!image) {
@@ -3761,7 +3808,7 @@ save_CompressedTexImage3DARB(GLenum target, GLint level,
          return;
       }
       MEMCPY(image, data, imageSize);
-      n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 10 );
+      n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 10 );
       if (n) {
          n[1].e = target;
          n[2].i = level;
@@ -3793,7 +3840,7 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
    GLvoid *image;
 
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
 
    /* make copy of image */
    image = MALLOC(imageSize);
@@ -3802,7 +3849,7 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
       return;
    }
    MEMCPY(image, data, imageSize);
-   n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 8 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 8 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -3832,7 +3879,7 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
    GLvoid *image;
 
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
 
    /* make copy of image */
    image = MALLOC(imageSize);
@@ -3841,7 +3888,7 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
       return;
    }
    MEMCPY(image, data, imageSize);
-   n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 10 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 10 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -3873,7 +3920,7 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
    GLvoid *image;
 
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VB(ctx, "dlist");
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
 
    /* make copy of image */
    image = MALLOC(imageSize);
@@ -3882,7 +3929,7 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
       return;
    }
    MEMCPY(image, data, imageSize);
-   n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 12 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 12 );
    if (n) {
       n[1].e = target;
       n[2].i = level;
@@ -3912,8 +3959,8 @@ static void save_PixelTexGenParameteriSGIS(GLenum target, GLint value)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   FLUSH_VB(ctx, "dlist");
-   n = alloc_instruction( ctx, OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS, 2 );
+   FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS, 2 );
    if (n) {
       n[1].e = target;
       n[2].i = value;
@@ -3941,56 +3988,6 @@ static void save_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value)
    save_PixelTexGenParameteriSGIS(target, (GLint) *value);
 }
 
-void gl_compile_cassette( GLcontext *ctx )
-{
-   Node *n = alloc_instruction( ctx, OPCODE_VERTEX_CASSETTE, 8 );
-   struct immediate *im = ctx->input;   
-
-   if (!n) 
-      return;
-   
-
-   /* Do some easy optimizations of the cassette.  
-    */
-#if 0
-   if (0 && im->v.Obj.size < 4 && im->Count > 15) {
-      im->Bounds = (GLfloat (*)[3]) MALLOC(6 * sizeof(GLfloat));
-      (gl_calc_bound_tab[im->v.Obj.size])( im->Bounds, &im->v.Obj );
-   }
-#endif
-
-   n[1].data = (void *)im;   
-   n[2].ui = im->Start;
-   n[3].ui = im->Count;
-   n[4].ui = im->BeginState;
-   n[5].ui = im->OrFlag;
-   n[6].ui = im->AndFlag;
-   n[7].ui = im->LastData;
-   n[8].ui = im->LastPrimitive;
-
-   if (im->Count > VB_MAX - 4) {
-
-      struct immediate *new_im = gl_immediate_alloc(ctx);      
-      if (!new_im) return;
-      SET_IMMEDIATE( ctx, new_im );
-      gl_reset_input( ctx );
-
-   } else {
-      im->Count++;;
-      im->Start = im->Count;   /* don't clear anything in reset_input */
-      im->ref_count++;
-
-      im->Primitive[im->Start] = ctx->Current.Primitive;
-      im->LastPrimitive = im->Start;
-      im->BeginState = VERT_BEGIN_0;
-      im->OrFlag = 0;
-      im->AndFlag = ~0;
-
-      if (0)
-        fprintf(stderr, "in compile_cassette, BeginState is %x\n", 
-             im->BeginState);
-   }   
-}
 
 /* KW: Compile commands  
  * 
@@ -4000,7 +3997,7 @@ void gl_compile_cassette( GLcontext *ctx )
 void gl_save_error( GLcontext *ctx, GLenum error, const char *s )
 {
    Node *n;
-   n = alloc_instruction( ctx, OPCODE_ERROR, 2 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ERROR, 2 );
    if (n) {
       n[1].e = error;
       n[2].data = (void *) s;
@@ -4037,12 +4034,11 @@ static void execute_list( GLcontext *ctx, GLuint list )
 {
    Node *n;
    GLboolean done;
-   OpCode opcode;
 
    if (!islist(ctx,list))
       return;
 
-/*    mesa_print_display_list( list ); */
+/*     mesa_print_display_list( list );  */
 
    ctx->CallDepth++;
 
@@ -4050,49 +4046,18 @@ static void execute_list( GLcontext *ctx, GLuint list )
 
    done = GL_FALSE;
    while (!done) {
-      opcode = n[0].opcode;
+      OpCode opcode = n[0].opcode;
+      int i = (int)n[0].opcode - (int)OPCODE_DRV_0;
 
-      switch (opcode) {
-         case OPCODE_ERROR:
-           gl_error( ctx, n[1].e, (const char *) n[2].data ); 
-            break;
-         case OPCODE_VERTEX_CASSETTE: {
-           struct immediate *IM;
-           
-           if (ctx->NewState)
-              gl_update_state(ctx);
-           if (ctx->CompileCVAFlag) {
-              ctx->CompileCVAFlag = 0;
-              ctx->CVA.elt.pipeline_valid = 0;
-           }
-           if (!ctx->CVA.elt.pipeline_valid)
-              gl_build_immediate_pipeline( ctx );
-
-           
-           IM = (struct immediate *) n[1].data;
-           IM->Start = n[2].ui;
-           IM->Count = n[3].ui;
-           IM->BeginState = n[4].ui;
-           IM->OrFlag = n[5].ui;
-           IM->AndFlag = n[6].ui;
-           IM->LastData = n[7].ui;
-           IM->LastPrimitive = n[8].ui;
-
-           if ((MESA_VERBOSE & VERBOSE_DISPLAY_LIST) &&
-               (MESA_VERBOSE & VERBOSE_IMMEDIATE))
-              gl_print_cassette( (struct immediate *) n[1].data );
-
-           if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST) {
-              fprintf(stderr, "Run cassette %d, rows %d..%d, beginstate %x ",
-                      IM->id,
-                      IM->Start, IM->Count, IM->BeginState);
-              gl_print_vert_flags("orflag", IM->OrFlag);
-           }
-
-           gl_fixup_cassette( ctx, (struct immediate *) n[1].data ); 
-           gl_execute_cassette( ctx, (struct immediate *) n[1].data ); 
-            break;
-        }
+      if (i >= 0 && i < ctx->listext.nr_opcodes) {
+        ctx->listext.opcode[i].execute(ctx, &n[1]);
+        n += ctx->listext.opcode[i].size;
+      }
+      else {
+        switch (opcode) {
+        case OPCODE_ERROR:
+           gl_error( ctx, n[1].e, (const char *) n[2].data ); 
+           break;
          case OPCODE_ACCUM:
            (*ctx->Exec->Accum)( n[1].e, n[2].f );
            break;
@@ -4518,7 +4483,7 @@ static void execute_list( GLcontext *ctx, GLuint list )
            break;
          case OPCODE_RECTF:
             (*ctx->Exec->Rectf)( n[1].f, n[2].f, n[3].f, n[4].f );
-           FLUSH_VB( ctx, "dlist rectf" );
+           FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
             break;
          case OPCODE_RESET_HISTOGRAM:
             (*ctx->Exec->ResetHistogram)( n[1].e );
@@ -4526,6 +4491,9 @@ static void execute_list( GLcontext *ctx, GLuint list )
          case OPCODE_RESET_MIN_MAX:
             (*ctx->Exec->ResetMinmax)( n[1].e );
             break;
+         case OPCODE_ROTATE:
+            (*ctx->Exec->Rotatef)( n[1].f, n[2].f, n[3].f, n[4].f );
+            break;
          case OPCODE_SCALE:
             (*ctx->Exec->Scalef)( n[1].f, n[2].f, n[3].f );
             break;
@@ -4716,13 +4684,13 @@ static void execute_list( GLcontext *ctx, GLuint list )
                gl_problem( ctx, msg );
             }
             done = GL_TRUE;
-      }
+        }
 
-      /* increment n to point to next compiled command */
-      if (opcode!=OPCODE_CONTINUE) {
-        n += InstSize[opcode];
+        /* increment n to point to next compiled command */
+        if (opcode!=OPCODE_CONTINUE) {
+           n += InstSize[opcode];
+        }
       }
-
    }
    ctx->CallDepth--;
 }
@@ -4817,8 +4785,8 @@ void
 _mesa_NewList( GLuint list, GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
-   struct immediate *IM;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glNewList");
+   FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
 
    if (MESA_VERBOSE&VERBOSE_API)
       fprintf(stderr, "glNewList %u %s\n", list, gl_lookup_enum_by_nr(mode));
@@ -4844,15 +4812,11 @@ _mesa_NewList( GLuint list, GLenum mode )
    ctx->CurrentBlock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE );
    ctx->CurrentListPtr = ctx->CurrentBlock;
    ctx->CurrentPos = 0;
-
-   IM = gl_immediate_alloc( ctx );
-   SET_IMMEDIATE( ctx, IM );
-   gl_reset_input( ctx );
-
    ctx->CompileFlag = GL_TRUE;
-   ctx->CompileCVAFlag = GL_FALSE;
    ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE);
 
+   ctx->Driver.NewList( ctx, list, mode );
+
    ctx->CurrentDispatch = ctx->Save;
    _glapi_set_dispatch( ctx->CurrentDispatch );
 }
@@ -4870,6 +4834,8 @@ _mesa_EndList( void )
       fprintf(stderr, "glEndList\n");
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glEndList" );
+   FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
+
 
    /* Check that a list is under construction */
    if (!ctx->CurrentListPtr) {
@@ -4877,7 +4843,7 @@ _mesa_EndList( void )
       return;
    }
 
-   (void) alloc_instruction( ctx, OPCODE_END_OF_LIST, 0 );
+   (void) ALLOC_INSTRUCTION( ctx, OPCODE_END_OF_LIST, 0 );
 
    /* Destroy old list, if any */
    gl_destroy_list(ctx, ctx->CurrentListNum);
@@ -4892,15 +4858,8 @@ _mesa_EndList( void )
    ctx->CurrentListPtr = NULL;
    ctx->ExecuteFlag = GL_TRUE;
    ctx->CompileFlag = GL_FALSE;
-   /* ctx->CompileCVAFlag = ...; */
 
-   /* KW: Put back the old input pointer.
-    */
-   if (--ctx->input->ref_count == 0)
-      gl_immediate_free( ctx->input );
-
-   SET_IMMEDIATE( ctx, ctx->VB->IM );
-   gl_reset_input( ctx );
+   ctx->Driver.EndList( ctx );
 
    /* Haven't tracked down why this is needed.
     */
@@ -4928,7 +4887,7 @@ _mesa_CallList( GLuint list )
    save_compile_flag = ctx->CompileFlag;   
    ctx->CompileFlag = GL_FALSE;
    
-   FLUSH_VB( ctx, "call list" );
+   FLUSH_TNL( ctx, (FLUSH_STORED_VERTICES | FLUSH_UPDATE_CURRENT) );
    execute_list( ctx, list );
    ctx->CompileFlag = save_compile_flag;
 
@@ -4958,7 +4917,7 @@ _mesa_CallLists( GLsizei n, GLenum type, const GLvoid *lists )
    save_compile_flag = ctx->CompileFlag;
    ctx->CompileFlag = GL_FALSE;
 
-   FLUSH_VB( ctx, "call lists" );
+   FLUSH_TNL( ctx, (FLUSH_STORED_VERTICES | FLUSH_UPDATE_CURRENT) );
 
    for (i=0;i<n;i++) {
       list = translate_id( i, type, lists );
@@ -5002,7 +4961,7 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize )
    /* GL 1.0 */
    table->Accum = save_Accum;
    table->AlphaFunc = save_AlphaFunc;
-   table->Begin = save_Begin;
+   table->Begin = _mesa_Begin;
    table->Bitmap = save_Bitmap;
    table->BlendFunc = save_BlendFunc;
    table->CallList = save_CallList;
@@ -5565,7 +5524,6 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list )
 {
    Node *n;
    GLboolean done;
-   OpCode opcode;
 
    if (!glIsList(list)) {
       fprintf(f,"%u is not a display list ID\n",list);
@@ -5578,9 +5536,14 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list )
 
    done = n ? GL_FALSE : GL_TRUE;
    while (!done) {
-      opcode = n[0].opcode;
-
-      switch (opcode) {
+      OpCode opcode = n[0].opcode;
+      int i = (int)n[0].opcode - (int)OPCODE_DRV_0;
+
+      if (i >= 0 && i < ctx->listext.nr_opcodes) {
+        ctx->listext.opcode[i].print(ctx, &n[1]);
+        n += ctx->listext.opcode[i].size;
+      } else {
+        switch (opcode) {
          case OPCODE_ACCUM:
             fprintf(f,"accum %s %g\n", enum_string(n[1].e), n[2].f );
            break;
@@ -5663,6 +5626,9 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list )
          case OPCODE_RECTF:
             fprintf( f, "Rectf %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f);
             break;
+         case OPCODE_ROTATE:
+            fprintf(f,"Rotate %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f );
+            break;
          case OPCODE_SCALE:
             fprintf(f,"Scale %g %g %g\n", n[1].f, n[2].f, n[3].f );
             break;
@@ -5683,13 +5649,6 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list )
          case OPCODE_ERROR:
             fprintf(f,"Error: %s %s\n", enum_string(n[1].e), (const char *)n[2].data );
             break;
-        case OPCODE_VERTEX_CASSETTE:
-            fprintf(f,"VERTEX-CASSETTE, id %u, rows %u..%u\n", 
-                   ((struct immediate *) n[1].data)->id,
-                   n[2].ui,
-                   n[3].ui);
-           gl_print_cassette( (struct immediate *) n[1].data );
-           break;
         case OPCODE_CONTINUE:
             fprintf(f,"DISPLAY-LIST-CONTINUE\n");
            n = (Node *) n[1].next;
@@ -5707,11 +5666,11 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list )
             else {
                fprintf(f,"command %d, %u operands\n",opcode,InstSize[opcode]);
             }
-      }
-
-      /* increment n to point to next compiled command */
-      if (opcode!=OPCODE_CONTINUE) {
-        n += InstSize[opcode];
+        }
+        /* increment n to point to next compiled command */
+        if (opcode!=OPCODE_CONTINUE) {
+           n += InstSize[opcode];
+        }
       }
    }
 }
index e24ce6fe738ec7409ebd8d94519c38dbf7195cec..cbe8a4b47c2a95e3f62ab80657a9fc1aa8c2775f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dlist.h,v 1.6 2000/09/24 16:11:55 brianp Exp $ */
+/* $Id: dlist.h,v 1.7 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -54,9 +54,17 @@ extern void _mesa_NewList( GLuint list, GLenum mode );
 
 extern void _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize );
 
-extern void gl_compile_cassette( GLcontext *ctx );
-
 extern void gl_save_error( GLcontext *ctx, GLenum error, const char *s );
 
 
+void *
+_mesa_alloc_instruction( GLcontext *ctx, int opcode, GLint sz );
+
+int
+_mesa_alloc_opcode( GLcontext *ctx, GLuint sz, 
+                   void (*execute)( GLcontext *, void * ),
+                   void (*destroy)( GLcontext *, void * ),
+                   void (*print)( GLcontext *, void * ) );
+
+
 #endif
index afdc59527340275f89cb8160affd65289e1a6871..34e1dcf991b0f255697666abacab6b6e301839dd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: drawpix.c,v 1.44 2000/10/31 18:09:44 keithw Exp $ */
+/* $Id: drawpix.c,v 1.45 2000/11/16 21:05:34 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -31,6 +31,7 @@
 #include "glheader.h"
 #include "colormac.h"
 #include "context.h"
+#include "drawpix.h"
 #include "feedback.h"
 #include "macros.h"
 #include "mem.h"
@@ -52,7 +53,7 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
                   GLenum format, GLenum type, const GLvoid *pixels )
 {
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels");
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "_mesa_DrawPixels" );
 
    if (ctx->RenderMode==GL_RENDER) {
       GLint x, y;
@@ -86,6 +87,9 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
       if (ctx->Current.RasterPosValid) {
          GLfloat color[4];
         GLfloat texcoord[4], invq;
+
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
+
          color[0] = CHAN_TO_FLOAT(ctx->Current.Color[0]);
          color[1] = CHAN_TO_FLOAT(ctx->Current.Color[1]);
          color[2] = CHAN_TO_FLOAT(ctx->Current.Color[2]);
index 3d21f95bea1ff152bf2c14f7af05eb1a38e9ee16..afcb916fe8a974e5a10b64f60379e288f5bf2ea8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: enable.c,v 1.31 2000/11/05 18:40:57 keithw Exp $ */
+/* $Id: enable.c,v 1.32 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "enable.h"
 #include "light.h"
 #include "macros.h"
-#include "matrix.h"
 #include "mmath.h"
 #include "simple_list.h"
 #include "types.h"
-#include "vbfill.h"
-#include "xform.h"
 #include "enums.h"
+
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
+
 #endif
 
 
@@ -98,10 +99,14 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state )
               ctx->_Enabled |= ENABLE_USERCLIP;
               ctx->Transform._AnyClip++;
               
-              if (ctx->ProjectionMatrix.flags & MAT_DIRTY_ALL_OVER) {
-                 gl_matrix_analyze( &ctx->ProjectionMatrix );
+              if (ctx->ProjectionMatrix.flags & MAT_DIRTY) {
+                 _math_matrix_analyze( &ctx->ProjectionMatrix );
               }
               
+              /* This derived state also calculated in clip.c and
+               * from gl_update_state() on changes to EyeUserPlane
+               * and ctx->ProjectionMatrix respectively.
+               */
               gl_transform_vector( ctx->Transform._ClipUserPlane[p],
                                    ctx->Transform.EyeUserPlane[p],
                                    ctx->ProjectionMatrix.inv );
@@ -113,10 +118,13 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state )
         break;
       case GL_COLOR_MATERIAL:
          if (ctx->Light.ColorMaterialEnabled!=state) {
-            ctx->Light.ColorMaterialEnabled = state;
+           ctx->Light.ColorMaterialEnabled = state;
            ctx->NewState |= _NEW_LIGHT;
-            if (state)
+
+            if (state) {
+              FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
                gl_update_color_material( ctx, ctx->Current.Color );
+           }
          }
         break;
       case GL_CULL_FACE:
index 1c779eb5e3236fa90f0bd5f94659163e8a6623fb..1cb8e26d1ac6110180562ab9d6f3a634fb17e289 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: eval.c,v 1.14 2000/10/30 13:32:00 keithw Exp $ */
+/* $Id: eval.c,v 1.15 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "mem.h"
 #include "mmath.h"
 #include "types.h"
-#include "vb.h"
-#include "vbcull.h"
-#include "vbfill.h"
-#include "vbxform.h"
 #endif
 
 
-static GLfloat inv_tab[MAX_EVAL_ORDER];
-
-/*
- * Do one-time initialization for evaluators.
- */
-void gl_init_eval( void )
-{
-  static int init_flag = 0;
-  GLuint i;
-
-  /* Compute a table of nCr (combination) values used by the
-   * Bernstein polynomial generator.
-   */
-
-  /* KW: precompute 1/x for useful x.
-   */
-  if (init_flag==0) 
-  { 
-     for (i = 1 ; i < MAX_EVAL_ORDER ; i++)
-       inv_tab[i] = 1.0 / i;
-  }
-
-  init_flag = 1;
-}
-
-
-
-/*
- * Horner scheme for Bezier curves
- * 
- * Bezier curves can be computed via a Horner scheme.
- * Horner is numerically less stable than the de Casteljau
- * algorithm, but it is faster. For curves of degree n 
- * the complexity of Horner is O(n) and de Casteljau is O(n^2).
- * Since stability is not important for displaying curve 
- * points I decided to use the Horner scheme.
- *
- * A cubic Bezier curve with control points b0, b1, b2, b3 can be 
- * written as
- *
- *        (([3]        [3]     )     [3]       )     [3]
- * c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3
- *
- *                                           [n]
- * where s=1-t and the binomial coefficients [i]. These can 
- * be computed iteratively using the identity:
- *
- * [n]               [n  ]             [n]
- * [i] = (n-i+1)/i * [i-1]     and     [0] = 1
- */
-
-
-static void
-horner_bezier_curve(const GLfloat *cp, GLfloat *out, GLfloat t,
-                    GLuint dim, GLuint order)
-{
-  GLfloat s, powert;
-  GLuint i, k, bincoeff;
-
-  if(order >= 2)
-  { 
-    bincoeff = order-1;
-    s = 1.0-t;
-
-    for(k=0; k<dim; k++)
-      out[k] = s*cp[k] + bincoeff*t*cp[dim+k];
-
-    for(i=2, cp+=2*dim, powert=t*t; i<order; i++, powert*=t, cp +=dim)
-    {
-      bincoeff *= order-i;
-      bincoeff *= inv_tab[i];
-
-      for(k=0; k<dim; k++)
-        out[k] = s*out[k] + bincoeff*powert*cp[k];
-    }
-  }
-  else /* order=1 -> constant curve */
-  { 
-    for(k=0; k<dim; k++)
-      out[k] = cp[k];
-  } 
-}
-
-/*
- * Tensor product Bezier surfaces
- *
- * Again the Horner scheme is used to compute a point on a 
- * TP Bezier surface. First a control polygon for a curve
- * on the surface in one parameter direction is computed,
- * then the point on the curve for the other parameter 
- * direction is evaluated.
- *
- * To store the curve control polygon additional storage
- * for max(uorder,vorder) points is needed in the 
- * control net cn.
- */
-
-static void
-horner_bezier_surf(GLfloat *cn, GLfloat *out, GLfloat u, GLfloat v,
-                   GLuint dim, GLuint uorder, GLuint vorder)
-{
-  GLfloat *cp = cn + uorder*vorder*dim;
-  GLuint i, uinc = vorder*dim;
-
-  if(vorder > uorder)
-  {
-    if(uorder >= 2)
-    { 
-      GLfloat s, poweru;
-      GLuint j, k, bincoeff;
-
-      /* Compute the control polygon for the surface-curve in u-direction */
-      for(j=0; j<vorder; j++)
-      {
-        GLfloat *ucp = &cn[j*dim];
-
-        /* Each control point is the point for parameter u on a */ 
-        /* curve defined by the control polygons in u-direction */
-       bincoeff = uorder-1;
-       s = 1.0-u;
-
-       for(k=0; k<dim; k++)
-         cp[j*dim+k] = s*ucp[k] + bincoeff*u*ucp[uinc+k];
-
-       for(i=2, ucp+=2*uinc, poweru=u*u; i<uorder; 
-            i++, poweru*=u, ucp +=uinc)
-       {
-         bincoeff *= uorder-i;
-          bincoeff *= inv_tab[i];
-
-         for(k=0; k<dim; k++)
-           cp[j*dim+k] = s*cp[j*dim+k] + bincoeff*poweru*ucp[k];
-       }
-      }
-        
-      /* Evaluate curve point in v */
-      horner_bezier_curve(cp, out, v, dim, vorder);
-    }
-    else /* uorder=1 -> cn defines a curve in v */
-      horner_bezier_curve(cn, out, v, dim, vorder);
-  }
-  else /* vorder <= uorder */
-  {
-    if(vorder > 1)
-    {
-      GLuint i;
-
-      /* Compute the control polygon for the surface-curve in u-direction */
-      for(i=0; i<uorder; i++, cn += uinc)
-      {
-       /* For constant i all cn[i][j] (j=0..vorder) are located */
-       /* on consecutive memory locations, so we can use        */
-       /* horner_bezier_curve to compute the control points     */
-
-       horner_bezier_curve(cn, &cp[i*dim], v, dim, vorder);
-      }
-
-      /* Evaluate curve point in u */
-      horner_bezier_curve(cp, out, u, dim, uorder);
-    }
-    else  /* vorder=1 -> cn defines a curve in u */
-      horner_bezier_curve(cn, out, u, dim, uorder);
-  }
-}
-
-/*
- * The direct de Casteljau algorithm is used when a point on the
- * surface and the tangent directions spanning the tangent plane
- * should be computed (this is needed to compute normals to the
- * surface). In this case the de Casteljau algorithm approach is
- * nicer because a point and the partial derivatives can be computed 
- * at the same time. To get the correct tangent length du and dv
- * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1. 
- * Since only the directions are needed, this scaling step is omitted.
- *
- * De Casteljau needs additional storage for uorder*vorder
- * values in the control net cn.
- */
-
-static void
-de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv,
-                  GLfloat u, GLfloat v, GLuint dim, 
-                  GLuint uorder, GLuint vorder)
-{
-  GLfloat *dcn = cn + uorder*vorder*dim;
-  GLfloat us = 1.0-u, vs = 1.0-v;
-  GLuint h, i, j, k;
-  GLuint minorder = uorder < vorder ? uorder : vorder;
-  GLuint uinc = vorder*dim;
-  GLuint dcuinc = vorder;
-  /* Each component is evaluated separately to save buffer space  */
-  /* This does not drasticaly decrease the performance of the     */
-  /* algorithm. If additional storage for (uorder-1)*(vorder-1)   */
-  /* points would be available, the components could be accessed  */
-  /* in the innermost loop which could lead to less cache misses. */
-
-#define CN(I,J,K) cn[(I)*uinc+(J)*dim+(K)] 
-#define DCN(I, J) dcn[(I)*dcuinc+(J)]
-  if(minorder < 3)
-  {
-    if(uorder==vorder)
-    {
-      for(k=0; k<dim; k++)
-      {
-       /* Derivative direction in u */
-       du[k] = vs*(CN(1,0,k) - CN(0,0,k)) +
-                v*(CN(1,1,k) - CN(0,1,k));
-
-       /* Derivative direction in v */
-       dv[k] = us*(CN(0,1,k) - CN(0,0,k)) + 
-                u*(CN(1,1,k) - CN(1,0,k));
-
-       /* bilinear de Casteljau step */
-        out[k] =  us*(vs*CN(0,0,k) + v*CN(0,1,k)) +
-                  u*(vs*CN(1,0,k) + v*CN(1,1,k));
-      }
-    }
-    else if(minorder == uorder)
-    {
-      for(k=0; k<dim; k++)
-      {
-       /* bilinear de Casteljau step */
-       DCN(1,0) =    CN(1,0,k) -   CN(0,0,k);
-       DCN(0,0) = us*CN(0,0,k) + u*CN(1,0,k);
-
-       for(j=0; j<vorder-1; j++)
-       {
-         /* for the derivative in u */
-         DCN(1,j+1) =    CN(1,j+1,k) -   CN(0,j+1,k);
-         DCN(1,j)   = vs*DCN(1,j)    + v*DCN(1,j+1);
-
-         /* for the `point' */
-         DCN(0,j+1) = us*CN(0,j+1,k) + u*CN(1,j+1,k);
-         DCN(0,j)   = vs*DCN(0,j)    + v*DCN(0,j+1);
-       }
-        
-       /* remaining linear de Casteljau steps until the second last step */
-       for(h=minorder; h<vorder-1; h++)
-         for(j=0; j<vorder-h; j++)
-         {
-           /* for the derivative in u */
-           DCN(1,j) = vs*DCN(1,j) + v*DCN(1,j+1);
-
-           /* for the `point' */
-           DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1);
-         }
-
-       /* derivative direction in v */
-       dv[k] = DCN(0,1) - DCN(0,0);
-
-       /* derivative direction in u */
-       du[k] =   vs*DCN(1,0) + v*DCN(1,1);
-
-       /* last linear de Casteljau step */
-       out[k] =  vs*DCN(0,0) + v*DCN(0,1);
-      }
-    }
-    else /* minorder == vorder */
-    {
-      for(k=0; k<dim; k++)
-      {
-       /* bilinear de Casteljau step */
-       DCN(0,1) =    CN(0,1,k) -   CN(0,0,k);
-       DCN(0,0) = vs*CN(0,0,k) + v*CN(0,1,k);
-       for(i=0; i<uorder-1; i++)
-       {
-         /* for the derivative in v */
-         DCN(i+1,1) =    CN(i+1,1,k) -   CN(i+1,0,k);
-         DCN(i,1)   = us*DCN(i,1)    + u*DCN(i+1,1);
-
-         /* for the `point' */
-         DCN(i+1,0) = vs*CN(i+1,0,k) + v*CN(i+1,1,k);
-         DCN(i,0)   = us*DCN(i,0)    + u*DCN(i+1,0);
-       }
-        
-       /* remaining linear de Casteljau steps until the second last step */
-       for(h=minorder; h<uorder-1; h++)
-         for(i=0; i<uorder-h; i++)
-         {
-           /* for the derivative in v */
-           DCN(i,1) = us*DCN(i,1) + u*DCN(i+1,1);
-
-           /* for the `point' */
-           DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
-         }
-
-       /* derivative direction in u */
-       du[k] = DCN(1,0) - DCN(0,0);
-
-       /* derivative direction in v */
-       dv[k] =   us*DCN(0,1) + u*DCN(1,1);
-
-       /* last linear de Casteljau step */
-       out[k] =  us*DCN(0,0) + u*DCN(1,0);
-      }
-    }
-  }
-  else if(uorder == vorder)
-  {
-    for(k=0; k<dim; k++)
-    {
-      /* first bilinear de Casteljau step */
-      for(i=0; i<uorder-1; i++)
-      {
-       DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
-       for(j=0; j<vorder-1; j++)
-       {
-         DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
-         DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
-       }
-      }
-
-      /* remaining bilinear de Casteljau steps until the second last step */
-      for(h=2; h<minorder-1; h++)
-       for(i=0; i<uorder-h; i++)
-       {
-         DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
-         for(j=0; j<vorder-h; j++)
-         {
-           DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
-           DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
-         }
-       }
-
-      /* derivative direction in u */
-      du[k] = vs*(DCN(1,0) - DCN(0,0)) +
-              v*(DCN(1,1) - DCN(0,1));
-
-      /* derivative direction in v */
-      dv[k] = us*(DCN(0,1) - DCN(0,0)) + 
-              u*(DCN(1,1) - DCN(1,0));
-
-      /* last bilinear de Casteljau step */
-      out[k] =  us*(vs*DCN(0,0) + v*DCN(0,1)) +
-                u*(vs*DCN(1,0) + v*DCN(1,1));
-    }
-  }
-  else if(minorder == uorder)
-  {
-    for(k=0; k<dim; k++)
-    {
-      /* first bilinear de Casteljau step */
-      for(i=0; i<uorder-1; i++)
-      {
-       DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
-       for(j=0; j<vorder-1; j++)
-       {
-         DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
-         DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
-       }
-      }
-
-      /* remaining bilinear de Casteljau steps until the second last step */
-      for(h=2; h<minorder-1; h++)
-       for(i=0; i<uorder-h; i++)
-       {
-         DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
-         for(j=0; j<vorder-h; j++)
-         {
-           DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
-           DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
-         }
-       }
-
-      /* last bilinear de Casteljau step */
-      DCN(2,0) =    DCN(1,0) -   DCN(0,0);
-      DCN(0,0) = us*DCN(0,0) + u*DCN(1,0);
-      for(j=0; j<vorder-1; j++)
-      {
-       /* for the derivative in u */
-       DCN(2,j+1) =    DCN(1,j+1) -    DCN(0,j+1);
-       DCN(2,j)   = vs*DCN(2,j)    + v*DCN(2,j+1);
-       
-       /* for the `point' */
-       DCN(0,j+1) = us*DCN(0,j+1 ) + u*DCN(1,j+1);
-       DCN(0,j)   = vs*DCN(0,j)    + v*DCN(0,j+1);
-      }
-        
-      /* remaining linear de Casteljau steps until the second last step */
-      for(h=minorder; h<vorder-1; h++)
-       for(j=0; j<vorder-h; j++)
-       {
-         /* for the derivative in u */
-         DCN(2,j) = vs*DCN(2,j) + v*DCN(2,j+1);
-         
-         /* for the `point' */
-         DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1);
-       }
-      
-      /* derivative direction in v */
-      dv[k] = DCN(0,1) - DCN(0,0);
-      
-      /* derivative direction in u */
-      du[k] =   vs*DCN(2,0) + v*DCN(2,1);
-      
-      /* last linear de Casteljau step */
-      out[k] =  vs*DCN(0,0) + v*DCN(0,1);
-    }
-  }
-  else /* minorder == vorder */
-  {
-    for(k=0; k<dim; k++)
-    {
-      /* first bilinear de Casteljau step */
-      for(i=0; i<uorder-1; i++)
-      {
-       DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
-       for(j=0; j<vorder-1; j++)
-       {
-         DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
-         DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
-       }
-      }
-
-      /* remaining bilinear de Casteljau steps until the second last step */
-      for(h=2; h<minorder-1; h++)
-       for(i=0; i<uorder-h; i++)
-       {
-         DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
-         for(j=0; j<vorder-h; j++)
-         {
-           DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
-           DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
-         }
-       }
-
-      /* last bilinear de Casteljau step */
-      DCN(0,2) =    DCN(0,1) -   DCN(0,0);
-      DCN(0,0) = vs*DCN(0,0) + v*DCN(0,1);
-      for(i=0; i<uorder-1; i++)
-      {
-       /* for the derivative in v */
-       DCN(i+1,2) =    DCN(i+1,1)  -   DCN(i+1,0);
-       DCN(i,2)   = us*DCN(i,2)    + u*DCN(i+1,2);
-       
-       /* for the `point' */
-       DCN(i+1,0) = vs*DCN(i+1,0)  + v*DCN(i+1,1);
-       DCN(i,0)   = us*DCN(i,0)    + u*DCN(i+1,0);
-      }
-      
-      /* remaining linear de Casteljau steps until the second last step */
-      for(h=minorder; h<uorder-1; h++)
-       for(i=0; i<uorder-h; i++)
-       {
-         /* for the derivative in v */
-         DCN(i,2) = us*DCN(i,2) + u*DCN(i+1,2);
-         
-         /* for the `point' */
-         DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
-       }
-      
-      /* derivative direction in u */
-      du[k] = DCN(1,0) - DCN(0,0);
-      
-      /* derivative direction in v */
-      dv[k] =   us*DCN(0,2) + u*DCN(1,2);
-      
-      /* last linear de Casteljau step */
-      out[k] =  us*DCN(0,0) + u*DCN(1,0);
-    }
-  }
-#undef DCN
-#undef CN
-}
-
 /*
  * Return the number of components per control point for any type of
  * evaluator.  Return 0 if bad target.
@@ -1982,656 +1512,6 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
 
 
 
-static void eval_points1( GLfloat outcoord[][4], 
-                         GLfloat coord[][4],
-                         const GLuint *flags,
-                         GLuint start,
-                         GLfloat du, GLfloat u1 )
-{
-   GLuint i;
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & VERT_EVAL_P1) 
-        outcoord[i][0] = coord[i][0] * du + u1;
-      else if (flags[i] & VERT_EVAL_ANY) {
-        outcoord[i][0] = coord[i][0];
-        outcoord[i][1] = coord[i][1];
-      }
-}
-
-static void eval_points2( GLfloat outcoord[][4], 
-                         GLfloat coord[][4],
-                         const GLuint *flags,
-                         GLuint start,
-                         GLfloat du, GLfloat u1,
-                         GLfloat dv, GLfloat v1 )
-{
-   GLuint i;
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & VERT_EVAL_P2) {
-        outcoord[i][0] = coord[i][0] * du + u1;
-        outcoord[i][1] = coord[i][1] * dv + v1;
-      } else if (flags[i] & VERT_EVAL_ANY) {
-        outcoord[i][0] = coord[i][0];
-        outcoord[i][1] = coord[i][1];
-      }
-}
-
-
-static const GLubyte dirty_flags[5] = {
-   0,                          /* not possible */
-   VEC_DIRTY_0,
-   VEC_DIRTY_1, 
-   VEC_DIRTY_2, 
-   VEC_DIRTY_3
-};
-
-
-static GLvector4f *eval1_4f( GLvector4f *dest, 
-                            GLfloat coord[][4], 
-                            const GLuint *flags,
-                            GLuint start,
-                            GLuint dimension,
-                            struct gl_1d_map *map )
-{
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   GLfloat (*to)[4] = dest->data;
-   GLuint i;
-   
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        ASSIGN_4V(to[i], 0,0,0,1);
-        horner_bezier_curve(map->Points, to[i], u, dimension, map->Order);
-      }
-
-   dest->count = i;
-   dest->start = VEC_ELT(dest, GLfloat, start);
-   dest->size = MAX2(dest->size, dimension);
-   dest->flags |= dirty_flags[dimension];
-   return dest;
-}
-
-
-static GLvector1ui *eval1_1ui( GLvector1ui *dest, 
-                              GLfloat coord[][4], 
-                              const GLuint *flags,
-                              GLuint start,
-                              struct gl_1d_map *map )
-{
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   GLuint *to = dest->data;
-   GLuint i;
-
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        GLfloat tmp;
-        horner_bezier_curve(map->Points, &tmp, u, 1, map->Order);
-        to[i] = (GLuint) (GLint) tmp;
-      }
-
-   dest->start = VEC_ELT(dest, GLuint, start);
-   dest->count = i;
-   return dest;
-}
-
-static GLvector3f *eval1_norm( GLvector3f *dest, 
-                              GLfloat coord[][4],
-                              GLuint *flags, /* not const */
-                              GLuint start,
-                              struct gl_1d_map *map )
-{
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   GLfloat (*to)[3] = dest->data;
-   GLuint i;
-
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        horner_bezier_curve(map->Points, to[i], u, 3, map->Order);
-        flags[i+1] |= VERT_NORM; /* reset */
-      }
-
-   dest->start = VEC_ELT(dest, GLfloat, start);
-   dest->count = i;
-   return dest;
-}
-
-static GLvector4ub *eval1_color( GLvector4ub *dest, 
-                                GLfloat coord[][4],
-                                GLuint *flags, /* not const */
-                                GLuint start,
-                                struct gl_1d_map *map )
-{   
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   GLubyte (*to)[4] = dest->data;
-   GLuint i;
-
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        GLfloat fcolor[4];
-        horner_bezier_curve(map->Points, fcolor, u, 4, map->Order);
-        FLOAT_RGBA_TO_CHAN_RGBA(to[i], fcolor);
-        flags[i+1] |= VERT_RGBA; /* reset */
-      }
-
-   dest->start = VEC_ELT(dest, GLubyte, start);
-   dest->count = i;
-   return dest;
-}
-
-
-
-
-static GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr, 
-                                  GLvector3f *norm_ptr,
-                                  GLfloat coord[][4], 
-                                  GLuint *flags, 
-                                  GLuint start,
-                                  GLuint dimension,
-                                  struct gl_2d_map *map )
-{
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   const GLfloat v1 = map->v1;
-   const GLfloat dv = map->dv;
-   GLfloat (*obj)[4] = obj_ptr->data;
-   GLfloat (*normal)[3] = norm_ptr->data;
-   GLuint i;
-   
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        GLfloat v = (coord[i][1] - v1) * dv;
-        GLfloat du[4], dv[4];
-
-        ASSIGN_4V(obj[i], 0,0,0,1);
-        de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension,
-                          map->Uorder, map->Vorder);
-              
-        CROSS3(normal[i], du, dv);
-        NORMALIZE_3FV(normal[i]);
-        flags[i+1] |= VERT_NORM;
-      }
-   obj_ptr->start = VEC_ELT(obj_ptr, GLfloat, start);
-   obj_ptr->count = i;
-   obj_ptr->size = MAX2(obj_ptr->size, dimension);
-   obj_ptr->flags |= dirty_flags[dimension];
-   return obj_ptr;
-}
-
-
-static GLvector4f *eval2_4f( GLvector4f *dest, 
-                            GLfloat coord[][4], 
-                            const GLuint *flags,
-                            GLuint start,
-                            GLuint dimension,
-                            struct gl_2d_map *map )
-{
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   const GLfloat v1 = map->v1;
-   const GLfloat dv = map->dv;
-   GLfloat (*to)[4] = dest->data;
-   GLuint i;
-
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        GLfloat v = (coord[i][1] - v1) * dv;
-        horner_bezier_surf(map->Points, to[i], u, v, dimension,
-                           map->Uorder, map->Vorder);
-      }
-
-   dest->start = VEC_ELT(dest, GLfloat, start);
-   dest->count = i;
-   dest->size = MAX2(dest->size, dimension);
-   dest->flags |= dirty_flags[dimension];
-   return dest;
-}
-
-
-static GLvector3f *eval2_norm( GLvector3f *dest, 
-                              GLfloat coord[][4], 
-                              GLuint *flags, 
-                              GLuint start,
-                              struct gl_2d_map *map )
-{
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   const GLfloat v1 = map->v1;
-   const GLfloat dv = map->dv;
-   GLfloat (*to)[3] = dest->data;
-   GLuint i;
-
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        GLfloat v = (coord[i][1] - v1) * dv;
-        horner_bezier_surf(map->Points, to[i], u, v, 3,
-                           map->Uorder, map->Vorder);
-        flags[i+1] |= VERT_NORM; /* reset */
-     }
-
-   dest->start = VEC_ELT(dest, GLfloat, start);
-   dest->count = i;
-   return dest;
-}
-
-
-static GLvector1ui *eval2_1ui( GLvector1ui *dest, 
-                              GLfloat coord[][4], 
-                              const GLuint *flags,
-                              GLuint start,
-                              struct gl_2d_map *map )
-{
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   const GLfloat v1 = map->v1;
-   const GLfloat dv = map->dv;
-   GLuint *to = dest->data;
-   GLuint i;
-
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        GLfloat v = (coord[i][1] - v1) * dv;
-        GLfloat tmp;
-        horner_bezier_surf(map->Points, &tmp, u, v, 1,
-                           map->Uorder, map->Vorder);
-
-        to[i] = (GLuint) (GLint) tmp;
-      }
-
-   dest->start = VEC_ELT(dest, GLuint, start);
-   dest->count = i;
-   return dest;
-}
-
-
-
-static GLvector4ub *eval2_color( GLvector4ub *dest,
-                                GLfloat coord[][4], 
-                                GLuint *flags,
-                                GLuint start,
-                                struct gl_2d_map *map )
-{
-   const GLfloat u1 = map->u1;
-   const GLfloat du = map->du;
-   const GLfloat v1 = map->v1;
-   const GLfloat dv = map->dv;
-   GLubyte (*to)[4] = dest->data;
-   GLuint i;
-
-   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
-      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
-        GLfloat u = (coord[i][0] - u1) * du;
-        GLfloat v = (coord[i][1] - v1) * dv;
-        GLfloat fcolor[4];
-        horner_bezier_surf(map->Points, fcolor, u, v, 4,
-                           map->Uorder, map->Vorder);
-        FLOAT_RGBA_TO_CHAN_RGBA(to[i], fcolor);
-        flags[i+1] |= VERT_RGBA; /* reset */
-      }
-
-   dest->start = VEC_ELT(dest, GLubyte, start);
-   dest->count = i;
-   return dest;
-}
-
-
-static GLvector4f *copy_4f( GLvector4f *out, CONST GLvector4f *in, 
-                           const GLuint *flags,
-                           GLuint start )
-{
-   GLfloat (*to)[4] = out->data;
-   GLfloat (*from)[4] = in->data;
-   GLuint i;
-   
-   for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) 
-      if (!(flags[i] & VERT_EVAL_ANY)) 
-        COPY_4FV( to[i], from[i] );
-   
-   out->start = VEC_ELT(out, GLfloat, start);
-   return out;
-}
-
-static GLvector3f *copy_3f( GLvector3f *out, CONST GLvector3f *in, 
-                           const GLuint *flags,
-                           GLuint start )
-{
-   GLfloat (*to)[3] = out->data;
-   GLfloat (*from)[3] = in->data;
-   GLuint i;
-   
-   for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) 
-      if (!(flags[i] & VERT_EVAL_ANY)) 
-        COPY_3V( to[i], from[i] );
-   
-   out->start = VEC_ELT(out, GLfloat, start);
-   return out;
-}
-
-static GLvector4ub *copy_4ub( GLvector4ub *out, 
-                             CONST GLvector4ub *in, 
-                             const GLuint *flags,
-                             GLuint start )
-{
-   GLubyte (*to)[4] = out->data;
-   GLubyte (*from)[4] = in->data;
-   GLuint i;
-   
-   for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) 
-      if (!(flags[i] & VERT_EVAL_ANY)) 
-        COPY_4UBV( to[i], from[i] );
-
-   out->start = VEC_ELT(out, GLubyte, start);
-   return out;
-}
-
-static GLvector1ui *copy_1ui( GLvector1ui *out, 
-                             CONST GLvector1ui *in, 
-                             const GLuint *flags,
-                             GLuint start )
-{
-   GLuint *to = out->data;
-   CONST GLuint *from = in->data;
-   GLuint i;
-   
-   for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) 
-      if (!(flags[i] & VERT_EVAL_ANY)) 
-        to[i] = from[i];
-
-   out->start = VEC_ELT(out, GLuint, start);
-   return out;
-}
-
-
-/* KW: Rewrote this to perform eval on a whole buffer at once.
- *     Only evaluates active data items, and avoids scribbling
- *     the source buffer if we are running from a display list.
- *
- *     If the user (in this case looser) sends eval coordinates
- *     or runs a display list containing eval coords with no
- *     vertex maps enabled, we have to either copy all non-eval
- *     data to a new buffer, or find a way of working around
- *     the eval data.  I choose the second option.
- *
- * KW: This code not reached by cva - use IM to access storage.
- */
-void gl_eval_vb( struct vertex_buffer *VB )
-{
-   struct immediate *IM = VB->IM;
-   GLcontext *ctx = VB->ctx;
-   GLuint req = ctx->CVA.elt.inputs;
-   GLfloat (*coord)[4] = VB->ObjPtr->data;
-   GLuint *flags = VB->Flag;
-   GLuint new_flags = 0;
-   
-
-   GLuint any_eval1 = VB->OrFlag & (VERT_EVAL_C1|VERT_EVAL_P1);
-   GLuint any_eval2 = VB->OrFlag & (VERT_EVAL_C2|VERT_EVAL_P2);
-   GLuint all_eval = IM->AndFlag & VERT_EVAL_ANY;
-
-   /* Handle the degenerate cases.
-    */
-   if (any_eval1 && !ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) {
-      VB->PurgeFlags |= (VERT_EVAL_C1|VERT_EVAL_P1);
-      VB->EarlyCull = 0;
-      any_eval1 = GL_FALSE;
-   }
-  
-   if (any_eval2 && !ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) {
-      VB->PurgeFlags |= (VERT_EVAL_C2|VERT_EVAL_P2);
-      VB->EarlyCull = 0;
-      any_eval2 = GL_FALSE;
-   }
-
-   /* KW: This really is a degenerate case - doing this disables
-    * culling, and causes dummy values for the missing vertices to be
-    * transformed and clip tested.  It also forces the individual
-    * cliptesting of each primitive in vb_render.  I wish there was a
-    * nice alternative, but I can't say I want to put effort into
-    * optimizing such a bad usage of the library - I'd much rather
-    * work on useful changes.
-    */
-   if (VB->PurgeFlags) {
-      if (!any_eval1 && !any_eval2 && all_eval) VB->Count = VB->Start;
-      gl_purge_vertices( VB );
-      if (!any_eval1 && !any_eval2) return;
-   } else
-      VB->IndirectCount = VB->Count;
-
-   /* Translate points into coords.
-    */
-   if (any_eval1 && (VB->OrFlag & VERT_EVAL_P1)) 
-   {
-      eval_points1( IM->Obj, coord, flags, IM->Start,
-                   ctx->Eval.MapGrid1du,
-                   ctx->Eval.MapGrid1u1);
-
-      coord = IM->Obj;
-   }
-
-   if (any_eval2 && (VB->OrFlag & VERT_EVAL_P2)) 
-   {
-      eval_points2( IM->Obj, coord, flags, IM->Start,
-                   ctx->Eval.MapGrid2du,
-                   ctx->Eval.MapGrid2u1,
-                   ctx->Eval.MapGrid2dv,
-                   ctx->Eval.MapGrid2v1 );
-
-      coord = IM->Obj;
-   }
-
-   /* Perform the evaluations on active data elements.
-    */
-   if (req & VERT_INDEX) 
-   {
-      GLvector1ui  *in_index = VB->IndexPtr;
-      GLvector1ui  *out_index = &IM->v.Index;
-
-      if (ctx->Eval.Map1Index && any_eval1) 
-        VB->IndexPtr = eval1_1ui( out_index, coord, flags, IM->Start,
-                                  &ctx->EvalMap.Map1Index );
-      
-      if (ctx->Eval.Map2Index && any_eval2)
-        VB->IndexPtr = eval2_1ui( out_index, coord, flags, IM->Start,
-                                  &ctx->EvalMap.Map2Index );
-        
-      if (VB->IndexPtr != in_index) {
-        new_flags |= VERT_INDEX;
-        if (!all_eval)
-           VB->IndexPtr = copy_1ui( out_index, in_index, flags, IM->Start );
-      }
-   }
-
-   if (req & VERT_RGBA) 
-   {   
-      GLvector4ub  *in_color = VB->ColorPtr;
-      GLvector4ub  *out_color = &IM->v.Color;
-
-      if (ctx->Eval.Map1Color4 && any_eval1) 
-        VB->ColorPtr = eval1_color( out_color, coord, flags, IM->Start,
-                                    &ctx->EvalMap.Map1Color4 );
-      
-      if (ctx->Eval.Map2Color4 && any_eval2)
-        VB->ColorPtr = eval2_color( out_color, coord, flags, IM->Start,
-                                    &ctx->EvalMap.Map2Color4 );
-        
-      if (VB->ColorPtr != in_color) {
-        new_flags |= VERT_RGBA;
-        if (!all_eval)
-           VB->ColorPtr = copy_4ub( out_color, in_color, flags, IM->Start );
-      }
-
-      VB->Color[0] = VB->Color[1] = VB->ColorPtr;
-   }
-
-
-   if (req & VERT_NORM) 
-   {   
-      GLvector3f  *in_normal = VB->NormalPtr;
-      GLvector3f  *out_normal = &IM->v.Normal;
-
-      if (ctx->Eval.Map1Normal && any_eval1) 
-        VB->NormalPtr = eval1_norm( out_normal, coord, flags, IM->Start,
-                                    &ctx->EvalMap.Map1Normal );
-      
-      if (ctx->Eval.Map2Normal && any_eval2)
-        VB->NormalPtr = eval2_norm( out_normal, coord, flags, IM->Start,
-                                    &ctx->EvalMap.Map2Normal );
-        
-      new_flags |= VERT_NORM;
-
-      if (VB->NormalPtr != in_normal) {
-        if (!all_eval)
-           VB->NormalPtr = copy_3f( out_normal, in_normal, flags, IM->Start );
-      }
-   }
-
-     
-   if (req & VERT_TEX_ANY(0)) 
-   {
-      GLvector4f *tc = VB->TexCoordPtr[0];
-      GLvector4f *in = tc;
-      GLvector4f *out = &IM->v.TexCoord[0];
-
-      if (any_eval1) {
-        if (ctx->Eval.Map1TextureCoord4) 
-           tc = eval1_4f( out, coord, flags, IM->Start, 
-                          4, &ctx->EvalMap.Map1Texture4);
-        else if (ctx->Eval.Map1TextureCoord3) 
-           tc = eval1_4f( out, coord, flags, IM->Start, 3,
-                          &ctx->EvalMap.Map1Texture3);
-        else if (ctx->Eval.Map1TextureCoord2) 
-           tc = eval1_4f( out, coord, flags, IM->Start, 2,
-                          &ctx->EvalMap.Map1Texture2);
-        else if (ctx->Eval.Map1TextureCoord1) 
-           tc = eval1_4f( out, coord, flags, IM->Start, 1,
-                          &ctx->EvalMap.Map1Texture1);
-      }
-
-      if (any_eval2) {
-        if (ctx->Eval.Map2TextureCoord4) 
-           tc = eval2_4f( out, coord, flags, IM->Start,
-                          4, &ctx->EvalMap.Map2Texture4);
-        else if (ctx->Eval.Map2TextureCoord3) 
-           tc = eval2_4f( out, coord, flags, IM->Start,
-                          3, &ctx->EvalMap.Map2Texture3);
-        else if (ctx->Eval.Map2TextureCoord2) 
-           tc = eval2_4f( out, coord, flags, IM->Start,
-                          2, &ctx->EvalMap.Map2Texture2);
-        else if (ctx->Eval.Map2TextureCoord1) 
-           tc = eval2_4f( out, coord, flags, IM->Start,
-                          1, &ctx->EvalMap.Map2Texture1);
-      }
-
-      if (tc != in) {
-        new_flags |= VERT_TEX_ANY(0); /* fix for sizes.. */
-        if (!all_eval)
-           tc = copy_4f( out, in, flags, IM->Start );
-      }
-
-      VB->TexCoordPtr[0] = tc;
-   }
-
-
-   {
-      GLvector4f *in = VB->ObjPtr;
-      GLvector4f *out = &IM->v.Obj;
-      GLvector4f *obj = in;
-   
-      if (any_eval1) {
-        if (ctx->Eval.Map1Vertex4) 
-           obj = eval1_4f( out, coord, flags, IM->Start,
-                           4, &ctx->EvalMap.Map1Vertex4);
-        else 
-           obj = eval1_4f( out, coord, flags, IM->Start,
-                           3, &ctx->EvalMap.Map1Vertex3);
-      }
-
-      if (any_eval2) {
-        GLvector3f  *in_normal = VB->NormalPtr;
-        GLvector3f  *out_normal = &IM->v.Normal;
-
-        if (ctx->Eval.Map2Vertex4) 
-        {
-           if (ctx->Eval.AutoNormal && (req & VERT_NORM)) {
-              obj = eval2_obj_norm( out, out_normal, coord, flags, 
-                                    IM->Start, 4, &ctx->EvalMap.Map2Vertex4 );
-              VB->NormalPtr = out_normal;
-              new_flags |= VERT_NORM;
-           }
-           else
-              obj = eval2_4f( out, coord, flags, IM->Start,
-                              4, &ctx->EvalMap.Map2Vertex4 );
-        }
-        else if (ctx->Eval.Map2Vertex3) 
-        {
-           if (ctx->Eval.AutoNormal && (req & VERT_NORM)) {
-              obj = eval2_obj_norm( out, out_normal, coord, flags, 
-                                    IM->Start, 3, &ctx->EvalMap.Map2Vertex3 );
-              VB->NormalPtr = out_normal;
-              new_flags |= VERT_NORM;
-           }
-           else
-              obj = eval2_4f( out, coord, flags, IM->Start,
-                              3, &ctx->EvalMap.Map2Vertex3 );
-        }
-
-
-        if (VB->NormalPtr != in_normal) {
-           if (!all_eval)
-              VB->NormalPtr = copy_3f( out_normal, in_normal, flags, 
-                                       IM->Start );
-        }
-      }
-      
-      if (obj != in && !all_eval)
-        obj = copy_4f( out, in, flags, IM->Start );
-
-      VB->ObjPtr = obj;
-   }
-
-   if (new_flags) {
-      GLuint *oldflags = VB->Flag;
-      GLuint *flags = VB->Flag = VB->EvaluatedFlags;
-      GLuint i;
-      GLuint count = VB->Count;
-      GLuint andflag = VB->IM->AndFlag;
-
-      if (!flags) {
-        VB->EvaluatedFlags = (GLuint *) MALLOC(VB->Size * sizeof(GLuint));
-        flags = VB->Flag = VB->EvaluatedFlags;
-      }
-
-      if (all_eval) {
-        for (i = 0 ; i <= count ; i++) 
-           flags[i] = oldflags[i] | new_flags;
-        andflag |= new_flags;
-      } else {
-        andflag = ~0;
-        for (i = 0 ; i <= count ; i++) {
-           flags[i] = oldflags[i];
-           if (flags[i] & VERT_EVAL_ANY) 
-              flags[i] |= new_flags;
-           andflag &= flags[i];
-        }
-      }
-
-      VB->OrFlag |= new_flags;
-      VB->CullMode = (GLubyte) ((andflag & VERT_NORM) ? 0 : COMPACTED_NORMALS);
-   }
-}
-
-
 void
 _mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
 {
@@ -2694,279 +1574,4 @@ _mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
 
 
 
-/* KW: If are compiling, we don't know whether eval will produce a
- *     vertex when it is run in the future.  If this is pure immediate
- *     mode, eval is a noop if neither vertex map is enabled.
- *
- *     Thus we need to have a check in the display list code or
- *     elsewhere for eval(1,2) vertices in the case where
- *     map(1,2)_vertex is disabled, and to purge those vertices from
- *     the vb.  This is currently done
- *     via  modifications to the cull_vb and render_vb operations, and
- *     by using the existing cullmask mechanism for all other operations.  
- */
-
-
-/* KW: Because the eval values don't become 'current', fixup will flow
- *     through these vertices, and then evaluation will write on top
- *     of the fixup results.  
- *
- *     This is a little inefficient, but at least it is correct.  This
- *     could be short-circuited in the case where all vertices are
- *     eval-vertices, or more generally by a cullmask in fixup.
- *
- *     Note: using Obj to hold eval coord data.  This data is actually
- *     transformed if eval is disabled.  But disabling eval & sending
- *     eval coords is stupid, right?
- */
-
-
-#define EVALCOORD1(IM, x)                              \
-{                                                      \
-   GLuint count = IM->Count++;                         \
-   IM->Flag[count] |= VERT_EVAL_C1;                    \
-   ASSIGN_4V(IM->Obj[count], x, 0, 0, 1);              \
-   if (count == VB_MAX-1)                              \
-      _mesa_maybe_transform_vb( IM );                  \
-}
-
-#define EVALCOORD2(IM, x, y)                           \
-{                                                      \
-   GLuint count = IM->Count++;                         \
-   IM->Flag[count] |= VERT_EVAL_C2;                    \
-   ASSIGN_4V(IM->Obj[count], x, y, 0, 1);              \
-   if (count == VB_MAX-1)                              \
-      _mesa_maybe_transform_vb( IM );                  \
-}
-
-#define EVALPOINT1(IM, x)                              \
-{                                                      \
-   GLuint count = IM->Count++;                         \
-   IM->Flag[count] |= VERT_EVAL_P1;                    \
-   ASSIGN_4V(IM->Obj[count], x, 0, 0, 1);              \
-   if (count == VB_MAX-1)                              \
-      _mesa_maybe_transform_vb( IM );                  \
-}
-#define EVALPOINT2(IM, x, y)                           \
-{                                                      \
-   GLuint count = IM->Count++;                         \
-   IM->Flag[count] |= VERT_EVAL_P2;                    \
-   ASSIGN_4V(IM->Obj[count], x, y, 0, 1);              \
-   if (count == VB_MAX-1)                              \
-      _mesa_maybe_transform_vb( IM );                  \
-}
-
-
-/* Lame internal function:
- */
-static void
-eval_coord1f( GLcontext *CC, GLfloat u )
-{
-   struct immediate *i = CC->input;
-   EVALCOORD1( i, u );
-}
-
-
-void
-_mesa_EvalCoord1d( GLdouble u )
-{
-   GET_IMMEDIATE;
-   EVALCOORD1( IM, (GLfloat) u );
-}
-
-
-void
-_mesa_EvalCoord1f( GLfloat u )
-{
-   GET_IMMEDIATE;
-   EVALCOORD1( IM, u );
-}
-
-
-void
-_mesa_EvalCoord1dv( const GLdouble *u )
-{
-   GET_IMMEDIATE;
-   EVALCOORD1( IM, (GLfloat) *u );
-}
-
-
-void
-_mesa_EvalCoord1fv( const GLfloat *u )
-{
-   GET_IMMEDIATE;
-   EVALCOORD1( IM, (GLfloat) *u );
-}
-
-
-void
-_mesa_EvalCoord2d( GLdouble u, GLdouble v )
-{
-   GET_IMMEDIATE;
-   EVALCOORD2( IM, (GLfloat) u, (GLfloat) v );
-}
-
-
-void
-_mesa_EvalCoord2f( GLfloat u, GLfloat v )
-{
-   GET_IMMEDIATE;
-   EVALCOORD2( IM, u, v );
-}
-
-
-/* Lame internal function:
- */
-static void
-eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v )
-{
-   struct immediate *i = CC->input;
-   EVALCOORD2( i, u, v );
-}
-
-
-void
-_mesa_EvalCoord2dv( const GLdouble *u )
-{
-   GET_IMMEDIATE;
-   EVALCOORD2( IM, (GLfloat) u[0], (GLfloat) u[1] );
-}
-
-
-void
-_mesa_EvalCoord2fv( const GLfloat *u )
-{
-   GET_IMMEDIATE;
-   EVALCOORD2( IM, u[0], u[1] );
-}
-
-
-void
-_mesa_EvalPoint1( GLint i )
-{
-   GET_IMMEDIATE;
-   EVALPOINT1( IM, i );
-}
-
-
-void
-_mesa_EvalPoint2( GLint i, GLint j )
-{
-   GET_IMMEDIATE;
-   EVALPOINT2( IM, i, j );
-}
-
-
-
-
-void
-_mesa_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint i;
-   GLfloat u, du;
-   GLenum prim;
-
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glEvalMesh1");
-
-   switch (mode) {
-      case GL_POINT:
-         prim = GL_POINTS;
-         break;
-      case GL_LINE:
-         prim = GL_LINE_STRIP;
-         break;
-      default:
-         gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
-         return;
-   }
-
-   /* No effect if vertex maps disabled.
-    */
-   if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) 
-      return;
-
-   du = ctx->Eval.MapGrid1du;
-   u = ctx->Eval.MapGrid1u1 + i1 * du;
-
-   /* KW: Could short-circuit this to avoid the immediate mechanism.
-    */
-   RESET_IMMEDIATE(ctx);
-
-   gl_Begin( ctx, prim );
-   for (i=i1;i<=i2;i++,u+=du) {
-      eval_coord1f( ctx, u );
-   }
-   gl_End(ctx);
-}
-
-
-
-void
-_mesa_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint i, j;
-   GLfloat u, du, v, dv, v1, u1;
-
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glEvalMesh2");
-
-   /* No effect if vertex maps disabled.
-    */
-   if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) 
-      return;
-
-   du = ctx->Eval.MapGrid2du;
-   dv = ctx->Eval.MapGrid2dv;
-   v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
-   u1 = ctx->Eval.MapGrid2u1 + i1 * du;
-
-   RESET_IMMEDIATE(ctx);
-
-   switch (mode) {
-   case GL_POINT:
-      gl_Begin( ctx, GL_POINTS );
-      for (v=v1,j=j1;j<=j2;j++,v+=dv) {
-        for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           eval_coord2f( ctx, u, v );
-        }
-      }
-      gl_End(ctx);
-      break;
-   case GL_LINE:
-      for (v=v1,j=j1;j<=j2;j++,v+=dv) {
-        gl_Begin( ctx, GL_LINE_STRIP );
-        for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           eval_coord2f( ctx, u, v );
-        }
-        gl_End(ctx);
-      }
-      for (u=u1,i=i1;i<=i2;i++,u+=du) {
-        gl_Begin( ctx, GL_LINE_STRIP );
-        for (v=v1,j=j1;j<=j2;j++,v+=dv) {
-           eval_coord2f( ctx, u, v );
-        }
-        gl_End(ctx);
-      }
-      break;
-   case GL_FILL:
-      for (v=v1,j=j1;j<j2;j++,v+=dv) {
-        /* NOTE: a quad strip can't be used because the four */
-        /* can't be guaranteed to be coplanar! */
-        gl_Begin( ctx, GL_TRIANGLE_STRIP );
-        for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           eval_coord2f( ctx, u, v );
-           eval_coord2f( ctx, u, v+dv );
-        }
-        gl_End(ctx);
-      }
-      break;
-   default:
-      gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
-      return;
-   }
-}
-
-
 
index 0b87be3d5fec8c8319328280858281f1a24a8dfa..e2c61657af8200d19c4e3637e8bfac501622a736 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: eval.h,v 1.2 1999/11/11 01:22:26 brianp Exp $ */
+/* $Id: eval.h,v 1.3 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -61,8 +61,6 @@ extern GLfloat *gl_copy_map_points2d(GLenum target,
                                      const GLdouble *points );
 
 
-extern void gl_eval_vb( struct vertex_buffer *VB );
-
 
 extern void
 _mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
@@ -107,40 +105,5 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v );
 extern void
 _mesa_GetMapiv( GLenum target, GLenum query, GLint *v );
 
-extern void
-_mesa_EvalMesh1( GLenum mode, GLint i1, GLint i2 );
-
-extern void
-_mesa_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 );
-
-extern void
-_mesa_EvalCoord1d( GLdouble u );
-
-extern void
-_mesa_EvalCoord1f( GLfloat u );
-
-extern void
-_mesa_EvalCoord1dv( const GLdouble *u );
-
-extern void
-_mesa_EvalCoord1fv( const GLfloat *u );
-
-extern void
-_mesa_EvalCoord2d( GLdouble u, GLdouble v );
-
-extern void
-_mesa_EvalCoord2f( GLfloat u, GLfloat v );
-
-extern void
-_mesa_EvalCoord2dv( const GLdouble *u );
-
-extern void
-_mesa_EvalCoord2fv( const GLfloat *u );
-
-extern void
-_mesa_EvalPoint1( GLint i );
-
-extern void
-_mesa_EvalPoint2( GLint i, GLint j );
 
 #endif
index 97bf52fc99843b7092eeaf9a79c27a00d7a644de..9593fa2a976cbc8a881d93c3aa0e960b7ead1907 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fog.c,v 1.28 2000/11/05 18:40:58 keithw Exp $ */
+/* $Id: fog.c,v 1.29 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "colormac.h"
 #include "context.h"
 #include "fog.h"
-#include "macros.h"
-#include "mmath.h"
 #include "types.h"
-#include "xform.h"
 #endif
 
 
@@ -146,102 +143,3 @@ _mesa_Fogfv( GLenum pname, const GLfloat *params )
 }
 
 
-
-
-
-static GLvector1f *get_fogcoord_ptr( GLcontext *ctx, GLvector1f *tmp )
-{
-   struct vertex_buffer *VB = ctx->VB;
-
-   if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) {      
-      if (!ctx->_NeedEyeCoords) {
-        GLfloat *m = ctx->ModelView.m;
-        GLfloat plane[4];
-
-        plane[0] = m[2];
-        plane[1] = m[6];
-        plane[2] = m[10];
-        plane[3] = m[14];
-
-        /* Full eye coords weren't required, just calculate the
-         * eye Z values.  
-         */
-        gl_dotprod_tab[0][VB->ObjPtr->size](&VB->Eye, 2,
-                                            VB->ObjPtr, plane, 0 );
-
-        tmp->data = &(VB->Eye.data[0][2]);
-        tmp->start = VB->Eye.start+2;
-        tmp->stride = VB->Eye.stride;
-        return tmp;
-      }
-      else 
-      {
-        if (VB->EyePtr->size < 2)
-           gl_vector4f_clean_elem( &VB->Eye, VB->Count, 2 );
-
-        tmp->data = &(VB->EyePtr->data[0][2]);
-        tmp->start = VB->EyePtr->start+2;
-        tmp->stride = VB->EyePtr->stride;
-        return tmp;
-      }
-   } else
-      return VB->FogCoordPtr;
-}
-
-
-/* Use lookup table & interpolation?
- */
-static void 
-make_win_fog_coords( struct vertex_buffer *VB,
-                    GLvector1f *fogcoord)
-{
-   const GLcontext *ctx = VB->ctx;
-   GLfloat end  = ctx->Fog.End;
-   GLfloat *v = fogcoord->start;
-   GLuint stride = fogcoord->stride;
-   GLuint n = VB->Count - VB->Start;
-   GLfloat *out;               
-   GLfloat d;
-   GLuint i;
-
-   VB->FogCoordPtr = VB->store.FogCoord;
-   out = VB->FogCoordPtr->data + VB->Start;
-
-   switch (ctx->Fog.Mode) {
-   case GL_LINEAR:
-      d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
-      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
-        out[i] = (end - ABSF(*v)) * d;
-        if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]);
-      }
-      break;
-   case GL_EXP:
-      d = -ctx->Fog.Density;
-      for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) {
-        out[i] = exp( d*ABSF(*v) );
-        if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]);
-      }
-      break;
-   case GL_EXP2:
-      d = -(ctx->Fog.Density*ctx->Fog.Density);
-      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
-        GLfloat z = *v;
-        out[i] = exp( d*z*z ); 
-        if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]);
-      }
-      break;
-   default:
-      gl_problem(ctx, "Bad fog mode in make_fog_coord");
-      return;
-   }
-}
-
-
-void 
-_mesa_make_win_fog_coords( struct vertex_buffer *VB )
-{
-   GLvector1f tmp;
-
-   make_win_fog_coords( VB, get_fogcoord_ptr( VB->ctx, &tmp ) );
-}
-
index 15ccbc9966c77c4dff8824d44ef6ccc9317062aa..371fb80d8bfed2020fd2d6a3be17f468e4b27ba4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fog.h,v 1.9 2000/10/31 18:09:44 keithw Exp $ */
+/* $Id: fog.h,v 1.10 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -49,8 +49,4 @@ extern void
 _mesa_Fogiv(GLenum pname, const GLint *params );
 
 
-extern void 
-_mesa_make_win_fog_coords( struct vertex_buffer *VB );
-
-
 #endif
index 434e2e54005ffda8dbb0c790cf1ea1203b779a8c..980269d85447528e9f4f625a014479d197e9dc65 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: get.c,v 1.40 2000/11/15 16:38:40 brianp Exp $ */
+/* $Id: get.c,v 1.41 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "extensions.h"
 #include "get.h"
 #include "macros.h"
-#include "matrix.h"
 #include "mmath.h"
 #include "types.h"
-#include "vb.h"
+
+#include "math/m_matrix.h"
 #endif
 
 
@@ -228,15 +228,18 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          *params = ENUM_TO_BOOL(ctx->Polygon.CullFaceMode);
          break;
       case GL_CURRENT_COLOR:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = INT_TO_BOOL(ctx->Current.Color[0]);
          params[1] = INT_TO_BOOL(ctx->Current.Color[1]);
          params[2] = INT_TO_BOOL(ctx->Current.Color[2]);
          params[3] = INT_TO_BOOL(ctx->Current.Color[3]);
          break;
       case GL_CURRENT_INDEX:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          *params = INT_TO_BOOL(ctx->Current.Index);
          break;
       case GL_CURRENT_NORMAL:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = FLOAT_TO_BOOL(ctx->Current.Normal[0]);
          params[1] = FLOAT_TO_BOOL(ctx->Current.Normal[1]);
          params[2] = FLOAT_TO_BOOL(ctx->Current.Normal[2]);
@@ -269,6 +272,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          *params = ctx->Current.RasterPosValid;
         break;
       case GL_CURRENT_TEXTURE_COORDS:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][0]);
          params[1] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][1]);
          params[2] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][2]);
@@ -309,6 +313,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
         *params = ENUM_TO_BOOL(ctx->Color.DrawBuffer);
         break;
       case GL_EDGE_FLAG:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         *params = ctx->Current.EdgeFlag;
         break;
       case GL_FEEDBACK_BUFFER_SIZE:
@@ -1077,7 +1082,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ColorMatrix.m);
+            _math_transposef(tm, ctx->ColorMatrix.m);
             for (i=0;i<16;i++) {
                params[i] = FLOAT_TO_BOOL(tm[i]);
             }
@@ -1087,7 +1092,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ModelView.m);
+            _math_transposef(tm, ctx->ModelView.m);
             for (i=0;i<16;i++) {
                params[i] = FLOAT_TO_BOOL(tm[i]);
             }
@@ -1097,7 +1102,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ProjectionMatrix.m);
+            _math_transposef(tm, ctx->ProjectionMatrix.m);
             for (i=0;i<16;i++) {
                params[i] = FLOAT_TO_BOOL(tm[i]);
             }
@@ -1107,7 +1112,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->TextureMatrix[texTransformUnit].m);
+            _math_transposef(tm, ctx->TextureMatrix[texTransformUnit].m);
             for (i=0;i<16;i++) {
                params[i] = FLOAT_TO_BOOL(tm[i]);
             }
@@ -1236,6 +1241,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
         *params = ctx->Fog.ColorSumEnabled;
         break;
       case GL_CURRENT_SECONDARY_COLOR_EXT: 
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = INT_TO_BOOL(ctx->Current.SecondaryColor[0]);
          params[1] = INT_TO_BOOL(ctx->Current.SecondaryColor[1]);
          params[2] = INT_TO_BOOL(ctx->Current.SecondaryColor[2]);
@@ -1255,6 +1261,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
 
       /* GL_EXT_fog_coord */
       case GL_CURRENT_FOG_COORDINATE_EXT: 
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         *params = FLOAT_TO_BOOL(ctx->Current.FogCoord);
         break;
       case GL_FOG_COORDINATE_ARRAY_EXT:
@@ -1419,15 +1426,18 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
          *params = ENUM_TO_DOUBLE(ctx->Polygon.CullFaceMode);
          break;
       case GL_CURRENT_COLOR:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = CHAN_TO_FLOAT(ctx->Current.Color[0]);
          params[1] = CHAN_TO_FLOAT(ctx->Current.Color[1]);
          params[2] = CHAN_TO_FLOAT(ctx->Current.Color[2]);
          params[3] = CHAN_TO_FLOAT(ctx->Current.Color[3]);
          break;
       case GL_CURRENT_INDEX:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          *params = (GLdouble) ctx->Current.Index;
          break;
       case GL_CURRENT_NORMAL:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = (GLdouble) ctx->Current.Normal[0];
          params[1] = (GLdouble) ctx->Current.Normal[1];
          params[2] = (GLdouble) ctx->Current.Normal[2];
@@ -1460,6 +1470,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
         *params = (GLdouble) ctx->Current.RasterPosValid;
         break;
       case GL_CURRENT_TEXTURE_COORDS:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         params[0] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][0];
         params[1] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][1];
         params[2] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][2];
@@ -1500,6 +1511,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
         *params = ENUM_TO_DOUBLE(ctx->Color.DrawBuffer);
         break;
       case GL_EDGE_FLAG:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         *params = (GLdouble) ctx->Current.EdgeFlag;
         break;
       case GL_FEEDBACK_BUFFER_SIZE:
@@ -2268,7 +2280,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ColorMatrix.m);
+            _math_transposef(tm, ctx->ColorMatrix.m);
             for (i=0;i<16;i++) {
                params[i] = (GLdouble) tm[i];
             }
@@ -2278,7 +2290,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ModelView.m);
+            _math_transposef(tm, ctx->ModelView.m);
             for (i=0;i<16;i++) {
                params[i] = (GLdouble) tm[i];
             }
@@ -2288,7 +2300,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ProjectionMatrix.m);
+            _math_transposef(tm, ctx->ProjectionMatrix.m);
             for (i=0;i<16;i++) {
                params[i] = (GLdouble) tm[i];
             }
@@ -2298,7 +2310,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->TextureMatrix[texTransformUnit].m);
+            _math_transposef(tm, ctx->TextureMatrix[texTransformUnit].m);
             for (i=0;i<16;i++) {
                params[i] = (GLdouble) tm[i];
             }
@@ -2427,6 +2439,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
         *params = (GLdouble) ctx->Fog.ColorSumEnabled;
         break;
       case GL_CURRENT_SECONDARY_COLOR_EXT: 
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[0]);
          params[1] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[1]);
          params[2] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[2]);
@@ -2446,6 +2459,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
 
       /* GL_EXT_fog_coord */
       case GL_CURRENT_FOG_COORDINATE_EXT: 
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         *params = (GLdouble) ctx->Current.FogCoord;
         break;
       case GL_FOG_COORDINATE_ARRAY_EXT:
@@ -2611,15 +2625,18 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          *params = ENUM_TO_FLOAT(ctx->Polygon.CullFaceMode);
          break;
       case GL_CURRENT_COLOR:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = CHAN_TO_FLOAT(ctx->Current.Color[0]);
          params[1] = CHAN_TO_FLOAT(ctx->Current.Color[1]);
          params[2] = CHAN_TO_FLOAT(ctx->Current.Color[2]);
          params[3] = CHAN_TO_FLOAT(ctx->Current.Color[3]);
          break;
       case GL_CURRENT_INDEX:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          *params = (GLfloat) ctx->Current.Index;
          break;
       case GL_CURRENT_NORMAL:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = ctx->Current.Normal[0];
          params[1] = ctx->Current.Normal[1];
          params[2] = ctx->Current.Normal[2];
@@ -2652,6 +2669,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
         *params = (GLfloat) ctx->Current.RasterPosValid;
         break;
       case GL_CURRENT_TEXTURE_COORDS:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         params[0] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][0];
         params[1] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][1];
         params[2] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][2];
@@ -2692,6 +2710,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
         *params = ENUM_TO_FLOAT(ctx->Color.DrawBuffer);
         break;
       case GL_EDGE_FLAG:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         *params = (GLfloat) ctx->Current.EdgeFlag;
         break;
       case GL_FEEDBACK_BUFFER_SIZE:
@@ -3459,16 +3478,16 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
 
       /* GL_ARB_transpose_matrix */
       case GL_TRANSPOSE_COLOR_MATRIX_ARB:
-         gl_matrix_transposef(params, ctx->ColorMatrix.m);
+         _math_transposef(params, ctx->ColorMatrix.m);
          break;
       case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB:
-         gl_matrix_transposef(params, ctx->ModelView.m);
+         _math_transposef(params, ctx->ModelView.m);
          break;
       case GL_TRANSPOSE_PROJECTION_MATRIX_ARB:
-         gl_matrix_transposef(params, ctx->ProjectionMatrix.m);
+         _math_transposef(params, ctx->ProjectionMatrix.m);
          break;
       case GL_TRANSPOSE_TEXTURE_MATRIX_ARB:
-         gl_matrix_transposef(params, ctx->TextureMatrix[texTransformUnit].m);
+         _math_transposef(params, ctx->TextureMatrix[texTransformUnit].m);
          break;
 
       /* GL_HP_occlusion_test */
@@ -3593,6 +3612,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
         *params = (GLfloat) ctx->Fog.ColorSumEnabled;
         break;
       case GL_CURRENT_SECONDARY_COLOR_EXT: 
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[0]);
          params[1] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[1]);
          params[2] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[2]);
@@ -3612,6 +3632,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
 
       /* GL_EXT_fog_coord */
       case GL_CURRENT_FOG_COORDINATE_EXT: 
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         *params = (GLfloat) ctx->Current.FogCoord;
         break;
       case GL_FOG_COORDINATE_ARRAY_EXT:
@@ -3779,15 +3800,18 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          *params = (GLint) ctx->Polygon.CullFaceMode;
          break;
       case GL_CURRENT_COLOR:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = FLOAT_TO_INT( CHAN_TO_FLOAT( ctx->Current.Color[0] ) );
          params[1] = FLOAT_TO_INT( CHAN_TO_FLOAT( ctx->Current.Color[1] ) );
          params[2] = FLOAT_TO_INT( CHAN_TO_FLOAT( ctx->Current.Color[2] ) );
          params[3] = FLOAT_TO_INT( CHAN_TO_FLOAT( ctx->Current.Color[3] ) );
          break;
       case GL_CURRENT_INDEX:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          *params = (GLint) ctx->Current.Index;
          break;
       case GL_CURRENT_NORMAL:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = FLOAT_TO_INT( ctx->Current.Normal[0] );
          params[1] = FLOAT_TO_INT( ctx->Current.Normal[1] );
          params[2] = FLOAT_TO_INT( ctx->Current.Normal[2] );
@@ -3820,6 +3844,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
         *params = (GLint) ctx->Current.RasterPosValid;
         break;
       case GL_CURRENT_TEXTURE_COORDS:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = (GLint) ctx->Current.Texcoord[texTransformUnit][0];
          params[1] = (GLint) ctx->Current.Texcoord[texTransformUnit][1];
          params[2] = (GLint) ctx->Current.Texcoord[texTransformUnit][2];
@@ -3860,6 +3885,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
         *params = (GLint) ctx->Color.DrawBuffer;
         break;
       case GL_EDGE_FLAG:
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         *params = (GLint) ctx->Current.EdgeFlag;
         break;
       case GL_FEEDBACK_BUFFER_SIZE:
@@ -4628,7 +4654,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ColorMatrix.m);
+            _math_transposef(tm, ctx->ColorMatrix.m);
             for (i=0;i<16;i++) {
                params[i] = (GLint) tm[i];
             }
@@ -4638,7 +4664,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ModelView.m);
+            _math_transposef(tm, ctx->ModelView.m);
             for (i=0;i<16;i++) {
                params[i] = (GLint) tm[i];
             }
@@ -4648,7 +4674,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->ProjectionMatrix.m);
+            _math_transposef(tm, ctx->ProjectionMatrix.m);
             for (i=0;i<16;i++) {
                params[i] = (GLint) tm[i];
             }
@@ -4658,7 +4684,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          {
             GLfloat tm[16];
             GLuint i;
-            gl_matrix_transposef(tm, ctx->TextureMatrix[texTransformUnit].m);
+            _math_transposef(tm, ctx->TextureMatrix[texTransformUnit].m);
             for (i=0;i<16;i++) {
                params[i] = (GLint) tm[i];
             }
@@ -4788,6 +4814,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
         *params = (GLint) ctx->Fog.ColorSumEnabled;
         break;
       case GL_CURRENT_SECONDARY_COLOR_EXT: 
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
          params[0] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.SecondaryColor[0] ) );
          params[1] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.SecondaryColor[1] ) );
          params[2] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.SecondaryColor[2] ) );
@@ -4807,6 +4834,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
 
       /* GL_EXT_fog_coord */
       case GL_CURRENT_FOG_COORDINATE_EXT: 
+        FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
         *params = (GLint) ctx->Current.FogCoord;
         break;
       case GL_FOG_COORDINATE_ARRAY_EXT:
index 1c4f6982d93a68587b47fbf10f2521aba426e31e..ef31c561ba684bda8cd0252313d07666621f935a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: light.c,v 1.25 2000/11/15 16:38:59 brianp Exp $ */
+/* $Id: light.c,v 1.26 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "enums.h"
 #include "light.h"
 #include "macros.h"
-#include "matrix.h"
 #include "mem.h"
 #include "mmath.h"
-#include "shade.h"
 #include "simple_list.h"
 #include "types.h"
-#include "vb.h"
-#include "xform.h"
+
+#include "math/m_xform.h"
+#include "math/m_matrix.h"
 #endif
 
 
@@ -123,7 +122,7 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
       case GL_SPOT_DIRECTION:
         /* transform direction by inverse modelview */
         if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-           gl_matrix_analyze( &ctx->ModelView );
+           _math_matrix_analyze( &ctx->ModelView );
         }
         TRANSFORM_NORMAL( l->EyeDirection, params, ctx->ModelView.inv );
          break;
@@ -533,7 +532,7 @@ void gl_update_material( GLcontext *ctx,
    if (ctx->Light.ColorMaterialEnabled)
       bitmask &= ~ctx->Light.ColorMaterialBitmask;
 
-   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
+   if (MESA_VERBOSE&VERBOSE_IMMEDIATE) 
       fprintf(stderr, "gl_update_material, mask 0x%x\n", bitmask);
 
    if (!bitmask) 
@@ -829,8 +828,10 @@ _mesa_ColorMaterial( GLenum face, GLenum mode )
       ctx->Light.ColorMaterialMode = mode;
    }
 
-   if (ctx->Light.ColorMaterialEnabled)
+   if (ctx->Light.ColorMaterialEnabled) {
+      FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
       gl_update_color_material( ctx, ctx->Current.Color );
+   }
 
    ctx->NewState |= _NEW_LIGHT;
 }
@@ -845,86 +846,6 @@ _mesa_Materialf( GLenum face, GLenum pname, GLfloat param )
 }
 
 
-/* KW:  This is now called directly (ie by name) from the glMaterial* 
- *      API functions.
- */
-void
-_mesa_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct immediate *IM;
-   struct gl_material *mat;
-   GLuint bitmask;
-   GLuint count;
-
-   bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
-   if (bitmask == 0)
-      return;
-
-   IM = ctx->input;
-   count = IM->Count;
-
-   if (!IM->Material) {
-      IM->Material = 
-        (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) * 
-                                            VB_SIZE * 2 );
-      IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE );
-   }
-
-
-   if (!(IM->Flag[count] & VERT_MATERIAL)) {
-      IM->Flag[count] |= VERT_MATERIAL;
-      IM->MaterialMask[count] = 0;      
-   }
-
-
-   IM->MaterialMask[count] |= bitmask;
-   mat = IM->Material[count];
-
-   if (bitmask & FRONT_AMBIENT_BIT) {
-      COPY_4FV( mat[0].Ambient, params );
-   }
-   if (bitmask & BACK_AMBIENT_BIT) {
-      COPY_4FV( mat[1].Ambient, params );
-   }
-   if (bitmask & FRONT_DIFFUSE_BIT) {
-      COPY_4FV( mat[0].Diffuse, params );
-   }
-   if (bitmask & BACK_DIFFUSE_BIT) {
-      COPY_4FV( mat[1].Diffuse, params );
-   }
-   if (bitmask & FRONT_SPECULAR_BIT) {
-      COPY_4FV( mat[0].Specular, params );
-   }
-   if (bitmask & BACK_SPECULAR_BIT) {
-      COPY_4FV( mat[1].Specular, params );
-   }
-   if (bitmask & FRONT_EMISSION_BIT) {
-      COPY_4FV( mat[0].Emission, params );
-   }
-   if (bitmask & BACK_EMISSION_BIT) {
-      COPY_4FV( mat[1].Emission, params );
-   }
-   if (bitmask & FRONT_SHININESS_BIT) {
-      GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
-      mat[0].Shininess = shininess;
-   }
-   if (bitmask & BACK_SHININESS_BIT) {
-      GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
-      mat[1].Shininess = shininess;
-   }
-   if (bitmask & FRONT_INDEXES_BIT) {
-      mat[0].AmbientIndex = params[0];
-      mat[0].DiffuseIndex = params[1];
-      mat[0].SpecularIndex = params[2];
-   }
-   if (bitmask & BACK_INDEXES_BIT) {
-      mat[1].AmbientIndex = params[0];
-      mat[1].DiffuseIndex = params[1];
-      mat[1].SpecularIndex = params[2];
-   }
-}
-
 
 void
 _mesa_Materiali(GLenum face, GLenum pname, GLint param )
@@ -1281,8 +1202,6 @@ gl_update_lighting( GLcontext *ctx )
         light->_sli = DOT3(ci, light->Specular);
       }
    }
-
-   gl_update_lighting_function(ctx);
 }
 
 
@@ -1364,54 +1283,3 @@ gl_compute_light_positions( GLcontext *ctx )
 }
 
 
-/* _NEW_TRANSFORM
- * _NEW_MODELVIEW
- * _TNL_NEW_NEED_NORMALS    
- * _TNL_NEW_NEED_EYE_COORDS
- *
- * Update on (_NEW_TRANSFORM|_NEW_MODELVIEW)
- * And also on NewLightingSpaces() callback.
- */
-void
-gl_update_normal_transform( GLcontext *ctx )
-{
-
-   if (!ctx->_NeedNormals) {
-      ctx->_NormalTransform = 0;
-      return;
-   }
-
-   if (ctx->_NeedEyeCoords) {
-      GLuint transform = NORM_TRANSFORM_NO_ROT;
-
-      if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
-                                 MAT_FLAG_ROTATION |
-                                 MAT_FLAG_GENERAL_3D |
-                                 MAT_FLAG_PERSPECTIVE)) 
-        transform = NORM_TRANSFORM;
-           
-              
-      if (ctx->Transform.Normalize) {
-        ctx->_NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
-      } 
-      else if (ctx->Transform.RescaleNormals &&
-              ctx->_ModelViewInvScale != 1.0) {
-        ctx->_NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
-      }
-      else {
-        ctx->_NormalTransform = gl_normal_tab[transform];
-      }
-   }
-   else {
-      if (ctx->Transform.Normalize) {
-        ctx->_NormalTransform = gl_normal_tab[NORM_NORMALIZE];
-      }
-      else if (!ctx->Transform.RescaleNormals &&
-              ctx->_ModelViewInvScale != 1.0) {
-        ctx->_NormalTransform = gl_normal_tab[NORM_RESCALE];
-      }
-      else {
-        ctx->_NormalTransform = 0;
-      }
-   }
-}
index 78178f982b8e05f00293553f787f3e152da1fec4..4c2589fbf47d29980ce13074f8cff1b491ccbc8f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: light.h,v 1.4 2000/10/28 18:34:48 brianp Exp $ */
+/* $Id: light.h,v 1.5 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 
 #include "types.h"
 
-struct gl_shine_tab {
-   struct gl_shine_tab *next, *prev;
-   GLfloat tab[SHINE_TABLE_SIZE+1];
-   GLfloat shininess;
-   GLuint refcount;
-};
-
 
 extern void
 _mesa_ShadeModel( GLenum mode );
@@ -94,6 +87,23 @@ extern void
 _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params );
 
 
+/* Lerp between adjacent values in the f(x) lookup table, giving a
+ * continuous function, with adequeate overall accuracy.  (Though
+ * still pretty good compared to a straight lookup). 
+ */
+#define GET_SHINE_TAB_ENTRY( table, dp, result )                       \
+do {                                                                   \
+   struct gl_shine_tab *_tab = table;                                  \
+   if (dp>1.0)                                                         \
+      result = pow( dp, _tab->shininess );                             \
+   else {                                                              \
+      float f = (dp * (SHINE_TABLE_SIZE-1));                           \
+      int k = (int) f;                                                 \
+      result = _tab->tab[k] + (f-k)*(_tab->tab[k+1]-_tab->tab[k]);     \
+   }                                                                   \
+} while (0)
+
+
 
 extern GLuint gl_material_bitmask( GLcontext *ctx, 
                                   GLenum face, GLenum pname, 
@@ -112,8 +122,6 @@ extern void gl_update_lighting( GLcontext *ctx );
 
 extern void gl_compute_light_positions( GLcontext *ctx );
 
-extern void gl_update_normal_transform( GLcontext *ctx );
-
 extern void gl_update_material( GLcontext *ctx, 
                                const struct gl_material src[2], 
                                GLuint bitmask );
index 2a86e09a54f2c8f607fed8e0eb8377b47b18744d..3d9aad52b715622ab7f8b2d875f52d54ad97573d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: lines.c,v 1.21 2000/11/05 18:40:58 keithw Exp $ */
+/* $Id: lines.c,v 1.22 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -37,7 +37,6 @@
 #include "mmath.h"
 #include "texstate.h"
 #include "types.h"
-#include "vb.h"
 #endif
 
 
index d84d2edd7c8ccf93c6a68205a336a4f97f4a8347..d5d9e42e7f785bb94b337738a177503e16cac00c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: macros.h,v 1.13 2000/11/05 18:40:58 keithw Exp $ */
+/* $Id: macros.h,v 1.14 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -35,6 +35,8 @@
 
 
 #include "glheader.h"
+/* Do not reference types.h from this file.
+ */
 
 
 /* Limits: */
index 7cf464e07bf8dbcd10e498d3726e71b9acd0da5e..227f54b73d5efb173fd98bcc1ad134d8ca0d0ae5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: matrix.c,v 1.25 2000/11/13 20:02:56 keithw Exp $ */
+/* $Id: matrix.c,v 1.26 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "mem.h"
 #include "mmath.h"
 #include "types.h"
-#endif
-
-
-static const char *types[] = {
-   "MATRIX_GENERAL",
-   "MATRIX_IDENTITY",
-   "MATRIX_3D_NO_ROT",
-   "MATRIX_PERSPECTIVE",
-   "MATRIX_2D",
-   "MATRIX_2D_NO_ROT",
-   "MATRIX_3D"
-};
-
-
-static GLfloat Identity[16] = {
-   1.0, 0.0, 0.0, 0.0,
-   0.0, 1.0, 0.0, 0.0,
-   0.0, 0.0, 1.0, 0.0,
-   0.0, 0.0, 0.0, 1.0
-};
-
-
-
-static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b );
-
-
-static void print_matrix_floats( const GLfloat m[16] )
-{
-   int i;
-   for (i=0;i<4;i++) {
-      fprintf(stderr,"\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] );
-   }
-}
-
-void gl_print_matrix( const GLmatrix *m )
-{
-   fprintf(stderr, "Matrix type: %s, flags: %x\n", types[m->type], m->flags);
-   print_matrix_floats(m->m);
-   fprintf(stderr, "Inverse: \n");
-   if (m->inv) {
-      GLfloat prod[16];
-      print_matrix_floats(m->inv);
-      matmul4(prod, m->m, m->inv);
-      fprintf(stderr, "Mat * Inverse:\n");
-      print_matrix_floats(prod);
-   }
-   else {
-      fprintf(stderr, "  - not available\n");
-   }
-}
-
-
-
-/*
- * This matmul was contributed by Thomas Malik 
- *
- * Perform a 4x4 matrix multiplication  (product = a x b).
- * Input:  a, b - matrices to multiply
- * Output:  product - product of a and b
- * WARNING: (product != b) assumed
- * NOTE:    (product == a) allowed    
- *
- * KW: 4*16 = 64 muls
- */
-#define A(row,col)  a[(col<<2)+row]
-#define B(row,col)  b[(col<<2)+row]
-#define P(row,col)  product[(col<<2)+row]
-
-static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b )
-{
-   GLint i;
-   for (i = 0; i < 4; i++) {
-      const GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
-      P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
-      P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
-      P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
-      P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
-   }
-}
-
-
-/* Multiply two matrices known to occupy only the top three rows,
- * such as typical modelling matrices, and ortho matrices.
- */
-static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b )
-{
-   GLint i;
-   for (i = 0; i < 3; i++) {
-      const GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
-      P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0);
-      P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1);
-      P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2);
-      P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3;
-   }
-   P(3,0) = 0;
-   P(3,1) = 0;
-   P(3,2) = 0;
-   P(3,3) = 1;
-}
-
-static void matmul4fd( GLfloat *product, const GLfloat *a, const GLdouble *b )
-{
-   GLint i;
-   for (i = 0; i < 4; i++) {
-      const GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
-      P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
-      P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
-      P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
-      P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
-   }
-}
-
-#undef A
-#undef B
-#undef P
-
-
-#define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; }
-#define MAT(m,r,c) (m)[(c)*4+(r)]
-
-/*
- * Compute inverse of 4x4 transformation matrix.
- * Code contributed by Jacques Leroy jle@star.be
- * Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
- */
-static GLboolean invert_matrix_general( GLmatrix *mat )
-{
-   const GLfloat *m = mat->m;
-   GLfloat *out = mat->inv;
-   GLfloat wtmp[4][8];
-   GLfloat m0, m1, m2, m3, s;
-   GLfloat *r0, *r1, *r2, *r3;
-  
-   r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
-  
-   r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1),
-   r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3),
-   r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
-  
-   r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1),
-   r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3),
-   r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
-  
-   r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1),
-   r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3),
-   r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
-  
-   r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1),
-   r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3),
-   r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
-  
-   /* choose pivot - or die */
-   if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2);
-   if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1);
-   if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0);
-   if (0.0 == r0[0])  return GL_FALSE;
-  
-   /* eliminate first variable     */
-   m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
-   s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
-   s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
-   s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
-   s = r0[4];
-   if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
-   s = r0[5];
-   if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
-   s = r0[6];
-   if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
-   s = r0[7];
-   if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
-  
-   /* choose pivot - or die */
-   if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2);
-   if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1);
-   if (0.0 == r1[1])  return GL_FALSE;
-  
-   /* eliminate second variable */
-   m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
-   r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
-   r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
-   s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
-   s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
-   s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
-   s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
-  
-   /* choose pivot - or die */
-   if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2);
-   if (0.0 == r2[2])  return GL_FALSE;
-  
-   /* eliminate third variable */
-   m3 = r3[2]/r2[2];
-   r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
-   r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
-   r3[7] -= m3 * r2[7];
-  
-   /* last check */
-   if (0.0 == r3[3]) return GL_FALSE;
-  
-   s = 1.0/r3[3];              /* now back substitute row 3 */
-   r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
-  
-   m2 = r2[3];                 /* now back substitute row 2 */
-   s  = 1.0/r2[2];
-   r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
-   r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
-   m1 = r1[3];
-   r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
-   r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
-   m0 = r0[3];
-   r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
-   r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
-  
-   m1 = r1[2];                 /* now back substitute row 1 */
-   s  = 1.0/r1[1];
-   r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
-   r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
-   m0 = r0[2];
-   r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
-   r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
-  
-   m0 = r0[1];                 /* now back substitute row 0 */
-   s  = 1.0/r0[0];
-   r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
-   r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
-  
-   MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5],
-   MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7],
-   MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5],
-   MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7],
-   MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5],
-   MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7],
-   MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5],
-   MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; 
-  
-   return GL_TRUE;
-}
-#undef SWAP_ROWS
-
-
-/* Adapted from graphics gems II.
- */  
-static GLboolean invert_matrix_3d_general( GLmatrix *mat )
-{
-   const GLfloat *in = mat->m;
-   GLfloat *out = mat->inv;
-   GLfloat pos, neg, t;
-   GLfloat det;
-
-   /* Calculate the determinant of upper left 3x3 submatrix and
-    * determine if the matrix is singular. 
-    */
-   pos = neg = 0.0;
-   t =  MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2);
-   if (t >= 0.0) pos += t; else neg += t;
-
-   t =  MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2);
-   if (t >= 0.0) pos += t; else neg += t;
-
-   t =  MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2);
-   if (t >= 0.0) pos += t; else neg += t;
-
-   t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2);
-   if (t >= 0.0) pos += t; else neg += t;
-
-   t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2);
-   if (t >= 0.0) pos += t; else neg += t;
-
-   t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2);
-   if (t >= 0.0) pos += t; else neg += t;
-
-   det = pos + neg;
-
-   if (det*det < 1e-25) 
-      return GL_FALSE;
-   
-   det = 1.0 / det;
-   MAT(out,0,0) = (  (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det);
-   MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det);
-   MAT(out,0,2) = (  (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det);
-   MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det);
-   MAT(out,1,1) = (  (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det);
-   MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det);
-   MAT(out,2,0) = (  (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det);
-   MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det);
-   MAT(out,2,2) = (  (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det);
-
-   /* Do the translation part */
-   MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
-                    MAT(in,1,3) * MAT(out,0,1) +
-                    MAT(in,2,3) * MAT(out,0,2) );
-   MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
-                    MAT(in,1,3) * MAT(out,1,1) +
-                    MAT(in,2,3) * MAT(out,1,2) );
-   MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
-                    MAT(in,1,3) * MAT(out,2,1) +
-                    MAT(in,2,3) * MAT(out,2,2) );
-    
-   return GL_TRUE;
-}
-
-
-static GLboolean invert_matrix_3d( GLmatrix *mat )
-{
-   const GLfloat *in = mat->m;
-   GLfloat *out = mat->inv;
-
-   if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING)) {
-      return invert_matrix_3d_general( mat );
-   }
-   
-   if (mat->flags & MAT_FLAG_UNIFORM_SCALE) {
-      GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) +
-                       MAT(in,0,1) * MAT(in,0,1) +
-                       MAT(in,0,2) * MAT(in,0,2));
-
-      if (scale == 0.0) 
-         return GL_FALSE;
-
-      scale = 1.0 / scale;
-
-      /* Transpose and scale the 3 by 3 upper-left submatrix. */
-      MAT(out,0,0) = scale * MAT(in,0,0);
-      MAT(out,1,0) = scale * MAT(in,0,1);
-      MAT(out,2,0) = scale * MAT(in,0,2);
-      MAT(out,0,1) = scale * MAT(in,1,0);
-      MAT(out,1,1) = scale * MAT(in,1,1);
-      MAT(out,2,1) = scale * MAT(in,1,2);
-      MAT(out,0,2) = scale * MAT(in,2,0);
-      MAT(out,1,2) = scale * MAT(in,2,1);
-      MAT(out,2,2) = scale * MAT(in,2,2);
-   }
-   else if (mat->flags & MAT_FLAG_ROTATION) {
-      /* Transpose the 3 by 3 upper-left submatrix. */
-      MAT(out,0,0) = MAT(in,0,0);
-      MAT(out,1,0) = MAT(in,0,1);
-      MAT(out,2,0) = MAT(in,0,2);
-      MAT(out,0,1) = MAT(in,1,0);
-      MAT(out,1,1) = MAT(in,1,1);
-      MAT(out,2,1) = MAT(in,1,2);
-      MAT(out,0,2) = MAT(in,2,0);
-      MAT(out,1,2) = MAT(in,2,1);
-      MAT(out,2,2) = MAT(in,2,2);
-   }
-   else {
-      /* pure translation */
-      MEMCPY( out, Identity, sizeof(Identity) );
-      MAT(out,0,3) = - MAT(in,0,3);
-      MAT(out,1,3) = - MAT(in,1,3);
-      MAT(out,2,3) = - MAT(in,2,3);
-      return GL_TRUE;
-   }
-    
-   if (mat->flags & MAT_FLAG_TRANSLATION) {
-      /* Do the translation part */
-      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
-                       MAT(in,1,3) * MAT(out,0,1) +
-                       MAT(in,2,3) * MAT(out,0,2) );
-      MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
-                       MAT(in,1,3) * MAT(out,1,1) +
-                       MAT(in,2,3) * MAT(out,1,2) );
-      MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
-                       MAT(in,1,3) * MAT(out,2,1) +
-                       MAT(in,2,3) * MAT(out,2,2) );
-   }
-   else {
-      MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0;
-   }
-    
-   return GL_TRUE;
-}
-
-  
-
-static GLboolean invert_matrix_identity( GLmatrix *mat )
-{
-   MEMCPY( mat->inv, Identity, sizeof(Identity) );
-   return GL_TRUE;
-}
-
-
-static GLboolean invert_matrix_3d_no_rot( GLmatrix *mat )
-{
-   const GLfloat *in = mat->m;
-   GLfloat *out = mat->inv;
-
-   if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 )       
-      return GL_FALSE;
-  
-   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
-   MAT(out,0,0) = 1.0 / MAT(in,0,0);
-   MAT(out,1,1) = 1.0 / MAT(in,1,1);
-   MAT(out,2,2) = 1.0 / MAT(in,2,2);
-
-   if (mat->flags & MAT_FLAG_TRANSLATION) {
-      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
-      MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
-      MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2));
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLboolean invert_matrix_2d_no_rot( GLmatrix *mat )
-{
-   const GLfloat *in = mat->m;
-   GLfloat *out = mat->inv;
-
-   if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0)       
-      return GL_FALSE;
-  
-   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
-   MAT(out,0,0) = 1.0 / MAT(in,0,0);
-   MAT(out,1,1) = 1.0 / MAT(in,1,1);
-
-   if (mat->flags & MAT_FLAG_TRANSLATION) {
-      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
-      MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLboolean invert_matrix_perspective( GLmatrix *mat )
-{
-   const GLfloat *in = mat->m;
-   GLfloat *out = mat->inv;
-
-   if (MAT(in,2,3) == 0)
-      return GL_FALSE;
-
-   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
-
-   MAT(out,0,0) = 1.0 / MAT(in,0,0);
-   MAT(out,1,1) = 1.0 / MAT(in,1,1);
-
-   MAT(out,0,3) = MAT(in,0,2);
-   MAT(out,1,3) = MAT(in,1,2);
-
-   MAT(out,2,2) = 0;
-   MAT(out,2,3) = -1;
-
-   MAT(out,3,2) = 1.0 / MAT(in,2,3);
-   MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2);
-
-   return GL_TRUE;
-}
-
-
-typedef GLboolean (*inv_mat_func)( GLmatrix *mat );
-
-
-static inv_mat_func inv_mat_tab[7] = {
-   invert_matrix_general,
-   invert_matrix_identity,
-   invert_matrix_3d_no_rot,
-   invert_matrix_perspective,
-   invert_matrix_3d,           /* lazy! */
-   invert_matrix_2d_no_rot,
-   invert_matrix_3d
-};
-
-
-static GLboolean matrix_invert( GLmatrix *mat )
-{
-   if (inv_mat_tab[mat->type](mat)) {
-      mat->flags &= ~MAT_FLAG_SINGULAR;
-      return GL_TRUE;
-   } else {
-      mat->flags |= MAT_FLAG_SINGULAR;
-      MEMCPY( mat->inv, Identity, sizeof(Identity) );
-      return GL_FALSE;
-   }  
-}
-
-
-
-void gl_matrix_transposef( GLfloat to[16], const GLfloat from[16] )
-{
-   to[0] = from[0];
-   to[1] = from[4];
-   to[2] = from[8];
-   to[3] = from[12];
-   to[4] = from[1];
-   to[5] = from[5];
-   to[6] = from[9];
-   to[7] = from[13];
-   to[8] = from[2];
-   to[9] = from[6];
-   to[10] = from[10];
-   to[11] = from[14];
-   to[12] = from[3];
-   to[13] = from[7];
-   to[14] = from[11];
-   to[15] = from[15];
-}
-
-
-
-void gl_matrix_transposed( GLdouble to[16], const GLdouble from[16] )
-{
-   to[0] = from[0];
-   to[1] = from[4];
-   to[2] = from[8];
-   to[3] = from[12];
-   to[4] = from[1];
-   to[5] = from[5];
-   to[6] = from[9];
-   to[7] = from[13];
-   to[8] = from[2];
-   to[9] = from[6];
-   to[10] = from[10];
-   to[11] = from[14];
-   to[12] = from[3];
-   to[13] = from[7];
-   to[14] = from[11];
-   to[15] = from[15];
-}
-
-
-
-/*
- * Generate a 4x4 transformation matrix from glRotate parameters.
- */
-void gl_rotation_matrix( GLfloat angle, GLfloat x, GLfloat y, GLfloat z,
-                         GLfloat m[] )
-{
-   /* This function contributed by Erich Boleyn (erich@uruk.org) */
-   GLfloat mag, s, c;
-   GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
-
-   s = sin( angle * DEG2RAD );
-   c = cos( angle * DEG2RAD );
-
-   mag = GL_SQRT( x*x + y*y + z*z );
-
-   if (mag <= 1.0e-4) {
-      /* generate an identity matrix and return */
-      MEMCPY(m, Identity, sizeof(GLfloat)*16);
-      return;
-   }
-
-   x /= mag;
-   y /= mag;
-   z /= mag;
-
-#define M(row,col)  m[col*4+row]
-
-   /*
-    *     Arbitrary axis rotation matrix.
-    *
-    *  This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
-    *  like so:  Rz * Ry * T * Ry' * Rz'.  T is the final rotation
-    *  (which is about the X-axis), and the two composite transforms
-    *  Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
-    *  from the arbitrary axis to the X-axis then back.  They are
-    *  all elementary rotations.
-    *
-    *  Rz' is a rotation about the Z-axis, to bring the axis vector
-    *  into the x-z plane.  Then Ry' is applied, rotating about the
-    *  Y-axis to bring the axis vector parallel with the X-axis.  The
-    *  rotation about the X-axis is then performed.  Ry and Rz are
-    *  simply the respective inverse transforms to bring the arbitrary
-    *  axis back to it's original orientation.  The first transforms
-    *  Rz' and Ry' are considered inverses, since the data from the
-    *  arbitrary axis gives you info on how to get to it, not how
-    *  to get away from it, and an inverse must be applied.
-    *
-    *  The basic calculation used is to recognize that the arbitrary
-    *  axis vector (x, y, z), since it is of unit length, actually
-    *  represents the sines and cosines of the angles to rotate the
-    *  X-axis to the same orientation, with theta being the angle about
-    *  Z and phi the angle about Y (in the order described above)
-    *  as follows:
-    *
-    *  cos ( theta ) = x / sqrt ( 1 - z^2 )
-    *  sin ( theta ) = y / sqrt ( 1 - z^2 )
-    *
-    *  cos ( phi ) = sqrt ( 1 - z^2 )
-    *  sin ( phi ) = z
-    *
-    *  Note that cos ( phi ) can further be inserted to the above
-    *  formulas:
-    *
-    *  cos ( theta ) = x / cos ( phi )
-    *  sin ( theta ) = y / sin ( phi )
-    *
-    *  ...etc.  Because of those relations and the standard trigonometric
-    *  relations, it is pssible to reduce the transforms down to what
-    *  is used below.  It may be that any primary axis chosen will give the
-    *  same results (modulo a sign convention) using thie method.
-    *
-    *  Particularly nice is to notice that all divisions that might
-    *  have caused trouble when parallel to certain planes or
-    *  axis go away with care paid to reducing the expressions.
-    *  After checking, it does perform correctly under all cases, since
-    *  in all the cases of division where the denominator would have
-    *  been zero, the numerator would have been zero as well, giving
-    *  the expected result.
-    */
-
-   xx = x * x;
-   yy = y * y;
-   zz = z * z;
-   xy = x * y;
-   yz = y * z;
-   zx = z * x;
-   xs = x * s;
-   ys = y * s;
-   zs = z * s;
-   one_c = 1.0F - c;
-
-   M(0,0) = (one_c * xx) + c;
-   M(0,1) = (one_c * xy) - zs;
-   M(0,2) = (one_c * zx) + ys;
-   M(0,3) = 0.0F;
-
-   M(1,0) = (one_c * xy) + zs;
-   M(1,1) = (one_c * yy) + c;
-   M(1,2) = (one_c * yz) - xs;
-   M(1,3) = 0.0F;
-
-   M(2,0) = (one_c * zx) - ys;
-   M(2,1) = (one_c * yz) + xs;
-   M(2,2) = (one_c * zz) + c;
-   M(2,3) = 0.0F;
-
-   M(3,0) = 0.0F;
-   M(3,1) = 0.0F;
-   M(3,2) = 0.0F;
-   M(3,3) = 1.0F;
-
-#undef M
-}
-
-#define ZERO(x) (1<<x)
-#define ONE(x)  (1<<(x+16))
-
-#define MASK_NO_TRX      (ZERO(12) | ZERO(13) | ZERO(14))
-#define MASK_NO_2D_SCALE ( ONE(0)  | ONE(5))
-
-#define MASK_IDENTITY    ( ONE(0)  | ZERO(4)  | ZERO(8)  | ZERO(12) |\
-                         ZERO(1)  |  ONE(5)  | ZERO(9)  | ZERO(13) |\
-                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
-                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
-
-#define MASK_2D_NO_ROT   (           ZERO(4)  | ZERO(8)  |           \
-                         ZERO(1)  |            ZERO(9)  |           \
-                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
-                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
-
-#define MASK_2D          (                      ZERO(8)  |           \
-                                               ZERO(9)  |           \
-                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
-                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
-
-
-#define MASK_3D_NO_ROT   (           ZERO(4)  | ZERO(8)  |           \
-                         ZERO(1)  |            ZERO(9)  |           \
-                         ZERO(2)  | ZERO(6)  |                      \
-                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
-
-#define MASK_3D          (                                           \
-                                                                    \
-                                                                    \
-                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
-
-
-#define MASK_PERSPECTIVE (           ZERO(4)  |            ZERO(12) |\
-                         ZERO(1)  |                       ZERO(13) |\
-                         ZERO(2)  | ZERO(6)  |                      \
-                         ZERO(3)  | ZERO(7)  |            ZERO(15) )
-
-#define SQ(x) ((x)*(x))
-  
-/* Determine type and flags from scratch.  This is expensive enough to
- * only want to do it once.
- */
-static void analyze_from_scratch( GLmatrix *mat )
-{
-   const GLfloat *m = mat->m;
-   GLuint mask = 0;
-   GLuint i;
-
-   for (i = 0 ; i < 16 ; i++) {
-      if (m[i] == 0.0) mask |= (1<<i);
-   }
-   
-   if (m[0] == 1.0F) mask |= (1<<16);
-   if (m[5] == 1.0F) mask |= (1<<21);
-   if (m[10] == 1.0F) mask |= (1<<26);
-   if (m[15] == 1.0F) mask |= (1<<31);
-
-   mat->flags &= ~MAT_FLAGS_GEOMETRY;
-
-   /* Check for translation - no-one really cares 
-    */
-   if ((mask & MASK_NO_TRX) != MASK_NO_TRX) 
-      mat->flags |= MAT_FLAG_TRANSLATION;      
-
-   /* Do the real work
-    */
-   if (mask == MASK_IDENTITY) {
-      mat->type = MATRIX_IDENTITY;
-   }
-   else if ((mask & MASK_2D_NO_ROT) == MASK_2D_NO_ROT) {
-      mat->type = MATRIX_2D_NO_ROT;
-      
-      if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE)
-        mat->flags = MAT_FLAG_GENERAL_SCALE;
-   }
-   else if ((mask & MASK_2D) == MASK_2D) {
-      GLfloat mm = DOT2(m, m);
-      GLfloat m4m4 = DOT2(m+4,m+4);
-      GLfloat mm4 = DOT2(m,m+4);
-
-      mat->type = MATRIX_2D;
-
-      /* Check for scale */
-      if (SQ(mm-1) > SQ(1e-6) ||
-         SQ(m4m4-1) > SQ(1e-6)) 
-        mat->flags |= MAT_FLAG_GENERAL_SCALE;
-
-      /* Check for rotation */
-      if (SQ(mm4) > SQ(1e-6))
-        mat->flags |= MAT_FLAG_GENERAL_3D;
-      else
-        mat->flags |= MAT_FLAG_ROTATION;
-
-   }
-   else if ((mask & MASK_3D_NO_ROT) == MASK_3D_NO_ROT) {
-      mat->type = MATRIX_3D_NO_ROT;
-
-      /* Check for scale */
-      if (SQ(m[0]-m[5]) < SQ(1e-6) && 
-         SQ(m[0]-m[10]) < SQ(1e-6)) {
-        if (SQ(m[0]-1.0) > SQ(1e-6)) {
-           mat->flags |= MAT_FLAG_UNIFORM_SCALE;
-         }
-      }
-      else {
-        mat->flags |= MAT_FLAG_GENERAL_SCALE;
-      }
-   }
-   else if ((mask & MASK_3D) == MASK_3D) {
-      GLfloat c1 = DOT3(m,m);
-      GLfloat c2 = DOT3(m+4,m+4);
-      GLfloat c3 = DOT3(m+8,m+8);
-      GLfloat d1 = DOT3(m, m+4);
-      GLfloat cp[3];
-
-      mat->type = MATRIX_3D;
-
-      /* Check for scale */
-      if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) {
-        if (SQ(c1-1.0) > SQ(1e-6))
-           mat->flags |= MAT_FLAG_UNIFORM_SCALE;
-        /* else no scale at all */
-      }
-      else {
-        mat->flags |= MAT_FLAG_GENERAL_SCALE;
-      }
-
-      /* Check for rotation */
-      if (SQ(d1) < SQ(1e-6)) {
-        CROSS3( cp, m, m+4 );
-        SUB_3V( cp, cp, (m+8) );
-        if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) 
-           mat->flags |= MAT_FLAG_ROTATION;
-        else
-           mat->flags |= MAT_FLAG_GENERAL_3D;
-      }
-      else {
-        mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */
-      }
-   }
-   else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) {
-      mat->type = MATRIX_PERSPECTIVE;
-      mat->flags |= MAT_FLAG_GENERAL;
-   }
-   else {
-      mat->type = MATRIX_GENERAL;
-      mat->flags |= MAT_FLAG_GENERAL;
-   }
-}
-
-
-/* Analyse a matrix given that its flags are accurate - this is the
- * more common operation, hopefully. 
- */
-static void analyze_from_flags( GLmatrix *mat )
-{
-   const GLfloat *m = mat->m;
-
-   if (TEST_MAT_FLAGS(mat, 0)) {
-      mat->type = MATRIX_IDENTITY;
-   }
-   else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION |
-                                MAT_FLAG_UNIFORM_SCALE |
-                                MAT_FLAG_GENERAL_SCALE))) {
-      if ( m[10]==1.0F && m[14]==0.0F ) {
-        mat->type = MATRIX_2D_NO_ROT;
-      }
-      else {
-        mat->type = MATRIX_3D_NO_ROT;
-      }
-   }
-   else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) {
-      if (                                 m[ 8]==0.0F               
-            &&                             m[ 9]==0.0F
-            && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) {
-        mat->type = MATRIX_2D;
-      }
-      else {
-        mat->type = MATRIX_3D;
-      }
-   }
-   else if (                 m[4]==0.0F                 && m[12]==0.0F
-            && m[1]==0.0F                               && m[13]==0.0F
-            && m[2]==0.0F && m[6]==0.0F
-            && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) {
-      mat->type = MATRIX_PERSPECTIVE;
-   }
-   else {
-      mat->type = MATRIX_GENERAL;
-   }
-}
-
-
-void gl_matrix_analyze( GLmatrix *mat ) 
-{
-   if (mat->flags & MAT_DIRTY_TYPE) {
-      if (mat->flags & MAT_DIRTY_FLAGS) 
-        analyze_from_scratch( mat );
-      else
-        analyze_from_flags( mat );
-   }
-
-   if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) {
-      matrix_invert( mat );
-   }
-
-   mat->flags &= ~(MAT_DIRTY_FLAGS|
-                  MAT_DIRTY_TYPE|
-                  MAT_DIRTY_INVERSE);
-}
-
-
-static void matrix_copy( GLmatrix *to, const GLmatrix *from )
-{
-   MEMCPY( to->m, from->m, sizeof(Identity) );
-   to->flags = from->flags | MAT_DIRTY_DEPENDENTS;
-   to->type = from->type;
-
-   if (to->inv != 0) {
-      if (from->inv == 0) {
-        matrix_invert( to );
-      }
-      else {
-        MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16);
-      }
-   }
-}
-
-/*
- * Multiply a matrix by an array of floats with known properties.
- */
-static void mat_mul_floats( GLmatrix *mat, const GLfloat *m, GLuint flags )
-{
-   mat->flags |= (flags |
-                 MAT_DIRTY_TYPE | 
-                 MAT_DIRTY_INVERSE | 
-                 MAT_DIRTY_DEPENDENTS);
-
-   if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D))
-      matmul34( mat->m, mat->m, m );
-   else 
-      matmul4( mat->m, mat->m, m );      
-
-}
-
-
-void gl_matrix_ctr( GLmatrix *m )
-{
-   if ( m->m == 0 ) {
-      m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
-   }
-   MEMCPY( m->m, Identity, sizeof(Identity) );
-   m->inv = 0;
-   m->type = MATRIX_IDENTITY;
-   m->flags = MAT_DIRTY_DEPENDENTS;
-}
-
-void gl_matrix_dtr( GLmatrix *m )
-{
-   if ( m->m != 0 ) {
-      ALIGN_FREE( m->m );
-      m->m = 0;
-   }
-   if ( m->inv != 0 ) {
-      ALIGN_FREE( m->inv );
-      m->inv = 0;
-   }
-}
-
-
-void gl_matrix_alloc_inv( GLmatrix *m )
-{
-   if ( m->inv == 0 ) {
-      m->inv = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
-      MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) );
-   }
-}
-
-
-void gl_matrix_mul( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b )
-{
-   dest->flags = (a->flags |
-                 b->flags |
-                 MAT_DIRTY_TYPE | 
-                 MAT_DIRTY_INVERSE | 
-                 MAT_DIRTY_DEPENDENTS);
-
-   if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D))
-      matmul34( dest->m, a->m, b->m );
-   else 
-      matmul4( dest->m, a->m, b->m );
-}
 
+#include "math/m_matrix.h"
+#endif
 
 
 /**********************************************************************/
@@ -1017,45 +90,21 @@ _mesa_Frustum( GLdouble left, GLdouble right,
                GLdouble nearval, GLdouble farval )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLfloat x, y, a, b, c, d;
-   GLfloat m[16];
    GLmatrix *mat = 0;
 
    GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glFrustrum" );
 
-   if ((nearval<=0.0 || farval<=0.0) || (nearval == farval) || (left == right) || (top == bottom)) {
-      gl_error( ctx,  GL_INVALID_VALUE, "glFrustum(near or far)" );
+   if (nearval <= 0.0 ||
+       farval <= 0.0 || 
+       nearval == farval || 
+       left == right || 
+       top == bottom) 
+   {
+      gl_error( ctx,  GL_INVALID_VALUE, "glFrustum" );
       return;
    }
-
-   x = (2.0*nearval) / (right-left);
-   y = (2.0*nearval) / (top-bottom);
-   a = (right+left) / (right-left);
-   b = (top+bottom) / (top-bottom);
-   c = -(farval+nearval) / ( farval-nearval);
-   d = -(2.0*farval*nearval) / (farval-nearval);  /* error? */
-
-#define M(row,col)  m[col*4+row]
-   M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F;
-   M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F;
-   M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d;
-   M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F;
-#undef M
-
-   mat_mul_floats( mat, m, MAT_FLAG_PERSPECTIVE );
-
-   if (ctx->Transform.MatrixMode == GL_PROJECTION) {
-      /* Need to keep a stack of near/far values in case the user push/pops
-       * the projection matrix stack so that we can call Driver.NearFar()
-       * after a pop.
-       */
-      ctx->NearFarStack[ctx->ProjectionStackDepth][0] = nearval;
-      ctx->NearFarStack[ctx->ProjectionStackDepth][1] = farval;
-      
-      if (ctx->Driver.NearFar) {
-        (*ctx->Driver.NearFar)( ctx, nearval, farval );
-      }
-   }
+   
+   _math_matrix_frustrum( mat, left, right, bottom, top, nearval, farval );
 }
 
 
@@ -1065,38 +114,19 @@ _mesa_Ortho( GLdouble left, GLdouble right,
              GLdouble nearval, GLdouble farval )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLfloat x, y, z;
-   GLfloat tx, ty, tz;
-   GLfloat m[16];
    GLmatrix *mat = 0;
 
    GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glOrtho" );
    
-   if ((left == right) || (bottom == top) || (nearval == farval)) {
-      gl_error( ctx,  GL_INVALID_VALUE,
-                "gl_Ortho((l = r) or (b = top) or (n=f)" );
+   if (left == right || 
+       bottom == top || 
+       nearval == farval) 
+   {
+      gl_error( ctx,  GL_INVALID_VALUE, "gl_Ortho" );
       return;
    }
 
-   x = 2.0 / (right-left);
-   y = 2.0 / (top-bottom);
-   z = -2.0 / (farval-nearval);
-   tx = -(right+left) / (right-left);
-   ty = -(top+bottom) / (top-bottom);
-   tz = -(farval+nearval) / (farval-nearval);
-
-#define M(row,col)  m[col*4+row]
-   M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = 0.0F;  M(0,3) = tx;
-   M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = 0.0F;  M(1,3) = ty;
-   M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = z;     M(2,3) = tz;
-   M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = 0.0F;  M(3,3) = 1.0F;
-#undef M
-
-   mat_mul_floats( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION));
-
-   if (ctx->Driver.NearFar) {
-      (*ctx->Driver.NearFar)( ctx, nearval, farval );
-   }
+   _math_matrix_ortho( mat, left, right, bottom, top, nearval, farval );
 }
 
 
@@ -1135,7 +165,7 @@ _mesa_PushMatrix( void )
             gl_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
             return;
          }
-         matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++],
+         _math_matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++],
                       &ctx->ModelView );
          break;
       case GL_PROJECTION:
@@ -1143,14 +173,8 @@ _mesa_PushMatrix( void )
             gl_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
             return;
          }
-         matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++],
+         _math_matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++],
                       &ctx->ProjectionMatrix );
-
-         /* Save near and far projection values */
-         ctx->NearFarStack[ctx->ProjectionStackDepth][0]
-            = ctx->NearFarStack[ctx->ProjectionStackDepth-1][0];
-         ctx->NearFarStack[ctx->ProjectionStackDepth][1]
-            = ctx->NearFarStack[ctx->ProjectionStackDepth-1][1];
          break;
       case GL_TEXTURE:
          {
@@ -1159,7 +183,7 @@ _mesa_PushMatrix( void )
                gl_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
                return;
             }
-           matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++],
+           _math_matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++],
                          &ctx->TextureMatrix[t] );
          }
          break;
@@ -1168,7 +192,7 @@ _mesa_PushMatrix( void )
             gl_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
             return;
          }
-         matrix_copy( &ctx->ColorStack[ctx->ColorStackDepth++],
+         _math_matrix_copy( &ctx->ColorStack[ctx->ColorStackDepth++],
                       &ctx->ColorMatrix );
          break;
       default:
@@ -1194,8 +218,8 @@ _mesa_PopMatrix( void )
             gl_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
             return;
          }
-         matrix_copy( &ctx->ModelView,
-                      &ctx->ModelViewStack[--ctx->ModelViewStackDepth] );
+         _math_matrix_copy( &ctx->ModelView,
+                           &ctx->ModelViewStack[--ctx->ModelViewStackDepth] );
         ctx->NewState |= _NEW_MODELVIEW;
          break;
       case GL_PROJECTION:
@@ -1204,18 +228,9 @@ _mesa_PopMatrix( void )
             return;
          }
 
-         matrix_copy( &ctx->ProjectionMatrix,
-                      &ctx->ProjectionStack[--ctx->ProjectionStackDepth] );
+         _math_matrix_copy( &ctx->ProjectionMatrix,
+                           &ctx->ProjectionStack[--ctx->ProjectionStackDepth] );
         ctx->NewState |= _NEW_PROJECTION;
-
-         /* Device driver near/far values */
-         {
-            GLfloat nearVal = ctx->NearFarStack[ctx->ProjectionStackDepth][0];
-            GLfloat farVal  = ctx->NearFarStack[ctx->ProjectionStackDepth][1];
-            if (ctx->Driver.NearFar) {
-               (*ctx->Driver.NearFar)( ctx, nearVal, farVal );
-            }
-         }
          break;
       case GL_TEXTURE:
          {
@@ -1224,8 +239,8 @@ _mesa_PopMatrix( void )
                gl_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
                return;
             }
-           matrix_copy(&ctx->TextureMatrix[t],
-                        &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]);
+           _math_matrix_copy(&ctx->TextureMatrix[t],
+                             &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]);
            ctx->NewState |= _NEW_TEXTURE_MATRIX;
          }
          break;
@@ -1234,8 +249,8 @@ _mesa_PopMatrix( void )
             gl_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
             return;
          }
-         matrix_copy(&ctx->ColorMatrix,
-                     &ctx->ColorStack[--ctx->ColorStackDepth]);
+         _math_matrix_copy(&ctx->ColorMatrix,
+                          &ctx->ColorStack[--ctx->ColorStackDepth]);
         ctx->NewState |= _NEW_COLOR_MATRIX;
          break;
       default:
@@ -1251,19 +266,7 @@ _mesa_LoadIdentity( void )
    GET_CURRENT_CONTEXT(ctx);
    GLmatrix *mat = 0;
    GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadIdentity");
-
-   MEMCPY( mat->m, Identity, 16*sizeof(GLfloat) );
-
-   if (mat->inv)
-      MEMCPY( mat->inv, Identity, 16*sizeof(GLfloat) );
-
-   mat->type = MATRIX_IDENTITY;
-   
-   /* Have to set this to dirty to make sure we recalculate the
-    * combined matrix later.  The update_matrix in this case is a
-    * shortcircuit anyway...
-    */
-   mat->flags = MAT_DIRTY_DEPENDENTS;  
+   _math_matrix_set_identity( mat );
 }
 
 
@@ -1273,38 +276,15 @@ _mesa_LoadMatrixf( const GLfloat *m )
    GET_CURRENT_CONTEXT(ctx);
    GLmatrix *mat = 0;
    GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadMatrix");
-
-   MEMCPY( mat->m, m, 16*sizeof(GLfloat) );
-   mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER);
-
-   if (ctx->Transform.MatrixMode == GL_PROJECTION) {
-
-#define M(row,col)  m[col*4+row]
-      GLfloat c = M(2,2);
-      GLfloat d = M(2,3);
-#undef M
-      GLfloat n = (c ==  1.0 ? 0.0 : d / (c - 1.0));
-      GLfloat f = (c == -1.0 ? 1.0 : d / (c + 1.0));
-
-      /* Need to keep a stack of near/far values in case the user
-       * push/pops the projection matrix stack so that we can call
-       * Driver.NearFar() after a pop.
-       */
-      ctx->NearFarStack[ctx->ProjectionStackDepth][0] = n;
-      ctx->NearFarStack[ctx->ProjectionStackDepth][1] = f;
-
-      if (ctx->Driver.NearFar) {
-        (*ctx->Driver.NearFar)( ctx, n, f );
-      }
-   }
+   _math_matrix_loadf( mat, m );
 }
 
 
 void
 _mesa_LoadMatrixd( const GLdouble *m )
 {
-   GLfloat f[16];
    GLint i;
+   GLfloat f[16];
    for (i = 0; i < 16; i++)
       f[i] = m[i];
    _mesa_LoadMatrixf(f);
@@ -1321,8 +301,7 @@ _mesa_MultMatrixf( const GLfloat *m )
    GET_CURRENT_CONTEXT(ctx);
    GLmatrix *mat = 0;
    GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glMultMatrix" );
-   matmul4( mat->m, mat->m, m );
-   mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER);
+   _math_matrix_mul_floats( mat, m );
 }
 
 
@@ -1332,11 +311,11 @@ _mesa_MultMatrixf( const GLfloat *m )
 void
 _mesa_MultMatrixd( const GLdouble *m )
 {
-   GET_CURRENT_CONTEXT(ctx);
-   GLmatrix *mat = 0;
-   GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glMultMatrix" );
-   matmul4fd( mat->m, mat->m, m );
-   mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER);
+   GLint i;
+   GLfloat f[16];
+   for (i = 0; i < 16; i++)
+      f[i] = m[i];
+   _mesa_MultMatrixf( f );
 }
 
 
@@ -1349,13 +328,10 @@ void
 _mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLfloat m[16];
    if (angle != 0.0F) {
       GLmatrix *mat = 0;
       GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glRotate" );
-
-      gl_rotation_matrix( angle, x, y, z, m );
-      mat_mul_floats( mat, m, MAT_FLAG_ROTATION );
+      _math_matrix_rotate( mat, angle, x, y, z );
    }
 }
 
@@ -1374,23 +350,8 @@ _mesa_Scalef( GLfloat x, GLfloat y, GLfloat z )
 {
    GET_CURRENT_CONTEXT(ctx);
    GLmatrix *mat = 0;
-   GLfloat *m;
    GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glScale");
-
-   m = mat->m;
-   m[0] *= x;   m[4] *= y;   m[8]  *= z;
-   m[1] *= x;   m[5] *= y;   m[9]  *= z;
-   m[2] *= x;   m[6] *= y;   m[10] *= z;
-   m[3] *= x;   m[7] *= y;   m[11] *= z;
-
-   if (fabs(x - y) < 1e-8 && fabs(x - z) < 1e-8)
-      mat->flags |= MAT_FLAG_UNIFORM_SCALE;
-   else
-      mat->flags |= MAT_FLAG_GENERAL_SCALE;
-
-   mat->flags |= (MAT_DIRTY_TYPE | 
-                 MAT_DIRTY_INVERSE | 
-                 MAT_DIRTY_DEPENDENTS);
+   _math_matrix_scale( mat, x, y, z );
 }
 
 
@@ -1409,18 +370,8 @@ _mesa_Translatef( GLfloat x, GLfloat y, GLfloat z )
 {
    GET_CURRENT_CONTEXT(ctx);
    GLmatrix *mat = 0;
-   GLfloat *m;
    GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glTranslate");
-   m = mat->m;
-   m[12] = m[0] * x + m[4] * y + m[8]  * z + m[12];
-   m[13] = m[1] * x + m[5] * y + m[9]  * z + m[13];
-   m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
-   m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
-
-   mat->flags |= (MAT_FLAG_TRANSLATION | 
-                 MAT_DIRTY_TYPE | 
-                 MAT_DIRTY_INVERSE | 
-                 MAT_DIRTY_DEPENDENTS);
+   _math_matrix_translate( mat, x, y, z );
 }
 
 
@@ -1431,12 +382,11 @@ _mesa_Translated( GLdouble x, GLdouble y, GLdouble z )
 }
 
 
-
 void
 _mesa_LoadTransposeMatrixfARB( const GLfloat *m )
 {
    GLfloat tm[16];
-   gl_matrix_transposef(tm, m);
+   _math_transposef(tm, m);
    _mesa_LoadMatrixf(tm);
 }
 
@@ -1444,9 +394,9 @@ _mesa_LoadTransposeMatrixfARB( const GLfloat *m )
 void
 _mesa_LoadTransposeMatrixdARB( const GLdouble *m )
 {
-   GLdouble tm[16];
-   gl_matrix_transposed(tm, m);
-   _mesa_LoadMatrixd(tm);
+   GLfloat tm[16];
+   _math_transposefd(tm, m);
+   _mesa_LoadMatrixf(tm);
 }
 
 
@@ -1454,7 +404,7 @@ void
 _mesa_MultTransposeMatrixfARB( const GLfloat *m )
 {
    GLfloat tm[16];
-   gl_matrix_transposef(tm, m);
+   _math_transposef(tm, m);
    _mesa_MultMatrixf(tm);
 }
 
@@ -1462,9 +412,9 @@ _mesa_MultTransposeMatrixfARB( const GLfloat *m )
 void
 _mesa_MultTransposeMatrixdARB( const GLdouble *m )
 {
-   GLdouble tm[16];
-   gl_matrix_transposed(tm, m);
-   _mesa_MultMatrixd(tm);
+   GLfloat tm[16];
+   _math_transposefd(tm, m);
+   _mesa_MultMatrixf(tm);
 }
 
 
@@ -1518,7 +468,6 @@ gl_Viewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height )
    ctx->Viewport._WindowMap.m[MAT_TY] = ctx->Viewport._WindowMap.m[MAT_SY] + y;
    ctx->Viewport._WindowMap.m[MAT_SZ] = 0.5 * ctx->Visual.DepthMaxF;
    ctx->Viewport._WindowMap.m[MAT_TZ] = 0.5 * ctx->Visual.DepthMaxF;
-
    ctx->Viewport._WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION;
    ctx->Viewport._WindowMap.type = MATRIX_3D_NO_ROT;
    ctx->NewState |= _NEW_VIEWPORT;
index db88b2857cf00607d1fa0a86fbac750623eddea3..fce9dace65798c9cd28a9603af8b27aec207ec7d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: matrix.h,v 1.8 2000/10/29 18:12:15 brianp Exp $ */
+/* $Id: matrix.h,v 1.9 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #endif
 
 
-extern void
-gl_matrix_transposef( GLfloat to[16], const GLfloat from[16] );
-
-extern void
-gl_matrix_transposed( GLdouble to[16], const GLdouble from[16] );
-
-
-extern void
-gl_rotation_matrix( GLfloat angle, GLfloat x, GLfloat y, GLfloat z,
-                    GLfloat m[] );
-
-
 extern void
 gl_calculate_model_project_matrix( GLcontext *ctx );
 
-extern void
-gl_matrix_ctr( GLmatrix *m );
-
-extern void
-gl_matrix_dtr( GLmatrix *m );
-
-extern void
-gl_matrix_alloc_inv( GLmatrix *m );
-
-extern void
-gl_matrix_mul( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b );
-
-extern void
-gl_matrix_analyze( GLmatrix *mat );
-
-extern void
-gl_print_matrix( const GLmatrix *m );
-
-
 
 extern void
 _mesa_Frustum( GLdouble left, GLdouble right,
index b4de245e9f6ffa429127cf174a840b4e4335a71f..26c4d5efab43cbb5758968f4e43d116ea2a6803c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: points.c,v 1.22 2000/11/15 16:38:40 brianp Exp $ */
+/* $Id: points.c,v 1.23 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -36,7 +36,6 @@
 #include "points.h"
 #include "texstate.h"
 #include "types.h"
-#include "vb.h"
 #endif
 
 
index e8d36a3ba008333a410d6e685d1d577a3f8c5c22..a59e22a36a1e61af429a98bfbe80c30d8ad430bf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: rastpos.c,v 1.13 2000/11/13 20:02:56 keithw Exp $ */
+/* $Id: rastpos.c,v 1.14 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "feedback.h"
 #include "light.h"
 #include "macros.h"
-#include "matrix.h"
 #include "mmath.h"
 #include "rastpos.h"
-#include "shade.h"
 #include "state.h"
+#include "simple_list.h"
 #include "types.h"
-#include "xform.h"
+
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
 #endif
 
 
+/*
+ * Clip a point against the view volume.
+ * Input:  v - vertex-vector describing the point to clip
+ * Return:  0 = outside view volume
+ *          1 = inside view volume
+ */
+static GLuint gl_viewclip_point( const GLfloat v[] )
+{
+   if (   v[0] > v[3] || v[0] < -v[3]
+       || v[1] > v[3] || v[1] < -v[3]
+       || v[2] > v[3] || v[2] < -v[3] ) {
+      return 0;
+   }
+   else {
+      return 1;
+   }
+}
+
+/*
+ * Clip a point against the user clipping planes.
+ * Input:  v - vertex-vector describing the point to clip.
+ * Return:  0 = point was clipped
+ *          1 = point not clipped
+ */
+static GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] )
+{
+   GLuint p;
+
+   for (p=0;p<MAX_CLIP_PLANES;p++) {
+      if (ctx->Transform.ClipEnabled[p]) {
+        GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0]
+                    + v[1] * ctx->Transform._ClipUserPlane[p][1]
+                    + v[2] * ctx->Transform._ClipUserPlane[p][2]
+                    + v[3] * ctx->Transform._ClipUserPlane[p][3];
+         if (dot < 0.0F) {
+            return 0;
+         }
+      }
+   }
+
+   return 1;
+}
+
+
+/* This has been split off to allow the normal shade routines to
+ * get a little closer to the vertex buffer, and to use the 
+ * GLvector objects directly.
+ */
+static void gl_shade_rastpos( GLcontext *ctx,
+                             GLfloat vertex[4],
+                             GLfloat normal[3],
+                             GLfloat Rcolor[4],
+                             GLuint *index )
+{
+   GLfloat (*base)[3] = ctx->Light._BaseColor;
+   const GLchan *sumA = ctx->Light._BaseAlpha;
+   struct gl_light *light;
+   GLfloat color[4];
+   GLfloat diffuse = 0, specular = 0;
+
+   COPY_3V(color, base[0]);
+   color[3] = CHAN_TO_FLOAT( sumA[0] );
+
+   foreach (light, &ctx->Light.EnabledList) {
+      GLfloat n_dot_h;
+      GLfloat attenuation = 1.0;
+      GLfloat VP[3];  
+      GLfloat n_dot_VP;
+      GLfloat *h;
+      GLfloat contrib[3];
+      GLboolean normalized;
+
+      if (!(light->_Flags & LIGHT_POSITIONAL)) {
+        COPY_3V(VP, light->_VP_inf_norm);
+        attenuation = light->_VP_inf_spot_attenuation;
+      }
+      else {
+        GLfloat d; 
+        
+        SUB_3V(VP, light->_Position, vertex);
+        d = LEN_3FV( VP );
+        
+        if ( d > 1e-6) {
+           GLfloat invd = 1.0F / d;
+           SELF_SCALE_SCALAR_3V(VP, invd);
+        }
+        attenuation = 1.0F / (light->ConstantAttenuation + d * 
+                              (light->LinearAttenuation + d * 
+                               light->QuadraticAttenuation));
+        
+        if (light->_Flags & LIGHT_SPOT) 
+        {
+           GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
+           
+           if (PV_dot_dir<light->_CosCutoff) {
+              continue; 
+           }
+           else 
+           {
+              double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
+              int k = (int) x;
+              GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
+                              + (x-k)*light->_SpotExpTable[k][1]);
+              attenuation *= spot;
+           }
+        }
+      }
+
+      if (attenuation < 1e-3) 
+        continue;
+
+      n_dot_VP = DOT3( normal, VP );
+
+      if (n_dot_VP < 0.0F) {
+        ACC_SCALE_SCALAR_3V(color, attenuation, light->_MatAmbient[0]);
+        continue;
+      } 
+
+      COPY_3V(contrib, light->_MatAmbient[0]);
+      ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[0]);
+      diffuse += n_dot_VP * light->_dli * attenuation;
+
+      if (light->_IsMatSpecular[0]) {
+        if (ctx->Light.Model.LocalViewer) {
+           GLfloat v[3];
+           COPY_3V(v, vertex);
+           NORMALIZE_3FV(v);
+           SUB_3V(VP, VP, v);
+           h = VP;
+           normalized = 0;
+        }
+        else if (light->_Flags & LIGHT_POSITIONAL) {
+           h = VP;
+           ACC_3V(h, ctx->_EyeZDir);
+           normalized = 0;
+        }
+         else {
+           h = light->_h_inf_norm;
+           normalized = 1;
+        }
+        
+        n_dot_h = DOT3(normal, h);
+
+        if (n_dot_h > 0.0F) {
+           struct gl_material *mat = &ctx->Light.Material[0];
+           GLfloat spec_coef;
+           GLfloat shininess = mat->Shininess;
+
+           if (!normalized) {
+              n_dot_h *= n_dot_h;
+              n_dot_h /= LEN_SQUARED_3FV( h );
+              shininess *= .5;
+           }
+           
+           GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec_coef );
+
+           if (spec_coef > 1.0e-10) {
+              ACC_SCALE_SCALAR_3V( contrib, spec_coef,
+                                   light->_MatSpecular[0]);
+              specular += spec_coef * light->_sli * attenuation;
+           }
+        }
+      }
+
+      ACC_SCALE_SCALAR_3V( color, attenuation, contrib );
+   } 
+
+   if (ctx->Visual.RGBAflag) {
+      Rcolor[0] = CLAMP(color[0], 0.0F, 1.0F);
+      Rcolor[1] = CLAMP(color[1], 0.0F, 1.0F);
+      Rcolor[2] = CLAMP(color[2], 0.0F, 1.0F);
+      Rcolor[3] = CLAMP(color[3], 0.0F, 1.0F);
+   }
+   else {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      GLfloat d_a = mat->DiffuseIndex - mat->AmbientIndex;
+      GLfloat s_a = mat->SpecularIndex - mat->AmbientIndex;
+      GLfloat ind = mat->AmbientIndex
+                  + diffuse * (1.0F-specular) * d_a
+                  + specular * s_a;
+      if (ind > mat->SpecularIndex) {
+        ind = mat->SpecularIndex;
+      }
+      *index = (GLuint) (GLint) ind;
+   }
+
+}
+
 /*
  * Caller:  context->API.RasterPos4f
  */
@@ -54,10 +243,12 @@ static void raster_pos4f( GLcontext *ctx,
    GLfloat v[4], eye[4], clip[4], ndc[3], d;
 
    /* KW: Added this test, which is in the spec.  We can't do this
-    *     outside begin/end any more because the ctx->Current values
+    *     inside begin/end any more because the ctx->Current values
     *     aren't uptodate during that period. 
     */
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glRasterPos" );
+   FLUSH_TNL_RETURN(ctx, (FLUSH_INSIDE_BEGIN_END|
+                         FLUSH_STORED_VERTICES|
+                         FLUSH_UPDATE_CURRENT), "raster_pos4f");
 
    if (ctx->NewState)
       gl_update_state( ctx );
index eb68bf70a5f858899153042da39e84f1d75bd3d9..d1dde8c88ed344248e8a8b50eda78e940272b434 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: state.c,v 1.44 2000/11/15 16:38:59 brianp Exp $ */
+/* $Id: state.c,v 1.45 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -46,7 +46,6 @@
 #include "context.h"
 #include "convolve.h"
 #include "copypix.h"
-#include "cva.h"
 #include "depth.h"
 #include "dlist.h"
 #include "drawpix.h"
@@ -63,7 +62,6 @@
 #include "masking.h"
 #include "matrix.h"
 #include "mmath.h"
-#include "pipeline.h"
 #include "pixel.h"
 #include "pixeltex.h"
 #include "points.h"
@@ -72,7 +70,6 @@
 #include "readpix.h"
 #include "rect.h"
 #include "scissor.h"
-#include "shade.h"
 #include "state.h"
 #include "stencil.h"
 #include "teximage.h"
 #include "texture.h"
 #include "types.h"
 #include "varray.h"
-#include "vbfill.h"
-#include "vbrender.h"
 #include "winpos.h"
-#include "xform.h"
+
 #include "swrast/swrast.h"
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
+#include "tnl/t_eval.h"
+#include "tnl/t_vbfill.h"
+#include "tnl/t_varray.h"
+#include "tnl/t_rect.h"
 #endif
 
 
@@ -690,150 +691,6 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
 /**********************************************************************/
 
 
-
-
-
-void gl_print_state( const char *msg, GLuint state )
-{
-   fprintf(stderr,
-          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
-          msg,
-          state,
-          (state & _NEW_MODELVIEW)       ? "ctx->ModelView, " : "",
-          (state & _NEW_PROJECTION)      ? "ctx->Projection, " : "",
-          (state & _NEW_TEXTURE_MATRIX)  ? "ctx->TextureMatrix, " : "",
-          (state & _NEW_COLOR_MATRIX)    ? "ctx->ColorMatrix, " : "",
-          (state & _NEW_ACCUM)           ? "ctx->Accum, " : "",
-          (state & _NEW_COLOR)           ? "ctx->Color, " : "",
-          (state & _NEW_DEPTH)           ? "ctx->Depth, " : "",
-          (state & _NEW_EVAL)            ? "ctx->Eval/EvalMap, " : "",
-          (state & _NEW_FOG)             ? "ctx->Fog, " : "",
-          (state & _NEW_HINT)            ? "ctx->Hint, " : "",
-          (state & _NEW_LIGHT)           ? "ctx->Light, " : "",
-          (state & _NEW_LINE)            ? "ctx->Line, " : "",
-          (state & _NEW_FEEDBACK_SELECT) ? "ctx->Feedback/Select, " : "",
-          (state & _NEW_PIXEL)           ? "ctx->Pixel, " : "",
-          (state & _NEW_POINT)           ? "ctx->Point, " : "",
-          (state & _NEW_POLYGON)         ? "ctx->Polygon, " : "",
-          (state & _NEW_POLYGONSTIPPLE)  ? "ctx->PolygonStipple, " : "",
-          (state & _NEW_SCISSOR)         ? "ctx->Scissor, " : "",
-          (state & _NEW_TEXTURE)         ? "ctx->Texture, " : "",
-          (state & _NEW_TRANSFORM)       ? "ctx->Transform, " : "",
-          (state & _NEW_VIEWPORT)        ? "ctx->Viewport, " : "",
-          (state & _NEW_PACKUNPACK)      ? "ctx->Pack/Unpack, " : "",
-          (state & _NEW_ARRAY)           ? "ctx->Array, " : "",
-          (state & _NEW_COLORTABLE)      ? "ctx->{*}ColorTable, " : "",
-          (state & _NEW_RENDERMODE)      ? "ctx->RenderMode, " : "",
-          (state & _NEW_BUFFERS)         ? "ctx->Visual, ctx->DrawBuffer,, " : "");
-}
-
-
-void gl_print_enable_flags( const char *msg, GLuint flags )
-{
-   fprintf(stderr,
-          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
-          msg,
-          flags,
-          (flags & ENABLE_TEX0)       ? "tex-0, " : "",
-          (flags & ENABLE_TEX1)       ? "tex-1, " : "",
-          (flags & ENABLE_LIGHT)      ? "light, " : "",
-          (flags & ENABLE_FOG)        ? "fog, " : "",
-          (flags & ENABLE_USERCLIP)   ? "userclip, " : "",
-          (flags & ENABLE_TEXGEN0)    ? "tex-gen-0, " : "",
-          (flags & ENABLE_TEXGEN1)    ? "tex-gen-1, " : "",
-          (flags & ENABLE_TEXMAT0)    ? "tex-mat-0, " : "",
-          (flags & ENABLE_TEXMAT1)    ? "tex-mat-1, " : "",
-          (flags & ENABLE_NORMALIZE)  ? "normalize, " : "",
-          (flags & ENABLE_RESCALE)    ? "rescale, " : "");
-}
-
-
-/* Note: This routine refers to derived texture attribute values to
- * compute the ENABLE_TEXMAT flags, but is only called on
- * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
- * flags are updated by _mesa_update_textures(), below.  
- * 
- * If both TEXTURE and TEXTURE_MATRIX change at once, these values
- * will be computed twice. 
- */
-static void
-_mesa_update_texture_matrices( GLcontext *ctx )
-{
-   GLuint i;
-
-   ctx->_Enabled &= ~(ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2);
-
-   for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
-      if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER) {
-        gl_matrix_analyze( &ctx->TextureMatrix[i] );
-        ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
-
-        if (ctx->Texture.Unit[i]._ReallyEnabled &&
-            ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
-           ctx->_Enabled |= ENABLE_TEXMAT0 << i;
-      }
-   }
-}
-
-
-/* Note: This routine refers to derived texture matrix values to
- * compute the ENABLE_TEXMAT flags, but is only called on
- * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
- * flags are updated by _mesa_update_texture_matrices, above.  
- * 
- * If both TEXTURE and TEXTURE_MATRIX change at once, these values
- * will be computed twice.  
- */
-static void
-_mesa_update_textures( GLcontext *ctx )
-{
-   GLuint i;
-
-   ctx->Texture._ReallyEnabled = 0;
-   ctx->_Enabled &= ~(ENABLE_TEXGEN0 | ENABLE_TEXGEN1 | ENABLE_TEXGEN2 |
-                     ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2 |
-                     ENABLE_TEX0 | ENABLE_TEX1 | ENABLE_TEX2);
-
-   gl_update_dirty_texobjs(ctx);
-
-   for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
-      
-      ctx->Texture.Unit[i]._ReallyEnabled = 0;
-
-      if (ctx->Texture.Unit[i].Enabled) {
-
-        gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
-
-        if (ctx->Texture.Unit[i]._ReallyEnabled) {
-           GLuint flag = ctx->Texture.Unit[i]._ReallyEnabled << (i * 4);
-
-           ctx->Texture._ReallyEnabled |= flag;
-           ctx->_Enabled |= flag;
-
-           if (ctx->Texture.Unit[i]._GenFlags) {
-              ctx->_Enabled |= ENABLE_TEXGEN0 << i;
-              ctx->Texture._GenFlags |= ctx->Texture.Unit[i]._GenFlags;
-           }
-
-           if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
-              ctx->_Enabled |= ENABLE_TEXMAT0 << i;
-        }
-      }
-   }
-
-   ctx->_NeedNormals &= ~NEED_NORMALS_TEXGEN;
-   ctx->_NeedEyeCoords &= ~NEED_EYE_TEXGEN;
-
-   if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) {
-      ctx->_NeedNormals |= NEED_NORMALS_TEXGEN;
-      ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN;
-   }
-   
-   if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) {
-      ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN;
-   }
-}
-
 static void
 _mesa_update_polygon( GLcontext *ctx )
 {
@@ -872,11 +729,11 @@ static void
 _mesa_calculate_model_project_matrix( GLcontext *ctx )
 {
    if (!ctx->_NeedEyeCoords) {
-      gl_matrix_mul( &ctx->_ModelProjectMatrix,
-                    &ctx->ProjectionMatrix,
-                    &ctx->ModelView );
+      _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix,
+                              &ctx->ProjectionMatrix,
+                              &ctx->ModelView );
 
-      gl_matrix_analyze( &ctx->_ModelProjectMatrix );
+      _math_matrix_analyze( &ctx->_ModelProjectMatrix );
    }
 }
 
@@ -913,7 +770,6 @@ _mesa_update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords )
        */
       _mesa_update_modelview_scale(ctx);
       _mesa_calculate_model_project_matrix(ctx);
-      gl_update_normal_transform( ctx ); 
       gl_compute_light_positions( ctx );
 
       if (ctx->Driver.LightingSpaceChange)
@@ -932,9 +788,6 @@ _mesa_update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords )
       if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 
         _mesa_calculate_model_project_matrix(ctx);
            
-      if (new_state & _TNL_NEW_NORMAL_TRANSFORM)
-        gl_update_normal_transform( ctx ); /* references _ModelViewInvScale */
-            
       if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
         gl_compute_light_positions( ctx );
    }
@@ -973,7 +826,7 @@ _mesa_update_drawbuffer( GLcontext *ctx )
 static void
 _mesa_update_projection( GLcontext *ctx )
 {
-   gl_matrix_analyze( &ctx->ProjectionMatrix );
+   _math_matrix_analyze( &ctx->ProjectionMatrix );
       
    /* Recompute clip plane positions in clipspace.  This is also done
     * in _mesa_ClipPlane().
@@ -1015,7 +868,7 @@ void gl_update_state( GLcontext *ctx )
       gl_print_state("", new_state);
 
    if (new_state & _NEW_MODELVIEW) 
-      gl_matrix_analyze( &ctx->ModelView );
+      _math_matrix_analyze( &ctx->ModelView );
 
    if (new_state & _NEW_PROJECTION) 
       _mesa_update_projection( ctx );
@@ -1024,16 +877,13 @@ void gl_update_state( GLcontext *ctx )
       _mesa_update_texture_matrices( ctx );
 
    if (new_state & _NEW_COLOR_MATRIX) 
-      gl_matrix_analyze( &ctx->ColorMatrix );
+      _math_matrix_analyze( &ctx->ColorMatrix );
    
    /* References ColorMatrix.type (derived above).
     */
    if (new_state & (_NEW_PIXEL|_NEW_COLOR_MATRIX))
       _mesa_update_image_transfer_state(ctx);
 
-   if (new_state & _NEW_ARRAY)
-      gl_update_client_state( ctx );
-
    /* Contributes to NeedEyeCoords, NeedNormals.
     */
    if (new_state & _NEW_TEXTURE) 
@@ -1050,12 +900,6 @@ void gl_update_state( GLcontext *ctx )
    if (new_state & _NEW_LIGHT) 
       gl_update_lighting( ctx );
 
-   if (new_state & (_NEW_LIGHT|_NEW_TEXTURE|_NEW_FOG|
-                   _DD_NEW_TRI_LIGHT_TWOSIDE |
-                   _DD_NEW_SEPERATE_SPECULAR |
-                   _DD_NEW_TRI_UNFILLED ))
-      gl_update_clipmask(ctx);
-
    /* We can light in object space if the modelview matrix preserves
     * lengths and relative angles.
     */
@@ -1082,17 +926,13 @@ void gl_update_state( GLcontext *ctx )
                    _TNL_NEW_NEED_EYE_COORDS)) 
       _mesa_update_tnl_spaces( ctx, oldneedeyecoords );
 
-   if (new_state & ctx->Driver.UpdateStateNotify)
-   {
-      /*
-       * Here the driver sets up all the ctx->Driver function pointers to
-       * it's specific, private functions.
-       */
-      ctx->Driver.UpdateState(ctx);
-      gl_set_render_vb_function(ctx); /* XXX: remove this mechanism */
-   }
-
-   gl_update_pipelines(ctx);
+   /*
+    * Here the driver sets up all the ctx->Driver function pointers
+    * to it's specific, private functions, and performs any
+    * internal state management necessary, including invalidating
+    * state of active modules.
+    */
+   ctx->Driver.UpdateState(ctx);
    ctx->NewState = 0;
 }
 
index 45a39f61620856d43e4cfbe55a8158b88665e51e..0e33e683de1ce8c8513a652a7a876f8dbe7c7ea2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstate.c,v 1.21 2000/11/05 18:40:58 keithw Exp $ */
+/* $Id: texstate.c,v 1.22 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "enums.h"
 #include "extensions.h"
 #include "macros.h"
-#include "matrix.h"
 #include "texobj.h"
 #include "teximage.h"
 #include "texstate.h"
 #include "texture.h"
 #include "types.h"
-#include "xform.h"
+#include "math/m_xform.h"
+#include "math/m_matrix.h"
 #include "swrast/swrast.h"
 #endif
 
@@ -1116,7 +1116,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
         else if (pname==GL_EYE_PLANE) {
             /* Transform plane equation by the inverse modelview matrix */
             if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-               gl_matrix_analyze( &ctx->ModelView );
+               _math_matrix_analyze( &ctx->ModelView );
             }
             gl_transform_vector( texUnit->EyePlaneS, params,
                                  ctx->ModelView.inv );
@@ -1164,7 +1164,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
         else if (pname==GL_EYE_PLANE) {
             /* Transform plane equation by the inverse modelview matrix */
             if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-               gl_matrix_analyze( &ctx->ModelView );
+               _math_matrix_analyze( &ctx->ModelView );
             }
             gl_transform_vector( texUnit->EyePlaneT, params,
                                  ctx->ModelView.inv );
@@ -1208,7 +1208,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
         else if (pname==GL_EYE_PLANE) {
             /* Transform plane equation by the inverse modelview matrix */
             if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-               gl_matrix_analyze( &ctx->ModelView );
+               _math_matrix_analyze( &ctx->ModelView );
             }
             gl_transform_vector( texUnit->EyePlaneR, params,
                                  ctx->ModelView.inv );
@@ -1244,7 +1244,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
         else if (pname==GL_EYE_PLANE) {
             /* Transform plane equation by the inverse modelview matrix */
             if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-               gl_matrix_analyze( &ctx->ModelView );
+               _math_matrix_analyze( &ctx->ModelView );
             }
             gl_transform_vector( texUnit->EyePlaneQ, params,
                                  ctx->ModelView.inv );
@@ -1674,18 +1674,3 @@ void gl_remove_texobj_from_dirty_list( struct gl_shared_state *shared,
 }
 
 
-/*
- * This is called by gl_update_state() if the _NEW_TEXTURE bit in
- * ctx->NewState is set.
- */
-void gl_update_dirty_texobjs( GLcontext *ctx )
-{
-   struct gl_texture_object *t, *next;
-   for (t = ctx->Shared->DirtyTexObjList; t; t = next) {
-      next = t->NextDirty;
-      _mesa_test_texobj_completeness(ctx, t);
-      t->NextDirty = NULL;
-      t->Dirty = GL_FALSE;
-   }
-   ctx->Shared->DirtyTexObjList = NULL;
-}
index d3111f02e3f0aa163c83c4edbe1f090019f4dc5d..9954a0a126d56f7055d8eec9cc00f77b48974e82 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstate.h,v 1.2 1999/11/11 01:22:28 brianp Exp $ */
+/* $Id: texstate.h,v 1.3 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -140,8 +140,6 @@ extern void
 gl_remove_texobj_from_dirty_list( struct gl_shared_state *shared,
                                   struct gl_texture_object *tObj );
 
-extern void
-gl_update_dirty_texobjs( GLcontext *ctx );
 
 
 #endif
index d604beb9ddee2dff2ea38befcc3166ef391e6c11..3cd368779c0bab91f8f072b3eddd1a45cffa2692 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: varray.c,v 1.30 2000/11/05 18:40:59 keithw Exp $ */
+/* $Id: varray.c,v 1.31 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #else
 #include "glheader.h"
 #include "context.h"
-#include "cva.h"
 #include "enable.h"
 #include "enums.h"
 #include "dlist.h"
 #include "light.h"
 #include "macros.h"
 #include "mmath.h"
-#include "pipeline.h"
 #include "state.h"
 #include "texstate.h"
-#include "translate.h"
 #include "types.h"
 #include "varray.h"
-#include "vb.h"
-#include "vbfill.h"
-#include "vbrender.h"
-#include "vbindirect.h"
-#include "vbxform.h"
-#include "xform.h"
+#include "math/m_translate.h"
 #endif
 
 
@@ -96,9 +88,10 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
    ctx->Array.Vertex.Stride = stride;
    ctx->Array.Vertex.Ptr = (void *) ptr;
    ctx->Array._VertexFunc = gl_trans_4f_tab[size][TYPE_IDX(type)];
-   ctx->Array._VertexEltFunc = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
-   ctx->Array._NewArrayState |= VERT_OBJ_ANY;
    ctx->NewState |= _NEW_ARRAY;
+
+   if (ctx->Driver.VertexPointer)
+      ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -146,9 +139,10 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
    ctx->Array.Normal.Stride = stride;
    ctx->Array.Normal.Ptr = (void *) ptr;
    ctx->Array._NormalFunc = gl_trans_3f_tab[TYPE_IDX(type)];
-   ctx->Array._NormalEltFunc = gl_trans_elt_3f_tab[TYPE_IDX(type)];
-   ctx->Array._NewArrayState |= VERT_NORM;
    ctx->NewState |= _NEW_ARRAY;
+
+   if (ctx->Driver.NormalPointer)
+      ctx->Driver.NormalPointer( ctx, type, stride, ptr );
 }
 
 
@@ -209,9 +203,10 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
    ctx->Array.Color.Stride = stride;
    ctx->Array.Color.Ptr = (void *) ptr;
    ctx->Array._ColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
-   ctx->Array._ColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)];
-   ctx->Array._NewArrayState |= VERT_RGBA;
    ctx->NewState |= _NEW_ARRAY;
+
+   if (ctx->Driver.ColorPointer)
+      ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -244,9 +239,10 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
    ctx->Array.FogCoord.Stride = stride;
    ctx->Array.FogCoord.Ptr = (void *) ptr;
    ctx->Array._FogCoordFunc = gl_trans_1f_tab[TYPE_IDX(type)];
-   ctx->Array._FogCoordEltFunc = gl_trans_elt_1f_tab[TYPE_IDX(type)];
-   ctx->Array._NewArrayState |= VERT_FOG_COORD;
    ctx->NewState |= _NEW_ARRAY;
+
+   if (ctx->Driver.FogCoordPointer)
+      ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
 }
 
 
@@ -287,9 +283,10 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
    ctx->Array.Index.Stride = stride;
    ctx->Array.Index.Ptr = (void *) ptr;
    ctx->Array._IndexFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
-   ctx->Array._IndexEltFunc = gl_trans_elt_1ui_tab[TYPE_IDX(type)];
-   ctx->Array._NewArrayState |= VERT_INDEX;
    ctx->NewState |= _NEW_ARRAY;
+
+   if (ctx->Driver.IndexPointer)
+      ctx->Driver.IndexPointer( ctx, type, stride, ptr );
 }
 
 
@@ -350,9 +347,10 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
    ctx->Array.SecondaryColor.Stride = stride;
    ctx->Array.SecondaryColor.Ptr = (void *) ptr;
    ctx->Array._SecondaryColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
-   ctx->Array._SecondaryColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)];
-   ctx->Array._NewArrayState |= VERT_SPEC_RGB;
    ctx->NewState |= _NEW_ARRAY;
+
+   if (ctx->Driver.SecondaryColorPointer)
+      ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -405,11 +403,11 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr
    ctx->Array.TexCoord[texUnit].Type = type;
    ctx->Array.TexCoord[texUnit].Stride = stride;
    ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr;
-
    ctx->Array._TexCoordFunc[texUnit] = gl_trans_4f_tab[size][TYPE_IDX(type)];
-   ctx->Array._TexCoordEltFunc[texUnit] = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
-   ctx->Array._NewArrayState |= VERT_TEX_ANY(texUnit);
    ctx->NewState |= _NEW_ARRAY;
+
+   if (ctx->Driver.TexCoordPointer)
+      ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -433,9 +431,10 @@ _mesa_EdgeFlagPointer(GLsizei stride, const void *vptr)
    } else {
       ctx->Array._EdgeFlagFunc = 0;
    }
-   ctx->Array._EdgeFlagEltFunc = gl_trans_elt_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
-   ctx->Array._NewArrayState |= VERT_EDGE;
    ctx->NewState |= _NEW_ARRAY;
+
+   if (ctx->Driver.EdgeFlagPointer)
+      ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
 }
 
 
@@ -498,620 +497,6 @@ _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
 
 
 
-/* KW: Batch function to exec all the array elements in the input
- *     buffer prior to transform.  Done only the first time a vertex
- *     buffer is executed or compiled.
- *
- * KW: Have to do this after each glEnd if cva isn't active.  (also
- *     have to do it after each full buffer)
- */
-void gl_exec_array_elements( GLcontext *ctx, struct immediate *IM,
-                            GLuint start, 
-                            GLuint count)
-{
-   GLuint *flags = IM->Flag;
-   GLuint *elts = IM->Elt;
-   GLuint translate = ctx->Array._Flags;
-   GLuint i;
-
-   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
-      fprintf(stderr, "exec_array_elements %d .. %d\n", start, count);
-   
-   if (translate & VERT_OBJ_ANY) 
-      (ctx->Array._VertexEltFunc)( IM->Obj, 
-                                 &ctx->Array.Vertex, 
-                                 flags, elts, (VERT_ELT|VERT_OBJ_ANY),
-                                 start, count);
-   
-   if (translate & VERT_NORM) 
-      (ctx->Array._NormalEltFunc)( IM->Normal, 
-                                 &ctx->Array.Normal, 
-                                 flags, elts, (VERT_ELT|VERT_NORM),
-                                 start, count);
-
-   if (translate & VERT_EDGE) 
-      (ctx->Array._EdgeFlagEltFunc)( IM->EdgeFlag, 
-                                   &ctx->Array.EdgeFlag, 
-                                   flags, elts, (VERT_ELT|VERT_EDGE),
-                                   start, count);
-   
-   if (translate & VERT_RGBA)
-      (ctx->Array._ColorEltFunc)( IM->Color, 
-                                &ctx->Array.Color, 
-                                flags, elts, (VERT_ELT|VERT_RGBA),
-                                start, count);
-
-
-   if (translate & VERT_SPEC_RGB)
-      (ctx->Array._SecondaryColorEltFunc)( IM->SecondaryColor, 
-                                         &ctx->Array.SecondaryColor, 
-                                         flags, elts, (VERT_ELT|VERT_SPEC_RGB),
-                                         start, count);
-
-   if (translate & VERT_FOG_COORD)
-      (ctx->Array._FogCoordEltFunc)( IM->FogCoord, 
-                                   &ctx->Array.FogCoord, 
-                                   flags, elts, (VERT_ELT|VERT_FOG_COORD),
-                                   start, count);
-
-   if (translate & VERT_INDEX)
-      (ctx->Array._IndexEltFunc)( IM->Index, 
-                                &ctx->Array.Index, 
-                                flags, elts, (VERT_ELT|VERT_INDEX),
-                                start, count);
-
-   if (translate & VERT_TEX0_ANY)
-      (ctx->Array._TexCoordEltFunc[0])( IM->TexCoord[0], 
-                                      &ctx->Array.TexCoord[0], 
-                                      flags, elts, (VERT_ELT|VERT_TEX0_ANY),
-                                      start, count);
-
-   if (translate & VERT_TEX1_ANY)
-      (ctx->Array._TexCoordEltFunc[1])( IM->TexCoord[1], 
-                                      &ctx->Array.TexCoord[1], 
-                                      flags, elts, (VERT_ELT|VERT_TEX1_ANY),
-                                      start, count);
-
-#if MAX_TEXTURE_UNITS > 2
-   if (translate & VERT_TEX2_ANY)
-      (ctx->Array._TexCoordEltFunc[2])( IM->TexCoord[2], 
-                                      &ctx->Array.TexCoord[2], 
-                                      flags, elts, (VERT_ELT|VERT_TEX2_ANY),
-                                      start, count);
-#endif
-#if MAX_TEXTURE_UNITS > 3
-   if (translate & VERT_TEX3_ANY)
-      (ctx->Array._TexCoordEltFunc[3])( IM->TexCoord[3], 
-                                      &ctx->Array.TexCoord[3], 
-                                      flags, elts, (VERT_ELT|VERT_TEX3_ANY),
-                                      start, count);
-#endif
-
-   for (i = start ; i < count ; i++) 
-      if (flags[i] & VERT_ELT) 
-        flags[i] |= translate;
-
-}
-
-
-
-/* Enough funny business going on in here it might be quicker to use a
- * function pointer.
- */
-#define ARRAY_ELT( IM, i )                                     \
-{                                                              \
-   GLuint count = IM->Count;                                   \
-   IM->Elt[count] = i;                                         \
-   IM->Flag[count] = ((IM->Flag[count] & IM->ArrayAndFlags) |  \
-                     VERT_ELT);                                \
-   IM->FlushElt |= IM->ArrayEltFlush;                          \
-   IM->Count = count += IM->ArrayIncr;                         \
-   if (count == VB_MAX)                                                \
-      _mesa_maybe_transform_vb( IM );                          \
-}
-
-
-void
-_mesa_ArrayElement( GLint i )
-{
-   GET_IMMEDIATE;
-   ARRAY_ELT( IM, i );
-}
-
-
-static void
-gl_ArrayElement( GLcontext *CC, GLint i )
-{
-   struct immediate *im = CC->input;
-   ARRAY_ELT( im, i );
-}
-
-
-
-void
-_mesa_DrawArrays(GLenum mode, GLint start, GLsizei count)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct vertex_buffer *VB = ctx->VB;
-   GLint i;
-
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawArrays");
-
-   if (count<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
-      return;
-   }
-
-   if (!ctx->CompileFlag && ctx->Array.Vertex.Enabled) {
-      GLint remaining = count;
-      GLint i;
-      struct gl_client_array *Normal;
-      struct gl_client_array *Color;
-      struct gl_client_array *SecondaryColor;
-      struct gl_client_array *FogCoord;
-      struct gl_client_array *Index;
-      struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS];
-      struct gl_client_array *EdgeFlag;
-      struct immediate *IM = VB->IM;
-      struct gl_pipeline *elt = &ctx->CVA.elt;
-      GLboolean relock;
-      GLuint fallback, required;
-
-      if (ctx->NewState)
-        gl_update_state( ctx );        
-
-      /* Just turn off cva on this path.  Could be useful for multipass
-       * rendering to keep it turned on.
-       */
-      relock = ctx->CompileCVAFlag;
-
-      if (relock) {
-        ctx->CompileCVAFlag = 0;
-        elt->pipeline_valid = 0;
-      }
-
-      if (!elt->pipeline_valid)
-        gl_build_immediate_pipeline( ctx );
-
-      required = elt->inputs;
-      fallback = (elt->inputs & ~ctx->Array._Summary);
-
-      /* The translate function doesn't do anything about size.  It
-       * just ensures that type and stride come out right.
-       */
-      IM->v.Obj.size = ctx->Array.Vertex.Size;
-
-      if (required & VERT_RGBA) {
-        Color = &ctx->Array.Color;
-        if (fallback & VERT_RGBA) {
-           Color = &ctx->Fallback.Color;
-           ctx->Array._ColorFunc = 
-              gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)];
-        }
-      }
-
-      if (required & VERT_SPEC_RGB) 
-      {
-        SecondaryColor = &ctx->Array.SecondaryColor;
-        if (fallback & VERT_SPEC_RGB) {
-           SecondaryColor = &ctx->Fallback.SecondaryColor;
-           ctx->Array._SecondaryColorFunc = 
-              gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)];
-        }
-      }
-
-      if (required & VERT_FOG_COORD) 
-      {
-        FogCoord = &ctx->Array.FogCoord;
-        if (fallback & VERT_FOG_COORD) {
-           FogCoord = &ctx->Fallback.FogCoord;
-           ctx->Array._FogCoordFunc = 
-              gl_trans_1f_tab[TYPE_IDX(GL_FLOAT)];
-        }
-      }
-   
-      if (required & VERT_INDEX) {
-        Index = &ctx->Array.Index;
-        if (fallback & VERT_INDEX) {
-           Index = &ctx->Fallback.Index;
-           ctx->Array._IndexFunc = gl_trans_1ui_tab[TYPE_IDX(GL_UNSIGNED_INT)];
-        }
-      }
-
-      for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)  {
-        GLuint flag = VERT_TEX_ANY(i);
-
-        if (required & flag) {
-           TexCoord[i] = &ctx->Array.TexCoord[i];
-
-           if (fallback & flag) {
-              TexCoord[i] = &ctx->Fallback.TexCoord[i];
-              TexCoord[i]->Size = gl_texcoord_size( ctx->Current.Flag, i );
-
-              ctx->Array._TexCoordFunc[i] = 
-                 gl_trans_4f_tab[TexCoord[i]->Size][TYPE_IDX(GL_FLOAT)];
-           }
-        }
-      }
-
-      if (ctx->Array._Flags != ctx->Array._Flag[0]) {
-        for (i = 0 ; i < VB_MAX ; i++) 
-           ctx->Array._Flag[i] = ctx->Array._Flags;
-      }
-
-      if (required & VERT_NORM)  {
-        Normal = &ctx->Array.Normal;
-        if (fallback & VERT_NORM) {
-           Normal = &ctx->Fallback.Normal;
-           ctx->Array._NormalFunc = gl_trans_3f_tab[TYPE_IDX(GL_FLOAT)];
-        }
-      }
-
-      if ( required & VERT_EDGE ) {
-        if (mode == GL_TRIANGLES || 
-            mode == GL_QUADS || 
-            mode == GL_POLYGON) {
-           EdgeFlag = &ctx->Array.EdgeFlag;
-           if (fallback & VERT_EDGE) {
-              EdgeFlag = &ctx->Fallback.EdgeFlag;
-              ctx->Array._EdgeFlagFunc = 
-                 gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
-           }
-        }
-        else
-           required &= ~VERT_EDGE;
-      }
-
-      VB->Primitive = IM->Primitive; 
-      VB->NextPrimitive = IM->NextPrimitive; 
-      VB->MaterialMask = IM->MaterialMask;
-      VB->Material = IM->Material;
-      VB->BoundsPtr = 0;
-
-      while (remaining > 0) {
-         GLint vbspace = VB_MAX - VB_START;
-        GLuint count, n;
-        
-        if (vbspace >= remaining) {
-           n = remaining;
-           VB->LastPrimitive = VB_START + n;
-        }
-         else {
-           n = vbspace;
-           VB->LastPrimitive = VB_START;
-        }
-        
-        VB->CullMode = 0;
-        
-        ctx->Array._VertexFunc( IM->Obj + VB_START, 
-                               &ctx->Array.Vertex, start, n );
-        
-        if (required & VERT_NORM) {
-           ctx->Array._NormalFunc( IM->Normal + VB_START, 
-                                  Normal, start, n );
-        }
-        
-        if (required & VERT_EDGE) {
-           ctx->Array._EdgeFlagFunc( IM->EdgeFlag + VB_START, 
-                                    EdgeFlag, start, n );
-        }
-        
-        if (required & VERT_RGBA) {
-           ctx->Array._ColorFunc( IM->Color + VB_START, 
-                                 Color, start, n );
-        }
-
-        if (required & VERT_SPEC_RGB) {
-           ctx->Array._SecondaryColorFunc( IM->SecondaryColor + VB_START, 
-                                          SecondaryColor, start, n );
-        }
-
-        if (required & VERT_FOG_COORD) {
-           ctx->Array._FogCoordFunc( IM->FogCoord + VB_START, 
-                                    FogCoord, start, n );
-        }
-        
-        if (required & VERT_INDEX) {
-           ctx->Array._IndexFunc( IM->Index + VB_START, 
-                                 Index, start, n );
-        }
-        
-        if (required & VERT_TEX0_ANY) {
-           IM->v.TexCoord[0].size = TexCoord[0]->Size;
-           ctx->Array._TexCoordFunc[0]( IM->TexCoord[0] + VB_START, 
-                                       TexCoord[0], start, n );
-        }
-        
-        if (required & VERT_TEX1_ANY) {
-           IM->v.TexCoord[1].size = TexCoord[1]->Size;
-           ctx->Array._TexCoordFunc[1]( IM->TexCoord[1] + VB_START, 
-                                       TexCoord[1], start, n );
-        }
-#if MAX_TEXTURE_UNITS > 2
-        if (required & VERT_TEX2_ANY) {
-           IM->v.TexCoord[2].size = TexCoord[2]->Size;
-           ctx->Array._TexCoordFunc[2]( IM->TexCoord[2] + VB_START, 
-                                       TexCoord[2], start, n );
-        }
-#endif
-#if MAX_TEXTURE_UNITS > 3
-        if (required & VERT_TEX3_ANY) {
-           IM->v.TexCoord[3].size = TexCoord[3]->Size;
-           ctx->Array._TexCoordFunc[3]( IM->TexCoord[3] + VB_START, 
-                                       TexCoord[3], start, n );
-        }
-#endif
-
-        VB->ObjPtr = &IM->v.Obj;
-        VB->NormalPtr = &IM->v.Normal;
-        VB->ColorPtr = &IM->v.Color;
-        VB->Color[0] = VB->Color[1] = VB->ColorPtr;
-        VB->IndexPtr = &IM->v.Index;
-        VB->EdgeFlagPtr = &IM->v.EdgeFlag;
-        VB->SecondaryColorPtr = &IM->v.SecondaryColor;
-        VB->FogCoordPtr = &IM->v.FogCoord;
-         for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-            VB->TexCoordPtr[i] = &IM->v.TexCoord[i];
-         }
-
-        VB->Flag = ctx->Array._Flag;
-        VB->OrFlag = ctx->Array._Flags;
-
-        VB->Start = IM->Start = VB_START;
-        count = VB->Count = IM->Count = VB_START + n;
-
-#define RESET_VEC(v, t, s, c) (v.start = t v.data[s], v.count = c)  
-
-        RESET_VEC(IM->v.Obj, (GLfloat *), VB_START, count);
-        RESET_VEC(IM->v.Normal, (GLfloat *), VB_START, count);
-         for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-            RESET_VEC(IM->v.TexCoord[i], (GLfloat *), VB_START, count);
-         }
-        RESET_VEC(IM->v.Index, &, VB_START, count);
-        RESET_VEC(IM->v.Elt, &, VB_START, count);
-        RESET_VEC(IM->v.EdgeFlag, &, VB_START, count);
-        RESET_VEC(IM->v.Color, (GLubyte *), VB_START, count);
-        RESET_VEC(VB->Clip, (GLfloat *), VB_START, count);
-        RESET_VEC(VB->Eye, (GLfloat *), VB_START, count);
-        RESET_VEC(VB->Win, (GLfloat *), VB_START, count);
-        RESET_VEC(VB->BColor, (GLubyte *), VB_START, count); 
-        RESET_VEC(VB->BIndex, &, VB_START, count);
-
-        VB->NextPrimitive[VB->CopyStart] = VB->Count;
-        VB->Primitive[VB->CopyStart] = mode;
-        ctx->Array._Flag[count] |= VERT_END_VB;
-
-         /* Transform and render.
-         */
-         gl_run_pipeline( VB );
-        gl_reset_vb( VB );
-
-        /* Restore values:
-         */
-        ctx->Array._Flag[count] = ctx->Array._Flags;
-        ctx->Array._Flag[VB_START] = ctx->Array._Flags;
-
-         start += n;
-         remaining -= n;
-      }
-
-      gl_reset_input( ctx );
-
-      if (relock) {
-        ctx->CompileCVAFlag = relock;
-        elt->pipeline_valid = 0;
-      }
-   }
-   else if (ctx->Array.Vertex.Enabled) 
-   {
-      /* The GL_COMPILE and GL_COMPILE_AND_EXECUTE cases.  These
-       * could be handled by the above code, but it gets a little
-       * complex.  The generated list is still of good quality
-       * this way.
-       */
-      gl_Begin( ctx, mode );
-      for (i=0;i<count;i++) {
-         gl_ArrayElement( ctx, start+i );
-      }
-      gl_End( ctx );
-   }
-   else
-   {
-      /* The degenerate case where vertices are not enabled - only
-       * need to process the very final array element, as all of the
-       * preceding ones would be overwritten anyway. 
-       */
-      gl_Begin( ctx, mode );
-      gl_ArrayElement( ctx, start+count );
-      gl_End( ctx );
-   }
-}
-
-
-
-/* KW: Exactly fakes the effects of calling glArrayElement multiple times.
- */
-#if 1
-#define DRAW_ELT(FUNC, TYPE)                           \
-static void FUNC( GLcontext *ctx, GLenum mode,         \
-                 TYPE *indices, GLuint count )         \
-{                                                      \
-   GLuint i,j;                                         \
-                                                       \
-   gl_Begin( ctx, mode );                              \
-                                                       \
-   for (j = 0 ; j < count ; ) {                                \
-      struct immediate *IM = ctx->input;               \
-      GLuint start = IM->Start;                                \
-      GLuint nr = MIN2( VB_MAX, count - j + start );   \
-      GLuint sf = IM->Flag[start];                     \
-      IM->FlushElt |= IM->ArrayEltFlush;               \
-                                                       \
-      for (i = start ; i < nr ; i++) {                 \
-        IM->Elt[i] = (GLuint) *indices++;              \
-        IM->Flag[i] = VERT_ELT;                        \
-      }                                                        \
-                                                       \
-      if (j == 0) IM->Flag[start] |= sf;               \
-                                                       \
-      IM->Count = nr;                                  \
-      j += nr - start;                                 \
-                                                       \
-      if (j == count)                                  \
-         gl_End( ctx );                                        \
-      _mesa_maybe_transform_vb( IM );                  \
-   }                                                   \
-}
-#else 
-#define DRAW_ELT(FUNC, TYPE)                           \
-static void FUNC( GLcontext *ctx, GLenum mode,         \
-                  TYPE *indices, GLuint count )        \
-{                                                      \
-  int i;                                               \
-  glBegin(mode);                                       \
-  for (i = 0 ; i < count ; i++)                                \
-    glArrayElement( indices[i] );                      \
-  glEnd();                                             \
-}
-#endif
-       
-
-DRAW_ELT( draw_elt_ubyte, GLubyte )
-DRAW_ELT( draw_elt_ushort, GLushort )
-DRAW_ELT( draw_elt_uint, GLuint )
-
-
-static GLuint natural_stride[0x10] = 
-{
-   sizeof(GLbyte),             /* 0 */
-   sizeof(GLubyte),            /* 1 */
-   sizeof(GLshort),            /* 2 */
-   sizeof(GLushort),           /* 3 */
-   sizeof(GLint),              /* 4 */
-   sizeof(GLuint),             /* 5 */
-   sizeof(GLfloat),            /* 6 */
-   2 * sizeof(GLbyte),         /* 7 */
-   3 * sizeof(GLbyte),         /* 8 */
-   4 * sizeof(GLbyte),         /* 9 */
-   sizeof(GLdouble),           /* a */
-   0,                          /* b */
-   0,                          /* c */
-   0,                          /* d */
-   0,                          /* e */
-   0                           /* f */
-};
-
-
-void
-_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct gl_cva *cva;
-      
-   cva = &ctx->CVA;
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawElements");
-
-   if (count <= 0) {
-      if (count < 0)
-        gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
-      return;
-   }
-
-   if (mode < 0 || mode > GL_POLYGON) {
-      gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
-      return;
-   }
-   
-   if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT)
-   {
-       gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
-       return;
-   }
-
-   if (ctx->NewState)
-      gl_update_state(ctx);
-
-   if (ctx->CompileCVAFlag) 
-   {
-      /* Treat VERT_ELT like a special client array.
-       */
-      ctx->Array._NewArrayState |= VERT_ELT;
-      ctx->Array._Summary |= VERT_ELT;
-      ctx->Array._Flags |= VERT_ELT;
-
-      cva->elt_mode = mode;
-      cva->elt_count = count;
-      cva->Elt.Type = type;
-      cva->Elt.Ptr = (void *) indices;
-      cva->Elt.StrideB = natural_stride[TYPE_IDX(type)];
-      cva->EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
-
-      if (!cva->pre.pipeline_valid) 
-        gl_build_precalc_pipeline( ctx );
-      else if (MESA_VERBOSE & VERBOSE_PIPELINE)
-        fprintf(stderr, ": dont rebuild\n");
-
-      gl_cva_force_precalc( ctx );
-
-      /* Did we 'precalculate' the render op?
-       */
-      if (ctx->CVA.pre.ops & PIPE_OP_RENDER) {
-        ctx->Array._NewArrayState |= VERT_ELT;
-        ctx->Array._Summary &= ~VERT_ELT;
-        ctx->Array._Flags &= ~VERT_ELT;
-        return;
-      } 
-
-      if ( (MESA_VERBOSE&VERBOSE_VARRAY) )
-        printf("using immediate\n");
-   }
-
-
-   /* Otherwise, have to use the immediate path to render.
-    */
-   switch (type) {
-   case GL_UNSIGNED_BYTE:
-   {
-      GLubyte *ub_indices = (GLubyte *) indices;
-      if (ctx->Array._Summary & VERT_OBJ_ANY) {
-        draw_elt_ubyte( ctx, mode, ub_indices, count );
-      } else {
-        gl_ArrayElement( ctx, (GLuint) ub_indices[count-1] );
-      }
-   }
-   break;
-   case GL_UNSIGNED_SHORT:
-   {
-      GLushort *us_indices = (GLushort *) indices;
-      if (ctx->Array._Summary & VERT_OBJ_ANY) {
-        draw_elt_ushort( ctx, mode, us_indices, count );
-      } else {
-        gl_ArrayElement( ctx, (GLuint) us_indices[count-1] );
-      }
-   }
-   break;
-   case GL_UNSIGNED_INT:
-   {
-      GLuint *ui_indices = (GLuint *) indices;
-      if (ctx->Array._Summary & VERT_OBJ_ANY) {
-        draw_elt_uint( ctx, mode, ui_indices, count );
-      } else {
-        gl_ArrayElement( ctx, ui_indices[count-1] );
-      }
-   }
-   break;
-   default:
-      gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
-      break;
-   }
-
-   if (ctx->CompileCVAFlag) {
-      ctx->Array._NewArrayState |= VERT_ELT;
-      ctx->Array._Summary &= ~VERT_ELT;
-   }
-}
-
-
 
 void
 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
@@ -1307,81 +692,3 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
 
 
 
-void
-_mesa_DrawRangeElements(GLenum mode, GLuint start,
-                        GLuint end, GLsizei count,
-                        GLenum type, const GLvoid *indices)
-{
-   GET_CURRENT_CONTEXT(ctx);
-
-   if (end < start) {
-      gl_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements( end < start )");
-      return;
-   }
-
-#if 0
-   /*
-    * XXX something in locked arrays is broken!  If start = 0,
-    * end = 1 and count = 2 we'll take the LockArrays path and
-    * get incorrect results.  See Scott McMillan's bug of 3 Jan 2000.
-    * For now, don't use locked arrays.
-    */
-   if (!ctx->Array.LockCount && 2*count > (GLint) 3*(end-start)) {
-      glLockArraysEXT( start, end );
-      glDrawElements( mode, count, type, indices );
-      glUnlockArraysEXT();
-   } else {
-      glDrawElements( mode, count, type, indices );
-   }
-#else
-   glDrawElements( mode, count, type, indices );
-#endif
-}
-
-
-
-void gl_update_client_state( GLcontext *ctx )
-{
-   static const GLuint sz_flags[5] = {
-      0, 
-      0,
-      VERT_OBJ_2, 
-      VERT_OBJ_23, 
-      VERT_OBJ_234
-   };
-   static const GLuint tc_flags[5] = {
-      0, 
-      VERT_TEX0_12, 
-      VERT_TEX0_12, 
-      VERT_TEX0_123, 
-      VERT_TEX0_1234
-   };
-   GLint i;
-
-   ctx->Array._Flags = 0;
-   ctx->Array._Summary = 0;
-   ctx->input->ArrayIncr = 0;
-   
-   if (ctx->Array.Normal.Enabled)         ctx->Array._Flags |= VERT_NORM;
-   if (ctx->Array.Color.Enabled)          ctx->Array._Flags |= VERT_RGBA;
-   if (ctx->Array.SecondaryColor.Enabled) ctx->Array._Flags |= VERT_SPEC_RGB;
-   if (ctx->Array.FogCoord.Enabled)       ctx->Array._Flags |= VERT_FOG_COORD;
-   if (ctx->Array.Index.Enabled)          ctx->Array._Flags |= VERT_INDEX;
-   if (ctx->Array.EdgeFlag.Enabled)       ctx->Array._Flags |= VERT_EDGE;
-   if (ctx->Array.Vertex.Enabled) {
-      ctx->Array._Flags |= sz_flags[ctx->Array.Vertex.Size];
-      ctx->input->ArrayIncr = 1;
-   }
-   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
-      if (ctx->Array.TexCoord[i].Enabled) {
-         ctx->Array._Flags |= (tc_flags[ctx->Array.TexCoord[i].Size] << (i * NR_TEXSIZE_BITS));
-      }
-   }
-
-   /* Not really important any more:
-    */
-   ctx->Array._Summary = ctx->Array._Flags & VERT_DATA;
-   ctx->input->ArrayAndFlags = ~ctx->Array._Flags;
-   ctx->input->ArrayEltFlush = !(ctx->CompileCVAFlag);
-}
-
index 2f42dfabcbd7d85e7a660035f9ce10182179d881..bc5a679094ba5376185d22bc8516f70bd59e207f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: varray.h,v 1.8 2000/10/27 16:44:41 keithw Exp $ */
+/* $Id: varray.h,v 1.9 2000/11/16 21:05:35 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -95,53 +95,9 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
                               GLsizei stride, const GLvoid *ptr);
 
 
-extern void
-_mesa_ArrayElement( GLint );
-
-
-extern void
-_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count);
-
-
-extern void
-_mesa_save_DrawArrays(GLenum mode, GLint first, GLsizei count);
-
-
-extern void
-_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
-                   const GLvoid *indices);
-
-
-extern void
-_mesa_save_DrawElements(GLenum mode, GLsizei count,
-                        GLenum type, const GLvoid *indices);
-
-
 extern void
 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer);
 
-extern void
-_mesa_save_InterleavedArrays(GLenum format, GLsizei stride,
-                             const GLvoid *pointer);
-
-
-extern void
-_mesa_DrawRangeElements(GLenum mode, GLuint start,
-                        GLuint end, GLsizei count, GLenum type,
-                        const GLvoid *indices);
-
-extern void
-_mesa_save_DrawRangeElements(GLenum mode,
-                             GLuint start, GLuint end, GLsizei count,
-                             GLenum type, const GLvoid *indices );
-
-
-extern void gl_exec_array_elements( GLcontext *ctx, 
-                                   struct immediate *IM,
-                                   GLuint start, 
-                                   GLuint end );
-
-extern void gl_update_client_state( GLcontext *ctx );
 
 
 #endif
diff --git a/src/mesa/math/m_clip_tmp.h b/src/mesa/math/m_clip_tmp.h
new file mode 100644 (file)
index 0000000..321d3a9
--- /dev/null
@@ -0,0 +1,175 @@
+/* $Id: m_clip_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+/* KW: a clever asm implementation would nestle integer versions
+ * of the outcode calculation underneath the division.  Gcc won't
+ * do this, strangely enough, so I only do the divide in
+ * the case where the cliptest passes.  This isn't essential,
+ * and an asm implementation needn't replicate that behaviour.
+ */
+static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec, 
+                                          GLvector4f *proj_vec, 
+                                          GLubyte clipMask[],
+                                          GLubyte *orMask, 
+                                          GLubyte *andMask )
+{
+   const GLuint stride = clip_vec->stride;
+   const GLfloat *from = (GLfloat *)clip_vec->start;
+   const GLuint count = clip_vec->count;
+   GLuint c = 0;
+   GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start;
+   GLubyte tmpAndMask = *andMask;
+   GLubyte tmpOrMask = *orMask;
+   GLuint i;
+   STRIDE_LOOP {
+      const GLfloat cx = from[0];
+      const GLfloat cy = from[1];
+      const GLfloat cz = from[2];
+      const GLfloat cw = from[3];
+#if defined(macintosh)
+      /* on powerpc cliptest is 17% faster in this way. */
+      GLuint mask;
+      mask = (((cw < cx) << CLIP_RIGHT_SHIFT));
+      mask |= (((cw < -cx) << CLIP_LEFT_SHIFT));
+      mask |= (((cw < cy) << CLIP_TOP_SHIFT));
+      mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT));
+      mask |= (((cw < cz) << CLIP_FAR_SHIFT));
+      mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+#else /* !defined(macintosh)) */
+      GLubyte mask = 0;
+      if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
+      if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
+      if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
+      if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
+      if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
+      if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+#endif /* defined(macintosh) */
+
+      clipMask[i] = mask;
+      if (mask) {
+        c++;
+        tmpAndMask &= mask;
+        tmpOrMask |= mask;
+        vProj[i][0] = 0;       /* no longer required? */
+        vProj[i][1] = 0;
+        vProj[i][2] = 0;
+        vProj[i][3] = 1;
+      } else {
+        GLfloat oow = 1.0F / cw;        
+        vProj[i][3] = oow;
+        vProj[i][0] = cx * oow;
+        vProj[i][1] = cy * oow;
+        vProj[i][2] = cz * oow;      
+      }         
+   }
+
+   *orMask = tmpOrMask;
+   *andMask = (GLubyte) (c < count ? 0 : tmpAndMask);
+
+   proj_vec->flags |= VEC_SIZE_4;
+   proj_vec->size = 3;
+   proj_vec->count = clip_vec->count;
+   return proj_vec;
+}
+
+static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec, 
+                                          GLvector4f *proj_vec, 
+                                          GLubyte clipMask[],
+                                          GLubyte *orMask, 
+                                          GLubyte *andMask )
+{
+   const GLuint stride = clip_vec->stride;
+   const GLuint count = clip_vec->count;
+   const GLfloat *from = (GLfloat *)clip_vec->start;
+
+   GLubyte tmpOrMask = *orMask;
+   GLubyte tmpAndMask = *andMask;
+   GLuint i;
+   STRIDE_LOOP {
+      const GLfloat cx = from[0], cy = from[1], cz = from[2];
+      GLubyte mask = 0;
+      if (cx >  1.0)       mask |= CLIP_RIGHT_BIT;
+      else if (cx < -1.0)  mask |= CLIP_LEFT_BIT;
+      if (cy >  1.0)       mask |= CLIP_TOP_BIT;
+      else if (cy < -1.0)  mask |= CLIP_BOTTOM_BIT;
+      if (cz >  1.0)       mask |= CLIP_FAR_BIT;
+      else if (cz < -1.0)  mask |= CLIP_NEAR_BIT;
+      clipMask[i] = mask;
+      tmpOrMask |= mask;
+      tmpAndMask &= mask;
+   }
+
+   gl_vector4f_clean_elem(proj_vec, count, 3);
+      
+   *orMask = tmpOrMask;
+   *andMask = tmpAndMask;
+   return clip_vec;
+}
+
+static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec, 
+                                          GLvector4f *proj_vec, 
+                                          GLubyte clipMask[],
+                                          GLubyte *orMask, 
+                                          GLubyte *andMask )
+{
+   const GLuint stride = clip_vec->stride;
+   const GLuint count = clip_vec->count;
+   const GLfloat *from = (GLfloat *)clip_vec->start;
+
+   GLubyte tmpOrMask = *orMask;
+   GLubyte tmpAndMask = *andMask;
+   GLuint i;
+   STRIDE_LOOP {
+      const GLfloat cx = from[0], cy = from[1];
+      GLubyte mask = 0;
+      if (cx >  1.0)       mask |= CLIP_RIGHT_BIT;
+      else if (cx < -1.0)  mask |= CLIP_LEFT_BIT;
+      if (cy >  1.0)       mask |= CLIP_TOP_BIT;
+      else if (cy < -1.0)  mask |= CLIP_BOTTOM_BIT;
+      clipMask[i] = mask;
+      tmpOrMask |= mask;
+      tmpAndMask &= mask;
+   }
+
+   gl_vector4f_clean_elem(proj_vec, count, 3);
+
+   *orMask = tmpOrMask;
+   *andMask = tmpAndMask;
+   return clip_vec;
+}
+
+
+static void TAG(init_c_cliptest)( void )
+{
+   gl_clip_tab[4] = TAG(cliptest_points4);
+   gl_clip_tab[3] = TAG(cliptest_points3);
+   gl_clip_tab[2] = TAG(cliptest_points2);
+}
diff --git a/src/mesa/math/m_copy_tmp.h b/src/mesa/math/m_copy_tmp.h
new file mode 100644 (file)
index 0000000..b328537
--- /dev/null
@@ -0,0 +1,126 @@
+/* $Id: m_copy_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ *
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+#define COPY_FUNC( BITS )                                              \
+static void TAG2(copy, BITS)(GLvector4f *to, const GLvector4f *f,      \
+                            const GLubyte mask[] )                     \
+{                                                                      \
+   GLfloat (*t)[4] = (GLfloat (*)[4])to->start;                                \
+   GLfloat *from = f->start;                                           \
+   GLuint stride = f->stride;                                          \
+   GLuint count = f->count;                                            \
+   GLuint i;                                                           \
+   (void) mask;                                                                \
+                                                                       \
+   if (BITS)                                                           \
+      STRIDE_LOOP {                                                    \
+        CULL_CHECK {                                                   \
+           if (BITS&1) t[i][0] = from[0];                              \
+           if (BITS&2) t[i][1] = from[1];                              \
+           if (BITS&4) t[i][2] = from[2];                              \
+           if (BITS&8) t[i][3] = from[3];                              \
+        }                                                              \
+      }                                                                        \
+}
+
+
+
+/* static void TAG2(clean, BITS)(GLvector4f *to ) */
+/* { */
+/*    GLfloat (*t)[4] = to->data; */
+/*    GLuint i; */
+
+/*    if (BITS) */
+/*       for (i = 0 ; i < VB_SIZE ; i++) { */
+/*          if (BITS&1) t[i][0] = 0; */
+/*      if (BITS&2) t[i][1] = 0; */
+/*      if (BITS&4) t[i][2] = 0; */
+/*      if (BITS&8) t[i][3] = 1; */
+/*       } */
+/*    to->flags &= ~BITS; */
+/* } */
+
+
+/* We got them all here:
+ */
+COPY_FUNC( 0x0 )               /* noop */
+COPY_FUNC( 0x1 )
+COPY_FUNC( 0x2 )
+COPY_FUNC( 0x3 )
+COPY_FUNC( 0x4 )
+COPY_FUNC( 0x5 )
+COPY_FUNC( 0x6 )
+COPY_FUNC( 0x7 )
+COPY_FUNC( 0x8 )
+COPY_FUNC( 0x9 )
+COPY_FUNC( 0xa )
+COPY_FUNC( 0xb )
+COPY_FUNC( 0xc )
+COPY_FUNC( 0xd )
+COPY_FUNC( 0xe )
+COPY_FUNC( 0xf )
+
+static void TAG2(init_copy, 0 ) ( void )
+{
+   gl_copy_tab[IDX][0x0] = TAG2(copy, 0x0);
+   gl_copy_tab[IDX][0x1] = TAG2(copy, 0x1);
+   gl_copy_tab[IDX][0x2] = TAG2(copy, 0x2);
+   gl_copy_tab[IDX][0x3] = TAG2(copy, 0x3);
+   gl_copy_tab[IDX][0x4] = TAG2(copy, 0x4);
+   gl_copy_tab[IDX][0x5] = TAG2(copy, 0x5);
+   gl_copy_tab[IDX][0x6] = TAG2(copy, 0x6);
+   gl_copy_tab[IDX][0x7] = TAG2(copy, 0x7);
+   gl_copy_tab[IDX][0x8] = TAG2(copy, 0x8);
+   gl_copy_tab[IDX][0x9] = TAG2(copy, 0x9);
+   gl_copy_tab[IDX][0xa] = TAG2(copy, 0xa);
+   gl_copy_tab[IDX][0xb] = TAG2(copy, 0xb);
+   gl_copy_tab[IDX][0xc] = TAG2(copy, 0xc);
+   gl_copy_tab[IDX][0xd] = TAG2(copy, 0xd);
+   gl_copy_tab[IDX][0xe] = TAG2(copy, 0xe);
+   gl_copy_tab[IDX][0xf] = TAG2(copy, 0xf);
+
+/*    gl_clean_tab[IDX][0x0] = TAG2(clean, 0x0); */
+/*    gl_clean_tab[IDX][0x1] = TAG2(clean, 0x1); */
+/*    gl_clean_tab[IDX][0x2] = TAG2(clean, 0x2); */
+/*    gl_clean_tab[IDX][0x3] = TAG2(clean, 0x3); */
+/*    gl_clean_tab[IDX][0x4] = TAG2(clean, 0x4); */
+/*    gl_clean_tab[IDX][0x5] = TAG2(clean, 0x5); */
+/*    gl_clean_tab[IDX][0x6] = TAG2(clean, 0x6); */
+/*    gl_clean_tab[IDX][0x7] = TAG2(clean, 0x7); */
+/*    gl_clean_tab[IDX][0x8] = TAG2(clean, 0x8); */
+/*    gl_clean_tab[IDX][0x9] = TAG2(clean, 0x9); */
+/*    gl_clean_tab[IDX][0xa] = TAG2(clean, 0xa); */
+/*    gl_clean_tab[IDX][0xb] = TAG2(clean, 0xb); */
+/*    gl_clean_tab[IDX][0xc] = TAG2(clean, 0xc); */
+/*    gl_clean_tab[IDX][0xd] = TAG2(clean, 0xd); */
+/*    gl_clean_tab[IDX][0xe] = TAG2(clean, 0xe); */
+/*    gl_clean_tab[IDX][0xf] = TAG2(clean, 0xf); */
+}
diff --git a/src/mesa/math/m_debug_xform.c b/src/mesa/math/m_debug_xform.c
new file mode 100644 (file)
index 0000000..5041fc4
--- /dev/null
@@ -0,0 +1,930 @@
+/* $Id: m_debug_xform.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ *
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Updated for P6 architecture by Gareth Hughes.
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "mem.h"
+
+#include "m_debug_xform.h"
+#include "m_matrix.h"
+#include "m_xform.h"
+
+
+#ifdef DEBUG  /* This code only used for debugging */
+
+
+/* Comment this out to deactivate the cycle counter.
+ * NOTE: it works only on CPUs which know the 'rdtsc' command (586 or higher)
+ * (hope, you don't try to debug Mesa on a 386 ;)
+ */
+#if defined(__GNUC__) && defined(__i386__) && defined(USE_X86_ASM)
+#define  RUN_XFORM_BENCHMARK
+#endif
+
+#define TEST_COUNT             128     /* size of the tested vector array   */
+
+#define REQUIRED_PRECISION     10      /* allow 4 bits to miss              */
+#define MAX_PRECISION          24      /* max. precision possible           */
+
+
+#ifdef  RUN_XFORM_BENCHMARK
+/* Overhead of profiling counter in cycles.  Automatically adjusted to
+ * your machine at run time - counter initialization should give very
+ * consistent results.
+ */
+static int need_counter = 1;
+static long counter_overhead = 0;
+
+/* Modify the the number of tests if you like.
+ * We take the minimum of all results, because every error should be
+ * positive (time used by other processes, task switches etc).
+ * It is assumed that all calculations are done in the cache.
+ */
+
+#if 1 /* PPro, PII, PIII version */
+
+/* Profiling on the P6 architecture requires a little more work, due to
+ * the internal out-of-order execution.  We must perform a serializing
+ * 'cpuid' instruction before and after the 'rdtsc' instructions to make
+ * sure no other uops are executed when we sample the timestamp counter.
+ */
+#define  INIT_COUNTER()                                                        \
+   do {                                                                        \
+      int cycle_i;                                                     \
+      counter_overhead = LONG_MAX;                                     \
+      for ( cycle_i = 0 ; cycle_i < 4 ; cycle_i++ ) {                  \
+        long cycle_tmp1 = 0, cycle_tmp2 = 0;                           \
+        __asm__ ( "push %%ebx       \n"                                \
+                  "xor %%eax, %%eax \n"                                \
+                  "cpuid            \n"                                \
+                  "rdtsc            \n"                                \
+                  "mov %%eax, %0    \n"                                \
+                  "xor %%eax, %%eax \n"                                \
+                  "cpuid            \n"                                \
+                  "pop %%ebx        \n"                                \
+                  "push %%ebx       \n"                                \
+                  "xor %%eax, %%eax \n"                                \
+                  "cpuid            \n"                                \
+                  "rdtsc            \n"                                \
+                  "mov %%eax, %1    \n"                                \
+                  "xor %%eax, %%eax \n"                                \
+                  "cpuid            \n"                                \
+                  "pop %%ebx        \n"                                \
+                  : "=m" (cycle_tmp1), "=m" (cycle_tmp2)               \
+                  : : "eax", "ecx", "edx" );                           \
+        if ( counter_overhead > (cycle_tmp2 - cycle_tmp1) ) {          \
+           counter_overhead = cycle_tmp2 - cycle_tmp1;                 \
+        }                                                              \
+      }                                                                        \
+   } while (0)
+
+#define  BEGIN_RACE(x)                                                 \
+   x = LONG_MAX;                                                       \
+   for ( cycle_i = 0 ; cycle_i < 10 ; cycle_i++ ) {                    \
+      long cycle_tmp1 = 0, cycle_tmp2 = 0;                             \
+      __asm__ ( "push %%ebx       \n"                                  \
+               "xor %%eax, %%eax \n"                                   \
+               "cpuid            \n"                                   \
+               "rdtsc            \n"                                   \
+               "mov %%eax, %0    \n"                                   \
+               "xor %%eax, %%eax \n"                                   \
+               "cpuid            \n"                                   \
+               "pop %%ebx        \n"                                   \
+               : "=m" (cycle_tmp1)                                     \
+               : : "eax", "ecx", "edx" );
+
+#define END_RACE(x)                                                    \
+      __asm__ ( "push %%ebx       \n"                                  \
+               "xor %%eax, %%eax \n"                                   \
+               "cpuid            \n"                                   \
+               "rdtsc            \n"                                   \
+               "mov %%eax, %0    \n"                                   \
+               "xor %%eax, %%eax \n"                                   \
+               "cpuid            \n"                                   \
+               "pop %%ebx        \n"                                   \
+               : "=m" (cycle_tmp2)                                     \
+               : : "eax", "ecx", "edx" );                              \
+      if ( x > (cycle_tmp2 - cycle_tmp1) ) {                           \
+        x = cycle_tmp2 - cycle_tmp1;                                   \
+      }                                                                        \
+   }                                                                   \
+   x -= counter_overhead;
+
+#else /* PPlain, PMMX version */
+
+/* To ensure accurate results, we stall the pipelines with the
+ * non-pairable 'cdq' instruction.  This ensures all the code being
+ * profiled is complete when the 'rdtsc' instruction executes.
+ */
+#define  INIT_COUNTER(x)                                               \
+   do {                                                                        \
+      int cycle_i;                                                     \
+      x = LONG_MAX;                                                    \
+      for ( cycle_i = 0 ; cycle_i < 32 ; cycle_i++ ) {                 \
+        long cycle_tmp1, cycle_tmp2, dummy;                            \
+        __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp1) );               \
+        __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp2) );               \
+        __asm__ ( "cdq" );                                             \
+        __asm__ ( "cdq" );                                             \
+        __asm__ ( "rdtsc" : "=a" (cycle_tmp1), "=d" (dummy) );         \
+        __asm__ ( "cdq" );                                             \
+        __asm__ ( "cdq" );                                             \
+        __asm__ ( "rdtsc" : "=a" (cycle_tmp2), "=d" (dummy) );         \
+        if ( x > (cycle_tmp2 - cycle_tmp1) )                           \
+           x = cycle_tmp2 - cycle_tmp1;                                \
+      }                                                                        \
+   } while (0)
+
+#define  BEGIN_RACE(x)                                                 \
+   x = LONG_MAX;                                                       \
+   for ( cycle_i = 0 ; cycle_i < 16 ; cycle_i++ ) {                    \
+      long cycle_tmp1, cycle_tmp2, dummy;                              \
+      __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp1) );                 \
+      __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp2) );                 \
+      __asm__ ( "cdq" );                                               \
+      __asm__ ( "cdq" );                                               \
+      __asm__ ( "rdtsc" : "=a" (cycle_tmp1), "=d" (dummy) );
+
+
+#define END_RACE(x)                                                    \
+      __asm__ ( "cdq" );                                               \
+      __asm__ ( "cdq" );                                               \
+      __asm__ ( "rdtsc" : "=a" (cycle_tmp2), "=d" (dummy) );           \
+      if ( x > (cycle_tmp2 - cycle_tmp1) )                             \
+        x = cycle_tmp2 - cycle_tmp1;                                   \
+   }                                                                   \
+   x -= counter_overhead;
+
+#endif
+
+#else
+
+#define BEGIN_RACE(x)
+#define END_RACE(x)
+
+#endif
+
+
+static char *mesa_profile = NULL;
+
+
+enum { NIL=0, ONE=1, NEG=-1, VAR=2 };
+
+static int m_general[16] = {
+   VAR, VAR, VAR, VAR,
+   VAR, VAR, VAR, VAR,
+   VAR, VAR, VAR, VAR,
+   VAR, VAR, VAR, VAR
+};
+static int m_identity[16] = {
+   ONE, NIL, NIL, NIL,
+   NIL, ONE, NIL, NIL,
+   NIL, NIL, ONE, NIL,
+   NIL, NIL, NIL, ONE
+};
+static int  m_2d[16]  = {
+   VAR, VAR, NIL, VAR,
+   VAR, VAR, NIL, VAR,
+   NIL, NIL, ONE, NIL,
+   NIL, NIL, NIL, ONE
+};
+static int m_2d_no_rot[16] = {
+   VAR, NIL, NIL, VAR,
+   NIL, VAR, NIL, VAR,
+   NIL, NIL, ONE, NIL,
+   NIL, NIL, NIL, ONE
+};
+static int m_3d[16] = {
+   VAR, VAR, VAR, VAR,
+   VAR, VAR, VAR, VAR,
+   VAR, VAR, VAR, VAR,
+   NIL, NIL, NIL, ONE
+};
+static int m_3d_no_rot[16] = {
+   VAR, NIL, NIL, VAR,
+   NIL, VAR, NIL, VAR,
+   NIL, NIL, VAR, VAR,
+   NIL, NIL, NIL, ONE
+};
+static int m_perspective[16] = {
+   VAR, NIL, VAR, NIL,
+   NIL, VAR, VAR, NIL,
+   NIL, NIL, VAR, VAR,
+   NIL, NIL, NEG, NIL
+};
+static int *templates[7] = {
+   m_general,
+   m_identity,
+   m_3d_no_rot,
+   m_perspective,
+   m_2d,
+   m_2d_no_rot,
+   m_3d
+};
+static int mtypes[7] = {
+   MATRIX_GENERAL,
+   MATRIX_IDENTITY,
+   MATRIX_3D_NO_ROT,
+   MATRIX_PERSPECTIVE,
+   MATRIX_2D,
+   MATRIX_2D_NO_ROT,
+   MATRIX_3D
+};
+static char *mstrings[7] = {
+   "MATRIX_GENERAL",
+   "MATRIX_IDENTITY",
+   "MATRIX_3D_NO_ROT",
+   "MATRIX_PERSPECTIVE",
+   "MATRIX_2D",
+   "MATRIX_2D_NO_ROT",
+   "MATRIX_3D"
+};
+
+
+
+static int m_norm_identity[16] = {
+   ONE, NIL, NIL, NIL,
+   NIL, ONE, NIL, NIL,
+   NIL, NIL, ONE, NIL,
+   NIL, NIL, NIL, NIL
+};
+static int m_norm_general[16] = {
+   VAR, VAR, VAR, NIL,
+   VAR, VAR, VAR, NIL,
+   VAR, VAR, VAR, NIL,
+   NIL, NIL, NIL, NIL
+};
+static int m_norm_no_rot[16] = {
+   VAR, NIL, NIL, NIL,
+   NIL, VAR, NIL, NIL,
+   NIL, NIL, VAR, NIL,
+   NIL, NIL, NIL, NIL
+};
+static int *norm_templates[8] = {
+   m_norm_no_rot,
+   m_norm_no_rot,
+   m_norm_no_rot,
+   m_norm_general,
+   m_norm_general,
+   m_norm_general,
+   m_norm_identity,
+   m_norm_identity
+};
+static int norm_types[8] = {
+   NORM_TRANSFORM_NO_ROT,
+   NORM_TRANSFORM_NO_ROT | NORM_RESCALE,
+   NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE,
+   NORM_TRANSFORM,
+   NORM_TRANSFORM | NORM_RESCALE,
+   NORM_TRANSFORM | NORM_NORMALIZE,
+   NORM_RESCALE,
+   NORM_NORMALIZE
+};
+static int norm_scale_types[8] = {               /*  rescale factor          */
+   NIL,                                          /*  NIL disables rescaling  */
+   VAR,
+   NIL,
+   NIL,
+   VAR,
+   NIL,
+   VAR,
+   NIL
+};
+static int norm_normalize_types[8] = {           /*  normalizing ?? (no = 0) */
+   0,
+   0,
+   1,
+   0,
+   0,
+   1,
+   0,
+   1
+};
+static char *norm_strings[8] = {
+   "NORM_TRANSFORM_NO_ROT",
+   "NORM_TRANSFORM_NO_ROT | NORM_RESCALE",
+   "NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE",
+   "NORM_TRANSFORM",
+   "NORM_TRANSFORM | NORM_RESCALE",
+   "NORM_TRANSFORM | NORM_NORMALIZE",
+   "NORM_RESCALE",
+   "NORM_NORMALIZE"
+};
+
+
+
+/* ================================================================
+ * Helper functions
+ */
+
+static GLfloat rnd( void )
+{
+   GLfloat f = (GLfloat)rand() / (GLfloat)RAND_MAX;
+   GLfloat gran = (GLfloat)(1 << 13);
+
+   f = (GLfloat)(GLint)(f * gran) / gran;
+
+   return f * 2.0 - 1.0;
+}
+
+static int significand_match( GLfloat a, GLfloat b )
+{
+   GLfloat d = a - b;
+   int a_ex, b_ex, d_ex;
+
+   if ( d == 0.0F ) {
+      return MAX_PRECISION;   /* Exact match */
+   }
+
+   if ( a == 0.0F || b == 0.0F ) {
+      /* It would probably be better to check if the
+       * non-zero number is denormalized and return
+       * the index of the highest set bit here.
+       */
+      return 0;
+   }
+
+   frexp( a, &a_ex );
+   frexp( b, &b_ex );
+   frexp( d, &d_ex );
+
+   if ( a_ex < b_ex )
+      return a_ex - d_ex;
+   else
+      return b_ex - d_ex;
+}
+
+
+
+/* ================================================================
+ * Reference transformations
+ */
+
+static void ref_transform( GLvector4f *dst,
+                           const GLmatrix *mat,
+                           const GLvector4f *src,
+                           const GLubyte *clipmask,
+                           const GLubyte flag )
+{
+   int i;
+   GLfloat *s = (GLfloat *)src->start;
+   GLfloat (*d)[4] = (GLfloat (*)[4])dst->start;
+   const GLfloat *m = mat->m;
+
+   (void) clipmask;
+   (void) flag;
+
+   for ( i = 0 ; i < src->count ; i++ ) {
+      GLfloat x = s[0], y = s[1], z = s[2], w = s[3];
+      d[i][0] = m[0]*x + m[4]*y + m[ 8]*z + m[12]*w;
+      d[i][1] = m[1]*x + m[5]*y + m[ 9]*z + m[13]*w;
+      d[i][2] = m[2]*x + m[6]*y + m[10]*z + m[14]*w;
+      d[i][3] = m[3]*x + m[7]*y + m[11]*z + m[15]*w;
+      s = (GLfloat *)((char *)s + src->stride);
+   }
+}
+
+static void ref_norm_transform_rescale( const GLmatrix *mat,
+                                       GLfloat scale,
+                                       const GLvector3f *in,
+                                       const GLfloat *lengths,
+                                       const GLubyte mask[],
+                                       GLvector3f *dest )
+{
+   int i;
+   const GLfloat *s = in->start;
+   const GLfloat *m = mat->inv;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+
+   (void) mask;
+   (void) lengths;
+
+   for ( i = 0 ; i < in->count ; i++ ) {
+      GLfloat x = s[0], y = s[1], z = s[2] ;
+      GLfloat tx = m[0]*x + m[1]*y + m[ 2]*z ;
+      GLfloat ty = m[4]*x + m[5]*y + m[ 6]*z ;
+      GLfloat tz = m[8]*x + m[9]*y + m[10]*z ;
+
+      out[i][0] = tx * scale;
+      out[i][1] = ty * scale;
+      out[i][2] = tz * scale;
+
+      s = (GLfloat *)((char *)s + in->stride);
+   }
+}
+
+static void ref_norm_transform_normalize( const GLmatrix *mat,
+                                         GLfloat scale,
+                                         const GLvector3f *in,
+                                         const GLfloat *lengths,
+                                         const GLubyte mask[],
+                                         GLvector3f *dest )
+{
+   int i;
+   const GLfloat *s = in->start;
+   const GLfloat *m = mat->inv;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+
+   (void) mask;
+
+   for ( i = 0 ; i < in->count ; i++ ) {
+      GLfloat x = s[0], y = s[1], z = s[2] ;
+      GLfloat tx = m[0]*x + m[1]*y + m[ 2]*z ;
+      GLfloat ty = m[4]*x + m[5]*y + m[ 6]*z ;
+      GLfloat tz = m[8]*x + m[9]*y + m[10]*z ;
+
+      if ( !lengths ) {
+         GLfloat len = tx*tx + ty*ty + tz*tz;
+         if ( len > 1e-20 ) {
+           /* Hmmm, don't know how we could test the precalculated
+            * length case...
+            */
+            scale = 1.0 / sqrt( len );
+            out[i][0] = tx * scale;
+            out[i][1] = ty * scale;
+            out[i][2] = tz * scale;
+         } else {
+            out[i][0] = out[i][1] = out[i][2] = 0;
+         }
+      } else {
+         scale = lengths[i];;
+         out[i][0] = tx * scale;
+         out[i][1] = ty * scale;
+         out[i][2] = tz * scale;
+      }
+
+      s = (GLfloat *)((char *)s + in->stride);
+   }
+}
+
+
+
+/* ================================================================
+ * Vertex transformation tests
+ */
+
+/* Ensure our arrays are correctly aligned.
+ */
+#if defined(__GNUC__)
+#define ALIGN16(x)             x __attribute__ ((aligned (16)))
+#else
+#define ALIGN16(x)             x
+#endif
+static GLfloat ALIGN16(s[TEST_COUNT][5]);
+static GLfloat ALIGN16(d[TEST_COUNT][4]);
+static GLfloat ALIGN16(r[TEST_COUNT][4]);
+
+static int test_transform_function( transform_func func, int psize, int mtype,
+                                    int masked, long *cycles )
+{
+   GLvector4f source[1], dest[1], ref[1];
+   GLmatrix mat[1];
+   GLfloat *m;
+   GLubyte mask[TEST_COUNT];
+   int i, j;
+#ifdef  RUN_XFORM_BENCHMARK
+   int cycle_i;                /* the counter for the benchmarks we run */
+#endif
+
+   (void) cycles;
+
+   if ( psize > 4 ) {
+      gl_problem( NULL, "test_transform_function called with psize > 4\n" );
+      return 0;
+   }
+
+   mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
+   mat->type = mtypes[mtype];
+
+   m = mat->m;
+
+   m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0;
+   m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] =  7.0;
+   m[2] = 44.0; m[6] =  9.0; m[10] =  7.0; m[14] =  3.0;
+   m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] =  9.0;
+
+   for ( i = 0 ; i < 4 ; i++ ) {
+      for ( j = 0 ; j < 4 ; j++ ) {
+         switch ( templates[mtype][i * 4 + j] ) {
+         case NIL:
+            m[j * 4 + i] = 0.0;
+            break;
+         case ONE:
+            m[j * 4 + i] = 1.0;
+            break;
+         case NEG:
+            m[j * 4 + i] = -1.0;
+            break;
+         case VAR:
+            break;
+         default:
+            abort();
+         }
+      }
+   }
+
+   for ( i = 0 ; i < TEST_COUNT ; i++) {
+      mask[i] = i % 2;                         /* mask every 2nd element */
+      d[i][0] = s[i][0] = 0.0;
+      d[i][1] = s[i][1] = 0.0;
+      d[i][2] = s[i][2] = 0.0;
+      d[i][3] = s[i][3] = 1.0;
+      for ( j = 0 ; j < psize ; j++ )
+         s[i][j] = rnd();
+   }
+
+   source->data = (GLfloat(*)[4])s;
+   source->start = (GLfloat *)s;
+   source->count = TEST_COUNT;
+   source->stride = sizeof(s[0]);
+   source->size = 4;
+   source->flags = 0;
+
+   dest->data = (GLfloat(*)[4])d;
+   dest->start = (GLfloat *)d;
+   dest->count = TEST_COUNT;
+   dest->stride = sizeof(float[4]);
+   dest->size = 0;
+   dest->flags = 0;
+
+   ref->data = (GLfloat(*)[4])r;
+   ref->start = (GLfloat *)r;
+   ref->count = TEST_COUNT;
+   ref->stride = sizeof(float[4]);
+   ref->size = 0;
+   ref->flags = 0;
+
+   ref_transform( ref, mat, source, NULL, 0 );
+
+   if ( mesa_profile ) {
+      if ( masked ) {
+         BEGIN_RACE( *cycles );
+         func( dest, mat->m, source, mask, 1 );
+         END_RACE( *cycles );
+      } else {
+         BEGIN_RACE( *cycles );
+         func( dest, mat->m, source, NULL, 0 );
+         END_RACE( *cycles );
+     }
+   }
+   else {
+      if ( masked ) {
+         func( dest, mat->m, source, mask, 1 );
+      } else {
+         func( dest, mat->m, source, NULL, 0 );
+      }
+   }
+
+   for ( i = 0 ; i < TEST_COUNT ; i++ ) {
+      if ( masked && (mask[i] & 1) )
+         continue;
+
+      for ( j = 0 ; j < 4 ; j++ ) {
+         if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) {
+            printf( "-----------------------------\n" );
+            printf( "(i = %i, j = %i)\n", i, j );
+            printf( "%f \t %f \t [diff = %e - %i bit missed]\n",
+                   d[i][0], r[i][0], r[i][0]-d[i][0],
+                   MAX_PRECISION - significand_match( d[i][0], r[i][0] ) );
+            printf( "%f \t %f \t [diff = %e - %i bit missed]\n",
+                   d[i][1], r[i][1], r[i][1]-d[i][1],
+                   MAX_PRECISION - significand_match( d[i][1], r[i][1] ) );
+            printf( "%f \t %f \t [diff = %e - %i bit missed]\n",
+                   d[i][2], r[i][2], r[i][2]-d[i][2],
+                   MAX_PRECISION - significand_match( d[i][2], r[i][2] ) );
+            printf( "%f \t %f \t [diff = %e - %i bit missed]\n",
+                   d[i][3], r[i][3], r[i][3]-d[i][3],
+                   MAX_PRECISION - significand_match( d[i][3], r[i][3] ) );
+            return 0;
+         }
+      }
+   }
+
+   ALIGN_FREE( mat->m );
+   return 1;
+}
+
+void gl_test_all_transform_functions( char *description )
+{
+   int masked, psize, mtype;
+   long benchmark_tab[2][4][7];
+   static int first_time = 1;
+
+   if ( first_time ) {
+      first_time = 0;
+      mesa_profile = getenv( "MESA_PROFILE" );
+   }
+
+#ifdef RUN_XFORM_BENCHMARK
+   if ( mesa_profile ) {
+      if ( need_counter ) {
+        need_counter = 0;
+        INIT_COUNTER();
+        printf( "counter overhead: %ld cycles\n\n", counter_overhead );
+      }
+      printf( "transform results after hooking in %s functions:\n", description );
+   }
+#endif
+
+   for ( masked = 0 ; masked <= 1 ; masked++ ) {
+      int cma = masked ? 1 : 0;
+      char *cmastring = masked ? "CULL_MASK_ACTIVE" : "0";
+
+#ifdef RUN_XFORM_BENCHMARK
+      if ( mesa_profile ) {
+         printf( "\n culling: %s \n", masked ? "CULL_MASK_ACTIVE" : "0" );
+         for ( psize = 1 ; psize <= 4 ; psize++ ) {
+            printf( " p%d\t", psize );
+         }
+         printf( "\n--------------------------------------------------------\n" );
+      }
+#endif
+
+      for ( mtype = 0 ; mtype < 7 ; mtype++ ) {
+         for ( psize = 1 ; psize <= 4 ; psize++ ) {
+            transform_func func = gl_transform_tab[cma][psize][mtypes[mtype]];
+            long *cycles = &(benchmark_tab[cma][psize-1][mtype]);
+
+            if ( test_transform_function( func, psize, mtype,
+                                         masked, cycles ) == 0 ) {
+               char buf[100];
+               sprintf( buf, "gl_transform_tab[%s][%d][%s] failed test (%s)",
+                        cmastring, psize, mstrings[mtype], description );
+               gl_problem( NULL, buf );
+            }
+#ifdef RUN_XFORM_BENCHMARK
+            if ( mesa_profile )
+               printf( " %li\t", benchmark_tab[cma][psize-1][mtype] );
+#endif
+         }
+#ifdef RUN_XFORM_BENCHMARK
+         if ( mesa_profile )
+            printf( " | [%s]\n", mstrings[mtype] );
+#endif
+      }
+#ifdef RUN_XFORM_BENCHMARK
+      if ( mesa_profile )
+         printf( "\n" );
+#endif
+   }
+}
+
+
+
+/* ================================================================
+ * Normal transformation tests
+ */
+
+static int test_norm_function( normal_func func, int mtype,
+                              int masked, long *cycles )
+{
+   GLvector3f source[1], dest[1], dest2[1], ref[1], ref2[1];
+   GLmatrix mat[1];
+   GLfloat s[TEST_COUNT][5], d[TEST_COUNT][3], r[TEST_COUNT][3];
+   GLfloat d2[TEST_COUNT][3], r2[TEST_COUNT][3], length[TEST_COUNT];
+   GLfloat scale;
+   GLfloat *m;
+   GLubyte mask[TEST_COUNT];
+   int i, j;
+#ifdef  RUN_XFORM_BENCHMARK
+   int cycle_i;                /* the counter for the benchmarks we run */
+#endif
+
+   (void) cycles;
+
+   mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
+   mat->inv = m = mat->m;
+
+   m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0;
+   m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] =  7.0;
+   m[2] = 44.0; m[6] =  9.0; m[10] =  7.0; m[14] =  3.0;
+   m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] =  9.0;
+
+   scale = 1.0F + rnd () * norm_scale_types[mtype];
+
+   for ( i = 0 ; i < 4 ; i++ ) {
+      for ( j = 0 ; j < 4 ; j++ ) {
+         switch ( norm_templates[mtype][i * 4 + j] ) {
+         case NIL:
+            m[j * 4 + i] = 0.0;
+            break;
+         case ONE:
+            m[j * 4 + i] = 1.0;
+            break;
+         case NEG:
+            m[j * 4 + i] = -1.0;
+            break;
+         case VAR:
+            break;
+         default:
+            abort();
+         }
+      }
+   }
+
+   for ( i = 0 ; i < TEST_COUNT ; i++ ) {
+      mask[i] = i % 2;                         /* mask every 2nd element */
+      d[i][0] = s[i][0] = d2[i][0] = 0.0;
+      d[i][1] = s[i][1] = d2[i][1] = 0.0;
+      d[i][2] = s[i][2] = d2[i][2] = 0.0;
+      for ( j = 0 ; j < 3 ; j++ )
+         s[i][j] = rnd();
+      length[i] = 1 / sqrt( s[i][0]*s[i][0] +
+                           s[i][1]*s[i][1] +
+                           s[i][2]*s[i][2] );
+   }
+
+   source->data = (GLfloat(*)[3])s;
+   source->start = (GLfloat *)s;
+   source->count = TEST_COUNT;
+   source->stride = sizeof(s[0]);
+   source->flags = 0;
+
+   dest->data = (GLfloat(*)[3])d;
+   dest->start = (GLfloat *)d;
+   dest->count = TEST_COUNT;
+   dest->stride = sizeof(float[3]);
+   dest->flags = 0;
+
+   dest2->data = (GLfloat(*)[3])d2;
+   dest2->start = (GLfloat *)d2;
+   dest2->count = TEST_COUNT;
+   dest2->stride = sizeof(float[3]);
+   dest2->flags = 0;
+
+   ref->data = (GLfloat(*)[3])r;
+   ref->start = (GLfloat *)r;
+   ref->count = TEST_COUNT;
+   ref->stride = sizeof(float[3]);
+   ref->flags = 0;
+
+   ref2->data = (GLfloat(*)[3])r2;
+   ref2->start = (GLfloat *)r2;
+   ref2->count = TEST_COUNT;
+   ref2->stride = sizeof(float[3]);
+   ref2->flags = 0;
+
+   if ( norm_normalize_types[mtype] == 0 ) {
+      ref_norm_transform_rescale( mat, scale, source, NULL, NULL, ref );
+   } else {
+      ref_norm_transform_normalize( mat, scale, source, NULL, NULL, ref );
+      ref_norm_transform_normalize( mat, scale, source, length, NULL, ref2 );
+   }
+
+   if ( mesa_profile ) {
+      if ( masked ) {
+         BEGIN_RACE( *cycles );
+         func( mat, scale, source, NULL, mask, dest );
+         END_RACE( *cycles );
+         func( mat, scale, source, length, mask, dest2 );
+      } else {
+         BEGIN_RACE( *cycles );
+         func( mat, scale, source, NULL, NULL, dest );
+         END_RACE( *cycles );
+         func( mat, scale, source, length, NULL, dest2 );
+      }
+   } else {
+      if ( masked ) {
+         func( mat, scale, source, NULL, mask, dest );
+         func( mat, scale, source, length, mask, dest2 );
+      } else {
+         func( mat, scale, source, NULL, NULL, dest );
+         func( mat, scale, source, length, NULL, dest2 );
+      }
+   }
+
+   for ( i = 0 ; i < TEST_COUNT ; i++ ) {
+      if ( masked && !(mask[i] & 1) )
+         continue;
+
+      for ( j = 0 ; j < 3 ; j++ ) {
+         if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) {
+            printf( "-----------------------------\n" );
+            printf( "(i = %i, j = %i)\n", i, j );
+            printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
+                   d[i][0], r[i][0], r[i][0]/d[i][0],
+                   MAX_PRECISION - significand_match( d[i][0], r[i][0] ) );
+            printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
+                   d[i][1], r[i][1], r[i][1]/d[i][1],
+                   MAX_PRECISION - significand_match( d[i][1], r[i][1] ) );
+            printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
+                   d[i][2], r[i][2], r[i][2]/d[i][2],
+                   MAX_PRECISION - significand_match( d[i][2], r[i][2] ) );
+            return 0;
+         }
+
+         if ( norm_normalize_types[mtype] != 0 ) {
+            if ( significand_match( d2[i][j], r2[i][j] ) < REQUIRED_PRECISION ) {
+               printf( "------------------- precalculated length case ------\n" );
+               printf( "(i = %i, j = %i)\n", i, j );
+               printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
+                      d2[i][0], r2[i][0], r2[i][0]/d2[i][0],
+                      MAX_PRECISION - significand_match( d2[i][0], r2[i][0] ) );
+               printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
+                      d2[i][1], r2[i][1], r2[i][1]/d2[i][1],
+                      MAX_PRECISION - significand_match( d2[i][1], r2[i][1] ) );
+               printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
+                      d2[i][2], r2[i][2], r2[i][2]/d2[i][2],
+                      MAX_PRECISION - significand_match( d2[i][2], r2[i][2] ) );
+               return 0;
+            }
+         }
+      }
+   }
+
+   ALIGN_FREE( mat->m );
+   return 1;
+}
+
+void gl_test_all_normal_transform_functions( char *description )
+{
+   int masked;
+   int mtype;
+   long benchmark_tab[0xf][0x4];
+   static int first_time = 1;
+
+   if ( first_time ) {
+      first_time = 0;
+      mesa_profile = getenv( "MESA_PROFILE" );
+   }
+
+#ifdef RUN_XFORM_BENCHMARK
+   if ( mesa_profile ) {
+      if ( need_counter ) {
+        need_counter = 0;
+        INIT_COUNTER();
+        printf( "counter overhead: %ld cycles\n\n", counter_overhead );
+      }
+      printf( "normal transform results after hooking in %s functions:\n",
+             description );
+   }
+#endif
+
+   for ( masked = 0 ; masked <= 1 ; masked++ ) {
+      int cma = masked ? 1 : 0;
+      char *cmastring = masked ? "CULL_MASK_ACTIVE" : "0";
+
+#ifdef RUN_XFORM_BENCHMARK
+      if ( mesa_profile ) {
+         printf( "\n culling: %s \n", masked ? "CULL_MASK_ACTIVE" : "0" );
+         printf( "\n-------------------------------------------------------\n" );
+      }
+#endif
+
+      for ( mtype = 0 ; mtype < 8 ; mtype++ ) {
+         normal_func func = gl_normal_tab[norm_types[mtype]][cma];
+         long *cycles = &(benchmark_tab[mtype][cma]);
+
+         if ( test_norm_function( func, mtype, masked, cycles ) == 0 ) {
+            char buf[100];
+            sprintf( buf, "gl_normal_tab[%s][%s] failed test (%s)",
+                     cmastring, norm_strings[mtype], description );
+            gl_problem( NULL, buf );
+        }
+
+#ifdef RUN_XFORM_BENCHMARK
+         if ( mesa_profile ) {
+            printf( " %li\t", benchmark_tab[mtype][cma] );
+            printf( " | [%s]\n", norm_strings[mtype] );
+         }
+      }
+      if ( mesa_profile )
+        printf( "\n" );
+#else
+      }
+#endif
+   }
+#ifdef RUN_XFORM_BENCHMARK
+   if ( mesa_profile )
+      fflush( stdout );
+#endif
+}
+
+#endif /* DEBUG */
diff --git a/src/mesa/math/m_dotprod_tmp.h b/src/mesa/math/m_dotprod_tmp.h
new file mode 100644 (file)
index 0000000..637e35f
--- /dev/null
@@ -0,0 +1,128 @@
+/* $Id: m_dotprod_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+/* Note - respects the stride of the output vector.
+ */
+static void TAG(dotprod_vec2)( GLvector4f *out_vec, 
+                            GLuint elt,
+                            const GLvector4f *coord_vec, 
+                            const GLfloat plane[4], 
+                            const GLubyte mask[])
+{
+   GLuint stride = coord_vec->stride;
+   GLfloat *coord = coord_vec->start;
+   GLuint count = coord_vec->count;
+
+   GLuint outstride = out_vec->stride;
+   GLfloat *out = out_vec->start + elt;
+   GLuint i;
+   
+   const GLfloat plane0 = plane[0], plane1 = plane[1], plane3 = plane[3];
+      
+   (void) mask;
+
+   for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) {
+      CULL_CHECK {
+        *out = (coord[0] * plane0 +
+                coord[1] * plane1 +
+                           plane3);
+      }
+   }   
+   out_vec->count = coord_vec->count;
+}
+
+static void TAG(dotprod_vec3)( GLvector4f *out_vec, 
+                            GLuint elt,
+                            const GLvector4f *coord_vec, 
+                            const GLfloat plane[4], 
+                            const GLubyte mask[])
+{
+   GLuint stride = coord_vec->stride;
+   GLfloat *coord = coord_vec->start;
+   GLuint count = coord_vec->count;
+
+   GLuint outstride = out_vec->stride;
+   GLfloat *out = out_vec->start + elt;
+   GLuint i;
+
+   const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2];
+   const GLfloat plane3 = plane[3];
+
+   (void) mask;
+
+   for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) {
+      CULL_CHECK {
+        *out = (coord[0] * plane0 +
+                coord[1] * plane1 +
+                coord[2] * plane2 +
+                           plane3);
+      }
+   }   
+   out_vec->count = coord_vec->count;
+}
+
+static void TAG(dotprod_vec4)( GLvector4f *out_vec, 
+                            GLuint elt,
+                            const GLvector4f *coord_vec, 
+                            const GLfloat plane[4], 
+                            const GLubyte mask[])
+{
+   GLuint stride = coord_vec->stride;
+   GLfloat *coord = coord_vec->start;
+   GLuint count = coord_vec->count;
+
+   GLuint outstride = out_vec->stride;
+   GLfloat *out = out_vec->start + elt;
+   GLuint i;
+
+   const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2];
+   const GLfloat plane3 = plane[3];
+
+   (void) mask;
+
+   for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) {
+      CULL_CHECK {
+        *out = (coord[0] * plane0 +
+                coord[1] * plane1 +
+                coord[2] * plane2 +
+                coord[3] * plane3);
+      }
+   }   
+   out_vec->count = coord_vec->count;
+}
+
+
+static void TAG(init_dotprod)( void )
+{
+   gl_dotprod_tab[IDX&1][2] = TAG(dotprod_vec2);
+   gl_dotprod_tab[IDX&1][3] = TAG(dotprod_vec3);
+   gl_dotprod_tab[IDX&1][4] = TAG(dotprod_vec4);
+}
diff --git a/src/mesa/math/m_matrix.c b/src/mesa/math/m_matrix.c
new file mode 100644 (file)
index 0000000..ae55c94
--- /dev/null
@@ -0,0 +1,1113 @@
+/* $Id: m_matrix.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ * 
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Matrix operations
+ *
+ * NOTES:
+ * 1. 4x4 transformation matrices are stored in memory in column major order.
+ * 2. Points/vertices are to be thought of as column vectors.
+ * 3. Transformation of a point p by a matrix M is: p' = M * p
+ */
+
+
+#include "glheader.h"
+#include "macros.h"
+#include "mem.h"
+#include "mmath.h"
+
+#include "m_matrix.h"
+
+
+static const char *types[] = {
+   "MATRIX_GENERAL",
+   "MATRIX_IDENTITY",
+   "MATRIX_3D_NO_ROT",
+   "MATRIX_PERSPECTIVE",
+   "MATRIX_2D",
+   "MATRIX_2D_NO_ROT",
+   "MATRIX_3D"
+};
+
+
+static GLfloat Identity[16] = {
+   1.0, 0.0, 0.0, 0.0,
+   0.0, 1.0, 0.0, 0.0,
+   0.0, 0.0, 1.0, 0.0,
+   0.0, 0.0, 0.0, 1.0
+};
+
+
+
+
+/*
+ * This matmul was contributed by Thomas Malik 
+ *
+ * Perform a 4x4 matrix multiplication  (product = a x b).
+ * Input:  a, b - matrices to multiply
+ * Output:  product - product of a and b
+ * WARNING: (product != b) assumed
+ * NOTE:    (product == a) allowed    
+ *
+ * KW: 4*16 = 64 muls
+ */
+#define A(row,col)  a[(col<<2)+row]
+#define B(row,col)  b[(col<<2)+row]
+#define P(row,col)  product[(col<<2)+row]
+
+static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b )
+{
+   GLint i;
+   for (i = 0; i < 4; i++) {
+      const GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
+      P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
+      P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
+      P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
+      P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
+   }
+}
+
+
+/* Multiply two matrices known to occupy only the top three rows, such
+ * as typical model matrices, and ortho matrices.  
+ */
+static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b )
+{
+   GLint i;
+   for (i = 0; i < 3; i++) {
+      const GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
+      P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0);
+      P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1);
+      P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2);
+      P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3;
+   }
+   P(3,0) = 0;
+   P(3,1) = 0;
+   P(3,2) = 0;
+   P(3,3) = 1;
+}
+
+
+#undef A
+#undef B
+#undef P
+
+
+/*
+ * Multiply a matrix by an array of floats with known properties.
+ */
+static void matrix_multf( GLmatrix *mat, const GLfloat *m, GLuint flags )
+{
+   mat->flags |= (flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE);
+
+   if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D))
+      matmul34( mat->m, mat->m, m );
+   else 
+      matmul4( mat->m, mat->m, m ); 
+}
+
+
+static void print_matrix_floats( const GLfloat m[16] )
+{
+   int i;
+   for (i=0;i<4;i++) {
+      fprintf(stderr,"\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] );
+   }
+}
+
+void 
+_math_matrix_print( const GLmatrix *m )
+{
+   fprintf(stderr, "Matrix type: %s, flags: %x\n", types[m->type], m->flags);
+   print_matrix_floats(m->m);
+   fprintf(stderr, "Inverse: \n");
+   if (m->inv) {
+      GLfloat prod[16];
+      print_matrix_floats(m->inv);
+      matmul4(prod, m->m, m->inv);
+      fprintf(stderr, "Mat * Inverse:\n");
+      print_matrix_floats(prod);
+   }
+   else {
+      fprintf(stderr, "  - not available\n");
+   }
+}
+
+
+
+
+#define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; }
+#define MAT(m,r,c) (m)[(c)*4+(r)]
+
+/*
+ * Compute inverse of 4x4 transformation matrix.
+ * Code contributed by Jacques Leroy jle@star.be
+ * Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
+ */
+static GLboolean invert_matrix_general( GLmatrix *mat )
+{
+   const GLfloat *m = mat->m;
+   GLfloat *out = mat->inv;
+   GLfloat wtmp[4][8];
+   GLfloat m0, m1, m2, m3, s;
+   GLfloat *r0, *r1, *r2, *r3;
+  
+   r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
+  
+   r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1),
+   r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3),
+   r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
+  
+   r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1),
+   r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3),
+   r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
+  
+   r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1),
+   r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3),
+   r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
+  
+   r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1),
+   r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3),
+   r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
+  
+   /* choose pivot - or die */
+   if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2);
+   if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1);
+   if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0);
+   if (0.0 == r0[0])  return GL_FALSE;
+  
+   /* eliminate first variable     */
+   m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
+   s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
+   s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
+   s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
+   s = r0[4];
+   if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
+   s = r0[5];
+   if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
+   s = r0[6];
+   if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
+   s = r0[7];
+   if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
+  
+   /* choose pivot - or die */
+   if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2);
+   if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1);
+   if (0.0 == r1[1])  return GL_FALSE;
+  
+   /* eliminate second variable */
+   m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
+   r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
+   r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
+   s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
+   s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
+   s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
+   s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
+  
+   /* choose pivot - or die */
+   if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2);
+   if (0.0 == r2[2])  return GL_FALSE;
+  
+   /* eliminate third variable */
+   m3 = r3[2]/r2[2];
+   r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
+   r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
+   r3[7] -= m3 * r2[7];
+  
+   /* last check */
+   if (0.0 == r3[3]) return GL_FALSE;
+  
+   s = 1.0/r3[3];              /* now back substitute row 3 */
+   r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
+  
+   m2 = r2[3];                 /* now back substitute row 2 */
+   s  = 1.0/r2[2];
+   r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
+   r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
+   m1 = r1[3];
+   r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
+   r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
+   m0 = r0[3];
+   r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
+   r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
+  
+   m1 = r1[2];                 /* now back substitute row 1 */
+   s  = 1.0/r1[1];
+   r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
+   r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
+   m0 = r0[2];
+   r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
+   r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
+  
+   m0 = r0[1];                 /* now back substitute row 0 */
+   s  = 1.0/r0[0];
+   r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
+   r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
+  
+   MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5],
+   MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7],
+   MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5],
+   MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7],
+   MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5],
+   MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7],
+   MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5],
+   MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; 
+  
+   return GL_TRUE;
+}
+#undef SWAP_ROWS
+
+
+/* Adapted from graphics gems II.
+ */  
+static GLboolean invert_matrix_3d_general( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+   GLfloat pos, neg, t;
+   GLfloat det;
+
+   /* Calculate the determinant of upper left 3x3 submatrix and
+    * determine if the matrix is singular. 
+    */
+   pos = neg = 0.0;
+   t =  MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t =  MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t =  MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   det = pos + neg;
+
+   if (det*det < 1e-25) 
+      return GL_FALSE;
+   
+   det = 1.0 / det;
+   MAT(out,0,0) = (  (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det);
+   MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det);
+   MAT(out,0,2) = (  (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det);
+   MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det);
+   MAT(out,1,1) = (  (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det);
+   MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det);
+   MAT(out,2,0) = (  (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det);
+   MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det);
+   MAT(out,2,2) = (  (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det);
+
+   /* Do the translation part */
+   MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
+                    MAT(in,1,3) * MAT(out,0,1) +
+                    MAT(in,2,3) * MAT(out,0,2) );
+   MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
+                    MAT(in,1,3) * MAT(out,1,1) +
+                    MAT(in,2,3) * MAT(out,1,2) );
+   MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
+                    MAT(in,1,3) * MAT(out,2,1) +
+                    MAT(in,2,3) * MAT(out,2,2) );
+    
+   return GL_TRUE;
+}
+
+
+static GLboolean invert_matrix_3d( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+
+   if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING)) {
+      return invert_matrix_3d_general( mat );
+   }
+   
+   if (mat->flags & MAT_FLAG_UNIFORM_SCALE) {
+      GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) +
+                       MAT(in,0,1) * MAT(in,0,1) +
+                       MAT(in,0,2) * MAT(in,0,2));
+
+      if (scale == 0.0) 
+         return GL_FALSE;
+
+      scale = 1.0 / scale;
+
+      /* Transpose and scale the 3 by 3 upper-left submatrix. */
+      MAT(out,0,0) = scale * MAT(in,0,0);
+      MAT(out,1,0) = scale * MAT(in,0,1);
+      MAT(out,2,0) = scale * MAT(in,0,2);
+      MAT(out,0,1) = scale * MAT(in,1,0);
+      MAT(out,1,1) = scale * MAT(in,1,1);
+      MAT(out,2,1) = scale * MAT(in,1,2);
+      MAT(out,0,2) = scale * MAT(in,2,0);
+      MAT(out,1,2) = scale * MAT(in,2,1);
+      MAT(out,2,2) = scale * MAT(in,2,2);
+   }
+   else if (mat->flags & MAT_FLAG_ROTATION) {
+      /* Transpose the 3 by 3 upper-left submatrix. */
+      MAT(out,0,0) = MAT(in,0,0);
+      MAT(out,1,0) = MAT(in,0,1);
+      MAT(out,2,0) = MAT(in,0,2);
+      MAT(out,0,1) = MAT(in,1,0);
+      MAT(out,1,1) = MAT(in,1,1);
+      MAT(out,2,1) = MAT(in,1,2);
+      MAT(out,0,2) = MAT(in,2,0);
+      MAT(out,1,2) = MAT(in,2,1);
+      MAT(out,2,2) = MAT(in,2,2);
+   }
+   else {
+      /* pure translation */
+      MEMCPY( out, Identity, sizeof(Identity) );
+      MAT(out,0,3) = - MAT(in,0,3);
+      MAT(out,1,3) = - MAT(in,1,3);
+      MAT(out,2,3) = - MAT(in,2,3);
+      return GL_TRUE;
+   }
+    
+   if (mat->flags & MAT_FLAG_TRANSLATION) {
+      /* Do the translation part */
+      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
+                       MAT(in,1,3) * MAT(out,0,1) +
+                       MAT(in,2,3) * MAT(out,0,2) );
+      MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
+                       MAT(in,1,3) * MAT(out,1,1) +
+                       MAT(in,2,3) * MAT(out,1,2) );
+      MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
+                       MAT(in,1,3) * MAT(out,2,1) +
+                       MAT(in,2,3) * MAT(out,2,2) );
+   }
+   else {
+      MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0;
+   }
+    
+   return GL_TRUE;
+}
+
+  
+
+static GLboolean invert_matrix_identity( GLmatrix *mat )
+{
+   MEMCPY( mat->inv, Identity, sizeof(Identity) );
+   return GL_TRUE;
+}
+
+
+static GLboolean invert_matrix_3d_no_rot( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+
+   if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 )       
+      return GL_FALSE;
+  
+   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
+   MAT(out,0,0) = 1.0 / MAT(in,0,0);
+   MAT(out,1,1) = 1.0 / MAT(in,1,1);
+   MAT(out,2,2) = 1.0 / MAT(in,2,2);
+
+   if (mat->flags & MAT_FLAG_TRANSLATION) {
+      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
+      MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
+      MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2));
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean invert_matrix_2d_no_rot( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+
+   if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0)       
+      return GL_FALSE;
+  
+   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
+   MAT(out,0,0) = 1.0 / MAT(in,0,0);
+   MAT(out,1,1) = 1.0 / MAT(in,1,1);
+
+   if (mat->flags & MAT_FLAG_TRANSLATION) {
+      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
+      MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean invert_matrix_perspective( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+
+   if (MAT(in,2,3) == 0)
+      return GL_FALSE;
+
+   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
+
+   MAT(out,0,0) = 1.0 / MAT(in,0,0);
+   MAT(out,1,1) = 1.0 / MAT(in,1,1);
+
+   MAT(out,0,3) = MAT(in,0,2);
+   MAT(out,1,3) = MAT(in,1,2);
+
+   MAT(out,2,2) = 0;
+   MAT(out,2,3) = -1;
+
+   MAT(out,3,2) = 1.0 / MAT(in,2,3);
+   MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2);
+
+   return GL_TRUE;
+}
+
+
+typedef GLboolean (*inv_mat_func)( GLmatrix *mat );
+
+
+static inv_mat_func inv_mat_tab[7] = {
+   invert_matrix_general,
+   invert_matrix_identity,
+   invert_matrix_3d_no_rot,
+   invert_matrix_perspective,
+   invert_matrix_3d,           /* lazy! */
+   invert_matrix_2d_no_rot,
+   invert_matrix_3d
+};
+
+
+static GLboolean matrix_invert( GLmatrix *mat )
+{
+   if (inv_mat_tab[mat->type](mat)) {
+      mat->flags &= ~MAT_FLAG_SINGULAR;
+      return GL_TRUE;
+   } else {
+      mat->flags |= MAT_FLAG_SINGULAR;
+      MEMCPY( mat->inv, Identity, sizeof(Identity) );
+      return GL_FALSE;
+   }  
+}
+
+
+
+
+
+
+/*
+ * Generate a 4x4 transformation matrix from glRotate parameters, and
+ * postmultiply the input matrix by it.
+ */
+void 
+_math_matrix_rotate( GLmatrix *mat, 
+                    GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
+{
+   /* This function contributed by Erich Boleyn (erich@uruk.org) */
+   GLfloat mag, s, c;
+   GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
+   GLfloat m[16];
+   
+   s = sin( angle * DEG2RAD );
+   c = cos( angle * DEG2RAD );
+
+   mag = GL_SQRT( x*x + y*y + z*z );
+
+   if (mag <= 1.0e-4) {
+      /* generate an identity matrix and return */
+      MEMCPY(m, Identity, sizeof(GLfloat)*16);
+      return;
+   }
+
+   x /= mag;
+   y /= mag;
+   z /= mag;
+
+#define M(row,col)  m[col*4+row]
+
+   /*
+    *     Arbitrary axis rotation matrix.
+    *
+    *  This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
+    *  like so:  Rz * Ry * T * Ry' * Rz'.  T is the final rotation
+    *  (which is about the X-axis), and the two composite transforms
+    *  Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
+    *  from the arbitrary axis to the X-axis then back.  They are
+    *  all elementary rotations.
+    *
+    *  Rz' is a rotation about the Z-axis, to bring the axis vector
+    *  into the x-z plane.  Then Ry' is applied, rotating about the
+    *  Y-axis to bring the axis vector parallel with the X-axis.  The
+    *  rotation about the X-axis is then performed.  Ry and Rz are
+    *  simply the respective inverse transforms to bring the arbitrary
+    *  axis back to it's original orientation.  The first transforms
+    *  Rz' and Ry' are considered inverses, since the data from the
+    *  arbitrary axis gives you info on how to get to it, not how
+    *  to get away from it, and an inverse must be applied.
+    *
+    *  The basic calculation used is to recognize that the arbitrary
+    *  axis vector (x, y, z), since it is of unit length, actually
+    *  represents the sines and cosines of the angles to rotate the
+    *  X-axis to the same orientation, with theta being the angle about
+    *  Z and phi the angle about Y (in the order described above)
+    *  as follows:
+    *
+    *  cos ( theta ) = x / sqrt ( 1 - z^2 )
+    *  sin ( theta ) = y / sqrt ( 1 - z^2 )
+    *
+    *  cos ( phi ) = sqrt ( 1 - z^2 )
+    *  sin ( phi ) = z
+    *
+    *  Note that cos ( phi ) can further be inserted to the above
+    *  formulas:
+    *
+    *  cos ( theta ) = x / cos ( phi )
+    *  sin ( theta ) = y / sin ( phi )
+    *
+    *  ...etc.  Because of those relations and the standard trigonometric
+    *  relations, it is pssible to reduce the transforms down to what
+    *  is used below.  It may be that any primary axis chosen will give the
+    *  same results (modulo a sign convention) using thie method.
+    *
+    *  Particularly nice is to notice that all divisions that might
+    *  have caused trouble when parallel to certain planes or
+    *  axis go away with care paid to reducing the expressions.
+    *  After checking, it does perform correctly under all cases, since
+    *  in all the cases of division where the denominator would have
+    *  been zero, the numerator would have been zero as well, giving
+    *  the expected result.
+    */
+
+   xx = x * x;
+   yy = y * y;
+   zz = z * z;
+   xy = x * y;
+   yz = y * z;
+   zx = z * x;
+   xs = x * s;
+   ys = y * s;
+   zs = z * s;
+   one_c = 1.0F - c;
+
+   M(0,0) = (one_c * xx) + c;
+   M(0,1) = (one_c * xy) - zs;
+   M(0,2) = (one_c * zx) + ys;
+   M(0,3) = 0.0F;
+
+   M(1,0) = (one_c * xy) + zs;
+   M(1,1) = (one_c * yy) + c;
+   M(1,2) = (one_c * yz) - xs;
+   M(1,3) = 0.0F;
+
+   M(2,0) = (one_c * zx) - ys;
+   M(2,1) = (one_c * yz) + xs;
+   M(2,2) = (one_c * zz) + c;
+   M(2,3) = 0.0F;
+
+   M(3,0) = 0.0F;
+   M(3,1) = 0.0F;
+   M(3,2) = 0.0F;
+   M(3,3) = 1.0F;
+
+#undef M
+
+   matrix_multf( mat, m, MAT_FLAG_ROTATION );
+}
+
+
+void
+_math_matrix_frustrum( GLmatrix *mat, 
+                      GLfloat left, GLfloat right,
+                      GLfloat bottom, GLfloat top, 
+                      GLfloat nearval, GLfloat farval )
+{
+   GLfloat x, y, a, b, c, d;
+   GLfloat m[16];
+
+   x = (2.0*nearval) / (right-left);
+   y = (2.0*nearval) / (top-bottom);
+   a = (right+left) / (right-left);
+   b = (top+bottom) / (top-bottom);
+   c = -(farval+nearval) / ( farval-nearval);
+   d = -(2.0*farval*nearval) / (farval-nearval);  /* error? */
+
+#define M(row,col)  m[col*4+row]
+   M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F;
+   M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F;
+   M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d;
+   M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F;
+#undef M
+
+   matrix_multf( mat, m, MAT_FLAG_PERSPECTIVE );
+}
+
+void
+_math_matrix_ortho( GLmatrix *mat,     
+                   GLfloat left, GLfloat right,
+                   GLfloat bottom, GLfloat top, 
+                   GLfloat nearval, GLfloat farval )
+{
+   GLfloat x, y, z;
+   GLfloat tx, ty, tz;
+   GLfloat m[16];
+
+   x = 2.0 / (right-left);
+   y = 2.0 / (top-bottom);
+   z = -2.0 / (farval-nearval);
+   tx = -(right+left) / (right-left);
+   ty = -(top+bottom) / (top-bottom);
+   tz = -(farval+nearval) / (farval-nearval);
+
+#define M(row,col)  m[col*4+row]
+   M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = 0.0F;  M(0,3) = tx;
+   M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = 0.0F;  M(1,3) = ty;
+   M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = z;     M(2,3) = tz;
+   M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = 0.0F;  M(3,3) = 1.0F;
+#undef M
+
+   matrix_multf( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION));
+}
+
+
+#define ZERO(x) (1<<x)
+#define ONE(x)  (1<<(x+16))
+
+#define MASK_NO_TRX      (ZERO(12) | ZERO(13) | ZERO(14))
+#define MASK_NO_2D_SCALE ( ONE(0)  | ONE(5))
+
+#define MASK_IDENTITY    ( ONE(0)  | ZERO(4)  | ZERO(8)  | ZERO(12) |\
+                         ZERO(1)  |  ONE(5)  | ZERO(9)  | ZERO(13) |\
+                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+#define MASK_2D_NO_ROT   (           ZERO(4)  | ZERO(8)  |           \
+                         ZERO(1)  |            ZERO(9)  |           \
+                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+#define MASK_2D          (                      ZERO(8)  |           \
+                                               ZERO(9)  |           \
+                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+
+#define MASK_3D_NO_ROT   (           ZERO(4)  | ZERO(8)  |           \
+                         ZERO(1)  |            ZERO(9)  |           \
+                         ZERO(2)  | ZERO(6)  |                      \
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+#define MASK_3D          (                                           \
+                                                                    \
+                                                                    \
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+
+#define MASK_PERSPECTIVE (           ZERO(4)  |            ZERO(12) |\
+                         ZERO(1)  |                       ZERO(13) |\
+                         ZERO(2)  | ZERO(6)  |                      \
+                         ZERO(3)  | ZERO(7)  |            ZERO(15) )
+
+#define SQ(x) ((x)*(x))
+  
+/* Determine type and flags from scratch.  This is expensive enough to
+ * only want to do it once.
+ */
+static void analyze_from_scratch( GLmatrix *mat )
+{
+   const GLfloat *m = mat->m;
+   GLuint mask = 0;
+   GLuint i;
+
+   for (i = 0 ; i < 16 ; i++) {
+      if (m[i] == 0.0) mask |= (1<<i);
+   }
+   
+   if (m[0] == 1.0F) mask |= (1<<16);
+   if (m[5] == 1.0F) mask |= (1<<21);
+   if (m[10] == 1.0F) mask |= (1<<26);
+   if (m[15] == 1.0F) mask |= (1<<31);
+
+   mat->flags &= ~MAT_FLAGS_GEOMETRY;
+
+   /* Check for translation - no-one really cares 
+    */
+   if ((mask & MASK_NO_TRX) != MASK_NO_TRX) 
+      mat->flags |= MAT_FLAG_TRANSLATION;      
+
+   /* Do the real work
+    */
+   if (mask == MASK_IDENTITY) {
+      mat->type = MATRIX_IDENTITY;
+   }
+   else if ((mask & MASK_2D_NO_ROT) == MASK_2D_NO_ROT) {
+      mat->type = MATRIX_2D_NO_ROT;
+      
+      if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE)
+        mat->flags = MAT_FLAG_GENERAL_SCALE;
+   }
+   else if ((mask & MASK_2D) == MASK_2D) {
+      GLfloat mm = DOT2(m, m);
+      GLfloat m4m4 = DOT2(m+4,m+4);
+      GLfloat mm4 = DOT2(m,m+4);
+
+      mat->type = MATRIX_2D;
+
+      /* Check for scale */
+      if (SQ(mm-1) > SQ(1e-6) ||
+         SQ(m4m4-1) > SQ(1e-6)) 
+        mat->flags |= MAT_FLAG_GENERAL_SCALE;
+
+      /* Check for rotation */
+      if (SQ(mm4) > SQ(1e-6))
+        mat->flags |= MAT_FLAG_GENERAL_3D;
+      else
+        mat->flags |= MAT_FLAG_ROTATION;
+
+   }
+   else if ((mask & MASK_3D_NO_ROT) == MASK_3D_NO_ROT) {
+      mat->type = MATRIX_3D_NO_ROT;
+
+      /* Check for scale */
+      if (SQ(m[0]-m[5]) < SQ(1e-6) && 
+         SQ(m[0]-m[10]) < SQ(1e-6)) {
+        if (SQ(m[0]-1.0) > SQ(1e-6)) {
+           mat->flags |= MAT_FLAG_UNIFORM_SCALE;
+         }
+      }
+      else {
+        mat->flags |= MAT_FLAG_GENERAL_SCALE;
+      }
+   }
+   else if ((mask & MASK_3D) == MASK_3D) {
+      GLfloat c1 = DOT3(m,m);
+      GLfloat c2 = DOT3(m+4,m+4);
+      GLfloat c3 = DOT3(m+8,m+8);
+      GLfloat d1 = DOT3(m, m+4);
+      GLfloat cp[3];
+
+      mat->type = MATRIX_3D;
+
+      /* Check for scale */
+      if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) {
+        if (SQ(c1-1.0) > SQ(1e-6))
+           mat->flags |= MAT_FLAG_UNIFORM_SCALE;
+        /* else no scale at all */
+      }
+      else {
+        mat->flags |= MAT_FLAG_GENERAL_SCALE;
+      }
+
+      /* Check for rotation */
+      if (SQ(d1) < SQ(1e-6)) {
+        CROSS3( cp, m, m+4 );
+        SUB_3V( cp, cp, (m+8) );
+        if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) 
+           mat->flags |= MAT_FLAG_ROTATION;
+        else
+           mat->flags |= MAT_FLAG_GENERAL_3D;
+      }
+      else {
+        mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */
+      }
+   }
+   else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) {
+      mat->type = MATRIX_PERSPECTIVE;
+      mat->flags |= MAT_FLAG_GENERAL;
+   }
+   else {
+      mat->type = MATRIX_GENERAL;
+      mat->flags |= MAT_FLAG_GENERAL;
+   }
+}
+
+
+/* Analyse a matrix given that its flags are accurate - this is the
+ * more common operation, hopefully. 
+ */
+static void analyze_from_flags( GLmatrix *mat )
+{
+   const GLfloat *m = mat->m;
+
+   if (TEST_MAT_FLAGS(mat, 0)) {
+      mat->type = MATRIX_IDENTITY;
+   }
+   else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION |
+                                MAT_FLAG_UNIFORM_SCALE |
+                                MAT_FLAG_GENERAL_SCALE))) {
+      if ( m[10]==1.0F && m[14]==0.0F ) {
+        mat->type = MATRIX_2D_NO_ROT;
+      }
+      else {
+        mat->type = MATRIX_3D_NO_ROT;
+      }
+   }
+   else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) {
+      if (                                 m[ 8]==0.0F               
+            &&                             m[ 9]==0.0F
+            && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) {
+        mat->type = MATRIX_2D;
+      }
+      else {
+        mat->type = MATRIX_3D;
+      }
+   }
+   else if (                 m[4]==0.0F                 && m[12]==0.0F
+            && m[1]==0.0F                               && m[13]==0.0F
+            && m[2]==0.0F && m[6]==0.0F
+            && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) {
+      mat->type = MATRIX_PERSPECTIVE;
+   }
+   else {
+      mat->type = MATRIX_GENERAL;
+   }
+}
+
+
+void 
+_math_matrix_analyze( GLmatrix *mat ) 
+{
+   if (mat->flags & MAT_DIRTY_TYPE) {
+      if (mat->flags & MAT_DIRTY_FLAGS) 
+        analyze_from_scratch( mat );
+      else
+        analyze_from_flags( mat );
+   }
+
+   if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) {
+      matrix_invert( mat );
+   }
+
+   mat->flags &= ~(MAT_DIRTY_FLAGS|
+                  MAT_DIRTY_TYPE|
+                  MAT_DIRTY_INVERSE);
+}
+
+
+void 
+_math_matrix_copy( GLmatrix *to, const GLmatrix *from )
+{
+   MEMCPY( to->m, from->m, sizeof(Identity) );
+   to->flags = from->flags;
+   to->type = from->type;
+
+   if (to->inv != 0) {
+      if (from->inv == 0) {
+        matrix_invert( to );
+      }
+      else {
+        MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16);
+      }
+   }
+}
+
+
+void 
+_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z )
+{
+   GLfloat *m = mat->m;
+   m[0] *= x;   m[4] *= y;   m[8]  *= z;
+   m[1] *= x;   m[5] *= y;   m[9]  *= z;
+   m[2] *= x;   m[6] *= y;   m[10] *= z;
+   m[3] *= x;   m[7] *= y;   m[11] *= z;
+
+   if (fabs(x - y) < 1e-8 && fabs(x - z) < 1e-8)
+      mat->flags |= MAT_FLAG_UNIFORM_SCALE;
+   else
+      mat->flags |= MAT_FLAG_GENERAL_SCALE;
+
+   mat->flags |= (MAT_DIRTY_TYPE | 
+                 MAT_DIRTY_INVERSE);
+}
+
+
+void 
+_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z )
+{
+   GLfloat *m = mat->m;
+   m[12] = m[0] * x + m[4] * y + m[8]  * z + m[12];
+   m[13] = m[1] * x + m[5] * y + m[9]  * z + m[13];
+   m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
+   m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
+
+   mat->flags |= (MAT_FLAG_TRANSLATION | 
+                 MAT_DIRTY_TYPE | 
+                 MAT_DIRTY_INVERSE);
+}
+
+
+void 
+_math_matrix_loadf( GLmatrix *mat, const GLfloat *m )
+{
+   MEMCPY( mat->m, m, 16*sizeof(GLfloat) );
+   mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY);
+}
+
+void 
+_math_matrix_ctr( GLmatrix *m )
+{
+   if ( m->m == 0 ) {
+      m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
+   }
+   MEMCPY( m->m, Identity, sizeof(Identity) );
+   m->inv = 0;
+   m->type = MATRIX_IDENTITY;
+   m->flags = 0;
+}
+
+void 
+_math_matrix_dtr( GLmatrix *m )
+{
+   if ( m->m != 0 ) {
+      ALIGN_FREE( m->m );
+      m->m = 0;
+   }
+   if ( m->inv != 0 ) {
+      ALIGN_FREE( m->inv );
+      m->inv = 0;
+   }
+}
+
+
+void 
+_math_matrix_alloc_inv( GLmatrix *m )
+{
+   if ( m->inv == 0 ) {
+      m->inv = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
+      MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) );
+   }
+}
+
+
+void 
+_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b )
+{
+   dest->flags = (a->flags |
+                 b->flags |
+                 MAT_DIRTY_TYPE | 
+                 MAT_DIRTY_INVERSE);
+
+   if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D))
+      matmul34( dest->m, a->m, b->m );
+   else 
+      matmul4( dest->m, a->m, b->m );
+}
+
+
+void 
+_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *m )
+{
+   dest->flags |= (MAT_FLAG_GENERAL |
+                  MAT_DIRTY_TYPE | 
+                  MAT_DIRTY_INVERSE);
+
+   matmul4( dest->m, dest->m, m );   
+}
+
+void 
+_math_matrix_set_identity( GLmatrix *mat )
+{
+   MEMCPY( mat->m, Identity, 16*sizeof(GLfloat) );
+
+   if (mat->inv)
+      MEMCPY( mat->inv, Identity, 16*sizeof(GLfloat) );
+
+   mat->type = MATRIX_IDENTITY;
+   mat->flags &= ~(MAT_DIRTY_FLAGS|
+                  MAT_DIRTY_TYPE|
+                  MAT_DIRTY_INVERSE);
+}
+
+
+
+void 
+_math_transposef( GLfloat to[16], const GLfloat from[16] )
+{
+   to[0] = from[0];
+   to[1] = from[4];
+   to[2] = from[8];
+   to[3] = from[12];
+   to[4] = from[1];
+   to[5] = from[5];
+   to[6] = from[9];
+   to[7] = from[13];
+   to[8] = from[2];
+   to[9] = from[6];
+   to[10] = from[10];
+   to[11] = from[14];
+   to[12] = from[3];
+   to[13] = from[7];
+   to[14] = from[11];
+   to[15] = from[15];
+}
+
+
+void 
+_math_transposed( GLdouble to[16], const GLdouble from[16] )
+{
+   to[0] = from[0];
+   to[1] = from[4];
+   to[2] = from[8];
+   to[3] = from[12];
+   to[4] = from[1];
+   to[5] = from[5];
+   to[6] = from[9];
+   to[7] = from[13];
+   to[8] = from[2];
+   to[9] = from[6];
+   to[10] = from[10];
+   to[11] = from[14];
+   to[12] = from[3];
+   to[13] = from[7];
+   to[14] = from[11];
+   to[15] = from[15];
+}
+
+void 
+_math_transposefd( GLfloat to[16], const GLdouble from[16] )
+{
+   to[0] = from[0];
+   to[1] = from[4];
+   to[2] = from[8];
+   to[3] = from[12];
+   to[4] = from[1];
+   to[5] = from[5];
+   to[6] = from[9];
+   to[7] = from[13];
+   to[8] = from[2];
+   to[9] = from[6];
+   to[10] = from[10];
+   to[11] = from[14];
+   to[12] = from[3];
+   to[13] = from[7];
+   to[14] = from[11];
+   to[15] = from[15];
+}
diff --git a/src/mesa/math/m_matrix.h b/src/mesa/math/m_matrix.h
new file mode 100644 (file)
index 0000000..8eedbdb
--- /dev/null
@@ -0,0 +1,176 @@
+/* $Id: m_matrix.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ * 
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _M_MATRIX_H
+#define _M_MATRIX_H
+
+
+
+/* Give symbolic names to some of the entries in the matrix to help
+ * out with the rework of the viewport_map as a matrix transform.
+ */
+#define MAT_SX 0
+#define MAT_SY 5
+#define MAT_SZ 10
+#define MAT_TX 12
+#define MAT_TY 13
+#define MAT_TZ 14
+
+/*
+ * Different kinds of 4x4 transformation matrices:
+ */
+#define MATRIX_GENERAL         0       /* general 4x4 matrix */
+#define MATRIX_IDENTITY                1       /* identity matrix */
+#define MATRIX_3D_NO_ROT       2       /* ortho projection and others... */
+#define MATRIX_PERSPECTIVE     3       /* perspective projection matrix */
+#define MATRIX_2D              4       /* 2-D transformation */
+#define MATRIX_2D_NO_ROT       5       /* 2-D scale & translate only */
+#define MATRIX_3D              6       /* 3-D transformation */
+
+#define MAT_FLAG_IDENTITY       0
+#define MAT_FLAG_GENERAL        0x1
+#define MAT_FLAG_ROTATION       0x2
+#define MAT_FLAG_TRANSLATION    0x4
+#define MAT_FLAG_UNIFORM_SCALE  0x8
+#define MAT_FLAG_GENERAL_SCALE  0x10
+#define MAT_FLAG_GENERAL_3D     0x20
+#define MAT_FLAG_PERSPECTIVE    0x40
+#define MAT_FLAG_SINGULAR       0x80
+#define MAT_DIRTY_TYPE          0x100
+#define MAT_DIRTY_FLAGS         0x200
+#define MAT_DIRTY_INVERSE       0x400
+
+#define MAT_FLAGS_ANGLE_PRESERVING (MAT_FLAG_ROTATION | \
+                                   MAT_FLAG_TRANSLATION | \
+                                   MAT_FLAG_UNIFORM_SCALE)
+
+#define MAT_FLAGS_LENGTH_PRESERVING (MAT_FLAG_ROTATION | \
+                                    MAT_FLAG_TRANSLATION)
+
+#define MAT_FLAGS_3D (MAT_FLAG_ROTATION | \
+                     MAT_FLAG_TRANSLATION | \
+                     MAT_FLAG_UNIFORM_SCALE | \
+                     MAT_FLAG_GENERAL_SCALE | \
+                     MAT_FLAG_GENERAL_3D)
+
+#define MAT_FLAGS_GEOMETRY (MAT_FLAG_GENERAL | \
+                           MAT_FLAG_ROTATION | \
+                           MAT_FLAG_TRANSLATION | \
+                           MAT_FLAG_UNIFORM_SCALE | \
+                           MAT_FLAG_GENERAL_SCALE | \
+                           MAT_FLAG_GENERAL_3D | \
+                           MAT_FLAG_PERSPECTIVE | \
+                           MAT_FLAG_SINGULAR)
+
+#define MAT_DIRTY          (MAT_DIRTY_TYPE | \
+                           MAT_DIRTY_FLAGS | \
+                           MAT_DIRTY_INVERSE)
+
+#define TEST_MAT_FLAGS(mat, a)  \
+    ((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0)
+
+
+typedef struct {
+   GLfloat *m;         /* 16-byte aligned */
+   GLfloat *inv;       /* optional, 16-byte aligned */
+   GLuint flags;
+   GLuint type;                /* one of the MATRIX_* values */
+} GLmatrix;
+
+
+
+
+extern void
+_math_matrix_ctr( GLmatrix *m );
+
+extern void
+_math_matrix_dtr( GLmatrix *m );
+
+extern void
+_math_matrix_alloc_inv( GLmatrix *m );
+
+extern void
+_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b );
+
+extern void
+_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *b );
+
+extern void 
+_math_matrix_loadf( GLmatrix *mat, const GLfloat *m );
+
+extern void 
+_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z );
+
+extern void
+_math_matrix_rotate( GLmatrix *m, GLfloat angle, 
+                    GLfloat x, GLfloat y, GLfloat z );
+
+extern void 
+_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z );
+
+extern void
+_math_matrix_ortho( GLmatrix *mat,     
+                   GLfloat left, GLfloat right,
+                   GLfloat bottom, GLfloat top, 
+                   GLfloat nearval, GLfloat farval );
+
+extern void
+_math_matrix_frustrum( GLmatrix *mat, 
+                      GLfloat left, GLfloat right,
+                      GLfloat bottom, GLfloat top, 
+                      GLfloat nearval, GLfloat farval );
+
+extern void
+_math_matrix_set_identity( GLmatrix *dest );
+
+extern void 
+_math_matrix_copy( GLmatrix *to, const GLmatrix *from );
+
+extern void
+_math_matrix_analyze( GLmatrix *mat );
+
+extern void
+_math_matrix_print( const GLmatrix *m );
+
+
+
+
+/* Related functions that don't actually operate on GLmatrix structs:
+ */
+extern void
+_math_transposef( GLfloat to[16], const GLfloat from[16] );
+
+extern void
+_math_transposed( GLdouble to[16], const GLdouble from[16] );
+
+extern void
+_math_transposefd( GLfloat to[16], const GLdouble from[16] );
+
+
+
+
+#endif
diff --git a/src/mesa/math/m_norm_tmp.h b/src/mesa/math/m_norm_tmp.h
new file mode 100644 (file)
index 0000000..72770c2
--- /dev/null
@@ -0,0 +1,413 @@
+/* $Id: m_norm_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.3
+ * 
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+static void _XFORMAPI
+TAG(transform_normalize_normals)( const GLmatrix *mat,
+                                  GLfloat scale,
+                                  const GLvector3f *in,
+                                  const GLfloat *lengths,
+                                  const GLubyte mask[],
+                                  GLvector3f *dest )
+{
+   GLuint i;  
+   const GLfloat *from = in->start;
+   GLuint stride = in->stride;
+   GLuint count = in->count;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+   GLfloat *m = mat->inv;
+   GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8];
+   GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9];
+   GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10];
+
+   (void) mask;
+   if (!lengths) {
+      STRIDE_LOOP {
+        CULL_CHECK {
+           GLfloat tx, ty, tz;
+           {
+              const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
+              tx = ux * m0 + uy * m1 + uz * m2;
+              ty = ux * m4 + uy * m5 + uz * m6;
+              tz = ux * m8 + uy * m9 + uz * m10;
+           }
+           {
+              GLdouble len = tx*tx + ty*ty + tz*tz;
+              if (len > 1e-20) {
+                 GLdouble scale = 1.0 / GL_SQRT(len);
+                 out[i][0] = (GLfloat) (tx * scale);
+                 out[i][1] = (GLfloat) (ty * scale);
+                 out[i][2] = (GLfloat) (tz * scale);
+              }
+              else
+              {
+                 out[i][0] = out[i][1] = out[i][2] = 0;
+              }
+           }
+        }
+      }
+   }
+   else {
+      /* scale has been snapped to 1.0 if it is close.
+       */
+      if (scale != 1.0) {
+        m0 *= scale,  m4 *= scale,  m8 *= scale;
+        m1 *= scale,  m5 *= scale,  m9 *= scale;
+        m2 *= scale,  m6 *= scale,  m10 *= scale;
+      }
+
+      STRIDE_LOOP {
+        CULL_CHECK {
+           GLfloat tx, ty, tz;
+           {
+              const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
+              tx = ux * m0 + uy * m1 + uz * m2;
+              ty = ux * m4 + uy * m5 + uz * m6;
+              tz = ux * m8 + uy * m9 + uz * m10;
+           }
+           {
+              GLfloat len = lengths[i];
+              out[i][0] = tx * len;
+              out[i][1] = ty * len;
+              out[i][2] = tz * len;
+           }
+        }
+      }
+   }
+   dest->count = in->count;
+}
+
+
+static void _XFORMAPI
+TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat,
+                                         GLfloat scale,
+                                         const GLvector3f *in,
+                                         const GLfloat *lengths,
+                                         const GLubyte mask[],
+                                         GLvector3f *dest )
+{
+   GLuint i;  
+   const GLfloat *from = in->start;
+   GLuint stride = in->stride;
+   GLuint count = in->count;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+   GLfloat *m = mat->inv;
+   GLfloat m0 = m[0];
+   GLfloat m5 = m[5];
+   GLfloat m10 = m[10];
+   (void) mask;
+   if (!lengths) {
+      STRIDE_LOOP {
+        CULL_CHECK {
+           GLfloat tx, ty, tz;
+           {
+              const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
+              tx = ux * m0                    ;
+              ty =           uy * m5          ;
+              tz =                     uz * m10;
+           }
+           {
+              GLdouble len = tx*tx + ty*ty + tz*tz;
+              if (len > 1e-20) {
+                 GLdouble scale = 1.0 / GL_SQRT(len);
+                 out[i][0] = (GLfloat) (tx * scale);
+                 out[i][1] = (GLfloat) (ty * scale);
+                 out[i][2] = (GLfloat) (tz * scale);
+              }
+              else
+              {
+                 out[i][0] = out[i][1] = out[i][2] = 0;
+              }
+           }
+        }
+      }
+   }
+   else {
+      /* scale has been snapped to 1.0 if it is close.
+       */
+      if (scale != 1.0) {
+        m0 *= scale; 
+        m5 *= scale;
+        m10 *= scale;
+      }
+
+      STRIDE_LOOP {
+        CULL_CHECK {
+           GLfloat tx, ty, tz;
+           {
+              const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
+              tx = ux * m0                    ;
+              ty =           uy * m5          ;
+              tz =                     uz * m10;
+           }
+           {
+              GLfloat len = lengths[i];
+              out[i][0] = tx * len;
+              out[i][1] = ty * len;
+              out[i][2] = tz * len;
+           }
+        }
+      }
+   }
+   dest->count = in->count;
+}
+
+
+static void _XFORMAPI
+TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat,
+                                       GLfloat scale,
+                                       const GLvector3f *in,
+                                       const GLfloat *lengths,
+                                       const GLubyte mask[],
+                                       GLvector3f *dest )
+{
+   GLuint i;  
+   const GLfloat *from = in->start;
+   GLuint stride = in->stride;
+   GLuint count = in->count;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+   const GLfloat *m = mat->inv;
+   GLfloat m0 = scale*m[0];
+   GLfloat m5 = scale*m[5];
+   GLfloat m10 = scale*m[10];
+   (void) lengths;
+   (void) mask;
+   STRIDE_LOOP {
+      CULL_CHECK {
+        GLfloat ux = from[0],  uy = from[1],  uz = from[2];
+        out[i][0] = ux * m0;
+        out[i][1] =           uy * m5;
+        out[i][2] =                     uz * m10;
+      }
+   }
+   dest->count = in->count;
+}
+
+static void _XFORMAPI
+TAG(transform_rescale_normals)( const GLmatrix *mat,
+                                GLfloat scale,
+                                const GLvector3f *in,
+                                const GLfloat *lengths,
+                                const GLubyte mask[],
+                                GLvector3f *dest )
+{
+   GLuint i;  
+   const GLfloat *from = in->start;
+   GLuint stride = in->stride;
+   GLuint count = in->count;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+   /* Since we are unlikely to have < 3 vertices in the buffer,
+    * it makes sense to pre-multiply by scale.
+    */
+   const GLfloat *m = mat->inv;
+   GLfloat m0 = scale*m[0],  m4 = scale*m[4],  m8 = scale*m[8];
+   GLfloat m1 = scale*m[1],  m5 = scale*m[5],  m9 = scale*m[9];
+   GLfloat m2 = scale*m[2],  m6 = scale*m[6],  m10 = scale*m[10];
+   (void) lengths;
+   (void) mask;
+   STRIDE_LOOP {
+      CULL_CHECK {
+        GLfloat ux = from[0],  uy = from[1],  uz = from[2];
+        out[i][0] = ux * m0 + uy * m1 + uz * m2;
+        out[i][1] = ux * m4 + uy * m5 + uz * m6;
+        out[i][2] = ux * m8 + uy * m9 + uz * m10;
+      }
+   }
+   dest->count = in->count;
+}
+
+
+static void _XFORMAPI
+TAG(transform_normals_no_rot)(const GLmatrix *mat,
+                              GLfloat scale,
+                              const GLvector3f *in,
+                              const GLfloat *lengths,
+                              const GLubyte mask[],
+                              GLvector3f *dest )
+{
+   GLuint i;  
+   const GLfloat *from = in->start;
+   GLuint stride = in->stride;
+   GLuint count = in->count;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+   const GLfloat *m = mat->inv;
+   GLfloat m0 = m[0];
+   GLfloat m5 = m[5];
+   GLfloat m10 = m[10];
+   (void) scale;
+   (void) lengths;
+   (void) mask;
+   STRIDE_LOOP {
+      CULL_CHECK {
+        GLfloat ux = from[0],  uy = from[1],  uz = from[2];
+        out[i][0] = ux * m0;
+        out[i][1] =           uy * m5;
+        out[i][2] =                     uz * m10;
+      }
+   }
+   dest->count = in->count;
+}
+
+
+static void _XFORMAPI
+TAG(transform_normals)( const GLmatrix *mat,
+                        GLfloat scale,
+                        const GLvector3f *in,
+                        const GLfloat *lengths,
+                        const GLubyte mask[],
+                        GLvector3f *dest )
+{
+   GLuint i;  
+   const GLfloat *from = in->start;
+   GLuint stride = in->stride;
+   GLuint count = in->count;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+   const GLfloat *m = mat->inv;
+   GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8];
+   GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9];
+   GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10];
+   (void) scale;
+   (void) lengths;
+   (void) mask;
+   STRIDE_LOOP {
+      CULL_CHECK {
+        GLfloat ux = from[0],  uy = from[1],  uz = from[2];
+        out[i][0] = ux * m0 + uy * m1 + uz * m2;
+        out[i][1] = ux * m4 + uy * m5 + uz * m6;
+        out[i][2] = ux * m8 + uy * m9 + uz * m10;
+      }
+   }
+   dest->count = in->count;
+}
+
+
+static void _XFORMAPI
+TAG(normalize_normals)( const GLmatrix *mat,
+                        GLfloat scale,
+                        const GLvector3f *in,
+                        const GLfloat *lengths,
+                        const GLubyte mask[],
+                        GLvector3f *dest )
+{
+   GLuint i;  
+   const GLfloat *from = in->start;
+   GLuint stride = in->stride;
+   GLuint count = in->count;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+   (void) mat;
+   (void) mask;
+   (void) scale;
+   if (lengths) {
+      STRIDE_LOOP {
+        CULL_CHECK {
+           const GLfloat x = from[0], y = from[1], z = from[2];
+           GLfloat invlen = lengths[i];
+           out[i][0] = x * invlen;
+           out[i][1] = y * invlen;
+           out[i][2] = z * invlen;
+        }       
+      }
+   }
+   else {
+      STRIDE_LOOP {
+        CULL_CHECK {
+           const GLfloat x = from[0], y = from[1], z = from[2];
+           GLdouble len = x * x + y * y + z * z;
+           if (len > 1e-50) {
+              len = 1.0 / GL_SQRT(len);
+              out[i][0] = (GLfloat) (x * len);
+              out[i][1] = (GLfloat) (y * len);
+              out[i][2] = (GLfloat) (z * len);
+           }
+           else {
+              out[i][0] = x;
+              out[i][1] = y;
+              out[i][2] = z;
+           }
+        }       
+      }
+   }
+   dest->count = in->count;
+}
+
+
+static void _XFORMAPI
+TAG(rescale_normals)( const GLmatrix *mat,
+                      GLfloat scale,
+                      const GLvector3f *in,
+                      const GLfloat *lengths,
+                      const GLubyte mask[],
+                      GLvector3f *dest )
+{
+   GLuint i;  
+   const GLfloat *from = in->start;
+   GLuint stride = in->stride;
+   GLuint count = in->count;
+   GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
+   (void) mat;
+   (void) lengths;
+   (void) mask;
+
+   STRIDE_LOOP {
+      CULL_CHECK {
+        SCALE_SCALAR_3V( out[i], scale, from );
+      }
+   }
+   dest->count = in->count;
+}
+
+
+static void _XFORMAPI
+TAG(init_c_norm_transform)( void )
+{
+   gl_normal_tab[NORM_TRANSFORM_NO_ROT][IDX] = 
+      TAG(transform_normals_no_rot);
+
+   gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE][IDX] = 
+      TAG(transform_rescale_normals_no_rot);
+
+   gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE][IDX] = 
+      TAG(transform_normalize_normals_no_rot);
+
+   gl_normal_tab[NORM_TRANSFORM][IDX] = 
+      TAG(transform_normals);
+
+   gl_normal_tab[NORM_TRANSFORM | NORM_RESCALE][IDX] = 
+      TAG(transform_rescale_normals);
+
+   gl_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE][IDX] = 
+      TAG(transform_normalize_normals);
+
+   gl_normal_tab[NORM_RESCALE][IDX] = 
+      TAG(rescale_normals);
+
+   gl_normal_tab[NORM_NORMALIZE][IDX] = 
+      TAG(normalize_normals);
+}
diff --git a/src/mesa/math/m_trans_tmp.h b/src/mesa/math/m_trans_tmp.h
new file mode 100644 (file)
index 0000000..952fde5
--- /dev/null
@@ -0,0 +1,210 @@
+/* $Id: m_trans_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+/* KW: This file also included by tnl/trans_elt.c to build code
+ *     specific to the implementation of array-elements in the
+ *     tnl module.
+ */
+
+
+#ifdef DEST_4F
+static void DEST_4F( GLfloat (*t)[4],
+                    CONST void *ptr,
+                    GLuint stride,
+                    ARGS)
+{
+   const GLubyte *f = (GLubyte *) ptr + SRC_START * stride;
+   const GLubyte *first = f;
+   GLuint i;
+
+   (void) first;
+   (void) start;
+   for (i = DST_START ; i < n ; i++, NEXT_F) {
+      CHECK { 
+         NEXT_F2;
+        if (SZ >= 1) t[i][0] = TRX_4F(f, 0);
+        if (SZ >= 2) t[i][1] = TRX_4F(f, 1);
+        if (SZ >= 3) t[i][2] = TRX_4F(f, 2);
+        if (SZ == 4) t[i][3] = TRX_4F(f, 3);
+      }
+   }
+}
+#endif
+
+
+#ifdef DEST_3F
+static void DEST_3F( GLfloat (*t)[3],
+                    CONST void *ptr,
+                    GLuint stride,
+                    ARGS)
+{
+   const GLubyte *f = (GLubyte *) ptr + SRC_START * stride;
+   const GLubyte *first = f;
+   GLuint i;
+   (void) first;
+   (void) start;
+   for (i = DST_START ; i < n ; i++, NEXT_F) {
+      CHECK {
+         NEXT_F2;
+        t[i][0] = TRX_3F(f, 0);
+        t[i][1] = TRX_3F(f, 1);
+        t[i][2] = TRX_3F(f, 2);
+      }
+   }
+}
+#endif
+
+#ifdef DEST_1F
+static void DEST_1F( GLfloat *t,
+                    CONST void *ptr,
+                    GLuint stride,
+                    ARGS)
+{
+   const GLubyte *f = (GLubyte *) ptr + SRC_START * stride;
+   const GLubyte *first = f;
+   GLuint i;
+   (void) first;
+   (void) start;
+   for (i = DST_START ; i < n ; i++, NEXT_F) {
+      CHECK {
+         NEXT_F2;
+        t[i] = TRX_1F(f, 0);
+      }
+   }
+}
+#endif
+
+#ifdef DEST_4UB
+static void DEST_4UB( GLubyte (*t)[4],
+                     CONST void *ptr,
+                     GLuint stride,
+                     ARGS)
+{
+   const GLubyte *f = (GLubyte *) ptr + SRC_START * stride;
+   const GLubyte *first = f;
+   GLuint i;
+   (void) start;
+   (void) first;
+   for (i = DST_START ; i < n ; i++, NEXT_F) {
+      CHECK {
+         NEXT_F2;
+        if (SZ >= 1) TRX_UB(t[i][0], f, 0);
+        if (SZ >= 2) TRX_UB(t[i][1], f, 1);
+        if (SZ >= 3) TRX_UB(t[i][2], f, 2); 
+        if (SZ == 4) TRX_UB(t[i][3], f, 3); else t[i][3] = 255;
+      }
+   }
+}
+#endif
+
+
+#ifdef DEST_1UB
+static void DEST_1UB( GLubyte *t,
+                     CONST void *ptr,
+                     GLuint stride,
+                     ARGS)
+{
+   const GLubyte *f = (GLubyte *) ptr + SRC_START * stride;
+   const GLubyte *first = f;
+   GLuint i;
+   (void) start;
+   (void) first;
+   for (i = DST_START ; i < n ; i++, NEXT_F) {
+      CHECK {
+         NEXT_F2;
+         TRX_UB(t[i], f, 0);
+      }
+   }
+}
+#endif
+
+
+#ifdef DEST_1UI
+static void DEST_1UI( GLuint *t,
+                     CONST void *ptr,
+                     GLuint stride,
+                     ARGS)
+{
+   const GLubyte *f = (GLubyte *) ptr + SRC_START * stride;
+   const GLubyte *first = f;
+   GLuint i;
+   (void) start;
+   (void) first;
+
+   for (i = DST_START ; i < n ; i++, NEXT_F) {
+      CHECK {
+         NEXT_F2;
+        t[i] = TRX_UI(f, 0);
+      }
+   }
+}
+#endif
+
+
+static void INIT(void)
+{
+#ifdef DEST_1UI
+   ASSERT(SZ == 1);
+   TAB(_1ui)[SRC_IDX] = DEST_1UI;
+#endif
+#ifdef DEST_1UB
+   ASSERT(SZ == 1);
+   TAB(_1ub)[SRC_IDX] = DEST_1UB;
+#endif
+#ifdef DEST_1F
+   ASSERT(SZ == 1);
+   TAB(_1f)[SRC_IDX] = DEST_1F;
+#endif
+#ifdef DEST_3F
+   ASSERT(SZ == 3);
+   TAB(_3f)[SRC_IDX] = DEST_3F;
+#endif
+#ifdef DEST_4UB
+   TAB(_4ub)[SZ][SRC_IDX] = DEST_4UB;
+#endif
+#ifdef DEST_4F
+   TAB(_4f)[SZ][SRC_IDX] = DEST_4F;
+#endif
+   
+}
+
+
+#undef INIT
+#undef DEST_1UI
+#undef DEST_1UB
+#undef DEST_4UB
+#undef DEST_3F
+#undef DEST_4F
+#undef DEST_1F
+#undef SZ
+#undef TAG
+
+
diff --git a/src/mesa/math/m_translate.c b/src/mesa/math/m_translate.c
new file mode 100644 (file)
index 0000000..945e357
--- /dev/null
@@ -0,0 +1,478 @@
+/* $Id: m_translate.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.3
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+#include "glheader.h"
+#include "colormac.h"
+#include "mem.h"
+#include "mmath.h"
+
+#include "m_translate.h"
+
+/* This macro is used on other systems, so undefine it for this module */
+
+#undef CHECK
+
+trans_1f_func gl_trans_1f_tab[MAX_TYPES];
+trans_1ui_func gl_trans_1ui_tab[MAX_TYPES];
+trans_1ub_func gl_trans_1ub_tab[MAX_TYPES];
+trans_3f_func  gl_trans_3f_tab[MAX_TYPES];
+trans_4ub_func gl_trans_4ub_tab[5][MAX_TYPES];
+trans_4f_func  gl_trans_4f_tab[5][MAX_TYPES];
+
+
+#define PTR_ELT(ptr, elt) (((SRC *)ptr)[elt])
+
+
+#define TAB(x) gl_trans##x##_tab
+#define ARGS   GLuint start, GLuint n
+#define SRC_START  start
+#define DST_START  0
+#define STRIDE stride
+#define NEXT_F f += stride
+#define NEXT_F2
+#define CHECK
+
+
+
+
+/* GL_BYTE
+ */
+#define SRC GLbyte
+#define SRC_IDX TYPE_IDX(GL_BYTE)
+#define TRX_3F(f,n)   BYTE_TO_FLOAT( PTR_ELT(f,n) )
+#define TRX_4F(f,n)   (GLfloat)( PTR_ELT(f,n) )
+#define TRX_UB(ub, f,n)  ub = BYTE_TO_UBYTE( PTR_ELT(f,n) )
+#define TRX_UI(f,n)  (PTR_ELT(f,n) < 0 ? 0 : (GLuint)  PTR_ELT(f,n))
+
+
+#define SZ 4
+#define INIT init_trans_4_GLbyte_raw
+#define DEST_4F trans_4_GLbyte_4f_raw
+#define DEST_4UB trans_4_GLbyte_4ub_raw
+#include "m_trans_tmp.h"
+
+#define SZ 3
+#define INIT init_trans_3_GLbyte_raw
+#define DEST_4F trans_3_GLbyte_4f_raw
+#define DEST_4UB trans_3_GLbyte_4ub_raw
+#define DEST_3F trans_3_GLbyte_3f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 2
+#define INIT init_trans_2_GLbyte_raw
+#define DEST_4F trans_2_GLbyte_4f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 1
+#define INIT init_trans_1_GLbyte_raw
+#define DEST_4F trans_1_GLbyte_4f_raw
+#define DEST_1UB trans_1_GLbyte_1ub_raw
+#define DEST_1UI trans_1_GLbyte_1ui_raw
+#include "m_trans_tmp.h"
+
+#undef SRC
+#undef TRX_3F
+#undef TRX_4F
+#undef TRX_UB
+#undef TRX_UI
+#undef SRC_IDX
+
+/* GL_UNSIGNED_BYTE
+ */
+#define SRC GLubyte
+#define SRC_IDX TYPE_IDX(GL_UNSIGNED_BYTE)
+#define TRX_3F(f,n)            /* unused */
+#define TRX_4F(f,n)            /* unused */
+#define TRX_UB(ub, f,n)             ub = PTR_ELT(f,n)
+#define TRX_UI(f,n)          (GLuint)PTR_ELT(f,n)
+
+/* 4ub->4ub handled in special case below.
+ */
+
+#define SZ 3
+#define INIT init_trans_3_GLubyte_raw
+#define DEST_4UB trans_3_GLubyte_4ub_raw
+#include "m_trans_tmp.h"
+
+
+#define SZ 1
+#define INIT init_trans_1_GLubyte_raw
+#define DEST_1UI trans_1_GLubyte_1ui_raw
+#define DEST_1UB trans_1_GLubyte_1ub_raw
+#include "m_trans_tmp.h"
+
+#undef SRC
+#undef SRC_IDX
+#undef TRX_3F
+#undef TRX_4F
+#undef TRX_UB
+#undef TRX_UI
+
+
+/* GL_SHORT
+ */
+#define SRC GLshort
+#define SRC_IDX TYPE_IDX(GL_SHORT)
+#define TRX_3F(f,n)   SHORT_TO_FLOAT( PTR_ELT(f,n) )
+#define TRX_4F(f,n)   (GLfloat)( PTR_ELT(f,n) )
+#define TRX_UB(ub, f,n)  ub = SHORT_TO_UBYTE(PTR_ELT(f,n))
+#define TRX_UI(f,n)  (PTR_ELT(f,n) < 0 ? 0 : (GLuint)  PTR_ELT(f,n))
+
+
+#define SZ  4
+#define INIT init_trans_4_GLshort_raw
+#define DEST_4F trans_4_GLshort_4f_raw
+#define DEST_4UB trans_4_GLshort_4ub_raw
+#include "m_trans_tmp.h"
+
+#define SZ 3
+#define INIT init_trans_3_GLshort_raw
+#define DEST_4F trans_3_GLshort_4f_raw
+#define DEST_4UB trans_3_GLshort_4ub_raw
+#define DEST_3F trans_3_GLshort_3f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 2
+#define INIT init_trans_2_GLshort_raw
+#define DEST_4F trans_2_GLshort_4f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 1
+#define INIT init_trans_1_GLshort_raw
+#define DEST_4F trans_1_GLshort_4f_raw
+#define DEST_1UB trans_1_GLshort_1ub_raw
+#define DEST_1UI trans_1_GLshort_1ui_raw
+#include "m_trans_tmp.h"
+
+
+#undef SRC
+#undef SRC_IDX
+#undef TRX_3F
+#undef TRX_4F
+#undef TRX_UB
+#undef TRX_UI
+
+
+/* GL_UNSIGNED_SHORT
+ */
+#define SRC GLushort
+#define SRC_IDX TYPE_IDX(GL_UNSIGNED_SHORT)
+#define TRX_3F(f,n)   USHORT_TO_FLOAT( PTR_ELT(f,n) )
+#define TRX_4F(f,n)   (GLfloat)( PTR_ELT(f,n) )
+#define TRX_UB(ub,f,n)  ub = (GLubyte) (PTR_ELT(f,n) >> 8)
+#define TRX_UI(f,n)  (GLuint)   PTR_ELT(f,n)
+
+
+#define SZ 4
+#define INIT init_trans_4_GLushort_raw
+#define DEST_4F trans_4_GLushort_4f_raw
+#define DEST_4UB trans_4_GLushort_4ub_raw
+#include "m_trans_tmp.h"
+
+#define SZ 3
+#define INIT init_trans_3_GLushort_raw
+#define DEST_4F trans_3_GLushort_4f_raw
+#define DEST_4UB trans_3_GLushort_4ub_raw
+#define DEST_3F trans_3_GLushort_3f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 2
+#define INIT init_trans_2_GLushort_raw
+#define DEST_4F trans_2_GLushort_4f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 1
+#define INIT init_trans_1_GLushort_raw
+#define DEST_4F trans_1_GLushort_4f_raw
+#define DEST_1UB trans_1_GLushort_1ub_raw
+#define DEST_1UI trans_1_GLushort_1ui_raw
+#include "m_trans_tmp.h"
+
+#undef SRC
+#undef SRC_IDX
+#undef TRX_3F
+#undef TRX_4F
+#undef TRX_UB
+#undef TRX_UI
+
+
+/* GL_INT
+ */
+#define SRC GLint
+#define SRC_IDX TYPE_IDX(GL_INT)
+#define TRX_3F(f,n)   INT_TO_FLOAT( PTR_ELT(f,n) )
+#define TRX_4F(f,n)   (GLfloat)( PTR_ELT(f,n) )
+#define TRX_UB(ub, f,n)  ub = INT_TO_UBYTE(PTR_ELT(f,n))
+#define TRX_UI(f,n)  (PTR_ELT(f,n) < 0 ? 0 : (GLuint)  PTR_ELT(f,n))
+
+
+#define SZ 4
+#define INIT init_trans_4_GLint_raw
+#define DEST_4F trans_4_GLint_4f_raw
+#define DEST_4UB trans_4_GLint_4ub_raw
+#include "m_trans_tmp.h"
+
+#define SZ 3
+#define INIT init_trans_3_GLint_raw
+#define DEST_4F trans_3_GLint_4f_raw
+#define DEST_4UB trans_3_GLint_4ub_raw
+#define DEST_3F trans_3_GLint_3f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 2
+#define INIT init_trans_2_GLint_raw
+#define DEST_4F trans_2_GLint_4f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 1
+#define INIT init_trans_1_GLint_raw
+#define DEST_4F trans_1_GLint_4f_raw
+#define DEST_1UB trans_1_GLint_1ub_raw
+#define DEST_1UI trans_1_GLint_1ui_raw
+#include "m_trans_tmp.h"
+
+
+#undef SRC
+#undef SRC_IDX
+#undef TRX_3F
+#undef TRX_4F
+#undef TRX_UB
+#undef TRX_UI
+
+
+/* GL_UNSIGNED_INT
+ */
+#define SRC GLuint
+#define SRC_IDX TYPE_IDX(GL_UNSIGNED_INT)
+#define TRX_3F(f,n)   INT_TO_FLOAT( PTR_ELT(f,n) )
+#define TRX_4F(f,n)   (GLfloat)( PTR_ELT(f,n) )
+#define TRX_UB(ub, f,n)  ub = (GLubyte) (PTR_ELT(f,n) >> 24)
+#define TRX_UI(f,n)            PTR_ELT(f,n)
+
+
+#define SZ 4
+#define INIT init_trans_4_GLuint_raw
+#define DEST_4F trans_4_GLuint_4f_raw
+#define DEST_4UB trans_4_GLuint_4ub_raw
+#include "m_trans_tmp.h"
+
+#define SZ 3
+#define INIT init_trans_3_GLuint_raw
+#define DEST_4F trans_3_GLuint_4f_raw
+#define DEST_4UB trans_3_GLuint_4ub_raw
+#define DEST_3F trans_3_GLuint_3f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 2
+#define INIT init_trans_2_GLuint_raw
+#define DEST_4F trans_2_GLuint_4f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 1
+#define INIT init_trans_1_GLuint_raw
+#define DEST_4F trans_1_GLuint_4f_raw
+#define DEST_1UB trans_1_GLuint_1ub_raw
+#define DEST_1UI trans_1_GLuint_1ui_raw
+#include "m_trans_tmp.h"
+
+#undef SRC
+#undef SRC_IDX
+#undef TRX_3F
+#undef TRX_4F
+#undef TRX_UB
+#undef TRX_UI
+
+
+/* GL_DOUBLE
+ */
+#define SRC GLdouble
+#define SRC_IDX TYPE_IDX(GL_DOUBLE)
+#define TRX_3F(f,n)   PTR_ELT(f,n)
+#define TRX_4F(f,n)   PTR_ELT(f,n)
+#define TRX_UB(ub,f,n) FLOAT_COLOR_TO_CHAN(ub, PTR_ELT(f,n))
+#define TRX_UI(f,n)  (GLuint) (GLint) PTR_ELT(f,n)
+#define TRX_1F(f,n)   PTR_ELT(f,n)
+
+
+#define SZ 4
+#define INIT init_trans_4_GLdouble_raw
+#define DEST_4F trans_4_GLdouble_4f_raw
+#define DEST_4UB trans_4_GLdouble_4ub_raw
+#include "m_trans_tmp.h"
+
+#define SZ 3
+#define INIT init_trans_3_GLdouble_raw
+#define DEST_4F trans_3_GLdouble_4f_raw
+#define DEST_4UB trans_3_GLdouble_4ub_raw
+#define DEST_3F trans_3_GLdouble_3f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 2
+#define INIT init_trans_2_GLdouble_raw
+#define DEST_4F trans_2_GLdouble_4f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 1
+#define INIT init_trans_1_GLdouble_raw
+#define DEST_4F trans_1_GLdouble_4f_raw
+#define DEST_1UB trans_1_GLdouble_1ub_raw
+#define DEST_1UI trans_1_GLdouble_1ui_raw
+#define DEST_1F trans_1_GLdouble_1f_raw
+#include "m_trans_tmp.h"
+
+#undef SRC
+#undef SRC_IDX
+
+/* GL_FLOAT
+ */
+#define SRC GLfloat
+#define SRC_IDX TYPE_IDX(GL_FLOAT)
+#define SZ 4
+#define INIT init_trans_4_GLfloat_raw 
+#define DEST_4UB trans_4_GLfloat_4ub_raw 
+#define DEST_4F  trans_4_GLfloat_4f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 3
+#define INIT init_trans_3_GLfloat_raw
+#define DEST_4F  trans_3_GLfloat_4f_raw
+#define DEST_4UB trans_3_GLfloat_4ub_raw
+#define DEST_3F trans_3_GLfloat_3f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 2
+#define INIT init_trans_2_GLfloat_raw
+#define DEST_4F trans_2_GLfloat_4f_raw
+#include "m_trans_tmp.h"
+
+#define SZ 1
+#define INIT init_trans_1_GLfloat_raw
+#define DEST_4F  trans_1_GLfloat_4f_raw
+#define DEST_1UB trans_1_GLfloat_1ub_raw
+#define DEST_1UI trans_1_GLfloat_1ui_raw
+#define DEST_1F trans_1_GLfloat_1f_raw
+
+#include "m_trans_tmp.h"
+
+#undef SRC
+#undef SRC_IDX
+#undef TRX_3F
+#undef TRX_4F
+#undef TRX_UB
+#undef TRX_UI
+
+
+static void trans_4_GLubyte_4ub_raw (GLubyte (*t)[4],
+                                    CONST void *Ptr,
+                                    GLuint stride,
+                                    ARGS )
+{
+   const GLubyte *f = (GLubyte *) Ptr + SRC_START * stride;
+   GLuint i;
+
+   if (((((long) f | (long) stride)) & 3L) == 0L) { 
+      /* Aligned.
+       */
+      for (i = DST_START ; i < n ; i++, f += stride) {
+        COPY_4UBV( t[i], f );
+      }
+   } else {
+      for (i = DST_START ; i < n ; i++, f += stride) {
+        t[i][0] = f[0];
+        t[i][1] = f[1];
+        t[i][2] = f[2];
+        t[i][3] = f[3];
+      }
+   }
+}
+
+
+static void init_translate_raw(void)
+{
+   MEMSET( TAB(_1ui), 0, sizeof(TAB(_1ui)) );
+   MEMSET( TAB(_1ub), 0, sizeof(TAB(_1ub)) );
+   MEMSET( TAB(_3f),  0, sizeof(TAB(_3f)) );
+   MEMSET( TAB(_4ub), 0, sizeof(TAB(_4ub)) );
+   MEMSET( TAB(_4f),  0, sizeof(TAB(_4f)) );
+
+   TAB(_4ub)[4][TYPE_IDX(GL_UNSIGNED_BYTE)] = trans_4_GLubyte_4ub_raw;
+
+   init_trans_4_GLbyte_raw();
+   init_trans_3_GLbyte_raw();
+   init_trans_2_GLbyte_raw();
+   init_trans_1_GLbyte_raw();
+   init_trans_1_GLubyte_raw();
+   init_trans_3_GLubyte_raw();
+   init_trans_4_GLshort_raw();
+   init_trans_3_GLshort_raw();
+   init_trans_2_GLshort_raw();
+   init_trans_1_GLshort_raw();
+   init_trans_4_GLushort_raw();
+   init_trans_3_GLushort_raw();
+   init_trans_2_GLushort_raw();
+   init_trans_1_GLushort_raw();
+   init_trans_4_GLint_raw();
+   init_trans_3_GLint_raw();
+   init_trans_2_GLint_raw();
+   init_trans_1_GLint_raw();
+   init_trans_4_GLuint_raw();
+   init_trans_3_GLuint_raw();
+   init_trans_2_GLuint_raw();
+   init_trans_1_GLuint_raw();
+   init_trans_4_GLdouble_raw();
+   init_trans_3_GLdouble_raw();
+   init_trans_2_GLdouble_raw();
+   init_trans_1_GLdouble_raw();
+   init_trans_4_GLfloat_raw();
+   init_trans_3_GLfloat_raw();
+   init_trans_2_GLfloat_raw();
+   init_trans_1_GLfloat_raw();
+}
+
+
+#undef TAB
+#undef CLASS
+#undef ARGS
+#undef CHECK
+#undef SRC_START
+#undef DST_START
+#undef NEXT_F
+#undef NEXT_F2
+
+
+
+
+
+void 
+_math_init_translate( void )
+{
+   init_translate_raw();
+}
diff --git a/src/mesa/math/m_translate.h b/src/mesa/math/m_translate.h
new file mode 100644 (file)
index 0000000..5c60b97
--- /dev/null
@@ -0,0 +1,92 @@
+/* $Id: m_translate.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _M_TRANSLATE_H_
+#define _M_TRANSLATE_H_
+
+
+typedef void (*trans_1f_func)(GLfloat *to,
+                             CONST void *ptr,
+                             GLuint stride,
+                             GLuint start, 
+                             GLuint n );
+
+typedef void (*trans_1ui_func)(GLuint *to,
+                              CONST void *ptr,
+                              GLuint stride,
+                              GLuint start, 
+                              GLuint n );
+
+typedef void (*trans_1ub_func)(GLubyte *to,
+                              CONST void *ptr,
+                              GLuint stride,
+                              GLuint start,
+                              GLuint n );
+
+typedef void (*trans_4ub_func)(GLubyte (*to)[4],
+                              CONST void *ptr,
+                              GLuint stride,
+                              GLuint start,
+                              GLuint n );
+
+typedef void (*trans_4f_func)(GLfloat (*to)[4],
+                             CONST void *ptr,
+                             GLuint stride,
+                             GLuint start, 
+                             GLuint n );
+
+typedef void (*trans_3f_func)(GLfloat (*to)[3],
+                             CONST void *ptr,
+                             GLuint stride,
+                             GLuint start, 
+                             GLuint n );
+
+
+
+
+/* Translate GL_UNSIGNED_BYTE, etc to the indexes used in the arrays
+ * below.
+ */
+#define TYPE_IDX(t) ((t) & 0xf)
+
+#define MAX_TYPES TYPE_IDX(GL_DOUBLE)+1      /* 0xa + 1 */
+
+/* Only useful combinations are defined, thus there is no function to
+ * translate eg, ubyte->float or ubyte->ubyte, which are never used.  
+ */
+extern trans_1f_func gl_trans_1f_tab[MAX_TYPES];
+extern trans_1ui_func gl_trans_1ui_tab[MAX_TYPES];
+extern trans_1ub_func gl_trans_1ub_tab[MAX_TYPES];
+extern trans_3f_func  gl_trans_3f_tab[MAX_TYPES];
+extern trans_4ub_func gl_trans_4ub_tab[5][MAX_TYPES];
+extern trans_4f_func  gl_trans_4f_tab[5][MAX_TYPES];
+
+
+extern void gl_init_translate( void );
+
+
+#endif
diff --git a/src/mesa/math/m_vector.c b/src/mesa/math/m_vector.c
new file mode 100644 (file)
index 0000000..4dbf68f
--- /dev/null
@@ -0,0 +1,367 @@
+/* $Id: m_vector.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ * 
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+#include "glheader.h"
+#include "macros.h"
+#include "mem.h"
+
+#include "m_vector.h"
+
+
+
+/*
+ * Given a vector [count][4] of floats, set all the [][elt] values
+ * to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3).
+ */
+void gl_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt )
+{
+   static const GLubyte elem_bits[4] = {
+      VEC_DIRTY_0,
+      VEC_DIRTY_1, 
+      VEC_DIRTY_2, 
+      VEC_DIRTY_3
+   };
+   static const GLfloat clean[4] = { 0, 0, 0, 1 };
+   const GLfloat v = clean[elt];
+   GLfloat (*data)[4] = (GLfloat (*)[4])vec->start;
+   GLuint i; 
+
+   for (i = 0 ; i < count ; i++)
+      data[i][elt] = v;
+
+   vec->flags &= ~elem_bits[elt];
+}
+
+static const GLubyte size_bits[5] = {
+   0,
+   VEC_SIZE_1,
+   VEC_SIZE_2,
+   VEC_SIZE_3,
+   VEC_SIZE_4,
+};
+
+
+
+/*
+ * Initialize GLvector objects.
+ * Input: v - the vector object to initialize.
+ *        flags - bitwise-OR of VEC_* flags
+ *        storage - pointer to storage for the vector's data
+ */
+
+
+void gl_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] )
+{
+   v->stride = 4 * sizeof(GLfloat);
+   v->size = 2;   /* may change: 2-4 for vertices and 1-4 for texcoords */
+   v->data = storage;
+   v->start = (GLfloat *) storage;
+   v->count = 0;
+   v->flags = size_bits[4] | flags | VEC_GOOD_STRIDE;
+}
+
+void gl_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*storage)[3] )
+{
+   v->stride = 3 * sizeof(GLfloat);
+   v->data = storage;
+   v->start = (GLfloat *) storage;
+   v->count = 0;
+   v->flags = flags | VEC_GOOD_STRIDE;
+}
+
+void gl_vector1f_init( GLvector1f *v, GLuint flags, GLfloat *storage )
+{
+   v->stride = 1*sizeof(GLfloat);
+   v->data = storage;
+   v->start = (GLfloat *)storage;
+   v->count = 0;
+   v->flags = flags | VEC_GOOD_STRIDE;
+}
+
+void gl_vector4ub_init( GLvector4ub *v, GLuint flags, GLubyte (*storage)[4] )
+{
+   v->stride = 4 * sizeof(GLubyte);
+   v->data = storage;
+   v->start = (GLubyte *) storage;
+   v->count = 0;
+   v->flags = flags | VEC_GOOD_STRIDE;
+}
+
+void gl_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage )
+{
+   v->stride = 1 * sizeof(GLubyte);
+   v->data = storage;
+   v->start = (GLubyte *) storage;
+   v->count = 0;
+   v->flags = flags | VEC_GOOD_STRIDE;
+}
+
+void gl_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage )
+{
+   v->stride = 1 * sizeof(GLuint);
+   v->data = storage;
+   v->start = (GLuint *) storage;
+   v->count = 0;
+   v->flags = flags | VEC_GOOD_STRIDE;
+}
+
+
+/*
+ * Initialize GLvector objects and allocate storage.
+ * Input: v - the vector object
+ *        sz - unused????
+ *        flags - bitwise-OR of VEC_* flags
+ *        count - number of elements to allocate in vector
+ *        alignment - desired memory alignment for the data (in bytes)
+ */
+
+
+void gl_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count,
+                       GLuint alignment )
+{
+   v->stride = 4 * sizeof(GLfloat);
+   v->size = 2;
+   v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLfloat), alignment );
+   v->start = (GLfloat *) v->storage;
+   v->data = (GLfloat (*)[4]) v->storage;
+   v->count = 0;
+   v->flags = size_bits[4] | flags | VEC_MALLOC | VEC_GOOD_STRIDE;
+}
+
+void gl_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count,
+                       GLuint alignment )
+{
+   v->stride = 3 * sizeof(GLfloat);
+   v->storage = ALIGN_MALLOC( count * 3 * sizeof(GLfloat), alignment );
+   v->start = (GLfloat *) v->storage;
+   v->data = (GLfloat (*)[3]) v->storage;
+   v->count = 0;
+   v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE;
+}
+
+void gl_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count,
+                       GLuint alignment )
+{
+   v->stride = sizeof(GLfloat);
+   v->storage = v->start = (GLfloat *)
+      ALIGN_MALLOC( count * sizeof(GLfloat), alignment );
+   v->data = v->start;
+   v->count = 0;
+   v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE;
+}
+
+void gl_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count,
+                        GLuint alignment )
+{
+   v->stride = 4 * sizeof(GLubyte);
+   v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLubyte), alignment );
+   v->start = (GLubyte *) v->storage;
+   v->data = (GLubyte (*)[4]) v->storage;
+   v->count = 0;
+   v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE;
+}
+
+void gl_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count,
+                        GLuint alignment )
+{
+   v->stride = 1 * sizeof(GLubyte);
+   v->storage = ALIGN_MALLOC( count * sizeof(GLubyte), alignment );
+   v->start = (GLubyte *) v->storage;      
+   v->data = (GLubyte *) v->storage;
+   v->count = 0;
+   v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE;
+}
+
+void gl_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count,
+                        GLuint alignment )
+{
+   v->stride = 1 * sizeof(GLuint);
+   v->storage = ALIGN_MALLOC( count * sizeof(GLuint), alignment );
+   v->start = (GLuint *) v->storage;      
+   v->data = (GLuint *) v->storage;
+   v->count = 0;
+   v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE;
+}
+
+
+
+/*
+ * Vector deallocation.  Free whatever memory is pointed to by the
+ * vector's storage field if the VEC_MALLOC flag is set.
+ * DO NOT free the GLvector object itself, though.
+ */
+
+
+void gl_vector4f_free( GLvector4f *v )
+{
+   if (v->flags & VEC_MALLOC) {
+      ALIGN_FREE( v->storage );
+      v->data = NULL;
+      v->start = NULL;
+      v->storage = NULL;
+      v->flags &= ~VEC_MALLOC;
+   }
+}
+
+void gl_vector3f_free( GLvector3f *v )
+{
+   if (v->flags & VEC_MALLOC) {
+      ALIGN_FREE( v->storage );
+      v->data = 0;
+      v->start = 0;
+      v->storage = 0;
+      v->flags &= ~VEC_MALLOC;
+   }
+}
+
+void gl_vector1f_free( GLvector1f *v )
+{
+   if (v->flags & VEC_MALLOC) {
+      ALIGN_FREE( v->storage );
+      v->data = NULL;
+      v->start = NULL;
+      v->storage = NULL;
+      v->flags &= ~VEC_MALLOC;
+   }
+}
+
+void gl_vector4ub_free( GLvector4ub *v )
+{
+   if (v->flags & VEC_MALLOC) {
+      ALIGN_FREE( v->storage );
+      v->data = NULL;
+      v->start = NULL;
+      v->storage = NULL;
+      v->flags &= ~VEC_MALLOC;
+   }
+}
+
+void gl_vector1ub_free( GLvector1ub *v )
+{
+   if (v->flags & VEC_MALLOC) {
+      ALIGN_FREE( v->storage );
+      v->data = NULL;
+      v->start = NULL;
+      v->storage = NULL;
+      v->flags &= ~VEC_MALLOC;
+   }
+}
+
+void gl_vector1ui_free( GLvector1ui *v )
+{
+   if (v->flags & VEC_MALLOC) {
+      ALIGN_FREE( v->storage );
+      v->data = NULL;
+      v->start = NULL;
+      v->storage = NULL;
+      v->flags &= ~VEC_MALLOC;
+   }
+}
+
+
+/*
+ * For debugging
+ */
+void gl_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling )
+{
+   GLfloat c[4] = { 0, 0, 0, 1 };
+   const char *templates[5] = {
+      "%d:\t0, 0, 0, 1\n",
+      "%d:\t%f, 0, 0, 1\n",
+      "%d:\t%f, %f, 0, 1\n",
+      "%d:\t%f, %f, %f, 1\n",
+      "%d:\t%f, %f, %f, %f\n"
+   };
+
+   const char *t = templates[v->size];
+   GLfloat *d = (GLfloat *)v->data;
+   GLuint j, i = 0, count;
+
+   printf("data-start\n");
+   for ( ; d != v->start ; STRIDE_F(d, v->stride), i++) 
+      printf( t, i, d[0], d[1], d[2], d[3]);
+   
+   printf("start-count(%u)\n", v->count);
+   count = i + v->count;
+
+   if (culling) {
+      for ( ; i < count ; STRIDE_F(d, v->stride), i++) 
+        if (cullmask[i]) 
+           printf( t, i, d[0], d[1], d[2], d[3]);      
+   }
+   else {
+      for ( ; i < count ; STRIDE_F(d, v->stride), i++) 
+        printf( t, i, d[0], d[1], d[2], d[3]);      
+   }
+
+   for (j = v->size ; j < 4; j++) {
+      if ((v->flags & (1<<j)) == 0) {
+
+        printf("checking col %u is clean as advertised ", j);
+
+        for (i = 0, d = (GLfloat *) v->data ; 
+             i < count && d[j] == c[j] ; 
+             i++, STRIDE_F(d, v->stride)) {};
+
+        if (i == count) 
+           printf(" --> ok\n");
+        else 
+           printf(" --> Failed at %u ******\n", i);
+      }
+   }
+}
+
+
+/*
+ * For debugging
+ */
+void gl_vector3f_print( GLvector3f *v, GLubyte *cullmask, GLboolean culling )
+{
+   GLfloat *d = (GLfloat *)v->data;
+   GLuint i = 0, count;
+
+   printf("data-start\n");
+   for ( ; d != v->start ; STRIDE_F(d,v->stride), i++) 
+      printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);
+   
+   printf("start-count(%u)\n", v->count);
+   count = i + v->count;
+
+   if (culling) {
+      for ( ; i < count ; STRIDE_F(d,v->stride), i++) 
+        if (cullmask[i])
+           printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);      
+   }
+   else {
+      for ( ; i < count ; STRIDE_F(d,v->stride), i++) 
+        printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);      
+   }
+}
diff --git a/src/mesa/math/m_vector.h b/src/mesa/math/m_vector.h
new file mode 100644 (file)
index 0000000..c4af1ea
--- /dev/null
@@ -0,0 +1,188 @@
+/* $Id: m_vector.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ * 
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+#ifndef _M_VECTOR_H_
+#define _M_VECTOR_H_
+
+#include "glheader.h"
+
+
+#define VEC_DIRTY_0        0x1 /* dirty flags not really used any more */
+#define VEC_DIRTY_1        0x2
+#define VEC_DIRTY_2        0x4
+#define VEC_DIRTY_3        0x8
+#define VEC_MALLOC         0x10 /* storage field points to self-allocated mem*/
+#define VEC_WRITABLE       0x20        /* keep both + and - bits for easy testing */
+#define VEC_NOT_WRITABLE   0x40
+#define VEC_GOOD_STRIDE    0x80        
+#define VEC_BAD_STRIDE     0x100
+
+#define VEC_WRITABLE_FLAGS (VEC_WRITABLE|VEC_NOT_WRITABLE)
+#define VEC_STRIDE_FLAGS   (VEC_GOOD_STRIDE|VEC_BAD_STRIDE)
+
+
+#define VEC_SIZE_1   VEC_DIRTY_0
+#define VEC_SIZE_2   (VEC_DIRTY_0|VEC_DIRTY_1)
+#define VEC_SIZE_3   (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2)
+#define VEC_SIZE_4   (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2|VEC_DIRTY_3)
+
+
+
+/* Wrap all the information about vectors up in a struct.  Has
+ * additional fields compared to the other vectors to help us track of
+ * different vertex sizes, and whether we need to clean columns out
+ * because they contain non-(0,0,0,1) values.  
+ *
+ * The start field is used to reserve data for copied vertices at the
+ * end of gl_transform_vb, and avoids the need for a multiplication in
+ * the transformation routines.
+ */
+typedef struct {
+   GLfloat (*data)[4]; /* may be malloc'd or point to client data */
+   GLfloat *start;     /* points somewhere inside of <data> */
+   GLuint count;       /* size of the vector (in elements) */
+   GLuint stride;      /* stride from one element to the next (in bytes) */
+   GLuint size;                /* 2-4 for vertices and 1-4 for texcoords */
+   GLuint flags;       /* which columns are dirty */
+   void *storage;      /* self-allocated storage */
+} GLvector4f;
+
+
+extern void gl_vector4f_init( GLvector4f *v, GLuint flags,
+                             GLfloat (*storage)[4] );
+extern void gl_vector4f_alloc( GLvector4f *v, GLuint flags,
+                              GLuint count, GLuint alignment );
+extern void gl_vector4f_free( GLvector4f *v );
+extern void gl_vector4f_print( GLvector4f *v, GLubyte *, GLboolean );
+extern void gl_vector4f_clean_elem( GLvector4f *vec, GLuint nr, GLuint elt );
+
+
+/* Could use a single vector type for normals and vertices, but
+ * this way avoids some casts.  
+ */
+typedef struct {
+   GLfloat (*data)[3];       
+   GLfloat *start;
+   GLuint count;
+   GLuint stride;
+   GLuint flags;
+   void *storage;
+} GLvector3f;
+
+extern void gl_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*)[3] );
+extern void gl_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count,
+                              GLuint alignment );
+extern void gl_vector3f_free( GLvector3f *v );
+extern void gl_vector3f_print( GLvector3f *v, GLubyte *, GLboolean );
+
+
+typedef struct {
+   GLfloat *data;       
+   GLfloat *start;
+   GLuint count;
+   GLuint stride;
+   GLuint flags;
+   void *storage;
+} GLvector1f;
+
+extern void gl_vector1f_free( GLvector1f *v );
+extern void gl_vector1f_init( GLvector1f *v, GLuint flags, GLfloat * );
+extern void gl_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count,
+                              GLuint alignment );
+
+
+/* For 4ub rgba values.
+ */
+typedef struct {
+   GLubyte (*data)[4];
+   GLubyte *start;
+   GLuint count;
+   GLuint stride;               
+   GLuint flags; 
+   void *storage;
+} GLvector4ub;
+
+extern void gl_vector4ub_init( GLvector4ub *v, GLuint flags, 
+                              GLubyte (*storage)[4] );
+extern void gl_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count,
+                               GLuint alignment );
+extern void gl_vector4ub_free( GLvector4ub * );
+
+
+
+
+/* For 1ub values, eg edgeflag.
+ */
+typedef struct {
+   GLubyte *data;
+   GLubyte *start;
+   GLuint count;
+   GLuint stride;               
+   GLuint flags; 
+   void *storage;
+} GLvector1ub;
+
+extern void gl_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage);
+extern void gl_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count,
+                               GLuint alignment );
+extern void gl_vector1ub_free( GLvector1ub * );
+
+
+
+
+/* For, eg Index, Array element.
+ */
+typedef struct {
+   GLuint *data;
+   GLuint *start;
+   GLuint count;
+   GLuint stride; 
+   GLuint flags; 
+   void *storage;
+} GLvector1ui;
+
+extern void gl_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage );
+extern void gl_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count, 
+                               GLuint alignment );
+extern void gl_vector1ui_free( GLvector1ui * );
+
+
+
+/*
+ * Given vector <v>, return a pointer (cast to <type *> to the <i>-th element.
+ *
+ * End up doing a lot of slow imuls if not careful.
+ */
+#define VEC_ELT( v, type, i ) \
+       ( (type *)  ( ((GLbyte *) ((v)->data)) + (i) * (v)->stride) )
+
+
+#endif
diff --git a/src/mesa/math/m_xform.c b/src/mesa/math/m_xform.c
new file mode 100644 (file)
index 0000000..6bc6a9c
--- /dev/null
@@ -0,0 +1,251 @@
+/* $Id: m_xform.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ *
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Matrix/vertex/vector transformation stuff
+ *
+ *
+ * NOTES:
+ * 1. 4x4 transformation matrices are stored in memory in column major order.
+ * 2. Points/vertices are to be thought of as column vectors.
+ * 3. Transformation of a point p by a matrix M is: p' = M * p
+ */
+
+
+#include "glheader.h"
+#include "macros.h"
+#include "mmath.h"
+
+#include "m_matrix.h"
+#include "m_xform.h"
+
+
+#ifdef DEBUG
+#include "m_debug_xform.h"
+#endif
+
+#ifdef USE_X86_ASM
+#include "X86/common_x86_asm.h"
+#endif
+
+clip_func gl_clip_tab[5];
+dotprod_func gl_dotprod_tab[2][5];
+vec_copy_func gl_copy_tab[2][0x10];
+normal_func gl_normal_tab[0xf][0x4];
+transform_func **(gl_transform_tab[2]);
+static transform_func *cull_transform_tab[5];
+static transform_func *raw_transform_tab[5];
+
+
+/* Raw data format used for:
+ *    - Object-to-eye transform prior to culling, although this too
+ *      could be culled under some circumstances.
+ *    - Eye-to-clip transform (via the function above).
+ *    - Cliptesting
+ *    - And everything else too, if culling happens to be disabled.
+ */
+#define TAG(x) x##_raw
+#define TAG2(x,y) x##y##_raw
+#define IDX 0
+#define STRIDE_LOOP for (i=0;i<count;i++, STRIDE_F(from, stride))
+#define LOOP for (i=0;i<n;i++)
+#define CULL_CHECK
+#define CLIP_CHECK
+#define ARGS
+#include "m_xform_tmp.h"
+#include "m_clip_tmp.h"
+#include "m_norm_tmp.h"
+#include "m_dotprod_tmp.h"
+#include "m_copy_tmp.h"
+#undef TAG
+#undef TAG2
+#undef LOOP
+#undef CULL_CHECK
+#undef CLIP_CHECK
+#undef ARGS
+#undef IDX
+
+/* Culled data used for:
+ *    - texture transformations
+ *    - viewport map transformation
+ *    - normal transformations prior to lighting
+ *    - user cliptests
+ */
+#define TAG(x) x##_masked
+#define TAG2(x,y) x##y##_masked
+#define IDX 1
+#define STRIDE_LOOP for (i=0;i<count;i++, STRIDE_F(from, stride))
+#define LOOP for (i=0;i<n;i++)
+#define CULL_CHECK if (mask[i])
+#define CLIP_CHECK if ((mask[i] & flag) == 0)
+#define ARGS , const GLubyte mask[]
+#include "m_xform_tmp.h"
+#include "m_norm_tmp.h"
+#include "m_dotprod_tmp.h"
+#include "m_copy_tmp.h"
+#undef TAG
+#undef TAG2
+#undef LOOP
+#undef CULL_CHECK
+#undef CLIP_CHECK
+#undef ARGS
+#undef IDX
+
+
+
+
+
+
+GLvector4f *gl_project_points( GLvector4f *proj_vec,
+                              const GLvector4f *clip_vec )
+{
+   const GLuint stride = clip_vec->stride;
+   const GLfloat *from = (GLfloat *)clip_vec->start;
+   const GLuint count = clip_vec->count;
+   GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start;
+   GLuint i;
+
+   for (i = 0 ; i < count ; i++, STRIDE_F(from, stride))
+   {
+        GLfloat oow = 1.0F / from[3];
+        vProj[i][3] = oow;
+        vProj[i][0] = from[0] * oow;
+        vProj[i][1] = from[1] * oow;
+        vProj[i][2] = from[2] * oow;
+   }
+
+   proj_vec->flags |= VEC_SIZE_4;
+   proj_vec->size = 3;
+   proj_vec->count = clip_vec->count;
+   return proj_vec;
+}
+
+
+
+
+
+
+/*
+ * Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix.  This
+ * function is used for transforming clipping plane equations and spotlight
+ * directions.
+ * Mathematically,  u = v * m.
+ * Input:  v - input vector
+ *         m - transformation matrix
+ * Output:  u - transformed vector
+ */
+void gl_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] )
+{
+   GLfloat v0=v[0], v1=v[1], v2=v[2], v3=v[3];
+#define M(row,col)  m[row + col*4]
+   u[0] = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + v3 * M(3,0);
+   u[1] = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + v3 * M(3,1);
+   u[2] = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + v3 * M(3,2);
+   u[3] = v0 * M(0,3) + v1 * M(1,3) + v2 * M(2,3) + v3 * M(3,3);
+#undef M
+}
+
+
+/* Useful for one-off point transformations, as in clipping.
+ * Note that because the matrix isn't analyzed we do too many
+ * multiplies, and that the result is always 4-clean.
+ */
+void gl_transform_point_sz( GLfloat Q[4], const GLfloat M[16],
+                           const GLfloat P[4], GLuint sz )
+{
+   if (Q == P)
+      return;
+
+   if (sz == 4)
+   {
+      Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] *  P[2] + M[12] * P[3];
+      Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] *  P[2] + M[13] * P[3];
+      Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3];
+      Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3];
+   }
+   else if (sz == 3)
+   {
+      Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] *  P[2] + M[12];
+      Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] *  P[2] + M[13];
+      Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14];
+      Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15];
+   }
+   else if (sz == 2)
+   {
+      Q[0] = M[0] * P[0] + M[4] * P[1] +                M[12];
+      Q[1] = M[1] * P[0] + M[5] * P[1] +                M[13];
+      Q[2] = M[2] * P[0] + M[6] * P[1] +                M[14];
+      Q[3] = M[3] * P[0] + M[7] * P[1] +                M[15];
+   }
+   else if (sz == 1)
+   {
+      Q[0] = M[0] * P[0] +                              M[12];
+      Q[1] = M[1] * P[0] +                              M[13];
+      Q[2] = M[2] * P[0] +                              M[14];
+      Q[3] = M[3] * P[0] +                              M[15];
+   }
+}
+
+
+/*
+ * This is called only once.  It initializes several tables with pointers
+ * to optimized transformation functions.  This is where we can test for
+ * AMD 3Dnow! capability, Intel Katmai, etc. and hook in the right code.
+ */
+void 
+_math_init_transformation( void )
+{
+   gl_transform_tab[0] = raw_transform_tab;
+   gl_transform_tab[1] = cull_transform_tab;
+
+   init_c_transformations_raw();
+   init_c_transformations_masked();
+   init_c_norm_transform_raw();
+   init_c_norm_transform_masked();
+   init_c_cliptest_raw();
+   init_copy0_raw();
+   init_copy0_masked();
+   init_dotprod_raw();
+   init_dotprod_masked();
+
+#ifdef DEBUG
+   gl_test_all_transform_functions( "default" );
+   gl_test_all_normal_transform_functions( "default" );
+#endif
+
+#ifdef USE_X86_ASM
+   gl_init_all_x86_transform_asm();
+#endif
+}
+
+void
+_math_init( void )
+{
+   _math_init_transformation();
+   _math_init_translate();
+   _math_init_vertices();
+}
diff --git a/src/mesa/math/m_xform.h b/src/mesa/math/m_xform.h
new file mode 100644 (file)
index 0000000..1c6ac46
--- /dev/null
@@ -0,0 +1,224 @@
+/* $Id: m_xform.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.3
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef _M_XFORM_H
+#define _M_XFORM_H
+
+
+#include "glheader.h"
+#include "config.h"
+#include "math/m_vector.h"
+#include "math/m_matrix.h"
+
+#ifdef USE_X86_ASM
+#define _XFORMAPI _ASMAPI
+#define _XFORMAPIP _ASMAPIP
+#else
+#define _XFORMAPI
+#define _XFORMAPIP *
+#endif
+
+/*
+ * Transform a point (column vector) by a matrix:   Q = M * P
+ */
+#define TRANSFORM_POINT( Q, M, P )                                     \
+   Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] *  P[2] + M[12] * P[3];     \
+   Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] *  P[2] + M[13] * P[3];     \
+   Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3];     \
+   Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3];
+
+
+#define TRANSFORM_POINT3( Q, M, P )                            \
+   Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] *  P[2] + M[12];    \
+   Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] *  P[2] + M[13];    \
+   Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14];    \
+   Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15];
+
+
+/*
+ * Transform a normal (row vector) by a matrix:  [NX NY NZ] = N * MAT
+ */
+#define TRANSFORM_NORMAL( TO, N, MAT )                         \
+do {                                                           \
+   TO[0] = N[0] * MAT[0] + N[1] * MAT[1] + N[2] * MAT[2];      \
+   TO[1] = N[0] * MAT[4] + N[1] * MAT[5] + N[2] * MAT[6];      \
+   TO[2] = N[0] * MAT[8] + N[1] * MAT[9] + N[2] * MAT[10];     \
+} while (0)
+
+
+extern void gl_transform_vector( GLfloat u[4],
+                                const GLfloat v[4],
+                                 const GLfloat m[16] );
+
+
+extern void gl_init_transformation( void );
+
+
+/* KW: Clip functions now do projective divide as well.  The projected
+ * coordinates are very useful to us because they let us cull
+ * backfaces and eliminate vertices from lighting, fogging, etc
+ * calculations.  Despite the fact that this divide could be done one
+ * day in hardware, we would still have a reason to want to do it here
+ * as long as those other calculations remain in software.
+ *
+ * Clipping is a convenient place to do the divide on x86 as it should be
+ * possible to overlap with integer outcode calculations.
+ *
+ * There are two cases where we wouldn't want to do the divide in cliptest:
+ *    - When we aren't clipping.  We still might want to cull backfaces
+ *      so the divide should be done elsewhere.  This currently never 
+ *      happens.
+ *
+ *    - When culling isn't likely to help us, such as when the GL culling
+ *      is disabled and we not lighting or are only lighting
+ *      one-sided.  In this situation, backface determination provides
+ *      us with no useful information.  A tricky case to detect is when
+ *      all input data is already culled, although hopefully the
+ *      application wouldn't turn on culling in such cases.
+ *
+ * We supply a buffer to hold the [x/w,y/w,z/w,1/w] values which
+ * are the result of the projection.  This is only used in the 
+ * 4-vector case - in other cases, we just use the clip coordinates
+ * as the projected coordinates - they are identical.
+ * 
+ * This is doubly convenient because it means the Win[] array is now
+ * of the same stride as all the others, so I can now turn map_vertices
+ * into a straight-forward matrix transformation, with asm acceleration
+ * automatically available.  
+ */
+
+/* Vertex buffer clipping flags 
+ */
+#define CLIP_RIGHT_SHIFT       0
+#define CLIP_LEFT_SHIFT        1
+#define CLIP_TOP_SHIFT         2
+#define CLIP_BOTTOM_SHIFT       3
+#define CLIP_NEAR_SHIFT        4
+#define CLIP_FAR_SHIFT         5
+
+#define CLIP_RIGHT_BIT   0x01
+#define CLIP_LEFT_BIT    0x02
+#define CLIP_TOP_BIT     0x04
+#define CLIP_BOTTOM_BIT  0x08
+#define CLIP_NEAR_BIT    0x10
+#define CLIP_FAR_BIT     0x20
+#define CLIP_USER_BIT    0x40
+#define CLIP_CULLED_BIT  0x80  /* Vertex has been culled */
+#define CLIP_ALL_BITS    0x3f
+
+
+typedef GLvector4f * (_XFORMAPIP clip_func)( GLvector4f *vClip,
+                                 GLvector4f *vProj, 
+                                 GLubyte clipMask[],
+                                 GLubyte *orMask, 
+                                 GLubyte *andMask );
+
+typedef void (*dotprod_func)( GLvector4f *out_vec, 
+                             GLuint elt,
+                             const GLvector4f *coord_vec, 
+                             const GLfloat plane[4], 
+                             const GLubyte mask[]);
+
+typedef void (*vec_copy_func)( GLvector4f *to, 
+                              const GLvector4f *from, 
+                              const GLubyte mask[]);
+
+
+
+/*
+ * Functions for transformation of normals in the VB.
+ */
+typedef void (_NORMAPIP normal_func)( const GLmatrix *mat,
+                            GLfloat scale,
+                            const GLvector3f *in,
+                            const GLfloat lengths[],
+                            const GLubyte mask[],
+                            GLvector3f *dest );
+
+
+/* Flags for selecting a normal transformation function. 
+ */
+#define NORM_RESCALE   0x1     /* apply the scale factor */
+#define NORM_NORMALIZE 0x2     /* normalize */
+#define NORM_TRANSFORM 0x4     /* apply the transformation matrix */
+#define NORM_TRANSFORM_NO_ROT 0x8      /* apply the transformation matrix */
+
+
+
+
+/* KW: New versions of the transform function allow a mask array
+ *     specifying that individual vector transform should be skipped
+ *     when the mask byte is zero.  This is always present as a
+ *     parameter, to allow a unified interface.  
+ */
+typedef void (_XFORMAPIP transform_func)( GLvector4f *to_vec,
+                                         const GLfloat m[16],
+                               const GLvector4f *from_vec, 
+                               const GLubyte *clipmask,
+                               const GLubyte flag );
+
+
+extern GLvector4f *gl_project_points( GLvector4f *to,
+                              const GLvector4f *from );
+
+extern void gl_transform_bounds3( GLubyte *orMask, GLubyte *andMask,
+                                 const GLfloat m[16],
+                          CONST GLfloat src[][3] );
+
+extern void gl_transform_bounds2( GLubyte *orMask, GLubyte *andMask,
+                                 const GLfloat m[16],
+                          CONST GLfloat src[][3] );
+
+
+extern dotprod_func  gl_dotprod_tab[2][5];
+extern vec_copy_func gl_copy_tab[2][0x10];
+extern clip_func     gl_clip_tab[5];
+extern normal_func   gl_normal_tab[0xf][0x4];
+
+/* Use of 3 layers of linked 1-dimensional arrays to reduce
+ * cost of lookup.
+ */
+extern transform_func **(gl_transform_tab[2]);
+
+
+extern void gl_transform_point_sz( GLfloat Q[4], const GLfloat M[16],
+                                  const GLfloat P[4], GLuint sz );
+
+
+#define TransformRaw( to, mat, from ) \
+      ( (*gl_transform_tab[0][(from)->size][(mat)->type])( to, (mat)->m, from, 0, 0 ), \
+        (to) )
+
+#define Transform( to, mat, from, mask, cull ) \
+      ( (*gl_transform_tab[cull!=0][(from)->size][(mat)->type])( to, (mat)->m, from, mask, cull ), \
+       (to) )
+
+
+#endif
diff --git a/src/mesa/math/m_xform_tmp.h b/src/mesa/math/m_xform_tmp.h
new file mode 100644 (file)
index 0000000..289255a
--- /dev/null
@@ -0,0 +1,974 @@
+/* $Id: m_xform_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ *
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * New (3.1) transformation code written by Keith Whitwell.
+ */
+
+
+/*----------------------------------------------------------------------
+ * Begin Keith's new code
+ *
+ *----------------------------------------------------------------------
+ */
+
+/* KW: Fixed stride, now measured in bytes as is the OpenGL array stride.
+ */
+
+/* KW: These are now parameterized to produce two versions, one
+ *     which transforms all incoming points, and a second which
+ *     takes notice of a cullmask array, and only transforms
+ *     unculled vertices.
+ */
+
+/* KW: 1-vectors can sneak into the texture pipeline via the array
+ *     interface.  These functions are here because I want consistant
+ *     treatment of the vertex sizes and a lazy strategy for
+ *     cleaning unused parts of the vector, and so as not to exclude
+ *     them from the vertex array interface.
+ *
+ *     Under our current analysis of matrices, there is no way that
+ *     the product of a matrix and a 1-vector can remain a 1-vector,
+ *     with the exception of the identity transform.
+ */
+
+/* KW: No longer zero-pad outgoing vectors.  Now that external
+ *     vectors can get into the pipeline we cannot ever assume
+ *     that there is more to a vector than indicated by its
+ *     size.
+ */
+
+/* KW: Now uses clipmask and a flag to allow us to skip both/either
+ *     cliped and/or culled vertices.
+ */
+
+static void _XFORMAPI
+TAG(transform_points1_general)( GLvector4f *to_vec,
+                               const GLfloat m[16],
+                                           const GLvector4f *from_vec,
+                                           const GLubyte *mask,
+                                           const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0],  m12 = m[12];
+   const GLfloat m1 = m[1],  m13 = m[13];
+   const GLfloat m2 = m[2],  m14 = m[14];
+   const GLfloat m3 = m[3],  m15 = m[15];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0];
+        to[i][0] = m0 * ox + m12;
+        to[i][1] = m1 * ox + m13;
+        to[i][2] = m2 * ox + m14;
+        to[i][3] = m3 * ox + m15;
+      }
+   }
+
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points1_identity)( GLvector4f *to_vec,
+                                const GLfloat m[16],
+                                            const GLvector4f *from_vec,
+                                            const GLubyte *mask,
+                                            const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLuint count = from_vec->count;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   if (to_vec == from_vec) return;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        to[i][0] = from[0];
+      }
+   }
+
+   to_vec->size = 1;
+   to_vec->flags |= VEC_SIZE_1;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points1_2d)( GLvector4f *to_vec,
+                          const GLfloat m[16],
+                                      const GLvector4f *from_vec,
+                                      const GLubyte *mask,
+                                      const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m1 = m[1];
+   const GLfloat m12 = m[12], m13 = m[13];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0];
+        to[i][0] = m0 * ox + m12;
+        to[i][1] = m1 * ox + m13;
+      }
+   }
+   to_vec->size = 2;
+   to_vec->flags |= VEC_SIZE_2;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points1_2d_no_rot)( GLvector4f *to_vec,
+                                 const GLfloat m[16],
+                                             const GLvector4f *from_vec,
+                                             const GLubyte *mask,
+                                             const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m12 = m[12], m13 = m[13];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0];
+        to[i][0] = m0 * ox + m12;
+        to[i][1] =           m13;
+      }
+   }
+
+   to_vec->size = 2;
+   to_vec->flags |= VEC_SIZE_2;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points1_3d)( GLvector4f *to_vec,
+                          const GLfloat m[16],
+                                      const GLvector4f *from_vec,
+                                      const GLubyte *mask,
+                                      const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m1 = m[1], m2 = m[2];
+   const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0];
+        to[i][0] = m0 * ox + m12;
+        to[i][1] = m1 * ox + m13;
+        to[i][2] = m2 * ox + m14;
+      }
+   }
+   to_vec->size = 3;
+   to_vec->flags |= VEC_SIZE_3;
+   to_vec->count = from_vec->count;
+}
+
+
+static void _XFORMAPI
+TAG(transform_points1_3d_no_rot)( GLvector4f *to_vec,
+                                 const GLfloat m[16],
+                                             const GLvector4f *from_vec,
+                                             const GLubyte *mask,
+                                             const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0];
+   const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0];
+        to[i][0] = m0 * ox           + m12;
+        to[i][1] =                     m13;
+        to[i][2] =                     m14;
+      }
+   }
+   to_vec->size = 3;
+   to_vec->flags |= VEC_SIZE_3;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points1_perspective)( GLvector4f *to_vec,
+                                   const GLfloat m[16],
+                                               const GLvector4f *from_vec,
+                                               const GLubyte *mask,
+                                               const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0];
+        to[i][0] = m0 * ox                ;
+        to[i][1] =           0            ;
+        to[i][2] =                     m14;
+        to[i][3] = 0;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+
+
+
+/* 2-vectors, which are a lot more relevant than 1-vectors, are
+ * present early in the geometry pipeline and throughout the
+ * texture pipeline.
+ */
+static void _XFORMAPI
+TAG(transform_points2_general)( GLvector4f *to_vec,
+                               const GLfloat m[16],
+                                           const GLvector4f *from_vec,
+                                           const GLubyte *mask,
+                                           const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0],  m4 = m[4],  m12 = m[12];
+   const GLfloat m1 = m[1],  m5 = m[5],  m13 = m[13];
+   const GLfloat m2 = m[2],  m6 = m[6],  m14 = m[14];
+   const GLfloat m3 = m[3],  m7 = m[7],  m15 = m[15];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1];
+        to[i][0] = m0 * ox + m4 * oy + m12;
+        to[i][1] = m1 * ox + m5 * oy + m13;
+        to[i][2] = m2 * ox + m6 * oy + m14;
+        to[i][3] = m3 * ox + m7 * oy + m15;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points2_identity)( GLvector4f *to_vec,
+                                const GLfloat m[16],
+                                            const GLvector4f *from_vec,
+                                            const GLubyte *mask,
+                                            const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   if (to_vec == from_vec) return;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        to[i][0] = from[0];
+        to[i][1] = from[1];
+      }
+   }
+   to_vec->size = 2;
+   to_vec->flags |= VEC_SIZE_2;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points2_2d)( GLvector4f *to_vec,
+                          const GLfloat m[16],
+                                      const GLvector4f *from_vec,
+                                      const GLubyte *mask,
+                                      const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
+   const GLfloat m12 = m[12], m13 = m[13];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1];
+        to[i][0] = m0 * ox + m4 * oy + m12;
+        to[i][1] = m1 * ox + m5 * oy + m13;
+      }
+   }
+
+   to_vec->size = 2;
+   to_vec->flags |= VEC_SIZE_2;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points2_2d_no_rot)( GLvector4f *to_vec,
+                                 const GLfloat m[16],
+                                             const GLvector4f *from_vec,
+                                             const GLubyte *mask,
+                                             const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1];
+        to[i][0] = m0 * ox           + m12;
+        to[i][1] =           m5 * oy + m13;
+      }
+   }
+
+   to_vec->size = 2;
+   to_vec->flags |= VEC_SIZE_2;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points2_3d)( GLvector4f *to_vec,
+                          const GLfloat m[16],
+                                      const GLvector4f *from_vec,
+                                      const GLubyte *mask,
+                                      const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
+   const GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1];
+        to[i][0] = m0 * ox + m4 * oy + m12;
+        to[i][1] = m1 * ox + m5 * oy + m13;
+        to[i][2] = m2 * ox + m6 * oy + m14;
+      }
+   }
+   to_vec->size = 3;
+   to_vec->flags |= VEC_SIZE_3;
+   to_vec->count = from_vec->count;
+}
+
+
+/* I would actually say this was a fairly important function, from
+ * a texture transformation point of view.
+ */
+static void _XFORMAPI
+TAG(transform_points2_3d_no_rot)( GLvector4f *to_vec,
+                                 const GLfloat m[16],
+                                             const GLvector4f *from_vec,
+                                             const GLubyte *mask,
+                                             const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5];
+   const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1];
+        to[i][0] = m0 * ox           + m12;
+        to[i][1] =           m5 * oy + m13;
+        to[i][2] =                     m14;
+      }
+   }
+   if (m14 == 0) {
+      to_vec->size = 2;
+      to_vec->flags |= VEC_SIZE_2;
+   } else {
+      to_vec->size = 3;
+      to_vec->flags |= VEC_SIZE_3;
+   }
+   to_vec->count = from_vec->count;
+}
+
+/* This may not be called too often, but I wouldn't say it was dead
+ * code.  It's also hard to remove any of these functions if you are
+ * attached to the assertions that have appeared in them.
+ */
+static void _XFORMAPI
+TAG(transform_points2_perspective)( GLvector4f *to_vec,
+                                   const GLfloat m[16],
+                                               const GLvector4f *from_vec,
+                                               const GLubyte *mask,
+                                               const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1];
+        to[i][0] = m0 * ox                ;
+        to[i][1] =           m5 * oy      ;
+        to[i][2] =                     m14;
+        to[i][3] = 0;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+
+
+static void _XFORMAPI
+TAG(transform_points3_general)( GLvector4f *to_vec,
+                               const GLfloat m[16],
+                                           const GLvector4f *from_vec,
+                                           const GLubyte *mask,
+                                           const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
+   const GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
+   const GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
+   const GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2];
+        to[i][0] = m0 * ox + m4 * oy + m8  * oz + m12;
+        to[i][1] = m1 * ox + m5 * oy + m9  * oz + m13;
+        to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14;
+        to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points3_identity)( GLvector4f *to_vec,
+                                const GLfloat m[16],
+                                            const GLvector4f *from_vec,
+                                            const GLubyte *mask,
+                                            const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   if (to_vec == from_vec) return;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        to[i][0] = from[0];
+        to[i][1] = from[1];
+        to[i][2] = from[2];
+      }
+   }
+   to_vec->size = 3;
+   to_vec->flags |= VEC_SIZE_3;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points3_2d)( GLvector4f *to_vec,
+                          const GLfloat m[16],
+                                      const GLvector4f *from_vec,
+                                      const GLubyte *mask,
+                                      const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
+   const GLfloat m12 = m[12], m13 = m[13];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2];
+        to[i][0] = m0 * ox + m4 * oy            + m12       ;
+        to[i][1] = m1 * ox + m5 * oy            + m13       ;
+        to[i][2] =                   +       oz             ;
+      }
+   }
+   to_vec->size = 3;
+   to_vec->flags |= VEC_SIZE_3;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points3_2d_no_rot)( GLvector4f *to_vec,
+                                 const GLfloat m[16],
+                                             const GLvector4f *from_vec,
+                                             const GLubyte *mask,
+                                             const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2];
+        to[i][0] = m0 * ox                      + m12       ;
+        to[i][1] =           m5 * oy            + m13       ;
+        to[i][2] =                   +       oz             ;
+      }
+   }
+   to_vec->size = 3;
+   to_vec->flags |= VEC_SIZE_3;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points3_3d)( GLvector4f *to_vec,
+                          const GLfloat m[16],
+                                      const GLvector4f *from_vec,
+                                      const GLubyte *mask,
+                                      const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
+   const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
+   const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2];
+        to[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12       ;
+        to[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13       ;
+        to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14       ;
+      }
+   }
+   to_vec->size = 3;
+   to_vec->flags |= VEC_SIZE_3;
+   to_vec->count = from_vec->count;
+}
+
+/* previously known as ortho...
+ */
+static void _XFORMAPI
+TAG(transform_points3_3d_no_rot)( GLvector4f *to_vec,
+                                 const GLfloat m[16],
+                                             const GLvector4f *from_vec,
+                                             const GLubyte *mask,
+                                             const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5];
+   const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2];
+        to[i][0] = m0 * ox                      + m12       ;
+        to[i][1] =           m5 * oy            + m13       ;
+        to[i][2] =                     m10 * oz + m14       ;
+      }
+   }
+   to_vec->size = 3;
+   to_vec->flags |= VEC_SIZE_3;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points3_perspective)( GLvector4f *to_vec,
+                                   const GLfloat m[16],
+                                               const GLvector4f *from_vec,
+                                               const GLubyte *mask,
+                                               const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9];
+   const GLfloat m10 = m[10], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2];
+        to[i][0] = m0 * ox           + m8  * oz       ;
+        to[i][1] =           m5 * oy + m9  * oz       ;
+        to[i][2] =                     m10 * oz + m14 ;
+        to[i][3] =                          -oz       ;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+
+
+static void _XFORMAPI
+TAG(transform_points4_general)( GLvector4f *to_vec,
+                               const GLfloat m[16],
+                                           const GLvector4f *from_vec,
+                                           const GLubyte *mask,
+                                           const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
+   const GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
+   const GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
+   const GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
+        to[i][0] = m0 * ox + m4 * oy + m8  * oz + m12 * ow;
+        to[i][1] = m1 * ox + m5 * oy + m9  * oz + m13 * ow;
+        to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
+        to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points4_identity)( GLvector4f *to_vec,
+                                const GLfloat m[16],
+                                            const GLvector4f *from_vec,
+                                            const GLubyte *mask,
+                                            const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   if (to_vec == from_vec) return;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        to[i][0] = from[0];
+        to[i][1] = from[1];
+        to[i][2] = from[2];
+        to[i][3] = from[3];
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points4_2d)( GLvector4f *to_vec,
+                          const GLfloat m[16],
+                                      const GLvector4f *from_vec,
+                                      const GLubyte *mask,
+                                      const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
+   const GLfloat m12 = m[12], m13 = m[13];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
+        to[i][0] = m0 * ox + m4 * oy            + m12 * ow;
+        to[i][1] = m1 * ox + m5 * oy            + m13 * ow;
+        to[i][2] =                   +       oz           ;
+        to[i][3] =                                      ow;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points4_2d_no_rot)( GLvector4f *to_vec,
+                                 const GLfloat m[16],
+                                             const GLvector4f *from_vec,
+                                             const GLubyte *mask,
+                                             const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
+        to[i][0] = m0 * ox                      + m12 * ow;
+        to[i][1] =           m5 * oy            + m13 * ow;
+        to[i][2] =                   +       oz           ;
+        to[i][3] =                                      ow;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points4_3d)( GLvector4f *to_vec,
+                          const GLfloat m[16],
+                                      const GLvector4f *from_vec,
+                                      const GLubyte *mask,
+                                      const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
+   const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
+   const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
+        to[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12 * ow;
+        to[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13 * ow;
+        to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
+        to[i][3] =                                      ow;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points4_3d_no_rot)( GLvector4f *to_vec,
+                                 const GLfloat m[16],
+                                             const GLvector4f *from_vec,
+                                             const GLubyte *mask,
+                                             const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5];
+   const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
+        to[i][0] = m0 * ox                      + m12 * ow;
+        to[i][1] =           m5 * oy            + m13 * ow;
+        to[i][2] =                     m10 * oz + m14 * ow;
+        to[i][3] =                                      ow;
+      }
+   }
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static void _XFORMAPI
+TAG(transform_points4_perspective)( GLvector4f *to_vec,
+                                   const GLfloat m[16],
+                                               const GLvector4f *from_vec,
+                                               const GLubyte *mask,
+                                               const GLubyte flag )
+{
+   const GLuint stride = from_vec->stride;
+   GLfloat *from = from_vec->start;
+   GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
+   GLuint count = from_vec->count;
+   const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9];
+   const GLfloat m10 = m[10], m14 = m[14];
+   GLuint i;
+   (void) mask;
+   (void) flag;
+   STRIDE_LOOP {
+      CLIP_CHECK {
+        const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
+        to[i][0] = m0 * ox           + m8  * oz            ;
+        to[i][1] =           m5 * oy + m9  * oz            ;
+        to[i][2] =                     m10 * oz + m14 * ow ;
+        to[i][3] =                          -oz            ;
+      }
+   }
+
+   to_vec->size = 4;
+   to_vec->flags |= VEC_SIZE_4;
+   to_vec->count = from_vec->count;
+}
+
+static transform_func _XFORMAPI TAG(transform_tab_1)[7];
+static transform_func _XFORMAPI TAG(transform_tab_2)[7];
+static transform_func _XFORMAPI TAG(transform_tab_3)[7];
+static transform_func _XFORMAPI TAG(transform_tab_4)[7];
+
+/* Similar functions could be called several times, with more highly
+ * optimized routines overwriting the arrays.  This only occurs during
+ * startup.
+ */
+static void _XFORMAPI TAG(init_c_transformations)( void )
+{
+#define TAG_TAB   gl_transform_tab[IDX]
+#define TAG_TAB_1 TAG(transform_tab_1)
+#define TAG_TAB_2 TAG(transform_tab_2)
+#define TAG_TAB_3 TAG(transform_tab_3)
+#define TAG_TAB_4 TAG(transform_tab_4)
+
+   TAG_TAB[1] = TAG_TAB_1;
+   TAG_TAB[2] = TAG_TAB_2;
+   TAG_TAB[3] = TAG_TAB_3;
+   TAG_TAB[4] = TAG_TAB_4;
+
+   /* 1-D points (ie texcoords) */
+   TAG_TAB_1[MATRIX_GENERAL]     = TAG(transform_points1_general);
+   TAG_TAB_1[MATRIX_IDENTITY]    = TAG(transform_points1_identity);
+   TAG_TAB_1[MATRIX_3D_NO_ROT]   = TAG(transform_points1_3d_no_rot);
+   TAG_TAB_1[MATRIX_PERSPECTIVE] = TAG(transform_points1_perspective) ;
+   TAG_TAB_1[MATRIX_2D]          = TAG(transform_points1_2d);
+   TAG_TAB_1[MATRIX_2D_NO_ROT]   = TAG(transform_points1_2d_no_rot);
+   TAG_TAB_1[MATRIX_3D]          = TAG(transform_points1_3d);
+
+   /* 2-D points */
+   TAG_TAB_2[MATRIX_GENERAL]     = TAG(transform_points2_general);
+   TAG_TAB_2[MATRIX_IDENTITY]    = TAG(transform_points2_identity);
+   TAG_TAB_2[MATRIX_3D_NO_ROT]   = TAG(transform_points2_3d_no_rot);
+   TAG_TAB_2[MATRIX_PERSPECTIVE] = TAG(transform_points2_perspective) ;
+   TAG_TAB_2[MATRIX_2D]          = TAG(transform_points2_2d);
+   TAG_TAB_2[MATRIX_2D_NO_ROT]   = TAG(transform_points2_2d_no_rot);
+   TAG_TAB_2[MATRIX_3D]          = TAG(transform_points2_3d);
+
+   /* 3-D points */
+   TAG_TAB_3[MATRIX_GENERAL]     = TAG(transform_points3_general);
+   TAG_TAB_3[MATRIX_IDENTITY]    = TAG(transform_points3_identity);
+   TAG_TAB_3[MATRIX_3D_NO_ROT]   = TAG(transform_points3_3d_no_rot);
+   TAG_TAB_3[MATRIX_PERSPECTIVE] = TAG(transform_points3_perspective);
+   TAG_TAB_3[MATRIX_2D]          = TAG(transform_points3_2d);
+   TAG_TAB_3[MATRIX_2D_NO_ROT]   = TAG(transform_points3_2d_no_rot);
+   TAG_TAB_3[MATRIX_3D]          = TAG(transform_points3_3d);
+
+   /* 4-D points */
+   TAG_TAB_4[MATRIX_GENERAL]     = TAG(transform_points4_general);
+   TAG_TAB_4[MATRIX_IDENTITY]    = TAG(transform_points4_identity);
+   TAG_TAB_4[MATRIX_3D_NO_ROT]   = TAG(transform_points4_3d_no_rot);
+   TAG_TAB_4[MATRIX_PERSPECTIVE] = TAG(transform_points4_perspective);
+   TAG_TAB_4[MATRIX_2D]          = TAG(transform_points4_2d);
+   TAG_TAB_4[MATRIX_2D_NO_ROT]   = TAG(transform_points4_2d_no_rot);
+   TAG_TAB_4[MATRIX_3D]          = TAG(transform_points4_3d);
+
+#undef TAG_TAB
+}
index f11186baedf618b525dd96a05bc2052fc8ac984b..c5f4127c2e28ca7bdf0908b7722d49273794b727 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_bitmap.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */
+/* $Id: s_bitmap.c,v 1.3 2000/11/16 21:05:41 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -56,11 +56,6 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
    if (SWRAST_CONTEXT(ctx)->NewState)
       _swrast_validate_derived( ctx );
 
-   if (PB->primitive != GL_BITMAP) {
-      gl_flush_pb( ctx );
-      PB->primitive = GL_BITMAP;
-   }
-
    /* Set bitmap drawing color */
    if (ctx->Visual.RGBAflag) {
       GLint r, g, b, a;
index e460a77f18183a6b900b7f00d80a23a70366dcdf..a16fe9ecf8aa1f17a982720324939511dfcff634 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_lines.c,v 1.5 2000/11/13 20:02:57 keithw Exp $ */
+/* $Id: s_lines.c,v 1.6 2000/11/16 21:05:41 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -28,7 +28,6 @@
 #include "glheader.h"
 #include "macros.h"
 #include "mmath.h"
-#include "vb.h"
 #include "s_aaline.h"
 #include "s_pb.h"
 #include "s_context.h"
index 5c30c5f5a21aa7b5853542b62c73c713601a0a84..e6f193f55582b3ac17418461ec54d8b0e454e895 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_points.c,v 1.5 2000/11/15 16:38:40 brianp Exp $ */
+/* $Id: s_points.c,v 1.6 2000/11/16 21:05:41 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -30,7 +30,6 @@
 #include "macros.h"
 #include "mmath.h"
 #include "texstate.h"
-#include "vb.h"
 
 #include "s_context.h"
 #include "s_feedback.h"
index 10942037a3a7871cb4a655d388debbad56d73ed4..e58abdc6c5568607125590fc19b031b53e91ba4a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ss_context.c,v 1.3 2000/11/13 20:02:58 keithw Exp $ */
+/* $Id: ss_context.c,v 1.4 2000/11/16 21:05:42 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -38,6 +38,7 @@
 
 #include "swrast_setup.h"
 
+#include "tnl/t_context.h"
 
 /* Stub for swsetup->Triangle to select a true triangle function 
  * after a state change.
index ab70f5c97bcf8e5055ac274ea5b6a13dae7bd967..9bcf13c3ed21b8c7cb3e84ed76449d8e757e7f2c 100644 (file)
@@ -29,6 +29,8 @@
 #include "macros.h"
 #include "types.h"
 
+#include "tnl/t_context.h"
+
 #include "ss_triangle.h"
 #include "ss_context.h"
 
index 37b566422520648487de3a70dac06503c859264b..054fcf9eb7f6899cf6391f891b488e9f35324ec1 100644 (file)
@@ -30,7 +30,7 @@ static void TAG(triangle)(GLcontext *ctx,
                          GLuint e0, GLuint e1, GLuint e2,
                          GLuint pv)
 {
-   struct vertex_buffer *VB = ctx->VB;
+   struct vertex_buffer *VB = TNL_VB(ctx);
    SWvertex *verts = SWSETUP_VB(VB)->verts;
    SWvertex *v[3];
    GLfloat offset;
@@ -224,7 +224,7 @@ static void TAG(quad)( GLcontext *ctx, GLuint v0,
 
 static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
 {
-   struct vertex_buffer *VB = ctx->VB;
+   struct vertex_buffer *VB = TNL_VB(ctx);
    SWvertex *verts = SWSETUP_VB(VB)->verts;
    GLubyte c[2][4], s[2][4];
    GLuint i[2];
@@ -264,7 +264,7 @@ static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
 
 static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
 {
-   struct vertex_buffer *VB = ctx->VB;
+   struct vertex_buffer *VB = TNL_VB(ctx);
    SWvertex *verts = SWSETUP_VB(VB)->verts;
    int i;
    
index 15e6049cb513926e4815df8ccd4ac95b8ec9ddcb..ff1916174b7fc6151269fd12c48551b2330718cd 100644 (file)
 
 #include "glheader.h"
 #include "macros.h"
-#include "stages.h"
 
 #include "swrast/swrast.h"
 
+#include "tnl/t_context.h"
+#include "tnl/t_stages.h"
+
+#include "math/m_vector.h"
 #include "ss_context.h"
 #include "ss_vb.h"
 
index 53fe5bcae668c7cc22f14d92a48b9e6b75524a48..47b30055000983fedf98b36cec444673907d3b9e 100644 (file)
@@ -29,6 +29,7 @@
 static void TAG(rs)(struct vertex_buffer *VB, GLuint start, GLuint end)
 {
    GLcontext *ctx = VB->ctx;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
    SWvertex *v;
    GLfloat (*eye)[4];
    GLfloat (*win)[4];
@@ -54,7 +55,7 @@ static void TAG(rs)(struct vertex_buffer *VB, GLuint start, GLuint end)
 
    /* TODO:  Get import_client_data to pad vectors out to 4 cleanly.
     */
-   gl_import_client_data( VB, ctx->_RenderFlags,
+   gl_import_client_data( VB, tnl->_RenderFlags,
                          (VB->ClipOrMask
                           ? /*  VEC_CLEAN| */VEC_WRITABLE|VEC_GOOD_STRIDE
                           : /*  VEC_CLEAN| */VEC_GOOD_STRIDE));
diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
new file mode 100644 (file)
index 0000000..bab6326
--- /dev/null
@@ -0,0 +1,201 @@
+#include "types.h"
+#include "mem.h"
+
+#include "t_context.h"
+#include "t_clip.h"
+#include "t_cva.h"
+#include "t_dlist.h"
+#include "t_eval.h"
+#include "t_pipeline.h"
+#include "t_shade.h"
+#include "t_light.h"
+#include "t_texture.h"
+#include "t_stages.h"
+#include "t_varray.h"
+#include "t_vb.h"
+#include "t_vbrender.h"
+#include "t_vbxform.h"
+#include "tnl.h"
+
+#if !defined(THREADS)
+struct immediate *_mesa_CurrentInput = NULL;
+#endif
+
+
+GLboolean 
+_tnl_flush_vertices( GLcontext *ctx, GLuint flush_flags )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct immediate *IM = TNL_CURRENT_IM(ctx);
+
+   if ((IM->Flag[IM->Count] & (VERT_BEGIN|VERT_END)) != VERT_END ||
+       (flush_flags & (FLUSH_STORED_VERTICES|FLUSH_UPDATE_CURRENT))) 
+   {
+      if (IM->Flag[IM->Start]) 
+        _mesa_flush_vb( ctx );
+      
+      /* Although this code updates the ctx->Current values, that bit
+       * is left set as there is no easy mechanism to set it
+       * elsewhere.  This means that each time core wants to examine
+       * ctx->Current, this function will be called.  After the first
+       * time, however, it will be a no-op.
+       */
+      ctx->Driver.NeedFlush &= ~(FLUSH_STORED_VERTICES |
+                                FLUSH_INSIDE_BEGIN_END);
+
+      return (tnl->_CurrentPrimitive == GL_POLYGON+1);
+   }
+   else
+      return GL_TRUE;
+}
+
+
+GLboolean
+_tnl_CreateContext( GLcontext *ctx )
+{
+   TNLcontext *tnl;
+   static int firsttime = 1;
+
+   /* Onetime initializations.  Doesn't really matter if this gets
+    * done twice: no need for mutexes. 
+    */
+   if (firsttime) {
+      firsttime = 0;
+      _tnl_clip_init( );
+      _tnl_eval_init( );
+      _tnl_shade_init( );
+      _tnl_texture_init( );
+      _tnl_trans_elt_init( );
+      _tnl_vbrender_init( );
+      _tnl_stages_init( );
+   }
+
+   /* Create the TNLcontext structure
+    */
+   ctx->swtnl_context = tnl = CALLOC( sizeof(TNLcontext) );
+   if (!tnl) {
+      return GL_FALSE;
+   }
+
+   /* Create and hook in the data structures available from ctx.
+    */
+   ctx->swtnl_vb = (void *)gl_vb_create_for_immediate( ctx );
+   if (!ctx->swtnl_vb) {
+      FREE(tnl);
+      ctx->swtnl_context = 0;
+      return GL_FALSE;
+   }
+
+   ctx->swtnl_im = (void *)TNL_VB(ctx)->IM;
+
+   
+   /* Initialize tnl state.
+    */
+   _tnl_dlist_init( ctx );
+   _tnl_pipeline_init( ctx );
+
+   tnl->_CurrentFlag = (VERT_NORM |
+                        VERT_INDEX |
+                        VERT_RGBA |
+                        VERT_SPEC_RGB |
+                        VERT_FOG_COORD |
+                        VERT_EDGE |
+                        VERT_TEX0_12 |
+                        VERT_TEX1_12 |
+                        VERT_TEX2_12 |
+                        VERT_TEX3_12 |
+                        VERT_MATERIAL);
+
+   tnl->_CurrentPrimitive = GL_POLYGON+1;
+
+   gl_reset_vb( TNL_VB(ctx) );
+   gl_reset_input( ctx );
+
+
+   /* Set a few default values in the driver struct.  This is a
+    * temporary mechanism.  
+    */
+   ctx->Driver.RenderVBCulledTab = _tnl_render_tab_cull;
+   ctx->Driver.RenderVBClippedTab = _tnl_render_tab_clipped;
+   ctx->Driver.RenderVBRawTab = _tnl_render_tab_raw;
+   ctx->Driver.NewList = _tnl_NewList;
+   ctx->Driver.EndList = _tnl_EndList;
+   ctx->Driver.FlushVertices = _tnl_flush_vertices;
+   ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT;
+   ctx->Driver.LightingSpaceChange = _tnl_LightingSpaceChange;
+   ctx->Driver.MakeCurrent = _tnl_MakeCurrent;
+   ctx->Driver.VertexPointer = _tnl_VertexPointer;
+   ctx->Driver.NormalPointer = _tnl_NormalPointer;
+   ctx->Driver.ColorPointer = _tnl_ColorPointer;
+   ctx->Driver.FogCoordPointer = _tnl_FogCoordPointer;
+   ctx->Driver.IndexPointer = _tnl_IndexPointer;
+   ctx->Driver.SecondaryColorPointer = _tnl_SecondaryColorPointer;
+   ctx->Driver.TexCoordPointer = _tnl_TexCoordPointer;
+   ctx->Driver.EdgeFlagPointer = _tnl_EdgeFlagPointer;
+
+   return GL_TRUE;
+}
+
+
+void
+_tnl_DestroyContext( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+   if (TNL_CURRENT_IM(ctx) != TNL_VB(ctx)->IM)
+      gl_immediate_free( TNL_CURRENT_IM(ctx) );
+
+   gl_vb_free( TNL_VB(ctx) );
+
+   /* Free cache of immediate buffers. */
+   while (tnl->nr_im_queued-- > 0) {
+      struct immediate * next = tnl->freed_im_queue->next;
+      ALIGN_FREE( tnl->freed_im_queue );
+      tnl->freed_im_queue = next;
+   }
+}
+
+
+/* Update all state that references _NeedEyeCoords 
+ */
+void
+_tnl_LightingSpaceChange( GLcontext *ctx )
+{
+   _tnl_update_normal_transform( ctx ); 
+}
+
+
+void 
+_tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
+{
+   if (new_state & _NEW_LIGHT)
+      gl_update_lighting_function(ctx);
+
+   if (new_state & _NEW_ARRAY)
+      gl_update_client_state( ctx );
+
+   if (new_state & _NEW_TEXTURE)
+      if (ctx->_Enabled & ENABLE_TEXGEN_ANY)
+        _tnl_update_texgen( ctx );
+      
+   if (new_state & (_NEW_LIGHT|_NEW_TEXTURE|_NEW_FOG|
+                   _DD_NEW_TRI_LIGHT_TWOSIDE |
+                   _DD_NEW_SEPERATE_SPECULAR |
+                   _DD_NEW_TRI_UNFILLED ))
+      gl_update_clipmask(ctx);
+
+   if (new_state & _TNL_NEW_NORMAL_TRANSFORM)
+      _tnl_update_normal_transform( ctx );
+
+   gl_update_pipelines(ctx);
+}
+
+void
+_tnl_MakeCurrent( GLcontext *ctx, 
+                 GLframebuffer *drawBuffer, 
+                 GLframebuffer *readBuffer )
+{
+#ifndef THREADS
+   SET_IMMEDIATE(newCtx, newCtx->input);
+#endif
+}
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
new file mode 100644 (file)
index 0000000..992c2a5
--- /dev/null
@@ -0,0 +1,629 @@
+
+/* $Id: t_context.h,v 1.1 2000/11/16 21:05:42 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _T_CONTEXT_H
+#define _T_CONTEXT_H
+
+#include "glheader.h"
+#include "types.h"
+
+#include "math/m_matrix.h"
+#include "math/m_vector.h"
+#include "math/m_xform.h"
+
+#include "t_trans_elt.h"
+
+
+
+/*
+ * Bits to indicate which faces a vertex participates in,
+ * what facing the primitive provoked by that vertex has,
+ * and some misc. flags.
+ */
+#define VERT_FACE_FRONT       0x1      /* is in a front-color primitive */
+#define VERT_FACE_REAR        0x2      /* is in a rear-color primitive */
+#define PRIM_FACE_FRONT       0x4      /* use front color */
+#define PRIM_FACE_REAR        0x8      /* use rear color */
+#define PRIM_CLIPPED          0x10     /* needs clipping */
+#define PRIM_USER_CLIPPED     CLIP_USER_BIT    /* 0x40 */
+
+
+#define PRIM_FLAG_SHIFT  2
+#define PRIM_FACE_FLAGS  (PRIM_FACE_FRONT|PRIM_FACE_REAR)
+#define VERT_FACE_FLAGS  (VERT_FACE_FRONT|VERT_FACE_REAR)
+
+#define PRIM_ANY_CLIP    (PRIM_CLIPPED|PRIM_USER_CLIPPED)
+#define PRIM_NOT_CULLED  (PRIM_ANY_CLIP|PRIM_FACE_FLAGS)
+
+/* Flags for VB->CullMode.
+ */
+#define CULL_MASK_ACTIVE  0x1
+#define COMPACTED_NORMALS 0x2
+#define CLIP_MASK_ACTIVE  0x4
+
+/* Flags for selecting a shading function.  The first two bits are
+ * shared with the cull mode (ie. cull_mask_active and
+ * compacted_normals.)
+ */
+#define SHADE_TWOSIDE           0x4
+
+
+/* KW: Flags that describe the current vertex state, and the contents
+ * of a vertex in a vertex-cassette.  
+ *
+ * For really major expansion, consider a 'VERT_ADDITIONAL_FLAGS' flag,
+ * which means there is data in another flags array (eg, extra_flags[]).
+ */
+
+#define VERT_OBJ_2           0x1       /* glVertex2 */
+#define VERT_OBJ_3           0x2        /* glVertex3 */
+#define VERT_OBJ_4           0x4        /* glVertex4 */
+#define VERT_BEGIN           0x8       /* glBegin */
+#define VERT_END             0x10      /* glEnd */
+#define VERT_ELT             0x20      /* glArrayElement */
+#define VERT_RGBA            0x40      /* glColor */
+#define VERT_NORM            0x80      /* glNormal */
+#define VERT_INDEX           0x100     /* glIndex */
+#define VERT_EDGE            0x200     /* glEdgeFlag */
+#define VERT_MATERIAL        0x400     /* glMaterial */
+#define VERT_END_VB          0x800     /* end vb marker */
+#define VERT_TEX0_12         0x1000       
+#define VERT_TEX0_3          0x2000
+#define VERT_TEX0_4          0x4000
+#define VERT_TEX1_12         0x8000
+#define VERT_TEX1_3          0x10000
+#define VERT_TEX1_4          0x20000
+#define VERT_TEX2_12         0x40000
+#define VERT_TEX2_3          0x80000
+#define VERT_TEX2_4          0x100000
+#define VERT_TEX3_12         0x200000
+#define VERT_TEX3_3          0x400000
+#define VERT_TEX3_4          0x800000
+#define VERT_EVAL_C1         0x1000000  /* could reuse OBJ bits for this? */
+#define VERT_EVAL_C2         0x2000000  /*    - or just use 3 bits */
+#define VERT_EVAL_P1         0x4000000  /*  */
+#define VERT_EVAL_P2         0x8000000  /*  */
+#define VERT_SPEC_RGB        0x10000000        
+#define VERT_FOG_COORD       0x20000000        /* internal use only, currently */
+
+#define VERT_EYE             VERT_BEGIN /* reuse */
+#define VERT_WIN             VERT_END   /* reuse */
+#define VERT_SETUP_FULL      VERT_EVAL_P1 /* Rastersetup has been done */
+#define VERT_PRECALC_DATA    VERT_END_VB /* reuse */
+
+/* Shorthands.
+ */
+#define VERT_TEX0_SHIFT 11
+
+#define VERT_EVAL_ANY      (VERT_EVAL_C1|VERT_EVAL_P1| \
+                            VERT_EVAL_C2|VERT_EVAL_P2)
+
+#define VERT_OBJ_23       (VERT_OBJ_3|VERT_OBJ_2)
+#define VERT_OBJ_234      (VERT_OBJ_4|VERT_OBJ_23)
+#define VERT_OBJ_ANY      VERT_OBJ_2
+
+#define VERT_TEX0_123     (VERT_TEX0_3|VERT_TEX0_12)
+#define VERT_TEX0_1234    (VERT_TEX0_4|VERT_TEX0_123)
+#define VERT_TEX0_ANY     VERT_TEX0_12
+
+#define VERT_TEX1_123     (VERT_TEX1_3|VERT_TEX1_12)
+#define VERT_TEX1_1234    (VERT_TEX1_4|VERT_TEX1_123)
+#define VERT_TEX1_ANY     VERT_TEX1_12
+
+#define VERT_TEX2_123     (VERT_TEX2_3|VERT_TEX2_12)
+#define VERT_TEX2_1234    (VERT_TEX2_4|VERT_TEX2_123)
+#define VERT_TEX2_ANY     VERT_TEX2_12
+
+#define VERT_TEX3_123     (VERT_TEX3_3|VERT_TEX3_12)
+#define VERT_TEX3_1234    (VERT_TEX3_4|VERT_TEX3_123)
+#define VERT_TEX3_ANY     VERT_TEX3_12
+
+#define NR_TEXSIZE_BITS   3
+#define VERT_TEX_ANY(i)   (VERT_TEX0_ANY << ((i) * NR_TEXSIZE_BITS))
+
+#define VERT_FIXUP         (VERT_TEX0_ANY | \
+                            VERT_TEX1_ANY | \
+                            VERT_TEX2_ANY | \
+                            VERT_TEX3_ANY | \
+                           VERT_RGBA | \
+                           VERT_SPEC_RGB | \
+                           VERT_FOG_COORD | \
+                            VERT_INDEX | \
+                            VERT_EDGE | \
+                            VERT_NORM)
+
+#define VERT_DATA          (VERT_TEX0_ANY | \
+                            VERT_TEX1_ANY | \
+                            VERT_TEX2_ANY | \
+                            VERT_TEX3_ANY | \
+                           VERT_RGBA | \
+                           VERT_SPEC_RGB | \
+                           VERT_FOG_COORD | \
+                            VERT_INDEX | \
+                            VERT_EDGE | \
+                            VERT_NORM | \
+                           VERT_OBJ_ANY | \
+                            VERT_MATERIAL | \
+                            VERT_ELT | \
+                           VERT_EVAL_ANY | \
+                            VERT_FOG_COORD)
+
+
+/* For beginstate
+ */
+#define VERT_BEGIN_0    0x1       /* glBegin (if initially inside beg/end) */
+#define VERT_BEGIN_1    0x2       /* glBegin (if initially outside beg/end) */
+#define VERT_ERROR_0    0x4       /* invalid_operation in initial state 0 */
+#define VERT_ERROR_1    0x8        /* invalid_operation in initial state 1 */
+
+
+struct gl_pipeline;
+struct tnl_context;
+
+/**
+ ** Vertex buffer/array structures
+ **/
+
+struct vertex_data
+{
+   GLfloat (*Obj)[4];
+   GLfloat (*Normal)[3];
+   GLchan  (*Color)[4];
+   GLuint   *Index;
+   GLubyte  *EdgeFlag;
+   GLfloat (*TexCoord[MAX_TEXTURE_UNITS])[4];
+   GLuint   *Elt;
+   GLfloat  *FogCoord;
+   GLubyte  (*SecondaryColor)[4];
+};
+
+struct vertex_arrays
+{
+   GLvector4f  Obj;
+   GLvector3f  Normal;
+   GLvector4ub Color;
+   GLvector1ui Index;
+   GLvector1ub EdgeFlag;
+   GLvector4f  TexCoord[MAX_TEXTURE_UNITS];
+   GLvector1ui Elt;     
+   GLvector4ub SecondaryColor;
+   GLvector1f  FogCoord;
+};
+
+struct vertex_array_pointers
+{
+   GLvector4f  *Obj;
+   GLvector3f  *Normal;
+   GLvector4ub *Color;
+   GLvector1ui *Index;
+   GLvector1ub *EdgeFlag;
+   GLvector4f  *TexCoord[MAX_TEXTURE_UNITS];
+   GLvector1ui *Elt;     
+   GLvector4ub *SecondaryColor;
+   GLvector1f *FogCoord;     
+};
+
+/* Values for VB->Type */
+enum {
+   VB_IMMEDIATE,
+   VB_CVA_PRECALC
+};
+
+
+/* Values for immediate->BeginState */
+#define VERT_BEGIN_0    0x1       /* glBegin (if initially inside beg/end) */
+#define VERT_BEGIN_1    0x2       /* glBegin (if initially outside beg/end) */
+#define VERT_ERROR_0    0x4       /* invalid_operation in initial state 0 */
+#define VERT_ERROR_1    0x8        /* invalid_operation in initial state 1 */
+
+
+/* KW: Represents everything that can take place between a begin and
+ * end, and can represent multiple begin/end pairs.  This plus *any*
+ * state variable (GLcontext) should be all you need to replay the
+ * represented begin/end pairs as if they took place in that state.  
+ *
+ * Thus this is sufficient for both immediate and compiled modes, but
+ * we could/should throw some elements away for compiled mode if we
+ * know they were empty. 
+ */
+struct immediate 
+{ 
+   struct immediate *next;     /* for cache of free IM's */
+   GLuint id, ref_count;
+
+   /* This must be saved when immediates are shared in display lists.
+    */
+   GLuint Start, Count;
+   GLuint LastData;            /* count or count+1 */
+   GLuint AndFlag, OrFlag, BeginState;
+   GLuint LastPrimitive;       
+
+   GLuint ArrayAndFlags;       /* precalc'ed for glArrayElt */
+   GLuint ArrayIncr;
+   GLuint ArrayEltFlush;
+   GLuint FlushElt;
+
+   GLuint TF1[MAX_TEXTURE_UNITS];      /* precalc'ed for glTexCoord */
+   GLuint TF2[MAX_TEXTURE_UNITS];
+   GLuint TF3[MAX_TEXTURE_UNITS];
+   GLuint TF4[MAX_TEXTURE_UNITS];
+
+   GLuint  Primitive[VB_SIZE]; /* GLubyte would do... */
+   GLuint  NextPrimitive[VB_SIZE]; 
+
+   /* allocate storage for these on demand:
+    */
+   struct  gl_material (*Material)[2]; 
+   GLuint  *MaterialMask;       
+
+   GLfloat (*TexCoordPtr[MAX_TEXTURE_UNITS])[4]; 
+
+   struct vertex_arrays v;
+   
+   struct __GLcontextRec *backref;                 
+
+   /* Normal lengths, zero if not available.
+    */
+   GLfloat   *NormalLengths;
+   GLuint     LastCalcedLength;
+
+   GLuint  Flag[VB_SIZE];    /* bitwise-OR of VERT_ flags */
+   GLchan  Color[VB_SIZE][4];
+   GLfloat Obj[VB_SIZE][4];
+   GLfloat Normal[VB_SIZE][3];
+   GLfloat TexCoord[MAX_TEXTURE_UNITS][VB_SIZE][4];
+   GLuint  Elt[VB_SIZE];
+   GLubyte EdgeFlag[VB_SIZE];
+   GLuint  Index[VB_SIZE];
+   GLubyte SecondaryColor[VB_SIZE][4];
+   GLfloat FogCoord[VB_SIZE];
+};
+
+
+/* Not so big on storage these days, although still has pointers to
+ * arrays used for temporary results.
+ */
+typedef struct vertex_buffer
+{
+   /* Backpointers.
+    */
+   struct __GLcontextRec *ctx;
+   struct tnl_context *tnlctx;
+
+   /* Driver_data is allocated in Driver.RegisterVB(), if required.
+    */
+   void *driver_data;
+
+   /* List of operations to process vertices in current state.
+    */
+   struct gl_pipeline *pipeline;
+
+   /* Temporary storage used by immediate mode functions and various
+    * operations in the pipeline.
+    */
+   struct immediate *IM;               
+   struct vertex_array_pointers store; 
+
+   /* Where to find outstanding untransformed vertices.
+    */
+   struct immediate *prev_buffer;
+
+   GLuint     Type;            /* Either VB_IMMEDIATE or VB_CVA_PRECALC */
+
+   GLuint     Size, Start, Count;
+   GLuint     Free, FirstFree;
+   GLuint     CopyStart;
+   GLuint     Parity, Ovf;
+   GLuint     PurgeFlags;
+   GLuint     IndirectCount;   /* defaults to count */
+   GLuint     OrFlag, SavedOrFlag;
+   GLuint     EarlyCull;
+   GLuint     Culled, CullDone;
+
+   /* Pointers to input data - default to buffers in 'im' above.
+    */
+   GLvector4f  *ObjPtr;
+   GLvector3f  *NormalPtr;
+   GLvector4ub *ColorPtr;
+   GLvector1ui *IndexPtr;
+   GLvector1ub *EdgeFlagPtr;
+   GLvector4f  *TexCoordPtr[MAX_TEXTURE_UNITS];
+   GLvector1ui *EltPtr;
+   GLvector4ub *SecondaryColorPtr;
+   GLvector1f  *FogCoordPtr;
+   GLuint      *Flag, FlagMax;
+   struct      gl_material (*Material)[2];
+   GLuint      *MaterialMask;       
+
+   GLuint      *NextPrimitive; 
+   GLuint      *Primitive;     
+   GLuint      LastPrimitive;
+
+   GLfloat (*BoundsPtr)[3];    /* Bounds for cull check */
+   GLfloat  *NormalLengthPtr;  /* Array of precomputed inv. normal lengths */
+   
+   /* Holds malloced storage for pipeline data not supplied by 
+    * the immediate struct.
+    */
+   GLvector4f Eye;
+   GLvector4f Clip;
+   GLvector4f Win;
+   GLvector4ub BColor;         /* not used in cva vb's */
+   GLvector1ui BIndex;         /* not used in cva vb's */
+   GLvector4ub BSecondary;     /* not used in cva vb's */
+
+   /* Temporary storage - may point into IM, or be dynamically
+    * allocated (for cva).  
+    */
+   GLubyte *ClipMask;
+   GLubyte *UserClipMask;
+   
+   /* Internal values.  Where these point depends on whether
+    * there were any identity matrices defined as transformations
+    * in the pipeline.
+    */
+   GLvector4f *EyePtr;
+   GLvector4f *ClipPtr;
+   GLvector4f *Unprojected;
+   GLvector4f *Projected;
+   GLvector4f *CurrentTexCoord;
+   GLuint     *Indirect;           /* For eval rescue and cva render */
+
+   /* Currently active colors
+    */
+   GLvector4ub *Color[2];
+   GLvector1ui *Index[2];
+   GLvector4ub *SecondaryColor[2];
+
+   /* Storage for colors which have been lit but not yet fogged.  
+    * Required for CVA, just point into store for normal VB's.
+    */
+   GLvector4ub *LitColor[2];
+   GLvector1ui *LitIndex[2];
+   GLvector4ub *LitSecondary[2];
+
+   /* Temporary values used in texgen.
+    */
+   GLfloat (*tmp_f)[3];
+   GLfloat *tmp_m;
+
+   /* Temporary values used in eval.
+    */
+   GLuint *EvaluatedFlags;
+
+   /* Not used for cva: 
+    */
+   GLubyte *NormCullStart;
+   GLubyte *CullMask;          /* Results of vertex culling */
+   GLubyte *NormCullMask;       /* Compressed onto shared normals */
+
+   GLubyte ClipOrMask;         /* bitwise-OR of all ClipMask[] values */
+   GLubyte ClipAndMask;                /* bitwise-AND of all ClipMask[] values */
+   GLubyte CullFlag[2];
+   GLubyte CullMode;           /* see flags below */
+
+   GLuint CopyCount;           /* max 3 vertices to copy after transform */
+   GLuint Copy[3];
+   GLfloat CopyProj[3][4];     /* temporary store for projected clip coords */
+
+   /* Hooks for module private data
+    */
+   void *swsetup_vb;
+
+} TNLvertexbuffer;
+
+
+typedef void (*gl_shade_func)( struct vertex_buffer *VB );
+
+typedef void (*clip_interp_func)( struct vertex_buffer *VB, GLuint dst,
+                                  GLfloat t, GLuint in, GLuint out );
+
+typedef GLuint (*clip_line_func)( struct vertex_buffer *VB, 
+                                 GLuint *i, GLuint *j,
+                                 GLubyte mask);
+
+typedef GLuint (*clip_poly_func)( struct vertex_buffer *VB,
+                                 GLuint n, GLuint vlist[],
+                                 GLubyte mask );
+
+
+#define MAX_PIPELINE_STAGES     30
+
+#define PIPE_IMMEDIATE          0x1
+#define PIPE_PRECALC            0x2
+
+#define PIPE_OP_VERT_XFORM        0x1
+#define PIPE_OP_NORM_XFORM        0x2
+#define PIPE_OP_LIGHT             0x4
+#define PIPE_OP_FOG               0x8
+#define PIPE_OP_TEX0             0x10
+#define PIPE_OP_TEX1             0x20
+#define PIPE_OP_TEX2             0x40
+#define PIPE_OP_TEX3             0x80
+#define PIPE_OP_RAST_SETUP_0    0x100
+#define PIPE_OP_RAST_SETUP_1    0x200
+#define PIPE_OP_RENDER          0x400
+#define PIPE_OP_CVA_PREPARE     0x800
+
+
+
+struct gl_pipeline_stage {
+   const char *name;
+   GLuint ops;                 /* PIPE_OP flags */
+   GLuint type;                        /* VERT flags */
+   GLuint special;             /* VERT flags - force update_inputs() */
+   GLuint state_change;                /* state flags - trigger update_inputs() */
+   GLuint cva_state_change;          /* state flags - recalc cva buffer */
+   GLuint elt_forbidden_inputs;      /* VERT flags - force a pipeline recalc */
+   GLuint pre_forbidden_inputs;             /* VERT flags - force a pipeline recalc */
+   GLuint active;                   /* VERT flags */
+   GLuint inputs;                   /* VERT flags */
+   GLuint outputs;                  /* VERT flags */
+   void (*check)( GLcontext *ctx, struct gl_pipeline_stage * );
+   void (*run)( struct vertex_buffer *VB );
+};
+
+
+struct gl_pipeline {
+   GLuint state_change;                /* state changes which require recalc */
+   GLuint cva_state_change;    /* ... which require re-run */
+   GLuint forbidden_inputs;    /* inputs which require recalc */
+   GLuint ops;                 /* what gets done in this pipe */
+   GLuint changed_ops;
+   GLuint inputs;
+   GLuint outputs;
+   GLuint new_inputs;
+   GLuint new_outputs;
+   GLuint fallback;
+   GLuint type;
+   GLuint pipeline_valid:1;
+   GLuint data_valid:1;
+   GLuint copy_transformed_data:1;
+   GLuint replay_copied_vertices:1;
+   GLuint new_state;           /* state changes since last recalc */
+   struct gl_pipeline_stage *stages[MAX_PIPELINE_STAGES];
+};
+
+
+
+/* All fields are derived.
+ */
+struct gl_cva {
+   struct gl_pipeline pre;
+   struct gl_pipeline elt;
+       
+   struct gl_client_array Elt;
+   trans_1ui_func EltFunc;
+
+   struct vertex_buffer *VB;
+   struct vertex_arrays v;
+   struct vertex_data store;
+
+   GLuint elt_count;
+   GLenum elt_mode;
+   GLuint elt_size;
+
+   GLuint forbidden_inputs;
+   GLuint orflag;
+   GLuint merge;
+
+   GLuint lock_changed;
+   GLuint last_orflag;
+   GLuint last_array_flags;
+   GLuint last_array_new_state;
+};
+
+
+
+typedef void (*texgen_func)( struct vertex_buffer *VB, 
+                            GLuint textureSet);
+
+
+
+typedef struct tnl_context {   
+
+   GLuint _ArrayFlag[VB_SIZE]; /* crock */
+   GLuint _ArrayFlags;
+   GLuint _ArraySummary;       /* Like flags, but no size information */
+   GLuint _ArrayNewState;      /* Tracks which arrays have been changed. */
+
+
+   /* Pipeline stages - shared between the two pipelines,
+    * which live in CVA.
+    */
+   struct gl_pipeline_stage PipelineStage[MAX_PIPELINE_STAGES];
+   GLuint NrPipelineStages;
+
+   /* Per-texunit derived state.
+    */
+   GLuint _TexgenSize[MAX_TEXTURE_UNITS];
+   GLuint _TexgenHoles[MAX_TEXTURE_UNITS];
+   texgen_func *_TexgenFunc[MAX_TEXTURE_UNITS];
+
+
+   /* Display list extensions
+    */
+   GLuint opcode_vertex_cassette;
+
+   /* Cva 
+    */
+   struct gl_cva CVA;
+   GLboolean CompileCVAFlag;
+
+   clip_poly_func *_poly_clip_tab;
+   clip_line_func *_line_clip_tab;
+   clip_interp_func _ClipInterpFunc; /* Clip interpolation function */
+   normal_func *_NormalTransform; 
+   gl_shade_func *_shade_func_tab;   /* Current shading function table */
+
+   GLenum _CurrentPrimitive;         /* Prim or GL_POLYGON+1 */
+   GLuint _CurrentFlag;
+
+   GLuint _RenderFlags;              /* Active inputs to render stage */
+
+   /* Cache of unused immediate structs */
+   struct immediate *freed_im_queue; 
+   GLuint nr_im_queued;
+
+} TNLcontext;
+
+
+
+#define TNL_CONTEXT(ctx) ((TNLcontext *)(ctx->swtnl_context))
+#define TNL_CURRENT_IM(ctx) ((struct immediate *)(ctx->swtnl_im))
+#define TNL_VB(ctx) ((struct vertex_buffer *)(ctx->swtnl_vb))
+
+extern void _tnl_reset_immediate( GLcontext *ctx );
+extern GLboolean _tnl_flush_vertices( GLcontext *ctx, GLuint flush_flags );
+
+
+extern void
+_tnl_MakeCurrent( GLcontext *ctx, 
+                 GLframebuffer *drawBuffer, 
+                 GLframebuffer *readBuffer );
+
+
+extern void
+_tnl_LightingSpaceChange( GLcontext *ctx );
+
+/*
+ * Macros for fetching current input buffer.
+ */
+#ifdef THREADS
+#define GET_IMMEDIATE  struct immediate *IM = TNL_CURRENT_IM(((GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context())))
+#define SET_IMMEDIATE(ctx, im)  ctx->swtnl_im = (void *)im
+#else
+extern struct immediate *_mesa_CurrentInput;
+#define GET_IMMEDIATE struct immediate *IM = _mesa_CurrentInput
+#define SET_IMMEDIATE(ctx, im)                 \
+do {                                           \
+   TNL_CURRENT_IM(ctx) = im;                   \
+   _mesa_CurrentInput = im;                    \
+} while (0)
+#endif
+
+#endif
diff --git a/src/mesa/tnl/t_pipeline.c b/src/mesa/tnl/t_pipeline.c
new file mode 100644 (file)
index 0000000..03c9391
--- /dev/null
@@ -0,0 +1,496 @@
+/* $Id: t_pipeline.c,v 1.1 2000/11/16 21:05:42 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ * 
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Dynamic pipelines, support for CVA.
+ * Copyright (C) 1999 Keith Whitwell.
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "mem.h"
+#include "mmath.h"
+#include "state.h"
+#include "types.h"
+
+#include "math/m_translate.h"
+#include "math/m_xform.h"
+
+#include "t_bbox.h"
+#include "t_clip.h"
+#include "t_cva.h"
+#include "t_fog.h"
+#include "t_light.h"
+#include "t_pipeline.h"
+#include "t_shade.h"
+#include "t_stages.h"
+#include "t_vbcull.h"
+#include "t_vbindirect.h"
+#include "t_vbrender.h"
+#include "t_vbxform.h"
+
+
+
+
+
+void gl_print_pipe_ops( const char *msg, GLuint flags )
+{
+   fprintf(stderr, 
+          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s\n",
+          msg,
+          flags,
+          (flags & PIPE_OP_CVA_PREPARE)   ? "cva-prepare, " : "",
+          (flags & PIPE_OP_VERT_XFORM)    ? "vert-xform, " : "",
+          (flags & PIPE_OP_NORM_XFORM)    ? "norm-xform, " : "",
+          (flags & PIPE_OP_LIGHT)         ? "light, " : "",
+          (flags & PIPE_OP_FOG)           ? "fog, " : "",
+          (flags & PIPE_OP_TEX0)          ? "tex-0, " : "",
+          (flags & PIPE_OP_TEX1)          ? "tex-1, " : "",
+          (flags & PIPE_OP_RAST_SETUP_0)  ? "rast-0, " : "",
+          (flags & PIPE_OP_RAST_SETUP_1)  ? "rast-1, " : "",
+          (flags & PIPE_OP_RENDER)        ? "render, " : "");
+
+}
+
+
+
+/* Have to reset only those parts of the vb which are being recalculated.
+ */
+void gl_reset_cva_vb( struct vertex_buffer *VB, GLuint stages )
+{
+   GLcontext *ctx = VB->ctx;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+   if (MESA_VERBOSE&VERBOSE_PIPELINE)
+      gl_print_pipe_ops( "reset cva vb", stages ); 
+
+   if (stages & PIPE_OP_VERT_XFORM) 
+   {
+      if (VB->ClipOrMask & CLIP_USER_BIT)
+        MEMSET(VB->UserClipMask, 0, VB->Count);
+
+      VB->ClipOrMask = 0;
+      VB->ClipAndMask = CLIP_ALL_BITS;
+      VB->CullMode = 0;
+      VB->CullFlag[0] = VB->CullFlag[1] = 0;
+      VB->Culled = 0;
+   }
+
+   if (stages & PIPE_OP_NORM_XFORM) {
+      VB->NormalPtr = &tnl->CVA.v.Normal;
+   }
+
+   if (stages & PIPE_OP_LIGHT) 
+   {
+      VB->ColorPtr = VB->Color[0] = VB->Color[1] = &tnl->CVA.v.Color;
+      VB->IndexPtr = VB->Index[0] = VB->Index[1] = &tnl->CVA.v.Index;
+   }
+   else if (stages & PIPE_OP_FOG) 
+   {
+      if (ctx->Light.Enabled) {
+        VB->Color[0] = VB->LitColor[0];
+        VB->Color[1] = VB->LitColor[1];      
+        VB->Index[0] = VB->LitIndex[0];
+        VB->Index[1] = VB->LitIndex[1];      
+      } else {
+        VB->Color[0] = VB->Color[1] = &tnl->CVA.v.Color;
+        VB->Index[0] = VB->Index[1] = &tnl->CVA.v.Index;
+      }
+      VB->ColorPtr = VB->Color[0];
+      VB->IndexPtr = VB->Index[0];
+   }
+}
+
+
+
+
+
+
+static void pipeline_ctr( struct gl_pipeline *p, GLcontext *ctx, GLuint type )
+{
+   GLuint i;
+   (void) ctx;
+
+   p->state_change = 0;
+   p->cva_state_change = 0;
+   p->inputs = 0;
+   p->outputs = 0;
+   p->type = type;
+   p->ops = 0;
+
+   for (i = 0 ; i < gl_default_nr_stages ; i++) 
+      p->state_change |= gl_default_pipeline[i].state_change;
+}
+
+
+void _tnl_pipeline_init( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+   MEMCPY( tnl->PipelineStage, 
+          gl_default_pipeline, 
+          sizeof(*gl_default_pipeline) * gl_default_nr_stages );
+   
+   tnl->NrPipelineStages = gl_default_nr_stages;
+      
+   pipeline_ctr( &tnl->CVA.elt, ctx, PIPE_IMMEDIATE);
+   pipeline_ctr( &tnl->CVA.pre, ctx, PIPE_PRECALC );
+}
+
+
+
+#define MINIMAL_VERT_DATA (VERT_DATA & ~(VERT_TEX0_4 | \
+                                         VERT_TEX1_4 | \
+                                         VERT_TEX2_4 | \
+                                         VERT_TEX3_4 | \
+                                         VERT_EVAL_ANY))
+
+#define VERT_CURRENT_DATA (VERT_TEX0_1234 | \
+                           VERT_TEX1_1234 | \
+                           VERT_TEX2_1234 | \
+                           VERT_TEX3_1234 | \
+                           VERT_RGBA | \
+                           VERT_SPEC_RGB | \
+                           VERT_FOG_COORD | \
+                          VERT_INDEX | \
+                           VERT_EDGE | \
+                           VERT_NORM | \
+                          VERT_MATERIAL)
+
+/* Called prior to every recomputation of the CVA precalc data, except where
+ * the driver is able to calculate the pipeline unassisted.
+ */
+static void build_full_precalc_pipeline( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct gl_pipeline_stage *pipeline = tnl->PipelineStage;
+   struct gl_cva *cva = &tnl->CVA;
+   struct gl_pipeline *pre = &cva->pre;   
+   struct gl_pipeline_stage **stages = pre->stages;
+   GLuint i;
+   GLuint newstate = pre->new_state;
+   GLuint changed_ops = 0;
+   GLuint oldoutputs = pre->outputs;
+   GLuint oldinputs = pre->inputs;
+   GLuint fallback = (VERT_CURRENT_DATA & tnl->_CurrentFlag & 
+                     ~tnl->_ArraySummary);
+   GLuint changed_outputs = (tnl->_ArrayNewState | 
+                            (fallback & cva->orflag));
+   GLuint available = fallback | tnl->_ArrayFlags;
+
+   pre->cva_state_change = 0;
+   pre->ops = 0;
+   pre->outputs = 0;
+   pre->inputs = 0;
+   pre->forbidden_inputs = 0;
+   pre->fallback = 0;
+
+   /* KW: Disable data reuse during Mesa reorg.  Make this more readable...
+    */
+   newstate = ~0;
+
+   if (tnl->_ArraySummary & VERT_ELT) 
+      cva->orflag &= VERT_MATERIAL;
+  
+   cva->orflag &= ~(tnl->_ArraySummary & ~VERT_OBJ_ANY);
+   available &= ~cva->orflag;
+   
+   pre->outputs = available;
+   pre->inputs = available;
+
+   if (MESA_VERBOSE & VERBOSE_PIPELINE) {
+      fprintf(stderr, ": Rebuild pipeline\n");
+      gl_print_vert_flags("orflag", cva->orflag);
+   }
+      
+   
+
+   /* If something changes in the pipeline, tag all subsequent stages
+    * using this value for recalcuation.  Also used to build the full
+    * pipeline by setting newstate and newinputs to ~0.
+    *
+    * Because all intermediate values are buffered, the new inputs
+    * are enough to fully specify what needs to be calculated, and a
+    * single pass identifies all stages requiring recalculation.
+    */
+   for (i = 0 ; i < tnl->NrPipelineStages ; i++) 
+   {
+      pipeline[i].check(ctx, &pipeline[i]);
+
+      if (pipeline[i].type & PIPE_PRECALC) 
+      {
+        if ((newstate & pipeline[i].cva_state_change) ||
+            (changed_outputs & pipeline[i].inputs) ||
+            !pipeline[i].inputs)
+        {          
+           changed_ops |= pipeline[i].ops;
+           changed_outputs |= pipeline[i].outputs;
+           pipeline[i].active &= ~PIPE_PRECALC;
+
+           if ((pipeline[i].inputs & ~available) == 0 &&
+               (pipeline[i].ops & pre->ops) == 0)
+           {
+              pipeline[i].active |= PIPE_PRECALC;
+              *stages++ = &pipeline[i];
+           } 
+        }
+      
+        /* Incompatible with multiple stages structs implementing
+         * the same stage.
+         */
+        available &= ~pipeline[i].outputs;
+        pre->outputs &= ~pipeline[i].outputs;
+
+        if (pipeline[i].active & PIPE_PRECALC) {
+           pre->ops |= pipeline[i].ops;
+           pre->outputs |= pipeline[i].outputs;
+           available |= pipeline[i].outputs;
+           pre->forbidden_inputs |= pipeline[i].pre_forbidden_inputs;
+        }
+      } 
+      else if (pipeline[i].active & PIPE_PRECALC) 
+      {
+        pipeline[i].active &= ~PIPE_PRECALC;
+        changed_outputs |= pipeline[i].outputs;
+        changed_ops |= pipeline[i].ops;
+      }
+   }
+
+   *stages = 0;
+
+   pre->new_outputs = pre->outputs & (changed_outputs | ~oldoutputs);
+   pre->new_inputs = pre->inputs & ~oldinputs;
+   pre->fallback = pre->inputs & fallback;
+   pre->forbidden_inputs |= pre->inputs & fallback;
+
+   pre->changed_ops = changed_ops;
+}
+
+void gl_build_precalc_pipeline( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct gl_pipeline *pre = &tnl->CVA.pre;   
+   struct gl_pipeline *elt = &tnl->CVA.elt;   
+
+   if (!ctx->Driver.BuildPrecalcPipeline ||
+       !ctx->Driver.BuildPrecalcPipeline( ctx ))
+      build_full_precalc_pipeline( ctx );
+
+   pre->data_valid = 0;
+   pre->pipeline_valid = 1;
+   elt->pipeline_valid = 0;
+   
+   tnl->CVA.orflag = 0;
+   
+   if (MESA_VERBOSE&VERBOSE_PIPELINE)
+      gl_print_pipeline( ctx, pre ); 
+}
+
+
+static void build_full_immediate_pipeline( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct gl_pipeline_stage *pipeline = tnl->PipelineStage;
+   struct gl_cva *cva = &tnl->CVA;
+   struct gl_pipeline *pre = &cva->pre;   
+   struct gl_pipeline *elt = &cva->elt;
+   struct gl_pipeline_stage **stages = elt->stages;
+   GLuint i;
+   GLuint newstate = elt->new_state;
+   GLuint active_ops = 0;
+   GLuint available = cva->orflag | MINIMAL_VERT_DATA;
+   GLuint generated = 0;
+   GLuint is_elt = 0;
+
+   if (pre->data_valid && tnl->CompileCVAFlag) {
+      is_elt = 1;
+      active_ops = cva->pre.ops;
+      available |= pre->outputs | VERT_PRECALC_DATA;
+   }
+
+
+   elt->outputs = 0;           /* not used */
+   elt->inputs = 0;
+
+   for (i = 0 ; i < tnl->NrPipelineStages ; i++) {
+      pipeline[i].active &= ~PIPE_IMMEDIATE;
+
+      if ((pipeline[i].state_change & newstate) ||
+         (pipeline[i].elt_forbidden_inputs & available)) 
+      {
+        pipeline[i].check(ctx, &pipeline[i]);
+      }
+
+      if ((pipeline[i].type & PIPE_IMMEDIATE) &&
+         (pipeline[i].ops & active_ops) == 0 && 
+         (pipeline[i].elt_forbidden_inputs & available) == 0
+        )
+      {
+        if (pipeline[i].inputs & ~available) 
+           elt->forbidden_inputs |= pipeline[i].inputs & ~available;
+        else
+        {
+           elt->inputs |= pipeline[i].inputs & ~generated;
+           elt->forbidden_inputs |= pipeline[i].elt_forbidden_inputs;
+           pipeline[i].active |= PIPE_IMMEDIATE;
+           *stages++ = &pipeline[i];
+           generated |= pipeline[i].outputs;
+           available |= pipeline[i].outputs;
+           active_ops |= pipeline[i].ops;
+        }
+      }
+   }
+
+   *stages = 0;
+   
+   elt->copy_transformed_data = 1;
+   elt->replay_copied_vertices = 0;
+
+   if (is_elt) {
+      cva->merge = elt->inputs & pre->outputs;
+      elt->ops = active_ops & ~pre->ops;
+   }
+}
+
+
+
+void gl_build_immediate_pipeline( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct gl_pipeline *elt = &tnl->CVA.elt;   
+
+   if (!ctx->Driver.BuildEltPipeline ||
+       !ctx->Driver.BuildEltPipeline( ctx )) {
+      build_full_immediate_pipeline( ctx );
+   }
+
+   elt->pipeline_valid = 1;
+   tnl->CVA.orflag = 0;
+   
+   if (MESA_VERBOSE&VERBOSE_PIPELINE)
+      gl_print_pipeline( ctx, elt ); 
+}
+   
+#define INTERESTED ~0
+
+void gl_update_pipelines( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint newstate = ctx->NewState;
+   struct gl_cva *cva = &tnl->CVA;
+
+   newstate &= INTERESTED;
+
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_STATE))
+      gl_print_enable_flags("enabled", ctx->_Enabled);
+
+   if (newstate ||
+       cva->lock_changed ||
+       cva->orflag != cva->last_orflag ||
+       tnl->_ArrayFlags != cva->last_array_flags)
+   {   
+      GLuint flags = VERT_WIN;
+
+      if (ctx->Visual.RGBAflag) {
+        flags |= VERT_RGBA;
+        if (ctx->_TriangleCaps && DD_SEPERATE_SPECULAR)
+           flags |= VERT_SPEC_RGB;
+      } else 
+        flags |= VERT_INDEX;
+
+      if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) 
+        flags |= VERT_TEX0_ANY;
+
+      if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY)
+        flags |= VERT_TEX1_ANY;
+
+#if MAX_TEXTURE_UNITS > 2
+      if (ctx->Texture._ReallyEnabled & TEXTURE2_ANY)
+        flags |= VERT_TEX2_ANY;
+#endif
+#if MAX_TEXTURE_UNITS > 3
+      if (ctx->Texture._ReallyEnabled & TEXTURE3_ANY)
+        flags |= VERT_TEX3_ANY;
+#endif
+   
+      if (ctx->Polygon._Unfilled) 
+        flags |= VERT_EDGE;
+      if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
+        flags |= VERT_FOG_COORD;
+
+      if (ctx->RenderMode==GL_FEEDBACK) {
+        flags = (VERT_WIN | VERT_RGBA | VERT_INDEX | VERT_NORM | VERT_EDGE
+                 | VERT_TEX0_ANY
+                  | VERT_TEX1_ANY
+#if MAX_TEXTURE_UNITS > 2
+                  | VERT_TEX2_ANY
+#endif
+#if MAX_TEXTURE_UNITS > 3
+                  | VERT_TEX3_ANY
+#endif
+                  );
+      }
+
+      tnl->_RenderFlags = flags;
+
+      cva->elt.new_state |= newstate;
+      cva->elt.pipeline_valid = 0;
+
+      cva->pre.new_state |= newstate;
+      cva->pre.forbidden_inputs = 0;
+      cva->pre.pipeline_valid = 0;
+      cva->lock_changed = 0;
+   }
+
+   if (tnl->_ArrayNewState != cva->last_array_new_state)
+      cva->pre.pipeline_valid = 0;
+
+   cva->pre.data_valid = 0;
+   cva->last_array_new_state = tnl->_ArrayNewState;
+   cva->last_orflag = cva->orflag;
+   cva->last_array_flags = tnl->_ArrayFlags;
+}
+
+void gl_run_pipeline( struct vertex_buffer *VB )
+{
+   struct gl_pipeline *pipe = VB->pipeline;
+   struct gl_pipeline_stage **stages = pipe->stages;
+   unsigned short x;
+
+   pipe->data_valid = 1;       /* optimized stages might want to reset this. */
+
+   if (0) gl_print_pipeline( VB->ctx, pipe );
+   
+   START_FAST_MATH(x);
+   
+   for ( VB->Culled = 0; *stages && !VB->Culled ; stages++ ) 
+      (*stages)->run( VB );
+
+   END_FAST_MATH(x);
+
+   pipe->new_state = 0;
+}
+
diff --git a/src/mesa/tnl/t_pipeline.h b/src/mesa/tnl/t_pipeline.h
new file mode 100644 (file)
index 0000000..36a2f06
--- /dev/null
@@ -0,0 +1,59 @@
+/* $Id: t_pipeline.h,v 1.1 2000/11/16 21:05:42 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * Author:
+ *    Keith Whitwell <keithw@valinux.com>
+ */
+
+
+
+#ifndef _T_PIPELINE_H_
+#define _T_PIPELINE_H_
+
+#include "types.h"
+#include "t_context.h"
+
+extern void gl_update_materials( struct vertex_buffer *VB);
+
+extern void _tnl_pipeline_init( GLcontext *ctx );
+extern void gl_update_pipelines( GLcontext *ctx );
+
+extern void gl_build_precalc_pipeline( GLcontext *ctx );
+extern void gl_build_immediate_pipeline( GLcontext *ctx );
+
+extern void gl_print_vert_flags( const char *name, GLuint flags );
+extern void gl_print_pipeline( GLcontext *ctx, struct gl_pipeline *p );
+extern void gl_print_active_pipeline( GLcontext *ctx, struct gl_pipeline *p );
+
+extern void gl_run_pipeline( struct vertex_buffer *VB );
+
+extern void gl_clean_color( struct vertex_buffer *VB );
+
+extern void gl_reset_cva_vb( struct vertex_buffer *VB, GLuint stages );
+
+extern void gl_print_pipe_ops( const char *msg, GLuint flags );
+
+#endif
diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h
new file mode 100644 (file)
index 0000000..dc46ef3
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Keith Whitwell <keithw@valinux.com>
+ */
+
+#ifndef _TNL_H
+#define _TNL_H
+
+#include "types.h"
+
+
+
+/* These are the public-access functions exported from tnl.  (Many
+ * more are currently hooked into dispatch directly by core code.)
+ */
+extern GLboolean
+_tnl_CreateContext( GLcontext *ctx );
+
+extern void
+_tnl_DestroyContext( GLcontext *ctx );
+
+extern void
+_tnl_InvalidateState( GLcontext *ctx, GLuint new_state );
+
+
+#endif
index 3becc8cc58cb7ff1c0cede93d8ba1a640be61cf8..f0e5e3af1ca25b425626e9b4c076ec2c000f2000 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: 3dnow.c,v 1.8 2000/10/23 00:16:28 gareth Exp $ */
+/* $Id: 3dnow.c,v 1.9 2000/11/16 21:05:41 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "glheader.h"
 #include "context.h"
 #include "types.h"
-#include "vertices.h"
-#include "xform.h"
 #include "3dnow.h"
 
+#include "math/m_vertices.h"
+#include "math/m_xform.h"
+
 #ifdef DEBUG
-#include "debug_xform.h"
+#include "math/m_debug_xform.h"
 #endif
 
 
index 1e17cc4bb4be0a340405e6d3b76b1fb806506da5..ee87c5af3dd4ec30698f8ba19836f5ed3d097885 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: 3dnow.h,v 1.2 2000/10/23 00:16:28 gareth Exp $ */
+/* $Id: 3dnow.h,v 1.3 2000/11/16 21:05:41 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -32,7 +32,7 @@
 #ifndef __3DNOW_H__
 #define __3DNOW_H__
 
-#include "xform.h"
+#include "math/m_xform.h"
 
 void gl_init_3dnow_transform_asm( void );
 void gl_init_3dnow_vertex_asm( void );
index 880be22e8f89caed263b0deae4462405cf931b93..f52f56da68555c72b013331b88315c25e451f15c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: common_x86_asm.h,v 1.2 2000/10/23 00:16:28 gareth Exp $ */
+/* $Id: common_x86_asm.h,v 1.3 2000/11/16 21:05:41 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -39,6 +39,8 @@
 #ifndef __COMMON_X86_ASM_H__
 #define __COMMON_X86_ASM_H__
 
+/* Do not reference types.h from this file.
+ */
 #include "common_x86_features.h"
 
 #ifdef HAVE_CONFIG_H
index fcd097867c4bcf48bf0b78adfb87f0ead29bc490..fe750ad7652159833b3465b22a57ad59577d75cf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: x86.c,v 1.9 2000/10/23 00:16:28 gareth Exp $ */
+/* $Id: x86.c,v 1.10 2000/11/16 21:05:41 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "glheader.h"
 #include "context.h"
 #include "types.h"
-#include "vertices.h"
-#include "xform.h"
+#include "math/m_vertices.h"
+#include "math/m_xform.h"
 #include "x86.h"
 
 #ifdef DEBUG
-#include "debug_xform.h"
+#include "math/m_debug_xform.h"
 #endif