From 23caf20169ac38436ee9c13914f1d6aa7cf6bb5e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 16 Nov 2000 21:05:34 +0000 Subject: [PATCH] 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. --- src/mesa/Makefile.X11 | 51 +- src/mesa/drivers/ggi/ggimesa.c | 2 +- src/mesa/drivers/glide/fxapi.c | 582 +---------- src/mesa/drivers/glide/fxdd.c | 41 +- src/mesa/drivers/glide/fxdrv.h | 11 +- src/mesa/drivers/glide/fxsetup.c | 2 + src/mesa/drivers/osmesa/osmesa.c | 13 +- src/mesa/drivers/svga/svgamesa.c | 4 +- src/mesa/drivers/x11/xm_api.c | 9 +- src/mesa/drivers/x11/xm_dd.c | 5 +- src/mesa/drivers/x11/xm_line.c | 3 +- src/mesa/drivers/x11/xm_span.c | 3 +- src/mesa/drivers/x11/xm_tri.c | 5 +- src/mesa/main/Makefile.X11 | 51 +- src/mesa/main/attrib.c | 6 +- src/mesa/main/clip.c | 417 +------- src/mesa/main/clip.h | 57 +- src/mesa/main/colormac.h | 5 +- src/mesa/main/context.c | 250 ++--- src/mesa/main/context.h | 21 +- src/mesa/main/dd.h | 127 ++- src/mesa/main/debug.c | 89 ++ src/mesa/main/debug.h | 8 + src/mesa/main/dlist.c | 869 ++++++++--------- src/mesa/main/dlist.h | 14 +- src/mesa/main/drawpix.c | 8 +- src/mesa/main/enable.c | 24 +- src/mesa/main/eval.c | 1397 +-------------------------- src/mesa/main/eval.h | 39 +- src/mesa/main/fog.c | 104 +- src/mesa/main/fog.h | 6 +- src/mesa/main/get.c | 66 +- src/mesa/main/light.c | 150 +-- src/mesa/main/light.h | 28 +- src/mesa/main/lines.c | 3 +- src/mesa/main/macros.h | 4 +- src/mesa/main/matrix.c | 1151 +--------------------- src/mesa/main/matrix.h | 33 +- src/mesa/main/points.c | 3 +- src/mesa/main/rastpos.c | 203 +++- src/mesa/main/state.c | 204 +--- src/mesa/main/texstate.c | 29 +- src/mesa/main/texstate.h | 4 +- src/mesa/main/varray.c | 745 +------------- src/mesa/main/varray.h | 46 +- src/mesa/math/m_clip_tmp.h | 175 ++++ src/mesa/math/m_copy_tmp.h | 126 +++ src/mesa/math/m_debug_xform.c | 930 ++++++++++++++++++ src/mesa/math/m_dotprod_tmp.h | 128 +++ src/mesa/math/m_matrix.c | 1113 +++++++++++++++++++++ src/mesa/math/m_matrix.h | 176 ++++ src/mesa/math/m_norm_tmp.h | 413 ++++++++ src/mesa/math/m_trans_tmp.h | 210 ++++ src/mesa/math/m_translate.c | 478 +++++++++ src/mesa/math/m_translate.h | 92 ++ src/mesa/math/m_vector.c | 367 +++++++ src/mesa/math/m_vector.h | 188 ++++ src/mesa/math/m_xform.c | 251 +++++ src/mesa/math/m_xform.h | 224 +++++ src/mesa/math/m_xform_tmp.h | 974 +++++++++++++++++++ src/mesa/swrast/s_bitmap.c | 7 +- src/mesa/swrast/s_lines.c | 3 +- src/mesa/swrast/s_points.c | 3 +- src/mesa/swrast_setup/ss_context.c | 3 +- src/mesa/swrast_setup/ss_triangle.c | 2 + src/mesa/swrast_setup/ss_tritmp.h | 6 +- src/mesa/swrast_setup/ss_vb.c | 5 +- src/mesa/swrast_setup/ss_vbtmp.h | 3 +- src/mesa/tnl/t_context.c | 201 ++++ src/mesa/tnl/t_context.h | 629 ++++++++++++ src/mesa/tnl/t_pipeline.c | 496 ++++++++++ src/mesa/tnl/t_pipeline.h | 59 ++ src/mesa/tnl/tnl.h | 48 + src/mesa/x86/3dnow.c | 9 +- src/mesa/x86/3dnow.h | 4 +- src/mesa/x86/common_x86_asm.h | 4 +- src/mesa/x86/x86.c | 8 +- 77 files changed, 8561 insertions(+), 5666 deletions(-) create mode 100644 src/mesa/main/debug.c create mode 100644 src/mesa/main/debug.h create mode 100644 src/mesa/math/m_clip_tmp.h create mode 100644 src/mesa/math/m_copy_tmp.h create mode 100644 src/mesa/math/m_debug_xform.c create mode 100644 src/mesa/math/m_dotprod_tmp.h create mode 100644 src/mesa/math/m_matrix.c create mode 100644 src/mesa/math/m_matrix.h create mode 100644 src/mesa/math/m_norm_tmp.h create mode 100644 src/mesa/math/m_trans_tmp.h create mode 100644 src/mesa/math/m_translate.c create mode 100644 src/mesa/math/m_translate.h create mode 100644 src/mesa/math/m_vector.c create mode 100644 src/mesa/math/m_vector.h create mode 100644 src/mesa/math/m_xform.c create mode 100644 src/mesa/math/m_xform.h create mode 100644 src/mesa/math/m_xform_tmp.h create mode 100644 src/mesa/tnl/t_context.c create mode 100644 src/mesa/tnl/t_context.h create mode 100644 src/mesa/tnl/t_pipeline.c create mode 100644 src/mesa/tnl/t_pipeline.h create mode 100644 src/mesa/tnl/tnl.h 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 (davibu@tin.it) Humanware s.r.l. - * - introduced a new MESA_GLX_FX related behavior - * - the Glide fog table was built in a wrong way (using - * gu* Glide function). Added the code for building the - * table following the OpenGL specs. Thanks to Steve Baker - * for highlighting the problem. - * - fixed few problems in my and Keith's fxDDClear code - * - merged my code with the Keith's one - * - used the new BlendFunc Mesa device driver function - * - used the new AlphaFunc Mesa device driver function - * - used the new Enable Mesa device driver function - * - fixed a bug related to fog in the Mesa core. Fog - * were applied two times: at vertex level and at fragment - * level (thanks to Steve Baker for reporting the problem) - * - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE) now works - * (thanks to Jiri Pop for reporting the problem) - * - the driver works fine with OpenGL Unreal - * - fixed a bug in the Mesa core clipping code (related - * to the q texture coordinate) - * - introduced the support for the q texture coordinate - * - * Keith Whitwell (keithw@cableinet.co.uk) - * - optimized the driver and written all the new code - * required by the new Mesa-3.1 device driver API - * and by the new Mesa-3.1 core changes - * - written the cva support and many other stuff - * - * Brian Paul (brian_paul@avid.com) Avid Technology - * - fixed display list share bug for MESA_GLX_FX = window/fullscreen - * - fixed glClear/gl...Mask related problem - * - * Bert Schoenwaelder (bert@prinz-atm.CS.Uni-Magdeburg.De) - * - the driver is now able to sleep when waiting for the completation - * of multiple swapbuffer operations instead of wasting - * CPU time (NOTE: you must uncomment the lines in the - * fxMesaSwapBuffers function in order to enable this option) - * - * Eero Pajarre (epajarre@koti.tpo.fi) - * - enabled the macro FLOAT_COLOR_TO_UBYTE_COLOR under - * windows - * - written an asm x86 optimized float->integer conversions - * for windows - * - * Theodore Jump (tjump@cais.com) - * - fixed a small problem in the __wglMonitor function of the - * wgl emulator - * - written the in-window-rendering hack support for windows - * and Vooodoo1/2 cards - * - * V0.29 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - included in Mesa-3.0 - * - now glGetString(GL_RENDERER) returns more information - * about the hardware configuration: "Mesa Glide - * CARD/ FB/ - * TM/ TMU/" - * where: CARD is the card used for the current context, - * FB is the number of MB for the framebuffer, - * TM is the number of MB for the texture memory, - * TMU is the number of TMU. You can try to run - * Mesa/demos/glinfo in order to have an example of the - * output - * - fixed a problem of the WGL emulator with the - * OpenGL Optimizer 1.1 (thanks to Erwin Coumans for - * the bug report) - * - fixed some bug in the fxwgl.c code (thanks to - * Peter Pettersson for a patch and a bug report) - * - * Theodore Jump (tjump@cais.com) - * - written the SST_DUALHEAD support in the WGL emulator - * - * Daryll Strauss (daryll@harlot.rb.ca.us) - * - fixed the Voodoo Rush support for the in window rendering - * - * V0.28 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - the only supported multitexture functions are GL_MODULATE - * for texture set 0 and GL_MODULATE for texture set 1. In - * all other cases, the driver falls back to pure software - * rendering - * - written the support for the new GL_EXT_multitexture - * - written the DD_MAX_TEXTURE_COORD_SETS support in the - * fxDDGetParameteri() function - * - the driver falls back to pure software rendering when - * texture mapping function is GL_BLEND - * - * V0.27 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - inluded in the Mesa-3.0beta5 - * - written a smal extension (GL_FXMESA_global_texture_lod_bias) in - * order to expose the LOD bias related Glide function - * - fixed a bug fxDDWriteMonoRGBAPixels() - * - the driver is now able to fallback to software rendering in - * any case not directly supported by the hardware - * - written the support for enabling/disabling dithering - * - the in-window-rendering hack now works with any X11 screen - * depth - * - fixed a problem related to color/depth/alpha buffer clears - * - fixed a problem when clearing buffer for a context with the - * alpha buffer - * - fixed a problem in the fxTMReloadSubMipMapLevel() function, - * I have forget a "break;" (thanks to Joe Waters for the bug report) - * - fixed a problem in the color format for the in window - * rendering hack - * - written the fxDDReadRGBAPixels function - * - written the fxDDDepthTestPixelsGeneric function - * - written the fxDDDepthTestSpanGeneric function - * - written the fxDDWriteMonoRGBAPixels function - * - written the fxDDWriteRGBAPixels function - * - removed the multitexture emulation code for Voodoo board - * with only one TMU - * - * Chris Prince - * - fixed a new bug in the wglUseFontBitmaps code - * - * Ralf Knoesel (rknoesel@Stormfront.com) - * - fixed a bug in the wglUseFontBitmaps code - * - * Rune Hasvold (runeh@ifi.uio.no) - * - fixed a problem related to the aux usage in the fxBestResolution - * function - * - fixed the order of pixel formats in the WGL emulator - * - * Fredrik Hubinette (hubbe@hubbe.net) - * - the driver shutdown the Glide for most common signals - * - * V0.26 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - included in the Mesa-3.0beta4 - * - fixed a problem related to a my optimization for the Rune's - * pixel-span optimization - * - fixed a problem related to fxDDSetNearFar() and ctx->ProjectionMatrixType - * (thanks to Ben "Ctrl-Alt-Delete" and the Raul Alonso's ssystem) - * - fixed a small bug in the Rune's pixel-span optimization - * - fixed a problem with GL_CCW (thanks to Curt Olson for and example - * of the problem) - * - grVertex setup code is now ready for the internal thread support - * - fixed a no used optimization with clipped vertices in - * grVertex setup code - * - fixed a problem in the GL_LIGHT_MODEL_TWO_SIDE support (thanks - * to Patrick H. Madden for a complete example of the bug) - * - * Rune Hasvold (runeh@ifi.uio.no) - * - highly optimized the driver functions for writing pixel - * span (2-3 times faster !) - * - * Axel W. Volley (volley@acm.org) Krauss-Maffei Wehrtechnik - * - written the fxDDReadDepthSpanFloat() and fxDDReadDepthSpanInt() - * functions - * - * V0.25 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - fixed a problem with Voodoo boards with only one TMU - * - fixed a bug in the fxMesaCreateContext() - * - now the GL_FRONT_AND_BACK works fine also with - * the alpha buffer and/or antialiasing - * - written the support for GL_FRONT_AND_BACK drawing but - * it doesn't works with the alpha buffer and/or antialiasing - * - fixed some bug in the Mesa core for glCopyTexSubImage - * and glCopyTexImage functions (thanks to Mike Connell - * for an example of the problem) - * - make some small optimizations in the Mesa core in order - * to save same driver call and state change for not very - * well written applications - * - introduced the NEW_DRVSTATE and make other optimizations - * for minimizing state changes - * - made a lot of optimizations in order to minimize state - * changes - * - it isn't more possible to create a context with the - * depth buffer and the stancil buffer (it isn't yet supported) - * - now the partial support for the Multitexture extension - * works with Quake2 for windows - * - vertex snap is not longer used for the Voodoo2 (FX_V2 - * must be defined) - * - done a lot of cleanup in the fxsetup.c file - * - now the partial support for the Multitexture extension - * works with GLQuake for windows - * - * Dieter Nuetzel (nuetzel@kogs.informatik.uni-hamburg.de) University of Hamburg - * - fixed a problem in the asm code for Linux of the fxvsetup.c file - * highlighted by the binutils-2.8.1.0.29. 'fildw' asm instruction - * changed in 'fild' - * - * Kevin Hester (kevinh@glassworks.net) - * - written the wglUseFontBitmaps() function in the WGL emulator - * - * V0.24 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - now the drive always uses per fragment fog - * - written a small optimization in the points drawing function - * - written the support for trilinear filtering with 2 TMUs - * - written the first partial support for the Multitexture extension. - * This task is quite hard because the color combine units work after - * the two texture combine units and not before as required by the - * Multitexture extension - * - written a workaround in fxBestResolution() in order to solve a - * problem with bzflag (it asks for 1x1 window !) - * - changed the fxBestResolution() behavior. It now returns the larger - * screen resolution supported by the hardware (instead of 640x480) - * when it is unable to find an appropriate resolution that is large - * enough for the requested size - * - the driver is now able to use also the texture memory attached to - * second TMU - * - the texture memory manager is now able to work with two TMUs and - * store texture maps in the memory attached to TMU0, TMU1 or to split - * the mimpmap levels across TMUs in order to support trilinear filtering - * - I have bought a Voodoo2 board ! - * - the amount of frambuffer ram is now doubled when an SLI configuration - * is detected - * - solved a problem related to the fxDDTexParam() and fxTexInvalidate() - * functions (thanks to Rune Hasvold for highlighting the problem) - * - done some cleanup in the fxvsetup.c file, written - * the FXVSETUP_FUNC macro - * - done a lot of cleanup in data types and field names - * - * Rune Hasvold (runeh@ifi.uio.no) - * - written the support for a right management of the auxiliary buffer. - * You can now use an 800x600 screen without the depth and alpha - * buffer - * - written the support for a new pixel format (without the depth - * and alpha buffer) in the WGL emulator - * - fixed a bug in the window version of the GLUT (it was ever asking - * for depth buffer) - * - * V0.23 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - included in the Mesa-3.0beta2 release - * - written the support for the OpenGL 1.2 GL_TEXTURE_BASE_LEVEL - * and GL_TEXTURE_MAX_LEVEL - * - rewritten several functions for a more clean support of texture - * mapping and in order to solve some bug - * - the accumulation buffer works (it is bit slow beacuase it requires - * to read/write from/to the Voodoo frame buffer but it works) - * - fixed a bug in the fxDDReadRGBASpan driver function (the R and - * B channels were read in the wrong order). Thanks to Jason Heym - * for highlighting the problem - * - written the support for multiple contexts on multiple boards. - * you can now use the Mesa/Voodoo with multiple Voodoo Graphics - * boards (for example with multiple screens or an HMD) - * - the fxBestResolution() now check all available resolutions - * and it is able to check the amount of framebuffer memory - * before return a resolution - * - modified the GLX/X11 driver in order to support all the - * resolution available - * - changed all function names. They should be now a bit more - * readable - * - written the Glide grVertex setup code for two TMU or - * for Multitexture support with emulationa dn one TMU - * - written the support for the new Mesa driver - * function GetParametri - * - small optimization/clean up in the texbind() function - * - fixed a FPU precision problem for glOrtho and texture - * mapping (thanks to Antti Juhani Huovilainen for an example - * of the problem) - * - written some small SGI OpenGL emulation code for the wgl, - * the OpenGL Optimizer and Cosmo3D work fine under windows ! - * - moved the point/line/triangle/quad support in the fxmesa7.c - * - fixed a bug in the clear_color_depth() (thanks to Henk Kok - * for an example of the problem) - * - written a small workaround for Linux GLQuake, it asks - * for the alpha buffer and the depth buffer at the some time - * (but it never uses the alpha buffer) - * - checked the antialiasing points, lines and polygons support. - * It works fine - * - written the support for standard OpenGL antialiasing using - * blending. Lines support works fine (tested with BZflag) - * while I have still to check the polygons and points support - * - written the support for the alpha buffer. The driver is now - * able to use the Voodoo auxiliary buffer as an alpha buffer - * instead of a depth buffer. Also all the OpenGL blending - * modes are now supported. But you can't request a context - * with an alpha buffer AND a depth buffer at the some time - * (this is an hardware limitation) - * - written the support for switching between the fullscreen - * rendering and the in-window-rendering hack on the fly - * - * Rune Hasvold (runeh@ifi.uio.no) - * - fixed a bug in the texparam() function - * - * Brian Paul (brianp@elastic.avid.com) Avid Technology - * - sources accomodated for the new Mesa 3.0beta1 - * - * V0.22 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - included with some v0.23 bug fix in the final release - * of the Mesa-2.6 - * - written the support for the MESA_WGL_FX env. var. but - * not tested because I have only Voodoo Graphics boards - * - fixed a bug in the backface culling code - * (thanks to David Farrell for an example of the problem) - * - fixed the "Quake2 elevator" bug - * - GL_POLYGONS with 3/4 vertices are now drawn as - * GL_TRIANLGES/GL_QUADS (a small optimization for GLQuake) - * - fixed a bug in fxmesa6.h for GL_LINE_LOOP - * - fixed a NearFarStack bug in the Mesa when applications - * directly call glLoadMatrix to load a projection matrix - * - done some cleanup in the fxmesa2.c file - * - the driver no longer translates the texture maps - * when the Mesa internal format and the Voodoo - * format are the some (usefull for 1 byte texture maps - * where the driver can directly use the Mesa texture - * map). Also the amount of used memory is halfed - * - fixed a bug for GL_DECAL and GL_RGBA - * - fixed a bug in the clear_color_depth() - * - tested the v0.22 with the Mesa-2.6beta2. Impressive - * performances improvement thanks to the new Josh's - * asm code (+10fps in the isosurf demo, +5fps in GLQuake - * TIMEREFRESH) - * - written a optimized version of the RenderVB Mesa driver - * function. The Voodoo driver is now able to upload polygons - * in the most common cases at a very good speed. Good - * performance improvement for large set of small polygons - * - optimized the asm code for setting up the color information - * in the Glide grVertex structure - * - fixed a bug in the fxmesa2.c asm code (the ClipMask[] - * wasn't working) - * - * Josh Vanderhoof (joshv@planet.net) - * - removed the flush() function because it isn't required - * - limited the maximum number of swapbuffers in the Voodoo - * commands FIFO (controlled by the env. var. MESA_FX_SWAP_PENDING) - * - * Holger Kleemiss (holger.kleemiss@metronet.de) STN Atlas Elektronik GmbH - * - applied some patch for the Voodoo Rush - * - * V0.21 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - the driver is now able to take advantage of the ClipMask[], - * ClipOrMask and ClipAndMask information also under Windows - * - introduced a new function in the Mesa driver interface - * ClearColorAndDepth(). Now the glClear() function is - * 2 times faster (!) when you have to clear the color buffer - * and the depth buffer at some time - * - written the first version of the fxRenderVB() driver - * function - * - optimized the glTexImage() path - * - removed the fxMesaTextureUsePalette() support - * - fixed a bug in the points support (thanks to David Farrell - * for an example of the problem) - * - written the optimized path for glSubTexImage(), - * introduced a new function in the Mesa driver interface - * TexSubImage(...) - * - fixed a bug for glColorMask and glDepthMask - * - the wbuffer is not more used. The Voodoo driver uses - * a standard 16bit zbuffer in all cases. It is more consistent - * and now GLQuake and GLQuake2test work also with a GL_ZTRICK 0 - * - the driver is now able to take advantage of the ClipMask[], - * ClipOrMask and ClipAndMask information (under Linux); - * - rewritten the setup_fx_units() function, now the texture - * mapping support is compliant to the OpenGL specs (GL_BLEND - * support is still missing). The LinuxGLQuake console correctly - * fade in/out and transparent water of GLQuake2test works fine - * - written the support for the env. var. FX_GLIDE_SWAPINTERVAL - * - found a bug in the Mesa core. There is a roundup problem for - * color values out of the [0.0,1.0] range - * - * Wonko - * - fixed a Voodoo Rush related problem in the fxwgl.c - * - * Daryll Strauss - * - written the scissor test support - * - * V0.20 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - written the closetmmanger() function in order to free all the memory - * allocated by the Texture Memory Manager (it will be useful - * when the support for multiple contexts/boards will be ready) - * - now the Voodoo driver runs without printing any information, - * define the env. var. MESA_FX_INFO if you want to read some - * information about the hardware and some statistic - * - written a small workaround for the "GLQuake multiplayer white box bug" - * in the setup_fx_units() funxtions. I'm already rewriting - * this function because it is the source of nearly all the current - * Voodoo driver problems - * - fixed the GLQuake texture misalignment problem (the texture - * coordinates must be scaled between 0.0 and 256.0 and not - * between 0.0 and 255.0) - * - written the support for the GL_EXT_shared_texture_palette - * - some small change for supporting the automatic building of the - * OpenGL32.dll under the Windows platform - * - the redefinition of a mipmap level is now a LOT faster. This path - * is used by GLQuake for dynamic lighting with some call to glTexSubImage2D() - * - the texture memory is now managed a set of 2MB blocks so - * texture maps can't be allocated on a 2MB boundary. The new Pure3D - * needs this kind of support (and probably any other Voodoo Graphics - * board with more than 2MB of texture memory) - * - * Brian Paul (brianp@elastic.avid.com) Avid Technology - * - added write_monocolor_span(), fixed bug in write_color_span() - * - added test for stenciling in choosepoint/line/triangle functions - * - * Joe Waters (falc@attila.aegistech.com) Aegis - * - written the support for the env. var. SST_SCREENREFRESH - * - * V0.19 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - written the 3Dfx Global Palette extension for GLQuake - * - written the support for the GL_EXT_paletted_texture (it works only with GL_RGBA - * palettes and the alpha value is ignored ... this is a limitation of the - * the current Glide version and Voodoo hardware) - * - fixed the amount of memory allocated for 8bit textures - * - merged the under construction v0.19 driver with the Mesa 2.5 - * - finally written the support for deleting textures - * - introduced a new powerful texture memory manager: the texture memory - * is used as a cache of the set of all defined texture maps. You can - * now define several MB of texture maps also with a 2MB of texture memory - * (the texture memory manager will do automatically all the swap out/swap in - * work). The new texture memory manager has also - * solved a lot of other bugs/no specs compliance/problems - * related to the texture memory usage. The texture - * manager code is inside the new fxmesa3.c file - * - broken the fxmesa.c file in two files (fxmesa1.c and fxmesa2.c) - * and done some code cleanup - * - now is possible to redefine texture mipmap levels already defined - * - fixed a problem with the amount of texture memory allocated for textures - * with not all mipmap levels defined - * - fixed a small problem with single buffer rendering - * - * Brian Paul (brianp@elastic.avid.com) Avid Technology - * - read/write_color_span() now use front/back buffer correctly - * - create GLvisual with 5,6,5 bits per pixel, not 8,8,8 - * - removed a few ^M characters from fxmesa2.c file - * - * V0.18 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - the Mesa-2.4beta3 is finally using the driver quads support (the - * previous Mesa versions have never taken any advantage from the quads support !) - * - tested with the Glide 2.4 for Win - * - ported all asm code to Linux - * - ported the v0.18 to Linux (without asm code) - * - back to Linux !!! - * - optimized the SETUP macro (no more vertex snap for points and lines) - * - optimized the SETUP macro (added one argument) - * - the Mesa/Voodoo is now 20/30% for points, lines and small triangles ! - * - performance improvement setting VBSIZE to 72 - * - the GrVertex texture code is now written in asm - * - the GrVertex zbuffer code is now written in asm - * - the GrVertex wbuffer code is now written in asm - * - the GrVertex gouraud code is now written in asm - * - the GrVertex snap code is now written in asm - * - changed the 8bit compressed texture maps in 8bit palette texture maps - * support (it has the some advantage of compressed texture maps without the - * problem of a fixed NCC table for all mipmap levels) - * - written the support for 8bit compressed texture maps (but texture maps with - * more than one mipmap level aren't working fine) - * - finnaly everthing is working fine in MesaQuake ! - * - fixed a bug in the computation of texture mapping coordinates (I have found - * the bug thanks to MesaQuake !) - * - written the GL_REPLACE support (mainly for MesaQuake) - * - written the support for textures with not all mipmap levels defined - * - rewritten all the Texture memory stuff - * - written the MesaQuake support (define MESAQUAKE) - * - working with a ZBuffer if glOrtho or not int the default glDepthRange, - * otherwise working with the WBuffer - * written the glDepthRange support - * - * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l. - * - written the fxCloseHardware() and the fxQuaryHardware() (mainly - * for the VoodooWGL emulator) - * - * Brian Paul (brianp@elastic.avid.com) Avid Technology - * - implemented read/write_color_span() so glRead/DrawPixels() works - * - now needs Glide 2.3 or later. Removed GLIDE_FULL_SCREEN and call to grSstOpen() - * - * V0.17 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - optimized the bitmap support (66% faster) - * - tested with the Mesa 2.3beta2 - * - * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l. - * - solved a problem with the drawbitmap() and the Voodoo Rush - * (GR_ORIGIN_LOWER_LEFT did not work with the Stingray) - * - * Brian Paul (brianp@elastic.avid.com) Avid Technology - * - linux stuff - * - general code clean-up - * - added attribList parameter to fxMesaCreateContext() - * - single buffering works now - * - VB colors are now GLubytes, removed ColorShift stuff - * - * Paul Metzger - * - linux stuff - * - * V0.16 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - written the quadfunc support (no performance improvement) - * - written the support for the new Mesa 2.3beta1 driver interface (Wow ! It is faaaster) - * - rewritten the glBitmap support for the Glide 2.3 (~35% slower !) - * - written the glBitmap support for the most common case (fonts) - * - * Jack Palevich - * - Glide 2.3 porting - * - * Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l. - * - extended the fxMesaCreateContext() and fxMesaCreateBestContext() - * functions in order to support also the Voodoo Rush - * - tested with the Hercules Stingray 128/3D (The rendering in a window works !) - * - * V0.15 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - written the GL_LUMINANCE_ALPHA support - * - written the GL_ALPHA support - * - written the GL_LUMINANCE support - * - now SETUP correctly set color for mono color sequences - * - written the 9x1,10x1,...,1x9,1x10,... texture map ratio support - * - written the no square texture map support - * - the fog table is no more rebuilt inside setup_fx_units() each time - * - * Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation - * - written (not yet finished: no texture mapping) support for glOrtho - * - some change to setup functions - * - the fog support is now fully compatible with the standard OpenGL - * - rewritten several parts of the driver in order to take - * advantage of meshes (40% faster !!!) - * - * V0.14 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - now glAlphaFunc() works - * - now glDepthMask() works - * - solved a mipmap problem when using more than one texture - * - moved ti, texid and wscale inside the fxMesaContext (now we can - * easy support more ctx and more boards) - * - the management of the fxMesaContext was completly broken ! - * - solved several problems about Alpha and texture Alpha - * - 4 (RGBA) texture channels supported - * - setting the default color to white - * - * Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation - * - small change to fxMesaCreateContext() and fxMesaMakeCurrent() - * - written the fog support - * - setting the default clear color to black - * - written cleangraphics() for the onexit() function - * - written fxMesaCreateBestContext() - * - * V0.13 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - now glBlendFunc() works for all glBlendFunc without DST_ALPHA - * (because the alpha buffer is not yet implemented) - * - now fxMesaCreateContext() accept resolution and refresh rate - * - fixed a bug for texture mapping: the w (alias z) must be set - * also without depth buffer - * - fixed a bug for texture image with width!=256 - * - written texparam() - * - written all point, line and triangle functions for all possible supported - * contexts and the driver is slight faster with points, lines and small triangles - * - fixed a small bug in fx/fxmesa.h (glOrtho) - * - * V0.12 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - glDepthFunc supported - * - introduced a trick to discover the far plane distance - * (see fxMesaSetFar and fx/fxmesa.h) - * - now the wbuffer works with homogeneous coordinate (and it - * doesn't work with a glOrtho projection :) - * - solved several problems with homogeneous coordinate and texture mapping - * - fixed a bug in all line functions - * - fixed a clear framebuffer bug - * - solved a display list/teximg problem (but use - * glBindTexture: it is several times faster) - * - * V0.11 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - introduced texture mapping support (not yet finished !) - * - tested with Mesa2.2b6 - * - the driver is faster - * - written glFlush/glFinish - * - the driver print a lot of info about the Glide lib - * - * v0.1 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. - * - Initial revision - * - */ - - #ifdef HAVE_CONFIG_H #include "conf.h" #endif @@ -686,13 +113,6 @@ fxMesaContext GLAPIENTRY fxMesaGetCurrentContext(void) } -void GLAPIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f) -{ - if(fxMesaCurrentCtx) - fxDDSetNearFar(fxMesaCurrentCtx->glCtx,n,f); -} - - /* * The 3Dfx Global Palette extension for GLQuake. * More a trick than a real extesion, use the shared global @@ -1294,7 +714,7 @@ void GLAPIENTRY fxMesaSwapBuffers(void) } if(fxMesaCurrentCtx) { - FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" ); + _mesa_swapbuffers( fxMesaCurrentCtx->glCtx ); if(fxMesaCurrentCtx->haveDoubleBuffer) { 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 - * tjump@spgs.com @@ -476,7 +474,6 @@ extern int glbCurrentBoard; extern void fxPrintSetupFlags( const char *msg, GLuint flags ); extern void fxSetupFXUnits(GLcontext *); extern void fxSetupDDPointers(GLcontext *); -extern void fxDDSetNearFar(GLcontext *, GLfloat, GLfloat); extern void fxDDSetupInit(void); extern void fxDDCvaInit(void); @@ -533,9 +530,7 @@ extern void fxDDPartialRasterSetup( struct vertex_buffer *VB ); extern void fxDDDoRasterSetup( struct vertex_buffer *VB ); -extern GLuint fxDDRegisterPipelineStages( struct gl_pipeline_stage *out, - const struct gl_pipeline_stage *in, - GLuint nr ); +extern void fxDDRegisterPipelineStages( GLcontext *ctx ); extern GLboolean fxDDBuildPrecalcPipeline( GLcontext *ctx ); 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;pTransform.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;iLight.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;iUnpack); 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;iExecuteFlag) { (*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;iAccum = 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 constant curve */ - { - for(k=0; k 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 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 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; ku1; - 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;jVB; - - 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 jle@star.be - * Return GL_TRUE for success, GL_FALSE for failure (singular matrix) - */ -static GLboolean invert_matrix_general( GLmatrix *mat ) -{ - const GLfloat *m = mat->m; - GLfloat *out = mat->inv; - GLfloat wtmp[4][8]; - GLfloat m0, m1, m2, m3, s; - GLfloat *r0, *r1, *r2, *r3; - - r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; - - r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), - r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), - r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, - - r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), - r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), - r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, - - r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), - r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), - r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, - - r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), - r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), - r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; - - /* choose pivot - or die */ - if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2); - if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1); - if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0); - if (0.0 == r0[0]) return GL_FALSE; - - /* eliminate first variable */ - m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; - s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; - s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; - s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; - s = r0[4]; - if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r0[5]; - if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r0[6]; - if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r0[7]; - if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2); - if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1); - if (0.0 == r1[1]) return GL_FALSE; - - /* eliminate second variable */ - m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; - r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; - r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; - s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2); - if (0.0 == r2[2]) return GL_FALSE; - - /* eliminate third variable */ - m3 = r3[2]/r2[2]; - r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], - r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], - r3[7] -= m3 * r2[7]; - - /* last check */ - if (0.0 == r3[3]) return GL_FALSE; - - s = 1.0/r3[3]; /* now back substitute row 3 */ - r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; - - m2 = r2[3]; /* now back substitute row 2 */ - s = 1.0/r2[2]; - r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), - r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); - m1 = r1[3]; - r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, - r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; - m0 = r0[3]; - r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, - r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; - - m1 = r1[2]; /* now back substitute row 1 */ - s = 1.0/r1[1]; - r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), - r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); - m0 = r0[2]; - r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, - r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; - - m0 = r0[1]; /* now back substitute row 0 */ - s = 1.0/r0[0]; - r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), - r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); - - MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], - MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], - MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], - MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], - MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], - MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], - MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], - MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; - - return GL_TRUE; -} -#undef SWAP_ROWS - - -/* Adapted from graphics gems II. - */ -static GLboolean invert_matrix_3d_general( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - GLfloat pos, neg, t; - GLfloat det; - - /* Calculate the determinant of upper left 3x3 submatrix and - * determine if the matrix is singular. - */ - pos = neg = 0.0; - t = MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2); - if (t >= 0.0) pos += t; else neg += t; - - t = MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2); - if (t >= 0.0) pos += t; else neg += t; - - t = MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2); - if (t >= 0.0) pos += t; else neg += t; - - det = pos + neg; - - if (det*det < 1e-25) - return GL_FALSE; - - det = 1.0 / det; - MAT(out,0,0) = ( (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det); - MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det); - MAT(out,0,2) = ( (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det); - MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det); - MAT(out,1,1) = ( (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det); - MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det); - MAT(out,2,0) = ( (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det); - MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det); - MAT(out,2,2) = ( (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det); - - /* Do the translation part */ - MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + - MAT(in,1,3) * MAT(out,0,1) + - MAT(in,2,3) * MAT(out,0,2) ); - MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + - MAT(in,1,3) * MAT(out,1,1) + - MAT(in,2,3) * MAT(out,1,2) ); - MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + - MAT(in,1,3) * MAT(out,2,1) + - MAT(in,2,3) * MAT(out,2,2) ); - - return GL_TRUE; -} - - -static GLboolean invert_matrix_3d( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - - if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING)) { - return invert_matrix_3d_general( mat ); - } - - if (mat->flags & MAT_FLAG_UNIFORM_SCALE) { - GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) + - MAT(in,0,1) * MAT(in,0,1) + - MAT(in,0,2) * MAT(in,0,2)); - - if (scale == 0.0) - return GL_FALSE; - - scale = 1.0 / scale; - - /* Transpose and scale the 3 by 3 upper-left submatrix. */ - MAT(out,0,0) = scale * MAT(in,0,0); - MAT(out,1,0) = scale * MAT(in,0,1); - MAT(out,2,0) = scale * MAT(in,0,2); - MAT(out,0,1) = scale * MAT(in,1,0); - MAT(out,1,1) = scale * MAT(in,1,1); - MAT(out,2,1) = scale * MAT(in,1,2); - MAT(out,0,2) = scale * MAT(in,2,0); - MAT(out,1,2) = scale * MAT(in,2,1); - MAT(out,2,2) = scale * MAT(in,2,2); - } - else if (mat->flags & MAT_FLAG_ROTATION) { - /* Transpose the 3 by 3 upper-left submatrix. */ - MAT(out,0,0) = MAT(in,0,0); - MAT(out,1,0) = MAT(in,0,1); - MAT(out,2,0) = MAT(in,0,2); - MAT(out,0,1) = MAT(in,1,0); - MAT(out,1,1) = MAT(in,1,1); - MAT(out,2,1) = MAT(in,1,2); - MAT(out,0,2) = MAT(in,2,0); - MAT(out,1,2) = MAT(in,2,1); - MAT(out,2,2) = MAT(in,2,2); - } - else { - /* pure translation */ - MEMCPY( out, Identity, sizeof(Identity) ); - MAT(out,0,3) = - MAT(in,0,3); - MAT(out,1,3) = - MAT(in,1,3); - MAT(out,2,3) = - MAT(in,2,3); - return GL_TRUE; - } - - if (mat->flags & MAT_FLAG_TRANSLATION) { - /* Do the translation part */ - MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + - MAT(in,1,3) * MAT(out,0,1) + - MAT(in,2,3) * MAT(out,0,2) ); - MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + - MAT(in,1,3) * MAT(out,1,1) + - MAT(in,2,3) * MAT(out,1,2) ); - MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + - MAT(in,1,3) * MAT(out,2,1) + - MAT(in,2,3) * MAT(out,2,2) ); - } - else { - MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0; - } - - return GL_TRUE; -} - - - -static GLboolean invert_matrix_identity( GLmatrix *mat ) -{ - MEMCPY( mat->inv, Identity, sizeof(Identity) ); - return GL_TRUE; -} - - -static GLboolean invert_matrix_3d_no_rot( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - - if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 ) - return GL_FALSE; - - MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); - MAT(out,0,0) = 1.0 / MAT(in,0,0); - MAT(out,1,1) = 1.0 / MAT(in,1,1); - MAT(out,2,2) = 1.0 / MAT(in,2,2); - - if (mat->flags & MAT_FLAG_TRANSLATION) { - MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); - MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); - MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2)); - } - - return GL_TRUE; -} - - -static GLboolean invert_matrix_2d_no_rot( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - - if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0) - return GL_FALSE; - - MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); - MAT(out,0,0) = 1.0 / MAT(in,0,0); - MAT(out,1,1) = 1.0 / MAT(in,1,1); - - if (mat->flags & MAT_FLAG_TRANSLATION) { - MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); - MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); - } - - return GL_TRUE; -} - - -static GLboolean invert_matrix_perspective( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - - if (MAT(in,2,3) == 0) - return GL_FALSE; - - MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); - - MAT(out,0,0) = 1.0 / MAT(in,0,0); - MAT(out,1,1) = 1.0 / MAT(in,1,1); - - MAT(out,0,3) = MAT(in,0,2); - MAT(out,1,3) = MAT(in,1,2); - - MAT(out,2,2) = 0; - MAT(out,2,3) = -1; - - MAT(out,3,2) = 1.0 / MAT(in,2,3); - MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2); - - return GL_TRUE; -} - - -typedef GLboolean (*inv_mat_func)( GLmatrix *mat ); - - -static inv_mat_func inv_mat_tab[7] = { - invert_matrix_general, - invert_matrix_identity, - invert_matrix_3d_no_rot, - invert_matrix_perspective, - invert_matrix_3d, /* lazy! */ - invert_matrix_2d_no_rot, - invert_matrix_3d -}; - - -static GLboolean matrix_invert( GLmatrix *mat ) -{ - if (inv_mat_tab[mat->type](mat)) { - mat->flags &= ~MAT_FLAG_SINGULAR; - return GL_TRUE; - } else { - mat->flags |= MAT_FLAG_SINGULAR; - MEMCPY( mat->inv, Identity, sizeof(Identity) ); - return GL_FALSE; - } -} - - - -void gl_matrix_transposef( GLfloat to[16], const GLfloat from[16] ) -{ - to[0] = from[0]; - to[1] = from[4]; - to[2] = from[8]; - to[3] = from[12]; - to[4] = from[1]; - to[5] = from[5]; - to[6] = from[9]; - to[7] = from[13]; - to[8] = from[2]; - to[9] = from[6]; - to[10] = from[10]; - to[11] = from[14]; - to[12] = from[3]; - to[13] = from[7]; - to[14] = from[11]; - to[15] = from[15]; -} - - - -void gl_matrix_transposed( GLdouble to[16], const GLdouble from[16] ) -{ - to[0] = from[0]; - to[1] = from[4]; - to[2] = from[8]; - to[3] = from[12]; - to[4] = from[1]; - to[5] = from[5]; - to[6] = from[9]; - to[7] = from[13]; - to[8] = from[2]; - to[9] = from[6]; - to[10] = from[10]; - to[11] = from[14]; - to[12] = from[3]; - to[13] = from[7]; - to[14] = from[11]; - to[15] = from[15]; -} - - - -/* - * Generate a 4x4 transformation matrix from glRotate parameters. - */ -void gl_rotation_matrix( GLfloat angle, GLfloat x, GLfloat y, GLfloat z, - GLfloat m[] ) -{ - /* This function contributed by Erich Boleyn (erich@uruk.org) */ - GLfloat mag, s, c; - GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c; - - s = sin( angle * DEG2RAD ); - c = cos( angle * DEG2RAD ); - - mag = GL_SQRT( x*x + y*y + z*z ); - - if (mag <= 1.0e-4) { - /* generate an identity matrix and return */ - MEMCPY(m, Identity, sizeof(GLfloat)*16); - return; - } - - x /= mag; - y /= mag; - z /= mag; - -#define M(row,col) m[col*4+row] - - /* - * Arbitrary axis rotation matrix. - * - * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied - * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation - * (which is about the X-axis), and the two composite transforms - * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary - * from the arbitrary axis to the X-axis then back. They are - * all elementary rotations. - * - * Rz' is a rotation about the Z-axis, to bring the axis vector - * into the x-z plane. Then Ry' is applied, rotating about the - * Y-axis to bring the axis vector parallel with the X-axis. The - * rotation about the X-axis is then performed. Ry and Rz are - * simply the respective inverse transforms to bring the arbitrary - * axis back to it's original orientation. The first transforms - * Rz' and Ry' are considered inverses, since the data from the - * arbitrary axis gives you info on how to get to it, not how - * to get away from it, and an inverse must be applied. - * - * The basic calculation used is to recognize that the arbitrary - * axis vector (x, y, z), since it is of unit length, actually - * represents the sines and cosines of the angles to rotate the - * X-axis to the same orientation, with theta being the angle about - * Z and phi the angle about Y (in the order described above) - * as follows: - * - * cos ( theta ) = x / sqrt ( 1 - z^2 ) - * sin ( theta ) = y / sqrt ( 1 - z^2 ) - * - * cos ( phi ) = sqrt ( 1 - z^2 ) - * sin ( phi ) = z - * - * Note that cos ( phi ) can further be inserted to the above - * formulas: - * - * cos ( theta ) = x / cos ( phi ) - * sin ( theta ) = y / sin ( phi ) - * - * ...etc. Because of those relations and the standard trigonometric - * relations, it is pssible to reduce the transforms down to what - * is used below. It may be that any primary axis chosen will give the - * same results (modulo a sign convention) using thie method. - * - * Particularly nice is to notice that all divisions that might - * have caused trouble when parallel to certain planes or - * axis go away with care paid to reducing the expressions. - * After checking, it does perform correctly under all cases, since - * in all the cases of division where the denominator would have - * been zero, the numerator would have been zero as well, giving - * the expected result. - */ - - xx = x * x; - yy = y * y; - zz = z * z; - xy = x * y; - yz = y * z; - zx = z * x; - xs = x * s; - ys = y * s; - zs = z * s; - one_c = 1.0F - c; - - M(0,0) = (one_c * xx) + c; - M(0,1) = (one_c * xy) - zs; - M(0,2) = (one_c * zx) + ys; - M(0,3) = 0.0F; - - M(1,0) = (one_c * xy) + zs; - M(1,1) = (one_c * yy) + c; - M(1,2) = (one_c * yz) - xs; - M(1,3) = 0.0F; - - M(2,0) = (one_c * zx) - ys; - M(2,1) = (one_c * yz) + xs; - M(2,2) = (one_c * zz) + c; - M(2,3) = 0.0F; - - M(3,0) = 0.0F; - M(3,1) = 0.0F; - M(3,2) = 0.0F; - M(3,3) = 1.0F; - -#undef M -} - -#define ZERO(x) (1<m; - GLuint mask = 0; - GLuint i; - - for (i = 0 ; i < 16 ; i++) { - if (m[i] == 0.0) mask |= (1<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 @@ -37,40 +37,9 @@ #endif -extern void -gl_matrix_transposef( GLfloat to[16], const GLfloat from[16] ); - -extern void -gl_matrix_transposed( GLdouble to[16], const GLdouble from[16] ); - - -extern void -gl_rotation_matrix( GLfloat angle, GLfloat x, GLfloat y, GLfloat z, - GLfloat m[] ); - - extern void gl_calculate_model_project_matrix( GLcontext *ctx ); -extern void -gl_matrix_ctr( GLmatrix *m ); - -extern void -gl_matrix_dtr( GLmatrix *m ); - -extern void -gl_matrix_alloc_inv( GLmatrix *m ); - -extern void -gl_matrix_mul( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ); - -extern void -gl_matrix_analyze( GLmatrix *mat ); - -extern void -gl_print_matrix( const GLmatrix *m ); - - extern void _mesa_Frustum( GLdouble left, GLdouble right, 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,16 +35,205 @@ #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;pTransform.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_CosCutoff) { + continue; + } + else + { + double x = PV_dot_dir * (EXP_TABLE_SIZE-1); + int k = (int) x; + GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] + + (x-k)*light->_SpotExpTable[k][1]); + attenuation *= spot; + } + } + } + + if (attenuation < 1e-3) + continue; + + n_dot_VP = DOT3( normal, VP ); + + if (n_dot_VP < 0.0F) { + ACC_SCALE_SCALAR_3V(color, attenuation, light->_MatAmbient[0]); + continue; + } + + COPY_3V(contrib, light->_MatAmbient[0]); + ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[0]); + diffuse += n_dot_VP * light->_dli * attenuation; + + if (light->_IsMatSpecular[0]) { + if (ctx->Light.Model.LocalViewer) { + GLfloat v[3]; + COPY_3V(v, vertex); + NORMALIZE_3FV(v); + SUB_3V(VP, VP, v); + h = VP; + normalized = 0; + } + else if (light->_Flags & LIGHT_POSITIONAL) { + h = VP; + ACC_3V(h, ctx->_EyeZDir); + normalized = 0; + } + else { + h = light->_h_inf_norm; + normalized = 1; + } + + n_dot_h = DOT3(normal, h); + + if (n_dot_h > 0.0F) { + struct gl_material *mat = &ctx->Light.Material[0]; + GLfloat spec_coef; + GLfloat shininess = mat->Shininess; + + if (!normalized) { + n_dot_h *= n_dot_h; + n_dot_h /= LEN_SQUARED_3FV( h ); + shininess *= .5; + } + + GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec_coef ); + + if (spec_coef > 1.0e-10) { + ACC_SCALE_SCALAR_3V( contrib, spec_coef, + light->_MatSpecular[0]); + specular += spec_coef * light->_sli * attenuation; + } + } + } + + ACC_SCALE_SCALAR_3V( color, attenuation, contrib ); + } + + if (ctx->Visual.RGBAflag) { + Rcolor[0] = CLAMP(color[0], 0.0F, 1.0F); + Rcolor[1] = CLAMP(color[1], 0.0F, 1.0F); + Rcolor[2] = CLAMP(color[2], 0.0F, 1.0F); + Rcolor[3] = CLAMP(color[3], 0.0F, 1.0F); + } + else { + struct gl_material *mat = &ctx->Light.Material[0]; + GLfloat d_a = mat->DiffuseIndex - mat->AmbientIndex; + GLfloat s_a = mat->SpecularIndex - mat->AmbientIndex; + GLfloat ind = mat->AmbientIndex + + diffuse * (1.0F-specular) * d_a + + specular * s_a; + if (ind > mat->SpecularIndex) { + ind = mat->SpecularIndex; + } + *index = (GLuint) (GLint) ind; + } + +} + /* * Caller: context->API.RasterPos4f */ @@ -54,10 +243,12 @@ static void raster_pos4f( GLcontext *ctx, GLfloat v[4], eye[4], clip[4], ndc[3], d; /* KW: Added this test, which is in the spec. We can't do this - * outside begin/end any more because the ctx->Current values + * inside begin/end any more because the ctx->Current values * aren't uptodate during that period. */ - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glRasterPos" ); + FLUSH_TNL_RETURN(ctx, (FLUSH_INSIDE_BEGIN_END| + FLUSH_STORED_VERTICES| + FLUSH_UPDATE_CURRENT), "raster_pos4f"); if (ctx->NewState) gl_update_state( ctx ); 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;iinput; \ - 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 @@ -95,53 +95,9 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr); -extern void -_mesa_ArrayElement( GLint ); - - -extern void -_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count); - - -extern void -_mesa_save_DrawArrays(GLenum mode, GLint first, GLsizei count); - - -extern void -_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices); - - -extern void -_mesa_save_DrawElements(GLenum mode, GLsizei count, - GLenum type, const GLvoid *indices); - - extern void _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer); -extern void -_mesa_save_InterleavedArrays(GLenum format, GLsizei stride, - const GLvoid *pointer); - - -extern void -_mesa_DrawRangeElements(GLenum mode, GLuint start, - GLuint end, GLsizei count, GLenum type, - const GLvoid *indices); - -extern void -_mesa_save_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, GLsizei count, - GLenum type, const GLvoid *indices ); - - -extern void gl_exec_array_elements( GLcontext *ctx, - struct immediate *IM, - GLuint start, - GLuint end ); - -extern void gl_update_client_state( GLcontext *ctx ); #endif diff --git a/src/mesa/math/m_clip_tmp.h b/src/mesa/math/m_clip_tmp.h new file mode 100644 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;icount = 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;icount = 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;icount = 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 jle@star.be + * Return GL_TRUE for success, GL_FALSE for failure (singular matrix) + */ +static GLboolean invert_matrix_general( GLmatrix *mat ) +{ + const GLfloat *m = mat->m; + GLfloat *out = mat->inv; + GLfloat wtmp[4][8]; + GLfloat m0, m1, m2, m3, s; + GLfloat *r0, *r1, *r2, *r3; + + r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; + + r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), + r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), + r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, + + r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), + r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), + r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, + + r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), + r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), + r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, + + r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), + r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), + r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; + + /* choose pivot - or die */ + if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2); + if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1); + if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0); + if (0.0 == r0[0]) return GL_FALSE; + + /* eliminate first variable */ + m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; + s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; + s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; + s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; + s = r0[4]; + if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r0[5]; + if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r0[6]; + if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r0[7]; + if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2); + if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1); + if (0.0 == r1[1]) return GL_FALSE; + + /* eliminate second variable */ + m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; + r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; + r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; + s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2); + if (0.0 == r2[2]) return GL_FALSE; + + /* eliminate third variable */ + m3 = r3[2]/r2[2]; + r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], + r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], + r3[7] -= m3 * r2[7]; + + /* last check */ + if (0.0 == r3[3]) return GL_FALSE; + + s = 1.0/r3[3]; /* now back substitute row 3 */ + r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; + + m2 = r2[3]; /* now back substitute row 2 */ + s = 1.0/r2[2]; + r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), + r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); + m1 = r1[3]; + r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, + r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; + m0 = r0[3]; + r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, + r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; + + m1 = r1[2]; /* now back substitute row 1 */ + s = 1.0/r1[1]; + r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), + r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); + m0 = r0[2]; + r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, + r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; + + m0 = r0[1]; /* now back substitute row 0 */ + s = 1.0/r0[0]; + r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), + r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); + + MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], + MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], + MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], + MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], + MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], + MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], + MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], + MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; + + return GL_TRUE; +} +#undef SWAP_ROWS + + +/* Adapted from graphics gems II. + */ +static GLboolean invert_matrix_3d_general( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + GLfloat pos, neg, t; + GLfloat det; + + /* Calculate the determinant of upper left 3x3 submatrix and + * determine if the matrix is singular. + */ + pos = neg = 0.0; + t = MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2); + if (t >= 0.0) pos += t; else neg += t; + + t = MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2); + if (t >= 0.0) pos += t; else neg += t; + + t = MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2); + if (t >= 0.0) pos += t; else neg += t; + + det = pos + neg; + + if (det*det < 1e-25) + return GL_FALSE; + + det = 1.0 / det; + MAT(out,0,0) = ( (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det); + MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det); + MAT(out,0,2) = ( (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det); + MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det); + MAT(out,1,1) = ( (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det); + MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det); + MAT(out,2,0) = ( (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det); + MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det); + MAT(out,2,2) = ( (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det); + + /* Do the translation part */ + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + + MAT(in,1,3) * MAT(out,0,1) + + MAT(in,2,3) * MAT(out,0,2) ); + MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + + MAT(in,1,3) * MAT(out,1,1) + + MAT(in,2,3) * MAT(out,1,2) ); + MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + + MAT(in,1,3) * MAT(out,2,1) + + MAT(in,2,3) * MAT(out,2,2) ); + + return GL_TRUE; +} + + +static GLboolean invert_matrix_3d( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING)) { + return invert_matrix_3d_general( mat ); + } + + if (mat->flags & MAT_FLAG_UNIFORM_SCALE) { + GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) + + MAT(in,0,1) * MAT(in,0,1) + + MAT(in,0,2) * MAT(in,0,2)); + + if (scale == 0.0) + return GL_FALSE; + + scale = 1.0 / scale; + + /* Transpose and scale the 3 by 3 upper-left submatrix. */ + MAT(out,0,0) = scale * MAT(in,0,0); + MAT(out,1,0) = scale * MAT(in,0,1); + MAT(out,2,0) = scale * MAT(in,0,2); + MAT(out,0,1) = scale * MAT(in,1,0); + MAT(out,1,1) = scale * MAT(in,1,1); + MAT(out,2,1) = scale * MAT(in,1,2); + MAT(out,0,2) = scale * MAT(in,2,0); + MAT(out,1,2) = scale * MAT(in,2,1); + MAT(out,2,2) = scale * MAT(in,2,2); + } + else if (mat->flags & MAT_FLAG_ROTATION) { + /* Transpose the 3 by 3 upper-left submatrix. */ + MAT(out,0,0) = MAT(in,0,0); + MAT(out,1,0) = MAT(in,0,1); + MAT(out,2,0) = MAT(in,0,2); + MAT(out,0,1) = MAT(in,1,0); + MAT(out,1,1) = MAT(in,1,1); + MAT(out,2,1) = MAT(in,1,2); + MAT(out,0,2) = MAT(in,2,0); + MAT(out,1,2) = MAT(in,2,1); + MAT(out,2,2) = MAT(in,2,2); + } + else { + /* pure translation */ + MEMCPY( out, Identity, sizeof(Identity) ); + MAT(out,0,3) = - MAT(in,0,3); + MAT(out,1,3) = - MAT(in,1,3); + MAT(out,2,3) = - MAT(in,2,3); + return GL_TRUE; + } + + if (mat->flags & MAT_FLAG_TRANSLATION) { + /* Do the translation part */ + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + + MAT(in,1,3) * MAT(out,0,1) + + MAT(in,2,3) * MAT(out,0,2) ); + MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + + MAT(in,1,3) * MAT(out,1,1) + + MAT(in,2,3) * MAT(out,1,2) ); + MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + + MAT(in,1,3) * MAT(out,2,1) + + MAT(in,2,3) * MAT(out,2,2) ); + } + else { + MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0; + } + + return GL_TRUE; +} + + + +static GLboolean invert_matrix_identity( GLmatrix *mat ) +{ + MEMCPY( mat->inv, Identity, sizeof(Identity) ); + return GL_TRUE; +} + + +static GLboolean invert_matrix_3d_no_rot( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 ) + return GL_FALSE; + + MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); + MAT(out,0,0) = 1.0 / MAT(in,0,0); + MAT(out,1,1) = 1.0 / MAT(in,1,1); + MAT(out,2,2) = 1.0 / MAT(in,2,2); + + if (mat->flags & MAT_FLAG_TRANSLATION) { + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); + MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); + MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2)); + } + + return GL_TRUE; +} + + +static GLboolean invert_matrix_2d_no_rot( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0) + return GL_FALSE; + + MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); + MAT(out,0,0) = 1.0 / MAT(in,0,0); + MAT(out,1,1) = 1.0 / MAT(in,1,1); + + if (mat->flags & MAT_FLAG_TRANSLATION) { + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); + MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); + } + + return GL_TRUE; +} + + +static GLboolean invert_matrix_perspective( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,2,3) == 0) + return GL_FALSE; + + MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); + + MAT(out,0,0) = 1.0 / MAT(in,0,0); + MAT(out,1,1) = 1.0 / MAT(in,1,1); + + MAT(out,0,3) = MAT(in,0,2); + MAT(out,1,3) = MAT(in,1,2); + + MAT(out,2,2) = 0; + MAT(out,2,3) = -1; + + MAT(out,3,2) = 1.0 / MAT(in,2,3); + MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2); + + return GL_TRUE; +} + + +typedef GLboolean (*inv_mat_func)( GLmatrix *mat ); + + +static inv_mat_func inv_mat_tab[7] = { + invert_matrix_general, + invert_matrix_identity, + invert_matrix_3d_no_rot, + invert_matrix_perspective, + invert_matrix_3d, /* lazy! */ + invert_matrix_2d_no_rot, + invert_matrix_3d +}; + + +static GLboolean matrix_invert( GLmatrix *mat ) +{ + if (inv_mat_tab[mat->type](mat)) { + mat->flags &= ~MAT_FLAG_SINGULAR; + return GL_TRUE; + } else { + mat->flags |= MAT_FLAG_SINGULAR; + MEMCPY( mat->inv, Identity, sizeof(Identity) ); + return GL_FALSE; + } +} + + + + + + +/* + * Generate a 4x4 transformation matrix from glRotate parameters, and + * postmultiply the input matrix by it. + */ +void +_math_matrix_rotate( GLmatrix *mat, + GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) +{ + /* This function contributed by Erich Boleyn (erich@uruk.org) */ + GLfloat mag, s, c; + GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c; + GLfloat m[16]; + + s = sin( angle * DEG2RAD ); + c = cos( angle * DEG2RAD ); + + mag = GL_SQRT( x*x + y*y + z*z ); + + if (mag <= 1.0e-4) { + /* generate an identity matrix and return */ + MEMCPY(m, Identity, sizeof(GLfloat)*16); + return; + } + + x /= mag; + y /= mag; + z /= mag; + +#define M(row,col) m[col*4+row] + + /* + * Arbitrary axis rotation matrix. + * + * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied + * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation + * (which is about the X-axis), and the two composite transforms + * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary + * from the arbitrary axis to the X-axis then back. They are + * all elementary rotations. + * + * Rz' is a rotation about the Z-axis, to bring the axis vector + * into the x-z plane. Then Ry' is applied, rotating about the + * Y-axis to bring the axis vector parallel with the X-axis. The + * rotation about the X-axis is then performed. Ry and Rz are + * simply the respective inverse transforms to bring the arbitrary + * axis back to it's original orientation. The first transforms + * Rz' and Ry' are considered inverses, since the data from the + * arbitrary axis gives you info on how to get to it, not how + * to get away from it, and an inverse must be applied. + * + * The basic calculation used is to recognize that the arbitrary + * axis vector (x, y, z), since it is of unit length, actually + * represents the sines and cosines of the angles to rotate the + * X-axis to the same orientation, with theta being the angle about + * Z and phi the angle about Y (in the order described above) + * as follows: + * + * cos ( theta ) = x / sqrt ( 1 - z^2 ) + * sin ( theta ) = y / sqrt ( 1 - z^2 ) + * + * cos ( phi ) = sqrt ( 1 - z^2 ) + * sin ( phi ) = z + * + * Note that cos ( phi ) can further be inserted to the above + * formulas: + * + * cos ( theta ) = x / cos ( phi ) + * sin ( theta ) = y / sin ( phi ) + * + * ...etc. Because of those relations and the standard trigonometric + * relations, it is pssible to reduce the transforms down to what + * is used below. It may be that any primary axis chosen will give the + * same results (modulo a sign convention) using thie method. + * + * Particularly nice is to notice that all divisions that might + * have caused trouble when parallel to certain planes or + * axis go away with care paid to reducing the expressions. + * After checking, it does perform correctly under all cases, since + * in all the cases of division where the denominator would have + * been zero, the numerator would have been zero as well, giving + * the expected result. + */ + + xx = x * x; + yy = y * y; + zz = z * z; + xy = x * y; + yz = y * z; + zx = z * x; + xs = x * s; + ys = y * s; + zs = z * s; + one_c = 1.0F - c; + + M(0,0) = (one_c * xx) + c; + M(0,1) = (one_c * xy) - zs; + M(0,2) = (one_c * zx) + ys; + M(0,3) = 0.0F; + + M(1,0) = (one_c * xy) + zs; + M(1,1) = (one_c * yy) + c; + M(1,2) = (one_c * yz) - xs; + M(1,3) = 0.0F; + + M(2,0) = (one_c * zx) - ys; + M(2,1) = (one_c * yz) + xs; + M(2,2) = (one_c * zz) + c; + M(2,3) = 0.0F; + + M(3,0) = 0.0F; + M(3,1) = 0.0F; + M(3,2) = 0.0F; + M(3,3) = 1.0F; + +#undef M + + matrix_multf( mat, m, MAT_FLAG_ROTATION ); +} + + +void +_math_matrix_frustrum( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ) +{ + GLfloat x, y, a, b, c, d; + GLfloat m[16]; + + x = (2.0*nearval) / (right-left); + y = (2.0*nearval) / (top-bottom); + a = (right+left) / (right-left); + b = (top+bottom) / (top-bottom); + c = -(farval+nearval) / ( farval-nearval); + d = -(2.0*farval*nearval) / (farval-nearval); /* error? */ + +#define M(row,col) m[col*4+row] + M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; + M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; + M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; + M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; +#undef M + + matrix_multf( mat, m, MAT_FLAG_PERSPECTIVE ); +} + +void +_math_matrix_ortho( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ) +{ + GLfloat x, y, z; + GLfloat tx, ty, tz; + GLfloat m[16]; + + x = 2.0 / (right-left); + y = 2.0 / (top-bottom); + z = -2.0 / (farval-nearval); + tx = -(right+left) / (right-left); + ty = -(top+bottom) / (top-bottom); + tz = -(farval+nearval) / (farval-nearval); + +#define M(row,col) m[col*4+row] + M(0,0) = x; M(0,1) = 0.0F; M(0,2) = 0.0F; M(0,3) = tx; + M(1,0) = 0.0F; M(1,1) = y; M(1,2) = 0.0F; M(1,3) = ty; + M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = z; M(2,3) = tz; + M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F; +#undef M + + matrix_multf( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION)); +} + + +#define ZERO(x) (1<m; + GLuint mask = 0; + GLuint i; + + for (i = 0 ; i < 16 ; i++) { + if (m[i] == 0.0) mask |= (1<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<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 */ + 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 , return a pointer (cast to to the -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;istride; + 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 + */ + + + +#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 + */ + +#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 -- 2.30.2