diff options
author | Keith Whitwell <[email protected]> | 2000-11-16 21:05:34 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2000-11-16 21:05:34 +0000 |
commit | 23caf20169ac38436ee9c13914f1d6aa7cf6bb5e (patch) | |
tree | 21307f7bbcaf9ee1e841d7e7bee130570a7b5b95 /src | |
parent | 179516673211a2350e479d5321840291f339f5dd (diff) |
Move the transform and lighting code to two new directories
math: Provides basic matrix and vector functionality that
might be useful to multiple software t&l
implementations, and is used by core mesa to
manage the Model, Project, etc matrices.
tnl: The real transform & lighting code from core mesa,
including everything from glVertex3f through vertex
buffer handling, transformation, clipping, lighting
and handoff to a driver for rasterization.
The interfaces of these can be further tightened up, but the basic
splitting up of state and code move is done.
Diffstat (limited to 'src')
77 files changed, 8561 insertions, 5666 deletions
diff --git a/src/mesa/Makefile.X11 b/src/mesa/Makefile.X11 index 533e0c32d95..acec47b09ca 100644 --- a/src/mesa/Makefile.X11 +++ b/src/mesa/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.32 2000/11/11 19:09:29 brianp Exp $ +# $Id: Makefile.X11,v 1.33 2000/11/16 21:05:34 keithw Exp $ # Mesa 3-D graphics library # Version: 3.5 @@ -21,10 +21,31 @@ LIBDIR = ../lib CORE_SOURCES = \ + tnl/t_bbox.c \ + tnl/t_clip.c \ + tnl/t_context.c \ + tnl/t_cva.c \ + tnl/t_debug.c \ + tnl/t_dlist.c \ + tnl/t_eval.c \ + tnl/t_fog.c \ + tnl/t_light.c \ + tnl/t_pipeline.c \ + tnl/t_rect.c \ + tnl/t_shade.c \ + tnl/t_stages.c \ + tnl/t_texture.c \ + tnl/t_trans_elt.c \ + tnl/t_varray.c \ + tnl/t_vb.c \ + tnl/t_vbcull.c \ + tnl/t_vbfill.c \ + tnl/t_vbindirect.c \ + tnl/t_vbrender.c \ + tnl/t_vbxform.c \ accum.c \ alpha.c \ attrib.c \ - bbox.c \ bitmap.c \ blend.c \ buffers.c \ @@ -34,8 +55,7 @@ CORE_SOURCES = \ context.c \ convolve.c \ copypix.c \ - cva.c \ - debug_xform.c \ + debug.c \ depth.c \ dispatch.c \ dlist.c \ @@ -64,7 +84,6 @@ CORE_SOURCES = \ matrix.c \ mem.c \ mmath.c \ - pipeline.c \ pixel.c \ pixeltex.c \ points.c \ @@ -73,8 +92,6 @@ CORE_SOURCES = \ readpix.c \ rect.c \ scissor.c \ - shade.c \ - stages.c \ state.c \ stencil.c \ teximage.c \ @@ -82,18 +99,8 @@ CORE_SOURCES = \ texstate.c \ texture.c \ texutil.c \ - translate.c \ varray.c \ - vb.c \ - vbcull.c \ - vbfill.c \ - vbindirect.c \ - vbrender.c \ - vbxform.c \ - vector.c \ - vertices.c \ winpos.c \ - xform.c \ X86/x86.c \ X86/common_x86.c \ X86/3dnow.c \ @@ -129,9 +136,13 @@ CORE_SOURCES = \ swrast/s_zoom.c \ swrast_setup/ss_context.c \ swrast_setup/ss_triangle.c \ - swrast_setup/ss_vb.c - - + swrast_setup/ss_vb.c \ + math/m_debug_xform.c \ + math/m_matrix.c \ + math/m_translate.c \ + math/m_vector.c \ + math/m_vertices.c \ + math/m_xform.c diff --git a/src/mesa/drivers/ggi/ggimesa.c b/src/mesa/drivers/ggi/ggimesa.c index 125aefcfb67..764ccba803e 100644 --- a/src/mesa/drivers/ggi/ggimesa.c +++ b/src/mesa/drivers/ggi/ggimesa.c @@ -508,7 +508,7 @@ void GGIMesaSwapBuffers(void) { GGIMESADPRINT_CORE("GGIMesaSwapBuffers\n"); - FLUSH_VB(GGIMesa->gl_ctx, "swap buffers"); + _mesa_swapbuffers( GGIMesa->gl_ctx ); gl_ggiFlush(GGIMesa->gl_ctx); if (GGIMesa->gl_vis->DBflag) diff --git a/src/mesa/drivers/glide/fxapi.c b/src/mesa/drivers/glide/fxapi.c index ea5f816258e..f3a6431aec5 100644 --- a/src/mesa/drivers/glide/fxapi.c +++ b/src/mesa/drivers/glide/fxapi.c @@ -43,579 +43,6 @@ */ -/* 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 ([email protected]) 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 ([email protected]) - * - 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 ([email protected]) Avid Technology - * - fixed display list share bug for MESA_GLX_FX = window/fullscreen - * - fixed glClear/gl...Mask related problem - * - * Bert Schoenwaelder ([email protected]) - * - 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 ([email protected]) - * - enabled the macro FLOAT_COLOR_TO_UBYTE_COLOR under - * windows - * - written an asm x86 optimized float->integer conversions - * for windows - * - * Theodore Jump ([email protected]) - * - 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 ([email protected]) 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 ([email protected]) - * - written the SST_DUALHEAD support in the WGL emulator - * - * Daryll Strauss ([email protected]) - * - fixed the Voodoo Rush support for the in window rendering - * - * V0.28 - David Bucciarelli ([email protected]) 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 ([email protected]) 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 <[email protected]> - * - fixed a new bug in the wglUseFontBitmaps code - * - * Ralf Knoesel ([email protected]) - * - fixed a bug in the wglUseFontBitmaps code - * - * Rune Hasvold ([email protected]) - * - fixed a problem related to the aux usage in the fxBestResolution - * function - * - fixed the order of pixel formats in the WGL emulator - * - * Fredrik Hubinette ([email protected]) - * - the driver shutdown the Glide for most common signals - * - * V0.26 - David Bucciarelli ([email protected]) 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 ([email protected]) - * - highly optimized the driver functions for writing pixel - * span (2-3 times faster !) - * - * Axel W. Volley ([email protected]) Krauss-Maffei Wehrtechnik - * - written the fxDDReadDepthSpanFloat() and fxDDReadDepthSpanInt() - * functions - * - * V0.25 - David Bucciarelli ([email protected]) 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 ([email protected]) 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 ([email protected]) - * - written the wglUseFontBitmaps() function in the WGL emulator - * - * V0.24 - David Bucciarelli ([email protected]) 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 ([email protected]) - * - 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 ([email protected]) 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 ([email protected]) - * - fixed a bug in the texparam() function - * - * Brian Paul ([email protected]) Avid Technology - * - sources accomodated for the new Mesa 3.0beta1 - * - * V0.22 - David Bucciarelli ([email protected]) 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 ([email protected]) - * - 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 ([email protected]) STN Atlas Elektronik GmbH - * - applied some patch for the Voodoo Rush - * - * V0.21 - David Bucciarelli ([email protected]) 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 <[email protected]> - * - fixed a Voodoo Rush related problem in the fxwgl.c - * - * Daryll Strauss <[email protected]> - * - written the scissor test support - * - * V0.20 - David Bucciarelli ([email protected]) 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 ([email protected]) Avid Technology - * - added write_monocolor_span(), fixed bug in write_color_span() - * - added test for stenciling in choosepoint/line/triangle functions - * - * Joe Waters ([email protected]) Aegis - * - written the support for the env. var. SST_SCREENREFRESH - * - * V0.19 - David Bucciarelli ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) Nova Computer s.r.l. - * - written the fxCloseHardware() and the fxQuaryHardware() (mainly - * for the VoodooWGL emulator) - * - * Brian Paul ([email protected]) 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 ([email protected]) Humanware s.r.l. - * - optimized the bitmap support (66% faster) - * - tested with the Mesa 2.3beta2 - * - * Diego Picciani ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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 ([email protected]) Humanware s.r.l. - * - Initial revision - * - */ - - #ifdef HAVE_CONFIG_H #include "conf.h" #endif @@ -686,13 +113,6 @@ fxMesaContext GLAPIENTRY fxMesaGetCurrentContext(void) } -void GLAPIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f) -{ - if(fxMesaCurrentCtx) - fxDDSetNearFar(fxMesaCurrentCtx->glCtx,n,f); -} - - /* * The 3Dfx Global Palette extension for GLQuake. * More a trick than a real extesion, use the shared global @@ -1294,7 +714,7 @@ void GLAPIENTRY fxMesaSwapBuffers(void) } if(fxMesaCurrentCtx) { - FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" ); + _mesa_swapbuffers( fxMesaCurrentCtx->glCtx ); if(fxMesaCurrentCtx->haveDoubleBuffer) { diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index e70be6cd6b0..178fa192ac0 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -58,6 +58,7 @@ #include "extensions.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" /* These lookup table are used to extract RGB values in [0,255] from * 16-bit pixel values. @@ -611,11 +612,6 @@ static void fxDDFinish(GLcontext *ctx) -void fxDDSetNearFar(GLcontext *ctx, GLfloat n, GLfloat f) -{ - FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG; - ctx->Driver.RenderStart = fxSetupFXUnits; -} /* KW: Put the word Mesa in the render string because quakeworld * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE). @@ -763,35 +759,28 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa ) /* Initialize the software rasterizer and helper modules. */ + fxMesa->glCtx->Driver.RegisterVB = fxDDRegisterVB; + _swrast_CreateContext( fxMesa->glCtx ); _swsetup_CreateContext( fxMesa->glCtx ); + _tnl_CreateContext( fxMesa->glCtx ); + + fxSetupDDPointers(fxMesa->glCtx); /* Tell the software rasterizer to use pixel fog always. */ _swrast_allow_vertex_fog( fxMesa->glCtx, GL_FALSE ); _swrast_allow_pixel_fog( fxMesa->glCtx, GL_TRUE ); - fxSetupDDPointers(fxMesa->glCtx); fxDDInitExtensions(fxMesa->glCtx); - fxDDSetNearFar(fxMesa->glCtx,1.0,100.0); - FX_grGlideGetState((GrState*)fxMesa->state); - /* XXX Fix me: callback not registered when main VB is created. - */ - if (fxMesa->glCtx->VB) - fxDDRegisterVB( fxMesa->glCtx->VB ); - /* XXX Fix me too: need to have the 'struct dd' prepared prior to * creating the context... The below is broken if you try to insert * new stages. */ - if (fxMesa->glCtx->NrPipelineStages) - fxMesa->glCtx->NrPipelineStages = fxDDRegisterPipelineStages( - fxMesa->glCtx->PipelineStage, - fxMesa->glCtx->PipelineStage, - fxMesa->glCtx->NrPipelineStages); + fxDDRegisterPipelineStages( fxMesa->glCtx ); /* Run the config file */ _mesa_context_initialize( fxMesa->glCtx ); @@ -936,6 +925,15 @@ static void fxDDUpdateDDPointers(GLcontext *ctx) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + + /* Recalculate fog table on projection matrix changes. This used to + * be triggered by the NearFar callback. + */ + if (new_state & _NEW_PROJECTION) { + FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG; + ctx->Driver.RenderStart = fxSetupFXUnits; + } if (new_state & (_FX_NEW_IS_IN_HARDWARE | _FX_NEW_RENDERSTATE | @@ -965,7 +963,6 @@ void fxSetupDDPointers(GLcontext *ctx) fprintf(stderr,"fxmesa: fxSetupDDPointers()\n"); } - ctx->Driver.UpdateStateNotify = ~0; ctx->Driver.UpdateState=fxDDUpdateDDPointers; ctx->Driver.WriteDepthSpan=fxDDWriteDepthSpan; @@ -975,8 +972,6 @@ void fxSetupDDPointers(GLcontext *ctx) ctx->Driver.GetString=fxDDGetString; - ctx->Driver.NearFar=fxDDSetNearFar; - ctx->Driver.ClearIndex=NULL; ctx->Driver.ClearColor=fxDDClearColor; ctx->Driver.Clear=fxDDClear; @@ -1009,8 +1004,6 @@ void fxSetupDDPointers(GLcontext *ctx) ctx->Driver.DeleteTexture=fxDDTexDel; ctx->Driver.UpdateTexturePalette=fxDDTexPalette; - ctx->Driver.RectFunc=NULL; - ctx->Driver.AlphaFunc=fxDDAlphaFunc; ctx->Driver.BlendFunc=fxDDBlendFunc; ctx->Driver.DepthFunc=fxDDDepthFunc; @@ -1026,8 +1019,6 @@ void fxSetupDDPointers(GLcontext *ctx) ctx->Driver.RegisterVB=fxDDRegisterVB; ctx->Driver.UnregisterVB=fxDDUnregisterVB; - ctx->Driver.RegisterPipelineStages = fxDDRegisterPipelineStages; - if (!getenv("FX_NO_FAST")) ctx->Driver.BuildPrecalcPipeline = fxDDBuildPrecalcPipeline; diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h index 833abceb34f..04049f091fa 100644 --- a/src/mesa/drivers/glide/fxdrv.h +++ b/src/mesa/drivers/glide/fxdrv.h @@ -62,14 +62,12 @@ #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 - @@ -476,7 +474,6 @@ extern int glbCurrentBoard; extern void fxPrintSetupFlags( const char *msg, GLuint flags ); extern void fxSetupFXUnits(GLcontext *); extern void fxSetupDDPointers(GLcontext *); -extern void fxDDSetNearFar(GLcontext *, GLfloat, GLfloat); extern void fxDDSetupInit(void); extern void fxDDCvaInit(void); @@ -533,9 +530,7 @@ extern void fxDDPartialRasterSetup( struct vertex_buffer *VB ); extern void fxDDDoRasterSetup( struct vertex_buffer *VB ); -extern GLuint fxDDRegisterPipelineStages( struct gl_pipeline_stage *out, - const struct gl_pipeline_stage *in, - GLuint nr ); +extern void fxDDRegisterPipelineStages( GLcontext *ctx ); extern GLboolean fxDDBuildPrecalcPipeline( GLcontext *ctx ); diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c index 5d5cd112924..2cc6add1d28 100644 --- a/src/mesa/drivers/glide/fxsetup.c +++ b/src/mesa/drivers/glide/fxsetup.c @@ -54,6 +54,8 @@ #include "fxdrv.h" #include "enums.h" +#include "tnl/t_context.h" + static GLuint fxGetTexSetConfiguration(GLcontext *ctx, struct gl_texture_object *tObj0, struct gl_texture_object *tObj1); diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 39d256a77f3..74850556a76 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -1,4 +1,4 @@ -/* $Id: osmesa.c,v 1.30 2000/11/14 17:50:07 brianp Exp $ */ +/* $Id: osmesa.c,v 1.31 2000/11/16 21:05:38 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -311,11 +311,11 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, { GLcontext *ctx = &osmesa->gl_ctx; + ctx->Driver.RegisterVB = _swsetup_RegisterVB; + _swrast_CreateContext( ctx ); _swsetup_CreateContext( ctx ); - - if (ctx->VB) - _swsetup_RegisterVB( ctx->VB ); + _tnl_CreateContext( ctx ); osmesa_register_swrast_functions( ctx ); } @@ -1690,7 +1690,6 @@ static void osmesa_update_state( GLcontext *ctx ) ASSERT((void *) osmesa == (void *) ctx->DriverCtx); ctx->Driver.GetString = get_string; - ctx->Driver.UpdateStateNotify = ~0; ctx->Driver.UpdateState = osmesa_update_state; ctx->Driver.SetDrawBuffer = set_draw_buffer; @@ -1747,4 +1746,8 @@ static void osmesa_update_state( GLcontext *ctx ) ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels; ctx->Driver.ReadCI32Span = read_index_span; ctx->Driver.ReadCI32Pixels = read_index_pixels; + + _swrast_InvalidateState( ctx, ctx->NewState ); + _swsetup_InvalidateState( ctx, ctx->NewState ); + _tnl_InvalidateState( ctx, ctx->NewState ); } diff --git a/src/mesa/drivers/svga/svgamesa.c b/src/mesa/drivers/svga/svgamesa.c index daa660e434b..5163e08ece6 100644 --- a/src/mesa/drivers/svga/svgamesa.c +++ b/src/mesa/drivers/svga/svgamesa.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa.c,v 1.7 2000/11/14 17:40:14 brianp Exp $ */ +/* $Id: svgamesa.c,v 1.8 2000/11/16 21:05:39 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -487,7 +487,7 @@ void SVGAMesaSwapBuffers( void ) copy_buffer(SVGABuffer.BackBuffer); #ifndef DEV - FLUSH_VB( SVGAMesa->gl_ctx, "swap buffers" ); + _mesa_swapbuffers( SVGAMesa->gl_ctx ); if (SVGAMesa->gl_vis->DBflag) #endif /* DEV */ { diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index 9fa029cd485..f48da3bbfe5 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -1,4 +1,4 @@ -/* $Id: xm_api.c,v 1.7 2000/11/14 17:40:15 brianp Exp $ */ +/* $Id: xm_api.c,v 1.8 2000/11/16 21:05:40 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -78,6 +78,7 @@ #include "macros.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" #ifndef GLX_NONE_EXT #define GLX_NONE_EXT 0x8000 @@ -1654,7 +1655,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */ ctx->Driver.UpdateState = xmesa_update_state; - ctx->Driver.UpdateStateNotify = ~0; #if defined(GLX_DIRECT_RENDERING) && !defined(XFree86Server) c->driContextPriv = driContextPriv; @@ -1664,14 +1664,11 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) */ xmesa_init_pointers( ctx ); - if (ctx->VB) - _swsetup_RegisterVB( ctx->VB ); - - /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); _swsetup_CreateContext( ctx ); + _tnl_CreateContext( ctx ); xmesa_register_swrast_functions( ctx ); diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 81700b5a52f..21c984d310c 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -1,4 +1,4 @@ -/* $Id: xm_dd.c,v 1.5 2000/11/14 17:40:15 brianp Exp $ */ +/* $Id: xm_dd.c,v 1.6 2000/11/16 21:05:40 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -32,12 +32,12 @@ #include "state.h" #include "depth.h" #include "macros.h" -#include "vb.h" #include "types.h" #include "xmesaP.h" #include "extensions.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" /* * Return the size (width,height of the current color buffer. @@ -871,6 +871,7 @@ void xmesa_update_state( GLcontext *ctx ) */ _swrast_InvalidateState( ctx, ctx->NewState ); _swsetup_InvalidateState( ctx, ctx->NewState ); + _tnl_InvalidateState( ctx, ctx->NewState ); /* setup pointers to front and back buffer clear functions */ diff --git a/src/mesa/drivers/x11/xm_line.c b/src/mesa/drivers/x11/xm_line.c index 9b5386caa6e..0513d045abc 100644 --- a/src/mesa/drivers/x11/xm_line.c +++ b/src/mesa/drivers/x11/xm_line.c @@ -1,4 +1,4 @@ -/* $Id: xm_line.c,v 1.9 2000/11/14 17:40:15 brianp Exp $ */ +/* $Id: xm_line.c,v 1.10 2000/11/16 21:05:40 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -35,7 +35,6 @@ #include "glxheader.h" #include "depth.h" #include "macros.h" -#include "vb.h" #include "types.h" #include "xmesaP.h" diff --git a/src/mesa/drivers/x11/xm_span.c b/src/mesa/drivers/x11/xm_span.c index 18f7de4f385..0d4eaab1c6d 100644 --- a/src/mesa/drivers/x11/xm_span.c +++ b/src/mesa/drivers/x11/xm_span.c @@ -1,4 +1,4 @@ -/* $Id: xm_span.c,v 1.2 2000/11/14 17:40:15 brianp Exp $ */ +/* $Id: xm_span.c,v 1.3 2000/11/16 21:05:40 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -32,7 +32,6 @@ #include "state.h" #include "depth.h" #include "macros.h" -#include "vb.h" #include "types.h" #include "xmesaP.h" #include "extensions.h" diff --git a/src/mesa/drivers/x11/xm_tri.c b/src/mesa/drivers/x11/xm_tri.c index a25d58092b8..0badaede8c6 100644 --- a/src/mesa/drivers/x11/xm_tri.c +++ b/src/mesa/drivers/x11/xm_tri.c @@ -1,4 +1,4 @@ -/* $Id: xm_tri.c,v 1.9 2000/11/14 17:40:15 brianp Exp $ */ +/* $Id: xm_tri.c,v 1.10 2000/11/16 21:05:40 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -35,7 +35,6 @@ #include "glxheader.h" #include "depth.h" #include "macros.h" -#include "vb.h" #include "types.h" #include "xmesaP.h" @@ -1411,7 +1410,7 @@ static void flat_LOOKUP8_triangle( GLcontext *ctx, #ifdef DEBUG -void +static void _xmesa_print_triangle_func( swrast_tri_func triFunc ) { printf("XMesa tri func = "); diff --git a/src/mesa/main/Makefile.X11 b/src/mesa/main/Makefile.X11 index 533e0c32d95..acec47b09ca 100644 --- a/src/mesa/main/Makefile.X11 +++ b/src/mesa/main/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.32 2000/11/11 19:09:29 brianp Exp $ +# $Id: Makefile.X11,v 1.33 2000/11/16 21:05:34 keithw Exp $ # Mesa 3-D graphics library # Version: 3.5 @@ -21,10 +21,31 @@ LIBDIR = ../lib CORE_SOURCES = \ + tnl/t_bbox.c \ + tnl/t_clip.c \ + tnl/t_context.c \ + tnl/t_cva.c \ + tnl/t_debug.c \ + tnl/t_dlist.c \ + tnl/t_eval.c \ + tnl/t_fog.c \ + tnl/t_light.c \ + tnl/t_pipeline.c \ + tnl/t_rect.c \ + tnl/t_shade.c \ + tnl/t_stages.c \ + tnl/t_texture.c \ + tnl/t_trans_elt.c \ + tnl/t_varray.c \ + tnl/t_vb.c \ + tnl/t_vbcull.c \ + tnl/t_vbfill.c \ + tnl/t_vbindirect.c \ + tnl/t_vbrender.c \ + tnl/t_vbxform.c \ accum.c \ alpha.c \ attrib.c \ - bbox.c \ bitmap.c \ blend.c \ buffers.c \ @@ -34,8 +55,7 @@ CORE_SOURCES = \ context.c \ convolve.c \ copypix.c \ - cva.c \ - debug_xform.c \ + debug.c \ depth.c \ dispatch.c \ dlist.c \ @@ -64,7 +84,6 @@ CORE_SOURCES = \ matrix.c \ mem.c \ mmath.c \ - pipeline.c \ pixel.c \ pixeltex.c \ points.c \ @@ -73,8 +92,6 @@ CORE_SOURCES = \ readpix.c \ rect.c \ scissor.c \ - shade.c \ - stages.c \ state.c \ stencil.c \ teximage.c \ @@ -82,18 +99,8 @@ CORE_SOURCES = \ texstate.c \ texture.c \ texutil.c \ - translate.c \ varray.c \ - vb.c \ - vbcull.c \ - vbfill.c \ - vbindirect.c \ - vbrender.c \ - vbxform.c \ - vector.c \ - vertices.c \ winpos.c \ - xform.c \ X86/x86.c \ X86/common_x86.c \ X86/3dnow.c \ @@ -129,9 +136,13 @@ CORE_SOURCES = \ swrast/s_zoom.c \ swrast_setup/ss_context.c \ swrast_setup/ss_triangle.c \ - swrast_setup/ss_vb.c - - + swrast_setup/ss_vb.c \ + math/m_debug_xform.c \ + math/m_matrix.c \ + math/m_translate.c \ + math/m_vector.c \ + math/m_vertices.c \ + math/m_xform.c diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 66557b1066b..b6c5174def7 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1,4 +1,4 @@ -/* $Id: attrib.c,v 1.33 2000/11/05 18:40:57 keithw Exp $ */ +/* $Id: attrib.c,v 1.34 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -136,6 +136,9 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_CURRENT_BIT) { struct gl_current_attrib *attr; + + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); + attr = MALLOC_STRUCT( gl_current_attrib ); MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) ); newnode = new_attrib_node( GL_CURRENT_BIT ); @@ -612,6 +615,7 @@ _mesa_PopAttrib(void) } break; case GL_CURRENT_BIT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); MEMCPY( &ctx->Current, attr->data, sizeof(struct gl_current_attrib) ); break; diff --git a/src/mesa/main/clip.c b/src/mesa/main/clip.c index 244753020b1..77d12814055 100644 --- a/src/mesa/main/clip.c +++ b/src/mesa/main/clip.c @@ -1,4 +1,4 @@ -/* $Id: clip.c,v 1.14 2000/11/13 20:02:56 keithw Exp $ */ +/* $Id: clip.c,v 1.15 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -30,133 +30,16 @@ #else #include "glheader.h" #include "clip.h" -#include "colormac.h" #include "context.h" #include "macros.h" -#include "matrix.h" #include "mmath.h" #include "types.h" -#include "vb.h" -#include "xform.h" -#endif - - - - -#define CLIP_RGBA0 0x1 -#define CLIP_RGBA1 0x2 -#define CLIP_TEX0 0x4 -#define CLIP_TEX1 0x8 -#define CLIP_INDEX0 0x10 -#define CLIP_INDEX1 0x20 -#define CLIP_FOG_COORD 0x40 - - -/* Linear interpolation between A and B: */ -#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) - - - -#define INTERP_SZ( t, vec, to, a, b, sz ) \ -do { \ - switch (sz) { \ - case 4: vec[to][3] = LINTERP( t, vec[a][3], vec[b][3] ); \ - case 3: vec[to][2] = LINTERP( t, vec[a][2], vec[b][2] ); \ - case 2: vec[to][1] = LINTERP( t, vec[a][1], vec[b][1] ); \ - case 1: vec[to][0] = LINTERP( t, vec[a][0], vec[b][0] ); \ - } \ -} while(0) - - -static clip_interp_func clip_interp_tab[0x80]; - -#define IND 0 -#define NAME clip_nil -#include "interp_tmp.h" - -#define IND (CLIP_RGBA0) -#define NAME clipRGBA0 -#include "interp_tmp.h" - -#define IND (CLIP_RGBA0|CLIP_RGBA1) -#define NAME clipRGBA0_RGBA1 -#include "interp_tmp.h" - -#define IND (CLIP_TEX0|CLIP_RGBA0) -#define NAME clipTEX0_RGBA0 -#include "interp_tmp.h" - -#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1) -#define NAME clipTEX0_RGBA0_RGBA1 -#include "interp_tmp.h" - -#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0) -#define NAME clipTEX1_TEX0_RGBA0 -#include "interp_tmp.h" - -#define IND (CLIP_TEX0) -#define NAME clipTEX0 -#include "interp_tmp.h" - -#define IND (CLIP_TEX1|CLIP_TEX0) -#define NAME clipTEX1_TEX0 -#include "interp_tmp.h" - -#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1) -#define NAME clipTEX1_TEX0_RGBA0_RGBA1 -#include "interp_tmp.h" - -#define IND (CLIP_INDEX0) -#define NAME clipINDEX0 -#include "interp_tmp.h" - -#define IND (CLIP_INDEX0|CLIP_INDEX1) -#define NAME clipINDEX0_INDEX1 -#include "interp_tmp.h" - -#define IND (CLIP_FOG_COORD) -#define NAME clip_FOG -#include "interp_tmp.h" - -#define IND (CLIP_RGBA0|CLIP_FOG_COORD) -#define NAME clipRGBA0_FOG -#include "interp_tmp.h" - -#define IND (CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD) -#define NAME clipRGBA0_RGBA1_FOG -#include "interp_tmp.h" - -#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD) -#define NAME clipTEX0_RGBA0_FOG -#include "interp_tmp.h" - -#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD) -#define NAME clipTEX0_RGBA0_RGBA1_FOG -#include "interp_tmp.h" - -#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD) -#define NAME clipTEX1_TEX0_RGBA0_FOG -#include "interp_tmp.h" - -#define IND (CLIP_TEX0|CLIP_FOG_COORD) -#define NAME clipTEX0_FOG -#include "interp_tmp.h" -#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_FOG_COORD) -#define NAME clipTEX1_TEX0_FOG -#include "interp_tmp.h" - -#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD) -#define NAME clipTEX1_TEX0_RGBA0_RGBA1_FOG -#include "interp_tmp.h" +#include "math/m_xform.h" +#include "math/m_matrix.h" +#endif -#define IND (CLIP_INDEX0|CLIP_FOG_COORD) -#define NAME clipINDEX0_FOG -#include "interp_tmp.h" -#define IND (CLIP_INDEX0|CLIP_INDEX1|CLIP_FOG_COORD) -#define NAME clipINDEX0_INDEX1_FOG -#include "interp_tmp.h" @@ -173,12 +56,6 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) GET_CURRENT_CONTEXT(ctx); GLint p; GLfloat equation[4]; - - equation[0] = eq[0]; - equation[1] = eq[1]; - equation[2] = eq[2]; - equation[3] = eq[3]; - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClipPlane"); p = (GLint) plane - (GLint) GL_CLIP_PLANE0; @@ -187,6 +64,11 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) return; } + equation[0] = eq[0]; + equation[1] = eq[1]; + equation[2] = eq[2]; + equation[3] = eq[3]; + /* * The equation is transformed by the transpose of the inverse of the * current modelview matrix and stored in the resulting eye coordinates. @@ -195,17 +77,21 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) * clipping now takes place. The clip-space equations are recalculated * whenever the projection matrix changes. */ - if (ctx->ModelView.flags & MAT_DIRTY_ALL_OVER) { - gl_matrix_analyze( &ctx->ModelView ); - } + if (ctx->ModelView.flags & MAT_DIRTY) + _math_matrix_analyze( &ctx->ModelView ); + gl_transform_vector( ctx->Transform.EyeUserPlane[p], equation, ctx->ModelView.inv ); + /* Update derived state. This state also depends on the projection + * matrix, and is recalculated on changes to the projection matrix by + * code in gl_update_state(). + */ if (ctx->Transform.ClipEnabled[p]) { - if (ctx->ProjectionMatrix.flags & MAT_DIRTY_ALL_OVER) { - gl_matrix_analyze( &ctx->ProjectionMatrix ); - } + if (ctx->ProjectionMatrix.flags & MAT_DIRTY) + _math_matrix_analyze( &ctx->ProjectionMatrix ); + gl_transform_vector( ctx->Transform._ClipUserPlane[p], ctx->Transform.EyeUserPlane[p], ctx->ProjectionMatrix.inv ); @@ -235,268 +121,3 @@ _mesa_GetClipPlane( GLenum plane, GLdouble *equation ) equation[2] = (GLdouble) ctx->Transform.EyeUserPlane[p][2]; equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3]; } - - - - -/**********************************************************************/ -/* View volume clipping. */ -/**********************************************************************/ - - -/* - * Clip a point against the view volume. - * Input: v - vertex-vector describing the point to clip - * Return: 0 = outside view volume - * 1 = inside view volume - */ -GLuint gl_viewclip_point( const GLfloat v[] ) -{ - if ( v[0] > v[3] || v[0] < -v[3] - || v[1] > v[3] || v[1] < -v[3] - || v[2] > v[3] || v[2] < -v[3] ) { - return 0; - } - else { - return 1; - } -} - -/* - * Clip a point against the user clipping planes. - * Input: v - vertex-vector describing the point to clip. - * Return: 0 = point was clipped - * 1 = point not clipped - */ -GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] ) -{ - GLuint p; - - for (p=0;p<MAX_CLIP_PLANES;p++) { - if (ctx->Transform.ClipEnabled[p]) { - GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0] - + v[1] * ctx->Transform._ClipUserPlane[p][1] - + v[2] * ctx->Transform._ClipUserPlane[p][2] - + v[3] * ctx->Transform._ClipUserPlane[p][3]; - if (dot < 0.0F) { - return 0; - } - } - } - - return 1; -} - - - - -#if 0 -#define NEGATIVE(x) ((*(int *)&x)<0) -#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) -#else -#define NEGATIVE(x) (x < 0) -#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) -#endif - - -static clip_poly_func gl_poly_clip_tab[2][5]; -static clip_line_func gl_line_clip_tab[2][5]; - -#define W(i) coord[i][3] -#define Z(i) coord[i][2] -#define Y(i) coord[i][1] -#define X(i) coord[i][0] -#define SIZE 4 -#define IND 0 -#define TAG(x) x##_4 -#include "clip_funcs.h" - -#define W(i) 1.0 -#define Z(i) coord[i][2] -#define Y(i) coord[i][1] -#define X(i) coord[i][0] -#define SIZE 3 -#define IND 0 -#define TAG(x) x##_3 -#include "clip_funcs.h" - -#define W(i) 1.0 -#define Z(i) 0.0 -#define Y(i) coord[i][1] -#define X(i) coord[i][0] -#define SIZE 2 -#define IND 0 -#define TAG(x) x##_2 -#include "clip_funcs.h" - -#define W(i) coord[i][3] -#define Z(i) coord[i][2] -#define Y(i) coord[i][1] -#define X(i) coord[i][0] -#define SIZE 4 -#define IND CLIP_TAB_EDGEFLAG -#define TAG(x) x##_4_edgeflag -#include "clip_funcs.h" - -#define W(i) 1.0 -#define Z(i) coord[i][2] -#define Y(i) coord[i][1] -#define X(i) coord[i][0] -#define SIZE 3 -#define IND CLIP_TAB_EDGEFLAG -#define TAG(x) x##_3_edgeflag -#include "clip_funcs.h" - -#define W(i) 1.0 -#define Z(i) 0.0 -#define Y(i) coord[i][1] -#define X(i) coord[i][0] -#define SIZE 2 -#define IND CLIP_TAB_EDGEFLAG -#define TAG(x) x##_2_edgeflag -#include "clip_funcs.h" - - - - -void gl_update_clipmask( GLcontext *ctx ) -{ - GLuint mask = 0; - - if (ctx->Visual.RGBAflag) - { - mask |= CLIP_RGBA0; - - if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_SEPERATE_SPECULAR)) - mask |= CLIP_RGBA1; - - if (ctx->Texture._ReallyEnabled & 0xf0) - mask |= CLIP_TEX1|CLIP_TEX0; - - if (ctx->Texture._ReallyEnabled & 0xf) - mask |= CLIP_TEX0; - } - else if (ctx->Light.ShadeModel==GL_SMOOTH) - { - mask |= CLIP_INDEX0; - - if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) - mask |= CLIP_INDEX1; - } - - if (ctx->Fog.Enabled) - mask |= CLIP_FOG_COORD; - - ctx->_ClipInterpFunc = clip_interp_tab[mask]; - ctx->_poly_clip_tab = gl_poly_clip_tab[0]; - ctx->_line_clip_tab = gl_line_clip_tab[0]; - - if (ctx->_TriangleCaps & DD_TRI_UNFILLED) { - ctx->_poly_clip_tab = gl_poly_clip_tab[1]; - ctx->_line_clip_tab = gl_line_clip_tab[0]; - } -} - - -#define USER_CLIPTEST(NAME, SZ) \ -static void NAME( struct vertex_buffer *VB ) \ -{ \ - GLcontext *ctx = VB->ctx; \ - GLubyte *clipMask = VB->ClipMask; \ - GLubyte *userClipMask = VB->UserClipMask; \ - GLuint start = VB->Start; \ - GLuint count = VB->Count; \ - GLuint p, i; \ - GLubyte bit; \ - \ - \ - for (bit = 1, p = 0; p < MAX_CLIP_PLANES ; p++, bit *=2) \ - if (ctx->Transform.ClipEnabled[p]) { \ - GLuint nr = 0; \ - const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; \ - const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; \ - const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; \ - const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; \ - GLfloat *coord = VB->ClipPtr->start; \ - GLuint stride = VB->ClipPtr->stride; \ - \ - for (i = start ; i < count ; i++, STRIDE_F(coord, stride)) { \ - GLfloat dp = coord[0] * a + coord[1] * b; \ - if (SZ > 2) dp += coord[2] * c; \ - if (SZ > 3) dp += coord[3] * d; else dp += d; \ - \ - if (dp < 0) { \ - clipMask[i] |= CLIP_USER_BIT; \ - userClipMask[i] |= bit; \ - nr++; \ - } \ - } \ - \ - if (nr > 0) { \ - VB->ClipOrMask |= CLIP_USER_BIT; \ - VB->CullMode |= CLIP_MASK_ACTIVE; \ - if (nr == count - start) { \ - VB->ClipAndMask |= CLIP_USER_BIT; \ - VB->Culled = 1; \ - return; \ - } \ - } \ - } \ -} - - -USER_CLIPTEST(userclip2, 2) -USER_CLIPTEST(userclip3, 3) -USER_CLIPTEST(userclip4, 4) - -static void (*(usercliptab[5]))( struct vertex_buffer * ) = { - 0, - 0, - userclip2, - userclip3, - userclip4 -}; - -void gl_user_cliptest( struct vertex_buffer *VB ) -{ - usercliptab[VB->ClipPtr->size]( VB ); -} - - -void gl_init_clip(void) -{ - init_clip_funcs_4(); - init_clip_funcs_3(); - init_clip_funcs_2(); - - init_clip_funcs_4_edgeflag(); - init_clip_funcs_3_edgeflag(); - init_clip_funcs_2_edgeflag(); - - clip_interp_tab[0] = clip_nil; - clip_interp_tab[CLIP_RGBA0] = clipRGBA0; - clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1] = clipRGBA0_RGBA1; - clip_interp_tab[CLIP_TEX0|CLIP_RGBA0] = clipTEX0_RGBA0; - clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = clipTEX0_RGBA0_RGBA1; - clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0] = clipTEX1_TEX0_RGBA0; - clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = - clipTEX1_TEX0_RGBA0_RGBA1; - clip_interp_tab[CLIP_TEX0] = clipTEX0; - clip_interp_tab[CLIP_TEX1|CLIP_TEX0] = clipTEX1_TEX0; - clip_interp_tab[CLIP_INDEX0] = clipINDEX0; - clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1] = clipINDEX0_INDEX1; - - clip_interp_tab[CLIP_FOG_COORD] = clip_FOG; - clip_interp_tab[CLIP_RGBA0|CLIP_FOG_COORD] = clipRGBA0_FOG; - clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = clipRGBA0_RGBA1_FOG; - clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD] = clipTEX0_RGBA0_FOG; - clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = clipTEX0_RGBA0_RGBA1_FOG; - clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD] = clipTEX1_TEX0_RGBA0_FOG; - clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = - clipTEX1_TEX0_RGBA0_RGBA1_FOG; - clip_interp_tab[CLIP_TEX0|CLIP_FOG_COORD] = clipTEX0_FOG; - clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_FOG_COORD] = clipTEX1_TEX0_FOG; - clip_interp_tab[CLIP_INDEX0|CLIP_FOG_COORD] = clipINDEX0_FOG; - clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1|CLIP_FOG_COORD] = clipINDEX0_INDEX1_FOG; -} - diff --git a/src/mesa/main/clip.h b/src/mesa/main/clip.h index abf2f7e9ce0..a44d6d0fe12 100644 --- a/src/mesa/main/clip.h +++ b/src/mesa/main/clip.h @@ -1,4 +1,4 @@ -/* $Id: clip.h,v 1.3 1999/11/11 01:22:25 brianp Exp $ */ +/* $Id: clip.h,v 1.4 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -31,65 +31,10 @@ #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 diff --git a/src/mesa/main/colormac.h b/src/mesa/main/colormac.h index b69f52fbbbf..57d4350cc49 100644 --- a/src/mesa/main/colormac.h +++ b/src/mesa/main/colormac.h @@ -1,4 +1,4 @@ -/* $Id: colormac.h,v 1.2 2000/10/29 18:12:14 brianp Exp $ */ +/* $Id: colormac.h,v 1.3 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -38,7 +38,8 @@ #include "config.h" #include "macros.h" #include "mmath.h" - +/* Do not reference types.h from this file. + */ /* diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index aff60fb5073..c0e75e92984 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,4 +1,4 @@ -/* $Id: context.c,v 1.105 2000/11/15 16:38:40 brianp Exp $ */ +/* $Id: context.c,v 1.106 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -33,7 +33,6 @@ #include "clip.h" #include "colortab.h" #include "context.h" -#include "cva.h" #include "dlist.h" #include "eval.h" #include "enums.h" @@ -46,25 +45,21 @@ #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) @@ -73,6 +68,25 @@ #endif +#ifndef MESA_VERBOSE +int MESA_VERBOSE = 0 +/* | VERBOSE_PIPELINE */ +/* | VERBOSE_IMMEDIATE */ +/* | VERBOSE_VARRAY */ +/* | VERBOSE_TEXTURE */ +/* | VERBOSE_API */ +/* | VERBOSE_DRIVER */ +/* | VERBOSE_STATE */ +/* | VERBOSE_CULL */ +/* | VERBOSE_DISPLAY_LIST */ +; +#endif + +#ifndef MESA_DEBUG_FLAGS +int MESA_DEBUG_FLAGS = 0 +/* | DEBUG_ALWAYS_FLUSH */ +; +#endif /**********************************************************************/ /***** OpenGL SI-style interface (new in Mesa 3.5) *****/ @@ -145,12 +159,6 @@ __glCoreNopDispatch(void) /**********************************************************************/ -#if !defined(THREADS) - -struct immediate *_mesa_CurrentInput = NULL; - -#endif - /**********************************************************************/ /***** GL Visual allocation/destruction *****/ @@ -442,17 +450,10 @@ one_time_init( void ) assert( sizeof(GLushort) >= 2 ); assert( sizeof(GLuint) >= 4 ); - gl_init_clip(); - gl_init_eval(); - _mesa_init_math(); gl_init_lists(); - gl_init_shade(); - gl_init_texture(); - gl_init_transformation(); - gl_init_translate(); - gl_init_vbrender(); - gl_init_vbxform(); - gl_init_vertices(); + + _mesa_init_math(); + _math_init(); if (getenv("MESA_DEBUG")) { _glapi_noop_enable_warnings(GL_TRUE); @@ -809,45 +810,43 @@ init_attrib_groups( GLcontext *ctx ) ctx->Const.NumCompressedTextureFormats = 0; /* Modelview matrix */ - gl_matrix_ctr( &ctx->ModelView ); - gl_matrix_alloc_inv( &ctx->ModelView ); + _math_matrix_ctr( &ctx->ModelView ); + _math_matrix_alloc_inv( &ctx->ModelView ); ctx->ModelViewStackDepth = 0; for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) { - gl_matrix_ctr( &ctx->ModelViewStack[i] ); - gl_matrix_alloc_inv( &ctx->ModelViewStack[i] ); + _math_matrix_ctr( &ctx->ModelViewStack[i] ); + _math_matrix_alloc_inv( &ctx->ModelViewStack[i] ); } /* Projection matrix - need inv for user clipping in clip space*/ - gl_matrix_ctr( &ctx->ProjectionMatrix ); - gl_matrix_alloc_inv( &ctx->ProjectionMatrix ); - - gl_matrix_ctr( &ctx->_ModelProjectMatrix ); + _math_matrix_ctr( &ctx->ProjectionMatrix ); + _math_matrix_alloc_inv( &ctx->ProjectionMatrix ); ctx->ProjectionStackDepth = 0; - ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */ - ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */ - for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) { - gl_matrix_ctr( &ctx->ProjectionStack[i] ); - gl_matrix_alloc_inv( &ctx->ProjectionStack[i] ); + _math_matrix_ctr( &ctx->ProjectionStack[i] ); + _math_matrix_alloc_inv( &ctx->ProjectionStack[i] ); } + /* Derived ModelProject matrix */ + _math_matrix_ctr( &ctx->_ModelProjectMatrix ); + /* Texture matrix */ for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - gl_matrix_ctr( &ctx->TextureMatrix[i] ); + _math_matrix_ctr( &ctx->TextureMatrix[i] ); ctx->TextureStackDepth[i] = 0; for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) { - gl_matrix_ctr( &ctx->TextureStack[i][j] ); + _math_matrix_ctr( &ctx->TextureStack[i][j] ); ctx->TextureStack[i][j].inv = 0; } } /* Color matrix */ - gl_matrix_ctr(&ctx->ColorMatrix); + _math_matrix_ctr(&ctx->ColorMatrix); ctx->ColorStackDepth = 0; for (j = 0; j < MAX_COLOR_STACK_DEPTH - 1; j++) { - gl_matrix_ctr(&ctx->ColorStack[j]); + _math_matrix_ctr(&ctx->ColorStack[j]); } /* Accumulate buffer group */ @@ -893,19 +892,6 @@ init_attrib_groups( GLcontext *ctx ) ctx->Current.RasterPosValid = GL_TRUE; ctx->Current.EdgeFlag = GL_TRUE; ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 ); - ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1); - - ctx->Current.Flag = (VERT_NORM | - VERT_INDEX | - VERT_RGBA | - VERT_SPEC_RGB | - VERT_FOG_COORD | - VERT_EDGE | - VERT_TEX0_12 | - VERT_TEX1_12 | - VERT_TEX2_12 | - VERT_TEX3_12 | - VERT_MATERIAL); init_fallback_arrays( ctx ); @@ -1023,15 +1009,9 @@ init_attrib_groups( GLcontext *ctx ) ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000; ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000; - /* Pipeline */ - gl_pipeline_init( ctx ); - gl_cva_init( ctx ); - /* Extensions */ gl_extensions_ctr( ctx ); - ctx->AllowVertexCull = CLIP_CULLED_BIT; - /* Lighting group */ for (i=0;i<MAX_LIGHTS;i++) { init_light( &ctx->Light.Light[i], i ); @@ -1227,7 +1207,7 @@ init_attrib_groups( GLcontext *ctx ) ctx->Viewport.Height = 0; ctx->Viewport.Near = 0.0; ctx->Viewport.Far = 1.0; - gl_matrix_ctr(&ctx->Viewport._WindowMap); + _math_matrix_ctr(&ctx->Viewport._WindowMap); #define Sz 10 #define Tz 14 @@ -1454,12 +1434,6 @@ _mesa_initialize_context( GLcontext *ctx, ctx->Visual = *visual; ctx->DrawBuffer = NULL; ctx->ReadBuffer = NULL; - - ctx->VB = gl_vb_create_for_immediate( ctx ); - if (!ctx->VB) { - return GL_FALSE; - } - ctx->input = ctx->VB->IM; if (share_list) { /* share the group of display lists of another context */ @@ -1469,7 +1443,6 @@ _mesa_initialize_context( GLcontext *ctx, /* allocate new group of display lists */ ctx->Shared = alloc_shared_state(); if (!ctx->Shared) { - ALIGN_FREE( ctx->VB ); return GL_FALSE; } } @@ -1479,9 +1452,6 @@ _mesa_initialize_context( GLcontext *ctx, init_attrib_groups( ctx ); - gl_reset_vb( ctx->VB ); - gl_reset_input( ctx ); - if (visual->DBflag) { ctx->Color.DrawBuffer = GL_BACK; ctx->Color.DriverDrawBuffer = GL_BACK_LEFT; @@ -1499,7 +1469,6 @@ _mesa_initialize_context( GLcontext *ctx, if (!alloc_proxy_textures(ctx)) { free_shared_state(ctx, ctx->Shared); - ALIGN_FREE( ctx->VB ); return GL_FALSE; } @@ -1526,7 +1495,6 @@ _mesa_initialize_context( GLcontext *ctx, ctx->Save = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*)); if (!ctx->Exec || !ctx->Save) { free_shared_state(ctx, ctx->Shared); - ALIGN_FREE( ctx->VB ); if (ctx->Exec) FREE( ctx->Exec ); } @@ -1541,7 +1509,6 @@ _mesa_initialize_context( GLcontext *ctx, or should we just trap in NewTrace (currently done)? */ if (!(ctx->TraceCtx)) { free_shared_state(ctx, ctx->Shared); - ALIGN_FREE( ctx->VB ); FREE( ctx->Exec ); FREE( ctx->Save ); return GL_FALSE; @@ -1554,7 +1521,6 @@ _mesa_initialize_context( GLcontext *ctx, #if 0 if (!(ctx->TraceCtx)) { free_shared_state(ctx, ctx->Shared); - ALIGN_FREE( ctx->VB ); FREE( ctx->Exec ); FREE( ctx->Save ); FREE( ctx->TraceCtx ); @@ -1613,26 +1579,21 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_make_current(NULL, NULL); } - gl_matrix_dtr( &ctx->ModelView ); + _math_matrix_dtr( &ctx->ModelView ); for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) { - gl_matrix_dtr( &ctx->ModelViewStack[i] ); + _math_matrix_dtr( &ctx->ModelViewStack[i] ); } - gl_matrix_dtr( &ctx->ProjectionMatrix ); + _math_matrix_dtr( &ctx->ProjectionMatrix ); for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) { - gl_matrix_dtr( &ctx->ProjectionStack[i] ); + _math_matrix_dtr( &ctx->ProjectionStack[i] ); } for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - gl_matrix_dtr( &ctx->TextureMatrix[i] ); + _math_matrix_dtr( &ctx->TextureMatrix[i] ); for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) { - gl_matrix_dtr( &ctx->TextureStack[i][j] ); + _math_matrix_dtr( &ctx->TextureStack[i][j] ); } } - if (ctx->input != ctx->VB->IM) - gl_immediate_free( ctx->input ); - - gl_vb_free( ctx->VB ); - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); ctx->Shared->RefCount--; assert(ctx->Shared->RefCount >= 0); @@ -1696,12 +1657,6 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_free_colortable_data( &ctx->PostColorMatrixColorTable ); _mesa_free_colortable_data( &ctx->Texture.Palette ); - /* Free cache of immediate buffers. */ - while (ctx->nr_im_queued-- > 0) { - struct immediate * next = ctx->freed_im_queue->next; - ALIGN_FREE( ctx->freed_im_queue ); - ctx->freed_im_queue = next; - } gl_extensions_dtr(ctx); FREE(ctx->Exec); @@ -1828,6 +1783,29 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer ) } +static void print_info( void ) +{ + fprintf(stderr, "Mesa GL_VERSION = %s\n", + (char *) _mesa_GetString(GL_VERSION)); + fprintf(stderr, "Mesa GL_RENDERER = %s\n", + (char *) _mesa_GetString(GL_RENDERER)); + fprintf(stderr, "Mesa GL_VENDOR = %s\n", + (char *) _mesa_GetString(GL_VENDOR)); + fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", + (char *) _mesa_GetString(GL_EXTENSIONS)); +#if defined(THREADS) + fprintf(stderr, "Mesa thread-safe: YES\n"); +#else + fprintf(stderr, "Mesa thread-safe: NO\n"); +#endif +#if defined(USE_X86_ASM) + fprintf(stderr, "Mesa x86-optimized: YES\n"); +#else + fprintf(stderr, "Mesa x86-optimized: NO\n"); +#endif +} + + /* * Bind the given context to the given draw-buffer and read-buffer * and make it the current context for this thread. @@ -1836,23 +1814,8 @@ void _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, GLframebuffer *readBuffer ) { -#if 0 - GLcontext *oldCtx = gl_get_context(); - - /* Flush the old context - */ - if (oldCtx) { - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "_mesa_make_current"); - - /* unbind frame buffers from context */ - if (oldCtx->DrawBuffer) { - oldCtx->DrawBuffer = NULL; - } - if (oldCtx->ReadBuffer) { - oldCtx->ReadBuffer = NULL; - } - } -#endif + if (MESA_VERBOSE) + fprintf(stderr, "_mesa_make_current2()\n"); /* We call this function periodically (just here for now) in * order to detect when multithreading has begun. @@ -1861,47 +1824,36 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, _glapi_set_context((void *) newCtx); ASSERT(_mesa_get_current_context() == newCtx); - if (newCtx) { - SET_IMMEDIATE(newCtx, newCtx->input); - _glapi_set_dispatch(newCtx->CurrentDispatch); - } - else { + + + if (!newCtx) { _glapi_set_dispatch(NULL); /* none current */ } + else { + _glapi_set_dispatch(newCtx->CurrentDispatch); - if (MESA_VERBOSE) fprintf(stderr, "_mesa_make_current()\n"); + if (drawBuffer && readBuffer) { + /* TODO: check if newCtx and buffer's visual match??? */ + newCtx->DrawBuffer = drawBuffer; + newCtx->ReadBuffer = readBuffer; + newCtx->NewState |= _NEW_BUFFERS; + /* gl_update_state( newCtx ); */ + } - if (newCtx && drawBuffer && readBuffer) { - /* TODO: check if newCtx and buffer's visual match??? */ - newCtx->DrawBuffer = drawBuffer; - newCtx->ReadBuffer = readBuffer; - newCtx->NewState |= _NEW_BUFFERS; - gl_update_state( newCtx ); - } + if (newCtx->Driver.MakeCurrent) + newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer ); - /* We can use this to help debug user's problems. Tell the to set - * the MESA_INFO env variable before running their app. Then the - * first time each context is made current we'll print some useful - * information. - */ - if (newCtx && newCtx->FirstTimeCurrent) { - if (getenv("MESA_INFO")) { - fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION)); - fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER)); - fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR)); - fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS)); -#if defined(THREADS) - fprintf(stderr, "Mesa thread-safe: YES\n"); -#else - fprintf(stderr, "Mesa thread-safe: NO\n"); -#endif -#if defined(USE_X86_ASM) - fprintf(stderr, "Mesa x86-optimized: YES\n"); -#else - fprintf(stderr, "Mesa x86-optimized: NO\n"); -#endif + /* We can use this to help debug user's problems. Tell them to set + * the MESA_INFO env variable before running their app. Then the + * first time each context is made current we'll print some useful + * information. + */ + if (newCtx->FirstTimeCurrent) { + if (getenv("MESA_INFO")) { + print_info(); + } + newCtx->FirstTimeCurrent = GL_FALSE; } - newCtx->FirstTimeCurrent = GL_FALSE; } } @@ -1927,7 +1879,7 @@ _mesa_get_current_context( void ) void _mesa_swapbuffers(GLcontext *ctx) { - FLUSH_VB( ctx, "swap buffers" ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); } diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index fe058c69d36..71ed19119ce 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -1,4 +1,4 @@ -/* $Id: context.h,v 1.20 2000/10/29 18:12:14 brianp Exp $ */ +/* $Id: context.h,v 1.21 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -169,33 +169,16 @@ _mesa_get_current_context(void); /* - * Macros for fetching current context, input buffer, etc. + * Macros for fetching current context. */ #ifdef THREADS #define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()) -#define GET_IMMEDIATE struct immediate *IM = ((GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()))->input - -#define SET_IMMEDIATE(ctx, im) \ -do { \ - ctx->input = im; \ -} while (0) - #else -extern struct immediate *_mesa_CurrentInput; - #define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) _glapi_Context -#define GET_IMMEDIATE struct immediate *IM = _mesa_CurrentInput - -#define SET_IMMEDIATE(ctx, im) \ -do { \ - ctx->input = im; \ - _mesa_CurrentInput = im; \ -} while (0) - #endif diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 9452a0e86c0..2c9a024842c 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.41 2000/11/14 17:40:13 brianp Exp $ */ +/* $Id: dd.h,v 1.42 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -34,7 +34,6 @@ struct gl_pixelstore_attrib; struct vertex_buffer; -struct immediate; struct gl_pipeline; struct gl_pipeline_stage; @@ -122,6 +121,30 @@ struct gl_pipeline_stage; + + + + +/* Point, line, triangle, quadrilateral and rectangle rasterizer + * functions. These are specific to the tnl module and will shortly + * move to a driver interface specific to that module. + */ +typedef void (*points_func)( GLcontext *ctx, GLuint first, GLuint last ); + +typedef void (*line_func)( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ); + +typedef void (*triangle_func)( GLcontext *ctx, + GLuint v1, GLuint v2, GLuint v3, GLuint pv ); + +typedef void (*quad_func)( GLcontext *ctx, GLuint v1, GLuint v2, + GLuint v3, GLuint v4, GLuint pv ); + +typedef void (*render_func)( struct vertex_buffer *VB, + GLuint start, + GLuint count, + GLuint parity ); + + /* * Device Driver function table. */ @@ -138,12 +161,6 @@ struct dd_function_table { * NULL can be returned. */ - GLuint UpdateStateNotify; - /* - * Tell mesa exactly when to call UpdateState. This is a bitwise - * or of the _NEW_* flags defined in types.h. - */ - void (*UpdateState)( GLcontext *ctx ); /* * UpdateState() is called whenver Mesa thinks the device driver should @@ -327,13 +344,6 @@ struct dd_function_table { * the error value. */ - void (*NearFar)( GLcontext *ctx, GLfloat nearVal, GLfloat farVal ); - /* - * Called from glFrustum and glOrtho to tell device driver the - * near and far clipping plane Z values. The 3Dfx driver, for example, - * uses this. - */ - /*** *** For supporting hardware Z buffers: @@ -744,14 +754,13 @@ struct dd_function_table { /*** - *** Accelerated point, line, polygon, quad and rect functions: + *** Accelerated point, line, polygon and quad functions: ***/ points_func PointsFunc; line_func LineFunc; triangle_func TriangleFunc; quad_func QuadFunc; - rect_func RectFunc; /*** @@ -798,12 +807,7 @@ struct dd_function_table { /*** *** NEW in Mesa 3.x ***/ - void (*LightingSpaceChange)( GLcontext *ctx ); - /* Notify driver that the special derived value _NeedEyeCoords has - * changed. - */ - void (*RegisterVB)( struct vertex_buffer *VB ); void (*UnregisterVB)( struct vertex_buffer *VB ); /* When Mesa creates a new vertex buffer it calls Driver.RegisterVB() @@ -814,35 +818,57 @@ struct dd_function_table { */ - void (*ResetVB)( struct vertex_buffer *VB ); - void (*ResetCvaVB)( struct vertex_buffer *VB, GLuint stages ); - /* Do any reset operations necessary to the driver data associated - * with these vertex buffers. - */ - GLuint RenderVectorFlags; - /* What do the render tables require of the vectors they deal - * with? + GLboolean (*BuildPrecalcPipeline)( GLcontext *ctx ); + GLboolean (*BuildEltPipeline)( GLcontext *ctx ); + /* Perform the full pipeline build, or return false. */ - GLuint (*RegisterPipelineStages)( struct gl_pipeline_stage *out, - const struct gl_pipeline_stage *in, - GLuint nr ); - /* Register new pipeline stages, or modify existing ones. See also - * the OptimizePipeline() functions. + + /*** + *** Support for multiple t&l engines + ***/ + +#define FLUSH_INSIDE_BEGIN_END 0x1 +#define FLUSH_STORED_VERTICES 0x2 +#define FLUSH_UPDATE_CURRENT 0x4 + + GLuint NeedFlush; + /* Set by the driver-supplied t&l engine. + * Bitflags defined above are set whenever + * - the engine *might* be inside a begin/end object. + * - there *might* be buffered vertices to be flushed. + * - the ctx->Current values *might* not be uptodate. + * + * The FlushVertices() call below may be used to resolve + * these conditions. */ + GLboolean (*FlushVertices)( GLcontext *ctx, GLuint flags ); + /* If inside begin/end, returns GL_FALSE. + * Otherwise, + * if (flags & FLUSH_STORED_VERTICES) flushes any buffered vertices, + * if (flags & FLUSH_UPDATE_CURRENT) updates ctx->Current, + * returns GL_TRUE. + * + * Note that the default t&l engine never clears the + * FLUSH_UPDATE_CURRENT bit, even after performing the update. + */ - GLboolean (*BuildPrecalcPipeline)( GLcontext *ctx ); - GLboolean (*BuildEltPipeline)( GLcontext *ctx ); - /* Perform the full pipeline build, or return false. + void (*LightingSpaceChange)( GLcontext *ctx ); + /* Notify driver that the special derived value _NeedEyeCoords has + * changed. */ + void (*NewList)( GLcontext *ctx, GLuint list, GLenum mode ); + void (*EndList)( GLcontext *ctx ); + /* Let the t&l component know what is going on with display lists + * in time to make changes to dispatch tables, etc. + */ - void (*OptimizePrecalcPipeline)( GLcontext *ctx, struct gl_pipeline *pipe ); - void (*OptimizeImmediatePipeline)( GLcontext *ctx, struct gl_pipeline *pipe); - /* Check to see if a fast path exists for this combination of stages - * in the precalc and immediate (elt) pipelines. + void (*MakeCurrent)( GLcontext *ctx, GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ); + /* Let the t&l component know when the context becomes current. */ @@ -898,6 +924,23 @@ struct dd_function_table { GLboolean (*GetFloatv)(GLcontext *ctx, GLenum pname, GLfloat *result); GLboolean (*GetIntegerv)(GLcontext *ctx, GLenum pname, GLint *result); GLboolean (*GetPointerv)(GLcontext *ctx, GLenum pname, GLvoid **result); + + + void (*VertexPointer)(GLcontext *ctx, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*NormalPointer)(GLcontext *ctx, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*ColorPointer)(GLcontext *ctx, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*FogCoordPointer)(GLcontext *ctx, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*IndexPointer)(GLcontext *ctx, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*SecondaryColorPointer)(GLcontext *ctx, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*TexCoordPointer)(GLcontext *ctx, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*EdgeFlagPointer)(GLcontext *ctx, GLsizei stride, const GLvoid *ptr); }; diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c new file mode 100644 index 00000000000..b467499816f --- /dev/null +++ b/src/mesa/main/debug.c @@ -0,0 +1,89 @@ +#include "types.h" +#include "debug.h" + +void gl_print_state( const char *msg, GLuint state ) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + state, + (state & _NEW_MODELVIEW) ? "ctx->ModelView, " : "", + (state & _NEW_PROJECTION) ? "ctx->Projection, " : "", + (state & _NEW_TEXTURE_MATRIX) ? "ctx->TextureMatrix, " : "", + (state & _NEW_COLOR_MATRIX) ? "ctx->ColorMatrix, " : "", + (state & _NEW_ACCUM) ? "ctx->Accum, " : "", + (state & _NEW_COLOR) ? "ctx->Color, " : "", + (state & _NEW_DEPTH) ? "ctx->Depth, " : "", + (state & _NEW_EVAL) ? "ctx->Eval/EvalMap, " : "", + (state & _NEW_FOG) ? "ctx->Fog, " : "", + (state & _NEW_HINT) ? "ctx->Hint, " : "", + (state & _NEW_LIGHT) ? "ctx->Light, " : "", + (state & _NEW_LINE) ? "ctx->Line, " : "", + (state & _NEW_FEEDBACK_SELECT) ? "ctx->Feedback/Select, " : "", + (state & _NEW_PIXEL) ? "ctx->Pixel, " : "", + (state & _NEW_POINT) ? "ctx->Point, " : "", + (state & _NEW_POLYGON) ? "ctx->Polygon, " : "", + (state & _NEW_POLYGONSTIPPLE) ? "ctx->PolygonStipple, " : "", + (state & _NEW_SCISSOR) ? "ctx->Scissor, " : "", + (state & _NEW_TEXTURE) ? "ctx->Texture, " : "", + (state & _NEW_TRANSFORM) ? "ctx->Transform, " : "", + (state & _NEW_VIEWPORT) ? "ctx->Viewport, " : "", + (state & _NEW_PACKUNPACK) ? "ctx->Pack/Unpack, " : "", + (state & _NEW_ARRAY) ? "ctx->Array, " : "", + (state & _NEW_COLORTABLE) ? "ctx->{*}ColorTable, " : "", + (state & _NEW_RENDERMODE) ? "ctx->RenderMode, " : "", + (state & _NEW_BUFFERS) ? "ctx->Visual, ctx->DrawBuffer,, " : ""); +} + + +void gl_print_enable_flags( const char *msg, GLuint flags ) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & ENABLE_TEX0) ? "tex-0, " : "", + (flags & ENABLE_TEX1) ? "tex-1, " : "", + (flags & ENABLE_LIGHT) ? "light, " : "", + (flags & ENABLE_FOG) ? "fog, " : "", + (flags & ENABLE_USERCLIP) ? "userclip, " : "", + (flags & ENABLE_TEXGEN0) ? "tex-gen-0, " : "", + (flags & ENABLE_TEXGEN1) ? "tex-gen-1, " : "", + (flags & ENABLE_TEXGEN2) ? "tex-gen-2, " : "", + (flags & ENABLE_TEXGEN3) ? "tex-gen-3, " : "", + (flags & ENABLE_TEXMAT0) ? "tex-mat-0, " : "", + (flags & ENABLE_TEXMAT1) ? "tex-mat-1, " : "", + (flags & ENABLE_TEXMAT2) ? "tex-mat-2, " : "", + (flags & ENABLE_TEXMAT3) ? "tex-mat-3, " : "", + (flags & ENABLE_NORMALIZE) ? "normalize, " : "", + (flags & ENABLE_RESCALE) ? "rescale, " : ""); +} + +void gl_print_tri_caps( const char *name, GLuint flags ) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + name, + flags, + (flags & DD_FEEDBACK) ? "feedback, " : "", + (flags & DD_SELECT) ? "select, " : "", + (flags & DD_FLATSHADE) ? "flat-shade, " : "", + (flags & DD_MULTIDRAW) ? "multidraw, " : "", + (flags & DD_SEPERATE_SPECULAR) ? "seperate-specular, " : "", + (flags & DD_TRI_LIGHT_TWOSIDE) ? "tri-light-twoside, " : "", + (flags & DD_TRI_UNFILLED) ? "tri-unfilled, " : "", + (flags & DD_TRI_STIPPLE) ? "tri-stipple, " : "", + (flags & DD_TRI_OFFSET) ? "tri-offset, " : "", + (flags & DD_TRI_CULL) ? "tri-bf-cull, " : "", + (flags & DD_TRI_SMOOTH) ? "tri-smooth, " : "", + (flags & DD_LINE_SMOOTH) ? "line-smooth, " : "", + (flags & DD_LINE_STIPPLE) ? "line-stipple, " : "", + (flags & DD_LINE_WIDTH) ? "line-wide, " : "", + (flags & DD_POINT_SMOOTH) ? "point-smooth, " : "", + (flags & DD_POINT_SIZE) ? "point-size, " : "", + (flags & DD_POINT_ATTEN) ? "point-atten, " : "", + (flags & DD_LIGHTING_CULL) ? "lighting-cull, " : "", + (flags & DD_TRI_CULL_FRONT_BACK) ? "cull-all, " : "", + (flags & DD_STENCIL) ? "stencil, " : "" + ); +} diff --git a/src/mesa/main/debug.h b/src/mesa/main/debug.h new file mode 100644 index 00000000000..1fff95411e9 --- /dev/null +++ b/src/mesa/main/debug.h @@ -0,0 +1,8 @@ +#ifndef _DEBUG_H +#define _DEBUG_H + +void gl_print_tri_caps( const char *name, GLuint flags ); +void gl_print_enable_flags( const char *msg, GLuint flags ); +void gl_print_state( const char *msg, GLuint state ); + +#endif diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index e3475bb5cb1..d66c0745a86 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -1,4 +1,4 @@ -/* $Id: dlist.c,v 1.50 2000/11/10 18:06:14 brianp Exp $ */ +/* $Id: dlist.c,v 1.51 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -32,7 +32,6 @@ #include "accum.h" #include "attrib.h" #include "bitmap.h" -#include "bbox.h" #include "blend.h" #include "buffers.h" #include "clip.h" @@ -41,7 +40,6 @@ #include "context.h" #include "convolve.h" #include "copypix.h" -#include "cva.h" #include "depth.h" #include "enable.h" #include "enums.h" @@ -59,7 +57,6 @@ #include "macros.h" #include "matrix.h" #include "mem.h" -#include "pipeline.h" #include "pixel.h" #include "pixeltex.h" #include "points.h" @@ -72,10 +69,13 @@ #include "texstate.h" #include "types.h" #include "varray.h" -#include "vb.h" -#include "vbfill.h" -#include "vbxform.h" -#include "xform.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "tnl/t_vbfill.h" +#include "tnl/t_eval.h" +#include "tnl/t_varray.h" #endif @@ -121,7 +121,6 @@ Functions which cause errors if called while compiling a display list: * The fact that these identifiers are assigned consecutive * integer values starting at 0 is very important, see InstSize array usage) * - * KW: Commented out opcodes now handled by vertex-cassettes. */ typedef enum { OPCODE_ACCUM, @@ -221,6 +220,7 @@ typedef enum { OPCODE_READ_BUFFER, OPCODE_RESET_HISTOGRAM, OPCODE_RESET_MIN_MAX, + OPCODE_ROTATE, OPCODE_SCALE, OPCODE_SCISSOR, OPCODE_SELECT_TEXTURE_SGIS, @@ -256,9 +256,9 @@ typedef enum { OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ - OPCODE_VERTEX_CASSETTE, /* render prebuilt vertex buffer */ OPCODE_CONTINUE, - OPCODE_END_OF_LIST + OPCODE_END_OF_LIST, + OPCODE_DRV_0 } OpCode; @@ -284,7 +284,9 @@ union node { -/* Number of nodes of storage needed for each instruction: */ +/* Number of nodes of storage needed for each instruction. Sizes for + * dynamically allocated opcodes are stored in the context struct. + */ static GLuint InstSize[ OPCODE_END_OF_LIST+1 ]; void mesa_print_display_list( GLuint list ); @@ -295,40 +297,6 @@ void mesa_print_display_list( GLuint list ); /**********************************************************************/ -/* - * Allocate space for a display list instruction. - * Input: opcode - type of instruction - * argcount - number of arguments following the instruction - * Return: pointer to first node in the instruction - */ -static Node *alloc_instruction( GLcontext *ctx, OpCode opcode, GLint argcount ) -{ - Node *n, *newblock; - GLuint count = InstSize[opcode]; - - assert( (GLint) count == argcount+1 ); - - if (ctx->CurrentPos + count + 2 > BLOCK_SIZE) { - /* This block is full. Allocate a new block and chain to it */ - n = ctx->CurrentBlock + ctx->CurrentPos; - n[0].opcode = OPCODE_CONTINUE; - newblock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE ); - if (!newblock) { - gl_error( ctx, GL_OUT_OF_MEMORY, "Building display list" ); - return NULL; - } - n[1].next = (Node *) newblock; - ctx->CurrentBlock = newblock; - ctx->CurrentPos = 0; - } - - n = ctx->CurrentBlock + ctx->CurrentPos; - ctx->CurrentPos += count; - - n[0].opcode = opcode; - - return n; -} @@ -362,13 +330,16 @@ void gl_destroy_list( GLcontext *ctx, GLuint list ) done = block ? GL_FALSE : GL_TRUE; while (!done) { - switch (n[0].opcode) { - /* special cases first */ - case OPCODE_VERTEX_CASSETTE: - if ( ! -- ((struct immediate *) n[1].data)->ref_count ) - gl_immediate_free( (struct immediate *) n[1].data ); - n += InstSize[n[0].opcode]; - break; + + /* check for extension opcodes first */ + + int i = (int)n[0].opcode - (int)OPCODE_DRV_0; + if (i >= 0 && i < ctx->listext.nr_opcodes) { + ctx->listext.opcode[i].destroy(ctx, &n[1]); + n += ctx->listext.opcode[i].size; + } + else { + switch (n[0].opcode) { case OPCODE_MAP1: FREE(n[6].data); n += InstSize[n[0].opcode]; @@ -466,9 +437,10 @@ void gl_destroy_list( GLcontext *ctx, GLuint list ) /* Most frequent case */ n += InstSize[n[0].opcode]; break; + } } } - + _mesa_HashRemove(ctx->Shared->DisplayList, list); } @@ -637,6 +609,7 @@ void gl_init_lists( void ) InstSize[OPCODE_READ_BUFFER] = 2; InstSize[OPCODE_RESET_HISTOGRAM] = 2; InstSize[OPCODE_RESET_MIN_MAX] = 2; + InstSize[OPCODE_ROTATE] = 5; InstSize[OPCODE_SCALE] = 4; InstSize[OPCODE_SCISSOR] = 5; InstSize[OPCODE_STENCIL_FUNC] = 4; @@ -657,7 +630,6 @@ void gl_init_lists( void ) InstSize[OPCODE_WINDOW_POS] = 5; InstSize[OPCODE_CONTINUE] = 2; InstSize[OPCODE_ERROR] = 3; - InstSize[OPCODE_VERTEX_CASSETTE] = 9; InstSize[OPCODE_END_OF_LIST] = 1; /* GL_SGIX/SGIS_pixel_texture */ InstSize[OPCODE_PIXEL_TEXGEN_SGIX] = 2; @@ -678,17 +650,88 @@ void gl_init_lists( void ) /* - * Display List compilation functions + * Allocate space for a display list instruction. + * Input: opcode - type of instruction + * argcount - size in bytes of data required. + * Return: pointer to the usable data area (not including the internal + * opcode). */ +void * +_mesa_alloc_instruction( GLcontext *ctx, int opcode, GLint sz ) +{ + Node *n, *newblock; + GLuint count = 1 + (sz + sizeof(Node) - 1) / sizeof(Node); +#ifdef DEBUG + if (opcode < (int) OPCODE_DRV_0) { + assert( (GLint) count == InstSize[opcode] ); + } +#endif + if (ctx->CurrentPos + count + 2 > BLOCK_SIZE) { + /* This block is full. Allocate a new block and chain to it */ + n = ctx->CurrentBlock + ctx->CurrentPos; + n[0].opcode = OPCODE_CONTINUE; + newblock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE ); + if (!newblock) { + gl_error( ctx, GL_OUT_OF_MEMORY, "Building display list" ); + return NULL; + } + n[1].next = (Node *) newblock; + ctx->CurrentBlock = newblock; + ctx->CurrentPos = 0; + } + n = ctx->CurrentBlock + ctx->CurrentPos; + ctx->CurrentPos += count; + + n[0].opcode = (OpCode) opcode; + + return (void *)&n[1]; +} + + +/* Allow modules and drivers to get their own opcodes. + */ +int +_mesa_alloc_opcode( GLcontext *ctx, + GLuint sz, + void (*execute)( GLcontext *, void * ), + void (*destroy)( GLcontext *, void * ), + void (*print)( GLcontext *, void * ) ) +{ + if (ctx->listext.nr_opcodes < GL_MAX_EXT_OPCODES) { + GLuint i = ctx->listext.nr_opcodes++; + ctx->listext.opcode[i].size = 1 + (sz + sizeof(Node) - 1)/sizeof(Node); + ctx->listext.opcode[i].execute = execute; + ctx->listext.opcode[i].destroy = destroy; + ctx->listext.opcode[i].print = print; + return i + OPCODE_DRV_0; + } + return -1; +} + + + +/* Mimic the old behaviour of alloc_instruction: + * - sz is in units of sizeof(Node) + * - return value a pointer to sizeof(Node) before the actual + * usable data area. + */ +#define ALLOC_INSTRUCTION(ctx, opcode, sz) \ + ((Node *)_mesa_alloc_instruction(ctx, opcode, sz*sizeof(Node)) - 1) + + + +/* + * Display List compilation functions + */ static void save_Accum( GLenum op, GLfloat value ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_ACCUM, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ACCUM, 2 ); if (n) { n[1].e = op; n[2].f = value; @@ -703,8 +746,8 @@ static void save_AlphaFunc( GLenum func, GLclampf ref ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_ALPHA_FUNC, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ALPHA_FUNC, 2 ); if (n) { n[1].e = func; n[2].f = (GLfloat) ref; @@ -715,18 +758,12 @@ static void save_AlphaFunc( GLenum func, GLclampf ref ) } -static void save_Begin( GLenum mode ) -{ - _mesa_Begin(mode); /* special case */ -} - - static void save_BindTexture( GLenum target, GLuint texture ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_BIND_TEXTURE, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BIND_TEXTURE, 2 ); if (n) { n[1].e = target; n[2].ui = texture; @@ -745,8 +782,8 @@ static void save_Bitmap( GLsizei width, GLsizei height, GET_CURRENT_CONTEXT(ctx); GLvoid *image = _mesa_unpack_bitmap( width, height, pixels, &ctx->Unpack ); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_BITMAP, 7 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BITMAP, 7 ); if (n) { n[1].i = (GLint) width; n[2].i = (GLint) height; @@ -770,8 +807,8 @@ static void save_BlendEquation( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_BLEND_EQUATION, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_EQUATION, 1 ); if (n) { n[1].e = mode; } @@ -785,8 +822,8 @@ static void save_BlendFunc( GLenum sfactor, GLenum dfactor ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_BLEND_FUNC, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_FUNC, 2 ); if (n) { n[1].e = sfactor; n[2].e = dfactor; @@ -802,8 +839,8 @@ static void save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_BLEND_FUNC_SEPARATE, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_FUNC_SEPARATE, 4 ); if (n) { n[1].e = sfactorRGB; n[2].e = dfactorRGB; @@ -822,8 +859,8 @@ static void save_BlendColor( GLfloat red, GLfloat green, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_BLEND_COLOR, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_COLOR, 4 ); if (n) { n[1].f = red; n[2].f = green; @@ -840,8 +877,8 @@ static void save_CallList( GLuint list ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CALL_LIST, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CALL_LIST, 1 ); if (n) { n[1].ui = list; } @@ -855,11 +892,11 @@ static void save_CallLists( GLsizei n, GLenum type, const GLvoid *lists ) { GET_CURRENT_CONTEXT(ctx); GLint i; - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); for (i=0;i<n;i++) { GLuint list = translate_id( i, type, lists ); - Node *n = alloc_instruction( ctx, OPCODE_CALL_LIST_OFFSET, 1 ); + Node *n = ALLOC_INSTRUCTION( ctx, OPCODE_CALL_LIST_OFFSET, 1 ); if (n) { n[1].ui = list; } @@ -874,8 +911,8 @@ static void save_Clear( GLbitfield mask ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CLEAR, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR, 1 ); if (n) { n[1].bf = mask; } @@ -890,8 +927,8 @@ static void save_ClearAccum( GLfloat red, GLfloat green, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CLEAR_ACCUM, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_ACCUM, 4 ); if (n) { n[1].f = red; n[2].f = green; @@ -909,8 +946,8 @@ static void save_ClearColor( GLclampf red, GLclampf green, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CLEAR_COLOR, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_COLOR, 4 ); if (n) { n[1].f = red; n[2].f = green; @@ -927,8 +964,8 @@ static void save_ClearDepth( GLclampd depth ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CLEAR_DEPTH, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_DEPTH, 1 ); if (n) { n[1].f = (GLfloat) depth; } @@ -942,8 +979,8 @@ static void save_ClearIndex( GLfloat c ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CLEAR_INDEX, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_INDEX, 1 ); if (n) { n[1].f = c; } @@ -957,8 +994,8 @@ static void save_ClearStencil( GLint s ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CLEAR_STENCIL, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_STENCIL, 1 ); if (n) { n[1].i = s; } @@ -972,8 +1009,8 @@ static void save_ClipPlane( GLenum plane, const GLdouble *equ ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CLIP_PLANE, 5 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLIP_PLANE, 5 ); if (n) { n[1].e = plane; n[2].f = equ[0]; @@ -993,8 +1030,8 @@ static void save_ColorMask( GLboolean red, GLboolean green, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COLOR_MASK, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_MASK, 4 ); if (n) { n[1].b = red; n[2].b = green; @@ -1011,8 +1048,8 @@ static void save_ColorMaterial( GLenum face, GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COLOR_MATERIAL, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_MATERIAL, 2 ); if (n) { n[1].e = face; n[2].e = mode; @@ -1039,8 +1076,8 @@ static void save_ColorTable( GLenum target, GLenum internalFormat, GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, table, &ctx->Unpack); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COLOR_TABLE, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE, 6 ); if (n) { n[1].e = target; n[2].e = internalFormat; @@ -1068,9 +1105,9 @@ save_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) Node *n; ASSERT_OUTSIDE_BEGIN_END(ctx, "glColorTableParameterfv"); - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); - n = alloc_instruction( ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6 ); if (n) { n[1].e = target; n[2].e = pname; @@ -1097,9 +1134,9 @@ save_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params) Node *n; ASSERT_OUTSIDE_BEGIN_END(ctx, "glColorTableParameterfv"); - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); - n = alloc_instruction( ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6 ); if (n) { n[1].e = target; n[2].e = pname; @@ -1128,8 +1165,8 @@ static void save_ColorSubTable( GLenum target, GLsizei start, GLsizei count, GLvoid *image = _mesa_unpack_image(count, 1, 1, format, type, table, &ctx->Unpack); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COLOR_SUB_TABLE, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_SUB_TABLE, 6 ); if (n) { n[1].e = target; n[2].i = start; @@ -1154,8 +1191,8 @@ save_CopyColorSubTable(GLenum target, GLsizei start, GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COPY_COLOR_SUB_TABLE, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_COLOR_SUB_TABLE, 6 ); if (n) { n[1].e = target; n[2].i = start; @@ -1176,8 +1213,8 @@ save_CopyColorTable(GLenum target, GLenum internalformat, GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COPY_COLOR_TABLE, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_COLOR_TABLE, 6 ); if (n) { n[1].e = target; n[2].e = internalformat; @@ -1199,8 +1236,8 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, filter, &ctx->Unpack); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CONVOLUTION_FILTER_1D, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_FILTER_1D, 6 ); if (n) { n[1].e = target; n[2].e = internalFormat; @@ -1228,8 +1265,8 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, filter, &ctx->Unpack); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CONVOLUTION_FILTER_2D, 7 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_FILTER_2D, 7 ); if (n) { n[1].e = target; n[2].e = internalFormat; @@ -1254,8 +1291,8 @@ save_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3 ); if (n) { n[1].e = target; n[2].e = pname; @@ -1272,8 +1309,8 @@ save_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 ); if (n) { n[1].e = target; n[2].e = pname; @@ -1300,8 +1337,8 @@ save_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3 ); if (n) { n[1].e = target; n[2].e = pname; @@ -1318,8 +1355,8 @@ save_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 ); if (n) { n[1].e = target; n[2].e = pname; @@ -1346,8 +1383,8 @@ static void save_CopyPixels( GLint x, GLint y, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COPY_PIXELS, 5 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_PIXELS, 5 ); if (n) { n[1].i = x; n[2].i = y; @@ -1368,8 +1405,8 @@ save_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COPY_TEX_IMAGE1D, 7 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_IMAGE1D, 7 ); if (n) { n[1].e = target; n[2].i = level; @@ -1394,8 +1431,8 @@ save_CopyTexImage2D( GLenum target, GLint level, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COPY_TEX_IMAGE2D, 8 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_IMAGE2D, 8 ); if (n) { n[1].e = target; n[2].i = level; @@ -1421,8 +1458,8 @@ save_CopyTexSubImage1D( GLenum target, GLint level, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6 ); if (n) { n[1].e = target; n[2].i = level; @@ -1445,8 +1482,8 @@ save_CopyTexSubImage2D( GLenum target, GLint level, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8 ); if (n) { n[1].e = target; n[2].i = level; @@ -1472,8 +1509,8 @@ save_CopyTexSubImage3D( GLenum target, GLint level, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9 ); if (n) { n[1].e = target; n[2].i = level; @@ -1497,8 +1534,8 @@ static void save_CullFace( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CULL_FACE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CULL_FACE, 1 ); if (n) { n[1].e = mode; } @@ -1512,8 +1549,8 @@ static void save_DepthFunc( GLenum func ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_DEPTH_FUNC, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_FUNC, 1 ); if (n) { n[1].e = func; } @@ -1527,8 +1564,8 @@ static void save_DepthMask( GLboolean mask ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_DEPTH_MASK, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_MASK, 1 ); if (n) { n[1].b = mask; } @@ -1542,8 +1579,8 @@ static void save_DepthRange( GLclampd nearval, GLclampd farval ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_DEPTH_RANGE, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_RANGE, 2 ); if (n) { n[1].f = (GLfloat) nearval; n[2].f = (GLfloat) farval; @@ -1558,8 +1595,8 @@ static void save_Disable( GLenum cap ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_DISABLE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DISABLE, 1 ); if (n) { n[1].e = cap; } @@ -1573,8 +1610,8 @@ static void save_DrawBuffer( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_DRAW_BUFFER, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DRAW_BUFFER, 1 ); if (n) { n[1].e = mode; } @@ -1592,8 +1629,8 @@ static void save_DrawPixels( GLsizei width, GLsizei height, GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, pixels, &ctx->Unpack); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_DRAW_PIXELS, 5 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DRAW_PIXELS, 5 ); if (n) { n[1].i = width; n[2].i = height; @@ -1615,8 +1652,8 @@ static void save_Enable( GLenum cap ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_ENABLE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ENABLE, 1 ); if (n) { n[1].e = cap; } @@ -1631,8 +1668,8 @@ static void save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_EVALMESH1, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_EVALMESH1, 3 ); if (n) { n[1].e = mode; n[2].i = i1; @@ -1649,8 +1686,8 @@ static void save_EvalMesh2( { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_EVALMESH2, 5 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_EVALMESH2, 5 ); if (n) { n[1].e = mode; n[2].i = i1; @@ -1670,8 +1707,8 @@ static void save_Fogfv( GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_FOG, 5 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_FOG, 5 ); if (n) { n[1].e = pname; n[2].f = params[0]; @@ -1726,8 +1763,8 @@ static void save_FrontFace( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_FRONT_FACE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_FRONT_FACE, 1 ); if (n) { n[1].e = mode; } @@ -1743,8 +1780,8 @@ static void save_Frustum( GLdouble left, GLdouble right, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_FRUSTUM, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_FRUSTUM, 6 ); if (n) { n[1].f = left; n[2].f = right; @@ -1763,8 +1800,8 @@ static void save_Hint( GLenum target, GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_HINT, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_HINT, 2 ); if (n) { n[1].e = target; n[2].e = mode; @@ -1780,8 +1817,8 @@ static void save_HintPGI( GLenum target, GLint mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_HINT_PGI, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_HINT_PGI, 2 ); if (n) { n[1].e = target; n[2].i = mode; @@ -1798,8 +1835,8 @@ save_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean si GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_HISTOGRAM, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_HISTOGRAM, 4 ); if (n) { n[1].e = target; n[2].i = width; @@ -1816,8 +1853,8 @@ static void save_IndexMask( GLuint mask ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_INDEX_MASK, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_INDEX_MASK, 1 ); if (n) { n[1].ui = mask; } @@ -1830,8 +1867,8 @@ static void save_IndexMask( GLuint mask ) static void save_InitNames( void ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); - (void) alloc_instruction( ctx, OPCODE_INIT_NAMES, 0 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_INIT_NAMES, 0 ); if (ctx->ExecuteFlag) { (*ctx->Exec->InitNames)(); } @@ -1842,8 +1879,8 @@ static void save_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_LIGHT, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LIGHT, 6 ); if (OPCODE_LIGHT) { GLint i, nParams; n[1].e = light; @@ -1946,8 +1983,8 @@ static void save_LightModelfv( GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_LIGHT_MODEL, 5 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LIGHT_MODEL, 5 ); if (n) { n[1].e = pname; n[2].f = params[0]; @@ -2000,8 +2037,8 @@ static void save_LineStipple( GLint factor, GLushort pattern ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_LINE_STIPPLE, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LINE_STIPPLE, 2 ); if (n) { n[1].i = factor; n[2].us = pattern; @@ -2016,8 +2053,8 @@ static void save_LineWidth( GLfloat width ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_LINE_WIDTH, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LINE_WIDTH, 1 ); if (n) { n[1].f = width; } @@ -2031,8 +2068,8 @@ static void save_ListBase( GLuint base ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_LIST_BASE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LIST_BASE, 1 ); if (n) { n[1].ui = base; } @@ -2045,8 +2082,8 @@ static void save_ListBase( GLuint base ) static void save_LoadIdentity( void ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); - (void) alloc_instruction( ctx, OPCODE_LOAD_IDENTITY, 0 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_IDENTITY, 0 ); if (ctx->ExecuteFlag) { (*ctx->Exec->LoadIdentity)(); } @@ -2057,8 +2094,8 @@ static void save_LoadMatrixf( const GLfloat *m ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_LOAD_MATRIX, 16 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_MATRIX, 16 ); if (n) { GLuint i; for (i=0;i<16;i++) { @@ -2086,8 +2123,8 @@ static void save_LoadName( GLuint name ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_LOAD_NAME, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_NAME, 1 ); if (n) { n[1].ui = name; } @@ -2101,8 +2138,8 @@ static void save_LogicOp( GLenum opcode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_LOGIC_OP, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LOGIC_OP, 1 ); if (n) { n[1].e = opcode; } @@ -2117,8 +2154,8 @@ static void save_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MAP1, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP1, 6 ); if (n) { GLfloat *pnts = gl_copy_map_points1d( target, stride, order, points ); n[1].e = target; @@ -2138,8 +2175,8 @@ static void save_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MAP1, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP1, 6 ); if (n) { GLfloat *pnts = gl_copy_map_points1f( target, stride, order, points ); n[1].e = target; @@ -2162,8 +2199,8 @@ static void save_Map2d( GLenum target, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MAP2, 10 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP2, 10 ); if (n) { GLfloat *pnts = gl_copy_map_points2d( target, ustride, uorder, vstride, vorder, points ); @@ -2194,8 +2231,8 @@ static void save_Map2f( GLenum target, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MAP2, 10 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP2, 10 ); if (n) { GLfloat *pnts = gl_copy_map_points2f( target, ustride, uorder, vstride, vorder, points ); @@ -2222,8 +2259,8 @@ static void save_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MAPGRID1, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAPGRID1, 3 ); if (n) { n[1].i = un; n[2].f = u1; @@ -2246,8 +2283,8 @@ static void save_MapGrid2f( GLint un, GLfloat u1, GLfloat u2, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MAPGRID2, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAPGRID2, 6 ); if (n) { n[1].i = un; n[2].f = u1; @@ -2274,8 +2311,8 @@ static void save_MatrixMode( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MATRIX_MODE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MATRIX_MODE, 1 ); if (n) { n[1].e = mode; } @@ -2291,8 +2328,8 @@ save_Minmax(GLenum target, GLenum internalFormat, GLboolean sink) GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MIN_MAX, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MIN_MAX, 3 ); if (n) { n[1].e = target; n[2].e = internalFormat; @@ -2308,8 +2345,8 @@ static void save_MultMatrixf( const GLfloat *m ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_MULT_MATRIX, 16 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MULT_MATRIX, 16 ); if (n) { GLuint i; for (i=0;i<16;i++) { @@ -2350,8 +2387,8 @@ static void save_Ortho( GLdouble left, GLdouble right, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_ORTHO, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ORTHO, 6 ); if (n) { n[1].f = left; n[2].f = right; @@ -2370,8 +2407,8 @@ static void save_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_PIXEL_MAP, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_MAP, 3 ); if (n) { n[1].e = map; n[2].i = mapsize; @@ -2424,8 +2461,8 @@ static void save_PixelTransferf( GLenum pname, GLfloat param ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_PIXEL_TRANSFER, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_TRANSFER, 2 ); if (n) { n[1].e = pname; n[2].f = param; @@ -2446,8 +2483,8 @@ static void save_PixelZoom( GLfloat xfactor, GLfloat yfactor ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_PIXEL_ZOOM, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_ZOOM, 2 ); if (n) { n[1].f = xfactor; n[2].f = yfactor; @@ -2462,8 +2499,8 @@ static void save_PointParameterfvEXT( GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_POINT_PARAMETERS, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POINT_PARAMETERS, 4 ); if (n) { n[1].e = pname; n[2].f = params[0]; @@ -2486,8 +2523,8 @@ static void save_PointSize( GLfloat size ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_POINT_SIZE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POINT_SIZE, 1 ); if (n) { n[1].f = size; } @@ -2501,8 +2538,8 @@ static void save_PolygonMode( GLenum face, GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_POLYGON_MODE, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_MODE, 2 ); if (n) { n[1].e = face; n[2].e = mode; @@ -2520,8 +2557,8 @@ static void save_PolygonStipple( const GLubyte *pattern ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_POLYGON_STIPPLE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_STIPPLE, 1 ); if (n) { void *data; n[1].data = MALLOC( 32 * 4 ); @@ -2538,8 +2575,8 @@ static void save_PolygonOffset( GLfloat factor, GLfloat units ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_POLYGON_OFFSET, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_OFFSET, 2 ); if (n) { n[1].f = factor; n[2].f = units; @@ -2560,8 +2597,8 @@ static void save_PolygonOffsetEXT( GLfloat factor, GLfloat bias ) static void save_PopAttrib( void ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); - (void) alloc_instruction( ctx, OPCODE_POP_ATTRIB, 0 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_ATTRIB, 0 ); if (ctx->ExecuteFlag) { (*ctx->Exec->PopAttrib)(); } @@ -2571,8 +2608,8 @@ static void save_PopAttrib( void ) static void save_PopMatrix( void ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); - (void) alloc_instruction( ctx, OPCODE_POP_MATRIX, 0 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_MATRIX, 0 ); if (ctx->ExecuteFlag) { (*ctx->Exec->PopMatrix)(); } @@ -2582,8 +2619,8 @@ static void save_PopMatrix( void ) static void save_PopName( void ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); - (void) alloc_instruction( ctx, OPCODE_POP_NAME, 0 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_NAME, 0 ); if (ctx->ExecuteFlag) { (*ctx->Exec->PopName)(); } @@ -2595,11 +2632,11 @@ static void save_PrioritizeTextures( GLsizei num, const GLuint *textures, { GET_CURRENT_CONTEXT(ctx); GLint i; - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); for (i=0;i<num;i++) { Node *n; - n = alloc_instruction( ctx, OPCODE_PRIORITIZE_TEXTURE, 2 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PRIORITIZE_TEXTURE, 2 ); if (n) { n[1].ui = textures[i]; n[2].f = priorities[i]; @@ -2615,8 +2652,8 @@ static void save_PushAttrib( GLbitfield mask ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_PUSH_ATTRIB, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_ATTRIB, 1 ); if (n) { n[1].bf = mask; } @@ -2629,8 +2666,8 @@ static void save_PushAttrib( GLbitfield mask ) static void save_PushMatrix( void ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); - (void) alloc_instruction( ctx, OPCODE_PUSH_MATRIX, 0 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_MATRIX, 0 ); if (ctx->ExecuteFlag) { (*ctx->Exec->PushMatrix)(); } @@ -2641,8 +2678,8 @@ static void save_PushName( GLuint name ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_PUSH_NAME, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_NAME, 1 ); if (n) { n[1].ui = name; } @@ -2656,8 +2693,8 @@ static void save_RasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_RASTER_POS, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_RASTER_POS, 4 ); if (n) { n[1].f = x; n[2].f = y; @@ -2789,8 +2826,8 @@ static void save_PassThrough( GLfloat token ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_PASSTHROUGH, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PASSTHROUGH, 1 ); if (n) { n[1].f = token; } @@ -2804,8 +2841,8 @@ static void save_ReadBuffer( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_READ_BUFFER, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_READ_BUFFER, 1 ); if (n) { n[1].e = mode; } @@ -2819,8 +2856,8 @@ static void save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_RECTF, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_RECTF, 4 ); if (n) { n[1].f = x1; n[2].f = y1; @@ -2873,8 +2910,8 @@ save_ResetHistogram(GLenum target) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_RESET_HISTOGRAM, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_RESET_HISTOGRAM, 1 ); if (n) { n[1].e = target; } @@ -2889,8 +2926,8 @@ save_ResetMinmax(GLenum target) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_RESET_MIN_MAX, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_RESET_MIN_MAX, 1 ); if (n) { n[1].e = target; } @@ -2902,9 +2939,19 @@ save_ResetMinmax(GLenum target) static void save_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) { - GLfloat m[16]; - gl_rotation_matrix( angle, x, y, z, m ); - save_MultMatrixf( m ); /* save and maybe execute */ + GET_CURRENT_CONTEXT(ctx); + Node *n; + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ROTATE, 4 ); + if (n) { + n[1].f = angle; + n[2].f = x; + n[3].f = y; + n[4].f = z; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Rotatef)( angle, x, y, z ); + } } @@ -2918,8 +2965,8 @@ static void save_Scalef( GLfloat x, GLfloat y, GLfloat z ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_SCALE, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_SCALE, 3 ); if (n) { n[1].f = x; n[2].f = y; @@ -2941,8 +2988,8 @@ static void save_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_SCISSOR, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_SCISSOR, 4 ); if (n) { n[1].i = x; n[2].i = y; @@ -2959,8 +3006,8 @@ static void save_ShadeModel( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_SHADE_MODEL, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_SHADE_MODEL, 1 ); if (n) { n[1].e = mode; } @@ -2974,8 +3021,8 @@ static void save_StencilFunc( GLenum func, GLint ref, GLuint mask ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_STENCIL_FUNC, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_FUNC, 3 ); if (n) { n[1].e = func; n[2].i = ref; @@ -2991,8 +3038,8 @@ static void save_StencilMask( GLuint mask ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_STENCIL_MASK, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_MASK, 1 ); if (n) { n[1].ui = mask; } @@ -3006,8 +3053,8 @@ static void save_StencilOp( GLenum fail, GLenum zfail, GLenum zpass ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_STENCIL_OP, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_OP, 3 ); if (n) { n[1].e = fail; n[2].e = zfail; @@ -3023,8 +3070,8 @@ static void save_TexEnvfv( GLenum target, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEXENV, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXENV, 6 ); if (n) { n[1].e = target; n[2].e = pname; @@ -3069,8 +3116,8 @@ static void save_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEXGEN, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXGEN, 6 ); if (n) { n[1].e = coord; n[2].e = pname; @@ -3131,8 +3178,8 @@ static void save_TexParameterfv( GLenum target, { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEXPARAMETER, 6 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXPARAMETER, 6 ); if (n) { n[1].e = target; n[2].e = pname; @@ -3187,8 +3234,8 @@ static void save_TexImage1D( GLenum target, GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, pixels, &ctx->Unpack); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEX_IMAGE1D, 8 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE1D, 8 ); if (n) { n[1].e = target; n[2].i = level; @@ -3226,8 +3273,8 @@ static void save_TexImage2D( GLenum target, GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, pixels, &ctx->Unpack); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEX_IMAGE2D, 9 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE2D, 9 ); if (n) { n[1].e = target; n[2].i = level; @@ -3267,8 +3314,8 @@ static void save_TexImage3D( GLenum target, Node *n; GLvoid *image = _mesa_unpack_image(width, height, depth, format, type, pixels, &ctx->Unpack); - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEX_IMAGE3D, 10 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE3D, 10 ); if (n) { n[1].e = target; n[2].i = level; @@ -3300,8 +3347,8 @@ static void save_TexSubImage1D( GLenum target, GLint level, GLint xoffset, Node *n; GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, pixels, &ctx->Unpack); - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE1D, 7 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE1D, 7 ); if (n) { n[1].e = target; n[2].i = level; @@ -3331,8 +3378,8 @@ static void save_TexSubImage2D( GLenum target, GLint level, Node *n; GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, pixels, &ctx->Unpack); - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE2D, 9 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE2D, 9 ); if (n) { n[1].e = target; n[2].i = level; @@ -3364,8 +3411,8 @@ static void save_TexSubImage3D( GLenum target, GLint level, Node *n; GLvoid *image = _mesa_unpack_image(width, height, depth, format, type, pixels, &ctx->Unpack); - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE3D, 11 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE3D, 11 ); if (n) { n[1].e = target; n[2].i = level; @@ -3394,8 +3441,8 @@ static void save_Translatef( GLfloat x, GLfloat y, GLfloat z ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_TRANSLATE, 3 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TRANSLATE, 3 ); if (n) { n[1].f = x; n[2].f = y; @@ -3418,8 +3465,8 @@ static void save_Viewport( GLint x, GLint y, GLsizei width, GLsizei height ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_VIEWPORT, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_VIEWPORT, 4 ); if (n) { n[1].i = x; n[2].i = y; @@ -3436,8 +3483,8 @@ static void save_WindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_WINDOW_POS, 4 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_WINDOW_POS, 4 ); if (n) { n[1].f = x; n[2].f = y; @@ -3571,8 +3618,8 @@ static void save_ActiveTextureARB( GLenum target ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_ACTIVE_TEXTURE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ACTIVE_TEXTURE, 1 ); if (n) { n[1].e = target; } @@ -3587,8 +3634,8 @@ static void save_ClientActiveTextureARB( GLenum target ) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_CLIENT_ACTIVE_TEXTURE, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLIENT_ACTIVE_TEXTURE, 1 ); if (n) { n[1].e = target; } @@ -3603,32 +3650,32 @@ static void save_ClientActiveTextureARB( GLenum target ) static void save_LoadTransposeMatrixdARB( const GLdouble m[16] ) { - GLdouble tm[16]; - gl_matrix_transposed(tm, m); - save_LoadMatrixd(tm); + GLfloat tm[16]; + _math_transposefd(tm, m); + save_LoadMatrixf(tm); } static void save_LoadTransposeMatrixfARB( const GLfloat m[16] ) { GLfloat tm[16]; - gl_matrix_transposef(tm, m); + _math_transposef(tm, m); save_LoadMatrixf(tm); } static void save_MultTransposeMatrixdARB( const GLdouble m[16] ) { - GLdouble tm[16]; - gl_matrix_transposed(tm, m); - save_MultMatrixd(tm); + GLfloat tm[16]; + _math_transposefd(tm, m); + save_MultMatrixf(tm); } static void save_MultTransposeMatrixfARB( const GLfloat m[16] ) { GLfloat tm[16]; - gl_matrix_transposef(tm, m); + _math_transposef(tm, m); save_MultMatrixf(tm); } @@ -3637,8 +3684,8 @@ static void save_PixelTexGenSGIX(GLenum mode) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_PIXEL_TEXGEN_SGIX, 1 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_TEXGEN_SGIX, 1 ); if (n) { n[1].e = mode; } @@ -3664,7 +3711,7 @@ save_CompressedTexImage1DARB(GLenum target, GLint level, else { Node *n; GLvoid *image; - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); /* make copy of image */ image = MALLOC(imageSize); if (!image) { @@ -3672,7 +3719,7 @@ save_CompressedTexImage1DARB(GLenum target, GLint level, return; } MEMCPY(image, data, imageSize); - n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 8 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 8 ); if (n) { n[1].e = target; n[2].i = level; @@ -3708,7 +3755,7 @@ save_CompressedTexImage2DARB(GLenum target, GLint level, else { Node *n; GLvoid *image; - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); /* make copy of image */ image = MALLOC(imageSize); if (!image) { @@ -3716,7 +3763,7 @@ save_CompressedTexImage2DARB(GLenum target, GLint level, return; } MEMCPY(image, data, imageSize); - n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 9 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 9 ); if (n) { n[1].e = target; n[2].i = level; @@ -3753,7 +3800,7 @@ save_CompressedTexImage3DARB(GLenum target, GLint level, else { Node *n; GLvoid *image; - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); /* make copy of image */ image = MALLOC(imageSize); if (!image) { @@ -3761,7 +3808,7 @@ save_CompressedTexImage3DARB(GLenum target, GLint level, return; } MEMCPY(image, data, imageSize); - n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 10 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 10 ); if (n) { n[1].e = target; n[2].i = level; @@ -3793,7 +3840,7 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLvoid *image; GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); /* make copy of image */ image = MALLOC(imageSize); @@ -3802,7 +3849,7 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, return; } MEMCPY(image, data, imageSize); - n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 8 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 8 ); if (n) { n[1].e = target; n[2].i = level; @@ -3832,7 +3879,7 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLvoid *image; GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); /* make copy of image */ image = MALLOC(imageSize); @@ -3841,7 +3888,7 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, return; } MEMCPY(image, data, imageSize); - n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 10 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 10 ); if (n) { n[1].e = target; n[2].i = level; @@ -3873,7 +3920,7 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLvoid *image; GET_CURRENT_CONTEXT(ctx); - FLUSH_VB(ctx, "dlist"); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); /* make copy of image */ image = MALLOC(imageSize); @@ -3882,7 +3929,7 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, return; } MEMCPY(image, data, imageSize); - n = alloc_instruction( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 12 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 12 ); if (n) { n[1].e = target; n[2].i = level; @@ -3912,8 +3959,8 @@ static void save_PixelTexGenParameteriSGIS(GLenum target, GLint value) { GET_CURRENT_CONTEXT(ctx); Node *n; - FLUSH_VB(ctx, "dlist"); - n = alloc_instruction( ctx, OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS, 2 ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS, 2 ); if (n) { n[1].e = target; n[2].i = value; @@ -3941,56 +3988,6 @@ static void save_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value) save_PixelTexGenParameteriSGIS(target, (GLint) *value); } -void gl_compile_cassette( GLcontext *ctx ) -{ - Node *n = alloc_instruction( ctx, OPCODE_VERTEX_CASSETTE, 8 ); - struct immediate *im = ctx->input; - - if (!n) - return; - - - /* Do some easy optimizations of the cassette. - */ -#if 0 - if (0 && im->v.Obj.size < 4 && im->Count > 15) { - im->Bounds = (GLfloat (*)[3]) MALLOC(6 * sizeof(GLfloat)); - (gl_calc_bound_tab[im->v.Obj.size])( im->Bounds, &im->v.Obj ); - } -#endif - - n[1].data = (void *)im; - n[2].ui = im->Start; - n[3].ui = im->Count; - n[4].ui = im->BeginState; - n[5].ui = im->OrFlag; - n[6].ui = im->AndFlag; - n[7].ui = im->LastData; - n[8].ui = im->LastPrimitive; - - if (im->Count > VB_MAX - 4) { - - struct immediate *new_im = gl_immediate_alloc(ctx); - if (!new_im) return; - SET_IMMEDIATE( ctx, new_im ); - gl_reset_input( ctx ); - - } else { - im->Count++;; - im->Start = im->Count; /* don't clear anything in reset_input */ - im->ref_count++; - - im->Primitive[im->Start] = ctx->Current.Primitive; - im->LastPrimitive = im->Start; - im->BeginState = VERT_BEGIN_0; - im->OrFlag = 0; - im->AndFlag = ~0; - - if (0) - fprintf(stderr, "in compile_cassette, BeginState is %x\n", - im->BeginState); - } -} /* KW: Compile commands * @@ -4000,7 +3997,7 @@ void gl_compile_cassette( GLcontext *ctx ) void gl_save_error( GLcontext *ctx, GLenum error, const char *s ) { Node *n; - n = alloc_instruction( ctx, OPCODE_ERROR, 2 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ERROR, 2 ); if (n) { n[1].e = error; n[2].data = (void *) s; @@ -4037,12 +4034,11 @@ static void execute_list( GLcontext *ctx, GLuint list ) { Node *n; GLboolean done; - OpCode opcode; if (!islist(ctx,list)) return; -/* mesa_print_display_list( list ); */ +/* mesa_print_display_list( list ); */ ctx->CallDepth++; @@ -4050,49 +4046,18 @@ static void execute_list( GLcontext *ctx, GLuint list ) done = GL_FALSE; while (!done) { - opcode = n[0].opcode; + OpCode opcode = n[0].opcode; + int i = (int)n[0].opcode - (int)OPCODE_DRV_0; - switch (opcode) { - case OPCODE_ERROR: - gl_error( ctx, n[1].e, (const char *) n[2].data ); - break; - case OPCODE_VERTEX_CASSETTE: { - struct immediate *IM; - - if (ctx->NewState) - gl_update_state(ctx); - if (ctx->CompileCVAFlag) { - ctx->CompileCVAFlag = 0; - ctx->CVA.elt.pipeline_valid = 0; - } - if (!ctx->CVA.elt.pipeline_valid) - gl_build_immediate_pipeline( ctx ); - - - IM = (struct immediate *) n[1].data; - IM->Start = n[2].ui; - IM->Count = n[3].ui; - IM->BeginState = n[4].ui; - IM->OrFlag = n[5].ui; - IM->AndFlag = n[6].ui; - IM->LastData = n[7].ui; - IM->LastPrimitive = n[8].ui; - - if ((MESA_VERBOSE & VERBOSE_DISPLAY_LIST) && - (MESA_VERBOSE & VERBOSE_IMMEDIATE)) - gl_print_cassette( (struct immediate *) n[1].data ); - - if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST) { - fprintf(stderr, "Run cassette %d, rows %d..%d, beginstate %x ", - IM->id, - IM->Start, IM->Count, IM->BeginState); - gl_print_vert_flags("orflag", IM->OrFlag); - } - - gl_fixup_cassette( ctx, (struct immediate *) n[1].data ); - gl_execute_cassette( ctx, (struct immediate *) n[1].data ); - break; - } + if (i >= 0 && i < ctx->listext.nr_opcodes) { + ctx->listext.opcode[i].execute(ctx, &n[1]); + n += ctx->listext.opcode[i].size; + } + else { + switch (opcode) { + case OPCODE_ERROR: + gl_error( ctx, n[1].e, (const char *) n[2].data ); + break; case OPCODE_ACCUM: (*ctx->Exec->Accum)( n[1].e, n[2].f ); break; @@ -4518,7 +4483,7 @@ static void execute_list( GLcontext *ctx, GLuint list ) break; case OPCODE_RECTF: (*ctx->Exec->Rectf)( n[1].f, n[2].f, n[3].f, n[4].f ); - FLUSH_VB( ctx, "dlist rectf" ); + FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); break; case OPCODE_RESET_HISTOGRAM: (*ctx->Exec->ResetHistogram)( n[1].e ); @@ -4526,6 +4491,9 @@ static void execute_list( GLcontext *ctx, GLuint list ) case OPCODE_RESET_MIN_MAX: (*ctx->Exec->ResetMinmax)( n[1].e ); break; + case OPCODE_ROTATE: + (*ctx->Exec->Rotatef)( n[1].f, n[2].f, n[3].f, n[4].f ); + break; case OPCODE_SCALE: (*ctx->Exec->Scalef)( n[1].f, n[2].f, n[3].f ); break; @@ -4716,13 +4684,13 @@ static void execute_list( GLcontext *ctx, GLuint list ) gl_problem( ctx, msg ); } done = GL_TRUE; - } + } - /* increment n to point to next compiled command */ - if (opcode!=OPCODE_CONTINUE) { - n += InstSize[opcode]; + /* increment n to point to next compiled command */ + if (opcode!=OPCODE_CONTINUE) { + n += InstSize[opcode]; + } } - } ctx->CallDepth--; } @@ -4817,8 +4785,8 @@ void _mesa_NewList( GLuint list, GLenum mode ) { GET_CURRENT_CONTEXT(ctx); - struct immediate *IM; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glNewList"); + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); if (MESA_VERBOSE&VERBOSE_API) fprintf(stderr, "glNewList %u %s\n", list, gl_lookup_enum_by_nr(mode)); @@ -4844,15 +4812,11 @@ _mesa_NewList( GLuint list, GLenum mode ) ctx->CurrentBlock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE ); ctx->CurrentListPtr = ctx->CurrentBlock; ctx->CurrentPos = 0; - - IM = gl_immediate_alloc( ctx ); - SET_IMMEDIATE( ctx, IM ); - gl_reset_input( ctx ); - ctx->CompileFlag = GL_TRUE; - ctx->CompileCVAFlag = GL_FALSE; ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE); + ctx->Driver.NewList( ctx, list, mode ); + ctx->CurrentDispatch = ctx->Save; _glapi_set_dispatch( ctx->CurrentDispatch ); } @@ -4870,6 +4834,8 @@ _mesa_EndList( void ) fprintf(stderr, "glEndList\n"); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glEndList" ); + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); + /* Check that a list is under construction */ if (!ctx->CurrentListPtr) { @@ -4877,7 +4843,7 @@ _mesa_EndList( void ) return; } - (void) alloc_instruction( ctx, OPCODE_END_OF_LIST, 0 ); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_END_OF_LIST, 0 ); /* Destroy old list, if any */ gl_destroy_list(ctx, ctx->CurrentListNum); @@ -4892,15 +4858,8 @@ _mesa_EndList( void ) ctx->CurrentListPtr = NULL; ctx->ExecuteFlag = GL_TRUE; ctx->CompileFlag = GL_FALSE; - /* ctx->CompileCVAFlag = ...; */ - /* KW: Put back the old input pointer. - */ - if (--ctx->input->ref_count == 0) - gl_immediate_free( ctx->input ); - - SET_IMMEDIATE( ctx, ctx->VB->IM ); - gl_reset_input( ctx ); + ctx->Driver.EndList( ctx ); /* Haven't tracked down why this is needed. */ @@ -4928,7 +4887,7 @@ _mesa_CallList( GLuint list ) save_compile_flag = ctx->CompileFlag; ctx->CompileFlag = GL_FALSE; - FLUSH_VB( ctx, "call list" ); + FLUSH_TNL( ctx, (FLUSH_STORED_VERTICES | FLUSH_UPDATE_CURRENT) ); execute_list( ctx, list ); ctx->CompileFlag = save_compile_flag; @@ -4958,7 +4917,7 @@ _mesa_CallLists( GLsizei n, GLenum type, const GLvoid *lists ) save_compile_flag = ctx->CompileFlag; ctx->CompileFlag = GL_FALSE; - FLUSH_VB( ctx, "call lists" ); + FLUSH_TNL( ctx, (FLUSH_STORED_VERTICES | FLUSH_UPDATE_CURRENT) ); for (i=0;i<n;i++) { list = translate_id( i, type, lists ); @@ -5002,7 +4961,7 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize ) /* GL 1.0 */ table->Accum = save_Accum; table->AlphaFunc = save_AlphaFunc; - table->Begin = save_Begin; + table->Begin = _mesa_Begin; table->Bitmap = save_Bitmap; table->BlendFunc = save_BlendFunc; table->CallList = save_CallList; @@ -5565,7 +5524,6 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list ) { Node *n; GLboolean done; - OpCode opcode; if (!glIsList(list)) { fprintf(f,"%u is not a display list ID\n",list); @@ -5578,9 +5536,14 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list ) done = n ? GL_FALSE : GL_TRUE; while (!done) { - opcode = n[0].opcode; - - switch (opcode) { + OpCode opcode = n[0].opcode; + int i = (int)n[0].opcode - (int)OPCODE_DRV_0; + + if (i >= 0 && i < ctx->listext.nr_opcodes) { + ctx->listext.opcode[i].print(ctx, &n[1]); + n += ctx->listext.opcode[i].size; + } else { + switch (opcode) { case OPCODE_ACCUM: fprintf(f,"accum %s %g\n", enum_string(n[1].e), n[2].f ); break; @@ -5663,6 +5626,9 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list ) case OPCODE_RECTF: fprintf( f, "Rectf %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f); break; + case OPCODE_ROTATE: + fprintf(f,"Rotate %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f ); + break; case OPCODE_SCALE: fprintf(f,"Scale %g %g %g\n", n[1].f, n[2].f, n[3].f ); break; @@ -5683,13 +5649,6 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list ) case OPCODE_ERROR: fprintf(f,"Error: %s %s\n", enum_string(n[1].e), (const char *)n[2].data ); break; - case OPCODE_VERTEX_CASSETTE: - fprintf(f,"VERTEX-CASSETTE, id %u, rows %u..%u\n", - ((struct immediate *) n[1].data)->id, - n[2].ui, - n[3].ui); - gl_print_cassette( (struct immediate *) n[1].data ); - break; case OPCODE_CONTINUE: fprintf(f,"DISPLAY-LIST-CONTINUE\n"); n = (Node *) n[1].next; @@ -5707,11 +5666,11 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list ) else { fprintf(f,"command %d, %u operands\n",opcode,InstSize[opcode]); } - } - - /* increment n to point to next compiled command */ - if (opcode!=OPCODE_CONTINUE) { - n += InstSize[opcode]; + } + /* increment n to point to next compiled command */ + if (opcode!=OPCODE_CONTINUE) { + n += InstSize[opcode]; + } } } } diff --git a/src/mesa/main/dlist.h b/src/mesa/main/dlist.h index e24ce6fe738..cbe8a4b47c2 100644 --- a/src/mesa/main/dlist.h +++ b/src/mesa/main/dlist.h @@ -1,4 +1,4 @@ -/* $Id: dlist.h,v 1.6 2000/09/24 16:11:55 brianp Exp $ */ +/* $Id: dlist.h,v 1.7 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -54,9 +54,17 @@ extern void _mesa_NewList( GLuint list, GLenum mode ); extern void _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize ); -extern void gl_compile_cassette( GLcontext *ctx ); - extern void gl_save_error( GLcontext *ctx, GLenum error, const char *s ); +void * +_mesa_alloc_instruction( GLcontext *ctx, int opcode, GLint sz ); + +int +_mesa_alloc_opcode( GLcontext *ctx, GLuint sz, + void (*execute)( GLcontext *, void * ), + void (*destroy)( GLcontext *, void * ), + void (*print)( GLcontext *, void * ) ); + + #endif diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index afdc5952734..34e1dcf991b 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -1,4 +1,4 @@ -/* $Id: drawpix.c,v 1.44 2000/10/31 18:09:44 keithw Exp $ */ +/* $Id: drawpix.c,v 1.45 2000/11/16 21:05:34 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -31,6 +31,7 @@ #include "glheader.h" #include "colormac.h" #include "context.h" +#include "drawpix.h" #include "feedback.h" #include "macros.h" #include "mem.h" @@ -52,7 +53,7 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "_mesa_DrawPixels" ); if (ctx->RenderMode==GL_RENDER) { GLint x, y; @@ -86,6 +87,9 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, if (ctx->Current.RasterPosValid) { GLfloat color[4]; GLfloat texcoord[4], invq; + + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); + color[0] = CHAN_TO_FLOAT(ctx->Current.Color[0]); color[1] = CHAN_TO_FLOAT(ctx->Current.Color[1]); color[2] = CHAN_TO_FLOAT(ctx->Current.Color[2]); diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 3d21f95bea1..afcb916fe8a 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -1,4 +1,4 @@ -/* $Id: enable.c,v 1.31 2000/11/05 18:40:57 keithw Exp $ */ +/* $Id: enable.c,v 1.32 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -33,13 +33,14 @@ #include "enable.h" #include "light.h" #include "macros.h" -#include "matrix.h" #include "mmath.h" #include "simple_list.h" #include "types.h" -#include "vbfill.h" -#include "xform.h" #include "enums.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + #endif @@ -98,10 +99,14 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) ctx->_Enabled |= ENABLE_USERCLIP; ctx->Transform._AnyClip++; - if (ctx->ProjectionMatrix.flags & MAT_DIRTY_ALL_OVER) { - gl_matrix_analyze( &ctx->ProjectionMatrix ); + if (ctx->ProjectionMatrix.flags & MAT_DIRTY) { + _math_matrix_analyze( &ctx->ProjectionMatrix ); } + /* This derived state also calculated in clip.c and + * from gl_update_state() on changes to EyeUserPlane + * and ctx->ProjectionMatrix respectively. + */ gl_transform_vector( ctx->Transform._ClipUserPlane[p], ctx->Transform.EyeUserPlane[p], ctx->ProjectionMatrix.inv ); @@ -113,10 +118,13 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) break; case GL_COLOR_MATERIAL: if (ctx->Light.ColorMaterialEnabled!=state) { - ctx->Light.ColorMaterialEnabled = state; + ctx->Light.ColorMaterialEnabled = state; ctx->NewState |= _NEW_LIGHT; - if (state) + + if (state) { + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); gl_update_color_material( ctx, ctx->Current.Color ); + } } break; case GL_CULL_FACE: diff --git a/src/mesa/main/eval.c b/src/mesa/main/eval.c index 1c779eb5e32..1cb8e26d1ac 100644 --- a/src/mesa/main/eval.c +++ b/src/mesa/main/eval.c @@ -1,4 +1,4 @@ -/* $Id: eval.c,v 1.14 2000/10/30 13:32:00 keithw Exp $ */ +/* $Id: eval.c,v 1.15 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -49,479 +49,9 @@ #include "mem.h" #include "mmath.h" #include "types.h" -#include "vb.h" -#include "vbcull.h" -#include "vbfill.h" -#include "vbxform.h" #endif -static GLfloat inv_tab[MAX_EVAL_ORDER]; - -/* - * Do one-time initialization for evaluators. - */ -void gl_init_eval( void ) -{ - static int init_flag = 0; - GLuint i; - - /* Compute a table of nCr (combination) values used by the - * Bernstein polynomial generator. - */ - - /* KW: precompute 1/x for useful x. - */ - if (init_flag==0) - { - for (i = 1 ; i < MAX_EVAL_ORDER ; i++) - inv_tab[i] = 1.0 / i; - } - - init_flag = 1; -} - - - -/* - * Horner scheme for Bezier curves - * - * Bezier curves can be computed via a Horner scheme. - * Horner is numerically less stable than the de Casteljau - * algorithm, but it is faster. For curves of degree n - * the complexity of Horner is O(n) and de Casteljau is O(n^2). - * Since stability is not important for displaying curve - * points I decided to use the Horner scheme. - * - * A cubic Bezier curve with control points b0, b1, b2, b3 can be - * written as - * - * (([3] [3] ) [3] ) [3] - * c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3 - * - * [n] - * where s=1-t and the binomial coefficients [i]. These can - * be computed iteratively using the identity: - * - * [n] [n ] [n] - * [i] = (n-i+1)/i * [i-1] and [0] = 1 - */ - - -static void -horner_bezier_curve(const GLfloat *cp, GLfloat *out, GLfloat t, - GLuint dim, GLuint order) -{ - GLfloat s, powert; - GLuint i, k, bincoeff; - - if(order >= 2) - { - bincoeff = order-1; - s = 1.0-t; - - for(k=0; k<dim; k++) - out[k] = s*cp[k] + bincoeff*t*cp[dim+k]; - - for(i=2, cp+=2*dim, powert=t*t; i<order; i++, powert*=t, cp +=dim) - { - bincoeff *= order-i; - bincoeff *= inv_tab[i]; - - for(k=0; k<dim; k++) - out[k] = s*out[k] + bincoeff*powert*cp[k]; - } - } - else /* order=1 -> constant curve */ - { - for(k=0; k<dim; k++) - out[k] = cp[k]; - } -} - -/* - * Tensor product Bezier surfaces - * - * Again the Horner scheme is used to compute a point on a - * TP Bezier surface. First a control polygon for a curve - * on the surface in one parameter direction is computed, - * then the point on the curve for the other parameter - * direction is evaluated. - * - * To store the curve control polygon additional storage - * for max(uorder,vorder) points is needed in the - * control net cn. - */ - -static void -horner_bezier_surf(GLfloat *cn, GLfloat *out, GLfloat u, GLfloat v, - GLuint dim, GLuint uorder, GLuint vorder) -{ - GLfloat *cp = cn + uorder*vorder*dim; - GLuint i, uinc = vorder*dim; - - if(vorder > uorder) - { - if(uorder >= 2) - { - GLfloat s, poweru; - GLuint j, k, bincoeff; - - /* Compute the control polygon for the surface-curve in u-direction */ - for(j=0; j<vorder; j++) - { - GLfloat *ucp = &cn[j*dim]; - - /* Each control point is the point for parameter u on a */ - /* curve defined by the control polygons in u-direction */ - bincoeff = uorder-1; - s = 1.0-u; - - for(k=0; k<dim; k++) - cp[j*dim+k] = s*ucp[k] + bincoeff*u*ucp[uinc+k]; - - for(i=2, ucp+=2*uinc, poweru=u*u; i<uorder; - i++, poweru*=u, ucp +=uinc) - { - bincoeff *= uorder-i; - bincoeff *= inv_tab[i]; - - for(k=0; k<dim; k++) - cp[j*dim+k] = s*cp[j*dim+k] + bincoeff*poweru*ucp[k]; - } - } - - /* Evaluate curve point in v */ - horner_bezier_curve(cp, out, v, dim, vorder); - } - else /* uorder=1 -> cn defines a curve in v */ - horner_bezier_curve(cn, out, v, dim, vorder); - } - else /* vorder <= uorder */ - { - if(vorder > 1) - { - GLuint i; - - /* Compute the control polygon for the surface-curve in u-direction */ - for(i=0; i<uorder; i++, cn += uinc) - { - /* For constant i all cn[i][j] (j=0..vorder) are located */ - /* on consecutive memory locations, so we can use */ - /* horner_bezier_curve to compute the control points */ - - horner_bezier_curve(cn, &cp[i*dim], v, dim, vorder); - } - - /* Evaluate curve point in u */ - horner_bezier_curve(cp, out, u, dim, uorder); - } - else /* vorder=1 -> cn defines a curve in u */ - horner_bezier_curve(cn, out, u, dim, uorder); - } -} - -/* - * The direct de Casteljau algorithm is used when a point on the - * surface and the tangent directions spanning the tangent plane - * should be computed (this is needed to compute normals to the - * surface). In this case the de Casteljau algorithm approach is - * nicer because a point and the partial derivatives can be computed - * at the same time. To get the correct tangent length du and dv - * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1. - * Since only the directions are needed, this scaling step is omitted. - * - * De Casteljau needs additional storage for uorder*vorder - * values in the control net cn. - */ - -static void -de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv, - GLfloat u, GLfloat v, GLuint dim, - GLuint uorder, GLuint vorder) -{ - GLfloat *dcn = cn + uorder*vorder*dim; - GLfloat us = 1.0-u, vs = 1.0-v; - GLuint h, i, j, k; - GLuint minorder = uorder < vorder ? uorder : vorder; - GLuint uinc = vorder*dim; - GLuint dcuinc = vorder; - - /* Each component is evaluated separately to save buffer space */ - /* This does not drasticaly decrease the performance of the */ - /* algorithm. If additional storage for (uorder-1)*(vorder-1) */ - /* points would be available, the components could be accessed */ - /* in the innermost loop which could lead to less cache misses. */ - -#define CN(I,J,K) cn[(I)*uinc+(J)*dim+(K)] -#define DCN(I, J) dcn[(I)*dcuinc+(J)] - if(minorder < 3) - { - if(uorder==vorder) - { - for(k=0; k<dim; k++) - { - /* Derivative direction in u */ - du[k] = vs*(CN(1,0,k) - CN(0,0,k)) + - v*(CN(1,1,k) - CN(0,1,k)); - - /* Derivative direction in v */ - dv[k] = us*(CN(0,1,k) - CN(0,0,k)) + - u*(CN(1,1,k) - CN(1,0,k)); - - /* bilinear de Casteljau step */ - out[k] = us*(vs*CN(0,0,k) + v*CN(0,1,k)) + - u*(vs*CN(1,0,k) + v*CN(1,1,k)); - } - } - else if(minorder == uorder) - { - for(k=0; k<dim; k++) - { - /* bilinear de Casteljau step */ - DCN(1,0) = CN(1,0,k) - CN(0,0,k); - DCN(0,0) = us*CN(0,0,k) + u*CN(1,0,k); - - for(j=0; j<vorder-1; j++) - { - /* for the derivative in u */ - DCN(1,j+1) = CN(1,j+1,k) - CN(0,j+1,k); - DCN(1,j) = vs*DCN(1,j) + v*DCN(1,j+1); - - /* for the `point' */ - DCN(0,j+1) = us*CN(0,j+1,k) + u*CN(1,j+1,k); - DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1); - } - - /* remaining linear de Casteljau steps until the second last step */ - for(h=minorder; h<vorder-1; h++) - for(j=0; j<vorder-h; j++) - { - /* for the derivative in u */ - DCN(1,j) = vs*DCN(1,j) + v*DCN(1,j+1); - - /* for the `point' */ - DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1); - } - - /* derivative direction in v */ - dv[k] = DCN(0,1) - DCN(0,0); - - /* derivative direction in u */ - du[k] = vs*DCN(1,0) + v*DCN(1,1); - - /* last linear de Casteljau step */ - out[k] = vs*DCN(0,0) + v*DCN(0,1); - } - } - else /* minorder == vorder */ - { - for(k=0; k<dim; k++) - { - /* bilinear de Casteljau step */ - DCN(0,1) = CN(0,1,k) - CN(0,0,k); - DCN(0,0) = vs*CN(0,0,k) + v*CN(0,1,k); - for(i=0; i<uorder-1; i++) - { - /* for the derivative in v */ - DCN(i+1,1) = CN(i+1,1,k) - CN(i+1,0,k); - DCN(i,1) = us*DCN(i,1) + u*DCN(i+1,1); - - /* for the `point' */ - DCN(i+1,0) = vs*CN(i+1,0,k) + v*CN(i+1,1,k); - DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); - } - - /* remaining linear de Casteljau steps until the second last step */ - for(h=minorder; h<uorder-1; h++) - for(i=0; i<uorder-h; i++) - { - /* for the derivative in v */ - DCN(i,1) = us*DCN(i,1) + u*DCN(i+1,1); - - /* for the `point' */ - DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); - } - - /* derivative direction in u */ - du[k] = DCN(1,0) - DCN(0,0); - - /* derivative direction in v */ - dv[k] = us*DCN(0,1) + u*DCN(1,1); - - /* last linear de Casteljau step */ - out[k] = us*DCN(0,0) + u*DCN(1,0); - } - } - } - else if(uorder == vorder) - { - for(k=0; k<dim; k++) - { - /* first bilinear de Casteljau step */ - for(i=0; i<uorder-1; i++) - { - DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k); - for(j=0; j<vorder-1; j++) - { - DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k); - DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); - } - } - - /* remaining bilinear de Casteljau steps until the second last step */ - for(h=2; h<minorder-1; h++) - for(i=0; i<uorder-h; i++) - { - DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); - for(j=0; j<vorder-h; j++) - { - DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1); - DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); - } - } - - /* derivative direction in u */ - du[k] = vs*(DCN(1,0) - DCN(0,0)) + - v*(DCN(1,1) - DCN(0,1)); - - /* derivative direction in v */ - dv[k] = us*(DCN(0,1) - DCN(0,0)) + - u*(DCN(1,1) - DCN(1,0)); - - /* last bilinear de Casteljau step */ - out[k] = us*(vs*DCN(0,0) + v*DCN(0,1)) + - u*(vs*DCN(1,0) + v*DCN(1,1)); - } - } - else if(minorder == uorder) - { - for(k=0; k<dim; k++) - { - /* first bilinear de Casteljau step */ - for(i=0; i<uorder-1; i++) - { - DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k); - for(j=0; j<vorder-1; j++) - { - DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k); - DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); - } - } - - /* remaining bilinear de Casteljau steps until the second last step */ - for(h=2; h<minorder-1; h++) - for(i=0; i<uorder-h; i++) - { - DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); - for(j=0; j<vorder-h; j++) - { - DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1); - DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); - } - } - - /* last bilinear de Casteljau step */ - DCN(2,0) = DCN(1,0) - DCN(0,0); - DCN(0,0) = us*DCN(0,0) + u*DCN(1,0); - for(j=0; j<vorder-1; j++) - { - /* for the derivative in u */ - DCN(2,j+1) = DCN(1,j+1) - DCN(0,j+1); - DCN(2,j) = vs*DCN(2,j) + v*DCN(2,j+1); - - /* for the `point' */ - DCN(0,j+1) = us*DCN(0,j+1 ) + u*DCN(1,j+1); - DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1); - } - - /* remaining linear de Casteljau steps until the second last step */ - for(h=minorder; h<vorder-1; h++) - for(j=0; j<vorder-h; j++) - { - /* for the derivative in u */ - DCN(2,j) = vs*DCN(2,j) + v*DCN(2,j+1); - - /* for the `point' */ - DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1); - } - - /* derivative direction in v */ - dv[k] = DCN(0,1) - DCN(0,0); - - /* derivative direction in u */ - du[k] = vs*DCN(2,0) + v*DCN(2,1); - - /* last linear de Casteljau step */ - out[k] = vs*DCN(0,0) + v*DCN(0,1); - } - } - else /* minorder == vorder */ - { - for(k=0; k<dim; k++) - { - /* first bilinear de Casteljau step */ - for(i=0; i<uorder-1; i++) - { - DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k); - for(j=0; j<vorder-1; j++) - { - DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k); - DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); - } - } - - /* remaining bilinear de Casteljau steps until the second last step */ - for(h=2; h<minorder-1; h++) - for(i=0; i<uorder-h; i++) - { - DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); - for(j=0; j<vorder-h; j++) - { - DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1); - DCN(i,j) = vs*DCN(i,j) + v*DCN(i,j+1); - } - } - - /* last bilinear de Casteljau step */ - DCN(0,2) = DCN(0,1) - DCN(0,0); - DCN(0,0) = vs*DCN(0,0) + v*DCN(0,1); - for(i=0; i<uorder-1; i++) - { - /* for the derivative in v */ - DCN(i+1,2) = DCN(i+1,1) - DCN(i+1,0); - DCN(i,2) = us*DCN(i,2) + u*DCN(i+1,2); - - /* for the `point' */ - DCN(i+1,0) = vs*DCN(i+1,0) + v*DCN(i+1,1); - DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); - } - - /* remaining linear de Casteljau steps until the second last step */ - for(h=minorder; h<uorder-1; h++) - for(i=0; i<uorder-h; i++) - { - /* for the derivative in v */ - DCN(i,2) = us*DCN(i,2) + u*DCN(i+1,2); - - /* for the `point' */ - DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0); - } - - /* derivative direction in u */ - du[k] = DCN(1,0) - DCN(0,0); - - /* derivative direction in v */ - dv[k] = us*DCN(0,2) + u*DCN(1,2); - - /* last linear de Casteljau step */ - out[k] = us*DCN(0,0) + u*DCN(1,0); - } - } -#undef DCN -#undef CN -} - /* * Return the number of components per control point for any type of * evaluator. Return 0 if bad target. @@ -1982,656 +1512,6 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) -static void eval_points1( GLfloat outcoord[][4], - GLfloat coord[][4], - const GLuint *flags, - GLuint start, - GLfloat du, GLfloat u1 ) -{ - GLuint i; - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & VERT_EVAL_P1) - outcoord[i][0] = coord[i][0] * du + u1; - else if (flags[i] & VERT_EVAL_ANY) { - outcoord[i][0] = coord[i][0]; - outcoord[i][1] = coord[i][1]; - } -} - -static void eval_points2( GLfloat outcoord[][4], - GLfloat coord[][4], - const GLuint *flags, - GLuint start, - GLfloat du, GLfloat u1, - GLfloat dv, GLfloat v1 ) -{ - GLuint i; - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & VERT_EVAL_P2) { - outcoord[i][0] = coord[i][0] * du + u1; - outcoord[i][1] = coord[i][1] * dv + v1; - } else if (flags[i] & VERT_EVAL_ANY) { - outcoord[i][0] = coord[i][0]; - outcoord[i][1] = coord[i][1]; - } -} - - -static const GLubyte dirty_flags[5] = { - 0, /* not possible */ - VEC_DIRTY_0, - VEC_DIRTY_1, - VEC_DIRTY_2, - VEC_DIRTY_3 -}; - - -static GLvector4f *eval1_4f( GLvector4f *dest, - GLfloat coord[][4], - const GLuint *flags, - GLuint start, - GLuint dimension, - struct gl_1d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - GLfloat (*to)[4] = dest->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { - GLfloat u = (coord[i][0] - u1) * du; - ASSIGN_4V(to[i], 0,0,0,1); - horner_bezier_curve(map->Points, to[i], u, dimension, map->Order); - } - - dest->count = i; - dest->start = VEC_ELT(dest, GLfloat, start); - dest->size = MAX2(dest->size, dimension); - dest->flags |= dirty_flags[dimension]; - return dest; -} - - -static GLvector1ui *eval1_1ui( GLvector1ui *dest, - GLfloat coord[][4], - const GLuint *flags, - GLuint start, - struct gl_1d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - GLuint *to = dest->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { - GLfloat u = (coord[i][0] - u1) * du; - GLfloat tmp; - horner_bezier_curve(map->Points, &tmp, u, 1, map->Order); - to[i] = (GLuint) (GLint) tmp; - } - - dest->start = VEC_ELT(dest, GLuint, start); - dest->count = i; - return dest; -} - -static GLvector3f *eval1_norm( GLvector3f *dest, - GLfloat coord[][4], - GLuint *flags, /* not const */ - GLuint start, - struct gl_1d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - GLfloat (*to)[3] = dest->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { - GLfloat u = (coord[i][0] - u1) * du; - horner_bezier_curve(map->Points, to[i], u, 3, map->Order); - flags[i+1] |= VERT_NORM; /* reset */ - } - - dest->start = VEC_ELT(dest, GLfloat, start); - dest->count = i; - return dest; -} - -static GLvector4ub *eval1_color( GLvector4ub *dest, - GLfloat coord[][4], - GLuint *flags, /* not const */ - GLuint start, - struct gl_1d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - GLubyte (*to)[4] = dest->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { - GLfloat u = (coord[i][0] - u1) * du; - GLfloat fcolor[4]; - horner_bezier_curve(map->Points, fcolor, u, 4, map->Order); - FLOAT_RGBA_TO_CHAN_RGBA(to[i], fcolor); - flags[i+1] |= VERT_RGBA; /* reset */ - } - - dest->start = VEC_ELT(dest, GLubyte, start); - dest->count = i; - return dest; -} - - - - -static GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr, - GLvector3f *norm_ptr, - GLfloat coord[][4], - GLuint *flags, - GLuint start, - GLuint dimension, - struct gl_2d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - const GLfloat v1 = map->v1; - const GLfloat dv = map->dv; - GLfloat (*obj)[4] = obj_ptr->data; - GLfloat (*normal)[3] = norm_ptr->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { - GLfloat u = (coord[i][0] - u1) * du; - GLfloat v = (coord[i][1] - v1) * dv; - GLfloat du[4], dv[4]; - - ASSIGN_4V(obj[i], 0,0,0,1); - de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension, - map->Uorder, map->Vorder); - - CROSS3(normal[i], du, dv); - NORMALIZE_3FV(normal[i]); - flags[i+1] |= VERT_NORM; - } - - obj_ptr->start = VEC_ELT(obj_ptr, GLfloat, start); - obj_ptr->count = i; - obj_ptr->size = MAX2(obj_ptr->size, dimension); - obj_ptr->flags |= dirty_flags[dimension]; - return obj_ptr; -} - - -static GLvector4f *eval2_4f( GLvector4f *dest, - GLfloat coord[][4], - const GLuint *flags, - GLuint start, - GLuint dimension, - struct gl_2d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - const GLfloat v1 = map->v1; - const GLfloat dv = map->dv; - GLfloat (*to)[4] = dest->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { - GLfloat u = (coord[i][0] - u1) * du; - GLfloat v = (coord[i][1] - v1) * dv; - horner_bezier_surf(map->Points, to[i], u, v, dimension, - map->Uorder, map->Vorder); - } - - dest->start = VEC_ELT(dest, GLfloat, start); - dest->count = i; - dest->size = MAX2(dest->size, dimension); - dest->flags |= dirty_flags[dimension]; - return dest; -} - - -static GLvector3f *eval2_norm( GLvector3f *dest, - GLfloat coord[][4], - GLuint *flags, - GLuint start, - struct gl_2d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - const GLfloat v1 = map->v1; - const GLfloat dv = map->dv; - GLfloat (*to)[3] = dest->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { - GLfloat u = (coord[i][0] - u1) * du; - GLfloat v = (coord[i][1] - v1) * dv; - horner_bezier_surf(map->Points, to[i], u, v, 3, - map->Uorder, map->Vorder); - flags[i+1] |= VERT_NORM; /* reset */ - } - - dest->start = VEC_ELT(dest, GLfloat, start); - dest->count = i; - return dest; -} - - -static GLvector1ui *eval2_1ui( GLvector1ui *dest, - GLfloat coord[][4], - const GLuint *flags, - GLuint start, - struct gl_2d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - const GLfloat v1 = map->v1; - const GLfloat dv = map->dv; - GLuint *to = dest->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { - GLfloat u = (coord[i][0] - u1) * du; - GLfloat v = (coord[i][1] - v1) * dv; - GLfloat tmp; - horner_bezier_surf(map->Points, &tmp, u, v, 1, - map->Uorder, map->Vorder); - - to[i] = (GLuint) (GLint) tmp; - } - - dest->start = VEC_ELT(dest, GLuint, start); - dest->count = i; - return dest; -} - - - -static GLvector4ub *eval2_color( GLvector4ub *dest, - GLfloat coord[][4], - GLuint *flags, - GLuint start, - struct gl_2d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - const GLfloat v1 = map->v1; - const GLfloat dv = map->dv; - GLubyte (*to)[4] = dest->data; - GLuint i; - - for (i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { - GLfloat u = (coord[i][0] - u1) * du; - GLfloat v = (coord[i][1] - v1) * dv; - GLfloat fcolor[4]; - horner_bezier_surf(map->Points, fcolor, u, v, 4, - map->Uorder, map->Vorder); - FLOAT_RGBA_TO_CHAN_RGBA(to[i], fcolor); - flags[i+1] |= VERT_RGBA; /* reset */ - } - - dest->start = VEC_ELT(dest, GLubyte, start); - dest->count = i; - return dest; -} - - -static GLvector4f *copy_4f( GLvector4f *out, CONST GLvector4f *in, - const GLuint *flags, - GLuint start ) -{ - GLfloat (*to)[4] = out->data; - GLfloat (*from)[4] = in->data; - GLuint i; - - for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (!(flags[i] & VERT_EVAL_ANY)) - COPY_4FV( to[i], from[i] ); - - out->start = VEC_ELT(out, GLfloat, start); - return out; -} - -static GLvector3f *copy_3f( GLvector3f *out, CONST GLvector3f *in, - const GLuint *flags, - GLuint start ) -{ - GLfloat (*to)[3] = out->data; - GLfloat (*from)[3] = in->data; - GLuint i; - - for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (!(flags[i] & VERT_EVAL_ANY)) - COPY_3V( to[i], from[i] ); - - out->start = VEC_ELT(out, GLfloat, start); - return out; -} - -static GLvector4ub *copy_4ub( GLvector4ub *out, - CONST GLvector4ub *in, - const GLuint *flags, - GLuint start ) -{ - GLubyte (*to)[4] = out->data; - GLubyte (*from)[4] = in->data; - GLuint i; - - for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (!(flags[i] & VERT_EVAL_ANY)) - COPY_4UBV( to[i], from[i] ); - - out->start = VEC_ELT(out, GLubyte, start); - return out; -} - -static GLvector1ui *copy_1ui( GLvector1ui *out, - CONST GLvector1ui *in, - const GLuint *flags, - GLuint start ) -{ - GLuint *to = out->data; - CONST GLuint *from = in->data; - GLuint i; - - for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) - if (!(flags[i] & VERT_EVAL_ANY)) - to[i] = from[i]; - - out->start = VEC_ELT(out, GLuint, start); - return out; -} - - -/* KW: Rewrote this to perform eval on a whole buffer at once. - * Only evaluates active data items, and avoids scribbling - * the source buffer if we are running from a display list. - * - * If the user (in this case looser) sends eval coordinates - * or runs a display list containing eval coords with no - * vertex maps enabled, we have to either copy all non-eval - * data to a new buffer, or find a way of working around - * the eval data. I choose the second option. - * - * KW: This code not reached by cva - use IM to access storage. - */ -void gl_eval_vb( struct vertex_buffer *VB ) -{ - struct immediate *IM = VB->IM; - GLcontext *ctx = VB->ctx; - GLuint req = ctx->CVA.elt.inputs; - GLfloat (*coord)[4] = VB->ObjPtr->data; - GLuint *flags = VB->Flag; - GLuint new_flags = 0; - - - GLuint any_eval1 = VB->OrFlag & (VERT_EVAL_C1|VERT_EVAL_P1); - GLuint any_eval2 = VB->OrFlag & (VERT_EVAL_C2|VERT_EVAL_P2); - GLuint all_eval = IM->AndFlag & VERT_EVAL_ANY; - - /* Handle the degenerate cases. - */ - if (any_eval1 && !ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) { - VB->PurgeFlags |= (VERT_EVAL_C1|VERT_EVAL_P1); - VB->EarlyCull = 0; - any_eval1 = GL_FALSE; - } - - if (any_eval2 && !ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) { - VB->PurgeFlags |= (VERT_EVAL_C2|VERT_EVAL_P2); - VB->EarlyCull = 0; - any_eval2 = GL_FALSE; - } - - /* KW: This really is a degenerate case - doing this disables - * culling, and causes dummy values for the missing vertices to be - * transformed and clip tested. It also forces the individual - * cliptesting of each primitive in vb_render. I wish there was a - * nice alternative, but I can't say I want to put effort into - * optimizing such a bad usage of the library - I'd much rather - * work on useful changes. - */ - if (VB->PurgeFlags) { - if (!any_eval1 && !any_eval2 && all_eval) VB->Count = VB->Start; - gl_purge_vertices( VB ); - if (!any_eval1 && !any_eval2) return; - } else - VB->IndirectCount = VB->Count; - - /* Translate points into coords. - */ - if (any_eval1 && (VB->OrFlag & VERT_EVAL_P1)) - { - eval_points1( IM->Obj, coord, flags, IM->Start, - ctx->Eval.MapGrid1du, - ctx->Eval.MapGrid1u1); - - coord = IM->Obj; - } - - if (any_eval2 && (VB->OrFlag & VERT_EVAL_P2)) - { - eval_points2( IM->Obj, coord, flags, IM->Start, - ctx->Eval.MapGrid2du, - ctx->Eval.MapGrid2u1, - ctx->Eval.MapGrid2dv, - ctx->Eval.MapGrid2v1 ); - - coord = IM->Obj; - } - - /* Perform the evaluations on active data elements. - */ - if (req & VERT_INDEX) - { - GLvector1ui *in_index = VB->IndexPtr; - GLvector1ui *out_index = &IM->v.Index; - - if (ctx->Eval.Map1Index && any_eval1) - VB->IndexPtr = eval1_1ui( out_index, coord, flags, IM->Start, - &ctx->EvalMap.Map1Index ); - - if (ctx->Eval.Map2Index && any_eval2) - VB->IndexPtr = eval2_1ui( out_index, coord, flags, IM->Start, - &ctx->EvalMap.Map2Index ); - - if (VB->IndexPtr != in_index) { - new_flags |= VERT_INDEX; - if (!all_eval) - VB->IndexPtr = copy_1ui( out_index, in_index, flags, IM->Start ); - } - } - - if (req & VERT_RGBA) - { - GLvector4ub *in_color = VB->ColorPtr; - GLvector4ub *out_color = &IM->v.Color; - - if (ctx->Eval.Map1Color4 && any_eval1) - VB->ColorPtr = eval1_color( out_color, coord, flags, IM->Start, - &ctx->EvalMap.Map1Color4 ); - - if (ctx->Eval.Map2Color4 && any_eval2) - VB->ColorPtr = eval2_color( out_color, coord, flags, IM->Start, - &ctx->EvalMap.Map2Color4 ); - - if (VB->ColorPtr != in_color) { - new_flags |= VERT_RGBA; - if (!all_eval) - VB->ColorPtr = copy_4ub( out_color, in_color, flags, IM->Start ); - } - - VB->Color[0] = VB->Color[1] = VB->ColorPtr; - } - - - if (req & VERT_NORM) - { - GLvector3f *in_normal = VB->NormalPtr; - GLvector3f *out_normal = &IM->v.Normal; - - if (ctx->Eval.Map1Normal && any_eval1) - VB->NormalPtr = eval1_norm( out_normal, coord, flags, IM->Start, - &ctx->EvalMap.Map1Normal ); - - if (ctx->Eval.Map2Normal && any_eval2) - VB->NormalPtr = eval2_norm( out_normal, coord, flags, IM->Start, - &ctx->EvalMap.Map2Normal ); - - new_flags |= VERT_NORM; - - if (VB->NormalPtr != in_normal) { - if (!all_eval) - VB->NormalPtr = copy_3f( out_normal, in_normal, flags, IM->Start ); - } - } - - - if (req & VERT_TEX_ANY(0)) - { - GLvector4f *tc = VB->TexCoordPtr[0]; - GLvector4f *in = tc; - GLvector4f *out = &IM->v.TexCoord[0]; - - if (any_eval1) { - if (ctx->Eval.Map1TextureCoord4) - tc = eval1_4f( out, coord, flags, IM->Start, - 4, &ctx->EvalMap.Map1Texture4); - else if (ctx->Eval.Map1TextureCoord3) - tc = eval1_4f( out, coord, flags, IM->Start, 3, - &ctx->EvalMap.Map1Texture3); - else if (ctx->Eval.Map1TextureCoord2) - tc = eval1_4f( out, coord, flags, IM->Start, 2, - &ctx->EvalMap.Map1Texture2); - else if (ctx->Eval.Map1TextureCoord1) - tc = eval1_4f( out, coord, flags, IM->Start, 1, - &ctx->EvalMap.Map1Texture1); - } - - if (any_eval2) { - if (ctx->Eval.Map2TextureCoord4) - tc = eval2_4f( out, coord, flags, IM->Start, - 4, &ctx->EvalMap.Map2Texture4); - else if (ctx->Eval.Map2TextureCoord3) - tc = eval2_4f( out, coord, flags, IM->Start, - 3, &ctx->EvalMap.Map2Texture3); - else if (ctx->Eval.Map2TextureCoord2) - tc = eval2_4f( out, coord, flags, IM->Start, - 2, &ctx->EvalMap.Map2Texture2); - else if (ctx->Eval.Map2TextureCoord1) - tc = eval2_4f( out, coord, flags, IM->Start, - 1, &ctx->EvalMap.Map2Texture1); - } - - if (tc != in) { - new_flags |= VERT_TEX_ANY(0); /* fix for sizes.. */ - if (!all_eval) - tc = copy_4f( out, in, flags, IM->Start ); - } - - VB->TexCoordPtr[0] = tc; - } - - - { - GLvector4f *in = VB->ObjPtr; - GLvector4f *out = &IM->v.Obj; - GLvector4f *obj = in; - - if (any_eval1) { - if (ctx->Eval.Map1Vertex4) - obj = eval1_4f( out, coord, flags, IM->Start, - 4, &ctx->EvalMap.Map1Vertex4); - else - obj = eval1_4f( out, coord, flags, IM->Start, - 3, &ctx->EvalMap.Map1Vertex3); - } - - if (any_eval2) { - GLvector3f *in_normal = VB->NormalPtr; - GLvector3f *out_normal = &IM->v.Normal; - - if (ctx->Eval.Map2Vertex4) - { - if (ctx->Eval.AutoNormal && (req & VERT_NORM)) { - obj = eval2_obj_norm( out, out_normal, coord, flags, - IM->Start, 4, &ctx->EvalMap.Map2Vertex4 ); - VB->NormalPtr = out_normal; - new_flags |= VERT_NORM; - } - else - obj = eval2_4f( out, coord, flags, IM->Start, - 4, &ctx->EvalMap.Map2Vertex4 ); - } - else if (ctx->Eval.Map2Vertex3) - { - if (ctx->Eval.AutoNormal && (req & VERT_NORM)) { - obj = eval2_obj_norm( out, out_normal, coord, flags, - IM->Start, 3, &ctx->EvalMap.Map2Vertex3 ); - VB->NormalPtr = out_normal; - new_flags |= VERT_NORM; - } - else - obj = eval2_4f( out, coord, flags, IM->Start, - 3, &ctx->EvalMap.Map2Vertex3 ); - } - - - if (VB->NormalPtr != in_normal) { - if (!all_eval) - VB->NormalPtr = copy_3f( out_normal, in_normal, flags, - IM->Start ); - } - } - - if (obj != in && !all_eval) - obj = copy_4f( out, in, flags, IM->Start ); - - VB->ObjPtr = obj; - } - - if (new_flags) { - GLuint *oldflags = VB->Flag; - GLuint *flags = VB->Flag = VB->EvaluatedFlags; - GLuint i; - GLuint count = VB->Count; - GLuint andflag = VB->IM->AndFlag; - - if (!flags) { - VB->EvaluatedFlags = (GLuint *) MALLOC(VB->Size * sizeof(GLuint)); - flags = VB->Flag = VB->EvaluatedFlags; - } - - if (all_eval) { - for (i = 0 ; i <= count ; i++) - flags[i] = oldflags[i] | new_flags; - andflag |= new_flags; - } else { - andflag = ~0; - for (i = 0 ; i <= count ; i++) { - flags[i] = oldflags[i]; - if (flags[i] & VERT_EVAL_ANY) - flags[i] |= new_flags; - andflag &= flags[i]; - } - } - - VB->OrFlag |= new_flags; - VB->CullMode = (GLubyte) ((andflag & VERT_NORM) ? 0 : COMPACTED_NORMALS); - } -} - - void _mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ) { @@ -2694,279 +1574,4 @@ _mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2, -/* KW: If are compiling, we don't know whether eval will produce a - * vertex when it is run in the future. If this is pure immediate - * mode, eval is a noop if neither vertex map is enabled. - * - * Thus we need to have a check in the display list code or - * elsewhere for eval(1,2) vertices in the case where - * map(1,2)_vertex is disabled, and to purge those vertices from - * the vb. This is currently done - * via modifications to the cull_vb and render_vb operations, and - * by using the existing cullmask mechanism for all other operations. - */ - - -/* KW: Because the eval values don't become 'current', fixup will flow - * through these vertices, and then evaluation will write on top - * of the fixup results. - * - * This is a little inefficient, but at least it is correct. This - * could be short-circuited in the case where all vertices are - * eval-vertices, or more generally by a cullmask in fixup. - * - * Note: using Obj to hold eval coord data. This data is actually - * transformed if eval is disabled. But disabling eval & sending - * eval coords is stupid, right? - */ - - -#define EVALCOORD1(IM, x) \ -{ \ - GLuint count = IM->Count++; \ - IM->Flag[count] |= VERT_EVAL_C1; \ - ASSIGN_4V(IM->Obj[count], x, 0, 0, 1); \ - if (count == VB_MAX-1) \ - _mesa_maybe_transform_vb( IM ); \ -} - -#define EVALCOORD2(IM, x, y) \ -{ \ - GLuint count = IM->Count++; \ - IM->Flag[count] |= VERT_EVAL_C2; \ - ASSIGN_4V(IM->Obj[count], x, y, 0, 1); \ - if (count == VB_MAX-1) \ - _mesa_maybe_transform_vb( IM ); \ -} - -#define EVALPOINT1(IM, x) \ -{ \ - GLuint count = IM->Count++; \ - IM->Flag[count] |= VERT_EVAL_P1; \ - ASSIGN_4V(IM->Obj[count], x, 0, 0, 1); \ - if (count == VB_MAX-1) \ - _mesa_maybe_transform_vb( IM ); \ -} - -#define EVALPOINT2(IM, x, y) \ -{ \ - GLuint count = IM->Count++; \ - IM->Flag[count] |= VERT_EVAL_P2; \ - ASSIGN_4V(IM->Obj[count], x, y, 0, 1); \ - if (count == VB_MAX-1) \ - _mesa_maybe_transform_vb( IM ); \ -} - - -/* Lame internal function: - */ -static void -eval_coord1f( GLcontext *CC, GLfloat u ) -{ - struct immediate *i = CC->input; - EVALCOORD1( i, u ); -} - - -void -_mesa_EvalCoord1d( GLdouble u ) -{ - GET_IMMEDIATE; - EVALCOORD1( IM, (GLfloat) u ); -} - - -void -_mesa_EvalCoord1f( GLfloat u ) -{ - GET_IMMEDIATE; - EVALCOORD1( IM, u ); -} - - -void -_mesa_EvalCoord1dv( const GLdouble *u ) -{ - GET_IMMEDIATE; - EVALCOORD1( IM, (GLfloat) *u ); -} - - -void -_mesa_EvalCoord1fv( const GLfloat *u ) -{ - GET_IMMEDIATE; - EVALCOORD1( IM, (GLfloat) *u ); -} - - -void -_mesa_EvalCoord2d( GLdouble u, GLdouble v ) -{ - GET_IMMEDIATE; - EVALCOORD2( IM, (GLfloat) u, (GLfloat) v ); -} - - -void -_mesa_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_IMMEDIATE; - EVALCOORD2( IM, u, v ); -} - - -/* Lame internal function: - */ -static void -eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v ) -{ - struct immediate *i = CC->input; - EVALCOORD2( i, u, v ); -} - - -void -_mesa_EvalCoord2dv( const GLdouble *u ) -{ - GET_IMMEDIATE; - EVALCOORD2( IM, (GLfloat) u[0], (GLfloat) u[1] ); -} - - -void -_mesa_EvalCoord2fv( const GLfloat *u ) -{ - GET_IMMEDIATE; - EVALCOORD2( IM, u[0], u[1] ); -} - - -void -_mesa_EvalPoint1( GLint i ) -{ - GET_IMMEDIATE; - EVALPOINT1( IM, i ); -} - - -void -_mesa_EvalPoint2( GLint i, GLint j ) -{ - GET_IMMEDIATE; - EVALPOINT2( IM, i, j ); -} - - - - -void -_mesa_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - GLfloat u, du; - GLenum prim; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glEvalMesh1"); - - switch (mode) { - case GL_POINT: - prim = GL_POINTS; - break; - case GL_LINE: - prim = GL_LINE_STRIP; - break; - default: - gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" ); - return; - } - - /* No effect if vertex maps disabled. - */ - if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) - return; - - du = ctx->Eval.MapGrid1du; - u = ctx->Eval.MapGrid1u1 + i1 * du; - - /* KW: Could short-circuit this to avoid the immediate mechanism. - */ - RESET_IMMEDIATE(ctx); - - gl_Begin( ctx, prim ); - for (i=i1;i<=i2;i++,u+=du) { - eval_coord1f( ctx, u ); - } - gl_End(ctx); -} - - - -void -_mesa_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i, j; - GLfloat u, du, v, dv, v1, u1; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glEvalMesh2"); - - /* No effect if vertex maps disabled. - */ - if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) - return; - - du = ctx->Eval.MapGrid2du; - dv = ctx->Eval.MapGrid2dv; - v1 = ctx->Eval.MapGrid2v1 + j1 * dv; - u1 = ctx->Eval.MapGrid2u1 + i1 * du; - - RESET_IMMEDIATE(ctx); - - switch (mode) { - case GL_POINT: - gl_Begin( ctx, GL_POINTS ); - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - for (u=u1,i=i1;i<=i2;i++,u+=du) { - eval_coord2f( ctx, u, v ); - } - } - gl_End(ctx); - break; - case GL_LINE: - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - gl_Begin( ctx, GL_LINE_STRIP ); - for (u=u1,i=i1;i<=i2;i++,u+=du) { - eval_coord2f( ctx, u, v ); - } - gl_End(ctx); - } - for (u=u1,i=i1;i<=i2;i++,u+=du) { - gl_Begin( ctx, GL_LINE_STRIP ); - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - eval_coord2f( ctx, u, v ); - } - gl_End(ctx); - } - break; - case GL_FILL: - for (v=v1,j=j1;j<j2;j++,v+=dv) { - /* NOTE: a quad strip can't be used because the four */ - /* can't be guaranteed to be coplanar! */ - gl_Begin( ctx, GL_TRIANGLE_STRIP ); - for (u=u1,i=i1;i<=i2;i++,u+=du) { - eval_coord2f( ctx, u, v ); - eval_coord2f( ctx, u, v+dv ); - } - gl_End(ctx); - } - break; - default: - gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" ); - return; - } -} - - diff --git a/src/mesa/main/eval.h b/src/mesa/main/eval.h index 0b87be3d5fe..e2c61657af8 100644 --- a/src/mesa/main/eval.h +++ b/src/mesa/main/eval.h @@ -1,4 +1,4 @@ -/* $Id: eval.h,v 1.2 1999/11/11 01:22:26 brianp Exp $ */ +/* $Id: eval.h,v 1.3 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -61,8 +61,6 @@ extern GLfloat *gl_copy_map_points2d(GLenum target, const GLdouble *points ); -extern void gl_eval_vb( struct vertex_buffer *VB ); - extern void _mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, @@ -107,40 +105,5 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ); extern void _mesa_GetMapiv( GLenum target, GLenum query, GLint *v ); -extern void -_mesa_EvalMesh1( GLenum mode, GLint i1, GLint i2 ); - -extern void -_mesa_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); - -extern void -_mesa_EvalCoord1d( GLdouble u ); - -extern void -_mesa_EvalCoord1f( GLfloat u ); - -extern void -_mesa_EvalCoord1dv( const GLdouble *u ); - -extern void -_mesa_EvalCoord1fv( const GLfloat *u ); - -extern void -_mesa_EvalCoord2d( GLdouble u, GLdouble v ); - -extern void -_mesa_EvalCoord2f( GLfloat u, GLfloat v ); - -extern void -_mesa_EvalCoord2dv( const GLdouble *u ); - -extern void -_mesa_EvalCoord2fv( const GLfloat *u ); - -extern void -_mesa_EvalPoint1( GLint i ); - -extern void -_mesa_EvalPoint2( GLint i, GLint j ); #endif diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c index 97bf52fc998..9593fa2a976 100644 --- a/src/mesa/main/fog.c +++ b/src/mesa/main/fog.c @@ -1,4 +1,4 @@ -/* $Id: fog.c,v 1.28 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: fog.c,v 1.29 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -32,10 +32,7 @@ #include "colormac.h" #include "context.h" #include "fog.h" -#include "macros.h" -#include "mmath.h" #include "types.h" -#include "xform.h" #endif @@ -146,102 +143,3 @@ _mesa_Fogfv( GLenum pname, const GLfloat *params ) } - - - -static GLvector1f *get_fogcoord_ptr( GLcontext *ctx, GLvector1f *tmp ) -{ - struct vertex_buffer *VB = ctx->VB; - - if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) { - if (!ctx->_NeedEyeCoords) { - GLfloat *m = ctx->ModelView.m; - GLfloat plane[4]; - - plane[0] = m[2]; - plane[1] = m[6]; - plane[2] = m[10]; - plane[3] = m[14]; - - /* Full eye coords weren't required, just calculate the - * eye Z values. - */ - gl_dotprod_tab[0][VB->ObjPtr->size](&VB->Eye, 2, - VB->ObjPtr, plane, 0 ); - - tmp->data = &(VB->Eye.data[0][2]); - tmp->start = VB->Eye.start+2; - tmp->stride = VB->Eye.stride; - return tmp; - } - else - { - if (VB->EyePtr->size < 2) - gl_vector4f_clean_elem( &VB->Eye, VB->Count, 2 ); - - tmp->data = &(VB->EyePtr->data[0][2]); - tmp->start = VB->EyePtr->start+2; - tmp->stride = VB->EyePtr->stride; - return tmp; - } - } else - return VB->FogCoordPtr; -} - - -/* Use lookup table & interpolation? - */ -static void -make_win_fog_coords( struct vertex_buffer *VB, - GLvector1f *fogcoord) -{ - const GLcontext *ctx = VB->ctx; - GLfloat end = ctx->Fog.End; - GLfloat *v = fogcoord->start; - GLuint stride = fogcoord->stride; - GLuint n = VB->Count - VB->Start; - GLfloat *out; - GLfloat d; - GLuint i; - - VB->FogCoordPtr = VB->store.FogCoord; - out = VB->FogCoordPtr->data + VB->Start; - - switch (ctx->Fog.Mode) { - case GL_LINEAR: - d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); - for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - out[i] = (end - ABSF(*v)) * d; - if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]); - } - break; - case GL_EXP: - d = -ctx->Fog.Density; - for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) { - out[i] = exp( d*ABSF(*v) ); - if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]); - } - break; - case GL_EXP2: - d = -(ctx->Fog.Density*ctx->Fog.Density); - for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - GLfloat z = *v; - out[i] = exp( d*z*z ); - if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]); - } - break; - default: - gl_problem(ctx, "Bad fog mode in make_fog_coord"); - return; - } -} - - -void -_mesa_make_win_fog_coords( struct vertex_buffer *VB ) -{ - GLvector1f tmp; - - make_win_fog_coords( VB, get_fogcoord_ptr( VB->ctx, &tmp ) ); -} - diff --git a/src/mesa/main/fog.h b/src/mesa/main/fog.h index 15ccbc9966c..371fb80d8bf 100644 --- a/src/mesa/main/fog.h +++ b/src/mesa/main/fog.h @@ -1,4 +1,4 @@ -/* $Id: fog.h,v 1.9 2000/10/31 18:09:44 keithw Exp $ */ +/* $Id: fog.h,v 1.10 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -49,8 +49,4 @@ extern void _mesa_Fogiv(GLenum pname, const GLint *params ); -extern void -_mesa_make_win_fog_coords( struct vertex_buffer *VB ); - - #endif diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 434e2e54005..980269d8544 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1,4 +1,4 @@ -/* $Id: get.c,v 1.40 2000/11/15 16:38:40 brianp Exp $ */ +/* $Id: get.c,v 1.41 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -36,10 +36,10 @@ #include "extensions.h" #include "get.h" #include "macros.h" -#include "matrix.h" #include "mmath.h" #include "types.h" -#include "vb.h" + +#include "math/m_matrix.h" #endif @@ -228,15 +228,18 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) *params = ENUM_TO_BOOL(ctx->Polygon.CullFaceMode); break; case GL_CURRENT_COLOR: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = INT_TO_BOOL(ctx->Current.Color[0]); params[1] = INT_TO_BOOL(ctx->Current.Color[1]); params[2] = INT_TO_BOOL(ctx->Current.Color[2]); params[3] = INT_TO_BOOL(ctx->Current.Color[3]); break; case GL_CURRENT_INDEX: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = INT_TO_BOOL(ctx->Current.Index); break; case GL_CURRENT_NORMAL: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = FLOAT_TO_BOOL(ctx->Current.Normal[0]); params[1] = FLOAT_TO_BOOL(ctx->Current.Normal[1]); params[2] = FLOAT_TO_BOOL(ctx->Current.Normal[2]); @@ -269,6 +272,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) *params = ctx->Current.RasterPosValid; break; case GL_CURRENT_TEXTURE_COORDS: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][0]); params[1] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][1]); params[2] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][2]); @@ -309,6 +313,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) *params = ENUM_TO_BOOL(ctx->Color.DrawBuffer); break; case GL_EDGE_FLAG: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = ctx->Current.EdgeFlag; break; case GL_FEEDBACK_BUFFER_SIZE: @@ -1077,7 +1082,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ColorMatrix.m); + _math_transposef(tm, ctx->ColorMatrix.m); for (i=0;i<16;i++) { params[i] = FLOAT_TO_BOOL(tm[i]); } @@ -1087,7 +1092,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ModelView.m); + _math_transposef(tm, ctx->ModelView.m); for (i=0;i<16;i++) { params[i] = FLOAT_TO_BOOL(tm[i]); } @@ -1097,7 +1102,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ProjectionMatrix.m); + _math_transposef(tm, ctx->ProjectionMatrix.m); for (i=0;i<16;i++) { params[i] = FLOAT_TO_BOOL(tm[i]); } @@ -1107,7 +1112,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->TextureMatrix[texTransformUnit].m); + _math_transposef(tm, ctx->TextureMatrix[texTransformUnit].m); for (i=0;i<16;i++) { params[i] = FLOAT_TO_BOOL(tm[i]); } @@ -1236,6 +1241,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) *params = ctx->Fog.ColorSumEnabled; break; case GL_CURRENT_SECONDARY_COLOR_EXT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = INT_TO_BOOL(ctx->Current.SecondaryColor[0]); params[1] = INT_TO_BOOL(ctx->Current.SecondaryColor[1]); params[2] = INT_TO_BOOL(ctx->Current.SecondaryColor[2]); @@ -1255,6 +1261,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) /* GL_EXT_fog_coord */ case GL_CURRENT_FOG_COORDINATE_EXT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = FLOAT_TO_BOOL(ctx->Current.FogCoord); break; case GL_FOG_COORDINATE_ARRAY_EXT: @@ -1419,15 +1426,18 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) *params = ENUM_TO_DOUBLE(ctx->Polygon.CullFaceMode); break; case GL_CURRENT_COLOR: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = CHAN_TO_FLOAT(ctx->Current.Color[0]); params[1] = CHAN_TO_FLOAT(ctx->Current.Color[1]); params[2] = CHAN_TO_FLOAT(ctx->Current.Color[2]); params[3] = CHAN_TO_FLOAT(ctx->Current.Color[3]); break; case GL_CURRENT_INDEX: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLdouble) ctx->Current.Index; break; case GL_CURRENT_NORMAL: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = (GLdouble) ctx->Current.Normal[0]; params[1] = (GLdouble) ctx->Current.Normal[1]; params[2] = (GLdouble) ctx->Current.Normal[2]; @@ -1460,6 +1470,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) *params = (GLdouble) ctx->Current.RasterPosValid; break; case GL_CURRENT_TEXTURE_COORDS: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][0]; params[1] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][1]; params[2] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][2]; @@ -1500,6 +1511,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) *params = ENUM_TO_DOUBLE(ctx->Color.DrawBuffer); break; case GL_EDGE_FLAG: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLdouble) ctx->Current.EdgeFlag; break; case GL_FEEDBACK_BUFFER_SIZE: @@ -2268,7 +2280,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ColorMatrix.m); + _math_transposef(tm, ctx->ColorMatrix.m); for (i=0;i<16;i++) { params[i] = (GLdouble) tm[i]; } @@ -2278,7 +2290,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ModelView.m); + _math_transposef(tm, ctx->ModelView.m); for (i=0;i<16;i++) { params[i] = (GLdouble) tm[i]; } @@ -2288,7 +2300,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ProjectionMatrix.m); + _math_transposef(tm, ctx->ProjectionMatrix.m); for (i=0;i<16;i++) { params[i] = (GLdouble) tm[i]; } @@ -2298,7 +2310,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->TextureMatrix[texTransformUnit].m); + _math_transposef(tm, ctx->TextureMatrix[texTransformUnit].m); for (i=0;i<16;i++) { params[i] = (GLdouble) tm[i]; } @@ -2427,6 +2439,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) *params = (GLdouble) ctx->Fog.ColorSumEnabled; break; case GL_CURRENT_SECONDARY_COLOR_EXT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[0]); params[1] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[1]); params[2] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[2]); @@ -2446,6 +2459,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) /* GL_EXT_fog_coord */ case GL_CURRENT_FOG_COORDINATE_EXT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLdouble) ctx->Current.FogCoord; break; case GL_FOG_COORDINATE_ARRAY_EXT: @@ -2611,15 +2625,18 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) *params = ENUM_TO_FLOAT(ctx->Polygon.CullFaceMode); break; case GL_CURRENT_COLOR: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = CHAN_TO_FLOAT(ctx->Current.Color[0]); params[1] = CHAN_TO_FLOAT(ctx->Current.Color[1]); params[2] = CHAN_TO_FLOAT(ctx->Current.Color[2]); params[3] = CHAN_TO_FLOAT(ctx->Current.Color[3]); break; case GL_CURRENT_INDEX: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLfloat) ctx->Current.Index; break; case GL_CURRENT_NORMAL: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = ctx->Current.Normal[0]; params[1] = ctx->Current.Normal[1]; params[2] = ctx->Current.Normal[2]; @@ -2652,6 +2669,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) *params = (GLfloat) ctx->Current.RasterPosValid; break; case GL_CURRENT_TEXTURE_COORDS: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][0]; params[1] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][1]; params[2] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][2]; @@ -2692,6 +2710,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) *params = ENUM_TO_FLOAT(ctx->Color.DrawBuffer); break; case GL_EDGE_FLAG: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLfloat) ctx->Current.EdgeFlag; break; case GL_FEEDBACK_BUFFER_SIZE: @@ -3459,16 +3478,16 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) /* GL_ARB_transpose_matrix */ case GL_TRANSPOSE_COLOR_MATRIX_ARB: - gl_matrix_transposef(params, ctx->ColorMatrix.m); + _math_transposef(params, ctx->ColorMatrix.m); break; case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB: - gl_matrix_transposef(params, ctx->ModelView.m); + _math_transposef(params, ctx->ModelView.m); break; case GL_TRANSPOSE_PROJECTION_MATRIX_ARB: - gl_matrix_transposef(params, ctx->ProjectionMatrix.m); + _math_transposef(params, ctx->ProjectionMatrix.m); break; case GL_TRANSPOSE_TEXTURE_MATRIX_ARB: - gl_matrix_transposef(params, ctx->TextureMatrix[texTransformUnit].m); + _math_transposef(params, ctx->TextureMatrix[texTransformUnit].m); break; /* GL_HP_occlusion_test */ @@ -3593,6 +3612,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) *params = (GLfloat) ctx->Fog.ColorSumEnabled; break; case GL_CURRENT_SECONDARY_COLOR_EXT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[0]); params[1] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[1]); params[2] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.SecondaryColor[2]); @@ -3612,6 +3632,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) /* GL_EXT_fog_coord */ case GL_CURRENT_FOG_COORDINATE_EXT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLfloat) ctx->Current.FogCoord; break; case GL_FOG_COORDINATE_ARRAY_EXT: @@ -3779,15 +3800,18 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) *params = (GLint) ctx->Polygon.CullFaceMode; break; case GL_CURRENT_COLOR: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = FLOAT_TO_INT( CHAN_TO_FLOAT( ctx->Current.Color[0] ) ); params[1] = FLOAT_TO_INT( CHAN_TO_FLOAT( ctx->Current.Color[1] ) ); params[2] = FLOAT_TO_INT( CHAN_TO_FLOAT( ctx->Current.Color[2] ) ); params[3] = FLOAT_TO_INT( CHAN_TO_FLOAT( ctx->Current.Color[3] ) ); break; case GL_CURRENT_INDEX: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLint) ctx->Current.Index; break; case GL_CURRENT_NORMAL: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = FLOAT_TO_INT( ctx->Current.Normal[0] ); params[1] = FLOAT_TO_INT( ctx->Current.Normal[1] ); params[2] = FLOAT_TO_INT( ctx->Current.Normal[2] ); @@ -3820,6 +3844,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) *params = (GLint) ctx->Current.RasterPosValid; break; case GL_CURRENT_TEXTURE_COORDS: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = (GLint) ctx->Current.Texcoord[texTransformUnit][0]; params[1] = (GLint) ctx->Current.Texcoord[texTransformUnit][1]; params[2] = (GLint) ctx->Current.Texcoord[texTransformUnit][2]; @@ -3860,6 +3885,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) *params = (GLint) ctx->Color.DrawBuffer; break; case GL_EDGE_FLAG: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLint) ctx->Current.EdgeFlag; break; case GL_FEEDBACK_BUFFER_SIZE: @@ -4628,7 +4654,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ColorMatrix.m); + _math_transposef(tm, ctx->ColorMatrix.m); for (i=0;i<16;i++) { params[i] = (GLint) tm[i]; } @@ -4638,7 +4664,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ModelView.m); + _math_transposef(tm, ctx->ModelView.m); for (i=0;i<16;i++) { params[i] = (GLint) tm[i]; } @@ -4648,7 +4674,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->ProjectionMatrix.m); + _math_transposef(tm, ctx->ProjectionMatrix.m); for (i=0;i<16;i++) { params[i] = (GLint) tm[i]; } @@ -4658,7 +4684,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) { GLfloat tm[16]; GLuint i; - gl_matrix_transposef(tm, ctx->TextureMatrix[texTransformUnit].m); + _math_transposef(tm, ctx->TextureMatrix[texTransformUnit].m); for (i=0;i<16;i++) { params[i] = (GLint) tm[i]; } @@ -4788,6 +4814,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) *params = (GLint) ctx->Fog.ColorSumEnabled; break; case GL_CURRENT_SECONDARY_COLOR_EXT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); params[0] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.SecondaryColor[0] ) ); params[1] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.SecondaryColor[1] ) ); params[2] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.SecondaryColor[2] ) ); @@ -4807,6 +4834,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) /* GL_EXT_fog_coord */ case GL_CURRENT_FOG_COORDINATE_EXT: + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); *params = (GLint) ctx->Current.FogCoord; break; case GL_FOG_COORDINATE_ARRAY_EXT: diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index 1c4f6982d93..ef31c561ba6 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -1,4 +1,4 @@ -/* $Id: light.c,v 1.25 2000/11/15 16:38:59 brianp Exp $ */ +/* $Id: light.c,v 1.26 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -34,14 +34,13 @@ #include "enums.h" #include "light.h" #include "macros.h" -#include "matrix.h" #include "mem.h" #include "mmath.h" -#include "shade.h" #include "simple_list.h" #include "types.h" -#include "vb.h" -#include "xform.h" + +#include "math/m_xform.h" +#include "math/m_matrix.h" #endif @@ -123,7 +122,7 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) case GL_SPOT_DIRECTION: /* transform direction by inverse modelview */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { - gl_matrix_analyze( &ctx->ModelView ); + _math_matrix_analyze( &ctx->ModelView ); } TRANSFORM_NORMAL( l->EyeDirection, params, ctx->ModelView.inv ); break; @@ -533,7 +532,7 @@ void gl_update_material( GLcontext *ctx, if (ctx->Light.ColorMaterialEnabled) bitmask &= ~ctx->Light.ColorMaterialBitmask; - if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) fprintf(stderr, "gl_update_material, mask 0x%x\n", bitmask); if (!bitmask) @@ -829,8 +828,10 @@ _mesa_ColorMaterial( GLenum face, GLenum mode ) ctx->Light.ColorMaterialMode = mode; } - if (ctx->Light.ColorMaterialEnabled) + if (ctx->Light.ColorMaterialEnabled) { + FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT ); gl_update_color_material( ctx, ctx->Current.Color ); + } ctx->NewState |= _NEW_LIGHT; } @@ -845,86 +846,6 @@ _mesa_Materialf( GLenum face, GLenum pname, GLfloat param ) } -/* KW: This is now called directly (ie by name) from the glMaterial* - * API functions. - */ -void -_mesa_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - struct immediate *IM; - struct gl_material *mat; - GLuint bitmask; - GLuint count; - - bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" ); - if (bitmask == 0) - return; - - IM = ctx->input; - count = IM->Count; - - if (!IM->Material) { - IM->Material = - (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) * - VB_SIZE * 2 ); - IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE ); - } - - - if (!(IM->Flag[count] & VERT_MATERIAL)) { - IM->Flag[count] |= VERT_MATERIAL; - IM->MaterialMask[count] = 0; - } - - - IM->MaterialMask[count] |= bitmask; - mat = IM->Material[count]; - - if (bitmask & FRONT_AMBIENT_BIT) { - COPY_4FV( mat[0].Ambient, params ); - } - if (bitmask & BACK_AMBIENT_BIT) { - COPY_4FV( mat[1].Ambient, params ); - } - if (bitmask & FRONT_DIFFUSE_BIT) { - COPY_4FV( mat[0].Diffuse, params ); - } - if (bitmask & BACK_DIFFUSE_BIT) { - COPY_4FV( mat[1].Diffuse, params ); - } - if (bitmask & FRONT_SPECULAR_BIT) { - COPY_4FV( mat[0].Specular, params ); - } - if (bitmask & BACK_SPECULAR_BIT) { - COPY_4FV( mat[1].Specular, params ); - } - if (bitmask & FRONT_EMISSION_BIT) { - COPY_4FV( mat[0].Emission, params ); - } - if (bitmask & BACK_EMISSION_BIT) { - COPY_4FV( mat[1].Emission, params ); - } - if (bitmask & FRONT_SHININESS_BIT) { - GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); - mat[0].Shininess = shininess; - } - if (bitmask & BACK_SHININESS_BIT) { - GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); - mat[1].Shininess = shininess; - } - if (bitmask & FRONT_INDEXES_BIT) { - mat[0].AmbientIndex = params[0]; - mat[0].DiffuseIndex = params[1]; - mat[0].SpecularIndex = params[2]; - } - if (bitmask & BACK_INDEXES_BIT) { - mat[1].AmbientIndex = params[0]; - mat[1].DiffuseIndex = params[1]; - mat[1].SpecularIndex = params[2]; - } -} - void _mesa_Materiali(GLenum face, GLenum pname, GLint param ) @@ -1281,8 +1202,6 @@ gl_update_lighting( GLcontext *ctx ) light->_sli = DOT3(ci, light->Specular); } } - - gl_update_lighting_function(ctx); } @@ -1364,54 +1283,3 @@ gl_compute_light_positions( GLcontext *ctx ) } -/* _NEW_TRANSFORM - * _NEW_MODELVIEW - * _TNL_NEW_NEED_NORMALS - * _TNL_NEW_NEED_EYE_COORDS - * - * Update on (_NEW_TRANSFORM|_NEW_MODELVIEW) - * And also on NewLightingSpaces() callback. - */ -void -gl_update_normal_transform( GLcontext *ctx ) -{ - - if (!ctx->_NeedNormals) { - ctx->_NormalTransform = 0; - return; - } - - if (ctx->_NeedEyeCoords) { - GLuint transform = NORM_TRANSFORM_NO_ROT; - - if (ctx->ModelView.flags & (MAT_FLAG_GENERAL | - MAT_FLAG_ROTATION | - MAT_FLAG_GENERAL_3D | - MAT_FLAG_PERSPECTIVE)) - transform = NORM_TRANSFORM; - - - if (ctx->Transform.Normalize) { - ctx->_NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE]; - } - else if (ctx->Transform.RescaleNormals && - ctx->_ModelViewInvScale != 1.0) { - ctx->_NormalTransform = gl_normal_tab[transform | NORM_RESCALE]; - } - else { - ctx->_NormalTransform = gl_normal_tab[transform]; - } - } - else { - if (ctx->Transform.Normalize) { - ctx->_NormalTransform = gl_normal_tab[NORM_NORMALIZE]; - } - else if (!ctx->Transform.RescaleNormals && - ctx->_ModelViewInvScale != 1.0) { - ctx->_NormalTransform = gl_normal_tab[NORM_RESCALE]; - } - else { - ctx->_NormalTransform = 0; - } - } -} diff --git a/src/mesa/main/light.h b/src/mesa/main/light.h index 78178f982b8..4c2589fbf47 100644 --- a/src/mesa/main/light.h +++ b/src/mesa/main/light.h @@ -1,4 +1,4 @@ -/* $Id: light.h,v 1.4 2000/10/28 18:34:48 brianp Exp $ */ +/* $Id: light.h,v 1.5 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -31,13 +31,6 @@ #include "types.h" -struct gl_shine_tab { - struct gl_shine_tab *next, *prev; - GLfloat tab[SHINE_TABLE_SIZE+1]; - GLfloat shininess; - GLuint refcount; -}; - extern void _mesa_ShadeModel( GLenum mode ); @@ -94,6 +87,23 @@ extern void _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ); +/* Lerp between adjacent values in the f(x) lookup table, giving a + * continuous function, with adequeate overall accuracy. (Though + * still pretty good compared to a straight lookup). + */ +#define GET_SHINE_TAB_ENTRY( table, dp, result ) \ +do { \ + struct gl_shine_tab *_tab = table; \ + if (dp>1.0) \ + result = pow( dp, _tab->shininess ); \ + else { \ + float f = (dp * (SHINE_TABLE_SIZE-1)); \ + int k = (int) f; \ + result = _tab->tab[k] + (f-k)*(_tab->tab[k+1]-_tab->tab[k]); \ + } \ +} while (0) + + extern GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname, @@ -112,8 +122,6 @@ extern void gl_update_lighting( GLcontext *ctx ); extern void gl_compute_light_positions( GLcontext *ctx ); -extern void gl_update_normal_transform( GLcontext *ctx ); - extern void gl_update_material( GLcontext *ctx, const struct gl_material src[2], GLuint bitmask ); diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c index 2a86e09a54f..3d9aad52b71 100644 --- a/src/mesa/main/lines.c +++ b/src/mesa/main/lines.c @@ -1,4 +1,4 @@ -/* $Id: lines.c,v 1.21 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: lines.c,v 1.22 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -37,7 +37,6 @@ #include "mmath.h" #include "texstate.h" #include "types.h" -#include "vb.h" #endif diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h index d84d2edd7c8..d5d9e42e7f7 100644 --- a/src/mesa/main/macros.h +++ b/src/mesa/main/macros.h @@ -1,4 +1,4 @@ -/* $Id: macros.h,v 1.13 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: macros.h,v 1.14 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -35,6 +35,8 @@ #include "glheader.h" +/* Do not reference types.h from this file. + */ /* Limits: */ diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index 7cf464e07bf..227f54b73d5 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -1,4 +1,4 @@ -/* $Id: matrix.c,v 1.25 2000/11/13 20:02:56 keithw Exp $ */ +/* $Id: matrix.c,v 1.26 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -47,936 +47,9 @@ #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 [email protected] - * 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 ([email protected]) */ - GLfloat mag, s, c; - GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c; - - s = sin( angle * DEG2RAD ); - c = cos( angle * DEG2RAD ); - - mag = GL_SQRT( x*x + y*y + z*z ); - - if (mag <= 1.0e-4) { - /* generate an identity matrix and return */ - MEMCPY(m, Identity, sizeof(GLfloat)*16); - return; - } - - x /= mag; - y /= mag; - z /= mag; - -#define M(row,col) m[col*4+row] - - /* - * Arbitrary axis rotation matrix. - * - * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied - * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation - * (which is about the X-axis), and the two composite transforms - * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary - * from the arbitrary axis to the X-axis then back. They are - * all elementary rotations. - * - * Rz' is a rotation about the Z-axis, to bring the axis vector - * into the x-z plane. Then Ry' is applied, rotating about the - * Y-axis to bring the axis vector parallel with the X-axis. The - * rotation about the X-axis is then performed. Ry and Rz are - * simply the respective inverse transforms to bring the arbitrary - * axis back to it's original orientation. The first transforms - * Rz' and Ry' are considered inverses, since the data from the - * arbitrary axis gives you info on how to get to it, not how - * to get away from it, and an inverse must be applied. - * - * The basic calculation used is to recognize that the arbitrary - * axis vector (x, y, z), since it is of unit length, actually - * represents the sines and cosines of the angles to rotate the - * X-axis to the same orientation, with theta being the angle about - * Z and phi the angle about Y (in the order described above) - * as follows: - * - * cos ( theta ) = x / sqrt ( 1 - z^2 ) - * sin ( theta ) = y / sqrt ( 1 - z^2 ) - * - * cos ( phi ) = sqrt ( 1 - z^2 ) - * sin ( phi ) = z - * - * Note that cos ( phi ) can further be inserted to the above - * formulas: - * - * cos ( theta ) = x / cos ( phi ) - * sin ( theta ) = y / sin ( phi ) - * - * ...etc. Because of those relations and the standard trigonometric - * relations, it is pssible to reduce the transforms down to what - * is used below. It may be that any primary axis chosen will give the - * same results (modulo a sign convention) using thie method. - * - * Particularly nice is to notice that all divisions that might - * have caused trouble when parallel to certain planes or - * axis go away with care paid to reducing the expressions. - * After checking, it does perform correctly under all cases, since - * in all the cases of division where the denominator would have - * been zero, the numerator would have been zero as well, giving - * the expected result. - */ - - xx = x * x; - yy = y * y; - zz = z * z; - xy = x * y; - yz = y * z; - zx = z * x; - xs = x * s; - ys = y * s; - zs = z * s; - one_c = 1.0F - c; - - M(0,0) = (one_c * xx) + c; - M(0,1) = (one_c * xy) - zs; - M(0,2) = (one_c * zx) + ys; - M(0,3) = 0.0F; - - M(1,0) = (one_c * xy) + zs; - M(1,1) = (one_c * yy) + c; - M(1,2) = (one_c * yz) - xs; - M(1,3) = 0.0F; - - M(2,0) = (one_c * zx) - ys; - M(2,1) = (one_c * yz) + xs; - M(2,2) = (one_c * zz) + c; - M(2,3) = 0.0F; - - M(3,0) = 0.0F; - M(3,1) = 0.0F; - M(3,2) = 0.0F; - M(3,3) = 1.0F; - -#undef M -} - -#define ZERO(x) (1<<x) -#define ONE(x) (1<<(x+16)) - -#define MASK_NO_TRX (ZERO(12) | ZERO(13) | ZERO(14)) -#define MASK_NO_2D_SCALE ( ONE(0) | ONE(5)) - -#define MASK_IDENTITY ( ONE(0) | ZERO(4) | ZERO(8) | ZERO(12) |\ - ZERO(1) | ONE(5) | ZERO(9) | ZERO(13) |\ - ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - -#define MASK_2D_NO_ROT ( ZERO(4) | ZERO(8) | \ - ZERO(1) | ZERO(9) | \ - ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - -#define MASK_2D ( ZERO(8) | \ - ZERO(9) | \ - ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - - -#define MASK_3D_NO_ROT ( ZERO(4) | ZERO(8) | \ - ZERO(1) | ZERO(9) | \ - ZERO(2) | ZERO(6) | \ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - -#define MASK_3D ( \ - \ - \ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - - -#define MASK_PERSPECTIVE ( ZERO(4) | ZERO(12) |\ - ZERO(1) | ZERO(13) |\ - ZERO(2) | ZERO(6) | \ - ZERO(3) | ZERO(7) | ZERO(15) ) - -#define SQ(x) ((x)*(x)) - -/* Determine type and flags from scratch. This is expensive enough to - * only want to do it once. - */ -static void analyze_from_scratch( GLmatrix *mat ) -{ - const GLfloat *m = mat->m; - GLuint mask = 0; - GLuint i; - - for (i = 0 ; i < 16 ; i++) { - if (m[i] == 0.0) mask |= (1<<i); - } - - if (m[0] == 1.0F) mask |= (1<<16); - if (m[5] == 1.0F) mask |= (1<<21); - if (m[10] == 1.0F) mask |= (1<<26); - if (m[15] == 1.0F) mask |= (1<<31); - - mat->flags &= ~MAT_FLAGS_GEOMETRY; - - /* Check for translation - no-one really cares - */ - if ((mask & MASK_NO_TRX) != MASK_NO_TRX) - mat->flags |= MAT_FLAG_TRANSLATION; - - /* Do the real work - */ - if (mask == MASK_IDENTITY) { - mat->type = MATRIX_IDENTITY; - } - else if ((mask & MASK_2D_NO_ROT) == MASK_2D_NO_ROT) { - mat->type = MATRIX_2D_NO_ROT; - - if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE) - mat->flags = MAT_FLAG_GENERAL_SCALE; - } - else if ((mask & MASK_2D) == MASK_2D) { - GLfloat mm = DOT2(m, m); - GLfloat m4m4 = DOT2(m+4,m+4); - GLfloat mm4 = DOT2(m,m+4); - - mat->type = MATRIX_2D; - - /* Check for scale */ - if (SQ(mm-1) > SQ(1e-6) || - SQ(m4m4-1) > SQ(1e-6)) - mat->flags |= MAT_FLAG_GENERAL_SCALE; - - /* Check for rotation */ - if (SQ(mm4) > SQ(1e-6)) - mat->flags |= MAT_FLAG_GENERAL_3D; - else - mat->flags |= MAT_FLAG_ROTATION; - - } - else if ((mask & MASK_3D_NO_ROT) == MASK_3D_NO_ROT) { - mat->type = MATRIX_3D_NO_ROT; - - /* Check for scale */ - if (SQ(m[0]-m[5]) < SQ(1e-6) && - SQ(m[0]-m[10]) < SQ(1e-6)) { - if (SQ(m[0]-1.0) > SQ(1e-6)) { - mat->flags |= MAT_FLAG_UNIFORM_SCALE; - } - } - else { - mat->flags |= MAT_FLAG_GENERAL_SCALE; - } - } - else if ((mask & MASK_3D) == MASK_3D) { - GLfloat c1 = DOT3(m,m); - GLfloat c2 = DOT3(m+4,m+4); - GLfloat c3 = DOT3(m+8,m+8); - GLfloat d1 = DOT3(m, m+4); - GLfloat cp[3]; - - mat->type = MATRIX_3D; - - /* Check for scale */ - if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) { - if (SQ(c1-1.0) > SQ(1e-6)) - mat->flags |= MAT_FLAG_UNIFORM_SCALE; - /* else no scale at all */ - } - else { - mat->flags |= MAT_FLAG_GENERAL_SCALE; - } - - /* Check for rotation */ - if (SQ(d1) < SQ(1e-6)) { - CROSS3( cp, m, m+4 ); - SUB_3V( cp, cp, (m+8) ); - if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) - mat->flags |= MAT_FLAG_ROTATION; - else - mat->flags |= MAT_FLAG_GENERAL_3D; - } - else { - mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */ - } - } - else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) { - mat->type = MATRIX_PERSPECTIVE; - mat->flags |= MAT_FLAG_GENERAL; - } - else { - mat->type = MATRIX_GENERAL; - mat->flags |= MAT_FLAG_GENERAL; - } -} - - -/* Analyse a matrix given that its flags are accurate - this is the - * more common operation, hopefully. - */ -static void analyze_from_flags( GLmatrix *mat ) -{ - const GLfloat *m = mat->m; - - if (TEST_MAT_FLAGS(mat, 0)) { - mat->type = MATRIX_IDENTITY; - } - else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION | - MAT_FLAG_UNIFORM_SCALE | - MAT_FLAG_GENERAL_SCALE))) { - if ( m[10]==1.0F && m[14]==0.0F ) { - mat->type = MATRIX_2D_NO_ROT; - } - else { - mat->type = MATRIX_3D_NO_ROT; - } - } - else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) { - if ( m[ 8]==0.0F - && m[ 9]==0.0F - && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) { - mat->type = MATRIX_2D; - } - else { - mat->type = MATRIX_3D; - } - } - else if ( m[4]==0.0F && m[12]==0.0F - && m[1]==0.0F && m[13]==0.0F - && m[2]==0.0F && m[6]==0.0F - && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) { - mat->type = MATRIX_PERSPECTIVE; - } - else { - mat->type = MATRIX_GENERAL; - } -} - - -void gl_matrix_analyze( GLmatrix *mat ) -{ - if (mat->flags & MAT_DIRTY_TYPE) { - if (mat->flags & MAT_DIRTY_FLAGS) - analyze_from_scratch( mat ); - else - analyze_from_flags( mat ); - } - - if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) { - matrix_invert( mat ); - } - - mat->flags &= ~(MAT_DIRTY_FLAGS| - MAT_DIRTY_TYPE| - MAT_DIRTY_INVERSE); -} - - -static void matrix_copy( GLmatrix *to, const GLmatrix *from ) -{ - MEMCPY( to->m, from->m, sizeof(Identity) ); - to->flags = from->flags | MAT_DIRTY_DEPENDENTS; - to->type = from->type; - - if (to->inv != 0) { - if (from->inv == 0) { - matrix_invert( to ); - } - else { - MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16); - } - } -} - -/* - * Multiply a matrix by an array of floats with known properties. - */ -static void mat_mul_floats( GLmatrix *mat, const GLfloat *m, GLuint flags ) -{ - mat->flags |= (flags | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE | - MAT_DIRTY_DEPENDENTS); - - if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) - matmul34( mat->m, mat->m, m ); - else - matmul4( mat->m, mat->m, m ); - -} - - -void gl_matrix_ctr( GLmatrix *m ) -{ - if ( m->m == 0 ) { - m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); - } - MEMCPY( m->m, Identity, sizeof(Identity) ); - m->inv = 0; - m->type = MATRIX_IDENTITY; - m->flags = MAT_DIRTY_DEPENDENTS; -} - -void gl_matrix_dtr( GLmatrix *m ) -{ - if ( m->m != 0 ) { - ALIGN_FREE( m->m ); - m->m = 0; - } - if ( m->inv != 0 ) { - ALIGN_FREE( m->inv ); - m->inv = 0; - } -} - - -void gl_matrix_alloc_inv( GLmatrix *m ) -{ - if ( m->inv == 0 ) { - m->inv = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); - MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) ); - } -} - - -void gl_matrix_mul( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ) -{ - dest->flags = (a->flags | - b->flags | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE | - MAT_DIRTY_DEPENDENTS); - - if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D)) - matmul34( dest->m, a->m, b->m ); - else - matmul4( dest->m, a->m, b->m ); -} +#include "math/m_matrix.h" +#endif /**********************************************************************/ @@ -1017,45 +90,21 @@ _mesa_Frustum( GLdouble left, GLdouble right, GLdouble nearval, GLdouble farval ) { GET_CURRENT_CONTEXT(ctx); - GLfloat x, y, a, b, c, d; - GLfloat m[16]; GLmatrix *mat = 0; GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glFrustrum" ); - if ((nearval<=0.0 || farval<=0.0) || (nearval == farval) || (left == right) || (top == bottom)) { - gl_error( ctx, GL_INVALID_VALUE, "glFrustum(near or far)" ); + if (nearval <= 0.0 || + farval <= 0.0 || + nearval == farval || + left == right || + top == bottom) + { + gl_error( ctx, GL_INVALID_VALUE, "glFrustum" ); return; } - - x = (2.0*nearval) / (right-left); - y = (2.0*nearval) / (top-bottom); - a = (right+left) / (right-left); - b = (top+bottom) / (top-bottom); - c = -(farval+nearval) / ( farval-nearval); - d = -(2.0*farval*nearval) / (farval-nearval); /* error? */ - -#define M(row,col) m[col*4+row] - M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; - M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; - M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; - M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; -#undef M - - mat_mul_floats( mat, m, MAT_FLAG_PERSPECTIVE ); - - if (ctx->Transform.MatrixMode == GL_PROJECTION) { - /* Need to keep a stack of near/far values in case the user push/pops - * the projection matrix stack so that we can call Driver.NearFar() - * after a pop. - */ - ctx->NearFarStack[ctx->ProjectionStackDepth][0] = nearval; - ctx->NearFarStack[ctx->ProjectionStackDepth][1] = farval; - - if (ctx->Driver.NearFar) { - (*ctx->Driver.NearFar)( ctx, nearval, farval ); - } - } + + _math_matrix_frustrum( mat, left, right, bottom, top, nearval, farval ); } @@ -1065,38 +114,19 @@ _mesa_Ortho( GLdouble left, GLdouble right, GLdouble nearval, GLdouble farval ) { GET_CURRENT_CONTEXT(ctx); - GLfloat x, y, z; - GLfloat tx, ty, tz; - GLfloat m[16]; GLmatrix *mat = 0; GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glOrtho" ); - if ((left == right) || (bottom == top) || (nearval == farval)) { - gl_error( ctx, GL_INVALID_VALUE, - "gl_Ortho((l = r) or (b = top) or (n=f)" ); + if (left == right || + bottom == top || + nearval == farval) + { + gl_error( ctx, GL_INVALID_VALUE, "gl_Ortho" ); return; } - x = 2.0 / (right-left); - y = 2.0 / (top-bottom); - z = -2.0 / (farval-nearval); - tx = -(right+left) / (right-left); - ty = -(top+bottom) / (top-bottom); - tz = -(farval+nearval) / (farval-nearval); - -#define M(row,col) m[col*4+row] - M(0,0) = x; M(0,1) = 0.0F; M(0,2) = 0.0F; M(0,3) = tx; - M(1,0) = 0.0F; M(1,1) = y; M(1,2) = 0.0F; M(1,3) = ty; - M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = z; M(2,3) = tz; - M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F; -#undef M - - mat_mul_floats( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION)); - - if (ctx->Driver.NearFar) { - (*ctx->Driver.NearFar)( ctx, nearval, farval ); - } + _math_matrix_ortho( mat, left, right, bottom, top, nearval, farval ); } @@ -1135,7 +165,7 @@ _mesa_PushMatrix( void ) gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix"); return; } - matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++], + _math_matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++], &ctx->ModelView ); break; case GL_PROJECTION: @@ -1143,14 +173,8 @@ _mesa_PushMatrix( void ) gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix"); return; } - matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++], + _math_matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++], &ctx->ProjectionMatrix ); - - /* Save near and far projection values */ - ctx->NearFarStack[ctx->ProjectionStackDepth][0] - = ctx->NearFarStack[ctx->ProjectionStackDepth-1][0]; - ctx->NearFarStack[ctx->ProjectionStackDepth][1] - = ctx->NearFarStack[ctx->ProjectionStackDepth-1][1]; break; case GL_TEXTURE: { @@ -1159,7 +183,7 @@ _mesa_PushMatrix( void ) gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix"); return; } - matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++], + _math_matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++], &ctx->TextureMatrix[t] ); } break; @@ -1168,7 +192,7 @@ _mesa_PushMatrix( void ) gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix"); return; } - matrix_copy( &ctx->ColorStack[ctx->ColorStackDepth++], + _math_matrix_copy( &ctx->ColorStack[ctx->ColorStackDepth++], &ctx->ColorMatrix ); break; default: @@ -1194,8 +218,8 @@ _mesa_PopMatrix( void ) gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix"); return; } - matrix_copy( &ctx->ModelView, - &ctx->ModelViewStack[--ctx->ModelViewStackDepth] ); + _math_matrix_copy( &ctx->ModelView, + &ctx->ModelViewStack[--ctx->ModelViewStackDepth] ); ctx->NewState |= _NEW_MODELVIEW; break; case GL_PROJECTION: @@ -1204,18 +228,9 @@ _mesa_PopMatrix( void ) return; } - matrix_copy( &ctx->ProjectionMatrix, - &ctx->ProjectionStack[--ctx->ProjectionStackDepth] ); + _math_matrix_copy( &ctx->ProjectionMatrix, + &ctx->ProjectionStack[--ctx->ProjectionStackDepth] ); ctx->NewState |= _NEW_PROJECTION; - - /* Device driver near/far values */ - { - GLfloat nearVal = ctx->NearFarStack[ctx->ProjectionStackDepth][0]; - GLfloat farVal = ctx->NearFarStack[ctx->ProjectionStackDepth][1]; - if (ctx->Driver.NearFar) { - (*ctx->Driver.NearFar)( ctx, nearVal, farVal ); - } - } break; case GL_TEXTURE: { @@ -1224,8 +239,8 @@ _mesa_PopMatrix( void ) gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix"); return; } - matrix_copy(&ctx->TextureMatrix[t], - &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]); + _math_matrix_copy(&ctx->TextureMatrix[t], + &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]); ctx->NewState |= _NEW_TEXTURE_MATRIX; } break; @@ -1234,8 +249,8 @@ _mesa_PopMatrix( void ) gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix"); return; } - matrix_copy(&ctx->ColorMatrix, - &ctx->ColorStack[--ctx->ColorStackDepth]); + _math_matrix_copy(&ctx->ColorMatrix, + &ctx->ColorStack[--ctx->ColorStackDepth]); ctx->NewState |= _NEW_COLOR_MATRIX; break; default: @@ -1251,19 +266,7 @@ _mesa_LoadIdentity( void ) GET_CURRENT_CONTEXT(ctx); GLmatrix *mat = 0; GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadIdentity"); - - MEMCPY( mat->m, Identity, 16*sizeof(GLfloat) ); - - if (mat->inv) - MEMCPY( mat->inv, Identity, 16*sizeof(GLfloat) ); - - mat->type = MATRIX_IDENTITY; - - /* Have to set this to dirty to make sure we recalculate the - * combined matrix later. The update_matrix in this case is a - * shortcircuit anyway... - */ - mat->flags = MAT_DIRTY_DEPENDENTS; + _math_matrix_set_identity( mat ); } @@ -1273,38 +276,15 @@ _mesa_LoadMatrixf( const GLfloat *m ) GET_CURRENT_CONTEXT(ctx); GLmatrix *mat = 0; GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadMatrix"); - - MEMCPY( mat->m, m, 16*sizeof(GLfloat) ); - mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER); - - if (ctx->Transform.MatrixMode == GL_PROJECTION) { - -#define M(row,col) m[col*4+row] - GLfloat c = M(2,2); - GLfloat d = M(2,3); -#undef M - GLfloat n = (c == 1.0 ? 0.0 : d / (c - 1.0)); - GLfloat f = (c == -1.0 ? 1.0 : d / (c + 1.0)); - - /* Need to keep a stack of near/far values in case the user - * push/pops the projection matrix stack so that we can call - * Driver.NearFar() after a pop. - */ - ctx->NearFarStack[ctx->ProjectionStackDepth][0] = n; - ctx->NearFarStack[ctx->ProjectionStackDepth][1] = f; - - if (ctx->Driver.NearFar) { - (*ctx->Driver.NearFar)( ctx, n, f ); - } - } + _math_matrix_loadf( mat, m ); } void _mesa_LoadMatrixd( const GLdouble *m ) { - GLfloat f[16]; GLint i; + GLfloat f[16]; for (i = 0; i < 16; i++) f[i] = m[i]; _mesa_LoadMatrixf(f); @@ -1321,8 +301,7 @@ _mesa_MultMatrixf( const GLfloat *m ) GET_CURRENT_CONTEXT(ctx); GLmatrix *mat = 0; GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glMultMatrix" ); - matmul4( mat->m, mat->m, m ); - mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER); + _math_matrix_mul_floats( mat, m ); } @@ -1332,11 +311,11 @@ _mesa_MultMatrixf( const GLfloat *m ) void _mesa_MultMatrixd( const GLdouble *m ) { - GET_CURRENT_CONTEXT(ctx); - GLmatrix *mat = 0; - GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glMultMatrix" ); - matmul4fd( mat->m, mat->m, m ); - mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER); + GLint i; + GLfloat f[16]; + for (i = 0; i < 16; i++) + f[i] = m[i]; + _mesa_MultMatrixf( f ); } @@ -1349,13 +328,10 @@ void _mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) { GET_CURRENT_CONTEXT(ctx); - GLfloat m[16]; if (angle != 0.0F) { GLmatrix *mat = 0; GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glRotate" ); - - gl_rotation_matrix( angle, x, y, z, m ); - mat_mul_floats( mat, m, MAT_FLAG_ROTATION ); + _math_matrix_rotate( mat, angle, x, y, z ); } } @@ -1374,23 +350,8 @@ _mesa_Scalef( GLfloat x, GLfloat y, GLfloat z ) { GET_CURRENT_CONTEXT(ctx); GLmatrix *mat = 0; - GLfloat *m; GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glScale"); - - m = mat->m; - m[0] *= x; m[4] *= y; m[8] *= z; - m[1] *= x; m[5] *= y; m[9] *= z; - m[2] *= x; m[6] *= y; m[10] *= z; - m[3] *= x; m[7] *= y; m[11] *= z; - - if (fabs(x - y) < 1e-8 && fabs(x - z) < 1e-8) - mat->flags |= MAT_FLAG_UNIFORM_SCALE; - else - mat->flags |= MAT_FLAG_GENERAL_SCALE; - - mat->flags |= (MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE | - MAT_DIRTY_DEPENDENTS); + _math_matrix_scale( mat, x, y, z ); } @@ -1409,18 +370,8 @@ _mesa_Translatef( GLfloat x, GLfloat y, GLfloat z ) { GET_CURRENT_CONTEXT(ctx); GLmatrix *mat = 0; - GLfloat *m; GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glTranslate"); - m = mat->m; - m[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; - m[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; - m[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; - m[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; - - mat->flags |= (MAT_FLAG_TRANSLATION | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE | - MAT_DIRTY_DEPENDENTS); + _math_matrix_translate( mat, x, y, z ); } @@ -1431,12 +382,11 @@ _mesa_Translated( GLdouble x, GLdouble y, GLdouble z ) } - void _mesa_LoadTransposeMatrixfARB( const GLfloat *m ) { GLfloat tm[16]; - gl_matrix_transposef(tm, m); + _math_transposef(tm, m); _mesa_LoadMatrixf(tm); } @@ -1444,9 +394,9 @@ _mesa_LoadTransposeMatrixfARB( const GLfloat *m ) void _mesa_LoadTransposeMatrixdARB( const GLdouble *m ) { - GLdouble tm[16]; - gl_matrix_transposed(tm, m); - _mesa_LoadMatrixd(tm); + GLfloat tm[16]; + _math_transposefd(tm, m); + _mesa_LoadMatrixf(tm); } @@ -1454,7 +404,7 @@ void _mesa_MultTransposeMatrixfARB( const GLfloat *m ) { GLfloat tm[16]; - gl_matrix_transposef(tm, m); + _math_transposef(tm, m); _mesa_MultMatrixf(tm); } @@ -1462,9 +412,9 @@ _mesa_MultTransposeMatrixfARB( const GLfloat *m ) void _mesa_MultTransposeMatrixdARB( const GLdouble *m ) { - GLdouble tm[16]; - gl_matrix_transposed(tm, m); - _mesa_MultMatrixd(tm); + GLfloat tm[16]; + _math_transposefd(tm, m); + _mesa_MultMatrixf(tm); } @@ -1518,7 +468,6 @@ gl_Viewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height ) ctx->Viewport._WindowMap.m[MAT_TY] = ctx->Viewport._WindowMap.m[MAT_SY] + y; ctx->Viewport._WindowMap.m[MAT_SZ] = 0.5 * ctx->Visual.DepthMaxF; ctx->Viewport._WindowMap.m[MAT_TZ] = 0.5 * ctx->Visual.DepthMaxF; - ctx->Viewport._WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION; ctx->Viewport._WindowMap.type = MATRIX_3D_NO_ROT; ctx->NewState |= _NEW_VIEWPORT; diff --git a/src/mesa/main/matrix.h b/src/mesa/main/matrix.h index db88b2857cf..fce9dace657 100644 --- a/src/mesa/main/matrix.h +++ b/src/mesa/main/matrix.h @@ -1,4 +1,4 @@ -/* $Id: matrix.h,v 1.8 2000/10/29 18:12:15 brianp Exp $ */ +/* $Id: matrix.h,v 1.9 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -38,39 +38,8 @@ 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, diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index b4de245e9f6..26c4d5efab4 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -1,4 +1,4 @@ -/* $Id: points.c,v 1.22 2000/11/15 16:38:40 brianp Exp $ */ +/* $Id: points.c,v 1.23 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -36,7 +36,6 @@ #include "points.h" #include "texstate.h" #include "types.h" -#include "vb.h" #endif diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c index e8d36a3ba00..a59e22a36a1 100644 --- a/src/mesa/main/rastpos.c +++ b/src/mesa/main/rastpos.c @@ -1,4 +1,4 @@ -/* $Id: rastpos.c,v 1.13 2000/11/13 20:02:56 keithw Exp $ */ +/* $Id: rastpos.c,v 1.14 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -35,17 +35,206 @@ #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 */ static void raster_pos4f( GLcontext *ctx, @@ -54,10 +243,12 @@ static void raster_pos4f( GLcontext *ctx, GLfloat v[4], eye[4], clip[4], ndc[3], d; /* KW: Added this test, which is in the spec. We can't do this - * outside begin/end any more because the ctx->Current values + * inside begin/end any more because the ctx->Current values * aren't uptodate during that period. */ - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glRasterPos" ); + FLUSH_TNL_RETURN(ctx, (FLUSH_INSIDE_BEGIN_END| + FLUSH_STORED_VERTICES| + FLUSH_UPDATE_CURRENT), "raster_pos4f"); if (ctx->NewState) gl_update_state( ctx ); diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index eb68bf70a5f..d1dde8c88ed 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1,4 +1,4 @@ -/* $Id: state.c,v 1.44 2000/11/15 16:38:59 brianp Exp $ */ +/* $Id: state.c,v 1.45 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -46,7 +46,6 @@ #include "context.h" #include "convolve.h" #include "copypix.h" -#include "cva.h" #include "depth.h" #include "dlist.h" #include "drawpix.h" @@ -63,7 +62,6 @@ #include "masking.h" #include "matrix.h" #include "mmath.h" -#include "pipeline.h" #include "pixel.h" #include "pixeltex.h" #include "points.h" @@ -72,7 +70,6 @@ #include "readpix.h" #include "rect.h" #include "scissor.h" -#include "shade.h" #include "state.h" #include "stencil.h" #include "teximage.h" @@ -81,11 +78,15 @@ #include "texture.h" #include "types.h" #include "varray.h" -#include "vbfill.h" -#include "vbrender.h" #include "winpos.h" -#include "xform.h" + #include "swrast/swrast.h" +#include "math/m_matrix.h" +#include "math/m_xform.h" +#include "tnl/t_eval.h" +#include "tnl/t_vbfill.h" +#include "tnl/t_varray.h" +#include "tnl/t_rect.h" #endif @@ -690,150 +691,6 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize) /**********************************************************************/ - - - -void gl_print_state( const char *msg, GLuint state ) -{ - fprintf(stderr, - "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", - msg, - state, - (state & _NEW_MODELVIEW) ? "ctx->ModelView, " : "", - (state & _NEW_PROJECTION) ? "ctx->Projection, " : "", - (state & _NEW_TEXTURE_MATRIX) ? "ctx->TextureMatrix, " : "", - (state & _NEW_COLOR_MATRIX) ? "ctx->ColorMatrix, " : "", - (state & _NEW_ACCUM) ? "ctx->Accum, " : "", - (state & _NEW_COLOR) ? "ctx->Color, " : "", - (state & _NEW_DEPTH) ? "ctx->Depth, " : "", - (state & _NEW_EVAL) ? "ctx->Eval/EvalMap, " : "", - (state & _NEW_FOG) ? "ctx->Fog, " : "", - (state & _NEW_HINT) ? "ctx->Hint, " : "", - (state & _NEW_LIGHT) ? "ctx->Light, " : "", - (state & _NEW_LINE) ? "ctx->Line, " : "", - (state & _NEW_FEEDBACK_SELECT) ? "ctx->Feedback/Select, " : "", - (state & _NEW_PIXEL) ? "ctx->Pixel, " : "", - (state & _NEW_POINT) ? "ctx->Point, " : "", - (state & _NEW_POLYGON) ? "ctx->Polygon, " : "", - (state & _NEW_POLYGONSTIPPLE) ? "ctx->PolygonStipple, " : "", - (state & _NEW_SCISSOR) ? "ctx->Scissor, " : "", - (state & _NEW_TEXTURE) ? "ctx->Texture, " : "", - (state & _NEW_TRANSFORM) ? "ctx->Transform, " : "", - (state & _NEW_VIEWPORT) ? "ctx->Viewport, " : "", - (state & _NEW_PACKUNPACK) ? "ctx->Pack/Unpack, " : "", - (state & _NEW_ARRAY) ? "ctx->Array, " : "", - (state & _NEW_COLORTABLE) ? "ctx->{*}ColorTable, " : "", - (state & _NEW_RENDERMODE) ? "ctx->RenderMode, " : "", - (state & _NEW_BUFFERS) ? "ctx->Visual, ctx->DrawBuffer,, " : ""); -} - - -void gl_print_enable_flags( const char *msg, GLuint flags ) -{ - fprintf(stderr, - "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n", - msg, - flags, - (flags & ENABLE_TEX0) ? "tex-0, " : "", - (flags & ENABLE_TEX1) ? "tex-1, " : "", - (flags & ENABLE_LIGHT) ? "light, " : "", - (flags & ENABLE_FOG) ? "fog, " : "", - (flags & ENABLE_USERCLIP) ? "userclip, " : "", - (flags & ENABLE_TEXGEN0) ? "tex-gen-0, " : "", - (flags & ENABLE_TEXGEN1) ? "tex-gen-1, " : "", - (flags & ENABLE_TEXMAT0) ? "tex-mat-0, " : "", - (flags & ENABLE_TEXMAT1) ? "tex-mat-1, " : "", - (flags & ENABLE_NORMALIZE) ? "normalize, " : "", - (flags & ENABLE_RESCALE) ? "rescale, " : ""); -} - - -/* Note: This routine refers to derived texture attribute values to - * compute the ENABLE_TEXMAT flags, but is only called on - * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE, the ENABLE_TEXMAT - * flags are updated by _mesa_update_textures(), below. - * - * If both TEXTURE and TEXTURE_MATRIX change at once, these values - * will be computed twice. - */ -static void -_mesa_update_texture_matrices( GLcontext *ctx ) -{ - GLuint i; - - ctx->_Enabled &= ~(ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2); - - for (i=0; i < ctx->Const.MaxTextureUnits; i++) { - if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER) { - gl_matrix_analyze( &ctx->TextureMatrix[i] ); - ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS; - - if (ctx->Texture.Unit[i]._ReallyEnabled && - ctx->TextureMatrix[i].type != MATRIX_IDENTITY) - ctx->_Enabled |= ENABLE_TEXMAT0 << i; - } - } -} - - -/* Note: This routine refers to derived texture matrix values to - * compute the ENABLE_TEXMAT flags, but is only called on - * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT - * flags are updated by _mesa_update_texture_matrices, above. - * - * If both TEXTURE and TEXTURE_MATRIX change at once, these values - * will be computed twice. - */ -static void -_mesa_update_textures( GLcontext *ctx ) -{ - GLuint i; - - ctx->Texture._ReallyEnabled = 0; - ctx->_Enabled &= ~(ENABLE_TEXGEN0 | ENABLE_TEXGEN1 | ENABLE_TEXGEN2 | - ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2 | - ENABLE_TEX0 | ENABLE_TEX1 | ENABLE_TEX2); - - gl_update_dirty_texobjs(ctx); - - for (i=0; i < ctx->Const.MaxTextureUnits; i++) { - - ctx->Texture.Unit[i]._ReallyEnabled = 0; - - if (ctx->Texture.Unit[i].Enabled) { - - gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] ); - - if (ctx->Texture.Unit[i]._ReallyEnabled) { - GLuint flag = ctx->Texture.Unit[i]._ReallyEnabled << (i * 4); - - ctx->Texture._ReallyEnabled |= flag; - ctx->_Enabled |= flag; - - if (ctx->Texture.Unit[i]._GenFlags) { - ctx->_Enabled |= ENABLE_TEXGEN0 << i; - ctx->Texture._GenFlags |= ctx->Texture.Unit[i]._GenFlags; - } - - if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY) - ctx->_Enabled |= ENABLE_TEXMAT0 << i; - } - } - } - - ctx->_NeedNormals &= ~NEED_NORMALS_TEXGEN; - ctx->_NeedEyeCoords &= ~NEED_EYE_TEXGEN; - - if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) { - ctx->_NeedNormals |= NEED_NORMALS_TEXGEN; - ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN; - } - - if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) { - ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN; - } -} - static void _mesa_update_polygon( GLcontext *ctx ) { @@ -872,11 +729,11 @@ static void _mesa_calculate_model_project_matrix( GLcontext *ctx ) { if (!ctx->_NeedEyeCoords) { - gl_matrix_mul( &ctx->_ModelProjectMatrix, - &ctx->ProjectionMatrix, - &ctx->ModelView ); + _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix, + &ctx->ProjectionMatrix, + &ctx->ModelView ); - gl_matrix_analyze( &ctx->_ModelProjectMatrix ); + _math_matrix_analyze( &ctx->_ModelProjectMatrix ); } } @@ -913,7 +770,6 @@ _mesa_update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords ) */ _mesa_update_modelview_scale(ctx); _mesa_calculate_model_project_matrix(ctx); - gl_update_normal_transform( ctx ); gl_compute_light_positions( ctx ); if (ctx->Driver.LightingSpaceChange) @@ -932,9 +788,6 @@ _mesa_update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords ) if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) _mesa_calculate_model_project_matrix(ctx); - if (new_state & _TNL_NEW_NORMAL_TRANSFORM) - gl_update_normal_transform( ctx ); /* references _ModelViewInvScale */ - if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW)) gl_compute_light_positions( ctx ); } @@ -973,7 +826,7 @@ _mesa_update_drawbuffer( GLcontext *ctx ) static void _mesa_update_projection( GLcontext *ctx ) { - gl_matrix_analyze( &ctx->ProjectionMatrix ); + _math_matrix_analyze( &ctx->ProjectionMatrix ); /* Recompute clip plane positions in clipspace. This is also done * in _mesa_ClipPlane(). @@ -1015,7 +868,7 @@ void gl_update_state( GLcontext *ctx ) gl_print_state("", new_state); if (new_state & _NEW_MODELVIEW) - gl_matrix_analyze( &ctx->ModelView ); + _math_matrix_analyze( &ctx->ModelView ); if (new_state & _NEW_PROJECTION) _mesa_update_projection( ctx ); @@ -1024,16 +877,13 @@ void gl_update_state( GLcontext *ctx ) _mesa_update_texture_matrices( ctx ); if (new_state & _NEW_COLOR_MATRIX) - gl_matrix_analyze( &ctx->ColorMatrix ); + _math_matrix_analyze( &ctx->ColorMatrix ); /* References ColorMatrix.type (derived above). */ if (new_state & (_NEW_PIXEL|_NEW_COLOR_MATRIX)) _mesa_update_image_transfer_state(ctx); - if (new_state & _NEW_ARRAY) - gl_update_client_state( ctx ); - /* Contributes to NeedEyeCoords, NeedNormals. */ if (new_state & _NEW_TEXTURE) @@ -1050,12 +900,6 @@ void gl_update_state( GLcontext *ctx ) if (new_state & _NEW_LIGHT) gl_update_lighting( ctx ); - if (new_state & (_NEW_LIGHT|_NEW_TEXTURE|_NEW_FOG| - _DD_NEW_TRI_LIGHT_TWOSIDE | - _DD_NEW_SEPERATE_SPECULAR | - _DD_NEW_TRI_UNFILLED )) - gl_update_clipmask(ctx); - /* We can light in object space if the modelview matrix preserves * lengths and relative angles. */ @@ -1082,17 +926,13 @@ void gl_update_state( GLcontext *ctx ) _TNL_NEW_NEED_EYE_COORDS)) _mesa_update_tnl_spaces( ctx, oldneedeyecoords ); - if (new_state & ctx->Driver.UpdateStateNotify) - { - /* - * Here the driver sets up all the ctx->Driver function pointers to - * it's specific, private functions. - */ - ctx->Driver.UpdateState(ctx); - gl_set_render_vb_function(ctx); /* XXX: remove this mechanism */ - } - - gl_update_pipelines(ctx); + /* + * Here the driver sets up all the ctx->Driver function pointers + * to it's specific, private functions, and performs any + * internal state management necessary, including invalidating + * state of active modules. + */ + ctx->Driver.UpdateState(ctx); ctx->NewState = 0; } diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 45a39f61620..0e33e683de1 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -1,4 +1,4 @@ -/* $Id: texstate.c,v 1.21 2000/11/05 18:40:58 keithw Exp $ */ +/* $Id: texstate.c,v 1.22 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -34,13 +34,13 @@ #include "enums.h" #include "extensions.h" #include "macros.h" -#include "matrix.h" #include "texobj.h" #include "teximage.h" #include "texstate.h" #include "texture.h" #include "types.h" -#include "xform.h" +#include "math/m_xform.h" +#include "math/m_matrix.h" #include "swrast/swrast.h" #endif @@ -1116,7 +1116,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) else if (pname==GL_EYE_PLANE) { /* Transform plane equation by the inverse modelview matrix */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { - gl_matrix_analyze( &ctx->ModelView ); + _math_matrix_analyze( &ctx->ModelView ); } gl_transform_vector( texUnit->EyePlaneS, params, ctx->ModelView.inv ); @@ -1164,7 +1164,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) else if (pname==GL_EYE_PLANE) { /* Transform plane equation by the inverse modelview matrix */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { - gl_matrix_analyze( &ctx->ModelView ); + _math_matrix_analyze( &ctx->ModelView ); } gl_transform_vector( texUnit->EyePlaneT, params, ctx->ModelView.inv ); @@ -1208,7 +1208,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) else if (pname==GL_EYE_PLANE) { /* Transform plane equation by the inverse modelview matrix */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { - gl_matrix_analyze( &ctx->ModelView ); + _math_matrix_analyze( &ctx->ModelView ); } gl_transform_vector( texUnit->EyePlaneR, params, ctx->ModelView.inv ); @@ -1244,7 +1244,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) else if (pname==GL_EYE_PLANE) { /* Transform plane equation by the inverse modelview matrix */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { - gl_matrix_analyze( &ctx->ModelView ); + _math_matrix_analyze( &ctx->ModelView ); } gl_transform_vector( texUnit->EyePlaneQ, params, ctx->ModelView.inv ); @@ -1674,18 +1674,3 @@ void gl_remove_texobj_from_dirty_list( struct gl_shared_state *shared, } -/* - * This is called by gl_update_state() if the _NEW_TEXTURE bit in - * ctx->NewState is set. - */ -void gl_update_dirty_texobjs( GLcontext *ctx ) -{ - struct gl_texture_object *t, *next; - for (t = ctx->Shared->DirtyTexObjList; t; t = next) { - next = t->NextDirty; - _mesa_test_texobj_completeness(ctx, t); - t->NextDirty = NULL; - t->Dirty = GL_FALSE; - } - ctx->Shared->DirtyTexObjList = NULL; -} diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h index d3111f02e3f..9954a0a126d 100644 --- a/src/mesa/main/texstate.h +++ b/src/mesa/main/texstate.h @@ -1,4 +1,4 @@ -/* $Id: texstate.h,v 1.2 1999/11/11 01:22:28 brianp Exp $ */ +/* $Id: texstate.h,v 1.3 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -140,8 +140,6 @@ extern void gl_remove_texobj_from_dirty_list( struct gl_shared_state *shared, struct gl_texture_object *tObj ); -extern void -gl_update_dirty_texobjs( GLcontext *ctx ); #endif diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index d604beb9dde..3cd368779c0 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -1,4 +1,4 @@ -/* $Id: varray.c,v 1.30 2000/11/05 18:40:59 keithw Exp $ */ +/* $Id: varray.c,v 1.31 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -29,25 +29,17 @@ #else #include "glheader.h" #include "context.h" -#include "cva.h" #include "enable.h" #include "enums.h" #include "dlist.h" #include "light.h" #include "macros.h" #include "mmath.h" -#include "pipeline.h" #include "state.h" #include "texstate.h" -#include "translate.h" #include "types.h" #include "varray.h" -#include "vb.h" -#include "vbfill.h" -#include "vbrender.h" -#include "vbindirect.h" -#include "vbxform.h" -#include "xform.h" +#include "math/m_translate.h" #endif @@ -96,9 +88,10 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) ctx->Array.Vertex.Stride = stride; ctx->Array.Vertex.Ptr = (void *) ptr; ctx->Array._VertexFunc = gl_trans_4f_tab[size][TYPE_IDX(type)]; - ctx->Array._VertexEltFunc = gl_trans_elt_4f_tab[size][TYPE_IDX(type)]; - ctx->Array._NewArrayState |= VERT_OBJ_ANY; ctx->NewState |= _NEW_ARRAY; + + if (ctx->Driver.VertexPointer) + ctx->Driver.VertexPointer( ctx, size, type, stride, ptr ); } @@ -146,9 +139,10 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) ctx->Array.Normal.Stride = stride; ctx->Array.Normal.Ptr = (void *) ptr; ctx->Array._NormalFunc = gl_trans_3f_tab[TYPE_IDX(type)]; - ctx->Array._NormalEltFunc = gl_trans_elt_3f_tab[TYPE_IDX(type)]; - ctx->Array._NewArrayState |= VERT_NORM; ctx->NewState |= _NEW_ARRAY; + + if (ctx->Driver.NormalPointer) + ctx->Driver.NormalPointer( ctx, type, stride, ptr ); } @@ -209,9 +203,10 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) ctx->Array.Color.Stride = stride; ctx->Array.Color.Ptr = (void *) ptr; ctx->Array._ColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)]; - ctx->Array._ColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)]; - ctx->Array._NewArrayState |= VERT_RGBA; ctx->NewState |= _NEW_ARRAY; + + if (ctx->Driver.ColorPointer) + ctx->Driver.ColorPointer( ctx, size, type, stride, ptr ); } @@ -244,9 +239,10 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) ctx->Array.FogCoord.Stride = stride; ctx->Array.FogCoord.Ptr = (void *) ptr; ctx->Array._FogCoordFunc = gl_trans_1f_tab[TYPE_IDX(type)]; - ctx->Array._FogCoordEltFunc = gl_trans_elt_1f_tab[TYPE_IDX(type)]; - ctx->Array._NewArrayState |= VERT_FOG_COORD; ctx->NewState |= _NEW_ARRAY; + + if (ctx->Driver.FogCoordPointer) + ctx->Driver.FogCoordPointer( ctx, type, stride, ptr ); } @@ -287,9 +283,10 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) ctx->Array.Index.Stride = stride; ctx->Array.Index.Ptr = (void *) ptr; ctx->Array._IndexFunc = gl_trans_1ui_tab[TYPE_IDX(type)]; - ctx->Array._IndexEltFunc = gl_trans_elt_1ui_tab[TYPE_IDX(type)]; - ctx->Array._NewArrayState |= VERT_INDEX; ctx->NewState |= _NEW_ARRAY; + + if (ctx->Driver.IndexPointer) + ctx->Driver.IndexPointer( ctx, type, stride, ptr ); } @@ -350,9 +347,10 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, ctx->Array.SecondaryColor.Stride = stride; ctx->Array.SecondaryColor.Ptr = (void *) ptr; ctx->Array._SecondaryColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)]; - ctx->Array._SecondaryColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)]; - ctx->Array._NewArrayState |= VERT_SPEC_RGB; ctx->NewState |= _NEW_ARRAY; + + if (ctx->Driver.SecondaryColorPointer) + ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr ); } @@ -405,11 +403,11 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ctx->Array.TexCoord[texUnit].Type = type; ctx->Array.TexCoord[texUnit].Stride = stride; ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr; - ctx->Array._TexCoordFunc[texUnit] = gl_trans_4f_tab[size][TYPE_IDX(type)]; - ctx->Array._TexCoordEltFunc[texUnit] = gl_trans_elt_4f_tab[size][TYPE_IDX(type)]; - ctx->Array._NewArrayState |= VERT_TEX_ANY(texUnit); ctx->NewState |= _NEW_ARRAY; + + if (ctx->Driver.TexCoordPointer) + ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr ); } @@ -433,9 +431,10 @@ _mesa_EdgeFlagPointer(GLsizei stride, const void *vptr) } else { ctx->Array._EdgeFlagFunc = 0; } - ctx->Array._EdgeFlagEltFunc = gl_trans_elt_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)]; - ctx->Array._NewArrayState |= VERT_EDGE; ctx->NewState |= _NEW_ARRAY; + + if (ctx->Driver.EdgeFlagPointer) + ctx->Driver.EdgeFlagPointer( ctx, stride, ptr ); } @@ -498,620 +497,6 @@ _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) -/* KW: Batch function to exec all the array elements in the input - * buffer prior to transform. Done only the first time a vertex - * buffer is executed or compiled. - * - * KW: Have to do this after each glEnd if cva isn't active. (also - * have to do it after each full buffer) - */ -void gl_exec_array_elements( GLcontext *ctx, struct immediate *IM, - GLuint start, - GLuint count) -{ - GLuint *flags = IM->Flag; - GLuint *elts = IM->Elt; - GLuint translate = ctx->Array._Flags; - GLuint i; - - if (MESA_VERBOSE&VERBOSE_IMMEDIATE) - fprintf(stderr, "exec_array_elements %d .. %d\n", start, count); - - if (translate & VERT_OBJ_ANY) - (ctx->Array._VertexEltFunc)( IM->Obj, - &ctx->Array.Vertex, - flags, elts, (VERT_ELT|VERT_OBJ_ANY), - start, count); - - if (translate & VERT_NORM) - (ctx->Array._NormalEltFunc)( IM->Normal, - &ctx->Array.Normal, - flags, elts, (VERT_ELT|VERT_NORM), - start, count); - - if (translate & VERT_EDGE) - (ctx->Array._EdgeFlagEltFunc)( IM->EdgeFlag, - &ctx->Array.EdgeFlag, - flags, elts, (VERT_ELT|VERT_EDGE), - start, count); - - if (translate & VERT_RGBA) - (ctx->Array._ColorEltFunc)( IM->Color, - &ctx->Array.Color, - flags, elts, (VERT_ELT|VERT_RGBA), - start, count); - - - if (translate & VERT_SPEC_RGB) - (ctx->Array._SecondaryColorEltFunc)( IM->SecondaryColor, - &ctx->Array.SecondaryColor, - flags, elts, (VERT_ELT|VERT_SPEC_RGB), - start, count); - - if (translate & VERT_FOG_COORD) - (ctx->Array._FogCoordEltFunc)( IM->FogCoord, - &ctx->Array.FogCoord, - flags, elts, (VERT_ELT|VERT_FOG_COORD), - start, count); - - if (translate & VERT_INDEX) - (ctx->Array._IndexEltFunc)( IM->Index, - &ctx->Array.Index, - flags, elts, (VERT_ELT|VERT_INDEX), - start, count); - - if (translate & VERT_TEX0_ANY) - (ctx->Array._TexCoordEltFunc[0])( IM->TexCoord[0], - &ctx->Array.TexCoord[0], - flags, elts, (VERT_ELT|VERT_TEX0_ANY), - start, count); - - if (translate & VERT_TEX1_ANY) - (ctx->Array._TexCoordEltFunc[1])( IM->TexCoord[1], - &ctx->Array.TexCoord[1], - flags, elts, (VERT_ELT|VERT_TEX1_ANY), - start, count); - -#if MAX_TEXTURE_UNITS > 2 - if (translate & VERT_TEX2_ANY) - (ctx->Array._TexCoordEltFunc[2])( IM->TexCoord[2], - &ctx->Array.TexCoord[2], - flags, elts, (VERT_ELT|VERT_TEX2_ANY), - start, count); -#endif -#if MAX_TEXTURE_UNITS > 3 - if (translate & VERT_TEX3_ANY) - (ctx->Array._TexCoordEltFunc[3])( IM->TexCoord[3], - &ctx->Array.TexCoord[3], - flags, elts, (VERT_ELT|VERT_TEX3_ANY), - start, count); -#endif - - for (i = start ; i < count ; i++) - if (flags[i] & VERT_ELT) - flags[i] |= translate; - -} - - - -/* Enough funny business going on in here it might be quicker to use a - * function pointer. - */ -#define ARRAY_ELT( IM, i ) \ -{ \ - GLuint count = IM->Count; \ - IM->Elt[count] = i; \ - IM->Flag[count] = ((IM->Flag[count] & IM->ArrayAndFlags) | \ - VERT_ELT); \ - IM->FlushElt |= IM->ArrayEltFlush; \ - IM->Count = count += IM->ArrayIncr; \ - if (count == VB_MAX) \ - _mesa_maybe_transform_vb( IM ); \ -} - - -void -_mesa_ArrayElement( GLint i ) -{ - GET_IMMEDIATE; - ARRAY_ELT( IM, i ); -} - - -static void -gl_ArrayElement( GLcontext *CC, GLint i ) -{ - struct immediate *im = CC->input; - ARRAY_ELT( im, i ); -} - - - -void -_mesa_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - struct vertex_buffer *VB = ctx->VB; - GLint i; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawArrays"); - - if (count<0) { - gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); - return; - } - - if (!ctx->CompileFlag && ctx->Array.Vertex.Enabled) { - GLint remaining = count; - GLint i; - struct gl_client_array *Normal; - struct gl_client_array *Color; - struct gl_client_array *SecondaryColor; - struct gl_client_array *FogCoord; - struct gl_client_array *Index; - struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS]; - struct gl_client_array *EdgeFlag; - struct immediate *IM = VB->IM; - struct gl_pipeline *elt = &ctx->CVA.elt; - GLboolean relock; - GLuint fallback, required; - - if (ctx->NewState) - gl_update_state( ctx ); - - /* Just turn off cva on this path. Could be useful for multipass - * rendering to keep it turned on. - */ - relock = ctx->CompileCVAFlag; - - if (relock) { - ctx->CompileCVAFlag = 0; - elt->pipeline_valid = 0; - } - - if (!elt->pipeline_valid) - gl_build_immediate_pipeline( ctx ); - - required = elt->inputs; - fallback = (elt->inputs & ~ctx->Array._Summary); - - /* The translate function doesn't do anything about size. It - * just ensures that type and stride come out right. - */ - IM->v.Obj.size = ctx->Array.Vertex.Size; - - if (required & VERT_RGBA) { - Color = &ctx->Array.Color; - if (fallback & VERT_RGBA) { - Color = &ctx->Fallback.Color; - ctx->Array._ColorFunc = - gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)]; - } - } - - if (required & VERT_SPEC_RGB) - { - SecondaryColor = &ctx->Array.SecondaryColor; - if (fallback & VERT_SPEC_RGB) { - SecondaryColor = &ctx->Fallback.SecondaryColor; - ctx->Array._SecondaryColorFunc = - gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)]; - } - } - - if (required & VERT_FOG_COORD) - { - FogCoord = &ctx->Array.FogCoord; - if (fallback & VERT_FOG_COORD) { - FogCoord = &ctx->Fallback.FogCoord; - ctx->Array._FogCoordFunc = - gl_trans_1f_tab[TYPE_IDX(GL_FLOAT)]; - } - } - - if (required & VERT_INDEX) { - Index = &ctx->Array.Index; - if (fallback & VERT_INDEX) { - Index = &ctx->Fallback.Index; - ctx->Array._IndexFunc = gl_trans_1ui_tab[TYPE_IDX(GL_UNSIGNED_INT)]; - } - } - - for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) { - GLuint flag = VERT_TEX_ANY(i); - - if (required & flag) { - TexCoord[i] = &ctx->Array.TexCoord[i]; - - if (fallback & flag) { - TexCoord[i] = &ctx->Fallback.TexCoord[i]; - TexCoord[i]->Size = gl_texcoord_size( ctx->Current.Flag, i ); - - ctx->Array._TexCoordFunc[i] = - gl_trans_4f_tab[TexCoord[i]->Size][TYPE_IDX(GL_FLOAT)]; - } - } - } - - if (ctx->Array._Flags != ctx->Array._Flag[0]) { - for (i = 0 ; i < VB_MAX ; i++) - ctx->Array._Flag[i] = ctx->Array._Flags; - } - - if (required & VERT_NORM) { - Normal = &ctx->Array.Normal; - if (fallback & VERT_NORM) { - Normal = &ctx->Fallback.Normal; - ctx->Array._NormalFunc = gl_trans_3f_tab[TYPE_IDX(GL_FLOAT)]; - } - } - - if ( required & VERT_EDGE ) { - if (mode == GL_TRIANGLES || - mode == GL_QUADS || - mode == GL_POLYGON) { - EdgeFlag = &ctx->Array.EdgeFlag; - if (fallback & VERT_EDGE) { - EdgeFlag = &ctx->Fallback.EdgeFlag; - ctx->Array._EdgeFlagFunc = - gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)]; - } - } - else - required &= ~VERT_EDGE; - } - - VB->Primitive = IM->Primitive; - VB->NextPrimitive = IM->NextPrimitive; - VB->MaterialMask = IM->MaterialMask; - VB->Material = IM->Material; - VB->BoundsPtr = 0; - - while (remaining > 0) { - GLint vbspace = VB_MAX - VB_START; - GLuint count, n; - - if (vbspace >= remaining) { - n = remaining; - VB->LastPrimitive = VB_START + n; - } - else { - n = vbspace; - VB->LastPrimitive = VB_START; - } - - VB->CullMode = 0; - - ctx->Array._VertexFunc( IM->Obj + VB_START, - &ctx->Array.Vertex, start, n ); - - if (required & VERT_NORM) { - ctx->Array._NormalFunc( IM->Normal + VB_START, - Normal, start, n ); - } - - if (required & VERT_EDGE) { - ctx->Array._EdgeFlagFunc( IM->EdgeFlag + VB_START, - EdgeFlag, start, n ); - } - - if (required & VERT_RGBA) { - ctx->Array._ColorFunc( IM->Color + VB_START, - Color, start, n ); - } - - if (required & VERT_SPEC_RGB) { - ctx->Array._SecondaryColorFunc( IM->SecondaryColor + VB_START, - SecondaryColor, start, n ); - } - - if (required & VERT_FOG_COORD) { - ctx->Array._FogCoordFunc( IM->FogCoord + VB_START, - FogCoord, start, n ); - } - - if (required & VERT_INDEX) { - ctx->Array._IndexFunc( IM->Index + VB_START, - Index, start, n ); - } - - if (required & VERT_TEX0_ANY) { - IM->v.TexCoord[0].size = TexCoord[0]->Size; - ctx->Array._TexCoordFunc[0]( IM->TexCoord[0] + VB_START, - TexCoord[0], start, n ); - } - - if (required & VERT_TEX1_ANY) { - IM->v.TexCoord[1].size = TexCoord[1]->Size; - ctx->Array._TexCoordFunc[1]( IM->TexCoord[1] + VB_START, - TexCoord[1], start, n ); - } -#if MAX_TEXTURE_UNITS > 2 - if (required & VERT_TEX2_ANY) { - IM->v.TexCoord[2].size = TexCoord[2]->Size; - ctx->Array._TexCoordFunc[2]( IM->TexCoord[2] + VB_START, - TexCoord[2], start, n ); - } -#endif -#if MAX_TEXTURE_UNITS > 3 - if (required & VERT_TEX3_ANY) { - IM->v.TexCoord[3].size = TexCoord[3]->Size; - ctx->Array._TexCoordFunc[3]( IM->TexCoord[3] + VB_START, - TexCoord[3], start, n ); - } -#endif - - VB->ObjPtr = &IM->v.Obj; - VB->NormalPtr = &IM->v.Normal; - VB->ColorPtr = &IM->v.Color; - VB->Color[0] = VB->Color[1] = VB->ColorPtr; - VB->IndexPtr = &IM->v.Index; - VB->EdgeFlagPtr = &IM->v.EdgeFlag; - VB->SecondaryColorPtr = &IM->v.SecondaryColor; - VB->FogCoordPtr = &IM->v.FogCoord; - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - VB->TexCoordPtr[i] = &IM->v.TexCoord[i]; - } - - VB->Flag = ctx->Array._Flag; - VB->OrFlag = ctx->Array._Flags; - - VB->Start = IM->Start = VB_START; - count = VB->Count = IM->Count = VB_START + n; - -#define RESET_VEC(v, t, s, c) (v.start = t v.data[s], v.count = c) - - RESET_VEC(IM->v.Obj, (GLfloat *), VB_START, count); - RESET_VEC(IM->v.Normal, (GLfloat *), VB_START, count); - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - RESET_VEC(IM->v.TexCoord[i], (GLfloat *), VB_START, count); - } - RESET_VEC(IM->v.Index, &, VB_START, count); - RESET_VEC(IM->v.Elt, &, VB_START, count); - RESET_VEC(IM->v.EdgeFlag, &, VB_START, count); - RESET_VEC(IM->v.Color, (GLubyte *), VB_START, count); - RESET_VEC(VB->Clip, (GLfloat *), VB_START, count); - RESET_VEC(VB->Eye, (GLfloat *), VB_START, count); - RESET_VEC(VB->Win, (GLfloat *), VB_START, count); - RESET_VEC(VB->BColor, (GLubyte *), VB_START, count); - RESET_VEC(VB->BIndex, &, VB_START, count); - - VB->NextPrimitive[VB->CopyStart] = VB->Count; - VB->Primitive[VB->CopyStart] = mode; - ctx->Array._Flag[count] |= VERT_END_VB; - - /* Transform and render. - */ - gl_run_pipeline( VB ); - gl_reset_vb( VB ); - - /* Restore values: - */ - ctx->Array._Flag[count] = ctx->Array._Flags; - ctx->Array._Flag[VB_START] = ctx->Array._Flags; - - start += n; - remaining -= n; - } - - gl_reset_input( ctx ); - - if (relock) { - ctx->CompileCVAFlag = relock; - elt->pipeline_valid = 0; - } - } - else if (ctx->Array.Vertex.Enabled) - { - /* The GL_COMPILE and GL_COMPILE_AND_EXECUTE cases. These - * could be handled by the above code, but it gets a little - * complex. The generated list is still of good quality - * this way. - */ - gl_Begin( ctx, mode ); - for (i=0;i<count;i++) { - gl_ArrayElement( ctx, start+i ); - } - gl_End( ctx ); - } - else - { - /* The degenerate case where vertices are not enabled - only - * need to process the very final array element, as all of the - * preceding ones would be overwritten anyway. - */ - gl_Begin( ctx, mode ); - gl_ArrayElement( ctx, start+count ); - gl_End( ctx ); - } -} - - - -/* KW: Exactly fakes the effects of calling glArrayElement multiple times. - */ -#if 1 -#define DRAW_ELT(FUNC, TYPE) \ -static void FUNC( GLcontext *ctx, GLenum mode, \ - TYPE *indices, GLuint count ) \ -{ \ - GLuint i,j; \ - \ - gl_Begin( ctx, mode ); \ - \ - for (j = 0 ; j < count ; ) { \ - struct immediate *IM = ctx->input; \ - GLuint start = IM->Start; \ - GLuint nr = MIN2( VB_MAX, count - j + start ); \ - GLuint sf = IM->Flag[start]; \ - IM->FlushElt |= IM->ArrayEltFlush; \ - \ - for (i = start ; i < nr ; i++) { \ - IM->Elt[i] = (GLuint) *indices++; \ - IM->Flag[i] = VERT_ELT; \ - } \ - \ - if (j == 0) IM->Flag[start] |= sf; \ - \ - IM->Count = nr; \ - j += nr - start; \ - \ - if (j == count) \ - gl_End( ctx ); \ - _mesa_maybe_transform_vb( IM ); \ - } \ -} -#else -#define DRAW_ELT(FUNC, TYPE) \ -static void FUNC( GLcontext *ctx, GLenum mode, \ - TYPE *indices, GLuint count ) \ -{ \ - int i; \ - glBegin(mode); \ - for (i = 0 ; i < count ; i++) \ - glArrayElement( indices[i] ); \ - glEnd(); \ -} -#endif - - -DRAW_ELT( draw_elt_ubyte, GLubyte ) -DRAW_ELT( draw_elt_ushort, GLushort ) -DRAW_ELT( draw_elt_uint, GLuint ) - - -static GLuint natural_stride[0x10] = -{ - sizeof(GLbyte), /* 0 */ - sizeof(GLubyte), /* 1 */ - sizeof(GLshort), /* 2 */ - sizeof(GLushort), /* 3 */ - sizeof(GLint), /* 4 */ - sizeof(GLuint), /* 5 */ - sizeof(GLfloat), /* 6 */ - 2 * sizeof(GLbyte), /* 7 */ - 3 * sizeof(GLbyte), /* 8 */ - 4 * sizeof(GLbyte), /* 9 */ - sizeof(GLdouble), /* a */ - 0, /* b */ - 0, /* c */ - 0, /* d */ - 0, /* e */ - 0 /* f */ -}; - - -void -_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_cva *cva; - - cva = &ctx->CVA; - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawElements"); - - if (count <= 0) { - if (count < 0) - gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); - return; - } - - if (mode < 0 || mode > GL_POLYGON) { - gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); - return; - } - - if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT) - { - gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - return; - } - - if (ctx->NewState) - gl_update_state(ctx); - - if (ctx->CompileCVAFlag) - { - /* Treat VERT_ELT like a special client array. - */ - ctx->Array._NewArrayState |= VERT_ELT; - ctx->Array._Summary |= VERT_ELT; - ctx->Array._Flags |= VERT_ELT; - - cva->elt_mode = mode; - cva->elt_count = count; - cva->Elt.Type = type; - cva->Elt.Ptr = (void *) indices; - cva->Elt.StrideB = natural_stride[TYPE_IDX(type)]; - cva->EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)]; - - if (!cva->pre.pipeline_valid) - gl_build_precalc_pipeline( ctx ); - else if (MESA_VERBOSE & VERBOSE_PIPELINE) - fprintf(stderr, ": dont rebuild\n"); - - gl_cva_force_precalc( ctx ); - - /* Did we 'precalculate' the render op? - */ - if (ctx->CVA.pre.ops & PIPE_OP_RENDER) { - ctx->Array._NewArrayState |= VERT_ELT; - ctx->Array._Summary &= ~VERT_ELT; - ctx->Array._Flags &= ~VERT_ELT; - return; - } - - if ( (MESA_VERBOSE&VERBOSE_VARRAY) ) - printf("using immediate\n"); - } - - - /* Otherwise, have to use the immediate path to render. - */ - switch (type) { - case GL_UNSIGNED_BYTE: - { - GLubyte *ub_indices = (GLubyte *) indices; - if (ctx->Array._Summary & VERT_OBJ_ANY) { - draw_elt_ubyte( ctx, mode, ub_indices, count ); - } else { - gl_ArrayElement( ctx, (GLuint) ub_indices[count-1] ); - } - } - break; - case GL_UNSIGNED_SHORT: - { - GLushort *us_indices = (GLushort *) indices; - if (ctx->Array._Summary & VERT_OBJ_ANY) { - draw_elt_ushort( ctx, mode, us_indices, count ); - } else { - gl_ArrayElement( ctx, (GLuint) us_indices[count-1] ); - } - } - break; - case GL_UNSIGNED_INT: - { - GLuint *ui_indices = (GLuint *) indices; - if (ctx->Array._Summary & VERT_OBJ_ANY) { - draw_elt_uint( ctx, mode, ui_indices, count ); - } else { - gl_ArrayElement( ctx, ui_indices[count-1] ); - } - } - break; - default: - gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - break; - } - - if (ctx->CompileCVAFlag) { - ctx->Array._NewArrayState |= VERT_ELT; - ctx->Array._Summary &= ~VERT_ELT; - } -} - - void _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) @@ -1307,81 +692,3 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) -void -_mesa_DrawRangeElements(GLenum mode, GLuint start, - GLuint end, GLsizei count, - GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - - if (end < start) { - gl_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements( end < start )"); - return; - } - -#if 0 - /* - * XXX something in locked arrays is broken! If start = 0, - * end = 1 and count = 2 we'll take the LockArrays path and - * get incorrect results. See Scott McMillan's bug of 3 Jan 2000. - * For now, don't use locked arrays. - */ - if (!ctx->Array.LockCount && 2*count > (GLint) 3*(end-start)) { - glLockArraysEXT( start, end ); - glDrawElements( mode, count, type, indices ); - glUnlockArraysEXT(); - } else { - glDrawElements( mode, count, type, indices ); - } -#else - glDrawElements( mode, count, type, indices ); -#endif -} - - - -void gl_update_client_state( GLcontext *ctx ) -{ - static const GLuint sz_flags[5] = { - 0, - 0, - VERT_OBJ_2, - VERT_OBJ_23, - VERT_OBJ_234 - }; - static const GLuint tc_flags[5] = { - 0, - VERT_TEX0_12, - VERT_TEX0_12, - VERT_TEX0_123, - VERT_TEX0_1234 - }; - GLint i; - - ctx->Array._Flags = 0; - ctx->Array._Summary = 0; - ctx->input->ArrayIncr = 0; - - if (ctx->Array.Normal.Enabled) ctx->Array._Flags |= VERT_NORM; - if (ctx->Array.Color.Enabled) ctx->Array._Flags |= VERT_RGBA; - if (ctx->Array.SecondaryColor.Enabled) ctx->Array._Flags |= VERT_SPEC_RGB; - if (ctx->Array.FogCoord.Enabled) ctx->Array._Flags |= VERT_FOG_COORD; - if (ctx->Array.Index.Enabled) ctx->Array._Flags |= VERT_INDEX; - if (ctx->Array.EdgeFlag.Enabled) ctx->Array._Flags |= VERT_EDGE; - if (ctx->Array.Vertex.Enabled) { - ctx->Array._Flags |= sz_flags[ctx->Array.Vertex.Size]; - ctx->input->ArrayIncr = 1; - } - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (ctx->Array.TexCoord[i].Enabled) { - ctx->Array._Flags |= (tc_flags[ctx->Array.TexCoord[i].Size] << (i * NR_TEXSIZE_BITS)); - } - } - - /* Not really important any more: - */ - ctx->Array._Summary = ctx->Array._Flags & VERT_DATA; - ctx->input->ArrayAndFlags = ~ctx->Array._Flags; - ctx->input->ArrayEltFlush = !(ctx->CompileCVAFlag); -} - diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index 2f42dfabcbd..bc5a679094b 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -1,4 +1,4 @@ -/* $Id: varray.h,v 1.8 2000/10/27 16:44:41 keithw Exp $ */ +/* $Id: varray.h,v 1.9 2000/11/16 21:05:35 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -96,52 +96,8 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, extern void -_mesa_ArrayElement( GLint ); - - -extern void -_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count); - - -extern void -_mesa_save_DrawArrays(GLenum mode, GLint first, GLsizei count); - - -extern void -_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices); - - -extern void -_mesa_save_DrawElements(GLenum mode, GLsizei count, - GLenum type, const GLvoid *indices); - - -extern void _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer); -extern void -_mesa_save_InterleavedArrays(GLenum format, GLsizei stride, - const GLvoid *pointer); - - -extern void -_mesa_DrawRangeElements(GLenum mode, GLuint start, - GLuint end, GLsizei count, GLenum type, - const GLvoid *indices); - -extern void -_mesa_save_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, GLsizei count, - GLenum type, const GLvoid *indices ); - - -extern void gl_exec_array_elements( GLcontext *ctx, - struct immediate *IM, - GLuint start, - GLuint end ); - -extern void gl_update_client_state( GLcontext *ctx ); #endif diff --git a/src/mesa/math/m_clip_tmp.h b/src/mesa/math/m_clip_tmp.h new file mode 100644 index 00000000000..321d3a9e616 --- /dev/null +++ b/src/mesa/math/m_clip_tmp.h @@ -0,0 +1,175 @@ +/* $Id: m_clip_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.1 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +/* KW: a clever asm implementation would nestle integer versions + * of the outcode calculation underneath the division. Gcc won't + * do this, strangely enough, so I only do the divide in + * the case where the cliptest passes. This isn't essential, + * and an asm implementation needn't replicate that behaviour. + */ +static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLfloat *from = (GLfloat *)clip_vec->start; + const GLuint count = clip_vec->count; + GLuint c = 0; + GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; + GLubyte tmpAndMask = *andMask; + GLubyte tmpOrMask = *orMask; + GLuint i; + STRIDE_LOOP { + const GLfloat cx = from[0]; + const GLfloat cy = from[1]; + const GLfloat cz = from[2]; + const GLfloat cw = from[3]; +#if defined(macintosh) + /* on powerpc cliptest is 17% faster in this way. */ + GLuint mask; + mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); + mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); + mask |= (((cw < cy) << CLIP_TOP_SHIFT)); + mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); + mask |= (((cw < cz) << CLIP_FAR_SHIFT)); + mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); +#else /* !defined(macintosh)) */ + GLubyte mask = 0; + if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; + if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; + if (-cy + cw < 0) mask |= CLIP_TOP_BIT; + if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; + if (-cz + cw < 0) mask |= CLIP_FAR_BIT; + if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; +#endif /* defined(macintosh) */ + + clipMask[i] = mask; + if (mask) { + c++; + tmpAndMask &= mask; + tmpOrMask |= mask; + vProj[i][0] = 0; /* no longer required? */ + vProj[i][1] = 0; + vProj[i][2] = 0; + vProj[i][3] = 1; + } else { + GLfloat oow = 1.0F / cw; + vProj[i][3] = oow; + vProj[i][0] = cx * oow; + vProj[i][1] = cy * oow; + vProj[i][2] = cz * oow; + } + } + + *orMask = tmpOrMask; + *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); + + proj_vec->flags |= VEC_SIZE_4; + proj_vec->size = 3; + proj_vec->count = clip_vec->count; + return proj_vec; +} + +static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLuint count = clip_vec->count; + const GLfloat *from = (GLfloat *)clip_vec->start; + + GLubyte tmpOrMask = *orMask; + GLubyte tmpAndMask = *andMask; + GLuint i; + STRIDE_LOOP { + const GLfloat cx = from[0], cy = from[1], cz = from[2]; + GLubyte mask = 0; + if (cx > 1.0) mask |= CLIP_RIGHT_BIT; + else if (cx < -1.0) mask |= CLIP_LEFT_BIT; + if (cy > 1.0) mask |= CLIP_TOP_BIT; + else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT; + if (cz > 1.0) mask |= CLIP_FAR_BIT; + else if (cz < -1.0) mask |= CLIP_NEAR_BIT; + clipMask[i] = mask; + tmpOrMask |= mask; + tmpAndMask &= mask; + } + + gl_vector4f_clean_elem(proj_vec, count, 3); + + *orMask = tmpOrMask; + *andMask = tmpAndMask; + return clip_vec; +} + +static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLuint count = clip_vec->count; + const GLfloat *from = (GLfloat *)clip_vec->start; + + GLubyte tmpOrMask = *orMask; + GLubyte tmpAndMask = *andMask; + GLuint i; + STRIDE_LOOP { + const GLfloat cx = from[0], cy = from[1]; + GLubyte mask = 0; + if (cx > 1.0) mask |= CLIP_RIGHT_BIT; + else if (cx < -1.0) mask |= CLIP_LEFT_BIT; + if (cy > 1.0) mask |= CLIP_TOP_BIT; + else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT; + clipMask[i] = mask; + tmpOrMask |= mask; + tmpAndMask &= mask; + } + + gl_vector4f_clean_elem(proj_vec, count, 3); + + *orMask = tmpOrMask; + *andMask = tmpAndMask; + return clip_vec; +} + + +static void TAG(init_c_cliptest)( void ) +{ + gl_clip_tab[4] = TAG(cliptest_points4); + gl_clip_tab[3] = TAG(cliptest_points3); + gl_clip_tab[2] = TAG(cliptest_points2); +} diff --git a/src/mesa/math/m_copy_tmp.h b/src/mesa/math/m_copy_tmp.h new file mode 100644 index 00000000000..b328537fafa --- /dev/null +++ b/src/mesa/math/m_copy_tmp.h @@ -0,0 +1,126 @@ +/* $Id: m_copy_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.1 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +#define COPY_FUNC( BITS ) \ +static void TAG2(copy, BITS)(GLvector4f *to, const GLvector4f *f, \ + const GLubyte mask[] ) \ +{ \ + GLfloat (*t)[4] = (GLfloat (*)[4])to->start; \ + GLfloat *from = f->start; \ + GLuint stride = f->stride; \ + GLuint count = f->count; \ + GLuint i; \ + (void) mask; \ + \ + if (BITS) \ + STRIDE_LOOP { \ + CULL_CHECK { \ + if (BITS&1) t[i][0] = from[0]; \ + if (BITS&2) t[i][1] = from[1]; \ + if (BITS&4) t[i][2] = from[2]; \ + if (BITS&8) t[i][3] = from[3]; \ + } \ + } \ +} + + + +/* static void TAG2(clean, BITS)(GLvector4f *to ) */ +/* { */ +/* GLfloat (*t)[4] = to->data; */ +/* GLuint i; */ + +/* if (BITS) */ +/* for (i = 0 ; i < VB_SIZE ; i++) { */ +/* if (BITS&1) t[i][0] = 0; */ +/* if (BITS&2) t[i][1] = 0; */ +/* if (BITS&4) t[i][2] = 0; */ +/* if (BITS&8) t[i][3] = 1; */ +/* } */ +/* to->flags &= ~BITS; */ +/* } */ + + +/* We got them all here: + */ +COPY_FUNC( 0x0 ) /* noop */ +COPY_FUNC( 0x1 ) +COPY_FUNC( 0x2 ) +COPY_FUNC( 0x3 ) +COPY_FUNC( 0x4 ) +COPY_FUNC( 0x5 ) +COPY_FUNC( 0x6 ) +COPY_FUNC( 0x7 ) +COPY_FUNC( 0x8 ) +COPY_FUNC( 0x9 ) +COPY_FUNC( 0xa ) +COPY_FUNC( 0xb ) +COPY_FUNC( 0xc ) +COPY_FUNC( 0xd ) +COPY_FUNC( 0xe ) +COPY_FUNC( 0xf ) + +static void TAG2(init_copy, 0 ) ( void ) +{ + gl_copy_tab[IDX][0x0] = TAG2(copy, 0x0); + gl_copy_tab[IDX][0x1] = TAG2(copy, 0x1); + gl_copy_tab[IDX][0x2] = TAG2(copy, 0x2); + gl_copy_tab[IDX][0x3] = TAG2(copy, 0x3); + gl_copy_tab[IDX][0x4] = TAG2(copy, 0x4); + gl_copy_tab[IDX][0x5] = TAG2(copy, 0x5); + gl_copy_tab[IDX][0x6] = TAG2(copy, 0x6); + gl_copy_tab[IDX][0x7] = TAG2(copy, 0x7); + gl_copy_tab[IDX][0x8] = TAG2(copy, 0x8); + gl_copy_tab[IDX][0x9] = TAG2(copy, 0x9); + gl_copy_tab[IDX][0xa] = TAG2(copy, 0xa); + gl_copy_tab[IDX][0xb] = TAG2(copy, 0xb); + gl_copy_tab[IDX][0xc] = TAG2(copy, 0xc); + gl_copy_tab[IDX][0xd] = TAG2(copy, 0xd); + gl_copy_tab[IDX][0xe] = TAG2(copy, 0xe); + gl_copy_tab[IDX][0xf] = TAG2(copy, 0xf); + +/* gl_clean_tab[IDX][0x0] = TAG2(clean, 0x0); */ +/* gl_clean_tab[IDX][0x1] = TAG2(clean, 0x1); */ +/* gl_clean_tab[IDX][0x2] = TAG2(clean, 0x2); */ +/* gl_clean_tab[IDX][0x3] = TAG2(clean, 0x3); */ +/* gl_clean_tab[IDX][0x4] = TAG2(clean, 0x4); */ +/* gl_clean_tab[IDX][0x5] = TAG2(clean, 0x5); */ +/* gl_clean_tab[IDX][0x6] = TAG2(clean, 0x6); */ +/* gl_clean_tab[IDX][0x7] = TAG2(clean, 0x7); */ +/* gl_clean_tab[IDX][0x8] = TAG2(clean, 0x8); */ +/* gl_clean_tab[IDX][0x9] = TAG2(clean, 0x9); */ +/* gl_clean_tab[IDX][0xa] = TAG2(clean, 0xa); */ +/* gl_clean_tab[IDX][0xb] = TAG2(clean, 0xb); */ +/* gl_clean_tab[IDX][0xc] = TAG2(clean, 0xc); */ +/* gl_clean_tab[IDX][0xd] = TAG2(clean, 0xd); */ +/* gl_clean_tab[IDX][0xe] = TAG2(clean, 0xe); */ +/* gl_clean_tab[IDX][0xf] = TAG2(clean, 0xf); */ +} diff --git a/src/mesa/math/m_debug_xform.c b/src/mesa/math/m_debug_xform.c new file mode 100644 index 00000000000..5041fc4ee07 --- /dev/null +++ b/src/mesa/math/m_debug_xform.c @@ -0,0 +1,930 @@ +/* $Id: m_debug_xform.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Updated for P6 architecture by Gareth Hughes. + */ + +#include "glheader.h" +#include "context.h" +#include "mem.h" + +#include "m_debug_xform.h" +#include "m_matrix.h" +#include "m_xform.h" + + +#ifdef DEBUG /* This code only used for debugging */ + + +/* Comment this out to deactivate the cycle counter. + * NOTE: it works only on CPUs which know the 'rdtsc' command (586 or higher) + * (hope, you don't try to debug Mesa on a 386 ;) + */ +#if defined(__GNUC__) && defined(__i386__) && defined(USE_X86_ASM) +#define RUN_XFORM_BENCHMARK +#endif + +#define TEST_COUNT 128 /* size of the tested vector array */ + +#define REQUIRED_PRECISION 10 /* allow 4 bits to miss */ +#define MAX_PRECISION 24 /* max. precision possible */ + + +#ifdef RUN_XFORM_BENCHMARK +/* Overhead of profiling counter in cycles. Automatically adjusted to + * your machine at run time - counter initialization should give very + * consistent results. + */ +static int need_counter = 1; +static long counter_overhead = 0; + +/* Modify the the number of tests if you like. + * We take the minimum of all results, because every error should be + * positive (time used by other processes, task switches etc). + * It is assumed that all calculations are done in the cache. + */ + +#if 1 /* PPro, PII, PIII version */ + +/* Profiling on the P6 architecture requires a little more work, due to + * the internal out-of-order execution. We must perform a serializing + * 'cpuid' instruction before and after the 'rdtsc' instructions to make + * sure no other uops are executed when we sample the timestamp counter. + */ +#define INIT_COUNTER() \ + do { \ + int cycle_i; \ + counter_overhead = LONG_MAX; \ + for ( cycle_i = 0 ; cycle_i < 4 ; cycle_i++ ) { \ + long cycle_tmp1 = 0, cycle_tmp2 = 0; \ + __asm__ ( "push %%ebx \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "rdtsc \n" \ + "mov %%eax, %0 \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "pop %%ebx \n" \ + "push %%ebx \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "rdtsc \n" \ + "mov %%eax, %1 \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "pop %%ebx \n" \ + : "=m" (cycle_tmp1), "=m" (cycle_tmp2) \ + : : "eax", "ecx", "edx" ); \ + if ( counter_overhead > (cycle_tmp2 - cycle_tmp1) ) { \ + counter_overhead = cycle_tmp2 - cycle_tmp1; \ + } \ + } \ + } while (0) + +#define BEGIN_RACE(x) \ + x = LONG_MAX; \ + for ( cycle_i = 0 ; cycle_i < 10 ; cycle_i++ ) { \ + long cycle_tmp1 = 0, cycle_tmp2 = 0; \ + __asm__ ( "push %%ebx \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "rdtsc \n" \ + "mov %%eax, %0 \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "pop %%ebx \n" \ + : "=m" (cycle_tmp1) \ + : : "eax", "ecx", "edx" ); + +#define END_RACE(x) \ + __asm__ ( "push %%ebx \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "rdtsc \n" \ + "mov %%eax, %0 \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "pop %%ebx \n" \ + : "=m" (cycle_tmp2) \ + : : "eax", "ecx", "edx" ); \ + if ( x > (cycle_tmp2 - cycle_tmp1) ) { \ + x = cycle_tmp2 - cycle_tmp1; \ + } \ + } \ + x -= counter_overhead; + +#else /* PPlain, PMMX version */ + +/* To ensure accurate results, we stall the pipelines with the + * non-pairable 'cdq' instruction. This ensures all the code being + * profiled is complete when the 'rdtsc' instruction executes. + */ +#define INIT_COUNTER(x) \ + do { \ + int cycle_i; \ + x = LONG_MAX; \ + for ( cycle_i = 0 ; cycle_i < 32 ; cycle_i++ ) { \ + long cycle_tmp1, cycle_tmp2, dummy; \ + __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp1) ); \ + __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp2) ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "rdtsc" : "=a" (cycle_tmp1), "=d" (dummy) ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "rdtsc" : "=a" (cycle_tmp2), "=d" (dummy) ); \ + if ( x > (cycle_tmp2 - cycle_tmp1) ) \ + x = cycle_tmp2 - cycle_tmp1; \ + } \ + } while (0) + +#define BEGIN_RACE(x) \ + x = LONG_MAX; \ + for ( cycle_i = 0 ; cycle_i < 16 ; cycle_i++ ) { \ + long cycle_tmp1, cycle_tmp2, dummy; \ + __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp1) ); \ + __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp2) ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "rdtsc" : "=a" (cycle_tmp1), "=d" (dummy) ); + + +#define END_RACE(x) \ + __asm__ ( "cdq" ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "rdtsc" : "=a" (cycle_tmp2), "=d" (dummy) ); \ + if ( x > (cycle_tmp2 - cycle_tmp1) ) \ + x = cycle_tmp2 - cycle_tmp1; \ + } \ + x -= counter_overhead; + +#endif + +#else + +#define BEGIN_RACE(x) +#define END_RACE(x) + +#endif + + +static char *mesa_profile = NULL; + + +enum { NIL=0, ONE=1, NEG=-1, VAR=2 }; + +static int m_general[16] = { + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR +}; +static int m_identity[16] = { + ONE, NIL, NIL, NIL, + NIL, ONE, NIL, NIL, + NIL, NIL, ONE, NIL, + NIL, NIL, NIL, ONE +}; +static int m_2d[16] = { + VAR, VAR, NIL, VAR, + VAR, VAR, NIL, VAR, + NIL, NIL, ONE, NIL, + NIL, NIL, NIL, ONE +}; +static int m_2d_no_rot[16] = { + VAR, NIL, NIL, VAR, + NIL, VAR, NIL, VAR, + NIL, NIL, ONE, NIL, + NIL, NIL, NIL, ONE +}; +static int m_3d[16] = { + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR, + NIL, NIL, NIL, ONE +}; +static int m_3d_no_rot[16] = { + VAR, NIL, NIL, VAR, + NIL, VAR, NIL, VAR, + NIL, NIL, VAR, VAR, + NIL, NIL, NIL, ONE +}; +static int m_perspective[16] = { + VAR, NIL, VAR, NIL, + NIL, VAR, VAR, NIL, + NIL, NIL, VAR, VAR, + NIL, NIL, NEG, NIL +}; +static int *templates[7] = { + m_general, + m_identity, + m_3d_no_rot, + m_perspective, + m_2d, + m_2d_no_rot, + m_3d +}; +static int mtypes[7] = { + MATRIX_GENERAL, + MATRIX_IDENTITY, + MATRIX_3D_NO_ROT, + MATRIX_PERSPECTIVE, + MATRIX_2D, + MATRIX_2D_NO_ROT, + MATRIX_3D +}; +static char *mstrings[7] = { + "MATRIX_GENERAL", + "MATRIX_IDENTITY", + "MATRIX_3D_NO_ROT", + "MATRIX_PERSPECTIVE", + "MATRIX_2D", + "MATRIX_2D_NO_ROT", + "MATRIX_3D" +}; + + + +static int m_norm_identity[16] = { + ONE, NIL, NIL, NIL, + NIL, ONE, NIL, NIL, + NIL, NIL, ONE, NIL, + NIL, NIL, NIL, NIL +}; +static int m_norm_general[16] = { + VAR, VAR, VAR, NIL, + VAR, VAR, VAR, NIL, + VAR, VAR, VAR, NIL, + NIL, NIL, NIL, NIL +}; +static int m_norm_no_rot[16] = { + VAR, NIL, NIL, NIL, + NIL, VAR, NIL, NIL, + NIL, NIL, VAR, NIL, + NIL, NIL, NIL, NIL +}; +static int *norm_templates[8] = { + m_norm_no_rot, + m_norm_no_rot, + m_norm_no_rot, + m_norm_general, + m_norm_general, + m_norm_general, + m_norm_identity, + m_norm_identity +}; +static int norm_types[8] = { + NORM_TRANSFORM_NO_ROT, + NORM_TRANSFORM_NO_ROT | NORM_RESCALE, + NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE, + NORM_TRANSFORM, + NORM_TRANSFORM | NORM_RESCALE, + NORM_TRANSFORM | NORM_NORMALIZE, + NORM_RESCALE, + NORM_NORMALIZE +}; +static int norm_scale_types[8] = { /* rescale factor */ + NIL, /* NIL disables rescaling */ + VAR, + NIL, + NIL, + VAR, + NIL, + VAR, + NIL +}; +static int norm_normalize_types[8] = { /* normalizing ?? (no = 0) */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1 +}; +static char *norm_strings[8] = { + "NORM_TRANSFORM_NO_ROT", + "NORM_TRANSFORM_NO_ROT | NORM_RESCALE", + "NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE", + "NORM_TRANSFORM", + "NORM_TRANSFORM | NORM_RESCALE", + "NORM_TRANSFORM | NORM_NORMALIZE", + "NORM_RESCALE", + "NORM_NORMALIZE" +}; + + + +/* ================================================================ + * Helper functions + */ + +static GLfloat rnd( void ) +{ + GLfloat f = (GLfloat)rand() / (GLfloat)RAND_MAX; + GLfloat gran = (GLfloat)(1 << 13); + + f = (GLfloat)(GLint)(f * gran) / gran; + + return f * 2.0 - 1.0; +} + +static int significand_match( GLfloat a, GLfloat b ) +{ + GLfloat d = a - b; + int a_ex, b_ex, d_ex; + + if ( d == 0.0F ) { + return MAX_PRECISION; /* Exact match */ + } + + if ( a == 0.0F || b == 0.0F ) { + /* It would probably be better to check if the + * non-zero number is denormalized and return + * the index of the highest set bit here. + */ + return 0; + } + + frexp( a, &a_ex ); + frexp( b, &b_ex ); + frexp( d, &d_ex ); + + if ( a_ex < b_ex ) + return a_ex - d_ex; + else + return b_ex - d_ex; +} + + + +/* ================================================================ + * Reference transformations + */ + +static void ref_transform( GLvector4f *dst, + const GLmatrix *mat, + const GLvector4f *src, + const GLubyte *clipmask, + const GLubyte flag ) +{ + int i; + GLfloat *s = (GLfloat *)src->start; + GLfloat (*d)[4] = (GLfloat (*)[4])dst->start; + const GLfloat *m = mat->m; + + (void) clipmask; + (void) flag; + + for ( i = 0 ; i < src->count ; i++ ) { + GLfloat x = s[0], y = s[1], z = s[2], w = s[3]; + d[i][0] = m[0]*x + m[4]*y + m[ 8]*z + m[12]*w; + d[i][1] = m[1]*x + m[5]*y + m[ 9]*z + m[13]*w; + d[i][2] = m[2]*x + m[6]*y + m[10]*z + m[14]*w; + d[i][3] = m[3]*x + m[7]*y + m[11]*z + m[15]*w; + s = (GLfloat *)((char *)s + src->stride); + } +} + +static void ref_norm_transform_rescale( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + int i; + const GLfloat *s = in->start; + const GLfloat *m = mat->inv; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + + (void) mask; + (void) lengths; + + for ( i = 0 ; i < in->count ; i++ ) { + GLfloat x = s[0], y = s[1], z = s[2] ; + GLfloat tx = m[0]*x + m[1]*y + m[ 2]*z ; + GLfloat ty = m[4]*x + m[5]*y + m[ 6]*z ; + GLfloat tz = m[8]*x + m[9]*y + m[10]*z ; + + out[i][0] = tx * scale; + out[i][1] = ty * scale; + out[i][2] = tz * scale; + + s = (GLfloat *)((char *)s + in->stride); + } +} + +static void ref_norm_transform_normalize( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + int i; + const GLfloat *s = in->start; + const GLfloat *m = mat->inv; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + + (void) mask; + + for ( i = 0 ; i < in->count ; i++ ) { + GLfloat x = s[0], y = s[1], z = s[2] ; + GLfloat tx = m[0]*x + m[1]*y + m[ 2]*z ; + GLfloat ty = m[4]*x + m[5]*y + m[ 6]*z ; + GLfloat tz = m[8]*x + m[9]*y + m[10]*z ; + + if ( !lengths ) { + GLfloat len = tx*tx + ty*ty + tz*tz; + if ( len > 1e-20 ) { + /* Hmmm, don't know how we could test the precalculated + * length case... + */ + scale = 1.0 / sqrt( len ); + out[i][0] = tx * scale; + out[i][1] = ty * scale; + out[i][2] = tz * scale; + } else { + out[i][0] = out[i][1] = out[i][2] = 0; + } + } else { + scale = lengths[i];; + out[i][0] = tx * scale; + out[i][1] = ty * scale; + out[i][2] = tz * scale; + } + + s = (GLfloat *)((char *)s + in->stride); + } +} + + + +/* ================================================================ + * Vertex transformation tests + */ + +/* Ensure our arrays are correctly aligned. + */ +#if defined(__GNUC__) +#define ALIGN16(x) x __attribute__ ((aligned (16))) +#else +#define ALIGN16(x) x +#endif +static GLfloat ALIGN16(s[TEST_COUNT][5]); +static GLfloat ALIGN16(d[TEST_COUNT][4]); +static GLfloat ALIGN16(r[TEST_COUNT][4]); + +static int test_transform_function( transform_func func, int psize, int mtype, + int masked, long *cycles ) +{ + GLvector4f source[1], dest[1], ref[1]; + GLmatrix mat[1]; + GLfloat *m; + GLubyte mask[TEST_COUNT]; + int i, j; +#ifdef RUN_XFORM_BENCHMARK + int cycle_i; /* the counter for the benchmarks we run */ +#endif + + (void) cycles; + + if ( psize > 4 ) { + gl_problem( NULL, "test_transform_function called with psize > 4\n" ); + return 0; + } + + mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + mat->type = mtypes[mtype]; + + m = mat->m; + + m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0; + m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] = 7.0; + m[2] = 44.0; m[6] = 9.0; m[10] = 7.0; m[14] = 3.0; + m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] = 9.0; + + for ( i = 0 ; i < 4 ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + switch ( templates[mtype][i * 4 + j] ) { + case NIL: + m[j * 4 + i] = 0.0; + break; + case ONE: + m[j * 4 + i] = 1.0; + break; + case NEG: + m[j * 4 + i] = -1.0; + break; + case VAR: + break; + default: + abort(); + } + } + } + + for ( i = 0 ; i < TEST_COUNT ; i++) { + mask[i] = i % 2; /* mask every 2nd element */ + d[i][0] = s[i][0] = 0.0; + d[i][1] = s[i][1] = 0.0; + d[i][2] = s[i][2] = 0.0; + d[i][3] = s[i][3] = 1.0; + for ( j = 0 ; j < psize ; j++ ) + s[i][j] = rnd(); + } + + source->data = (GLfloat(*)[4])s; + source->start = (GLfloat *)s; + source->count = TEST_COUNT; + source->stride = sizeof(s[0]); + source->size = 4; + source->flags = 0; + + dest->data = (GLfloat(*)[4])d; + dest->start = (GLfloat *)d; + dest->count = TEST_COUNT; + dest->stride = sizeof(float[4]); + dest->size = 0; + dest->flags = 0; + + ref->data = (GLfloat(*)[4])r; + ref->start = (GLfloat *)r; + ref->count = TEST_COUNT; + ref->stride = sizeof(float[4]); + ref->size = 0; + ref->flags = 0; + + ref_transform( ref, mat, source, NULL, 0 ); + + if ( mesa_profile ) { + if ( masked ) { + BEGIN_RACE( *cycles ); + func( dest, mat->m, source, mask, 1 ); + END_RACE( *cycles ); + } else { + BEGIN_RACE( *cycles ); + func( dest, mat->m, source, NULL, 0 ); + END_RACE( *cycles ); + } + } + else { + if ( masked ) { + func( dest, mat->m, source, mask, 1 ); + } else { + func( dest, mat->m, source, NULL, 0 ); + } + } + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + if ( masked && (mask[i] & 1) ) + continue; + + for ( j = 0 ; j < 4 ; j++ ) { + if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { + printf( "-----------------------------\n" ); + printf( "(i = %i, j = %i)\n", i, j ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][0], r[i][0], r[i][0]-d[i][0], + MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][1], r[i][1], r[i][1]-d[i][1], + MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][2], r[i][2], r[i][2]-d[i][2], + MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][3], r[i][3], r[i][3]-d[i][3], + MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); + return 0; + } + } + } + + ALIGN_FREE( mat->m ); + return 1; +} + +void gl_test_all_transform_functions( char *description ) +{ + int masked, psize, mtype; + long benchmark_tab[2][4][7]; + static int first_time = 1; + + if ( first_time ) { + first_time = 0; + mesa_profile = getenv( "MESA_PROFILE" ); + } + +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) { + if ( need_counter ) { + need_counter = 0; + INIT_COUNTER(); + printf( "counter overhead: %ld cycles\n\n", counter_overhead ); + } + printf( "transform results after hooking in %s functions:\n", description ); + } +#endif + + for ( masked = 0 ; masked <= 1 ; masked++ ) { + int cma = masked ? 1 : 0; + char *cmastring = masked ? "CULL_MASK_ACTIVE" : "0"; + +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) { + printf( "\n culling: %s \n", masked ? "CULL_MASK_ACTIVE" : "0" ); + for ( psize = 1 ; psize <= 4 ; psize++ ) { + printf( " p%d\t", psize ); + } + printf( "\n--------------------------------------------------------\n" ); + } +#endif + + for ( mtype = 0 ; mtype < 7 ; mtype++ ) { + for ( psize = 1 ; psize <= 4 ; psize++ ) { + transform_func func = gl_transform_tab[cma][psize][mtypes[mtype]]; + long *cycles = &(benchmark_tab[cma][psize-1][mtype]); + + if ( test_transform_function( func, psize, mtype, + masked, cycles ) == 0 ) { + char buf[100]; + sprintf( buf, "gl_transform_tab[%s][%d][%s] failed test (%s)", + cmastring, psize, mstrings[mtype], description ); + gl_problem( NULL, buf ); + } +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) + printf( " %li\t", benchmark_tab[cma][psize-1][mtype] ); +#endif + } +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) + printf( " | [%s]\n", mstrings[mtype] ); +#endif + } +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) + printf( "\n" ); +#endif + } +} + + + +/* ================================================================ + * Normal transformation tests + */ + +static int test_norm_function( normal_func func, int mtype, + int masked, long *cycles ) +{ + GLvector3f source[1], dest[1], dest2[1], ref[1], ref2[1]; + GLmatrix mat[1]; + GLfloat s[TEST_COUNT][5], d[TEST_COUNT][3], r[TEST_COUNT][3]; + GLfloat d2[TEST_COUNT][3], r2[TEST_COUNT][3], length[TEST_COUNT]; + GLfloat scale; + GLfloat *m; + GLubyte mask[TEST_COUNT]; + int i, j; +#ifdef RUN_XFORM_BENCHMARK + int cycle_i; /* the counter for the benchmarks we run */ +#endif + + (void) cycles; + + mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + mat->inv = m = mat->m; + + m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0; + m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] = 7.0; + m[2] = 44.0; m[6] = 9.0; m[10] = 7.0; m[14] = 3.0; + m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] = 9.0; + + scale = 1.0F + rnd () * norm_scale_types[mtype]; + + for ( i = 0 ; i < 4 ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + switch ( norm_templates[mtype][i * 4 + j] ) { + case NIL: + m[j * 4 + i] = 0.0; + break; + case ONE: + m[j * 4 + i] = 1.0; + break; + case NEG: + m[j * 4 + i] = -1.0; + break; + case VAR: + break; + default: + abort(); + } + } + } + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + mask[i] = i % 2; /* mask every 2nd element */ + d[i][0] = s[i][0] = d2[i][0] = 0.0; + d[i][1] = s[i][1] = d2[i][1] = 0.0; + d[i][2] = s[i][2] = d2[i][2] = 0.0; + for ( j = 0 ; j < 3 ; j++ ) + s[i][j] = rnd(); + length[i] = 1 / sqrt( s[i][0]*s[i][0] + + s[i][1]*s[i][1] + + s[i][2]*s[i][2] ); + } + + source->data = (GLfloat(*)[3])s; + source->start = (GLfloat *)s; + source->count = TEST_COUNT; + source->stride = sizeof(s[0]); + source->flags = 0; + + dest->data = (GLfloat(*)[3])d; + dest->start = (GLfloat *)d; + dest->count = TEST_COUNT; + dest->stride = sizeof(float[3]); + dest->flags = 0; + + dest2->data = (GLfloat(*)[3])d2; + dest2->start = (GLfloat *)d2; + dest2->count = TEST_COUNT; + dest2->stride = sizeof(float[3]); + dest2->flags = 0; + + ref->data = (GLfloat(*)[3])r; + ref->start = (GLfloat *)r; + ref->count = TEST_COUNT; + ref->stride = sizeof(float[3]); + ref->flags = 0; + + ref2->data = (GLfloat(*)[3])r2; + ref2->start = (GLfloat *)r2; + ref2->count = TEST_COUNT; + ref2->stride = sizeof(float[3]); + ref2->flags = 0; + + if ( norm_normalize_types[mtype] == 0 ) { + ref_norm_transform_rescale( mat, scale, source, NULL, NULL, ref ); + } else { + ref_norm_transform_normalize( mat, scale, source, NULL, NULL, ref ); + ref_norm_transform_normalize( mat, scale, source, length, NULL, ref2 ); + } + + if ( mesa_profile ) { + if ( masked ) { + BEGIN_RACE( *cycles ); + func( mat, scale, source, NULL, mask, dest ); + END_RACE( *cycles ); + func( mat, scale, source, length, mask, dest2 ); + } else { + BEGIN_RACE( *cycles ); + func( mat, scale, source, NULL, NULL, dest ); + END_RACE( *cycles ); + func( mat, scale, source, length, NULL, dest2 ); + } + } else { + if ( masked ) { + func( mat, scale, source, NULL, mask, dest ); + func( mat, scale, source, length, mask, dest2 ); + } else { + func( mat, scale, source, NULL, NULL, dest ); + func( mat, scale, source, length, NULL, dest2 ); + } + } + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + if ( masked && !(mask[i] & 1) ) + continue; + + for ( j = 0 ; j < 3 ; j++ ) { + if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { + printf( "-----------------------------\n" ); + printf( "(i = %i, j = %i)\n", i, j ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d[i][0], r[i][0], r[i][0]/d[i][0], + MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d[i][1], r[i][1], r[i][1]/d[i][1], + MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d[i][2], r[i][2], r[i][2]/d[i][2], + MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); + return 0; + } + + if ( norm_normalize_types[mtype] != 0 ) { + if ( significand_match( d2[i][j], r2[i][j] ) < REQUIRED_PRECISION ) { + printf( "------------------- precalculated length case ------\n" ); + printf( "(i = %i, j = %i)\n", i, j ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d2[i][0], r2[i][0], r2[i][0]/d2[i][0], + MAX_PRECISION - significand_match( d2[i][0], r2[i][0] ) ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d2[i][1], r2[i][1], r2[i][1]/d2[i][1], + MAX_PRECISION - significand_match( d2[i][1], r2[i][1] ) ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d2[i][2], r2[i][2], r2[i][2]/d2[i][2], + MAX_PRECISION - significand_match( d2[i][2], r2[i][2] ) ); + return 0; + } + } + } + } + + ALIGN_FREE( mat->m ); + return 1; +} + +void gl_test_all_normal_transform_functions( char *description ) +{ + int masked; + int mtype; + long benchmark_tab[0xf][0x4]; + static int first_time = 1; + + if ( first_time ) { + first_time = 0; + mesa_profile = getenv( "MESA_PROFILE" ); + } + +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) { + if ( need_counter ) { + need_counter = 0; + INIT_COUNTER(); + printf( "counter overhead: %ld cycles\n\n", counter_overhead ); + } + printf( "normal transform results after hooking in %s functions:\n", + description ); + } +#endif + + for ( masked = 0 ; masked <= 1 ; masked++ ) { + int cma = masked ? 1 : 0; + char *cmastring = masked ? "CULL_MASK_ACTIVE" : "0"; + +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) { + printf( "\n culling: %s \n", masked ? "CULL_MASK_ACTIVE" : "0" ); + printf( "\n-------------------------------------------------------\n" ); + } +#endif + + for ( mtype = 0 ; mtype < 8 ; mtype++ ) { + normal_func func = gl_normal_tab[norm_types[mtype]][cma]; + long *cycles = &(benchmark_tab[mtype][cma]); + + if ( test_norm_function( func, mtype, masked, cycles ) == 0 ) { + char buf[100]; + sprintf( buf, "gl_normal_tab[%s][%s] failed test (%s)", + cmastring, norm_strings[mtype], description ); + gl_problem( NULL, buf ); + } + +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) { + printf( " %li\t", benchmark_tab[mtype][cma] ); + printf( " | [%s]\n", norm_strings[mtype] ); + } + } + if ( mesa_profile ) + printf( "\n" ); +#else + } +#endif + } +#ifdef RUN_XFORM_BENCHMARK + if ( mesa_profile ) + fflush( stdout ); +#endif +} + +#endif /* DEBUG */ diff --git a/src/mesa/math/m_dotprod_tmp.h b/src/mesa/math/m_dotprod_tmp.h new file mode 100644 index 00000000000..637e35fd587 --- /dev/null +++ b/src/mesa/math/m_dotprod_tmp.h @@ -0,0 +1,128 @@ +/* $Id: m_dotprod_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.1 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +/* Note - respects the stride of the output vector. + */ +static void TAG(dotprod_vec2)( GLvector4f *out_vec, + GLuint elt, + const GLvector4f *coord_vec, + const GLfloat plane[4], + const GLubyte mask[]) +{ + GLuint stride = coord_vec->stride; + GLfloat *coord = coord_vec->start; + GLuint count = coord_vec->count; + + GLuint outstride = out_vec->stride; + GLfloat *out = out_vec->start + elt; + GLuint i; + + const GLfloat plane0 = plane[0], plane1 = plane[1], plane3 = plane[3]; + + (void) mask; + + for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { + CULL_CHECK { + *out = (coord[0] * plane0 + + coord[1] * plane1 + + plane3); + } + } + out_vec->count = coord_vec->count; +} + +static void TAG(dotprod_vec3)( GLvector4f *out_vec, + GLuint elt, + const GLvector4f *coord_vec, + const GLfloat plane[4], + const GLubyte mask[]) +{ + GLuint stride = coord_vec->stride; + GLfloat *coord = coord_vec->start; + GLuint count = coord_vec->count; + + GLuint outstride = out_vec->stride; + GLfloat *out = out_vec->start + elt; + GLuint i; + + const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; + const GLfloat plane3 = plane[3]; + + (void) mask; + + for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { + CULL_CHECK { + *out = (coord[0] * plane0 + + coord[1] * plane1 + + coord[2] * plane2 + + plane3); + } + } + out_vec->count = coord_vec->count; +} + +static void TAG(dotprod_vec4)( GLvector4f *out_vec, + GLuint elt, + const GLvector4f *coord_vec, + const GLfloat plane[4], + const GLubyte mask[]) +{ + GLuint stride = coord_vec->stride; + GLfloat *coord = coord_vec->start; + GLuint count = coord_vec->count; + + GLuint outstride = out_vec->stride; + GLfloat *out = out_vec->start + elt; + GLuint i; + + const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; + const GLfloat plane3 = plane[3]; + + (void) mask; + + for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { + CULL_CHECK { + *out = (coord[0] * plane0 + + coord[1] * plane1 + + coord[2] * plane2 + + coord[3] * plane3); + } + } + out_vec->count = coord_vec->count; +} + + +static void TAG(init_dotprod)( void ) +{ + gl_dotprod_tab[IDX&1][2] = TAG(dotprod_vec2); + gl_dotprod_tab[IDX&1][3] = TAG(dotprod_vec3); + gl_dotprod_tab[IDX&1][4] = TAG(dotprod_vec4); +} diff --git a/src/mesa/math/m_matrix.c b/src/mesa/math/m_matrix.c new file mode 100644 index 00000000000..ae55c946d9c --- /dev/null +++ b/src/mesa/math/m_matrix.c @@ -0,0 +1,1113 @@ +/* $Id: m_matrix.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * Matrix operations + * + * NOTES: + * 1. 4x4 transformation matrices are stored in memory in column major order. + * 2. Points/vertices are to be thought of as column vectors. + * 3. Transformation of a point p by a matrix M is: p' = M * p + */ + + +#include "glheader.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" + +#include "m_matrix.h" + + +static const char *types[] = { + "MATRIX_GENERAL", + "MATRIX_IDENTITY", + "MATRIX_3D_NO_ROT", + "MATRIX_PERSPECTIVE", + "MATRIX_2D", + "MATRIX_2D_NO_ROT", + "MATRIX_3D" +}; + + +static GLfloat Identity[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 +}; + + + + +/* + * This matmul was contributed by Thomas Malik + * + * Perform a 4x4 matrix multiplication (product = a x b). + * Input: a, b - matrices to multiply + * Output: product - product of a and b + * WARNING: (product != b) assumed + * NOTE: (product == a) allowed + * + * KW: 4*16 = 64 muls + */ +#define A(row,col) a[(col<<2)+row] +#define B(row,col) b[(col<<2)+row] +#define P(row,col) product[(col<<2)+row] + +static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b ) +{ + GLint i; + for (i = 0; i < 4; i++) { + const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); + } +} + + +/* Multiply two matrices known to occupy only the top three rows, such + * as typical model matrices, and ortho matrices. + */ +static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b ) +{ + GLint i; + for (i = 0; i < 3; i++) { + const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3; + } + P(3,0) = 0; + P(3,1) = 0; + P(3,2) = 0; + P(3,3) = 1; +} + + +#undef A +#undef B +#undef P + + +/* + * Multiply a matrix by an array of floats with known properties. + */ +static void matrix_multf( GLmatrix *mat, const GLfloat *m, GLuint flags ) +{ + mat->flags |= (flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE); + + if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) + matmul34( mat->m, mat->m, m ); + else + matmul4( mat->m, mat->m, m ); +} + + +static void print_matrix_floats( const GLfloat m[16] ) +{ + int i; + for (i=0;i<4;i++) { + fprintf(stderr,"\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] ); + } +} + +void +_math_matrix_print( const GLmatrix *m ) +{ + fprintf(stderr, "Matrix type: %s, flags: %x\n", types[m->type], m->flags); + print_matrix_floats(m->m); + fprintf(stderr, "Inverse: \n"); + if (m->inv) { + GLfloat prod[16]; + print_matrix_floats(m->inv); + matmul4(prod, m->m, m->inv); + fprintf(stderr, "Mat * Inverse:\n"); + print_matrix_floats(prod); + } + else { + fprintf(stderr, " - not available\n"); + } +} + + + + +#define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; } +#define MAT(m,r,c) (m)[(c)*4+(r)] + +/* + * Compute inverse of 4x4 transformation matrix. + * Code contributed by Jacques Leroy [email protected] + * 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 ([email protected]) */ + GLfloat mag, s, c; + GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c; + GLfloat m[16]; + + s = sin( angle * DEG2RAD ); + c = cos( angle * DEG2RAD ); + + mag = GL_SQRT( x*x + y*y + z*z ); + + if (mag <= 1.0e-4) { + /* generate an identity matrix and return */ + MEMCPY(m, Identity, sizeof(GLfloat)*16); + return; + } + + x /= mag; + y /= mag; + z /= mag; + +#define M(row,col) m[col*4+row] + + /* + * Arbitrary axis rotation matrix. + * + * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied + * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation + * (which is about the X-axis), and the two composite transforms + * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary + * from the arbitrary axis to the X-axis then back. They are + * all elementary rotations. + * + * Rz' is a rotation about the Z-axis, to bring the axis vector + * into the x-z plane. Then Ry' is applied, rotating about the + * Y-axis to bring the axis vector parallel with the X-axis. The + * rotation about the X-axis is then performed. Ry and Rz are + * simply the respective inverse transforms to bring the arbitrary + * axis back to it's original orientation. The first transforms + * Rz' and Ry' are considered inverses, since the data from the + * arbitrary axis gives you info on how to get to it, not how + * to get away from it, and an inverse must be applied. + * + * The basic calculation used is to recognize that the arbitrary + * axis vector (x, y, z), since it is of unit length, actually + * represents the sines and cosines of the angles to rotate the + * X-axis to the same orientation, with theta being the angle about + * Z and phi the angle about Y (in the order described above) + * as follows: + * + * cos ( theta ) = x / sqrt ( 1 - z^2 ) + * sin ( theta ) = y / sqrt ( 1 - z^2 ) + * + * cos ( phi ) = sqrt ( 1 - z^2 ) + * sin ( phi ) = z + * + * Note that cos ( phi ) can further be inserted to the above + * formulas: + * + * cos ( theta ) = x / cos ( phi ) + * sin ( theta ) = y / sin ( phi ) + * + * ...etc. Because of those relations and the standard trigonometric + * relations, it is pssible to reduce the transforms down to what + * is used below. It may be that any primary axis chosen will give the + * same results (modulo a sign convention) using thie method. + * + * Particularly nice is to notice that all divisions that might + * have caused trouble when parallel to certain planes or + * axis go away with care paid to reducing the expressions. + * After checking, it does perform correctly under all cases, since + * in all the cases of division where the denominator would have + * been zero, the numerator would have been zero as well, giving + * the expected result. + */ + + xx = x * x; + yy = y * y; + zz = z * z; + xy = x * y; + yz = y * z; + zx = z * x; + xs = x * s; + ys = y * s; + zs = z * s; + one_c = 1.0F - c; + + M(0,0) = (one_c * xx) + c; + M(0,1) = (one_c * xy) - zs; + M(0,2) = (one_c * zx) + ys; + M(0,3) = 0.0F; + + M(1,0) = (one_c * xy) + zs; + M(1,1) = (one_c * yy) + c; + M(1,2) = (one_c * yz) - xs; + M(1,3) = 0.0F; + + M(2,0) = (one_c * zx) - ys; + M(2,1) = (one_c * yz) + xs; + M(2,2) = (one_c * zz) + c; + M(2,3) = 0.0F; + + M(3,0) = 0.0F; + M(3,1) = 0.0F; + M(3,2) = 0.0F; + M(3,3) = 1.0F; + +#undef M + + matrix_multf( mat, m, MAT_FLAG_ROTATION ); +} + + +void +_math_matrix_frustrum( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ) +{ + GLfloat x, y, a, b, c, d; + GLfloat m[16]; + + x = (2.0*nearval) / (right-left); + y = (2.0*nearval) / (top-bottom); + a = (right+left) / (right-left); + b = (top+bottom) / (top-bottom); + c = -(farval+nearval) / ( farval-nearval); + d = -(2.0*farval*nearval) / (farval-nearval); /* error? */ + +#define M(row,col) m[col*4+row] + M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; + M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; + M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; + M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; +#undef M + + matrix_multf( mat, m, MAT_FLAG_PERSPECTIVE ); +} + +void +_math_matrix_ortho( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ) +{ + GLfloat x, y, z; + GLfloat tx, ty, tz; + GLfloat m[16]; + + x = 2.0 / (right-left); + y = 2.0 / (top-bottom); + z = -2.0 / (farval-nearval); + tx = -(right+left) / (right-left); + ty = -(top+bottom) / (top-bottom); + tz = -(farval+nearval) / (farval-nearval); + +#define M(row,col) m[col*4+row] + M(0,0) = x; M(0,1) = 0.0F; M(0,2) = 0.0F; M(0,3) = tx; + M(1,0) = 0.0F; M(1,1) = y; M(1,2) = 0.0F; M(1,3) = ty; + M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = z; M(2,3) = tz; + M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F; +#undef M + + matrix_multf( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION)); +} + + +#define ZERO(x) (1<<x) +#define ONE(x) (1<<(x+16)) + +#define MASK_NO_TRX (ZERO(12) | ZERO(13) | ZERO(14)) +#define MASK_NO_2D_SCALE ( ONE(0) | ONE(5)) + +#define MASK_IDENTITY ( ONE(0) | ZERO(4) | ZERO(8) | ZERO(12) |\ + ZERO(1) | ONE(5) | ZERO(9) | ZERO(13) |\ + ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ + ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + +#define MASK_2D_NO_ROT ( ZERO(4) | ZERO(8) | \ + ZERO(1) | ZERO(9) | \ + ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ + ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + +#define MASK_2D ( ZERO(8) | \ + ZERO(9) | \ + ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ + ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + + +#define MASK_3D_NO_ROT ( ZERO(4) | ZERO(8) | \ + ZERO(1) | ZERO(9) | \ + ZERO(2) | ZERO(6) | \ + ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + +#define MASK_3D ( \ + \ + \ + ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + + +#define MASK_PERSPECTIVE ( ZERO(4) | ZERO(12) |\ + ZERO(1) | ZERO(13) |\ + ZERO(2) | ZERO(6) | \ + ZERO(3) | ZERO(7) | ZERO(15) ) + +#define SQ(x) ((x)*(x)) + +/* Determine type and flags from scratch. This is expensive enough to + * only want to do it once. + */ +static void analyze_from_scratch( GLmatrix *mat ) +{ + const GLfloat *m = mat->m; + GLuint mask = 0; + GLuint i; + + for (i = 0 ; i < 16 ; i++) { + if (m[i] == 0.0) mask |= (1<<i); + } + + if (m[0] == 1.0F) mask |= (1<<16); + if (m[5] == 1.0F) mask |= (1<<21); + if (m[10] == 1.0F) mask |= (1<<26); + if (m[15] == 1.0F) mask |= (1<<31); + + mat->flags &= ~MAT_FLAGS_GEOMETRY; + + /* Check for translation - no-one really cares + */ + if ((mask & MASK_NO_TRX) != MASK_NO_TRX) + mat->flags |= MAT_FLAG_TRANSLATION; + + /* Do the real work + */ + if (mask == MASK_IDENTITY) { + mat->type = MATRIX_IDENTITY; + } + else if ((mask & MASK_2D_NO_ROT) == MASK_2D_NO_ROT) { + mat->type = MATRIX_2D_NO_ROT; + + if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE) + mat->flags = MAT_FLAG_GENERAL_SCALE; + } + else if ((mask & MASK_2D) == MASK_2D) { + GLfloat mm = DOT2(m, m); + GLfloat m4m4 = DOT2(m+4,m+4); + GLfloat mm4 = DOT2(m,m+4); + + mat->type = MATRIX_2D; + + /* Check for scale */ + if (SQ(mm-1) > SQ(1e-6) || + SQ(m4m4-1) > SQ(1e-6)) + mat->flags |= MAT_FLAG_GENERAL_SCALE; + + /* Check for rotation */ + if (SQ(mm4) > SQ(1e-6)) + mat->flags |= MAT_FLAG_GENERAL_3D; + else + mat->flags |= MAT_FLAG_ROTATION; + + } + else if ((mask & MASK_3D_NO_ROT) == MASK_3D_NO_ROT) { + mat->type = MATRIX_3D_NO_ROT; + + /* Check for scale */ + if (SQ(m[0]-m[5]) < SQ(1e-6) && + SQ(m[0]-m[10]) < SQ(1e-6)) { + if (SQ(m[0]-1.0) > SQ(1e-6)) { + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + } + } + else { + mat->flags |= MAT_FLAG_GENERAL_SCALE; + } + } + else if ((mask & MASK_3D) == MASK_3D) { + GLfloat c1 = DOT3(m,m); + GLfloat c2 = DOT3(m+4,m+4); + GLfloat c3 = DOT3(m+8,m+8); + GLfloat d1 = DOT3(m, m+4); + GLfloat cp[3]; + + mat->type = MATRIX_3D; + + /* Check for scale */ + if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) { + if (SQ(c1-1.0) > SQ(1e-6)) + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + /* else no scale at all */ + } + else { + mat->flags |= MAT_FLAG_GENERAL_SCALE; + } + + /* Check for rotation */ + if (SQ(d1) < SQ(1e-6)) { + CROSS3( cp, m, m+4 ); + SUB_3V( cp, cp, (m+8) ); + if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) + mat->flags |= MAT_FLAG_ROTATION; + else + mat->flags |= MAT_FLAG_GENERAL_3D; + } + else { + mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */ + } + } + else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) { + mat->type = MATRIX_PERSPECTIVE; + mat->flags |= MAT_FLAG_GENERAL; + } + else { + mat->type = MATRIX_GENERAL; + mat->flags |= MAT_FLAG_GENERAL; + } +} + + +/* Analyse a matrix given that its flags are accurate - this is the + * more common operation, hopefully. + */ +static void analyze_from_flags( GLmatrix *mat ) +{ + const GLfloat *m = mat->m; + + if (TEST_MAT_FLAGS(mat, 0)) { + mat->type = MATRIX_IDENTITY; + } + else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION | + MAT_FLAG_UNIFORM_SCALE | + MAT_FLAG_GENERAL_SCALE))) { + if ( m[10]==1.0F && m[14]==0.0F ) { + mat->type = MATRIX_2D_NO_ROT; + } + else { + mat->type = MATRIX_3D_NO_ROT; + } + } + else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) { + if ( m[ 8]==0.0F + && m[ 9]==0.0F + && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) { + mat->type = MATRIX_2D; + } + else { + mat->type = MATRIX_3D; + } + } + else if ( m[4]==0.0F && m[12]==0.0F + && m[1]==0.0F && m[13]==0.0F + && m[2]==0.0F && m[6]==0.0F + && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) { + mat->type = MATRIX_PERSPECTIVE; + } + else { + mat->type = MATRIX_GENERAL; + } +} + + +void +_math_matrix_analyze( GLmatrix *mat ) +{ + if (mat->flags & MAT_DIRTY_TYPE) { + if (mat->flags & MAT_DIRTY_FLAGS) + analyze_from_scratch( mat ); + else + analyze_from_flags( mat ); + } + + if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) { + matrix_invert( mat ); + } + + mat->flags &= ~(MAT_DIRTY_FLAGS| + MAT_DIRTY_TYPE| + MAT_DIRTY_INVERSE); +} + + +void +_math_matrix_copy( GLmatrix *to, const GLmatrix *from ) +{ + MEMCPY( to->m, from->m, sizeof(Identity) ); + to->flags = from->flags; + to->type = from->type; + + if (to->inv != 0) { + if (from->inv == 0) { + matrix_invert( to ); + } + else { + MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16); + } + } +} + + +void +_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ) +{ + GLfloat *m = mat->m; + m[0] *= x; m[4] *= y; m[8] *= z; + m[1] *= x; m[5] *= y; m[9] *= z; + m[2] *= x; m[6] *= y; m[10] *= z; + m[3] *= x; m[7] *= y; m[11] *= z; + + if (fabs(x - y) < 1e-8 && fabs(x - z) < 1e-8) + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + else + mat->flags |= MAT_FLAG_GENERAL_SCALE; + + mat->flags |= (MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); +} + + +void +_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ) +{ + GLfloat *m = mat->m; + m[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; + m[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; + m[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; + m[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; + + mat->flags |= (MAT_FLAG_TRANSLATION | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); +} + + +void +_math_matrix_loadf( GLmatrix *mat, const GLfloat *m ) +{ + MEMCPY( mat->m, m, 16*sizeof(GLfloat) ); + mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY); +} + +void +_math_matrix_ctr( GLmatrix *m ) +{ + if ( m->m == 0 ) { + m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + } + MEMCPY( m->m, Identity, sizeof(Identity) ); + m->inv = 0; + m->type = MATRIX_IDENTITY; + m->flags = 0; +} + +void +_math_matrix_dtr( GLmatrix *m ) +{ + if ( m->m != 0 ) { + ALIGN_FREE( m->m ); + m->m = 0; + } + if ( m->inv != 0 ) { + ALIGN_FREE( m->inv ); + m->inv = 0; + } +} + + +void +_math_matrix_alloc_inv( GLmatrix *m ) +{ + if ( m->inv == 0 ) { + m->inv = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) ); + } +} + + +void +_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ) +{ + dest->flags = (a->flags | + b->flags | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); + + if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D)) + matmul34( dest->m, a->m, b->m ); + else + matmul4( dest->m, a->m, b->m ); +} + + +void +_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *m ) +{ + dest->flags |= (MAT_FLAG_GENERAL | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); + + matmul4( dest->m, dest->m, m ); +} + +void +_math_matrix_set_identity( GLmatrix *mat ) +{ + MEMCPY( mat->m, Identity, 16*sizeof(GLfloat) ); + + if (mat->inv) + MEMCPY( mat->inv, Identity, 16*sizeof(GLfloat) ); + + mat->type = MATRIX_IDENTITY; + mat->flags &= ~(MAT_DIRTY_FLAGS| + MAT_DIRTY_TYPE| + MAT_DIRTY_INVERSE); +} + + + +void +_math_transposef( GLfloat to[16], const GLfloat from[16] ) +{ + to[0] = from[0]; + to[1] = from[4]; + to[2] = from[8]; + to[3] = from[12]; + to[4] = from[1]; + to[5] = from[5]; + to[6] = from[9]; + to[7] = from[13]; + to[8] = from[2]; + to[9] = from[6]; + to[10] = from[10]; + to[11] = from[14]; + to[12] = from[3]; + to[13] = from[7]; + to[14] = from[11]; + to[15] = from[15]; +} + + +void +_math_transposed( GLdouble to[16], const GLdouble from[16] ) +{ + to[0] = from[0]; + to[1] = from[4]; + to[2] = from[8]; + to[3] = from[12]; + to[4] = from[1]; + to[5] = from[5]; + to[6] = from[9]; + to[7] = from[13]; + to[8] = from[2]; + to[9] = from[6]; + to[10] = from[10]; + to[11] = from[14]; + to[12] = from[3]; + to[13] = from[7]; + to[14] = from[11]; + to[15] = from[15]; +} + +void +_math_transposefd( GLfloat to[16], const GLdouble from[16] ) +{ + to[0] = from[0]; + to[1] = from[4]; + to[2] = from[8]; + to[3] = from[12]; + to[4] = from[1]; + to[5] = from[5]; + to[6] = from[9]; + to[7] = from[13]; + to[8] = from[2]; + to[9] = from[6]; + to[10] = from[10]; + to[11] = from[14]; + to[12] = from[3]; + to[13] = from[7]; + to[14] = from[11]; + to[15] = from[15]; +} diff --git a/src/mesa/math/m_matrix.h b/src/mesa/math/m_matrix.h new file mode 100644 index 00000000000..8eedbdb9424 --- /dev/null +++ b/src/mesa/math/m_matrix.h @@ -0,0 +1,176 @@ +/* $Id: m_matrix.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _M_MATRIX_H +#define _M_MATRIX_H + + + +/* Give symbolic names to some of the entries in the matrix to help + * out with the rework of the viewport_map as a matrix transform. + */ +#define MAT_SX 0 +#define MAT_SY 5 +#define MAT_SZ 10 +#define MAT_TX 12 +#define MAT_TY 13 +#define MAT_TZ 14 + +/* + * Different kinds of 4x4 transformation matrices: + */ +#define MATRIX_GENERAL 0 /* general 4x4 matrix */ +#define MATRIX_IDENTITY 1 /* identity matrix */ +#define MATRIX_3D_NO_ROT 2 /* ortho projection and others... */ +#define MATRIX_PERSPECTIVE 3 /* perspective projection matrix */ +#define MATRIX_2D 4 /* 2-D transformation */ +#define MATRIX_2D_NO_ROT 5 /* 2-D scale & translate only */ +#define MATRIX_3D 6 /* 3-D transformation */ + +#define MAT_FLAG_IDENTITY 0 +#define MAT_FLAG_GENERAL 0x1 +#define MAT_FLAG_ROTATION 0x2 +#define MAT_FLAG_TRANSLATION 0x4 +#define MAT_FLAG_UNIFORM_SCALE 0x8 +#define MAT_FLAG_GENERAL_SCALE 0x10 +#define MAT_FLAG_GENERAL_3D 0x20 +#define MAT_FLAG_PERSPECTIVE 0x40 +#define MAT_FLAG_SINGULAR 0x80 +#define MAT_DIRTY_TYPE 0x100 +#define MAT_DIRTY_FLAGS 0x200 +#define MAT_DIRTY_INVERSE 0x400 + +#define MAT_FLAGS_ANGLE_PRESERVING (MAT_FLAG_ROTATION | \ + MAT_FLAG_TRANSLATION | \ + MAT_FLAG_UNIFORM_SCALE) + +#define MAT_FLAGS_LENGTH_PRESERVING (MAT_FLAG_ROTATION | \ + MAT_FLAG_TRANSLATION) + +#define MAT_FLAGS_3D (MAT_FLAG_ROTATION | \ + MAT_FLAG_TRANSLATION | \ + MAT_FLAG_UNIFORM_SCALE | \ + MAT_FLAG_GENERAL_SCALE | \ + MAT_FLAG_GENERAL_3D) + +#define MAT_FLAGS_GEOMETRY (MAT_FLAG_GENERAL | \ + MAT_FLAG_ROTATION | \ + MAT_FLAG_TRANSLATION | \ + MAT_FLAG_UNIFORM_SCALE | \ + MAT_FLAG_GENERAL_SCALE | \ + MAT_FLAG_GENERAL_3D | \ + MAT_FLAG_PERSPECTIVE | \ + MAT_FLAG_SINGULAR) + +#define MAT_DIRTY (MAT_DIRTY_TYPE | \ + MAT_DIRTY_FLAGS | \ + MAT_DIRTY_INVERSE) + +#define TEST_MAT_FLAGS(mat, a) \ + ((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0) + + +typedef struct { + GLfloat *m; /* 16-byte aligned */ + GLfloat *inv; /* optional, 16-byte aligned */ + GLuint flags; + GLuint type; /* one of the MATRIX_* values */ +} GLmatrix; + + + + +extern void +_math_matrix_ctr( GLmatrix *m ); + +extern void +_math_matrix_dtr( GLmatrix *m ); + +extern void +_math_matrix_alloc_inv( GLmatrix *m ); + +extern void +_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ); + +extern void +_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *b ); + +extern void +_math_matrix_loadf( GLmatrix *mat, const GLfloat *m ); + +extern void +_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ); + +extern void +_math_matrix_rotate( GLmatrix *m, GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ); + +extern void +_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ); + +extern void +_math_matrix_ortho( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ); + +extern void +_math_matrix_frustrum( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ); + +extern void +_math_matrix_set_identity( GLmatrix *dest ); + +extern void +_math_matrix_copy( GLmatrix *to, const GLmatrix *from ); + +extern void +_math_matrix_analyze( GLmatrix *mat ); + +extern void +_math_matrix_print( const GLmatrix *m ); + + + + +/* Related functions that don't actually operate on GLmatrix structs: + */ +extern void +_math_transposef( GLfloat to[16], const GLfloat from[16] ); + +extern void +_math_transposed( GLdouble to[16], const GLdouble from[16] ); + +extern void +_math_transposefd( GLfloat to[16], const GLdouble from[16] ); + + + + +#endif diff --git a/src/mesa/math/m_norm_tmp.h b/src/mesa/math/m_norm_tmp.h new file mode 100644 index 00000000000..72770c2075e --- /dev/null +++ b/src/mesa/math/m_norm_tmp.h @@ -0,0 +1,413 @@ +/* $Id: m_norm_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +static void _XFORMAPI +TAG(transform_normalize_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + GLfloat *m = mat->inv; + GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; + GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; + GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; + + (void) mask; + if (!lengths) { + STRIDE_LOOP { + CULL_CHECK { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 + uy * m1 + uz * m2; + ty = ux * m4 + uy * m5 + uz * m6; + tz = ux * m8 + uy * m9 + uz * m10; + } + { + GLdouble len = tx*tx + ty*ty + tz*tz; + if (len > 1e-20) { + GLdouble scale = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (tx * scale); + out[i][1] = (GLfloat) (ty * scale); + out[i][2] = (GLfloat) (tz * scale); + } + else + { + out[i][0] = out[i][1] = out[i][2] = 0; + } + } + } + } + } + else { + /* scale has been snapped to 1.0 if it is close. + */ + if (scale != 1.0) { + m0 *= scale, m4 *= scale, m8 *= scale; + m1 *= scale, m5 *= scale, m9 *= scale; + m2 *= scale, m6 *= scale, m10 *= scale; + } + + STRIDE_LOOP { + CULL_CHECK { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 + uy * m1 + uz * m2; + ty = ux * m4 + uy * m5 + uz * m6; + tz = ux * m8 + uy * m9 + uz * m10; + } + { + GLfloat len = lengths[i]; + out[i][0] = tx * len; + out[i][1] = ty * len; + out[i][2] = tz * len; + } + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + GLfloat *m = mat->inv; + GLfloat m0 = m[0]; + GLfloat m5 = m[5]; + GLfloat m10 = m[10]; + (void) mask; + if (!lengths) { + STRIDE_LOOP { + CULL_CHECK { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 ; + ty = uy * m5 ; + tz = uz * m10; + } + { + GLdouble len = tx*tx + ty*ty + tz*tz; + if (len > 1e-20) { + GLdouble scale = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (tx * scale); + out[i][1] = (GLfloat) (ty * scale); + out[i][2] = (GLfloat) (tz * scale); + } + else + { + out[i][0] = out[i][1] = out[i][2] = 0; + } + } + } + } + } + else { + /* scale has been snapped to 1.0 if it is close. + */ + if (scale != 1.0) { + m0 *= scale; + m5 *= scale; + m10 *= scale; + } + + STRIDE_LOOP { + CULL_CHECK { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 ; + ty = uy * m5 ; + tz = uz * m10; + } + { + GLfloat len = lengths[i]; + out[i][0] = tx * len; + out[i][1] = ty * len; + out[i][2] = tz * len; + } + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = scale*m[0]; + GLfloat m5 = scale*m[5]; + GLfloat m10 = scale*m[10]; + (void) lengths; + (void) mask; + STRIDE_LOOP { + CULL_CHECK { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0; + out[i][1] = uy * m5; + out[i][2] = uz * m10; + } + } + dest->count = in->count; +} + +static void _XFORMAPI +TAG(transform_rescale_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + /* Since we are unlikely to have < 3 vertices in the buffer, + * it makes sense to pre-multiply by scale. + */ + const GLfloat *m = mat->inv; + GLfloat m0 = scale*m[0], m4 = scale*m[4], m8 = scale*m[8]; + GLfloat m1 = scale*m[1], m5 = scale*m[5], m9 = scale*m[9]; + GLfloat m2 = scale*m[2], m6 = scale*m[6], m10 = scale*m[10]; + (void) lengths; + (void) mask; + STRIDE_LOOP { + CULL_CHECK { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0 + uy * m1 + uz * m2; + out[i][1] = ux * m4 + uy * m5 + uz * m6; + out[i][2] = ux * m8 + uy * m9 + uz * m10; + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normals_no_rot)(const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = m[0]; + GLfloat m5 = m[5]; + GLfloat m10 = m[10]; + (void) scale; + (void) lengths; + (void) mask; + STRIDE_LOOP { + CULL_CHECK { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0; + out[i][1] = uy * m5; + out[i][2] = uz * m10; + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; + GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; + GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; + (void) scale; + (void) lengths; + (void) mask; + STRIDE_LOOP { + CULL_CHECK { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0 + uy * m1 + uz * m2; + out[i][1] = ux * m4 + uy * m5 + uz * m6; + out[i][2] = ux * m8 + uy * m9 + uz * m10; + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(normalize_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + (void) mat; + (void) mask; + (void) scale; + if (lengths) { + STRIDE_LOOP { + CULL_CHECK { + const GLfloat x = from[0], y = from[1], z = from[2]; + GLfloat invlen = lengths[i]; + out[i][0] = x * invlen; + out[i][1] = y * invlen; + out[i][2] = z * invlen; + } + } + } + else { + STRIDE_LOOP { + CULL_CHECK { + const GLfloat x = from[0], y = from[1], z = from[2]; + GLdouble len = x * x + y * y + z * z; + if (len > 1e-50) { + len = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (x * len); + out[i][1] = (GLfloat) (y * len); + out[i][2] = (GLfloat) (z * len); + } + else { + out[i][0] = x; + out[i][1] = y; + out[i][2] = z; + } + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(rescale_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + (void) mat; + (void) lengths; + (void) mask; + + STRIDE_LOOP { + CULL_CHECK { + SCALE_SCALAR_3V( out[i], scale, from ); + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(init_c_norm_transform)( void ) +{ + gl_normal_tab[NORM_TRANSFORM_NO_ROT][IDX] = + TAG(transform_normals_no_rot); + + gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE][IDX] = + TAG(transform_rescale_normals_no_rot); + + gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE][IDX] = + TAG(transform_normalize_normals_no_rot); + + gl_normal_tab[NORM_TRANSFORM][IDX] = + TAG(transform_normals); + + gl_normal_tab[NORM_TRANSFORM | NORM_RESCALE][IDX] = + TAG(transform_rescale_normals); + + gl_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE][IDX] = + TAG(transform_normalize_normals); + + gl_normal_tab[NORM_RESCALE][IDX] = + TAG(rescale_normals); + + gl_normal_tab[NORM_NORMALIZE][IDX] = + TAG(normalize_normals); +} diff --git a/src/mesa/math/m_trans_tmp.h b/src/mesa/math/m_trans_tmp.h new file mode 100644 index 00000000000..952fde55942 --- /dev/null +++ b/src/mesa/math/m_trans_tmp.h @@ -0,0 +1,210 @@ +/* $Id: m_trans_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.1 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +/* KW: This file also included by tnl/trans_elt.c to build code + * specific to the implementation of array-elements in the + * tnl module. + */ + + +#ifdef DEST_4F +static void DEST_4F( GLfloat (*t)[4], + CONST void *ptr, + GLuint stride, + ARGS) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + + (void) first; + (void) start; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + if (SZ >= 1) t[i][0] = TRX_4F(f, 0); + if (SZ >= 2) t[i][1] = TRX_4F(f, 1); + if (SZ >= 3) t[i][2] = TRX_4F(f, 2); + if (SZ == 4) t[i][3] = TRX_4F(f, 3); + } + } +} +#endif + + +#ifdef DEST_3F +static void DEST_3F( GLfloat (*t)[3], + CONST void *ptr, + GLuint stride, + ARGS) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) first; + (void) start; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + t[i][0] = TRX_3F(f, 0); + t[i][1] = TRX_3F(f, 1); + t[i][2] = TRX_3F(f, 2); + } + } +} +#endif + +#ifdef DEST_1F +static void DEST_1F( GLfloat *t, + CONST void *ptr, + GLuint stride, + ARGS) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) first; + (void) start; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + t[i] = TRX_1F(f, 0); + } + } +} +#endif + +#ifdef DEST_4UB +static void DEST_4UB( GLubyte (*t)[4], + CONST void *ptr, + GLuint stride, + ARGS) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) start; + (void) first; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + if (SZ >= 1) TRX_UB(t[i][0], f, 0); + if (SZ >= 2) TRX_UB(t[i][1], f, 1); + if (SZ >= 3) TRX_UB(t[i][2], f, 2); + if (SZ == 4) TRX_UB(t[i][3], f, 3); else t[i][3] = 255; + } + } +} +#endif + + +#ifdef DEST_1UB +static void DEST_1UB( GLubyte *t, + CONST void *ptr, + GLuint stride, + ARGS) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) start; + (void) first; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + TRX_UB(t[i], f, 0); + } + } +} +#endif + + +#ifdef DEST_1UI +static void DEST_1UI( GLuint *t, + CONST void *ptr, + GLuint stride, + ARGS) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) start; + (void) first; + + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + t[i] = TRX_UI(f, 0); + } + } +} +#endif + + +static void INIT(void) +{ +#ifdef DEST_1UI + ASSERT(SZ == 1); + TAB(_1ui)[SRC_IDX] = DEST_1UI; +#endif +#ifdef DEST_1UB + ASSERT(SZ == 1); + TAB(_1ub)[SRC_IDX] = DEST_1UB; +#endif +#ifdef DEST_1F + ASSERT(SZ == 1); + TAB(_1f)[SRC_IDX] = DEST_1F; +#endif +#ifdef DEST_3F + ASSERT(SZ == 3); + TAB(_3f)[SRC_IDX] = DEST_3F; +#endif +#ifdef DEST_4UB + TAB(_4ub)[SZ][SRC_IDX] = DEST_4UB; +#endif +#ifdef DEST_4F + TAB(_4f)[SZ][SRC_IDX] = DEST_4F; +#endif + +} + + +#undef INIT +#undef DEST_1UI +#undef DEST_1UB +#undef DEST_4UB +#undef DEST_3F +#undef DEST_4F +#undef DEST_1F +#undef SZ +#undef TAG + + diff --git a/src/mesa/math/m_translate.c b/src/mesa/math/m_translate.c new file mode 100644 index 00000000000..945e35706c4 --- /dev/null +++ b/src/mesa/math/m_translate.c @@ -0,0 +1,478 @@ +/* $Id: m_translate.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "mem.h" +#include "mmath.h" + +#include "m_translate.h" + +/* This macro is used on other systems, so undefine it for this module */ + +#undef CHECK + +trans_1f_func gl_trans_1f_tab[MAX_TYPES]; +trans_1ui_func gl_trans_1ui_tab[MAX_TYPES]; +trans_1ub_func gl_trans_1ub_tab[MAX_TYPES]; +trans_3f_func gl_trans_3f_tab[MAX_TYPES]; +trans_4ub_func gl_trans_4ub_tab[5][MAX_TYPES]; +trans_4f_func gl_trans_4f_tab[5][MAX_TYPES]; + + +#define PTR_ELT(ptr, elt) (((SRC *)ptr)[elt]) + + +#define TAB(x) gl_trans##x##_tab +#define ARGS GLuint start, GLuint n +#define SRC_START start +#define DST_START 0 +#define STRIDE stride +#define NEXT_F f += stride +#define NEXT_F2 +#define CHECK + + + + +/* GL_BYTE + */ +#define SRC GLbyte +#define SRC_IDX TYPE_IDX(GL_BYTE) +#define TRX_3F(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = BYTE_TO_UBYTE( PTR_ELT(f,n) ) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLbyte_raw +#define DEST_4F trans_4_GLbyte_4f_raw +#define DEST_4UB trans_4_GLbyte_4ub_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLbyte_raw +#define DEST_4F trans_3_GLbyte_4f_raw +#define DEST_4UB trans_3_GLbyte_4ub_raw +#define DEST_3F trans_3_GLbyte_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLbyte_raw +#define DEST_4F trans_2_GLbyte_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLbyte_raw +#define DEST_4F trans_1_GLbyte_4f_raw +#define DEST_1UB trans_1_GLbyte_1ub_raw +#define DEST_1UI trans_1_GLbyte_1ui_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_UI +#undef SRC_IDX + +/* GL_UNSIGNED_BYTE + */ +#define SRC GLubyte +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_BYTE) +#define TRX_3F(f,n) /* unused */ +#define TRX_4F(f,n) /* unused */ +#define TRX_UB(ub, f,n) ub = PTR_ELT(f,n) +#define TRX_UI(f,n) (GLuint)PTR_ELT(f,n) + +/* 4ub->4ub handled in special case below. + */ + +#define SZ 3 +#define INIT init_trans_3_GLubyte_raw +#define DEST_4UB trans_3_GLubyte_4ub_raw +#include "m_trans_tmp.h" + + +#define SZ 1 +#define INIT init_trans_1_GLubyte_raw +#define DEST_1UI trans_1_GLubyte_1ui_raw +#define DEST_1UB trans_1_GLubyte_1ub_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_UI + + +/* GL_SHORT + */ +#define SRC GLshort +#define SRC_IDX TYPE_IDX(GL_SHORT) +#define TRX_3F(f,n) SHORT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = SHORT_TO_UBYTE(PTR_ELT(f,n)) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLshort_raw +#define DEST_4F trans_4_GLshort_4f_raw +#define DEST_4UB trans_4_GLshort_4ub_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLshort_raw +#define DEST_4F trans_3_GLshort_4f_raw +#define DEST_4UB trans_3_GLshort_4ub_raw +#define DEST_3F trans_3_GLshort_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLshort_raw +#define DEST_4F trans_2_GLshort_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLshort_raw +#define DEST_4F trans_1_GLshort_4f_raw +#define DEST_1UB trans_1_GLshort_1ub_raw +#define DEST_1UI trans_1_GLshort_1ui_raw +#include "m_trans_tmp.h" + + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_UI + + +/* GL_UNSIGNED_SHORT + */ +#define SRC GLushort +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_SHORT) +#define TRX_3F(f,n) USHORT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub,f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 8) +#define TRX_UI(f,n) (GLuint) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLushort_raw +#define DEST_4F trans_4_GLushort_4f_raw +#define DEST_4UB trans_4_GLushort_4ub_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLushort_raw +#define DEST_4F trans_3_GLushort_4f_raw +#define DEST_4UB trans_3_GLushort_4ub_raw +#define DEST_3F trans_3_GLushort_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLushort_raw +#define DEST_4F trans_2_GLushort_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLushort_raw +#define DEST_4F trans_1_GLushort_4f_raw +#define DEST_1UB trans_1_GLushort_1ub_raw +#define DEST_1UI trans_1_GLushort_1ui_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_UI + + +/* GL_INT + */ +#define SRC GLint +#define SRC_IDX TYPE_IDX(GL_INT) +#define TRX_3F(f,n) INT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = INT_TO_UBYTE(PTR_ELT(f,n)) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLint_raw +#define DEST_4F trans_4_GLint_4f_raw +#define DEST_4UB trans_4_GLint_4ub_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLint_raw +#define DEST_4F trans_3_GLint_4f_raw +#define DEST_4UB trans_3_GLint_4ub_raw +#define DEST_3F trans_3_GLint_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLint_raw +#define DEST_4F trans_2_GLint_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLint_raw +#define DEST_4F trans_1_GLint_4f_raw +#define DEST_1UB trans_1_GLint_1ub_raw +#define DEST_1UI trans_1_GLint_1ui_raw +#include "m_trans_tmp.h" + + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_UI + + +/* GL_UNSIGNED_INT + */ +#define SRC GLuint +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_INT) +#define TRX_3F(f,n) INT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 24) +#define TRX_UI(f,n) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLuint_raw +#define DEST_4F trans_4_GLuint_4f_raw +#define DEST_4UB trans_4_GLuint_4ub_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLuint_raw +#define DEST_4F trans_3_GLuint_4f_raw +#define DEST_4UB trans_3_GLuint_4ub_raw +#define DEST_3F trans_3_GLuint_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLuint_raw +#define DEST_4F trans_2_GLuint_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLuint_raw +#define DEST_4F trans_1_GLuint_4f_raw +#define DEST_1UB trans_1_GLuint_1ub_raw +#define DEST_1UI trans_1_GLuint_1ui_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_UI + + +/* GL_DOUBLE + */ +#define SRC GLdouble +#define SRC_IDX TYPE_IDX(GL_DOUBLE) +#define TRX_3F(f,n) PTR_ELT(f,n) +#define TRX_4F(f,n) PTR_ELT(f,n) +#define TRX_UB(ub,f,n) FLOAT_COLOR_TO_CHAN(ub, PTR_ELT(f,n)) +#define TRX_UI(f,n) (GLuint) (GLint) PTR_ELT(f,n) +#define TRX_1F(f,n) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLdouble_raw +#define DEST_4F trans_4_GLdouble_4f_raw +#define DEST_4UB trans_4_GLdouble_4ub_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLdouble_raw +#define DEST_4F trans_3_GLdouble_4f_raw +#define DEST_4UB trans_3_GLdouble_4ub_raw +#define DEST_3F trans_3_GLdouble_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLdouble_raw +#define DEST_4F trans_2_GLdouble_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLdouble_raw +#define DEST_4F trans_1_GLdouble_4f_raw +#define DEST_1UB trans_1_GLdouble_1ub_raw +#define DEST_1UI trans_1_GLdouble_1ui_raw +#define DEST_1F trans_1_GLdouble_1f_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX + +/* GL_FLOAT + */ +#define SRC GLfloat +#define SRC_IDX TYPE_IDX(GL_FLOAT) +#define SZ 4 +#define INIT init_trans_4_GLfloat_raw +#define DEST_4UB trans_4_GLfloat_4ub_raw +#define DEST_4F trans_4_GLfloat_4f_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLfloat_raw +#define DEST_4F trans_3_GLfloat_4f_raw +#define DEST_4UB trans_3_GLfloat_4ub_raw +#define DEST_3F trans_3_GLfloat_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLfloat_raw +#define DEST_4F trans_2_GLfloat_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLfloat_raw +#define DEST_4F trans_1_GLfloat_4f_raw +#define DEST_1UB trans_1_GLfloat_1ub_raw +#define DEST_1UI trans_1_GLfloat_1ui_raw +#define DEST_1F trans_1_GLfloat_1f_raw + +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_UI + + +static void trans_4_GLubyte_4ub_raw (GLubyte (*t)[4], + CONST void *Ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) Ptr + SRC_START * stride; + GLuint i; + + if (((((long) f | (long) stride)) & 3L) == 0L) { + /* Aligned. + */ + for (i = DST_START ; i < n ; i++, f += stride) { + COPY_4UBV( t[i], f ); + } + } else { + for (i = DST_START ; i < n ; i++, f += stride) { + t[i][0] = f[0]; + t[i][1] = f[1]; + t[i][2] = f[2]; + t[i][3] = f[3]; + } + } +} + + +static void init_translate_raw(void) +{ + MEMSET( TAB(_1ui), 0, sizeof(TAB(_1ui)) ); + MEMSET( TAB(_1ub), 0, sizeof(TAB(_1ub)) ); + MEMSET( TAB(_3f), 0, sizeof(TAB(_3f)) ); + MEMSET( TAB(_4ub), 0, sizeof(TAB(_4ub)) ); + MEMSET( TAB(_4f), 0, sizeof(TAB(_4f)) ); + + TAB(_4ub)[4][TYPE_IDX(GL_UNSIGNED_BYTE)] = trans_4_GLubyte_4ub_raw; + + init_trans_4_GLbyte_raw(); + init_trans_3_GLbyte_raw(); + init_trans_2_GLbyte_raw(); + init_trans_1_GLbyte_raw(); + init_trans_1_GLubyte_raw(); + init_trans_3_GLubyte_raw(); + init_trans_4_GLshort_raw(); + init_trans_3_GLshort_raw(); + init_trans_2_GLshort_raw(); + init_trans_1_GLshort_raw(); + init_trans_4_GLushort_raw(); + init_trans_3_GLushort_raw(); + init_trans_2_GLushort_raw(); + init_trans_1_GLushort_raw(); + init_trans_4_GLint_raw(); + init_trans_3_GLint_raw(); + init_trans_2_GLint_raw(); + init_trans_1_GLint_raw(); + init_trans_4_GLuint_raw(); + init_trans_3_GLuint_raw(); + init_trans_2_GLuint_raw(); + init_trans_1_GLuint_raw(); + init_trans_4_GLdouble_raw(); + init_trans_3_GLdouble_raw(); + init_trans_2_GLdouble_raw(); + init_trans_1_GLdouble_raw(); + init_trans_4_GLfloat_raw(); + init_trans_3_GLfloat_raw(); + init_trans_2_GLfloat_raw(); + init_trans_1_GLfloat_raw(); +} + + +#undef TAB +#undef CLASS +#undef ARGS +#undef CHECK +#undef SRC_START +#undef DST_START +#undef NEXT_F +#undef NEXT_F2 + + + + + +void +_math_init_translate( void ) +{ + init_translate_raw(); +} diff --git a/src/mesa/math/m_translate.h b/src/mesa/math/m_translate.h new file mode 100644 index 00000000000..5c60b972ff5 --- /dev/null +++ b/src/mesa/math/m_translate.h @@ -0,0 +1,92 @@ +/* $Id: m_translate.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.1 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _M_TRANSLATE_H_ +#define _M_TRANSLATE_H_ + + +typedef void (*trans_1f_func)(GLfloat *to, + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_1ui_func)(GLuint *to, + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_1ub_func)(GLubyte *to, + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_4ub_func)(GLubyte (*to)[4], + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_4f_func)(GLfloat (*to)[4], + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_3f_func)(GLfloat (*to)[3], + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + + + + +/* Translate GL_UNSIGNED_BYTE, etc to the indexes used in the arrays + * below. + */ +#define TYPE_IDX(t) ((t) & 0xf) + +#define MAX_TYPES TYPE_IDX(GL_DOUBLE)+1 /* 0xa + 1 */ + +/* Only useful combinations are defined, thus there is no function to + * translate eg, ubyte->float or ubyte->ubyte, which are never used. + */ +extern trans_1f_func gl_trans_1f_tab[MAX_TYPES]; +extern trans_1ui_func gl_trans_1ui_tab[MAX_TYPES]; +extern trans_1ub_func gl_trans_1ub_tab[MAX_TYPES]; +extern trans_3f_func gl_trans_3f_tab[MAX_TYPES]; +extern trans_4ub_func gl_trans_4ub_tab[5][MAX_TYPES]; +extern trans_4f_func gl_trans_4f_tab[5][MAX_TYPES]; + + +extern void gl_init_translate( void ); + + +#endif diff --git a/src/mesa/math/m_vector.c b/src/mesa/math/m_vector.c new file mode 100644 index 00000000000..4dbf68f8e0f --- /dev/null +++ b/src/mesa/math/m_vector.c @@ -0,0 +1,367 @@ +/* $Id: m_vector.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +#include "glheader.h" +#include "macros.h" +#include "mem.h" + +#include "m_vector.h" + + + +/* + * Given a vector [count][4] of floats, set all the [][elt] values + * to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3). + */ +void gl_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) +{ + static const GLubyte elem_bits[4] = { + VEC_DIRTY_0, + VEC_DIRTY_1, + VEC_DIRTY_2, + VEC_DIRTY_3 + }; + static const GLfloat clean[4] = { 0, 0, 0, 1 }; + const GLfloat v = clean[elt]; + GLfloat (*data)[4] = (GLfloat (*)[4])vec->start; + GLuint i; + + for (i = 0 ; i < count ; i++) + data[i][elt] = v; + + vec->flags &= ~elem_bits[elt]; +} + +static const GLubyte size_bits[5] = { + 0, + VEC_SIZE_1, + VEC_SIZE_2, + VEC_SIZE_3, + VEC_SIZE_4, +}; + + + +/* + * Initialize GLvector objects. + * Input: v - the vector object to initialize. + * flags - bitwise-OR of VEC_* flags + * storage - pointer to storage for the vector's data + */ + + +void gl_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] ) +{ + v->stride = 4 * sizeof(GLfloat); + v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */ + v->data = storage; + v->start = (GLfloat *) storage; + v->count = 0; + v->flags = size_bits[4] | flags | VEC_GOOD_STRIDE; +} + +void gl_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*storage)[3] ) +{ + v->stride = 3 * sizeof(GLfloat); + v->data = storage; + v->start = (GLfloat *) storage; + v->count = 0; + v->flags = flags | VEC_GOOD_STRIDE; +} + +void gl_vector1f_init( GLvector1f *v, GLuint flags, GLfloat *storage ) +{ + v->stride = 1*sizeof(GLfloat); + v->data = storage; + v->start = (GLfloat *)storage; + v->count = 0; + v->flags = flags | VEC_GOOD_STRIDE; +} + +void gl_vector4ub_init( GLvector4ub *v, GLuint flags, GLubyte (*storage)[4] ) +{ + v->stride = 4 * sizeof(GLubyte); + v->data = storage; + v->start = (GLubyte *) storage; + v->count = 0; + v->flags = flags | VEC_GOOD_STRIDE; +} + +void gl_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage ) +{ + v->stride = 1 * sizeof(GLubyte); + v->data = storage; + v->start = (GLubyte *) storage; + v->count = 0; + v->flags = flags | VEC_GOOD_STRIDE; +} + +void gl_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage ) +{ + v->stride = 1 * sizeof(GLuint); + v->data = storage; + v->start = (GLuint *) storage; + v->count = 0; + v->flags = flags | VEC_GOOD_STRIDE; +} + + +/* + * Initialize GLvector objects and allocate storage. + * Input: v - the vector object + * sz - unused???? + * flags - bitwise-OR of VEC_* flags + * count - number of elements to allocate in vector + * alignment - desired memory alignment for the data (in bytes) + */ + + +void gl_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 4 * sizeof(GLfloat); + v->size = 2; + v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLfloat), alignment ); + v->start = (GLfloat *) v->storage; + v->data = (GLfloat (*)[4]) v->storage; + v->count = 0; + v->flags = size_bits[4] | flags | VEC_MALLOC | VEC_GOOD_STRIDE; +} + +void gl_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 3 * sizeof(GLfloat); + v->storage = ALIGN_MALLOC( count * 3 * sizeof(GLfloat), alignment ); + v->start = (GLfloat *) v->storage; + v->data = (GLfloat (*)[3]) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; +} + +void gl_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = sizeof(GLfloat); + v->storage = v->start = (GLfloat *) + ALIGN_MALLOC( count * sizeof(GLfloat), alignment ); + v->data = v->start; + v->count = 0; + v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; +} + +void gl_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 4 * sizeof(GLubyte); + v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLubyte), alignment ); + v->start = (GLubyte *) v->storage; + v->data = (GLubyte (*)[4]) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; +} + +void gl_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 1 * sizeof(GLubyte); + v->storage = ALIGN_MALLOC( count * sizeof(GLubyte), alignment ); + v->start = (GLubyte *) v->storage; + v->data = (GLubyte *) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; +} + +void gl_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 1 * sizeof(GLuint); + v->storage = ALIGN_MALLOC( count * sizeof(GLuint), alignment ); + v->start = (GLuint *) v->storage; + v->data = (GLuint *) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; +} + + + +/* + * Vector deallocation. Free whatever memory is pointed to by the + * vector's storage field if the VEC_MALLOC flag is set. + * DO NOT free the GLvector object itself, though. + */ + + +void gl_vector4f_free( GLvector4f *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void gl_vector3f_free( GLvector3f *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = 0; + v->start = 0; + v->storage = 0; + v->flags &= ~VEC_MALLOC; + } +} + +void gl_vector1f_free( GLvector1f *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void gl_vector4ub_free( GLvector4ub *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void gl_vector1ub_free( GLvector1ub *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void gl_vector1ui_free( GLvector1ui *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + + +/* + * For debugging + */ +void gl_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling ) +{ + GLfloat c[4] = { 0, 0, 0, 1 }; + const char *templates[5] = { + "%d:\t0, 0, 0, 1\n", + "%d:\t%f, 0, 0, 1\n", + "%d:\t%f, %f, 0, 1\n", + "%d:\t%f, %f, %f, 1\n", + "%d:\t%f, %f, %f, %f\n" + }; + + const char *t = templates[v->size]; + GLfloat *d = (GLfloat *)v->data; + GLuint j, i = 0, count; + + printf("data-start\n"); + for ( ; d != v->start ; STRIDE_F(d, v->stride), i++) + printf( t, i, d[0], d[1], d[2], d[3]); + + printf("start-count(%u)\n", v->count); + count = i + v->count; + + if (culling) { + for ( ; i < count ; STRIDE_F(d, v->stride), i++) + if (cullmask[i]) + printf( t, i, d[0], d[1], d[2], d[3]); + } + else { + for ( ; i < count ; STRIDE_F(d, v->stride), i++) + printf( t, i, d[0], d[1], d[2], d[3]); + } + + for (j = v->size ; j < 4; j++) { + if ((v->flags & (1<<j)) == 0) { + + printf("checking col %u is clean as advertised ", j); + + for (i = 0, d = (GLfloat *) v->data ; + i < count && d[j] == c[j] ; + i++, STRIDE_F(d, v->stride)) {}; + + if (i == count) + printf(" --> ok\n"); + else + printf(" --> Failed at %u ******\n", i); + } + } +} + + +/* + * For debugging + */ +void gl_vector3f_print( GLvector3f *v, GLubyte *cullmask, GLboolean culling ) +{ + GLfloat *d = (GLfloat *)v->data; + GLuint i = 0, count; + + printf("data-start\n"); + for ( ; d != v->start ; STRIDE_F(d,v->stride), i++) + printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); + + printf("start-count(%u)\n", v->count); + count = i + v->count; + + if (culling) { + for ( ; i < count ; STRIDE_F(d,v->stride), i++) + if (cullmask[i]) + printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); + } + else { + for ( ; i < count ; STRIDE_F(d,v->stride), i++) + printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); + } +} diff --git a/src/mesa/math/m_vector.h b/src/mesa/math/m_vector.h new file mode 100644 index 00000000000..c4af1eaade5 --- /dev/null +++ b/src/mesa/math/m_vector.h @@ -0,0 +1,188 @@ +/* $Id: m_vector.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +#ifndef _M_VECTOR_H_ +#define _M_VECTOR_H_ + +#include "glheader.h" + + +#define VEC_DIRTY_0 0x1 /* dirty flags not really used any more */ +#define VEC_DIRTY_1 0x2 +#define VEC_DIRTY_2 0x4 +#define VEC_DIRTY_3 0x8 +#define VEC_MALLOC 0x10 /* storage field points to self-allocated mem*/ +#define VEC_WRITABLE 0x20 /* keep both + and - bits for easy testing */ +#define VEC_NOT_WRITABLE 0x40 +#define VEC_GOOD_STRIDE 0x80 +#define VEC_BAD_STRIDE 0x100 + +#define VEC_WRITABLE_FLAGS (VEC_WRITABLE|VEC_NOT_WRITABLE) +#define VEC_STRIDE_FLAGS (VEC_GOOD_STRIDE|VEC_BAD_STRIDE) + + +#define VEC_SIZE_1 VEC_DIRTY_0 +#define VEC_SIZE_2 (VEC_DIRTY_0|VEC_DIRTY_1) +#define VEC_SIZE_3 (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2) +#define VEC_SIZE_4 (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2|VEC_DIRTY_3) + + + +/* Wrap all the information about vectors up in a struct. Has + * additional fields compared to the other vectors to help us track of + * different vertex sizes, and whether we need to clean columns out + * because they contain non-(0,0,0,1) values. + * + * The start field is used to reserve data for copied vertices at the + * end of gl_transform_vb, and avoids the need for a multiplication in + * the transformation routines. + */ +typedef struct { + GLfloat (*data)[4]; /* may be malloc'd or point to client data */ + GLfloat *start; /* points somewhere inside of <data> */ + GLuint count; /* size of the vector (in elements) */ + GLuint stride; /* stride from one element to the next (in bytes) */ + GLuint size; /* 2-4 for vertices and 1-4 for texcoords */ + GLuint flags; /* which columns are dirty */ + void *storage; /* self-allocated storage */ +} GLvector4f; + + +extern void gl_vector4f_init( GLvector4f *v, GLuint flags, + GLfloat (*storage)[4] ); +extern void gl_vector4f_alloc( GLvector4f *v, GLuint flags, + GLuint count, GLuint alignment ); +extern void gl_vector4f_free( GLvector4f *v ); +extern void gl_vector4f_print( GLvector4f *v, GLubyte *, GLboolean ); +extern void gl_vector4f_clean_elem( GLvector4f *vec, GLuint nr, GLuint elt ); + + +/* Could use a single vector type for normals and vertices, but + * this way avoids some casts. + */ +typedef struct { + GLfloat (*data)[3]; + GLfloat *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector3f; + +extern void gl_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*)[3] ); +extern void gl_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void gl_vector3f_free( GLvector3f *v ); +extern void gl_vector3f_print( GLvector3f *v, GLubyte *, GLboolean ); + + +typedef struct { + GLfloat *data; + GLfloat *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector1f; + +extern void gl_vector1f_free( GLvector1f *v ); +extern void gl_vector1f_init( GLvector1f *v, GLuint flags, GLfloat * ); +extern void gl_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count, + GLuint alignment ); + + +/* For 4ub rgba values. + */ +typedef struct { + GLubyte (*data)[4]; + GLubyte *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector4ub; + +extern void gl_vector4ub_init( GLvector4ub *v, GLuint flags, + GLubyte (*storage)[4] ); +extern void gl_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void gl_vector4ub_free( GLvector4ub * ); + + + + +/* For 1ub values, eg edgeflag. + */ +typedef struct { + GLubyte *data; + GLubyte *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector1ub; + +extern void gl_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage); +extern void gl_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void gl_vector1ub_free( GLvector1ub * ); + + + + +/* For, eg Index, Array element. + */ +typedef struct { + GLuint *data; + GLuint *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector1ui; + +extern void gl_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage ); +extern void gl_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void gl_vector1ui_free( GLvector1ui * ); + + + +/* + * Given vector <v>, return a pointer (cast to <type *> to the <i>-th element. + * + * End up doing a lot of slow imuls if not careful. + */ +#define VEC_ELT( v, type, i ) \ + ( (type *) ( ((GLbyte *) ((v)->data)) + (i) * (v)->stride) ) + + +#endif diff --git a/src/mesa/math/m_xform.c b/src/mesa/math/m_xform.c new file mode 100644 index 00000000000..6bc6a9cea3b --- /dev/null +++ b/src/mesa/math/m_xform.c @@ -0,0 +1,251 @@ +/* $Id: m_xform.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * Matrix/vertex/vector transformation stuff + * + * + * NOTES: + * 1. 4x4 transformation matrices are stored in memory in column major order. + * 2. Points/vertices are to be thought of as column vectors. + * 3. Transformation of a point p by a matrix M is: p' = M * p + */ + + +#include "glheader.h" +#include "macros.h" +#include "mmath.h" + +#include "m_matrix.h" +#include "m_xform.h" + + +#ifdef DEBUG +#include "m_debug_xform.h" +#endif + +#ifdef USE_X86_ASM +#include "X86/common_x86_asm.h" +#endif + +clip_func gl_clip_tab[5]; +dotprod_func gl_dotprod_tab[2][5]; +vec_copy_func gl_copy_tab[2][0x10]; +normal_func gl_normal_tab[0xf][0x4]; +transform_func **(gl_transform_tab[2]); +static transform_func *cull_transform_tab[5]; +static transform_func *raw_transform_tab[5]; + + +/* Raw data format used for: + * - Object-to-eye transform prior to culling, although this too + * could be culled under some circumstances. + * - Eye-to-clip transform (via the function above). + * - Cliptesting + * - And everything else too, if culling happens to be disabled. + */ +#define TAG(x) x##_raw +#define TAG2(x,y) x##y##_raw +#define IDX 0 +#define STRIDE_LOOP for (i=0;i<count;i++, STRIDE_F(from, stride)) +#define LOOP for (i=0;i<n;i++) +#define CULL_CHECK +#define CLIP_CHECK +#define ARGS +#include "m_xform_tmp.h" +#include "m_clip_tmp.h" +#include "m_norm_tmp.h" +#include "m_dotprod_tmp.h" +#include "m_copy_tmp.h" +#undef TAG +#undef TAG2 +#undef LOOP +#undef CULL_CHECK +#undef CLIP_CHECK +#undef ARGS +#undef IDX + +/* Culled data used for: + * - texture transformations + * - viewport map transformation + * - normal transformations prior to lighting + * - user cliptests + */ +#define TAG(x) x##_masked +#define TAG2(x,y) x##y##_masked +#define IDX 1 +#define STRIDE_LOOP for (i=0;i<count;i++, STRIDE_F(from, stride)) +#define LOOP for (i=0;i<n;i++) +#define CULL_CHECK if (mask[i]) +#define CLIP_CHECK if ((mask[i] & flag) == 0) +#define ARGS , const GLubyte mask[] +#include "m_xform_tmp.h" +#include "m_norm_tmp.h" +#include "m_dotprod_tmp.h" +#include "m_copy_tmp.h" +#undef TAG +#undef TAG2 +#undef LOOP +#undef CULL_CHECK +#undef CLIP_CHECK +#undef ARGS +#undef IDX + + + + + + +GLvector4f *gl_project_points( GLvector4f *proj_vec, + const GLvector4f *clip_vec ) +{ + const GLuint stride = clip_vec->stride; + const GLfloat *from = (GLfloat *)clip_vec->start; + const GLuint count = clip_vec->count; + GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; + GLuint i; + + for (i = 0 ; i < count ; i++, STRIDE_F(from, stride)) + { + GLfloat oow = 1.0F / from[3]; + vProj[i][3] = oow; + vProj[i][0] = from[0] * oow; + vProj[i][1] = from[1] * oow; + vProj[i][2] = from[2] * oow; + } + + proj_vec->flags |= VEC_SIZE_4; + proj_vec->size = 3; + proj_vec->count = clip_vec->count; + return proj_vec; +} + + + + + + +/* + * Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix. This + * function is used for transforming clipping plane equations and spotlight + * directions. + * Mathematically, u = v * m. + * Input: v - input vector + * m - transformation matrix + * Output: u - transformed vector + */ +void gl_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] ) +{ + GLfloat v0=v[0], v1=v[1], v2=v[2], v3=v[3]; +#define M(row,col) m[row + col*4] + u[0] = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + v3 * M(3,0); + u[1] = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + v3 * M(3,1); + u[2] = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + v3 * M(3,2); + u[3] = v0 * M(0,3) + v1 * M(1,3) + v2 * M(2,3) + v3 * M(3,3); +#undef M +} + + +/* Useful for one-off point transformations, as in clipping. + * Note that because the matrix isn't analyzed we do too many + * multiplies, and that the result is always 4-clean. + */ +void gl_transform_point_sz( GLfloat Q[4], const GLfloat M[16], + const GLfloat P[4], GLuint sz ) +{ + if (Q == P) + return; + + if (sz == 4) + { + Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; + Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; + Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; + Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3]; + } + else if (sz == 3) + { + Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; + Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; + Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; + Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15]; + } + else if (sz == 2) + { + Q[0] = M[0] * P[0] + M[4] * P[1] + M[12]; + Q[1] = M[1] * P[0] + M[5] * P[1] + M[13]; + Q[2] = M[2] * P[0] + M[6] * P[1] + M[14]; + Q[3] = M[3] * P[0] + M[7] * P[1] + M[15]; + } + else if (sz == 1) + { + Q[0] = M[0] * P[0] + M[12]; + Q[1] = M[1] * P[0] + M[13]; + Q[2] = M[2] * P[0] + M[14]; + Q[3] = M[3] * P[0] + M[15]; + } +} + + +/* + * This is called only once. It initializes several tables with pointers + * to optimized transformation functions. This is where we can test for + * AMD 3Dnow! capability, Intel Katmai, etc. and hook in the right code. + */ +void +_math_init_transformation( void ) +{ + gl_transform_tab[0] = raw_transform_tab; + gl_transform_tab[1] = cull_transform_tab; + + init_c_transformations_raw(); + init_c_transformations_masked(); + init_c_norm_transform_raw(); + init_c_norm_transform_masked(); + init_c_cliptest_raw(); + init_copy0_raw(); + init_copy0_masked(); + init_dotprod_raw(); + init_dotprod_masked(); + +#ifdef DEBUG + gl_test_all_transform_functions( "default" ); + gl_test_all_normal_transform_functions( "default" ); +#endif + +#ifdef USE_X86_ASM + gl_init_all_x86_transform_asm(); +#endif +} + +void +_math_init( void ) +{ + _math_init_transformation(); + _math_init_translate(); + _math_init_vertices(); +} diff --git a/src/mesa/math/m_xform.h b/src/mesa/math/m_xform.h new file mode 100644 index 00000000000..1c6ac461e82 --- /dev/null +++ b/src/mesa/math/m_xform.h @@ -0,0 +1,224 @@ +/* $Id: m_xform.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + + + + +#ifndef _M_XFORM_H +#define _M_XFORM_H + + +#include "glheader.h" +#include "config.h" +#include "math/m_vector.h" +#include "math/m_matrix.h" + +#ifdef USE_X86_ASM +#define _XFORMAPI _ASMAPI +#define _XFORMAPIP _ASMAPIP +#else +#define _XFORMAPI +#define _XFORMAPIP * +#endif + +/* + * Transform a point (column vector) by a matrix: Q = M * P + */ +#define TRANSFORM_POINT( Q, M, P ) \ + Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; \ + Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; \ + Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; \ + Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3]; + + +#define TRANSFORM_POINT3( Q, M, P ) \ + Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; \ + Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; \ + Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; \ + Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15]; + + +/* + * Transform a normal (row vector) by a matrix: [NX NY NZ] = N * MAT + */ +#define TRANSFORM_NORMAL( TO, N, MAT ) \ +do { \ + TO[0] = N[0] * MAT[0] + N[1] * MAT[1] + N[2] * MAT[2]; \ + TO[1] = N[0] * MAT[4] + N[1] * MAT[5] + N[2] * MAT[6]; \ + TO[2] = N[0] * MAT[8] + N[1] * MAT[9] + N[2] * MAT[10]; \ +} while (0) + + +extern void gl_transform_vector( GLfloat u[4], + const GLfloat v[4], + const GLfloat m[16] ); + + +extern void gl_init_transformation( void ); + + +/* KW: Clip functions now do projective divide as well. The projected + * coordinates are very useful to us because they let us cull + * backfaces and eliminate vertices from lighting, fogging, etc + * calculations. Despite the fact that this divide could be done one + * day in hardware, we would still have a reason to want to do it here + * as long as those other calculations remain in software. + * + * Clipping is a convenient place to do the divide on x86 as it should be + * possible to overlap with integer outcode calculations. + * + * There are two cases where we wouldn't want to do the divide in cliptest: + * - When we aren't clipping. We still might want to cull backfaces + * so the divide should be done elsewhere. This currently never + * happens. + * + * - When culling isn't likely to help us, such as when the GL culling + * is disabled and we not lighting or are only lighting + * one-sided. In this situation, backface determination provides + * us with no useful information. A tricky case to detect is when + * all input data is already culled, although hopefully the + * application wouldn't turn on culling in such cases. + * + * We supply a buffer to hold the [x/w,y/w,z/w,1/w] values which + * are the result of the projection. This is only used in the + * 4-vector case - in other cases, we just use the clip coordinates + * as the projected coordinates - they are identical. + * + * This is doubly convenient because it means the Win[] array is now + * of the same stride as all the others, so I can now turn map_vertices + * into a straight-forward matrix transformation, with asm acceleration + * automatically available. + */ + +/* Vertex buffer clipping flags + */ +#define CLIP_RIGHT_SHIFT 0 +#define CLIP_LEFT_SHIFT 1 +#define CLIP_TOP_SHIFT 2 +#define CLIP_BOTTOM_SHIFT 3 +#define CLIP_NEAR_SHIFT 4 +#define CLIP_FAR_SHIFT 5 + +#define CLIP_RIGHT_BIT 0x01 +#define CLIP_LEFT_BIT 0x02 +#define CLIP_TOP_BIT 0x04 +#define CLIP_BOTTOM_BIT 0x08 +#define CLIP_NEAR_BIT 0x10 +#define CLIP_FAR_BIT 0x20 +#define CLIP_USER_BIT 0x40 +#define CLIP_CULLED_BIT 0x80 /* Vertex has been culled */ +#define CLIP_ALL_BITS 0x3f + + +typedef GLvector4f * (_XFORMAPIP clip_func)( GLvector4f *vClip, + GLvector4f *vProj, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ); + +typedef void (*dotprod_func)( GLvector4f *out_vec, + GLuint elt, + const GLvector4f *coord_vec, + const GLfloat plane[4], + const GLubyte mask[]); + +typedef void (*vec_copy_func)( GLvector4f *to, + const GLvector4f *from, + const GLubyte mask[]); + + + +/* + * Functions for transformation of normals in the VB. + */ +typedef void (_NORMAPIP normal_func)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat lengths[], + const GLubyte mask[], + GLvector3f *dest ); + + +/* Flags for selecting a normal transformation function. + */ +#define NORM_RESCALE 0x1 /* apply the scale factor */ +#define NORM_NORMALIZE 0x2 /* normalize */ +#define NORM_TRANSFORM 0x4 /* apply the transformation matrix */ +#define NORM_TRANSFORM_NO_ROT 0x8 /* apply the transformation matrix */ + + + + +/* KW: New versions of the transform function allow a mask array + * specifying that individual vector transform should be skipped + * when the mask byte is zero. This is always present as a + * parameter, to allow a unified interface. + */ +typedef void (_XFORMAPIP transform_func)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *clipmask, + const GLubyte flag ); + + +extern GLvector4f *gl_project_points( GLvector4f *to, + const GLvector4f *from ); + +extern void gl_transform_bounds3( GLubyte *orMask, GLubyte *andMask, + const GLfloat m[16], + CONST GLfloat src[][3] ); + +extern void gl_transform_bounds2( GLubyte *orMask, GLubyte *andMask, + const GLfloat m[16], + CONST GLfloat src[][3] ); + + +extern dotprod_func gl_dotprod_tab[2][5]; +extern vec_copy_func gl_copy_tab[2][0x10]; +extern clip_func gl_clip_tab[5]; +extern normal_func gl_normal_tab[0xf][0x4]; + +/* Use of 3 layers of linked 1-dimensional arrays to reduce + * cost of lookup. + */ +extern transform_func **(gl_transform_tab[2]); + + +extern void gl_transform_point_sz( GLfloat Q[4], const GLfloat M[16], + const GLfloat P[4], GLuint sz ); + + +#define TransformRaw( to, mat, from ) \ + ( (*gl_transform_tab[0][(from)->size][(mat)->type])( to, (mat)->m, from, 0, 0 ), \ + (to) ) + +#define Transform( to, mat, from, mask, cull ) \ + ( (*gl_transform_tab[cull!=0][(from)->size][(mat)->type])( to, (mat)->m, from, mask, cull ), \ + (to) ) + + +#endif diff --git a/src/mesa/math/m_xform_tmp.h b/src/mesa/math/m_xform_tmp.h new file mode 100644 index 00000000000..289255a9cf5 --- /dev/null +++ b/src/mesa/math/m_xform_tmp.h @@ -0,0 +1,974 @@ +/* $Id: m_xform_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.1 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +/*---------------------------------------------------------------------- + * Begin Keith's new code + * + *---------------------------------------------------------------------- + */ + +/* KW: Fixed stride, now measured in bytes as is the OpenGL array stride. + */ + +/* KW: These are now parameterized to produce two versions, one + * which transforms all incoming points, and a second which + * takes notice of a cullmask array, and only transforms + * unculled vertices. + */ + +/* KW: 1-vectors can sneak into the texture pipeline via the array + * interface. These functions are here because I want consistant + * treatment of the vertex sizes and a lazy strategy for + * cleaning unused parts of the vector, and so as not to exclude + * them from the vertex array interface. + * + * Under our current analysis of matrices, there is no way that + * the product of a matrix and a 1-vector can remain a 1-vector, + * with the exception of the identity transform. + */ + +/* KW: No longer zero-pad outgoing vectors. Now that external + * vectors can get into the pipeline we cannot ever assume + * that there is more to a vector than indicated by its + * size. + */ + +/* KW: Now uses clipmask and a flag to allow us to skip both/either + * cliped and/or culled vertices. + */ + +static void _XFORMAPI +TAG(transform_points1_general)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m12 = m[12]; + const GLfloat m1 = m[1], m13 = m[13]; + const GLfloat m2 = m[2], m14 = m[14]; + const GLfloat m3 = m[3], m15 = m[15]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m1 * ox + m13; + to[i][2] = m2 * ox + m14; + to[i][3] = m3 * ox + m15; + } + } + + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_identity)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLuint count = from_vec->count; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint i; + (void) mask; + (void) flag; + if (to_vec == from_vec) return; + STRIDE_LOOP { + CLIP_CHECK { + to[i][0] = from[0]; + } + } + + to_vec->size = 1; + to_vec->flags |= VEC_SIZE_1; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_2d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1]; + const GLfloat m12 = m[12], m13 = m[13]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m1 * ox + m13; + } + } + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_2d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m12 = m[12], m13 = m[13]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m13; + } + } + + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_3d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m2 = m[2]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m1 * ox + m13; + to[i][2] = m2 * ox + m14; + } + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + + +static void _XFORMAPI +TAG(transform_points1_3d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m13; + to[i][2] = m14; + } + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_perspective)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox ; + to[i][1] = 0 ; + to[i][2] = m14; + to[i][3] = 0; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + + + + +/* 2-vectors, which are a lot more relevant than 1-vectors, are + * present early in the geometry pipeline and throughout the + * texture pipeline. + */ +static void _XFORMAPI +TAG(transform_points2_general)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m4 = m[4], m12 = m[12]; + const GLfloat m1 = m[1], m5 = m[5], m13 = m[13]; + const GLfloat m2 = m[2], m6 = m[6], m14 = m[14]; + const GLfloat m3 = m[3], m7 = m[7], m15 = m[15]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m4 * oy + m12; + to[i][1] = m1 * ox + m5 * oy + m13; + to[i][2] = m2 * ox + m6 * oy + m14; + to[i][3] = m3 * ox + m7 * oy + m15; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points2_identity)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + GLuint i; + (void) mask; + (void) flag; + if (to_vec == from_vec) return; + STRIDE_LOOP { + CLIP_CHECK { + to[i][0] = from[0]; + to[i][1] = from[1]; + } + } + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points2_2d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; + const GLfloat m12 = m[12], m13 = m[13]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m4 * oy + m12; + to[i][1] = m1 * ox + m5 * oy + m13; + } + } + + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points2_2d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m12; + to[i][1] = m5 * oy + m13; + } + } + + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points2_3d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; + const GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m4 * oy + m12; + to[i][1] = m1 * ox + m5 * oy + m13; + to[i][2] = m2 * ox + m6 * oy + m14; + } + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + + +/* I would actually say this was a fairly important function, from + * a texture transformation point of view. + */ +static void _XFORMAPI +TAG(transform_points2_3d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m12; + to[i][1] = m5 * oy + m13; + to[i][2] = m14; + } + } + if (m14 == 0) { + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + } else { + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + } + to_vec->count = from_vec->count; +} + +/* This may not be called too often, but I wouldn't say it was dead + * code. It's also hard to remove any of these functions if you are + * attached to the assertions that have appeared in them. + */ +static void _XFORMAPI +TAG(transform_points2_perspective)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox ; + to[i][1] = m5 * oy ; + to[i][2] = m14; + to[i][3] = 0; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + + + +static void _XFORMAPI +TAG(transform_points3_general)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; + const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; + const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; + const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12; + to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13; + to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14; + to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_identity)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + GLuint i; + (void) mask; + (void) flag; + if (to_vec == from_vec) return; + STRIDE_LOOP { + CLIP_CHECK { + to[i][0] = from[0]; + to[i][1] = from[1]; + to[i][2] = from[2]; + } + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_2d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; + const GLfloat m12 = m[12], m13 = m[13]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m4 * oy + m12 ; + to[i][1] = m1 * ox + m5 * oy + m13 ; + to[i][2] = + oz ; + } + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_2d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m12 ; + to[i][1] = m5 * oy + m13 ; + to[i][2] = + oz ; + } + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_3d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; + const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 ; + to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 ; + to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 ; + } + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +/* previously known as ortho... + */ +static void _XFORMAPI +TAG(transform_points3_3d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5]; + const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m12 ; + to[i][1] = m5 * oy + m13 ; + to[i][2] = m10 * oz + m14 ; + } + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_perspective)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; + const GLfloat m10 = m[10], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m8 * oz ; + to[i][1] = m5 * oy + m9 * oz ; + to[i][2] = m10 * oz + m14 ; + to[i][3] = -oz ; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + + + +static void _XFORMAPI +TAG(transform_points4_general)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; + const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; + const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; + const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; + to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; + to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; + to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_identity)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + GLuint i; + (void) mask; + (void) flag; + if (to_vec == from_vec) return; + STRIDE_LOOP { + CLIP_CHECK { + to[i][0] = from[0]; + to[i][1] = from[1]; + to[i][2] = from[2]; + to[i][3] = from[3]; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_2d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; + const GLfloat m12 = m[12], m13 = m[13]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m4 * oy + m12 * ow; + to[i][1] = m1 * ox + m5 * oy + m13 * ow; + to[i][2] = + oz ; + to[i][3] = ow; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_2d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m12 * ow; + to[i][1] = m5 * oy + m13 * ow; + to[i][2] = + oz ; + to[i][3] = ow; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_3d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; + const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; + to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; + to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; + to[i][3] = ow; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_3d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5]; + const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m12 * ow; + to[i][1] = m5 * oy + m13 * ow; + to[i][2] = m10 * oz + m14 * ow; + to[i][3] = ow; + } + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_perspective)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec, + const GLubyte *mask, + const GLubyte flag ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; + const GLfloat m10 = m[10], m14 = m[14]; + GLuint i; + (void) mask; + (void) flag; + STRIDE_LOOP { + CLIP_CHECK { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m8 * oz ; + to[i][1] = m5 * oy + m9 * oz ; + to[i][2] = m10 * oz + m14 * ow ; + to[i][3] = -oz ; + } + } + + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static transform_func _XFORMAPI TAG(transform_tab_1)[7]; +static transform_func _XFORMAPI TAG(transform_tab_2)[7]; +static transform_func _XFORMAPI TAG(transform_tab_3)[7]; +static transform_func _XFORMAPI TAG(transform_tab_4)[7]; + +/* Similar functions could be called several times, with more highly + * optimized routines overwriting the arrays. This only occurs during + * startup. + */ +static void _XFORMAPI TAG(init_c_transformations)( void ) +{ +#define TAG_TAB gl_transform_tab[IDX] +#define TAG_TAB_1 TAG(transform_tab_1) +#define TAG_TAB_2 TAG(transform_tab_2) +#define TAG_TAB_3 TAG(transform_tab_3) +#define TAG_TAB_4 TAG(transform_tab_4) + + TAG_TAB[1] = TAG_TAB_1; + TAG_TAB[2] = TAG_TAB_2; + TAG_TAB[3] = TAG_TAB_3; + TAG_TAB[4] = TAG_TAB_4; + + /* 1-D points (ie texcoords) */ + TAG_TAB_1[MATRIX_GENERAL] = TAG(transform_points1_general); + TAG_TAB_1[MATRIX_IDENTITY] = TAG(transform_points1_identity); + TAG_TAB_1[MATRIX_3D_NO_ROT] = TAG(transform_points1_3d_no_rot); + TAG_TAB_1[MATRIX_PERSPECTIVE] = TAG(transform_points1_perspective) ; + TAG_TAB_1[MATRIX_2D] = TAG(transform_points1_2d); + TAG_TAB_1[MATRIX_2D_NO_ROT] = TAG(transform_points1_2d_no_rot); + TAG_TAB_1[MATRIX_3D] = TAG(transform_points1_3d); + + /* 2-D points */ + TAG_TAB_2[MATRIX_GENERAL] = TAG(transform_points2_general); + TAG_TAB_2[MATRIX_IDENTITY] = TAG(transform_points2_identity); + TAG_TAB_2[MATRIX_3D_NO_ROT] = TAG(transform_points2_3d_no_rot); + TAG_TAB_2[MATRIX_PERSPECTIVE] = TAG(transform_points2_perspective) ; + TAG_TAB_2[MATRIX_2D] = TAG(transform_points2_2d); + TAG_TAB_2[MATRIX_2D_NO_ROT] = TAG(transform_points2_2d_no_rot); + TAG_TAB_2[MATRIX_3D] = TAG(transform_points2_3d); + + /* 3-D points */ + TAG_TAB_3[MATRIX_GENERAL] = TAG(transform_points3_general); + TAG_TAB_3[MATRIX_IDENTITY] = TAG(transform_points3_identity); + TAG_TAB_3[MATRIX_3D_NO_ROT] = TAG(transform_points3_3d_no_rot); + TAG_TAB_3[MATRIX_PERSPECTIVE] = TAG(transform_points3_perspective); + TAG_TAB_3[MATRIX_2D] = TAG(transform_points3_2d); + TAG_TAB_3[MATRIX_2D_NO_ROT] = TAG(transform_points3_2d_no_rot); + TAG_TAB_3[MATRIX_3D] = TAG(transform_points3_3d); + + /* 4-D points */ + TAG_TAB_4[MATRIX_GENERAL] = TAG(transform_points4_general); + TAG_TAB_4[MATRIX_IDENTITY] = TAG(transform_points4_identity); + TAG_TAB_4[MATRIX_3D_NO_ROT] = TAG(transform_points4_3d_no_rot); + TAG_TAB_4[MATRIX_PERSPECTIVE] = TAG(transform_points4_perspective); + TAG_TAB_4[MATRIX_2D] = TAG(transform_points4_2d); + TAG_TAB_4[MATRIX_2D_NO_ROT] = TAG(transform_points4_2d_no_rot); + TAG_TAB_4[MATRIX_3D] = TAG(transform_points4_3d); + +#undef TAG_TAB +} diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c index f11186baedf..c5f4127c2e2 100644 --- a/src/mesa/swrast/s_bitmap.c +++ b/src/mesa/swrast/s_bitmap.c @@ -1,4 +1,4 @@ -/* $Id: s_bitmap.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */ +/* $Id: s_bitmap.c,v 1.3 2000/11/16 21:05:41 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -56,11 +56,6 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, if (SWRAST_CONTEXT(ctx)->NewState) _swrast_validate_derived( ctx ); - if (PB->primitive != GL_BITMAP) { - gl_flush_pb( ctx ); - PB->primitive = GL_BITMAP; - } - /* Set bitmap drawing color */ if (ctx->Visual.RGBAflag) { GLint r, g, b, a; diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c index e460a77f181..a16fe9ecf8a 100644 --- a/src/mesa/swrast/s_lines.c +++ b/src/mesa/swrast/s_lines.c @@ -1,4 +1,4 @@ -/* $Id: s_lines.c,v 1.5 2000/11/13 20:02:57 keithw Exp $ */ +/* $Id: s_lines.c,v 1.6 2000/11/16 21:05:41 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -28,7 +28,6 @@ #include "glheader.h" #include "macros.h" #include "mmath.h" -#include "vb.h" #include "s_aaline.h" #include "s_pb.h" #include "s_context.h" diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 5c30c5f5a21..e6f193f5558 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -1,4 +1,4 @@ -/* $Id: s_points.c,v 1.5 2000/11/15 16:38:40 brianp Exp $ */ +/* $Id: s_points.c,v 1.6 2000/11/16 21:05:41 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -30,7 +30,6 @@ #include "macros.h" #include "mmath.h" #include "texstate.h" -#include "vb.h" #include "s_context.h" #include "s_feedback.h" diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index 10942037a3a..e58abdc6c55 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -1,4 +1,4 @@ -/* $Id: ss_context.c,v 1.3 2000/11/13 20:02:58 keithw Exp $ */ +/* $Id: ss_context.c,v 1.4 2000/11/16 21:05:42 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -38,6 +38,7 @@ #include "swrast_setup.h" +#include "tnl/t_context.h" /* Stub for swsetup->Triangle to select a true triangle function * after a state change. diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c index ab70f5c97bc..9bcf13c3ed2 100644 --- a/src/mesa/swrast_setup/ss_triangle.c +++ b/src/mesa/swrast_setup/ss_triangle.c @@ -29,6 +29,8 @@ #include "macros.h" #include "types.h" +#include "tnl/t_context.h" + #include "ss_triangle.h" #include "ss_context.h" diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index 37b56642252..054fcf9eb7f 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -30,7 +30,7 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2, GLuint pv) { - struct vertex_buffer *VB = ctx->VB; + struct vertex_buffer *VB = TNL_VB(ctx); SWvertex *verts = SWSETUP_VB(VB)->verts; SWvertex *v[3]; GLfloat offset; @@ -224,7 +224,7 @@ static void TAG(quad)( GLcontext *ctx, GLuint v0, static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) { - struct vertex_buffer *VB = ctx->VB; + struct vertex_buffer *VB = TNL_VB(ctx); SWvertex *verts = SWSETUP_VB(VB)->verts; GLubyte c[2][4], s[2][4]; GLuint i[2]; @@ -264,7 +264,7 @@ static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) { - struct vertex_buffer *VB = ctx->VB; + struct vertex_buffer *VB = TNL_VB(ctx); SWvertex *verts = SWSETUP_VB(VB)->verts; int i; diff --git a/src/mesa/swrast_setup/ss_vb.c b/src/mesa/swrast_setup/ss_vb.c index 15e6049cb51..ff1916174b7 100644 --- a/src/mesa/swrast_setup/ss_vb.c +++ b/src/mesa/swrast_setup/ss_vb.c @@ -27,10 +27,13 @@ #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" diff --git a/src/mesa/swrast_setup/ss_vbtmp.h b/src/mesa/swrast_setup/ss_vbtmp.h index 53fe5bcae66..47b30055000 100644 --- a/src/mesa/swrast_setup/ss_vbtmp.h +++ b/src/mesa/swrast_setup/ss_vbtmp.h @@ -29,6 +29,7 @@ static void TAG(rs)(struct vertex_buffer *VB, GLuint start, GLuint end) { GLcontext *ctx = VB->ctx; + TNLcontext *tnl = TNL_CONTEXT(ctx); SWvertex *v; GLfloat (*eye)[4]; GLfloat (*win)[4]; @@ -54,7 +55,7 @@ static void TAG(rs)(struct vertex_buffer *VB, GLuint start, GLuint end) /* TODO: Get import_client_data to pad vectors out to 4 cleanly. */ - gl_import_client_data( VB, ctx->_RenderFlags, + gl_import_client_data( VB, tnl->_RenderFlags, (VB->ClipOrMask ? /* VEC_CLEAN| */VEC_WRITABLE|VEC_GOOD_STRIDE : /* VEC_CLEAN| */VEC_GOOD_STRIDE)); diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c new file mode 100644 index 00000000000..bab6326ebaf --- /dev/null +++ b/src/mesa/tnl/t_context.c @@ -0,0 +1,201 @@ +#include "types.h" +#include "mem.h" + +#include "t_context.h" +#include "t_clip.h" +#include "t_cva.h" +#include "t_dlist.h" +#include "t_eval.h" +#include "t_pipeline.h" +#include "t_shade.h" +#include "t_light.h" +#include "t_texture.h" +#include "t_stages.h" +#include "t_varray.h" +#include "t_vb.h" +#include "t_vbrender.h" +#include "t_vbxform.h" +#include "tnl.h" + +#if !defined(THREADS) +struct immediate *_mesa_CurrentInput = NULL; +#endif + + +GLboolean +_tnl_flush_vertices( GLcontext *ctx, GLuint flush_flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct immediate *IM = TNL_CURRENT_IM(ctx); + + if ((IM->Flag[IM->Count] & (VERT_BEGIN|VERT_END)) != VERT_END || + (flush_flags & (FLUSH_STORED_VERTICES|FLUSH_UPDATE_CURRENT))) + { + if (IM->Flag[IM->Start]) + _mesa_flush_vb( ctx ); + + /* Although this code updates the ctx->Current values, that bit + * is left set as there is no easy mechanism to set it + * elsewhere. This means that each time core wants to examine + * ctx->Current, this function will be called. After the first + * time, however, it will be a no-op. + */ + ctx->Driver.NeedFlush &= ~(FLUSH_STORED_VERTICES | + FLUSH_INSIDE_BEGIN_END); + + return (tnl->_CurrentPrimitive == GL_POLYGON+1); + } + else + return GL_TRUE; +} + + +GLboolean +_tnl_CreateContext( GLcontext *ctx ) +{ + TNLcontext *tnl; + static int firsttime = 1; + + /* Onetime initializations. Doesn't really matter if this gets + * done twice: no need for mutexes. + */ + if (firsttime) { + firsttime = 0; + _tnl_clip_init( ); + _tnl_eval_init( ); + _tnl_shade_init( ); + _tnl_texture_init( ); + _tnl_trans_elt_init( ); + _tnl_vbrender_init( ); + _tnl_stages_init( ); + } + + /* Create the TNLcontext structure + */ + ctx->swtnl_context = tnl = CALLOC( sizeof(TNLcontext) ); + if (!tnl) { + return GL_FALSE; + } + + /* Create and hook in the data structures available from ctx. + */ + ctx->swtnl_vb = (void *)gl_vb_create_for_immediate( ctx ); + if (!ctx->swtnl_vb) { + FREE(tnl); + ctx->swtnl_context = 0; + return GL_FALSE; + } + + ctx->swtnl_im = (void *)TNL_VB(ctx)->IM; + + + /* Initialize tnl state. + */ + _tnl_dlist_init( ctx ); + _tnl_pipeline_init( ctx ); + + tnl->_CurrentFlag = (VERT_NORM | + VERT_INDEX | + VERT_RGBA | + VERT_SPEC_RGB | + VERT_FOG_COORD | + VERT_EDGE | + VERT_TEX0_12 | + VERT_TEX1_12 | + VERT_TEX2_12 | + VERT_TEX3_12 | + VERT_MATERIAL); + + tnl->_CurrentPrimitive = GL_POLYGON+1; + + gl_reset_vb( TNL_VB(ctx) ); + gl_reset_input( ctx ); + + + /* Set a few default values in the driver struct. This is a + * temporary mechanism. + */ + ctx->Driver.RenderVBCulledTab = _tnl_render_tab_cull; + ctx->Driver.RenderVBClippedTab = _tnl_render_tab_clipped; + ctx->Driver.RenderVBRawTab = _tnl_render_tab_raw; + ctx->Driver.NewList = _tnl_NewList; + ctx->Driver.EndList = _tnl_EndList; + ctx->Driver.FlushVertices = _tnl_flush_vertices; + ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT; + ctx->Driver.LightingSpaceChange = _tnl_LightingSpaceChange; + ctx->Driver.MakeCurrent = _tnl_MakeCurrent; + ctx->Driver.VertexPointer = _tnl_VertexPointer; + ctx->Driver.NormalPointer = _tnl_NormalPointer; + ctx->Driver.ColorPointer = _tnl_ColorPointer; + ctx->Driver.FogCoordPointer = _tnl_FogCoordPointer; + ctx->Driver.IndexPointer = _tnl_IndexPointer; + ctx->Driver.SecondaryColorPointer = _tnl_SecondaryColorPointer; + ctx->Driver.TexCoordPointer = _tnl_TexCoordPointer; + ctx->Driver.EdgeFlagPointer = _tnl_EdgeFlagPointer; + + return GL_TRUE; +} + + +void +_tnl_DestroyContext( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (TNL_CURRENT_IM(ctx) != TNL_VB(ctx)->IM) + gl_immediate_free( TNL_CURRENT_IM(ctx) ); + + gl_vb_free( TNL_VB(ctx) ); + + /* Free cache of immediate buffers. */ + while (tnl->nr_im_queued-- > 0) { + struct immediate * next = tnl->freed_im_queue->next; + ALIGN_FREE( tnl->freed_im_queue ); + tnl->freed_im_queue = next; + } +} + + +/* Update all state that references _NeedEyeCoords + */ +void +_tnl_LightingSpaceChange( GLcontext *ctx ) +{ + _tnl_update_normal_transform( ctx ); +} + + +void +_tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + if (new_state & _NEW_LIGHT) + gl_update_lighting_function(ctx); + + if (new_state & _NEW_ARRAY) + gl_update_client_state( ctx ); + + if (new_state & _NEW_TEXTURE) + if (ctx->_Enabled & ENABLE_TEXGEN_ANY) + _tnl_update_texgen( ctx ); + + if (new_state & (_NEW_LIGHT|_NEW_TEXTURE|_NEW_FOG| + _DD_NEW_TRI_LIGHT_TWOSIDE | + _DD_NEW_SEPERATE_SPECULAR | + _DD_NEW_TRI_UNFILLED )) + gl_update_clipmask(ctx); + + if (new_state & _TNL_NEW_NORMAL_TRANSFORM) + _tnl_update_normal_transform( ctx ); + + gl_update_pipelines(ctx); +} + +void +_tnl_MakeCurrent( GLcontext *ctx, + GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ) +{ +#ifndef THREADS + SET_IMMEDIATE(newCtx, newCtx->input); +#endif +} diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h new file mode 100644 index 00000000000..992c2a58f9b --- /dev/null +++ b/src/mesa/tnl/t_context.h @@ -0,0 +1,629 @@ + +/* $Id: t_context.h,v 1.1 2000/11/16 21:05:42 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _T_CONTEXT_H +#define _T_CONTEXT_H + +#include "glheader.h" +#include "types.h" + +#include "math/m_matrix.h" +#include "math/m_vector.h" +#include "math/m_xform.h" + +#include "t_trans_elt.h" + + + +/* + * Bits to indicate which faces a vertex participates in, + * what facing the primitive provoked by that vertex has, + * and some misc. flags. + */ +#define VERT_FACE_FRONT 0x1 /* is in a front-color primitive */ +#define VERT_FACE_REAR 0x2 /* is in a rear-color primitive */ +#define PRIM_FACE_FRONT 0x4 /* use front color */ +#define PRIM_FACE_REAR 0x8 /* use rear color */ +#define PRIM_CLIPPED 0x10 /* needs clipping */ +#define PRIM_USER_CLIPPED CLIP_USER_BIT /* 0x40 */ + + +#define PRIM_FLAG_SHIFT 2 +#define PRIM_FACE_FLAGS (PRIM_FACE_FRONT|PRIM_FACE_REAR) +#define VERT_FACE_FLAGS (VERT_FACE_FRONT|VERT_FACE_REAR) + +#define PRIM_ANY_CLIP (PRIM_CLIPPED|PRIM_USER_CLIPPED) +#define PRIM_NOT_CULLED (PRIM_ANY_CLIP|PRIM_FACE_FLAGS) + +/* Flags for VB->CullMode. + */ +#define CULL_MASK_ACTIVE 0x1 +#define COMPACTED_NORMALS 0x2 +#define CLIP_MASK_ACTIVE 0x4 + +/* Flags for selecting a shading function. The first two bits are + * shared with the cull mode (ie. cull_mask_active and + * compacted_normals.) + */ +#define SHADE_TWOSIDE 0x4 + + +/* KW: Flags that describe the current vertex state, and the contents + * of a vertex in a vertex-cassette. + * + * For really major expansion, consider a 'VERT_ADDITIONAL_FLAGS' flag, + * which means there is data in another flags array (eg, extra_flags[]). + */ + +#define VERT_OBJ_2 0x1 /* glVertex2 */ +#define VERT_OBJ_3 0x2 /* glVertex3 */ +#define VERT_OBJ_4 0x4 /* glVertex4 */ +#define VERT_BEGIN 0x8 /* glBegin */ +#define VERT_END 0x10 /* glEnd */ +#define VERT_ELT 0x20 /* glArrayElement */ +#define VERT_RGBA 0x40 /* glColor */ +#define VERT_NORM 0x80 /* glNormal */ +#define VERT_INDEX 0x100 /* glIndex */ +#define VERT_EDGE 0x200 /* glEdgeFlag */ +#define VERT_MATERIAL 0x400 /* glMaterial */ +#define VERT_END_VB 0x800 /* end vb marker */ +#define VERT_TEX0_12 0x1000 +#define VERT_TEX0_3 0x2000 +#define VERT_TEX0_4 0x4000 +#define VERT_TEX1_12 0x8000 +#define VERT_TEX1_3 0x10000 +#define VERT_TEX1_4 0x20000 +#define VERT_TEX2_12 0x40000 +#define VERT_TEX2_3 0x80000 +#define VERT_TEX2_4 0x100000 +#define VERT_TEX3_12 0x200000 +#define VERT_TEX3_3 0x400000 +#define VERT_TEX3_4 0x800000 +#define VERT_EVAL_C1 0x1000000 /* could reuse OBJ bits for this? */ +#define VERT_EVAL_C2 0x2000000 /* - or just use 3 bits */ +#define VERT_EVAL_P1 0x4000000 /* */ +#define VERT_EVAL_P2 0x8000000 /* */ +#define VERT_SPEC_RGB 0x10000000 +#define VERT_FOG_COORD 0x20000000 /* internal use only, currently */ + +#define VERT_EYE VERT_BEGIN /* reuse */ +#define VERT_WIN VERT_END /* reuse */ +#define VERT_SETUP_FULL VERT_EVAL_P1 /* Rastersetup has been done */ +#define VERT_PRECALC_DATA VERT_END_VB /* reuse */ + +/* Shorthands. + */ +#define VERT_TEX0_SHIFT 11 + +#define VERT_EVAL_ANY (VERT_EVAL_C1|VERT_EVAL_P1| \ + VERT_EVAL_C2|VERT_EVAL_P2) + +#define VERT_OBJ_23 (VERT_OBJ_3|VERT_OBJ_2) +#define VERT_OBJ_234 (VERT_OBJ_4|VERT_OBJ_23) +#define VERT_OBJ_ANY VERT_OBJ_2 + +#define VERT_TEX0_123 (VERT_TEX0_3|VERT_TEX0_12) +#define VERT_TEX0_1234 (VERT_TEX0_4|VERT_TEX0_123) +#define VERT_TEX0_ANY VERT_TEX0_12 + +#define VERT_TEX1_123 (VERT_TEX1_3|VERT_TEX1_12) +#define VERT_TEX1_1234 (VERT_TEX1_4|VERT_TEX1_123) +#define VERT_TEX1_ANY VERT_TEX1_12 + +#define VERT_TEX2_123 (VERT_TEX2_3|VERT_TEX2_12) +#define VERT_TEX2_1234 (VERT_TEX2_4|VERT_TEX2_123) +#define VERT_TEX2_ANY VERT_TEX2_12 + +#define VERT_TEX3_123 (VERT_TEX3_3|VERT_TEX3_12) +#define VERT_TEX3_1234 (VERT_TEX3_4|VERT_TEX3_123) +#define VERT_TEX3_ANY VERT_TEX3_12 + +#define NR_TEXSIZE_BITS 3 +#define VERT_TEX_ANY(i) (VERT_TEX0_ANY << ((i) * NR_TEXSIZE_BITS)) + +#define VERT_FIXUP (VERT_TEX0_ANY | \ + VERT_TEX1_ANY | \ + VERT_TEX2_ANY | \ + VERT_TEX3_ANY | \ + VERT_RGBA | \ + VERT_SPEC_RGB | \ + VERT_FOG_COORD | \ + VERT_INDEX | \ + VERT_EDGE | \ + VERT_NORM) + +#define VERT_DATA (VERT_TEX0_ANY | \ + VERT_TEX1_ANY | \ + VERT_TEX2_ANY | \ + VERT_TEX3_ANY | \ + VERT_RGBA | \ + VERT_SPEC_RGB | \ + VERT_FOG_COORD | \ + VERT_INDEX | \ + VERT_EDGE | \ + VERT_NORM | \ + VERT_OBJ_ANY | \ + VERT_MATERIAL | \ + VERT_ELT | \ + VERT_EVAL_ANY | \ + VERT_FOG_COORD) + + +/* For beginstate + */ +#define VERT_BEGIN_0 0x1 /* glBegin (if initially inside beg/end) */ +#define VERT_BEGIN_1 0x2 /* glBegin (if initially outside beg/end) */ +#define VERT_ERROR_0 0x4 /* invalid_operation in initial state 0 */ +#define VERT_ERROR_1 0x8 /* invalid_operation in initial state 1 */ + + +struct gl_pipeline; +struct tnl_context; + +/** + ** Vertex buffer/array structures + **/ + +struct vertex_data +{ + GLfloat (*Obj)[4]; + GLfloat (*Normal)[3]; + GLchan (*Color)[4]; + GLuint *Index; + GLubyte *EdgeFlag; + GLfloat (*TexCoord[MAX_TEXTURE_UNITS])[4]; + GLuint *Elt; + GLfloat *FogCoord; + GLubyte (*SecondaryColor)[4]; +}; + +struct vertex_arrays +{ + GLvector4f Obj; + GLvector3f Normal; + GLvector4ub Color; + GLvector1ui Index; + GLvector1ub EdgeFlag; + GLvector4f TexCoord[MAX_TEXTURE_UNITS]; + GLvector1ui Elt; + GLvector4ub SecondaryColor; + GLvector1f FogCoord; +}; + +struct vertex_array_pointers +{ + GLvector4f *Obj; + GLvector3f *Normal; + GLvector4ub *Color; + GLvector1ui *Index; + GLvector1ub *EdgeFlag; + GLvector4f *TexCoord[MAX_TEXTURE_UNITS]; + GLvector1ui *Elt; + GLvector4ub *SecondaryColor; + GLvector1f *FogCoord; +}; + +/* Values for VB->Type */ +enum { + VB_IMMEDIATE, + VB_CVA_PRECALC +}; + + +/* Values for immediate->BeginState */ +#define VERT_BEGIN_0 0x1 /* glBegin (if initially inside beg/end) */ +#define VERT_BEGIN_1 0x2 /* glBegin (if initially outside beg/end) */ +#define VERT_ERROR_0 0x4 /* invalid_operation in initial state 0 */ +#define VERT_ERROR_1 0x8 /* invalid_operation in initial state 1 */ + + +/* KW: Represents everything that can take place between a begin and + * end, and can represent multiple begin/end pairs. This plus *any* + * state variable (GLcontext) should be all you need to replay the + * represented begin/end pairs as if they took place in that state. + * + * Thus this is sufficient for both immediate and compiled modes, but + * we could/should throw some elements away for compiled mode if we + * know they were empty. + */ +struct immediate +{ + struct immediate *next; /* for cache of free IM's */ + GLuint id, ref_count; + + /* This must be saved when immediates are shared in display lists. + */ + GLuint Start, Count; + GLuint LastData; /* count or count+1 */ + GLuint AndFlag, OrFlag, BeginState; + GLuint LastPrimitive; + + GLuint ArrayAndFlags; /* precalc'ed for glArrayElt */ + GLuint ArrayIncr; + GLuint ArrayEltFlush; + GLuint FlushElt; + + GLuint TF1[MAX_TEXTURE_UNITS]; /* precalc'ed for glTexCoord */ + GLuint TF2[MAX_TEXTURE_UNITS]; + GLuint TF3[MAX_TEXTURE_UNITS]; + GLuint TF4[MAX_TEXTURE_UNITS]; + + GLuint Primitive[VB_SIZE]; /* GLubyte would do... */ + GLuint NextPrimitive[VB_SIZE]; + + /* allocate storage for these on demand: + */ + struct gl_material (*Material)[2]; + GLuint *MaterialMask; + + GLfloat (*TexCoordPtr[MAX_TEXTURE_UNITS])[4]; + + struct vertex_arrays v; + + struct __GLcontextRec *backref; + + /* Normal lengths, zero if not available. + */ + GLfloat *NormalLengths; + GLuint LastCalcedLength; + + GLuint Flag[VB_SIZE]; /* bitwise-OR of VERT_ flags */ + GLchan Color[VB_SIZE][4]; + GLfloat Obj[VB_SIZE][4]; + GLfloat Normal[VB_SIZE][3]; + GLfloat TexCoord[MAX_TEXTURE_UNITS][VB_SIZE][4]; + GLuint Elt[VB_SIZE]; + GLubyte EdgeFlag[VB_SIZE]; + GLuint Index[VB_SIZE]; + GLubyte SecondaryColor[VB_SIZE][4]; + GLfloat FogCoord[VB_SIZE]; +}; + + +/* Not so big on storage these days, although still has pointers to + * arrays used for temporary results. + */ +typedef struct vertex_buffer +{ + /* Backpointers. + */ + struct __GLcontextRec *ctx; + struct tnl_context *tnlctx; + + /* Driver_data is allocated in Driver.RegisterVB(), if required. + */ + void *driver_data; + + /* List of operations to process vertices in current state. + */ + struct gl_pipeline *pipeline; + + /* Temporary storage used by immediate mode functions and various + * operations in the pipeline. + */ + struct immediate *IM; + struct vertex_array_pointers store; + + /* Where to find outstanding untransformed vertices. + */ + struct immediate *prev_buffer; + + GLuint Type; /* Either VB_IMMEDIATE or VB_CVA_PRECALC */ + + GLuint Size, Start, Count; + GLuint Free, FirstFree; + GLuint CopyStart; + GLuint Parity, Ovf; + GLuint PurgeFlags; + GLuint IndirectCount; /* defaults to count */ + GLuint OrFlag, SavedOrFlag; + GLuint EarlyCull; + GLuint Culled, CullDone; + + /* Pointers to input data - default to buffers in 'im' above. + */ + GLvector4f *ObjPtr; + GLvector3f *NormalPtr; + GLvector4ub *ColorPtr; + GLvector1ui *IndexPtr; + GLvector1ub *EdgeFlagPtr; + GLvector4f *TexCoordPtr[MAX_TEXTURE_UNITS]; + GLvector1ui *EltPtr; + GLvector4ub *SecondaryColorPtr; + GLvector1f *FogCoordPtr; + GLuint *Flag, FlagMax; + struct gl_material (*Material)[2]; + GLuint *MaterialMask; + + GLuint *NextPrimitive; + GLuint *Primitive; + GLuint LastPrimitive; + + GLfloat (*BoundsPtr)[3]; /* Bounds for cull check */ + GLfloat *NormalLengthPtr; /* Array of precomputed inv. normal lengths */ + + /* Holds malloced storage for pipeline data not supplied by + * the immediate struct. + */ + GLvector4f Eye; + GLvector4f Clip; + GLvector4f Win; + GLvector4ub BColor; /* not used in cva vb's */ + GLvector1ui BIndex; /* not used in cva vb's */ + GLvector4ub BSecondary; /* not used in cva vb's */ + + /* Temporary storage - may point into IM, or be dynamically + * allocated (for cva). + */ + GLubyte *ClipMask; + GLubyte *UserClipMask; + + /* Internal values. Where these point depends on whether + * there were any identity matrices defined as transformations + * in the pipeline. + */ + GLvector4f *EyePtr; + GLvector4f *ClipPtr; + GLvector4f *Unprojected; + GLvector4f *Projected; + GLvector4f *CurrentTexCoord; + GLuint *Indirect; /* For eval rescue and cva render */ + + /* Currently active colors + */ + GLvector4ub *Color[2]; + GLvector1ui *Index[2]; + GLvector4ub *SecondaryColor[2]; + + /* Storage for colors which have been lit but not yet fogged. + * Required for CVA, just point into store for normal VB's. + */ + GLvector4ub *LitColor[2]; + GLvector1ui *LitIndex[2]; + GLvector4ub *LitSecondary[2]; + + /* Temporary values used in texgen. + */ + GLfloat (*tmp_f)[3]; + GLfloat *tmp_m; + + /* Temporary values used in eval. + */ + GLuint *EvaluatedFlags; + + /* Not used for cva: + */ + GLubyte *NormCullStart; + GLubyte *CullMask; /* Results of vertex culling */ + GLubyte *NormCullMask; /* Compressed onto shared normals */ + + GLubyte ClipOrMask; /* bitwise-OR of all ClipMask[] values */ + GLubyte ClipAndMask; /* bitwise-AND of all ClipMask[] values */ + GLubyte CullFlag[2]; + GLubyte CullMode; /* see flags below */ + + GLuint CopyCount; /* max 3 vertices to copy after transform */ + GLuint Copy[3]; + GLfloat CopyProj[3][4]; /* temporary store for projected clip coords */ + + /* Hooks for module private data + */ + void *swsetup_vb; + +} TNLvertexbuffer; + + +typedef void (*gl_shade_func)( struct vertex_buffer *VB ); + +typedef void (*clip_interp_func)( struct vertex_buffer *VB, GLuint dst, + GLfloat t, GLuint in, GLuint out ); + +typedef GLuint (*clip_line_func)( struct vertex_buffer *VB, + GLuint *i, GLuint *j, + GLubyte mask); + +typedef GLuint (*clip_poly_func)( struct vertex_buffer *VB, + GLuint n, GLuint vlist[], + GLubyte mask ); + + +#define MAX_PIPELINE_STAGES 30 + +#define PIPE_IMMEDIATE 0x1 +#define PIPE_PRECALC 0x2 + +#define PIPE_OP_VERT_XFORM 0x1 +#define PIPE_OP_NORM_XFORM 0x2 +#define PIPE_OP_LIGHT 0x4 +#define PIPE_OP_FOG 0x8 +#define PIPE_OP_TEX0 0x10 +#define PIPE_OP_TEX1 0x20 +#define PIPE_OP_TEX2 0x40 +#define PIPE_OP_TEX3 0x80 +#define PIPE_OP_RAST_SETUP_0 0x100 +#define PIPE_OP_RAST_SETUP_1 0x200 +#define PIPE_OP_RENDER 0x400 +#define PIPE_OP_CVA_PREPARE 0x800 + + + +struct gl_pipeline_stage { + const char *name; + GLuint ops; /* PIPE_OP flags */ + GLuint type; /* VERT flags */ + GLuint special; /* VERT flags - force update_inputs() */ + GLuint state_change; /* state flags - trigger update_inputs() */ + GLuint cva_state_change; /* state flags - recalc cva buffer */ + GLuint elt_forbidden_inputs; /* VERT flags - force a pipeline recalc */ + GLuint pre_forbidden_inputs; /* VERT flags - force a pipeline recalc */ + GLuint active; /* VERT flags */ + GLuint inputs; /* VERT flags */ + GLuint outputs; /* VERT flags */ + void (*check)( GLcontext *ctx, struct gl_pipeline_stage * ); + void (*run)( struct vertex_buffer *VB ); +}; + + +struct gl_pipeline { + GLuint state_change; /* state changes which require recalc */ + GLuint cva_state_change; /* ... which require re-run */ + GLuint forbidden_inputs; /* inputs which require recalc */ + GLuint ops; /* what gets done in this pipe */ + GLuint changed_ops; + GLuint inputs; + GLuint outputs; + GLuint new_inputs; + GLuint new_outputs; + GLuint fallback; + GLuint type; + GLuint pipeline_valid:1; + GLuint data_valid:1; + GLuint copy_transformed_data:1; + GLuint replay_copied_vertices:1; + GLuint new_state; /* state changes since last recalc */ + struct gl_pipeline_stage *stages[MAX_PIPELINE_STAGES]; +}; + + + +/* All fields are derived. + */ +struct gl_cva { + struct gl_pipeline pre; + struct gl_pipeline elt; + + struct gl_client_array Elt; + trans_1ui_func EltFunc; + + struct vertex_buffer *VB; + struct vertex_arrays v; + struct vertex_data store; + + GLuint elt_count; + GLenum elt_mode; + GLuint elt_size; + + GLuint forbidden_inputs; + GLuint orflag; + GLuint merge; + + GLuint lock_changed; + GLuint last_orflag; + GLuint last_array_flags; + GLuint last_array_new_state; +}; + + + +typedef void (*texgen_func)( struct vertex_buffer *VB, + GLuint textureSet); + + + +typedef struct tnl_context { + + GLuint _ArrayFlag[VB_SIZE]; /* crock */ + GLuint _ArrayFlags; + GLuint _ArraySummary; /* Like flags, but no size information */ + GLuint _ArrayNewState; /* Tracks which arrays have been changed. */ + + + /* Pipeline stages - shared between the two pipelines, + * which live in CVA. + */ + struct gl_pipeline_stage PipelineStage[MAX_PIPELINE_STAGES]; + GLuint NrPipelineStages; + + /* Per-texunit derived state. + */ + GLuint _TexgenSize[MAX_TEXTURE_UNITS]; + GLuint _TexgenHoles[MAX_TEXTURE_UNITS]; + texgen_func *_TexgenFunc[MAX_TEXTURE_UNITS]; + + + /* Display list extensions + */ + GLuint opcode_vertex_cassette; + + /* Cva + */ + struct gl_cva CVA; + GLboolean CompileCVAFlag; + + clip_poly_func *_poly_clip_tab; + clip_line_func *_line_clip_tab; + clip_interp_func _ClipInterpFunc; /* Clip interpolation function */ + normal_func *_NormalTransform; + gl_shade_func *_shade_func_tab; /* Current shading function table */ + + GLenum _CurrentPrimitive; /* Prim or GL_POLYGON+1 */ + GLuint _CurrentFlag; + + GLuint _RenderFlags; /* Active inputs to render stage */ + + /* Cache of unused immediate structs */ + struct immediate *freed_im_queue; + GLuint nr_im_queued; + +} TNLcontext; + + + +#define TNL_CONTEXT(ctx) ((TNLcontext *)(ctx->swtnl_context)) +#define TNL_CURRENT_IM(ctx) ((struct immediate *)(ctx->swtnl_im)) +#define TNL_VB(ctx) ((struct vertex_buffer *)(ctx->swtnl_vb)) + +extern void _tnl_reset_immediate( GLcontext *ctx ); +extern GLboolean _tnl_flush_vertices( GLcontext *ctx, GLuint flush_flags ); + + +extern void +_tnl_MakeCurrent( GLcontext *ctx, + GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ); + + +extern void +_tnl_LightingSpaceChange( GLcontext *ctx ); + +/* + * Macros for fetching current input buffer. + */ +#ifdef THREADS +#define GET_IMMEDIATE struct immediate *IM = TNL_CURRENT_IM(((GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()))) +#define SET_IMMEDIATE(ctx, im) ctx->swtnl_im = (void *)im +#else +extern struct immediate *_mesa_CurrentInput; +#define GET_IMMEDIATE struct immediate *IM = _mesa_CurrentInput +#define SET_IMMEDIATE(ctx, im) \ +do { \ + TNL_CURRENT_IM(ctx) = im; \ + _mesa_CurrentInput = im; \ +} while (0) +#endif + +#endif diff --git a/src/mesa/tnl/t_pipeline.c b/src/mesa/tnl/t_pipeline.c new file mode 100644 index 00000000000..03c93911b93 --- /dev/null +++ b/src/mesa/tnl/t_pipeline.c @@ -0,0 +1,496 @@ +/* $Id: t_pipeline.c,v 1.1 2000/11/16 21:05:42 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Dynamic pipelines, support for CVA. + * Copyright (C) 1999 Keith Whitwell. + */ + +#include "glheader.h" +#include "context.h" +#include "mem.h" +#include "mmath.h" +#include "state.h" +#include "types.h" + +#include "math/m_translate.h" +#include "math/m_xform.h" + +#include "t_bbox.h" +#include "t_clip.h" +#include "t_cva.h" +#include "t_fog.h" +#include "t_light.h" +#include "t_pipeline.h" +#include "t_shade.h" +#include "t_stages.h" +#include "t_vbcull.h" +#include "t_vbindirect.h" +#include "t_vbrender.h" +#include "t_vbxform.h" + + + + + +void gl_print_pipe_ops( const char *msg, GLuint flags ) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & PIPE_OP_CVA_PREPARE) ? "cva-prepare, " : "", + (flags & PIPE_OP_VERT_XFORM) ? "vert-xform, " : "", + (flags & PIPE_OP_NORM_XFORM) ? "norm-xform, " : "", + (flags & PIPE_OP_LIGHT) ? "light, " : "", + (flags & PIPE_OP_FOG) ? "fog, " : "", + (flags & PIPE_OP_TEX0) ? "tex-0, " : "", + (flags & PIPE_OP_TEX1) ? "tex-1, " : "", + (flags & PIPE_OP_RAST_SETUP_0) ? "rast-0, " : "", + (flags & PIPE_OP_RAST_SETUP_1) ? "rast-1, " : "", + (flags & PIPE_OP_RENDER) ? "render, " : ""); + +} + + + +/* Have to reset only those parts of the vb which are being recalculated. + */ +void gl_reset_cva_vb( struct vertex_buffer *VB, GLuint stages ) +{ + GLcontext *ctx = VB->ctx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (MESA_VERBOSE&VERBOSE_PIPELINE) + gl_print_pipe_ops( "reset cva vb", stages ); + + if (stages & PIPE_OP_VERT_XFORM) + { + if (VB->ClipOrMask & CLIP_USER_BIT) + MEMSET(VB->UserClipMask, 0, VB->Count); + + VB->ClipOrMask = 0; + VB->ClipAndMask = CLIP_ALL_BITS; + VB->CullMode = 0; + VB->CullFlag[0] = VB->CullFlag[1] = 0; + VB->Culled = 0; + } + + if (stages & PIPE_OP_NORM_XFORM) { + VB->NormalPtr = &tnl->CVA.v.Normal; + } + + if (stages & PIPE_OP_LIGHT) + { + VB->ColorPtr = VB->Color[0] = VB->Color[1] = &tnl->CVA.v.Color; + VB->IndexPtr = VB->Index[0] = VB->Index[1] = &tnl->CVA.v.Index; + } + else if (stages & PIPE_OP_FOG) + { + if (ctx->Light.Enabled) { + VB->Color[0] = VB->LitColor[0]; + VB->Color[1] = VB->LitColor[1]; + VB->Index[0] = VB->LitIndex[0]; + VB->Index[1] = VB->LitIndex[1]; + } else { + VB->Color[0] = VB->Color[1] = &tnl->CVA.v.Color; + VB->Index[0] = VB->Index[1] = &tnl->CVA.v.Index; + } + VB->ColorPtr = VB->Color[0]; + VB->IndexPtr = VB->Index[0]; + } +} + + + + + + +static void pipeline_ctr( struct gl_pipeline *p, GLcontext *ctx, GLuint type ) +{ + GLuint i; + (void) ctx; + + p->state_change = 0; + p->cva_state_change = 0; + p->inputs = 0; + p->outputs = 0; + p->type = type; + p->ops = 0; + + for (i = 0 ; i < gl_default_nr_stages ; i++) + p->state_change |= gl_default_pipeline[i].state_change; +} + + +void _tnl_pipeline_init( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + MEMCPY( tnl->PipelineStage, + gl_default_pipeline, + sizeof(*gl_default_pipeline) * gl_default_nr_stages ); + + tnl->NrPipelineStages = gl_default_nr_stages; + + pipeline_ctr( &tnl->CVA.elt, ctx, PIPE_IMMEDIATE); + pipeline_ctr( &tnl->CVA.pre, ctx, PIPE_PRECALC ); +} + + + +#define MINIMAL_VERT_DATA (VERT_DATA & ~(VERT_TEX0_4 | \ + VERT_TEX1_4 | \ + VERT_TEX2_4 | \ + VERT_TEX3_4 | \ + VERT_EVAL_ANY)) + +#define VERT_CURRENT_DATA (VERT_TEX0_1234 | \ + VERT_TEX1_1234 | \ + VERT_TEX2_1234 | \ + VERT_TEX3_1234 | \ + VERT_RGBA | \ + VERT_SPEC_RGB | \ + VERT_FOG_COORD | \ + VERT_INDEX | \ + VERT_EDGE | \ + VERT_NORM | \ + VERT_MATERIAL) + +/* Called prior to every recomputation of the CVA precalc data, except where + * the driver is able to calculate the pipeline unassisted. + */ +static void build_full_precalc_pipeline( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct gl_pipeline_stage *pipeline = tnl->PipelineStage; + struct gl_cva *cva = &tnl->CVA; + struct gl_pipeline *pre = &cva->pre; + struct gl_pipeline_stage **stages = pre->stages; + GLuint i; + GLuint newstate = pre->new_state; + GLuint changed_ops = 0; + GLuint oldoutputs = pre->outputs; + GLuint oldinputs = pre->inputs; + GLuint fallback = (VERT_CURRENT_DATA & tnl->_CurrentFlag & + ~tnl->_ArraySummary); + GLuint changed_outputs = (tnl->_ArrayNewState | + (fallback & cva->orflag)); + GLuint available = fallback | tnl->_ArrayFlags; + + pre->cva_state_change = 0; + pre->ops = 0; + pre->outputs = 0; + pre->inputs = 0; + pre->forbidden_inputs = 0; + pre->fallback = 0; + + /* KW: Disable data reuse during Mesa reorg. Make this more readable... + */ + newstate = ~0; + + if (tnl->_ArraySummary & VERT_ELT) + cva->orflag &= VERT_MATERIAL; + + cva->orflag &= ~(tnl->_ArraySummary & ~VERT_OBJ_ANY); + available &= ~cva->orflag; + + pre->outputs = available; + pre->inputs = available; + + if (MESA_VERBOSE & VERBOSE_PIPELINE) { + fprintf(stderr, ": Rebuild pipeline\n"); + gl_print_vert_flags("orflag", cva->orflag); + } + + + + /* If something changes in the pipeline, tag all subsequent stages + * using this value for recalcuation. Also used to build the full + * pipeline by setting newstate and newinputs to ~0. + * + * Because all intermediate values are buffered, the new inputs + * are enough to fully specify what needs to be calculated, and a + * single pass identifies all stages requiring recalculation. + */ + for (i = 0 ; i < tnl->NrPipelineStages ; i++) + { + pipeline[i].check(ctx, &pipeline[i]); + + if (pipeline[i].type & PIPE_PRECALC) + { + if ((newstate & pipeline[i].cva_state_change) || + (changed_outputs & pipeline[i].inputs) || + !pipeline[i].inputs) + { + changed_ops |= pipeline[i].ops; + changed_outputs |= pipeline[i].outputs; + pipeline[i].active &= ~PIPE_PRECALC; + + if ((pipeline[i].inputs & ~available) == 0 && + (pipeline[i].ops & pre->ops) == 0) + { + pipeline[i].active |= PIPE_PRECALC; + *stages++ = &pipeline[i]; + } + } + + /* Incompatible with multiple stages structs implementing + * the same stage. + */ + available &= ~pipeline[i].outputs; + pre->outputs &= ~pipeline[i].outputs; + + if (pipeline[i].active & PIPE_PRECALC) { + pre->ops |= pipeline[i].ops; + pre->outputs |= pipeline[i].outputs; + available |= pipeline[i].outputs; + pre->forbidden_inputs |= pipeline[i].pre_forbidden_inputs; + } + } + else if (pipeline[i].active & PIPE_PRECALC) + { + pipeline[i].active &= ~PIPE_PRECALC; + changed_outputs |= pipeline[i].outputs; + changed_ops |= pipeline[i].ops; + } + } + + *stages = 0; + + pre->new_outputs = pre->outputs & (changed_outputs | ~oldoutputs); + pre->new_inputs = pre->inputs & ~oldinputs; + pre->fallback = pre->inputs & fallback; + pre->forbidden_inputs |= pre->inputs & fallback; + + pre->changed_ops = changed_ops; +} + +void gl_build_precalc_pipeline( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct gl_pipeline *pre = &tnl->CVA.pre; + struct gl_pipeline *elt = &tnl->CVA.elt; + + if (!ctx->Driver.BuildPrecalcPipeline || + !ctx->Driver.BuildPrecalcPipeline( ctx )) + build_full_precalc_pipeline( ctx ); + + pre->data_valid = 0; + pre->pipeline_valid = 1; + elt->pipeline_valid = 0; + + tnl->CVA.orflag = 0; + + if (MESA_VERBOSE&VERBOSE_PIPELINE) + gl_print_pipeline( ctx, pre ); +} + + +static void build_full_immediate_pipeline( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct gl_pipeline_stage *pipeline = tnl->PipelineStage; + struct gl_cva *cva = &tnl->CVA; + struct gl_pipeline *pre = &cva->pre; + struct gl_pipeline *elt = &cva->elt; + struct gl_pipeline_stage **stages = elt->stages; + GLuint i; + GLuint newstate = elt->new_state; + GLuint active_ops = 0; + GLuint available = cva->orflag | MINIMAL_VERT_DATA; + GLuint generated = 0; + GLuint is_elt = 0; + + if (pre->data_valid && tnl->CompileCVAFlag) { + is_elt = 1; + active_ops = cva->pre.ops; + available |= pre->outputs | VERT_PRECALC_DATA; + } + + + elt->outputs = 0; /* not used */ + elt->inputs = 0; + + for (i = 0 ; i < tnl->NrPipelineStages ; i++) { + pipeline[i].active &= ~PIPE_IMMEDIATE; + + if ((pipeline[i].state_change & newstate) || + (pipeline[i].elt_forbidden_inputs & available)) + { + pipeline[i].check(ctx, &pipeline[i]); + } + + if ((pipeline[i].type & PIPE_IMMEDIATE) && + (pipeline[i].ops & active_ops) == 0 && + (pipeline[i].elt_forbidden_inputs & available) == 0 + ) + { + if (pipeline[i].inputs & ~available) + elt->forbidden_inputs |= pipeline[i].inputs & ~available; + else + { + elt->inputs |= pipeline[i].inputs & ~generated; + elt->forbidden_inputs |= pipeline[i].elt_forbidden_inputs; + pipeline[i].active |= PIPE_IMMEDIATE; + *stages++ = &pipeline[i]; + generated |= pipeline[i].outputs; + available |= pipeline[i].outputs; + active_ops |= pipeline[i].ops; + } + } + } + + *stages = 0; + + elt->copy_transformed_data = 1; + elt->replay_copied_vertices = 0; + + if (is_elt) { + cva->merge = elt->inputs & pre->outputs; + elt->ops = active_ops & ~pre->ops; + } +} + + + +void gl_build_immediate_pipeline( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct gl_pipeline *elt = &tnl->CVA.elt; + + if (!ctx->Driver.BuildEltPipeline || + !ctx->Driver.BuildEltPipeline( ctx )) { + build_full_immediate_pipeline( ctx ); + } + + elt->pipeline_valid = 1; + tnl->CVA.orflag = 0; + + if (MESA_VERBOSE&VERBOSE_PIPELINE) + gl_print_pipeline( ctx, elt ); +} + +#define INTERESTED ~0 + +void gl_update_pipelines( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint newstate = ctx->NewState; + struct gl_cva *cva = &tnl->CVA; + + newstate &= INTERESTED; + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_STATE)) + gl_print_enable_flags("enabled", ctx->_Enabled); + + if (newstate || + cva->lock_changed || + cva->orflag != cva->last_orflag || + tnl->_ArrayFlags != cva->last_array_flags) + { + GLuint flags = VERT_WIN; + + if (ctx->Visual.RGBAflag) { + flags |= VERT_RGBA; + if (ctx->_TriangleCaps && DD_SEPERATE_SPECULAR) + flags |= VERT_SPEC_RGB; + } else + flags |= VERT_INDEX; + + if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) + flags |= VERT_TEX0_ANY; + + if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY) + flags |= VERT_TEX1_ANY; + +#if MAX_TEXTURE_UNITS > 2 + if (ctx->Texture._ReallyEnabled & TEXTURE2_ANY) + flags |= VERT_TEX2_ANY; +#endif +#if MAX_TEXTURE_UNITS > 3 + if (ctx->Texture._ReallyEnabled & TEXTURE3_ANY) + flags |= VERT_TEX3_ANY; +#endif + + if (ctx->Polygon._Unfilled) + flags |= VERT_EDGE; + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) + flags |= VERT_FOG_COORD; + + if (ctx->RenderMode==GL_FEEDBACK) { + flags = (VERT_WIN | VERT_RGBA | VERT_INDEX | VERT_NORM | VERT_EDGE + | VERT_TEX0_ANY + | VERT_TEX1_ANY +#if MAX_TEXTURE_UNITS > 2 + | VERT_TEX2_ANY +#endif +#if MAX_TEXTURE_UNITS > 3 + | VERT_TEX3_ANY +#endif + ); + } + + tnl->_RenderFlags = flags; + + cva->elt.new_state |= newstate; + cva->elt.pipeline_valid = 0; + + cva->pre.new_state |= newstate; + cva->pre.forbidden_inputs = 0; + cva->pre.pipeline_valid = 0; + cva->lock_changed = 0; + } + + if (tnl->_ArrayNewState != cva->last_array_new_state) + cva->pre.pipeline_valid = 0; + + cva->pre.data_valid = 0; + cva->last_array_new_state = tnl->_ArrayNewState; + cva->last_orflag = cva->orflag; + cva->last_array_flags = tnl->_ArrayFlags; +} + +void gl_run_pipeline( struct vertex_buffer *VB ) +{ + struct gl_pipeline *pipe = VB->pipeline; + struct gl_pipeline_stage **stages = pipe->stages; + unsigned short x; + + pipe->data_valid = 1; /* optimized stages might want to reset this. */ + + if (0) gl_print_pipeline( VB->ctx, pipe ); + + START_FAST_MATH(x); + + for ( VB->Culled = 0; *stages && !VB->Culled ; stages++ ) + (*stages)->run( VB ); + + END_FAST_MATH(x); + + pipe->new_state = 0; +} + diff --git a/src/mesa/tnl/t_pipeline.h b/src/mesa/tnl/t_pipeline.h new file mode 100644 index 00000000000..36a2f066c23 --- /dev/null +++ b/src/mesa/tnl/t_pipeline.h @@ -0,0 +1,59 @@ +/* $Id: t_pipeline.h,v 1.1 2000/11/16 21:05:42 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: + * Keith Whitwell <[email protected]> + */ + + + +#ifndef _T_PIPELINE_H_ +#define _T_PIPELINE_H_ + +#include "types.h" +#include "t_context.h" + +extern void gl_update_materials( struct vertex_buffer *VB); + +extern void _tnl_pipeline_init( GLcontext *ctx ); +extern void gl_update_pipelines( GLcontext *ctx ); + +extern void gl_build_precalc_pipeline( GLcontext *ctx ); +extern void gl_build_immediate_pipeline( GLcontext *ctx ); + +extern void gl_print_vert_flags( const char *name, GLuint flags ); +extern void gl_print_pipeline( GLcontext *ctx, struct gl_pipeline *p ); +extern void gl_print_active_pipeline( GLcontext *ctx, struct gl_pipeline *p ); + +extern void gl_run_pipeline( struct vertex_buffer *VB ); + +extern void gl_clean_color( struct vertex_buffer *VB ); + +extern void gl_reset_cva_vb( struct vertex_buffer *VB, GLuint stages ); + +extern void gl_print_pipe_ops( const char *msg, GLuint flags ); + +#endif diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h new file mode 100644 index 00000000000..dc46ef31346 --- /dev/null +++ b/src/mesa/tnl/tnl.h @@ -0,0 +1,48 @@ +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <[email protected]> + */ + +#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 diff --git a/src/mesa/x86/3dnow.c b/src/mesa/x86/3dnow.c index 3becc8cc58c..f0e5e3af1ca 100644 --- a/src/mesa/x86/3dnow.c +++ b/src/mesa/x86/3dnow.c @@ -1,4 +1,4 @@ -/* $Id: 3dnow.c,v 1.8 2000/10/23 00:16:28 gareth Exp $ */ +/* $Id: 3dnow.c,v 1.9 2000/11/16 21:05:41 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -32,12 +32,13 @@ #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 diff --git a/src/mesa/x86/3dnow.h b/src/mesa/x86/3dnow.h index 1e17cc4bb4b..ee87c5af3dd 100644 --- a/src/mesa/x86/3dnow.h +++ b/src/mesa/x86/3dnow.h @@ -1,4 +1,4 @@ -/* $Id: 3dnow.h,v 1.2 2000/10/23 00:16:28 gareth Exp $ */ +/* $Id: 3dnow.h,v 1.3 2000/11/16 21:05:41 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -32,7 +32,7 @@ #ifndef __3DNOW_H__ #define __3DNOW_H__ -#include "xform.h" +#include "math/m_xform.h" void gl_init_3dnow_transform_asm( void ); void gl_init_3dnow_vertex_asm( void ); diff --git a/src/mesa/x86/common_x86_asm.h b/src/mesa/x86/common_x86_asm.h index 880be22e8f8..f52f56da685 100644 --- a/src/mesa/x86/common_x86_asm.h +++ b/src/mesa/x86/common_x86_asm.h @@ -1,4 +1,4 @@ -/* $Id: common_x86_asm.h,v 1.2 2000/10/23 00:16:28 gareth Exp $ */ +/* $Id: common_x86_asm.h,v 1.3 2000/11/16 21:05:41 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -39,6 +39,8 @@ #ifndef __COMMON_X86_ASM_H__ #define __COMMON_X86_ASM_H__ +/* Do not reference types.h from this file. + */ #include "common_x86_features.h" #ifdef HAVE_CONFIG_H diff --git a/src/mesa/x86/x86.c b/src/mesa/x86/x86.c index fcd097867c4..fe750ad7652 100644 --- a/src/mesa/x86/x86.c +++ b/src/mesa/x86/x86.c @@ -1,4 +1,4 @@ -/* $Id: x86.c,v 1.9 2000/10/23 00:16:28 gareth Exp $ */ +/* $Id: x86.c,v 1.10 2000/11/16 21:05:41 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -31,12 +31,12 @@ #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 |