-# $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
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 \
context.c \
convolve.c \
copypix.c \
- cva.c \
- debug_xform.c \
+ debug.c \
depth.c \
dispatch.c \
dlist.c \
matrix.c \
mem.c \
mmath.c \
- pipeline.c \
pixel.c \
pixeltex.c \
points.c \
readpix.c \
rect.c \
scissor.c \
- shade.c \
- stages.c \
state.c \
stencil.c \
teximage.c \
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 \
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
{
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)
*/
-/* 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
}
-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
}
if(fxMesaCurrentCtx) {
- FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" );
+ _mesa_swapbuffers( fxMesaCurrentCtx->glCtx );
if(fxMesaCurrentCtx->haveDoubleBuffer) {
#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.
-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).
/* 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 );
_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 |
fprintf(stderr,"fxmesa: fxSetupDDPointers()\n");
}
- ctx->Driver.UpdateStateNotify = ~0;
ctx->Driver.UpdateState=fxDDUpdateDDPointers;
ctx->Driver.WriteDepthSpan=fxDDWriteDepthSpan;
ctx->Driver.GetString=fxDDGetString;
- ctx->Driver.NearFar=fxDDSetNearFar;
-
ctx->Driver.ClearIndex=NULL;
ctx->Driver.ClearColor=fxDDClearColor;
ctx->Driver.Clear=fxDDClear;
ctx->Driver.DeleteTexture=fxDDTexDel;
ctx->Driver.UpdateTexturePalette=fxDDTexPalette;
- ctx->Driver.RectFunc=NULL;
-
ctx->Driver.AlphaFunc=fxDDAlphaFunc;
ctx->Driver.BlendFunc=fxDDBlendFunc;
ctx->Driver.DepthFunc=fxDDDepthFunc;
ctx->Driver.RegisterVB=fxDDRegisterVB;
ctx->Driver.UnregisterVB=fxDDUnregisterVB;
- ctx->Driver.RegisterPipelineStages = fxDDRegisterPipelineStages;
-
if (!getenv("FX_NO_FAST"))
ctx->Driver.BuildPrecalcPipeline = fxDDBuildPrecalcPipeline;
#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
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);
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 );
#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);
-/* $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
{
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 );
}
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;
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 );
}
-/* $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
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 */
{
-/* $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
#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
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;
*/
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 );
-/* $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.
*/
_swrast_InvalidateState( ctx, ctx->NewState );
_swsetup_InvalidateState( ctx, ctx->NewState );
+ _tnl_InvalidateState( ctx, ctx->NewState );
/* setup pointers to front and back buffer clear functions */
-/* $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
#include "glxheader.h"
#include "depth.h"
#include "macros.h"
-#include "vb.h"
#include "types.h"
#include "xmesaP.h"
-/* $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
#include "state.h"
#include "depth.h"
#include "macros.h"
-#include "vb.h"
#include "types.h"
#include "xmesaP.h"
#include "extensions.h"
-/* $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
#include "glxheader.h"
#include "depth.h"
#include "macros.h"
-#include "vb.h"
#include "types.h"
#include "xmesaP.h"
#ifdef DEBUG
-void
+static void
_xmesa_print_triangle_func( swrast_tri_func triFunc )
{
printf("XMesa tri func = ");
-# $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
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 \
context.c \
convolve.c \
copypix.c \
- cva.c \
- debug_xform.c \
+ debug.c \
depth.c \
dispatch.c \
dlist.c \
matrix.c \
mem.c \
mmath.c \
- pipeline.c \
pixel.c \
pixeltex.c \
points.c \
readpix.c \
rect.c \
scissor.c \
- shade.c \
- stages.c \
state.c \
stencil.c \
teximage.c \
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 \
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
-/* $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
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 );
}
break;
case GL_CURRENT_BIT:
+ FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
MEMCPY( &ctx->Current, attr->data,
sizeof(struct gl_current_attrib) );
break;
-/* $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"
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;
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.
* 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 );
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;
-}
-
-/* $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
-/* $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
#include "config.h"
#include "macros.h"
#include "mmath.h"
-
+/* Do not reference types.h from this file.
+ */
/*
-/* $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
#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) *****/
/**********************************************************************/
-#if !defined(THREADS)
-
-struct immediate *_mesa_CurrentInput = NULL;
-
-#endif
-
/**********************************************************************/
/***** GL Visual allocation/destruction *****/
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);
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 */
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 );
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 );
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
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 */
/* allocate new group of display lists */
ctx->Shared = alloc_shared_state();
if (!ctx->Shared) {
- ALIGN_FREE( ctx->VB );
return GL_FALSE;
}
}
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;
if (!alloc_proxy_textures(ctx)) {
free_shared_state(ctx, ctx->Shared);
- ALIGN_FREE( ctx->VB );
return GL_FALSE;
}
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 );
}
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;
#if 0
if (!(ctx->TraceCtx)) {
free_shared_state(ctx, ctx->Shared);
- ALIGN_FREE( ctx->VB );
FREE( ctx->Exec );
FREE( ctx->Save );
FREE( ctx->TraceCtx );
_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);
_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);
}
+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.
_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.
_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;
}
}
void
_mesa_swapbuffers(GLcontext *ctx)
{
- FLUSH_VB( ctx, "swap buffers" );
+ FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
}
-/* $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
/*
- * 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
-/* $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
struct gl_pixelstore_attrib;
struct vertex_buffer;
-struct immediate;
struct gl_pipeline;
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.
*/
* 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
* 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:
/***
- *** 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;
/***
/***
*** 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()
*/
- 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.
*/
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);
};
--- /dev/null
+#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, " : ""
+ );
+}
--- /dev/null
+#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
-/* $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
#include "accum.h"
#include "attrib.h"
#include "bitmap.h"
-#include "bbox.h"
#include "blend.h"
#include "buffers.h"
#include "clip.h"
#include "context.h"
#include "convolve.h"
#include "copypix.h"
-#include "cva.h"
#include "depth.h"
#include "enable.h"
#include "enums.h"
#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
* 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,
OPCODE_READ_BUFFER,
OPCODE_RESET_HISTOGRAM,
OPCODE_RESET_MIN_MAX,
+ OPCODE_ROTATE,
OPCODE_SCALE,
OPCODE_SCISSOR,
OPCODE_SELECT_TEXTURE_SGIS,
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;
-/* 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 );
/**********************************************************************/
-/*
- * 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;
-}
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];
/* Most frequent case */
n += InstSize[n[0].opcode];
break;
+ }
}
}
-
+
_mesa_HashRemove(ctx->Shared->DisplayList, list);
}
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;
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;
/*
- * 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;
{
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;
}
-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;
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;
{
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;
}
{
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;
{
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;
{
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;
{
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;
}
{
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;
}
{
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;
}
{
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;
{
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;
{
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;
}
{
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;
}
{
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;
}
{
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];
{
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;
{
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;
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;
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;
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;
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;
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;
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;
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;
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;
{
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;
{
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;
{
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;
{
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;
{
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;
{
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;
{
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;
{
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;
{
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;
{
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;
{
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;
}
{
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;
}
{
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;
}
{
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;
{
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;
}
{
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;
}
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;
{
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;
}
{
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;
{
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;
{
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];
{
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;
}
{
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;
{
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;
{
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;
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;
{
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;
}
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)();
}
{
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;
{
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];
{
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;
{
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;
}
{
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;
}
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)();
}
{
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++) {
{
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;
}
{
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;
}
{
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;
{
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;
{
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 );
{
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 );
{
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;
{
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;
{
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;
}
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;
{
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++) {
{
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;
{
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;
{
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;
{
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;
{
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];
{
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;
}
{
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;
{
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 );
{
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;
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)();
}
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)();
}
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)();
}
{
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];
{
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;
}
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)();
}
{
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;
}
{
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;
{
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;
}
{
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;
}
{
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;
{
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;
}
{
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;
}
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 );
+ }
}
{
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;
{
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;
{
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;
}
{
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;
{
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;
}
{
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;
{
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;
{
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;
{
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;
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;
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;
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;
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;
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;
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;
{
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;
{
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;
{
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;
{
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;
}
{
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;
}
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);
}
{
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;
}
else {
Node *n;
GLvoid *image;
- FLUSH_VB(ctx, "dlist");
+ FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
/* make copy of image */
image = MALLOC(imageSize);
if (!image) {
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;
else {
Node *n;
GLvoid *image;
- FLUSH_VB(ctx, "dlist");
+ FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
/* make copy of image */
image = MALLOC(imageSize);
if (!image) {
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;
else {
Node *n;
GLvoid *image;
- FLUSH_VB(ctx, "dlist");
+ FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
/* make copy of image */
image = MALLOC(imageSize);
if (!image) {
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;
GLvoid *image;
GET_CURRENT_CONTEXT(ctx);
- FLUSH_VB(ctx, "dlist");
+ FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
/* make copy of image */
image = MALLOC(imageSize);
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;
GLvoid *image;
GET_CURRENT_CONTEXT(ctx);
- FLUSH_VB(ctx, "dlist");
+ FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
/* make copy of image */
image = MALLOC(imageSize);
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;
GLvoid *image;
GET_CURRENT_CONTEXT(ctx);
- FLUSH_VB(ctx, "dlist");
+ FLUSH_TNL( ctx, FLUSH_STORED_VERTICES );
/* make copy of image */
image = MALLOC(imageSize);
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;
{
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;
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
*
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;
{
Node *n;
GLboolean done;
- OpCode opcode;
if (!islist(ctx,list))
return;
-/* mesa_print_display_list( list ); */
+/* mesa_print_display_list( list ); */
ctx->CallDepth++;
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;
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 );
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;
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--;
}
_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));
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 );
}
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) {
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);
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.
*/
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;
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 );
/* 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;
{
Node *n;
GLboolean done;
- OpCode opcode;
if (!glIsList(list)) {
fprintf(f,"%u is not a display list ID\n",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;
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;
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;
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];
+ }
}
}
}
-/* $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
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
-/* $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
#include "glheader.h"
#include "colormac.h"
#include "context.h"
+#include "drawpix.h"
#include "feedback.h"
#include "macros.h"
#include "mem.h"
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;
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]);
-/* $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
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 );
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:
-/* $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.
-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 )
{
-/* 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;
- }
-}
-
-
-/* $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
const GLdouble *points );
-extern void gl_eval_vb( struct vertex_buffer *VB );
-
extern void
_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
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
-/* $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
}
-
-
-
-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 ) );
-}
-
-/* $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
_mesa_Fogiv(GLenum pname, const GLint *params );
-extern void
-_mesa_make_win_fog_coords( struct vertex_buffer *VB );
-
-
#endif
-/* $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
*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]);
*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]);
*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:
{
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]);
}
{
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]);
}
{
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]);
}
{
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]);
}
*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]);
/* 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:
*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];
*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];
*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:
{
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];
}
{
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];
}
{
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];
}
{
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];
}
*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]);
/* 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:
*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];
*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];
*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:
/* 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 */
*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]);
/* 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:
*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] );
*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];
*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:
{
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];
}
{
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];
}
{
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];
}
{
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];
}
*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] ) );
/* 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:
-/* $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
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;
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)
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;
}
}
-/* 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 )
light->_sli = DOT3(ci, light->Specular);
}
}
-
- gl_update_lighting_function(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;
- }
- }
-}
-/* $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 );
_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,
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 );
-/* $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
#include "mmath.h"
#include "texstate.h"
#include "types.h"
-#include "vb.h"
#endif
-/* $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
#include "glheader.h"
+/* Do not reference types.h from this file.
+ */
/* Limits: */
-/* $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
/**********************************************************************/
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 );
}
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 );
}
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:
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:
{
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;
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:
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:
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:
{
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;
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:
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 );
}
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);
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 );
}
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 );
}
_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 );
}
}
{
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 );
}
{
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 );
}
}
-
void
_mesa_LoadTransposeMatrixfARB( const GLfloat *m )
{
GLfloat tm[16];
- gl_matrix_transposef(tm, m);
+ _math_transposef(tm, m);
_mesa_LoadMatrixf(tm);
}
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);
}
_mesa_MultTransposeMatrixfARB( const GLfloat *m )
{
GLfloat tm[16];
- gl_matrix_transposef(tm, m);
+ _math_transposef(tm, m);
_mesa_MultMatrixf(tm);
}
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);
}
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;
-/* $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,
-/* $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
#include "points.h"
#include "texstate.h"
#include "types.h"
-#include "vb.h"
#endif
-/* $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
*/
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 );
-/* $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
#include "context.h"
#include "convolve.h"
#include "copypix.h"
-#include "cva.h"
#include "depth.h"
#include "dlist.h"
#include "drawpix.h"
#include "masking.h"
#include "matrix.h"
#include "mmath.h"
-#include "pipeline.h"
#include "pixel.h"
#include "pixeltex.h"
#include "points.h"
#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
/**********************************************************************/
-
-
-
-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 )
{
_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 );
}
}
*/
_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)
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 );
}
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().
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 );
_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)
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.
*/
_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;
}
-/* $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
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 );
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 );
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 );
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 );
}
-/*
- * 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;
-}
-/* $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
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
-/* $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
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 );
}
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 );
}
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 );
}
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 );
}
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 );
}
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 );
}
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 );
}
} 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 );
}
-/* 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)
-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);
-}
-
-/* $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
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
--- /dev/null
+/* $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);
+}
--- /dev/null
+/* $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); */
+}
--- /dev/null
+/* $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 */
--- /dev/null
+/* $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);
+}
--- /dev/null
+/* $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];
+}
--- /dev/null
+/* $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
--- /dev/null
+/* $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);
+}
--- /dev/null
+/* $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
+
+
--- /dev/null
+/* $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();
+}
--- /dev/null
+/* $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
--- /dev/null
+/* $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]);
+ }
+}
--- /dev/null
+/* $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
--- /dev/null
+/* $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();
+}
--- /dev/null
+/* $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
--- /dev/null
+/* $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
+}
-/* $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
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;
-/* $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
#include "glheader.h"
#include "macros.h"
#include "mmath.h"
-#include "vb.h"
#include "s_aaline.h"
#include "s_pb.h"
#include "s_context.h"
-/* $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
#include "macros.h"
#include "mmath.h"
#include "texstate.h"
-#include "vb.h"
#include "s_context.h"
#include "s_feedback.h"
-/* $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
#include "swrast_setup.h"
+#include "tnl/t_context.h"
/* Stub for swsetup->Triangle to select a true triangle function
* after a state change.
#include "macros.h"
#include "types.h"
+#include "tnl/t_context.h"
+
#include "ss_triangle.h"
#include "ss_context.h"
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;
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];
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;
#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"
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];
/* 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));
--- /dev/null
+#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
+}
--- /dev/null
+
+/* $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
--- /dev/null
+/* $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;
+}
+
--- /dev/null
+/* $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
--- /dev/null
+/*
+ * 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
-/* $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
-/* $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
#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 );
-/* $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
#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
-/* $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