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.tags/mesa_3_5
@@ -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 | |||
@@ -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) |
@@ -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 <version> | |||
* <Voodoo_Graphics|Voodoo_Rush|UNKNOWN> <num> CARD/<num> FB/ | |||
* <num> TM/<num> TMU/<NOSLI|SLI>" | |||
* where: <num> CARD is the card used for the current context, | |||
* <num> FB is the number of MB for the framebuffer, | |||
* <num> TM is the number of MB for the texture memory, | |||
* <num> TMU is the number of TMU. You can try to run | |||
* Mesa/demos/glinfo in order to have an example of the | |||
* output | |||
* - fixed a problem of the WGL emulator with the | |||
* OpenGL Optimizer 1.1 (thanks to Erwin Coumans for | |||
* the bug report) | |||
* - fixed some bug in the fxwgl.c code (thanks to | |||
* Peter Pettersson for a patch and a bug report) | |||
* | |||
* Theodore Jump (tjump@cais.com) | |||
* - written the SST_DUALHEAD support in the WGL emulator | |||
* | |||
* Daryll Strauss (daryll@harlot.rb.ca.us) | |||
* - fixed the Voodoo Rush support for the in window rendering | |||
* | |||
* V0.28 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - the only supported multitexture functions are GL_MODULATE | |||
* for texture set 0 and GL_MODULATE for texture set 1. In | |||
* all other cases, the driver falls back to pure software | |||
* rendering | |||
* - written the support for the new GL_EXT_multitexture | |||
* - written the DD_MAX_TEXTURE_COORD_SETS support in the | |||
* fxDDGetParameteri() function | |||
* - the driver falls back to pure software rendering when | |||
* texture mapping function is GL_BLEND | |||
* | |||
* V0.27 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - inluded in the Mesa-3.0beta5 | |||
* - written a smal extension (GL_FXMESA_global_texture_lod_bias) in | |||
* order to expose the LOD bias related Glide function | |||
* - fixed a bug fxDDWriteMonoRGBAPixels() | |||
* - the driver is now able to fallback to software rendering in | |||
* any case not directly supported by the hardware | |||
* - written the support for enabling/disabling dithering | |||
* - the in-window-rendering hack now works with any X11 screen | |||
* depth | |||
* - fixed a problem related to color/depth/alpha buffer clears | |||
* - fixed a problem when clearing buffer for a context with the | |||
* alpha buffer | |||
* - fixed a problem in the fxTMReloadSubMipMapLevel() function, | |||
* I have forget a "break;" (thanks to Joe Waters for the bug report) | |||
* - fixed a problem in the color format for the in window | |||
* rendering hack | |||
* - written the fxDDReadRGBAPixels function | |||
* - written the fxDDDepthTestPixelsGeneric function | |||
* - written the fxDDDepthTestSpanGeneric function | |||
* - written the fxDDWriteMonoRGBAPixels function | |||
* - written the fxDDWriteRGBAPixels function | |||
* - removed the multitexture emulation code for Voodoo board | |||
* with only one TMU | |||
* | |||
* Chris Prince <cprince@cs.washington.edu> | |||
* - fixed a new bug in the wglUseFontBitmaps code | |||
* | |||
* Ralf Knoesel (rknoesel@Stormfront.com) | |||
* - fixed a bug in the wglUseFontBitmaps code | |||
* | |||
* Rune Hasvold (runeh@ifi.uio.no) | |||
* - fixed a problem related to the aux usage in the fxBestResolution | |||
* function | |||
* - fixed the order of pixel formats in the WGL emulator | |||
* | |||
* Fredrik Hubinette (hubbe@hubbe.net) | |||
* - the driver shutdown the Glide for most common signals | |||
* | |||
* V0.26 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - included in the Mesa-3.0beta4 | |||
* - fixed a problem related to a my optimization for the Rune's | |||
* pixel-span optimization | |||
* - fixed a problem related to fxDDSetNearFar() and ctx->ProjectionMatrixType | |||
* (thanks to Ben "Ctrl-Alt-Delete" and the Raul Alonso's ssystem) | |||
* - fixed a small bug in the Rune's pixel-span optimization | |||
* - fixed a problem with GL_CCW (thanks to Curt Olson for and example | |||
* of the problem) | |||
* - grVertex setup code is now ready for the internal thread support | |||
* - fixed a no used optimization with clipped vertices in | |||
* grVertex setup code | |||
* - fixed a problem in the GL_LIGHT_MODEL_TWO_SIDE support (thanks | |||
* to Patrick H. Madden for a complete example of the bug) | |||
* | |||
* Rune Hasvold (runeh@ifi.uio.no) | |||
* - highly optimized the driver functions for writing pixel | |||
* span (2-3 times faster !) | |||
* | |||
* Axel W. Volley (volley@acm.org) Krauss-Maffei Wehrtechnik | |||
* - written the fxDDReadDepthSpanFloat() and fxDDReadDepthSpanInt() | |||
* functions | |||
* | |||
* V0.25 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - fixed a problem with Voodoo boards with only one TMU | |||
* - fixed a bug in the fxMesaCreateContext() | |||
* - now the GL_FRONT_AND_BACK works fine also with | |||
* the alpha buffer and/or antialiasing | |||
* - written the support for GL_FRONT_AND_BACK drawing but | |||
* it doesn't works with the alpha buffer and/or antialiasing | |||
* - fixed some bug in the Mesa core for glCopyTexSubImage | |||
* and glCopyTexImage functions (thanks to Mike Connell | |||
* for an example of the problem) | |||
* - make some small optimizations in the Mesa core in order | |||
* to save same driver call and state change for not very | |||
* well written applications | |||
* - introduced the NEW_DRVSTATE and make other optimizations | |||
* for minimizing state changes | |||
* - made a lot of optimizations in order to minimize state | |||
* changes | |||
* - it isn't more possible to create a context with the | |||
* depth buffer and the stancil buffer (it isn't yet supported) | |||
* - now the partial support for the Multitexture extension | |||
* works with Quake2 for windows | |||
* - vertex snap is not longer used for the Voodoo2 (FX_V2 | |||
* must be defined) | |||
* - done a lot of cleanup in the fxsetup.c file | |||
* - now the partial support for the Multitexture extension | |||
* works with GLQuake for windows | |||
* | |||
* Dieter Nuetzel (nuetzel@kogs.informatik.uni-hamburg.de) University of Hamburg | |||
* - fixed a problem in the asm code for Linux of the fxvsetup.c file | |||
* highlighted by the binutils-2.8.1.0.29. 'fildw' asm instruction | |||
* changed in 'fild' | |||
* | |||
* Kevin Hester (kevinh@glassworks.net) | |||
* - written the wglUseFontBitmaps() function in the WGL emulator | |||
* | |||
* V0.24 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - now the drive always uses per fragment fog | |||
* - written a small optimization in the points drawing function | |||
* - written the support for trilinear filtering with 2 TMUs | |||
* - written the first partial support for the Multitexture extension. | |||
* This task is quite hard because the color combine units work after | |||
* the two texture combine units and not before as required by the | |||
* Multitexture extension | |||
* - written a workaround in fxBestResolution() in order to solve a | |||
* problem with bzflag (it asks for 1x1 window !) | |||
* - changed the fxBestResolution() behavior. It now returns the larger | |||
* screen resolution supported by the hardware (instead of 640x480) | |||
* when it is unable to find an appropriate resolution that is large | |||
* enough for the requested size | |||
* - the driver is now able to use also the texture memory attached to | |||
* second TMU | |||
* - the texture memory manager is now able to work with two TMUs and | |||
* store texture maps in the memory attached to TMU0, TMU1 or to split | |||
* the mimpmap levels across TMUs in order to support trilinear filtering | |||
* - I have bought a Voodoo2 board ! | |||
* - the amount of frambuffer ram is now doubled when an SLI configuration | |||
* is detected | |||
* - solved a problem related to the fxDDTexParam() and fxTexInvalidate() | |||
* functions (thanks to Rune Hasvold for highlighting the problem) | |||
* - done some cleanup in the fxvsetup.c file, written | |||
* the FXVSETUP_FUNC macro | |||
* - done a lot of cleanup in data types and field names | |||
* | |||
* Rune Hasvold (runeh@ifi.uio.no) | |||
* - written the support for a right management of the auxiliary buffer. | |||
* You can now use an 800x600 screen without the depth and alpha | |||
* buffer | |||
* - written the support for a new pixel format (without the depth | |||
* and alpha buffer) in the WGL emulator | |||
* - fixed a bug in the window version of the GLUT (it was ever asking | |||
* for depth buffer) | |||
* | |||
* V0.23 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - included in the Mesa-3.0beta2 release | |||
* - written the support for the OpenGL 1.2 GL_TEXTURE_BASE_LEVEL | |||
* and GL_TEXTURE_MAX_LEVEL | |||
* - rewritten several functions for a more clean support of texture | |||
* mapping and in order to solve some bug | |||
* - the accumulation buffer works (it is bit slow beacuase it requires | |||
* to read/write from/to the Voodoo frame buffer but it works) | |||
* - fixed a bug in the fxDDReadRGBASpan driver function (the R and | |||
* B channels were read in the wrong order). Thanks to Jason Heym | |||
* for highlighting the problem | |||
* - written the support for multiple contexts on multiple boards. | |||
* you can now use the Mesa/Voodoo with multiple Voodoo Graphics | |||
* boards (for example with multiple screens or an HMD) | |||
* - the fxBestResolution() now check all available resolutions | |||
* and it is able to check the amount of framebuffer memory | |||
* before return a resolution | |||
* - modified the GLX/X11 driver in order to support all the | |||
* resolution available | |||
* - changed all function names. They should be now a bit more | |||
* readable | |||
* - written the Glide grVertex setup code for two TMU or | |||
* for Multitexture support with emulationa dn one TMU | |||
* - written the support for the new Mesa driver | |||
* function GetParametri | |||
* - small optimization/clean up in the texbind() function | |||
* - fixed a FPU precision problem for glOrtho and texture | |||
* mapping (thanks to Antti Juhani Huovilainen for an example | |||
* of the problem) | |||
* - written some small SGI OpenGL emulation code for the wgl, | |||
* the OpenGL Optimizer and Cosmo3D work fine under windows ! | |||
* - moved the point/line/triangle/quad support in the fxmesa7.c | |||
* - fixed a bug in the clear_color_depth() (thanks to Henk Kok | |||
* for an example of the problem) | |||
* - written a small workaround for Linux GLQuake, it asks | |||
* for the alpha buffer and the depth buffer at the some time | |||
* (but it never uses the alpha buffer) | |||
* - checked the antialiasing points, lines and polygons support. | |||
* It works fine | |||
* - written the support for standard OpenGL antialiasing using | |||
* blending. Lines support works fine (tested with BZflag) | |||
* while I have still to check the polygons and points support | |||
* - written the support for the alpha buffer. The driver is now | |||
* able to use the Voodoo auxiliary buffer as an alpha buffer | |||
* instead of a depth buffer. Also all the OpenGL blending | |||
* modes are now supported. But you can't request a context | |||
* with an alpha buffer AND a depth buffer at the some time | |||
* (this is an hardware limitation) | |||
* - written the support for switching between the fullscreen | |||
* rendering and the in-window-rendering hack on the fly | |||
* | |||
* Rune Hasvold (runeh@ifi.uio.no) | |||
* - fixed a bug in the texparam() function | |||
* | |||
* Brian Paul (brianp@elastic.avid.com) Avid Technology | |||
* - sources accomodated for the new Mesa 3.0beta1 | |||
* | |||
* V0.22 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - included with some v0.23 bug fix in the final release | |||
* of the Mesa-2.6 | |||
* - written the support for the MESA_WGL_FX env. var. but | |||
* not tested because I have only Voodoo Graphics boards | |||
* - fixed a bug in the backface culling code | |||
* (thanks to David Farrell for an example of the problem) | |||
* - fixed the "Quake2 elevator" bug | |||
* - GL_POLYGONS with 3/4 vertices are now drawn as | |||
* GL_TRIANLGES/GL_QUADS (a small optimization for GLQuake) | |||
* - fixed a bug in fxmesa6.h for GL_LINE_LOOP | |||
* - fixed a NearFarStack bug in the Mesa when applications | |||
* directly call glLoadMatrix to load a projection matrix | |||
* - done some cleanup in the fxmesa2.c file | |||
* - the driver no longer translates the texture maps | |||
* when the Mesa internal format and the Voodoo | |||
* format are the some (usefull for 1 byte texture maps | |||
* where the driver can directly use the Mesa texture | |||
* map). Also the amount of used memory is halfed | |||
* - fixed a bug for GL_DECAL and GL_RGBA | |||
* - fixed a bug in the clear_color_depth() | |||
* - tested the v0.22 with the Mesa-2.6beta2. Impressive | |||
* performances improvement thanks to the new Josh's | |||
* asm code (+10fps in the isosurf demo, +5fps in GLQuake | |||
* TIMEREFRESH) | |||
* - written a optimized version of the RenderVB Mesa driver | |||
* function. The Voodoo driver is now able to upload polygons | |||
* in the most common cases at a very good speed. Good | |||
* performance improvement for large set of small polygons | |||
* - optimized the asm code for setting up the color information | |||
* in the Glide grVertex structure | |||
* - fixed a bug in the fxmesa2.c asm code (the ClipMask[] | |||
* wasn't working) | |||
* | |||
* Josh Vanderhoof (joshv@planet.net) | |||
* - removed the flush() function because it isn't required | |||
* - limited the maximum number of swapbuffers in the Voodoo | |||
* commands FIFO (controlled by the env. var. MESA_FX_SWAP_PENDING) | |||
* | |||
* Holger Kleemiss (holger.kleemiss@metronet.de) STN Atlas Elektronik GmbH | |||
* - applied some patch for the Voodoo Rush | |||
* | |||
* V0.21 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - the driver is now able to take advantage of the ClipMask[], | |||
* ClipOrMask and ClipAndMask information also under Windows | |||
* - introduced a new function in the Mesa driver interface | |||
* ClearColorAndDepth(). Now the glClear() function is | |||
* 2 times faster (!) when you have to clear the color buffer | |||
* and the depth buffer at some time | |||
* - written the first version of the fxRenderVB() driver | |||
* function | |||
* - optimized the glTexImage() path | |||
* - removed the fxMesaTextureUsePalette() support | |||
* - fixed a bug in the points support (thanks to David Farrell | |||
* for an example of the problem) | |||
* - written the optimized path for glSubTexImage(), | |||
* introduced a new function in the Mesa driver interface | |||
* TexSubImage(...) | |||
* - fixed a bug for glColorMask and glDepthMask | |||
* - the wbuffer is not more used. The Voodoo driver uses | |||
* a standard 16bit zbuffer in all cases. It is more consistent | |||
* and now GLQuake and GLQuake2test work also with a GL_ZTRICK 0 | |||
* - the driver is now able to take advantage of the ClipMask[], | |||
* ClipOrMask and ClipAndMask information (under Linux); | |||
* - rewritten the setup_fx_units() function, now the texture | |||
* mapping support is compliant to the OpenGL specs (GL_BLEND | |||
* support is still missing). The LinuxGLQuake console correctly | |||
* fade in/out and transparent water of GLQuake2test works fine | |||
* - written the support for the env. var. FX_GLIDE_SWAPINTERVAL | |||
* - found a bug in the Mesa core. There is a roundup problem for | |||
* color values out of the [0.0,1.0] range | |||
* | |||
* Wonko <matt@khm.de> | |||
* - fixed a Voodoo Rush related problem in the fxwgl.c | |||
* | |||
* Daryll Strauss <daryll@harlot.rb.ca.us> | |||
* - written the scissor test support | |||
* | |||
* V0.20 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - written the closetmmanger() function in order to free all the memory | |||
* allocated by the Texture Memory Manager (it will be useful | |||
* when the support for multiple contexts/boards will be ready) | |||
* - now the Voodoo driver runs without printing any information, | |||
* define the env. var. MESA_FX_INFO if you want to read some | |||
* information about the hardware and some statistic | |||
* - written a small workaround for the "GLQuake multiplayer white box bug" | |||
* in the setup_fx_units() funxtions. I'm already rewriting | |||
* this function because it is the source of nearly all the current | |||
* Voodoo driver problems | |||
* - fixed the GLQuake texture misalignment problem (the texture | |||
* coordinates must be scaled between 0.0 and 256.0 and not | |||
* between 0.0 and 255.0) | |||
* - written the support for the GL_EXT_shared_texture_palette | |||
* - some small change for supporting the automatic building of the | |||
* OpenGL32.dll under the Windows platform | |||
* - the redefinition of a mipmap level is now a LOT faster. This path | |||
* is used by GLQuake for dynamic lighting with some call to glTexSubImage2D() | |||
* - the texture memory is now managed a set of 2MB blocks so | |||
* texture maps can't be allocated on a 2MB boundary. The new Pure3D | |||
* needs this kind of support (and probably any other Voodoo Graphics | |||
* board with more than 2MB of texture memory) | |||
* | |||
* Brian Paul (brianp@elastic.avid.com) Avid Technology | |||
* - added write_monocolor_span(), fixed bug in write_color_span() | |||
* - added test for stenciling in choosepoint/line/triangle functions | |||
* | |||
* Joe Waters (falc@attila.aegistech.com) Aegis | |||
* - written the support for the env. var. SST_SCREENREFRESH | |||
* | |||
* V0.19 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - written the 3Dfx Global Palette extension for GLQuake | |||
* - written the support for the GL_EXT_paletted_texture (it works only with GL_RGBA | |||
* palettes and the alpha value is ignored ... this is a limitation of the | |||
* the current Glide version and Voodoo hardware) | |||
* - fixed the amount of memory allocated for 8bit textures | |||
* - merged the under construction v0.19 driver with the Mesa 2.5 | |||
* - finally written the support for deleting textures | |||
* - introduced a new powerful texture memory manager: the texture memory | |||
* is used as a cache of the set of all defined texture maps. You can | |||
* now define several MB of texture maps also with a 2MB of texture memory | |||
* (the texture memory manager will do automatically all the swap out/swap in | |||
* work). The new texture memory manager has also | |||
* solved a lot of other bugs/no specs compliance/problems | |||
* related to the texture memory usage. The texture | |||
* manager code is inside the new fxmesa3.c file | |||
* - broken the fxmesa.c file in two files (fxmesa1.c and fxmesa2.c) | |||
* and done some code cleanup | |||
* - now is possible to redefine texture mipmap levels already defined | |||
* - fixed a problem with the amount of texture memory allocated for textures | |||
* with not all mipmap levels defined | |||
* - fixed a small problem with single buffer rendering | |||
* | |||
* Brian Paul (brianp@elastic.avid.com) Avid Technology | |||
* - read/write_color_span() now use front/back buffer correctly | |||
* - create GLvisual with 5,6,5 bits per pixel, not 8,8,8 | |||
* - removed a few ^M characters from fxmesa2.c file | |||
* | |||
* V0.18 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - the Mesa-2.4beta3 is finally using the driver quads support (the | |||
* previous Mesa versions have never taken any advantage from the quads support !) | |||
* - tested with the Glide 2.4 for Win | |||
* - ported all asm code to Linux | |||
* - ported the v0.18 to Linux (without asm code) | |||
* - back to Linux !!! | |||
* - optimized the SETUP macro (no more vertex snap for points and lines) | |||
* - optimized the SETUP macro (added one argument) | |||
* - the Mesa/Voodoo is now 20/30% for points, lines and small triangles ! | |||
* - performance improvement setting VBSIZE to 72 | |||
* - the GrVertex texture code is now written in asm | |||
* - the GrVertex zbuffer code is now written in asm | |||
* - the GrVertex wbuffer code is now written in asm | |||
* - the GrVertex gouraud code is now written in asm | |||
* - the GrVertex snap code is now written in asm | |||
* - changed the 8bit compressed texture maps in 8bit palette texture maps | |||
* support (it has the some advantage of compressed texture maps without the | |||
* problem of a fixed NCC table for all mipmap levels) | |||
* - written the support for 8bit compressed texture maps (but texture maps with | |||
* more than one mipmap level aren't working fine) | |||
* - finnaly everthing is working fine in MesaQuake ! | |||
* - fixed a bug in the computation of texture mapping coordinates (I have found | |||
* the bug thanks to MesaQuake !) | |||
* - written the GL_REPLACE support (mainly for MesaQuake) | |||
* - written the support for textures with not all mipmap levels defined | |||
* - rewritten all the Texture memory stuff | |||
* - written the MesaQuake support (define MESAQUAKE) | |||
* - working with a ZBuffer if glOrtho or not int the default glDepthRange, | |||
* otherwise working with the WBuffer | |||
* written the glDepthRange support | |||
* | |||
* Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l. | |||
* - written the fxCloseHardware() and the fxQuaryHardware() (mainly | |||
* for the VoodooWGL emulator) | |||
* | |||
* Brian Paul (brianp@elastic.avid.com) Avid Technology | |||
* - implemented read/write_color_span() so glRead/DrawPixels() works | |||
* - now needs Glide 2.3 or later. Removed GLIDE_FULL_SCREEN and call to grSstOpen() | |||
* | |||
* V0.17 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - optimized the bitmap support (66% faster) | |||
* - tested with the Mesa 2.3beta2 | |||
* | |||
* Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l. | |||
* - solved a problem with the drawbitmap() and the Voodoo Rush | |||
* (GR_ORIGIN_LOWER_LEFT did not work with the Stingray) | |||
* | |||
* Brian Paul (brianp@elastic.avid.com) Avid Technology | |||
* - linux stuff | |||
* - general code clean-up | |||
* - added attribList parameter to fxMesaCreateContext() | |||
* - single buffering works now | |||
* - VB colors are now GLubytes, removed ColorShift stuff | |||
* | |||
* Paul Metzger | |||
* - linux stuff | |||
* | |||
* V0.16 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - written the quadfunc support (no performance improvement) | |||
* - written the support for the new Mesa 2.3beta1 driver interface (Wow ! It is faaaster) | |||
* - rewritten the glBitmap support for the Glide 2.3 (~35% slower !) | |||
* - written the glBitmap support for the most common case (fonts) | |||
* | |||
* Jack Palevich | |||
* - Glide 2.3 porting | |||
* | |||
* Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l. | |||
* - extended the fxMesaCreateContext() and fxMesaCreateBestContext() | |||
* functions in order to support also the Voodoo Rush | |||
* - tested with the Hercules Stingray 128/3D (The rendering in a window works !) | |||
* | |||
* V0.15 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - written the GL_LUMINANCE_ALPHA support | |||
* - written the GL_ALPHA support | |||
* - written the GL_LUMINANCE support | |||
* - now SETUP correctly set color for mono color sequences | |||
* - written the 9x1,10x1,...,1x9,1x10,... texture map ratio support | |||
* - written the no square texture map support | |||
* - the fog table is no more rebuilt inside setup_fx_units() each time | |||
* | |||
* Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation | |||
* - written (not yet finished: no texture mapping) support for glOrtho | |||
* - some change to setup functions | |||
* - the fog support is now fully compatible with the standard OpenGL | |||
* - rewritten several parts of the driver in order to take | |||
* advantage of meshes (40% faster !!!) | |||
* | |||
* V0.14 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - now glAlphaFunc() works | |||
* - now glDepthMask() works | |||
* - solved a mipmap problem when using more than one texture | |||
* - moved ti, texid and wscale inside the fxMesaContext (now we can | |||
* easy support more ctx and more boards) | |||
* - the management of the fxMesaContext was completly broken ! | |||
* - solved several problems about Alpha and texture Alpha | |||
* - 4 (RGBA) texture channels supported | |||
* - setting the default color to white | |||
* | |||
* Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation | |||
* - small change to fxMesaCreateContext() and fxMesaMakeCurrent() | |||
* - written the fog support | |||
* - setting the default clear color to black | |||
* - written cleangraphics() for the onexit() function | |||
* - written fxMesaCreateBestContext() | |||
* | |||
* V0.13 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - now glBlendFunc() works for all glBlendFunc without DST_ALPHA | |||
* (because the alpha buffer is not yet implemented) | |||
* - now fxMesaCreateContext() accept resolution and refresh rate | |||
* - fixed a bug for texture mapping: the w (alias z) must be set | |||
* also without depth buffer | |||
* - fixed a bug for texture image with width!=256 | |||
* - written texparam() | |||
* - written all point, line and triangle functions for all possible supported | |||
* contexts and the driver is slight faster with points, lines and small triangles | |||
* - fixed a small bug in fx/fxmesa.h (glOrtho) | |||
* | |||
* V0.12 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - glDepthFunc supported | |||
* - introduced a trick to discover the far plane distance | |||
* (see fxMesaSetFar and fx/fxmesa.h) | |||
* - now the wbuffer works with homogeneous coordinate (and it | |||
* doesn't work with a glOrtho projection :) | |||
* - solved several problems with homogeneous coordinate and texture mapping | |||
* - fixed a bug in all line functions | |||
* - fixed a clear framebuffer bug | |||
* - solved a display list/teximg problem (but use | |||
* glBindTexture: it is several times faster) | |||
* | |||
* V0.11 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - introduced texture mapping support (not yet finished !) | |||
* - tested with Mesa2.2b6 | |||
* - the driver is faster | |||
* - written glFlush/glFinish | |||
* - the driver print a lot of info about the Glide lib | |||
* | |||
* v0.1 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l. | |||
* - Initial revision | |||
* | |||
*/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "conf.h" | |||
#endif | |||
@@ -686,13 +113,6 @@ fxMesaContext GLAPIENTRY fxMesaGetCurrentContext(void) | |||
} | |||
void GLAPIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f) | |||
{ | |||
if(fxMesaCurrentCtx) | |||
fxDDSetNearFar(fxMesaCurrentCtx->glCtx,n,f); | |||
} | |||
/* | |||
* The 3Dfx Global Palette extension for GLQuake. | |||
* More a trick than a real extesion, use the shared global | |||
@@ -1294,7 +714,7 @@ void GLAPIENTRY fxMesaSwapBuffers(void) | |||
} | |||
if(fxMesaCurrentCtx) { | |||
FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" ); | |||
_mesa_swapbuffers( fxMesaCurrentCtx->glCtx ); | |||
if(fxMesaCurrentCtx->haveDoubleBuffer) { | |||
@@ -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; | |||
@@ -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 ); | |||
@@ -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); |
@@ -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 ); | |||
} |
@@ -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 */ | |||
{ |
@@ -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 ); | |||
@@ -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 */ |
@@ -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" | |||
@@ -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" |
@@ -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 = "); |
@@ -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 | |||
@@ -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; |
@@ -1,4 +1,4 @@ | |||
/* $Id: clip.c,v 1.14 2000/11/13 20:02:56 keithw Exp $ */ | |||
/* $Id: clip.c,v 1.15 2000/11/16 21:05:34 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
@@ -30,133 +30,16 @@ | |||
#else | |||
#include "glheader.h" | |||
#include "clip.h" | |||
#include "colormac.h" | |||
#include "context.h" | |||
#include "macros.h" | |||
#include "matrix.h" | |||
#include "mmath.h" | |||
#include "types.h" | |||
#include "vb.h" | |||
#include "xform.h" | |||
#endif | |||
#define CLIP_RGBA0 0x1 | |||
#define CLIP_RGBA1 0x2 | |||
#define CLIP_TEX0 0x4 | |||
#define CLIP_TEX1 0x8 | |||
#define CLIP_INDEX0 0x10 | |||
#define CLIP_INDEX1 0x20 | |||
#define CLIP_FOG_COORD 0x40 | |||
/* Linear interpolation between A and B: */ | |||
#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) | |||
#define INTERP_SZ( t, vec, to, a, b, sz ) \ | |||
do { \ | |||
switch (sz) { \ | |||
case 4: vec[to][3] = LINTERP( t, vec[a][3], vec[b][3] ); \ | |||
case 3: vec[to][2] = LINTERP( t, vec[a][2], vec[b][2] ); \ | |||
case 2: vec[to][1] = LINTERP( t, vec[a][1], vec[b][1] ); \ | |||
case 1: vec[to][0] = LINTERP( t, vec[a][0], vec[b][0] ); \ | |||
} \ | |||
} while(0) | |||
static clip_interp_func clip_interp_tab[0x80]; | |||
#define IND 0 | |||
#define NAME clip_nil | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_RGBA0) | |||
#define NAME clipRGBA0 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_RGBA0|CLIP_RGBA1) | |||
#define NAME clipRGBA0_RGBA1 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX0|CLIP_RGBA0) | |||
#define NAME clipTEX0_RGBA0 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1) | |||
#define NAME clipTEX0_RGBA0_RGBA1 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0) | |||
#define NAME clipTEX1_TEX0_RGBA0 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX0) | |||
#define NAME clipTEX0 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX1|CLIP_TEX0) | |||
#define NAME clipTEX1_TEX0 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1) | |||
#define NAME clipTEX1_TEX0_RGBA0_RGBA1 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_INDEX0) | |||
#define NAME clipINDEX0 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_INDEX0|CLIP_INDEX1) | |||
#define NAME clipINDEX0_INDEX1 | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_FOG_COORD) | |||
#define NAME clip_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_RGBA0|CLIP_FOG_COORD) | |||
#define NAME clipRGBA0_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD) | |||
#define NAME clipRGBA0_RGBA1_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD) | |||
#define NAME clipTEX0_RGBA0_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD) | |||
#define NAME clipTEX0_RGBA0_RGBA1_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD) | |||
#define NAME clipTEX1_TEX0_RGBA0_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX0|CLIP_FOG_COORD) | |||
#define NAME clipTEX0_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_FOG_COORD) | |||
#define NAME clipTEX1_TEX0_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD) | |||
#define NAME clipTEX1_TEX0_RGBA0_RGBA1_FOG | |||
#include "interp_tmp.h" | |||
#include "math/m_xform.h" | |||
#include "math/m_matrix.h" | |||
#endif | |||
#define IND (CLIP_INDEX0|CLIP_FOG_COORD) | |||
#define NAME clipINDEX0_FOG | |||
#include "interp_tmp.h" | |||
#define IND (CLIP_INDEX0|CLIP_INDEX1|CLIP_FOG_COORD) | |||
#define NAME clipINDEX0_INDEX1_FOG | |||
#include "interp_tmp.h" | |||
@@ -173,12 +56,6 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) | |||
GET_CURRENT_CONTEXT(ctx); | |||
GLint p; | |||
GLfloat equation[4]; | |||
equation[0] = eq[0]; | |||
equation[1] = eq[1]; | |||
equation[2] = eq[2]; | |||
equation[3] = eq[3]; | |||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClipPlane"); | |||
p = (GLint) plane - (GLint) GL_CLIP_PLANE0; | |||
@@ -187,6 +64,11 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) | |||
return; | |||
} | |||
equation[0] = eq[0]; | |||
equation[1] = eq[1]; | |||
equation[2] = eq[2]; | |||
equation[3] = eq[3]; | |||
/* | |||
* The equation is transformed by the transpose of the inverse of the | |||
* current modelview matrix and stored in the resulting eye coordinates. | |||
@@ -195,17 +77,21 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) | |||
* clipping now takes place. The clip-space equations are recalculated | |||
* whenever the projection matrix changes. | |||
*/ | |||
if (ctx->ModelView.flags & MAT_DIRTY_ALL_OVER) { | |||
gl_matrix_analyze( &ctx->ModelView ); | |||
} | |||
if (ctx->ModelView.flags & MAT_DIRTY) | |||
_math_matrix_analyze( &ctx->ModelView ); | |||
gl_transform_vector( ctx->Transform.EyeUserPlane[p], equation, | |||
ctx->ModelView.inv ); | |||
/* Update derived state. This state also depends on the projection | |||
* matrix, and is recalculated on changes to the projection matrix by | |||
* code in gl_update_state(). | |||
*/ | |||
if (ctx->Transform.ClipEnabled[p]) { | |||
if (ctx->ProjectionMatrix.flags & MAT_DIRTY_ALL_OVER) { | |||
gl_matrix_analyze( &ctx->ProjectionMatrix ); | |||
} | |||
if (ctx->ProjectionMatrix.flags & MAT_DIRTY) | |||
_math_matrix_analyze( &ctx->ProjectionMatrix ); | |||
gl_transform_vector( ctx->Transform._ClipUserPlane[p], | |||
ctx->Transform.EyeUserPlane[p], | |||
ctx->ProjectionMatrix.inv ); | |||
@@ -235,268 +121,3 @@ _mesa_GetClipPlane( GLenum plane, GLdouble *equation ) | |||
equation[2] = (GLdouble) ctx->Transform.EyeUserPlane[p][2]; | |||
equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3]; | |||
} | |||
/**********************************************************************/ | |||
/* View volume clipping. */ | |||
/**********************************************************************/ | |||
/* | |||
* Clip a point against the view volume. | |||
* Input: v - vertex-vector describing the point to clip | |||
* Return: 0 = outside view volume | |||
* 1 = inside view volume | |||
*/ | |||
GLuint gl_viewclip_point( const GLfloat v[] ) | |||
{ | |||
if ( v[0] > v[3] || v[0] < -v[3] | |||
|| v[1] > v[3] || v[1] < -v[3] | |||
|| v[2] > v[3] || v[2] < -v[3] ) { | |||
return 0; | |||
} | |||
else { | |||
return 1; | |||
} | |||
} | |||
/* | |||
* Clip a point against the user clipping planes. | |||
* Input: v - vertex-vector describing the point to clip. | |||
* Return: 0 = point was clipped | |||
* 1 = point not clipped | |||
*/ | |||
GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] ) | |||
{ | |||
GLuint p; | |||
for (p=0;p<MAX_CLIP_PLANES;p++) { | |||
if (ctx->Transform.ClipEnabled[p]) { | |||
GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0] | |||
+ v[1] * ctx->Transform._ClipUserPlane[p][1] | |||
+ v[2] * ctx->Transform._ClipUserPlane[p][2] | |||
+ v[3] * ctx->Transform._ClipUserPlane[p][3]; | |||
if (dot < 0.0F) { | |||
return 0; | |||
} | |||
} | |||
} | |||
return 1; | |||
} | |||
#if 0 | |||
#define NEGATIVE(x) ((*(int *)&x)<0) | |||
#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) | |||
#else | |||
#define NEGATIVE(x) (x < 0) | |||
#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) | |||
#endif | |||
static clip_poly_func gl_poly_clip_tab[2][5]; | |||
static clip_line_func gl_line_clip_tab[2][5]; | |||
#define W(i) coord[i][3] | |||
#define Z(i) coord[i][2] | |||
#define Y(i) coord[i][1] | |||
#define X(i) coord[i][0] | |||
#define SIZE 4 | |||
#define IND 0 | |||
#define TAG(x) x##_4 | |||
#include "clip_funcs.h" | |||
#define W(i) 1.0 | |||
#define Z(i) coord[i][2] | |||
#define Y(i) coord[i][1] | |||
#define X(i) coord[i][0] | |||
#define SIZE 3 | |||
#define IND 0 | |||
#define TAG(x) x##_3 | |||
#include "clip_funcs.h" | |||
#define W(i) 1.0 | |||
#define Z(i) 0.0 | |||
#define Y(i) coord[i][1] | |||
#define X(i) coord[i][0] | |||
#define SIZE 2 | |||
#define IND 0 | |||
#define TAG(x) x##_2 | |||
#include "clip_funcs.h" | |||
#define W(i) coord[i][3] | |||
#define Z(i) coord[i][2] | |||
#define Y(i) coord[i][1] | |||
#define X(i) coord[i][0] | |||
#define SIZE 4 | |||
#define IND CLIP_TAB_EDGEFLAG | |||
#define TAG(x) x##_4_edgeflag | |||
#include "clip_funcs.h" | |||
#define W(i) 1.0 | |||
#define Z(i) coord[i][2] | |||
#define Y(i) coord[i][1] | |||
#define X(i) coord[i][0] | |||
#define SIZE 3 | |||
#define IND CLIP_TAB_EDGEFLAG | |||
#define TAG(x) x##_3_edgeflag | |||
#include "clip_funcs.h" | |||
#define W(i) 1.0 | |||
#define Z(i) 0.0 | |||
#define Y(i) coord[i][1] | |||
#define X(i) coord[i][0] | |||
#define SIZE 2 | |||
#define IND CLIP_TAB_EDGEFLAG | |||
#define TAG(x) x##_2_edgeflag | |||
#include "clip_funcs.h" | |||
void gl_update_clipmask( GLcontext *ctx ) | |||
{ | |||
GLuint mask = 0; | |||
if (ctx->Visual.RGBAflag) | |||
{ | |||
mask |= CLIP_RGBA0; | |||
if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_SEPERATE_SPECULAR)) | |||
mask |= CLIP_RGBA1; | |||
if (ctx->Texture._ReallyEnabled & 0xf0) | |||
mask |= CLIP_TEX1|CLIP_TEX0; | |||
if (ctx->Texture._ReallyEnabled & 0xf) | |||
mask |= CLIP_TEX0; | |||
} | |||
else if (ctx->Light.ShadeModel==GL_SMOOTH) | |||
{ | |||
mask |= CLIP_INDEX0; | |||
if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) | |||
mask |= CLIP_INDEX1; | |||
} | |||
if (ctx->Fog.Enabled) | |||
mask |= CLIP_FOG_COORD; | |||
ctx->_ClipInterpFunc = clip_interp_tab[mask]; | |||
ctx->_poly_clip_tab = gl_poly_clip_tab[0]; | |||
ctx->_line_clip_tab = gl_line_clip_tab[0]; | |||
if (ctx->_TriangleCaps & DD_TRI_UNFILLED) { | |||
ctx->_poly_clip_tab = gl_poly_clip_tab[1]; | |||
ctx->_line_clip_tab = gl_line_clip_tab[0]; | |||
} | |||
} | |||
#define USER_CLIPTEST(NAME, SZ) \ | |||
static void NAME( struct vertex_buffer *VB ) \ | |||
{ \ | |||
GLcontext *ctx = VB->ctx; \ | |||
GLubyte *clipMask = VB->ClipMask; \ | |||
GLubyte *userClipMask = VB->UserClipMask; \ | |||
GLuint start = VB->Start; \ | |||
GLuint count = VB->Count; \ | |||
GLuint p, i; \ | |||
GLubyte bit; \ | |||
\ | |||
\ | |||
for (bit = 1, p = 0; p < MAX_CLIP_PLANES ; p++, bit *=2) \ | |||
if (ctx->Transform.ClipEnabled[p]) { \ | |||
GLuint nr = 0; \ | |||
const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; \ | |||
const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; \ | |||
const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; \ | |||
const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; \ | |||
GLfloat *coord = VB->ClipPtr->start; \ | |||
GLuint stride = VB->ClipPtr->stride; \ | |||
\ | |||
for (i = start ; i < count ; i++, STRIDE_F(coord, stride)) { \ | |||
GLfloat dp = coord[0] * a + coord[1] * b; \ | |||
if (SZ > 2) dp += coord[2] * c; \ | |||
if (SZ > 3) dp += coord[3] * d; else dp += d; \ | |||
\ | |||
if (dp < 0) { \ | |||
clipMask[i] |= CLIP_USER_BIT; \ | |||
userClipMask[i] |= bit; \ | |||
nr++; \ | |||
} \ | |||
} \ | |||
\ | |||
if (nr > 0) { \ | |||
VB->ClipOrMask |= CLIP_USER_BIT; \ | |||
VB->CullMode |= CLIP_MASK_ACTIVE; \ | |||
if (nr == count - start) { \ | |||
VB->ClipAndMask |= CLIP_USER_BIT; \ | |||
VB->Culled = 1; \ | |||
return; \ | |||
} \ | |||
} \ | |||
} \ | |||
} | |||
USER_CLIPTEST(userclip2, 2) | |||
USER_CLIPTEST(userclip3, 3) | |||
USER_CLIPTEST(userclip4, 4) | |||
static void (*(usercliptab[5]))( struct vertex_buffer * ) = { | |||
0, | |||
0, | |||
userclip2, | |||
userclip3, | |||
userclip4 | |||
}; | |||
void gl_user_cliptest( struct vertex_buffer *VB ) | |||
{ | |||
usercliptab[VB->ClipPtr->size]( VB ); | |||
} | |||
void gl_init_clip(void) | |||
{ | |||
init_clip_funcs_4(); | |||
init_clip_funcs_3(); | |||
init_clip_funcs_2(); | |||
init_clip_funcs_4_edgeflag(); | |||
init_clip_funcs_3_edgeflag(); | |||
init_clip_funcs_2_edgeflag(); | |||
clip_interp_tab[0] = clip_nil; | |||
clip_interp_tab[CLIP_RGBA0] = clipRGBA0; | |||
clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1] = clipRGBA0_RGBA1; | |||
clip_interp_tab[CLIP_TEX0|CLIP_RGBA0] = clipTEX0_RGBA0; | |||
clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = clipTEX0_RGBA0_RGBA1; | |||
clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0] = clipTEX1_TEX0_RGBA0; | |||
clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = | |||
clipTEX1_TEX0_RGBA0_RGBA1; | |||
clip_interp_tab[CLIP_TEX0] = clipTEX0; | |||
clip_interp_tab[CLIP_TEX1|CLIP_TEX0] = clipTEX1_TEX0; | |||
clip_interp_tab[CLIP_INDEX0] = clipINDEX0; | |||
clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1] = clipINDEX0_INDEX1; | |||
clip_interp_tab[CLIP_FOG_COORD] = clip_FOG; | |||
clip_interp_tab[CLIP_RGBA0|CLIP_FOG_COORD] = clipRGBA0_FOG; | |||
clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = clipRGBA0_RGBA1_FOG; | |||
clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD] = clipTEX0_RGBA0_FOG; | |||
clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = clipTEX0_RGBA0_RGBA1_FOG; | |||
clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD] = clipTEX1_TEX0_RGBA0_FOG; | |||
clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = | |||
clipTEX1_TEX0_RGBA0_RGBA1_FOG; | |||
clip_interp_tab[CLIP_TEX0|CLIP_FOG_COORD] = clipTEX0_FOG; | |||
clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_FOG_COORD] = clipTEX1_TEX0_FOG; | |||
clip_interp_tab[CLIP_INDEX0|CLIP_FOG_COORD] = clipINDEX0_FOG; | |||
clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1|CLIP_FOG_COORD] = clipINDEX0_INDEX1_FOG; | |||
} | |||
@@ -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 |
@@ -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. | |||
*/ | |||
/* |
@@ -1,4 +1,4 @@ | |||
/* $Id: context.c,v 1.105 2000/11/15 16:38:40 brianp Exp $ */ | |||
/* $Id: context.c,v 1.106 2000/11/16 21:05:34 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
@@ -33,7 +33,6 @@ | |||
#include "clip.h" | |||
#include "colortab.h" | |||
#include "context.h" | |||
#include "cva.h" | |||
#include "dlist.h" | |||
#include "eval.h" | |||
#include "enums.h" | |||
@@ -46,25 +45,21 @@ | |||
#include "imports.h" | |||
#include "light.h" | |||
#include "macros.h" | |||
#include "matrix.h" | |||
#include "mem.h" | |||
#include "mmath.h" | |||
#include "pipeline.h" | |||
#include "shade.h" | |||
#include "simple_list.h" | |||
#include "stages.h" | |||
#include "state.h" | |||
#include "translate.h" | |||
#include "teximage.h" | |||
#include "texobj.h" | |||
#include "texture.h" | |||
#include "types.h" | |||
#include "varray.h" | |||
#include "vb.h" | |||
#include "vbrender.h" | |||
#include "vbxform.h" | |||
#include "vertices.h" | |||
#include "xform.h" | |||
#include "math/m_translate.h" | |||
#include "math/m_vertices.h" | |||
#include "math/m_matrix.h" | |||
#include "math/m_xform.h" | |||
#include "math/math.h" | |||
#endif | |||
#if defined(MESA_TRACE) | |||
@@ -73,6 +68,25 @@ | |||
#endif | |||
#ifndef MESA_VERBOSE | |||
int MESA_VERBOSE = 0 | |||
/* | VERBOSE_PIPELINE */ | |||
/* | VERBOSE_IMMEDIATE */ | |||
/* | VERBOSE_VARRAY */ | |||
/* | VERBOSE_TEXTURE */ | |||
/* | VERBOSE_API */ | |||
/* | VERBOSE_DRIVER */ | |||
/* | VERBOSE_STATE */ | |||
/* | VERBOSE_CULL */ | |||
/* | VERBOSE_DISPLAY_LIST */ | |||
; | |||
#endif | |||
#ifndef MESA_DEBUG_FLAGS | |||
int MESA_DEBUG_FLAGS = 0 | |||
/* | DEBUG_ALWAYS_FLUSH */ | |||
; | |||
#endif | |||
/**********************************************************************/ | |||
/***** OpenGL SI-style interface (new in Mesa 3.5) *****/ | |||
@@ -145,12 +159,6 @@ __glCoreNopDispatch(void) | |||
/**********************************************************************/ | |||
#if !defined(THREADS) | |||
struct immediate *_mesa_CurrentInput = NULL; | |||
#endif | |||
/**********************************************************************/ | |||
/***** GL Visual allocation/destruction *****/ | |||
@@ -442,17 +450,10 @@ one_time_init( void ) | |||
assert( sizeof(GLushort) >= 2 ); | |||
assert( sizeof(GLuint) >= 4 ); | |||
gl_init_clip(); | |||
gl_init_eval(); | |||
_mesa_init_math(); | |||
gl_init_lists(); | |||
gl_init_shade(); | |||
gl_init_texture(); | |||
gl_init_transformation(); | |||
gl_init_translate(); | |||
gl_init_vbrender(); | |||
gl_init_vbxform(); | |||
gl_init_vertices(); | |||
_mesa_init_math(); | |||
_math_init(); | |||
if (getenv("MESA_DEBUG")) { | |||
_glapi_noop_enable_warnings(GL_TRUE); | |||
@@ -809,45 +810,43 @@ init_attrib_groups( GLcontext *ctx ) | |||
ctx->Const.NumCompressedTextureFormats = 0; | |||
/* Modelview matrix */ | |||
gl_matrix_ctr( &ctx->ModelView ); | |||
gl_matrix_alloc_inv( &ctx->ModelView ); | |||
_math_matrix_ctr( &ctx->ModelView ); | |||
_math_matrix_alloc_inv( &ctx->ModelView ); | |||
ctx->ModelViewStackDepth = 0; | |||
for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) { | |||
gl_matrix_ctr( &ctx->ModelViewStack[i] ); | |||
gl_matrix_alloc_inv( &ctx->ModelViewStack[i] ); | |||
_math_matrix_ctr( &ctx->ModelViewStack[i] ); | |||
_math_matrix_alloc_inv( &ctx->ModelViewStack[i] ); | |||
} | |||
/* Projection matrix - need inv for user clipping in clip space*/ | |||
gl_matrix_ctr( &ctx->ProjectionMatrix ); | |||
gl_matrix_alloc_inv( &ctx->ProjectionMatrix ); | |||
gl_matrix_ctr( &ctx->_ModelProjectMatrix ); | |||
_math_matrix_ctr( &ctx->ProjectionMatrix ); | |||
_math_matrix_alloc_inv( &ctx->ProjectionMatrix ); | |||
ctx->ProjectionStackDepth = 0; | |||
ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */ | |||
ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */ | |||
for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) { | |||
gl_matrix_ctr( &ctx->ProjectionStack[i] ); | |||
gl_matrix_alloc_inv( &ctx->ProjectionStack[i] ); | |||
_math_matrix_ctr( &ctx->ProjectionStack[i] ); | |||
_math_matrix_alloc_inv( &ctx->ProjectionStack[i] ); | |||
} | |||
/* Derived ModelProject matrix */ | |||
_math_matrix_ctr( &ctx->_ModelProjectMatrix ); | |||
/* Texture matrix */ | |||
for (i = 0; i < MAX_TEXTURE_UNITS; i++) { | |||
gl_matrix_ctr( &ctx->TextureMatrix[i] ); | |||
_math_matrix_ctr( &ctx->TextureMatrix[i] ); | |||
ctx->TextureStackDepth[i] = 0; | |||
for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) { | |||
gl_matrix_ctr( &ctx->TextureStack[i][j] ); | |||
_math_matrix_ctr( &ctx->TextureStack[i][j] ); | |||
ctx->TextureStack[i][j].inv = 0; | |||
} | |||
} | |||
/* Color matrix */ | |||
gl_matrix_ctr(&ctx->ColorMatrix); | |||
_math_matrix_ctr(&ctx->ColorMatrix); | |||
ctx->ColorStackDepth = 0; | |||
for (j = 0; j < MAX_COLOR_STACK_DEPTH - 1; j++) { | |||
gl_matrix_ctr(&ctx->ColorStack[j]); | |||
_math_matrix_ctr(&ctx->ColorStack[j]); | |||
} | |||
/* Accumulate buffer group */ | |||
@@ -893,19 +892,6 @@ init_attrib_groups( GLcontext *ctx ) | |||
ctx->Current.RasterPosValid = GL_TRUE; | |||
ctx->Current.EdgeFlag = GL_TRUE; | |||
ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 ); | |||
ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1); | |||
ctx->Current.Flag = (VERT_NORM | | |||
VERT_INDEX | | |||
VERT_RGBA | | |||
VERT_SPEC_RGB | | |||
VERT_FOG_COORD | | |||
VERT_EDGE | | |||
VERT_TEX0_12 | | |||
VERT_TEX1_12 | | |||
VERT_TEX2_12 | | |||
VERT_TEX3_12 | | |||
VERT_MATERIAL); | |||
init_fallback_arrays( ctx ); | |||
@@ -1023,15 +1009,9 @@ init_attrib_groups( GLcontext *ctx ) | |||
ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000; | |||
ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000; | |||
/* Pipeline */ | |||
gl_pipeline_init( ctx ); | |||
gl_cva_init( ctx ); | |||
/* Extensions */ | |||
gl_extensions_ctr( ctx ); | |||
ctx->AllowVertexCull = CLIP_CULLED_BIT; | |||
/* Lighting group */ | |||
for (i=0;i<MAX_LIGHTS;i++) { | |||
init_light( &ctx->Light.Light[i], i ); | |||
@@ -1227,7 +1207,7 @@ init_attrib_groups( GLcontext *ctx ) | |||
ctx->Viewport.Height = 0; | |||
ctx->Viewport.Near = 0.0; | |||
ctx->Viewport.Far = 1.0; | |||
gl_matrix_ctr(&ctx->Viewport._WindowMap); | |||
_math_matrix_ctr(&ctx->Viewport._WindowMap); | |||
#define Sz 10 | |||
#define Tz 14 | |||
@@ -1454,12 +1434,6 @@ _mesa_initialize_context( GLcontext *ctx, | |||
ctx->Visual = *visual; | |||
ctx->DrawBuffer = NULL; | |||
ctx->ReadBuffer = NULL; | |||
ctx->VB = gl_vb_create_for_immediate( ctx ); | |||
if (!ctx->VB) { | |||
return GL_FALSE; | |||
} | |||
ctx->input = ctx->VB->IM; | |||
if (share_list) { | |||
/* share the group of display lists of another context */ | |||
@@ -1469,7 +1443,6 @@ _mesa_initialize_context( GLcontext *ctx, | |||
/* allocate new group of display lists */ | |||
ctx->Shared = alloc_shared_state(); | |||
if (!ctx->Shared) { | |||
ALIGN_FREE( ctx->VB ); | |||
return GL_FALSE; | |||
} | |||
} | |||
@@ -1479,9 +1452,6 @@ _mesa_initialize_context( GLcontext *ctx, | |||
init_attrib_groups( ctx ); | |||
gl_reset_vb( ctx->VB ); | |||
gl_reset_input( ctx ); | |||
if (visual->DBflag) { | |||
ctx->Color.DrawBuffer = GL_BACK; | |||
ctx->Color.DriverDrawBuffer = GL_BACK_LEFT; | |||
@@ -1499,7 +1469,6 @@ _mesa_initialize_context( GLcontext *ctx, | |||
if (!alloc_proxy_textures(ctx)) { | |||
free_shared_state(ctx, ctx->Shared); | |||
ALIGN_FREE( ctx->VB ); | |||
return GL_FALSE; | |||
} | |||
@@ -1526,7 +1495,6 @@ _mesa_initialize_context( GLcontext *ctx, | |||
ctx->Save = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*)); | |||
if (!ctx->Exec || !ctx->Save) { | |||
free_shared_state(ctx, ctx->Shared); | |||
ALIGN_FREE( ctx->VB ); | |||
if (ctx->Exec) | |||
FREE( ctx->Exec ); | |||
} | |||
@@ -1541,7 +1509,6 @@ _mesa_initialize_context( GLcontext *ctx, | |||
or should we just trap in NewTrace (currently done)? */ | |||
if (!(ctx->TraceCtx)) { | |||
free_shared_state(ctx, ctx->Shared); | |||
ALIGN_FREE( ctx->VB ); | |||
FREE( ctx->Exec ); | |||
FREE( ctx->Save ); | |||
return GL_FALSE; | |||
@@ -1554,7 +1521,6 @@ _mesa_initialize_context( GLcontext *ctx, | |||
#if 0 | |||
if (!(ctx->TraceCtx)) { | |||
free_shared_state(ctx, ctx->Shared); | |||
ALIGN_FREE( ctx->VB ); | |||
FREE( ctx->Exec ); | |||
FREE( ctx->Save ); | |||
FREE( ctx->TraceCtx ); | |||
@@ -1613,26 +1579,21 @@ _mesa_free_context_data( GLcontext *ctx ) | |||
_mesa_make_current(NULL, NULL); | |||
} | |||
gl_matrix_dtr( &ctx->ModelView ); | |||
_math_matrix_dtr( &ctx->ModelView ); | |||
for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) { | |||
gl_matrix_dtr( &ctx->ModelViewStack[i] ); | |||
_math_matrix_dtr( &ctx->ModelViewStack[i] ); | |||
} | |||
gl_matrix_dtr( &ctx->ProjectionMatrix ); | |||
_math_matrix_dtr( &ctx->ProjectionMatrix ); | |||
for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) { | |||
gl_matrix_dtr( &ctx->ProjectionStack[i] ); | |||
_math_matrix_dtr( &ctx->ProjectionStack[i] ); | |||
} | |||
for (i = 0; i < MAX_TEXTURE_UNITS; i++) { | |||
gl_matrix_dtr( &ctx->TextureMatrix[i] ); | |||
_math_matrix_dtr( &ctx->TextureMatrix[i] ); | |||
for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) { | |||
gl_matrix_dtr( &ctx->TextureStack[i][j] ); | |||
_math_matrix_dtr( &ctx->TextureStack[i][j] ); | |||
} | |||
} | |||
if (ctx->input != ctx->VB->IM) | |||
gl_immediate_free( ctx->input ); | |||
gl_vb_free( ctx->VB ); | |||
_glthread_LOCK_MUTEX(ctx->Shared->Mutex); | |||
ctx->Shared->RefCount--; | |||
assert(ctx->Shared->RefCount >= 0); | |||
@@ -1696,12 +1657,6 @@ _mesa_free_context_data( GLcontext *ctx ) | |||
_mesa_free_colortable_data( &ctx->PostColorMatrixColorTable ); | |||
_mesa_free_colortable_data( &ctx->Texture.Palette ); | |||
/* Free cache of immediate buffers. */ | |||
while (ctx->nr_im_queued-- > 0) { | |||
struct immediate * next = ctx->freed_im_queue->next; | |||
ALIGN_FREE( ctx->freed_im_queue ); | |||
ctx->freed_im_queue = next; | |||
} | |||
gl_extensions_dtr(ctx); | |||
FREE(ctx->Exec); | |||
@@ -1828,6 +1783,29 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer ) | |||
} | |||
static void print_info( void ) | |||
{ | |||
fprintf(stderr, "Mesa GL_VERSION = %s\n", | |||
(char *) _mesa_GetString(GL_VERSION)); | |||
fprintf(stderr, "Mesa GL_RENDERER = %s\n", | |||
(char *) _mesa_GetString(GL_RENDERER)); | |||
fprintf(stderr, "Mesa GL_VENDOR = %s\n", | |||
(char *) _mesa_GetString(GL_VENDOR)); | |||
fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", | |||
(char *) _mesa_GetString(GL_EXTENSIONS)); | |||
#if defined(THREADS) | |||
fprintf(stderr, "Mesa thread-safe: YES\n"); | |||
#else | |||
fprintf(stderr, "Mesa thread-safe: NO\n"); | |||
#endif | |||
#if defined(USE_X86_ASM) | |||
fprintf(stderr, "Mesa x86-optimized: YES\n"); | |||
#else | |||
fprintf(stderr, "Mesa x86-optimized: NO\n"); | |||
#endif | |||
} | |||
/* | |||
* Bind the given context to the given draw-buffer and read-buffer | |||
* and make it the current context for this thread. | |||
@@ -1836,23 +1814,8 @@ void | |||
_mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, | |||
GLframebuffer *readBuffer ) | |||
{ | |||
#if 0 | |||
GLcontext *oldCtx = gl_get_context(); | |||
/* Flush the old context | |||
*/ | |||
if (oldCtx) { | |||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "_mesa_make_current"); | |||
/* unbind frame buffers from context */ | |||
if (oldCtx->DrawBuffer) { | |||
oldCtx->DrawBuffer = NULL; | |||
} | |||
if (oldCtx->ReadBuffer) { | |||
oldCtx->ReadBuffer = NULL; | |||
} | |||
} | |||
#endif | |||
if (MESA_VERBOSE) | |||
fprintf(stderr, "_mesa_make_current2()\n"); | |||
/* We call this function periodically (just here for now) in | |||
* order to detect when multithreading has begun. | |||
@@ -1861,47 +1824,36 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, | |||
_glapi_set_context((void *) newCtx); | |||
ASSERT(_mesa_get_current_context() == newCtx); | |||
if (newCtx) { | |||
SET_IMMEDIATE(newCtx, newCtx->input); | |||
_glapi_set_dispatch(newCtx->CurrentDispatch); | |||
} | |||
else { | |||
if (!newCtx) { | |||
_glapi_set_dispatch(NULL); /* none current */ | |||
} | |||
else { | |||
_glapi_set_dispatch(newCtx->CurrentDispatch); | |||
if (MESA_VERBOSE) fprintf(stderr, "_mesa_make_current()\n"); | |||
if (drawBuffer && readBuffer) { | |||
/* TODO: check if newCtx and buffer's visual match??? */ | |||
newCtx->DrawBuffer = drawBuffer; | |||
newCtx->ReadBuffer = readBuffer; | |||
newCtx->NewState |= _NEW_BUFFERS; | |||
/* gl_update_state( newCtx ); */ | |||
} | |||
if (newCtx && drawBuffer && readBuffer) { | |||
/* TODO: check if newCtx and buffer's visual match??? */ | |||
newCtx->DrawBuffer = drawBuffer; | |||
newCtx->ReadBuffer = readBuffer; | |||
newCtx->NewState |= _NEW_BUFFERS; | |||
gl_update_state( newCtx ); | |||
} | |||
if (newCtx->Driver.MakeCurrent) | |||
newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer ); | |||
/* We can use this to help debug user's problems. Tell the to set | |||
* the MESA_INFO env variable before running their app. Then the | |||
* first time each context is made current we'll print some useful | |||
* information. | |||
*/ | |||
if (newCtx && newCtx->FirstTimeCurrent) { | |||
if (getenv("MESA_INFO")) { | |||
fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION)); | |||
fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER)); | |||
fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR)); | |||
fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS)); | |||
#if defined(THREADS) | |||
fprintf(stderr, "Mesa thread-safe: YES\n"); | |||
#else | |||
fprintf(stderr, "Mesa thread-safe: NO\n"); | |||
#endif | |||
#if defined(USE_X86_ASM) | |||
fprintf(stderr, "Mesa x86-optimized: YES\n"); | |||
#else | |||
fprintf(stderr, "Mesa x86-optimized: NO\n"); | |||
#endif | |||
/* We can use this to help debug user's problems. Tell them to set | |||
* the MESA_INFO env variable before running their app. Then the | |||
* first time each context is made current we'll print some useful | |||
* information. | |||
*/ | |||
if (newCtx->FirstTimeCurrent) { | |||
if (getenv("MESA_INFO")) { | |||
print_info(); | |||
} | |||
newCtx->FirstTimeCurrent = GL_FALSE; | |||
} | |||
newCtx->FirstTimeCurrent = GL_FALSE; | |||
} | |||
} | |||
@@ -1927,7 +1879,7 @@ _mesa_get_current_context( void ) | |||
void | |||
_mesa_swapbuffers(GLcontext *ctx) | |||
{ | |||
FLUSH_VB( ctx, "swap buffers" ); | |||
FLUSH_TNL( ctx, FLUSH_STORED_VERTICES ); | |||
} | |||
@@ -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 | |||
@@ -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); | |||
}; | |||
@@ -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, " : "" | |||
); | |||
} |
@@ -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 |
@@ -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 |
@@ -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]); |
@@ -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: |
@@ -1,4 +1,4 @@ | |||
/* $Id: eval.h,v 1.2 1999/11/11 01:22:26 brianp Exp $ */ | |||
/* $Id: eval.h,v 1.3 2000/11/16 21:05:35 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
@@ -61,8 +61,6 @@ extern GLfloat *gl_copy_map_points2d(GLenum target, | |||
const GLdouble *points ); | |||
extern void gl_eval_vb( struct vertex_buffer *VB ); | |||
extern void | |||
_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, | |||
@@ -107,40 +105,5 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ); | |||
extern void | |||
_mesa_GetMapiv( GLenum target, GLenum query, GLint *v ); | |||
extern void | |||
_mesa_EvalMesh1( GLenum mode, GLint i1, GLint i2 ); | |||
extern void | |||
_mesa_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); | |||
extern void | |||
_mesa_EvalCoord1d( GLdouble u ); | |||
extern void | |||
_mesa_EvalCoord1f( GLfloat u ); | |||
extern void | |||
_mesa_EvalCoord1dv( const GLdouble *u ); | |||
extern void | |||
_mesa_EvalCoord1fv( const GLfloat *u ); | |||
extern void | |||
_mesa_EvalCoord2d( GLdouble u, GLdouble v ); | |||
extern void | |||
_mesa_EvalCoord2f( GLfloat u, GLfloat v ); | |||
extern void | |||
_mesa_EvalCoord2dv( const GLdouble *u ); | |||
extern void | |||
_mesa_EvalCoord2fv( const GLfloat *u ); | |||
extern void | |||
_mesa_EvalPoint1( GLint i ); | |||
extern void | |||
_mesa_EvalPoint2( GLint i, GLint j ); | |||
#endif |
@@ -1,4 +1,4 @@ | |||
/* $Id: fog.c,v 1.28 2000/11/05 18:40:58 keithw Exp $ */ | |||
/* $Id: fog.c,v 1.29 2000/11/16 21:05:35 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
@@ -32,10 +32,7 @@ | |||
#include "colormac.h" | |||
#include "context.h" | |||
#include "fog.h" | |||
#include "macros.h" | |||
#include "mmath.h" | |||
#include "types.h" | |||
#include "xform.h" | |||
#endif | |||
@@ -146,102 +143,3 @@ _mesa_Fogfv( GLenum pname, const GLfloat *params ) | |||
} | |||
static GLvector1f *get_fogcoord_ptr( GLcontext *ctx, GLvector1f *tmp ) | |||
{ | |||
struct vertex_buffer *VB = ctx->VB; | |||
if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) { | |||
if (!ctx->_NeedEyeCoords) { | |||
GLfloat *m = ctx->ModelView.m; | |||
GLfloat plane[4]; | |||
plane[0] = m[2]; | |||
plane[1] = m[6]; | |||
plane[2] = m[10]; | |||
plane[3] = m[14]; | |||
/* Full eye coords weren't required, just calculate the | |||
* eye Z values. | |||
*/ | |||
gl_dotprod_tab[0][VB->ObjPtr->size](&VB->Eye, 2, | |||
VB->ObjPtr, plane, 0 ); | |||
tmp->data = &(VB->Eye.data[0][2]); | |||
tmp->start = VB->Eye.start+2; | |||
tmp->stride = VB->Eye.stride; | |||
return tmp; | |||
} | |||
else | |||
{ | |||
if (VB->EyePtr->size < 2) | |||
gl_vector4f_clean_elem( &VB->Eye, VB->Count, 2 ); | |||
tmp->data = &(VB->EyePtr->data[0][2]); | |||
tmp->start = VB->EyePtr->start+2; | |||
tmp->stride = VB->EyePtr->stride; | |||
return tmp; | |||
} | |||
} else | |||
return VB->FogCoordPtr; | |||
} | |||
/* Use lookup table & interpolation? | |||
*/ | |||
static void | |||
make_win_fog_coords( struct vertex_buffer *VB, | |||
GLvector1f *fogcoord) | |||
{ | |||
const GLcontext *ctx = VB->ctx; | |||
GLfloat end = ctx->Fog.End; | |||
GLfloat *v = fogcoord->start; | |||
GLuint stride = fogcoord->stride; | |||
GLuint n = VB->Count - VB->Start; | |||
GLfloat *out; | |||
GLfloat d; | |||
GLuint i; | |||
VB->FogCoordPtr = VB->store.FogCoord; | |||
out = VB->FogCoordPtr->data + VB->Start; | |||
switch (ctx->Fog.Mode) { | |||
case GL_LINEAR: | |||
d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); | |||
for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { | |||
out[i] = (end - ABSF(*v)) * d; | |||
if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]); | |||
} | |||
break; | |||
case GL_EXP: | |||
d = -ctx->Fog.Density; | |||
for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) { | |||
out[i] = exp( d*ABSF(*v) ); | |||
if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]); | |||
} | |||
break; | |||
case GL_EXP2: | |||
d = -(ctx->Fog.Density*ctx->Fog.Density); | |||
for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { | |||
GLfloat z = *v; | |||
out[i] = exp( d*z*z ); | |||
if (0) fprintf(stderr, "z %f out %f\n", *v, out[i]); | |||
} | |||
break; | |||
default: | |||
gl_problem(ctx, "Bad fog mode in make_fog_coord"); | |||
return; | |||
} | |||
} | |||
void | |||
_mesa_make_win_fog_coords( struct vertex_buffer *VB ) | |||
{ | |||
GLvector1f tmp; | |||
make_win_fog_coords( VB, get_fogcoord_ptr( VB->ctx, &tmp ) ); | |||
} | |||
@@ -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 |
@@ -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: |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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 ); |
@@ -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 | |||
@@ -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: */ |
@@ -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, |
@@ -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 | |||
@@ -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;p<MAX_CLIP_PLANES;p++) { | |||
if (ctx->Transform.ClipEnabled[p]) { | |||
GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0] | |||
+ v[1] * ctx->Transform._ClipUserPlane[p][1] | |||
+ v[2] * ctx->Transform._ClipUserPlane[p][2] | |||
+ v[3] * ctx->Transform._ClipUserPlane[p][3]; | |||
if (dot < 0.0F) { | |||
return 0; | |||
} | |||
} | |||
} | |||
return 1; | |||
} | |||
/* This has been split off to allow the normal shade routines to | |||
* get a little closer to the vertex buffer, and to use the | |||
* GLvector objects directly. | |||
*/ | |||
static void gl_shade_rastpos( GLcontext *ctx, | |||
GLfloat vertex[4], | |||
GLfloat normal[3], | |||
GLfloat Rcolor[4], | |||
GLuint *index ) | |||
{ | |||
GLfloat (*base)[3] = ctx->Light._BaseColor; | |||
const GLchan *sumA = ctx->Light._BaseAlpha; | |||
struct gl_light *light; | |||
GLfloat color[4]; | |||
GLfloat diffuse = 0, specular = 0; | |||
COPY_3V(color, base[0]); | |||
color[3] = CHAN_TO_FLOAT( sumA[0] ); | |||
foreach (light, &ctx->Light.EnabledList) { | |||
GLfloat n_dot_h; | |||
GLfloat attenuation = 1.0; | |||
GLfloat VP[3]; | |||
GLfloat n_dot_VP; | |||
GLfloat *h; | |||
GLfloat contrib[3]; | |||
GLboolean normalized; | |||
if (!(light->_Flags & LIGHT_POSITIONAL)) { | |||
COPY_3V(VP, light->_VP_inf_norm); | |||
attenuation = light->_VP_inf_spot_attenuation; | |||
} | |||
else { | |||
GLfloat d; | |||
SUB_3V(VP, light->_Position, vertex); | |||
d = LEN_3FV( VP ); | |||
if ( d > 1e-6) { | |||
GLfloat invd = 1.0F / d; | |||
SELF_SCALE_SCALAR_3V(VP, invd); | |||
} | |||
attenuation = 1.0F / (light->ConstantAttenuation + d * | |||
(light->LinearAttenuation + d * | |||
light->QuadraticAttenuation)); | |||
if (light->_Flags & LIGHT_SPOT) | |||
{ | |||
GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); | |||
if (PV_dot_dir<light->_CosCutoff) { | |||
continue; | |||
} | |||
else | |||
{ | |||
double x = PV_dot_dir * (EXP_TABLE_SIZE-1); | |||
int k = (int) x; | |||
GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] | |||
+ (x-k)*light->_SpotExpTable[k][1]); | |||
attenuation *= spot; | |||
} | |||
} | |||
} | |||
if (attenuation < 1e-3) | |||
continue; | |||
n_dot_VP = DOT3( normal, VP ); | |||
if (n_dot_VP < 0.0F) { | |||
ACC_SCALE_SCALAR_3V(color, attenuation, light->_MatAmbient[0]); | |||
continue; | |||
} | |||
COPY_3V(contrib, light->_MatAmbient[0]); | |||
ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[0]); | |||
diffuse += n_dot_VP * light->_dli * attenuation; | |||
if (light->_IsMatSpecular[0]) { | |||
if (ctx->Light.Model.LocalViewer) { | |||
GLfloat v[3]; | |||
COPY_3V(v, vertex); | |||
NORMALIZE_3FV(v); | |||
SUB_3V(VP, VP, v); | |||
h = VP; | |||
normalized = 0; | |||
} | |||
else if (light->_Flags & LIGHT_POSITIONAL) { | |||
h = VP; | |||
ACC_3V(h, ctx->_EyeZDir); | |||
normalized = 0; | |||
} | |||
else { | |||
h = light->_h_inf_norm; | |||
normalized = 1; | |||
} | |||
n_dot_h = DOT3(normal, h); | |||
if (n_dot_h > 0.0F) { | |||
struct gl_material *mat = &ctx->Light.Material[0]; | |||
GLfloat spec_coef; | |||
GLfloat shininess = mat->Shininess; | |||
if (!normalized) { | |||
n_dot_h *= n_dot_h; | |||
n_dot_h /= LEN_SQUARED_3FV( h ); | |||
shininess *= .5; | |||
} | |||
GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec_coef ); | |||
if (spec_coef > 1.0e-10) { | |||
ACC_SCALE_SCALAR_3V( contrib, spec_coef, | |||
light->_MatSpecular[0]); | |||
specular += spec_coef * light->_sli * attenuation; | |||
} | |||
} | |||
} | |||
ACC_SCALE_SCALAR_3V( color, attenuation, contrib ); | |||
} | |||
if (ctx->Visual.RGBAflag) { | |||
Rcolor[0] = CLAMP(color[0], 0.0F, 1.0F); | |||
Rcolor[1] = CLAMP(color[1], 0.0F, 1.0F); | |||
Rcolor[2] = CLAMP(color[2], 0.0F, 1.0F); | |||
Rcolor[3] = CLAMP(color[3], 0.0F, 1.0F); | |||
} | |||
else { | |||
struct gl_material *mat = &ctx->Light.Material[0]; | |||
GLfloat d_a = mat->DiffuseIndex - mat->AmbientIndex; | |||
GLfloat s_a = mat->SpecularIndex - mat->AmbientIndex; | |||
GLfloat ind = mat->AmbientIndex | |||
+ diffuse * (1.0F-specular) * d_a | |||
+ specular * s_a; | |||
if (ind > mat->SpecularIndex) { | |||
ind = mat->SpecularIndex; | |||
} | |||
*index = (GLuint) (GLint) ind; | |||
} | |||
} | |||
/* | |||
* Caller: context->API.RasterPos4f | |||
*/ | |||
@@ -54,10 +243,12 @@ static void raster_pos4f( GLcontext *ctx, | |||
GLfloat v[4], eye[4], clip[4], ndc[3], d; | |||
/* KW: Added this test, which is in the spec. We can't do this | |||
* outside begin/end any more because the ctx->Current values | |||
* inside begin/end any more because the ctx->Current values | |||
* aren't uptodate during that period. | |||
*/ | |||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glRasterPos" ); | |||
FLUSH_TNL_RETURN(ctx, (FLUSH_INSIDE_BEGIN_END| | |||
FLUSH_STORED_VERTICES| | |||
FLUSH_UPDATE_CURRENT), "raster_pos4f"); | |||
if (ctx->NewState) | |||
gl_update_state( ctx ); |
@@ -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; | |||
} | |||
@@ -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; | |||
} |
@@ -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 |
@@ -1,4 +1,4 @@ | |||
/* $Id: varray.c,v 1.30 2000/11/05 18:40:59 keithw Exp $ */ | |||
/* $Id: varray.c,v 1.31 2000/11/16 21:05:35 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
@@ -29,25 +29,17 @@ | |||
#else | |||
#include "glheader.h" | |||
#include "context.h" | |||
#include "cva.h" | |||
#include "enable.h" | |||
#include "enums.h" | |||
#include "dlist.h" | |||
#include "light.h" | |||
#include "macros.h" | |||
#include "mmath.h" | |||
#include "pipeline.h" | |||
#include "state.h" | |||
#include "texstate.h" | |||
#include "translate.h" | |||
#include "types.h" | |||
#include "varray.h" | |||
#include "vb.h" | |||
#include "vbfill.h" | |||
#include "vbrender.h" | |||
#include "vbindirect.h" | |||
#include "vbxform.h" | |||
#include "xform.h" | |||
#include "math/m_translate.h" | |||
#endif | |||
@@ -96,9 +88,10 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) | |||
ctx->Array.Vertex.Stride = stride; | |||
ctx->Array.Vertex.Ptr = (void *) ptr; | |||
ctx->Array._VertexFunc = gl_trans_4f_tab[size][TYPE_IDX(type)]; | |||
ctx->Array._VertexEltFunc = gl_trans_elt_4f_tab[size][TYPE_IDX(type)]; | |||
ctx->Array._NewArrayState |= VERT_OBJ_ANY; | |||
ctx->NewState |= _NEW_ARRAY; | |||
if (ctx->Driver.VertexPointer) | |||
ctx->Driver.VertexPointer( ctx, size, type, stride, ptr ); | |||
} | |||
@@ -146,9 +139,10 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) | |||
ctx->Array.Normal.Stride = stride; | |||
ctx->Array.Normal.Ptr = (void *) ptr; | |||
ctx->Array._NormalFunc = gl_trans_3f_tab[TYPE_IDX(type)]; | |||
ctx->Array._NormalEltFunc = gl_trans_elt_3f_tab[TYPE_IDX(type)]; | |||
ctx->Array._NewArrayState |= VERT_NORM; | |||
ctx->NewState |= _NEW_ARRAY; | |||
if (ctx->Driver.NormalPointer) | |||
ctx->Driver.NormalPointer( ctx, type, stride, ptr ); | |||
} | |||
@@ -209,9 +203,10 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) | |||
ctx->Array.Color.Stride = stride; | |||
ctx->Array.Color.Ptr = (void *) ptr; | |||
ctx->Array._ColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)]; | |||
ctx->Array._ColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)]; | |||
ctx->Array._NewArrayState |= VERT_RGBA; | |||
ctx->NewState |= _NEW_ARRAY; | |||
if (ctx->Driver.ColorPointer) | |||
ctx->Driver.ColorPointer( ctx, size, type, stride, ptr ); | |||
} | |||
@@ -244,9 +239,10 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) | |||
ctx->Array.FogCoord.Stride = stride; | |||
ctx->Array.FogCoord.Ptr = (void *) ptr; | |||
ctx->Array._FogCoordFunc = gl_trans_1f_tab[TYPE_IDX(type)]; | |||
ctx->Array._FogCoordEltFunc = gl_trans_elt_1f_tab[TYPE_IDX(type)]; | |||
ctx->Array._NewArrayState |= VERT_FOG_COORD; | |||
ctx->NewState |= _NEW_ARRAY; | |||
if (ctx->Driver.FogCoordPointer) | |||
ctx->Driver.FogCoordPointer( ctx, type, stride, ptr ); | |||
} | |||
@@ -287,9 +283,10 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) | |||
ctx->Array.Index.Stride = stride; | |||
ctx->Array.Index.Ptr = (void *) ptr; | |||
ctx->Array._IndexFunc = gl_trans_1ui_tab[TYPE_IDX(type)]; | |||
ctx->Array._IndexEltFunc = gl_trans_elt_1ui_tab[TYPE_IDX(type)]; | |||
ctx->Array._NewArrayState |= VERT_INDEX; | |||
ctx->NewState |= _NEW_ARRAY; | |||
if (ctx->Driver.IndexPointer) | |||
ctx->Driver.IndexPointer( ctx, type, stride, ptr ); | |||
} | |||
@@ -350,9 +347,10 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, | |||
ctx->Array.SecondaryColor.Stride = stride; | |||
ctx->Array.SecondaryColor.Ptr = (void *) ptr; | |||
ctx->Array._SecondaryColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)]; | |||
ctx->Array._SecondaryColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)]; | |||
ctx->Array._NewArrayState |= VERT_SPEC_RGB; | |||
ctx->NewState |= _NEW_ARRAY; | |||
if (ctx->Driver.SecondaryColorPointer) | |||
ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr ); | |||
} | |||
@@ -405,11 +403,11 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr | |||
ctx->Array.TexCoord[texUnit].Type = type; | |||
ctx->Array.TexCoord[texUnit].Stride = stride; | |||
ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr; | |||
ctx->Array._TexCoordFunc[texUnit] = gl_trans_4f_tab[size][TYPE_IDX(type)]; | |||
ctx->Array._TexCoordEltFunc[texUnit] = gl_trans_elt_4f_tab[size][TYPE_IDX(type)]; | |||
ctx->Array._NewArrayState |= VERT_TEX_ANY(texUnit); | |||
ctx->NewState |= _NEW_ARRAY; | |||
if (ctx->Driver.TexCoordPointer) | |||
ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr ); | |||
} | |||
@@ -433,9 +431,10 @@ _mesa_EdgeFlagPointer(GLsizei stride, const void *vptr) | |||
} else { | |||
ctx->Array._EdgeFlagFunc = 0; | |||
} | |||
ctx->Array._EdgeFlagEltFunc = gl_trans_elt_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)]; | |||
ctx->Array._NewArrayState |= VERT_EDGE; | |||
ctx->NewState |= _NEW_ARRAY; | |||
if (ctx->Driver.EdgeFlagPointer) | |||
ctx->Driver.EdgeFlagPointer( ctx, stride, ptr ); | |||
} | |||
@@ -498,620 +497,6 @@ _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) | |||
/* KW: Batch function to exec all the array elements in the input | |||
* buffer prior to transform. Done only the first time a vertex | |||
* buffer is executed or compiled. | |||
* | |||
* KW: Have to do this after each glEnd if cva isn't active. (also | |||
* have to do it after each full buffer) | |||
*/ | |||
void gl_exec_array_elements( GLcontext *ctx, struct immediate *IM, | |||
GLuint start, | |||
GLuint count) | |||
{ | |||
GLuint *flags = IM->Flag; | |||
GLuint *elts = IM->Elt; | |||
GLuint translate = ctx->Array._Flags; | |||
GLuint i; | |||
if (MESA_VERBOSE&VERBOSE_IMMEDIATE) | |||
fprintf(stderr, "exec_array_elements %d .. %d\n", start, count); | |||
if (translate & VERT_OBJ_ANY) | |||
(ctx->Array._VertexEltFunc)( IM->Obj, | |||
&ctx->Array.Vertex, | |||
flags, elts, (VERT_ELT|VERT_OBJ_ANY), | |||
start, count); | |||
if (translate & VERT_NORM) | |||
(ctx->Array._NormalEltFunc)( IM->Normal, | |||
&ctx->Array.Normal, | |||
flags, elts, (VERT_ELT|VERT_NORM), | |||
start, count); | |||
if (translate & VERT_EDGE) | |||
(ctx->Array._EdgeFlagEltFunc)( IM->EdgeFlag, | |||
&ctx->Array.EdgeFlag, | |||
flags, elts, (VERT_ELT|VERT_EDGE), | |||
start, count); | |||
if (translate & VERT_RGBA) | |||
(ctx->Array._ColorEltFunc)( IM->Color, | |||
&ctx->Array.Color, | |||
flags, elts, (VERT_ELT|VERT_RGBA), | |||
start, count); | |||
if (translate & VERT_SPEC_RGB) | |||
(ctx->Array._SecondaryColorEltFunc)( IM->SecondaryColor, | |||
&ctx->Array.SecondaryColor, | |||
flags, elts, (VERT_ELT|VERT_SPEC_RGB), | |||
start, count); | |||
if (translate & VERT_FOG_COORD) | |||
(ctx->Array._FogCoordEltFunc)( IM->FogCoord, | |||
&ctx->Array.FogCoord, | |||
flags, elts, (VERT_ELT|VERT_FOG_COORD), | |||
start, count); | |||
if (translate & VERT_INDEX) | |||
(ctx->Array._IndexEltFunc)( IM->Index, | |||
&ctx->Array.Index, | |||
flags, elts, (VERT_ELT|VERT_INDEX), | |||
start, count); | |||
if (translate & VERT_TEX0_ANY) | |||
(ctx->Array._TexCoordEltFunc[0])( IM->TexCoord[0], | |||
&ctx->Array.TexCoord[0], | |||
flags, elts, (VERT_ELT|VERT_TEX0_ANY), | |||
start, count); | |||
if (translate & VERT_TEX1_ANY) | |||
(ctx->Array._TexCoordEltFunc[1])( IM->TexCoord[1], | |||
&ctx->Array.TexCoord[1], | |||
flags, elts, (VERT_ELT|VERT_TEX1_ANY), | |||
start, count); | |||
#if MAX_TEXTURE_UNITS > 2 | |||
if (translate & VERT_TEX2_ANY) | |||
(ctx->Array._TexCoordEltFunc[2])( IM->TexCoord[2], | |||
&ctx->Array.TexCoord[2], | |||
flags, elts, (VERT_ELT|VERT_TEX2_ANY), | |||
start, count); | |||
#endif | |||
#if MAX_TEXTURE_UNITS > 3 | |||
if (translate & VERT_TEX3_ANY) | |||
(ctx->Array._TexCoordEltFunc[3])( IM->TexCoord[3], | |||
&ctx->Array.TexCoord[3], | |||
flags, elts, (VERT_ELT|VERT_TEX3_ANY), | |||
start, count); | |||
#endif | |||
for (i = start ; i < count ; i++) | |||
if (flags[i] & VERT_ELT) | |||
flags[i] |= translate; | |||
} | |||
/* Enough funny business going on in here it might be quicker to use a | |||
* function pointer. | |||
*/ | |||
#define ARRAY_ELT( IM, i ) \ | |||
{ \ | |||
GLuint count = IM->Count; \ | |||
IM->Elt[count] = i; \ | |||
IM->Flag[count] = ((IM->Flag[count] & IM->ArrayAndFlags) | \ | |||
VERT_ELT); \ | |||
IM->FlushElt |= IM->ArrayEltFlush; \ | |||
IM->Count = count += IM->ArrayIncr; \ | |||
if (count == VB_MAX) \ | |||
_mesa_maybe_transform_vb( IM ); \ | |||
} | |||
void | |||
_mesa_ArrayElement( GLint i ) | |||
{ | |||
GET_IMMEDIATE; | |||
ARRAY_ELT( IM, i ); | |||
} | |||
static void | |||
gl_ArrayElement( GLcontext *CC, GLint i ) | |||
{ | |||
struct immediate *im = CC->input; | |||
ARRAY_ELT( im, i ); | |||
} | |||
void | |||
_mesa_DrawArrays(GLenum mode, GLint start, GLsizei count) | |||
{ | |||
GET_CURRENT_CONTEXT(ctx); | |||
struct vertex_buffer *VB = ctx->VB; | |||
GLint i; | |||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawArrays"); | |||
if (count<0) { | |||
gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); | |||
return; | |||
} | |||
if (!ctx->CompileFlag && ctx->Array.Vertex.Enabled) { | |||
GLint remaining = count; | |||
GLint i; | |||
struct gl_client_array *Normal; | |||
struct gl_client_array *Color; | |||
struct gl_client_array *SecondaryColor; | |||
struct gl_client_array *FogCoord; | |||
struct gl_client_array *Index; | |||
struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS]; | |||
struct gl_client_array *EdgeFlag; | |||
struct immediate *IM = VB->IM; | |||
struct gl_pipeline *elt = &ctx->CVA.elt; | |||
GLboolean relock; | |||
GLuint fallback, required; | |||
if (ctx->NewState) | |||
gl_update_state( ctx ); | |||
/* Just turn off cva on this path. Could be useful for multipass | |||
* rendering to keep it turned on. | |||
*/ | |||
relock = ctx->CompileCVAFlag; | |||
if (relock) { | |||
ctx->CompileCVAFlag = 0; | |||
elt->pipeline_valid = 0; | |||
} | |||
if (!elt->pipeline_valid) | |||
gl_build_immediate_pipeline( ctx ); | |||
required = elt->inputs; | |||
fallback = (elt->inputs & ~ctx->Array._Summary); | |||
/* The translate function doesn't do anything about size. It | |||
* just ensures that type and stride come out right. | |||
*/ | |||
IM->v.Obj.size = ctx->Array.Vertex.Size; | |||
if (required & VERT_RGBA) { | |||
Color = &ctx->Array.Color; | |||
if (fallback & VERT_RGBA) { | |||
Color = &ctx->Fallback.Color; | |||
ctx->Array._ColorFunc = | |||
gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)]; | |||
} | |||
} | |||
if (required & VERT_SPEC_RGB) | |||
{ | |||
SecondaryColor = &ctx->Array.SecondaryColor; | |||
if (fallback & VERT_SPEC_RGB) { | |||
SecondaryColor = &ctx->Fallback.SecondaryColor; | |||
ctx->Array._SecondaryColorFunc = | |||
gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)]; | |||
} | |||
} | |||
if (required & VERT_FOG_COORD) | |||
{ | |||
FogCoord = &ctx->Array.FogCoord; | |||
if (fallback & VERT_FOG_COORD) { | |||
FogCoord = &ctx->Fallback.FogCoord; | |||
ctx->Array._FogCoordFunc = | |||
gl_trans_1f_tab[TYPE_IDX(GL_FLOAT)]; | |||
} | |||
} | |||
if (required & VERT_INDEX) { | |||
Index = &ctx->Array.Index; | |||
if (fallback & VERT_INDEX) { | |||
Index = &ctx->Fallback.Index; | |||
ctx->Array._IndexFunc = gl_trans_1ui_tab[TYPE_IDX(GL_UNSIGNED_INT)]; | |||
} | |||
} | |||
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) { | |||
GLuint flag = VERT_TEX_ANY(i); | |||
if (required & flag) { | |||
TexCoord[i] = &ctx->Array.TexCoord[i]; | |||
if (fallback & flag) { | |||
TexCoord[i] = &ctx->Fallback.TexCoord[i]; | |||
TexCoord[i]->Size = gl_texcoord_size( ctx->Current.Flag, i ); | |||
ctx->Array._TexCoordFunc[i] = | |||
gl_trans_4f_tab[TexCoord[i]->Size][TYPE_IDX(GL_FLOAT)]; | |||
} | |||
} | |||
} | |||
if (ctx->Array._Flags != ctx->Array._Flag[0]) { | |||
for (i = 0 ; i < VB_MAX ; i++) | |||
ctx->Array._Flag[i] = ctx->Array._Flags; | |||
} | |||
if (required & VERT_NORM) { | |||
Normal = &ctx->Array.Normal; | |||
if (fallback & VERT_NORM) { | |||
Normal = &ctx->Fallback.Normal; | |||
ctx->Array._NormalFunc = gl_trans_3f_tab[TYPE_IDX(GL_FLOAT)]; | |||
} | |||
} | |||
if ( required & VERT_EDGE ) { | |||
if (mode == GL_TRIANGLES || | |||
mode == GL_QUADS || | |||
mode == GL_POLYGON) { | |||
EdgeFlag = &ctx->Array.EdgeFlag; | |||
if (fallback & VERT_EDGE) { | |||
EdgeFlag = &ctx->Fallback.EdgeFlag; | |||
ctx->Array._EdgeFlagFunc = | |||
gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)]; | |||
} | |||
} | |||
else | |||
required &= ~VERT_EDGE; | |||
} | |||
VB->Primitive = IM->Primitive; | |||
VB->NextPrimitive = IM->NextPrimitive; | |||
VB->MaterialMask = IM->MaterialMask; | |||
VB->Material = IM->Material; | |||
VB->BoundsPtr = 0; | |||
while (remaining > 0) { | |||
GLint vbspace = VB_MAX - VB_START; | |||
GLuint count, n; | |||
if (vbspace >= remaining) { | |||
n = remaining; | |||
VB->LastPrimitive = VB_START + n; | |||
} | |||
else { | |||
n = vbspace; | |||
VB->LastPrimitive = VB_START; | |||
} | |||
VB->CullMode = 0; | |||
ctx->Array._VertexFunc( IM->Obj + VB_START, | |||
&ctx->Array.Vertex, start, n ); | |||
if (required & VERT_NORM) { | |||
ctx->Array._NormalFunc( IM->Normal + VB_START, | |||
Normal, start, n ); | |||
} | |||
if (required & VERT_EDGE) { | |||
ctx->Array._EdgeFlagFunc( IM->EdgeFlag + VB_START, | |||
EdgeFlag, start, n ); | |||
} | |||
if (required & VERT_RGBA) { | |||
ctx->Array._ColorFunc( IM->Color + VB_START, | |||
Color, start, n ); | |||
} | |||
if (required & VERT_SPEC_RGB) { | |||
ctx->Array._SecondaryColorFunc( IM->SecondaryColor + VB_START, | |||
SecondaryColor, start, n ); | |||
} | |||
if (required & VERT_FOG_COORD) { | |||
ctx->Array._FogCoordFunc( IM->FogCoord + VB_START, | |||
FogCoord, start, n ); | |||
} | |||
if (required & VERT_INDEX) { | |||
ctx->Array._IndexFunc( IM->Index + VB_START, | |||
Index, start, n ); | |||
} | |||
if (required & VERT_TEX0_ANY) { | |||
IM->v.TexCoord[0].size = TexCoord[0]->Size; | |||
ctx->Array._TexCoordFunc[0]( IM->TexCoord[0] + VB_START, | |||
TexCoord[0], start, n ); | |||
} | |||
if (required & VERT_TEX1_ANY) { | |||
IM->v.TexCoord[1].size = TexCoord[1]->Size; | |||
ctx->Array._TexCoordFunc[1]( IM->TexCoord[1] + VB_START, | |||
TexCoord[1], start, n ); | |||
} | |||
#if MAX_TEXTURE_UNITS > 2 | |||
if (required & VERT_TEX2_ANY) { | |||
IM->v.TexCoord[2].size = TexCoord[2]->Size; | |||
ctx->Array._TexCoordFunc[2]( IM->TexCoord[2] + VB_START, | |||
TexCoord[2], start, n ); | |||
} | |||
#endif | |||
#if MAX_TEXTURE_UNITS > 3 | |||
if (required & VERT_TEX3_ANY) { | |||
IM->v.TexCoord[3].size = TexCoord[3]->Size; | |||
ctx->Array._TexCoordFunc[3]( IM->TexCoord[3] + VB_START, | |||
TexCoord[3], start, n ); | |||
} | |||
#endif | |||
VB->ObjPtr = &IM->v.Obj; | |||
VB->NormalPtr = &IM->v.Normal; | |||
VB->ColorPtr = &IM->v.Color; | |||
VB->Color[0] = VB->Color[1] = VB->ColorPtr; | |||
VB->IndexPtr = &IM->v.Index; | |||
VB->EdgeFlagPtr = &IM->v.EdgeFlag; | |||
VB->SecondaryColorPtr = &IM->v.SecondaryColor; | |||
VB->FogCoordPtr = &IM->v.FogCoord; | |||
for (i = 0; i < MAX_TEXTURE_UNITS; i++) { | |||
VB->TexCoordPtr[i] = &IM->v.TexCoord[i]; | |||
} | |||
VB->Flag = ctx->Array._Flag; | |||
VB->OrFlag = ctx->Array._Flags; | |||
VB->Start = IM->Start = VB_START; | |||
count = VB->Count = IM->Count = VB_START + n; | |||
#define RESET_VEC(v, t, s, c) (v.start = t v.data[s], v.count = c) | |||
RESET_VEC(IM->v.Obj, (GLfloat *), VB_START, count); | |||
RESET_VEC(IM->v.Normal, (GLfloat *), VB_START, count); | |||
for (i = 0; i < MAX_TEXTURE_UNITS; i++) { | |||
RESET_VEC(IM->v.TexCoord[i], (GLfloat *), VB_START, count); | |||
} | |||
RESET_VEC(IM->v.Index, &, VB_START, count); | |||
RESET_VEC(IM->v.Elt, &, VB_START, count); | |||
RESET_VEC(IM->v.EdgeFlag, &, VB_START, count); | |||
RESET_VEC(IM->v.Color, (GLubyte *), VB_START, count); | |||
RESET_VEC(VB->Clip, (GLfloat *), VB_START, count); | |||
RESET_VEC(VB->Eye, (GLfloat *), VB_START, count); | |||
RESET_VEC(VB->Win, (GLfloat *), VB_START, count); | |||
RESET_VEC(VB->BColor, (GLubyte *), VB_START, count); | |||
RESET_VEC(VB->BIndex, &, VB_START, count); | |||
VB->NextPrimitive[VB->CopyStart] = VB->Count; | |||
VB->Primitive[VB->CopyStart] = mode; | |||
ctx->Array._Flag[count] |= VERT_END_VB; | |||
/* Transform and render. | |||
*/ | |||
gl_run_pipeline( VB ); | |||
gl_reset_vb( VB ); | |||
/* Restore values: | |||
*/ | |||
ctx->Array._Flag[count] = ctx->Array._Flags; | |||
ctx->Array._Flag[VB_START] = ctx->Array._Flags; | |||
start += n; | |||
remaining -= n; | |||
} | |||
gl_reset_input( ctx ); | |||
if (relock) { | |||
ctx->CompileCVAFlag = relock; | |||
elt->pipeline_valid = 0; | |||
} | |||
} | |||
else if (ctx->Array.Vertex.Enabled) | |||
{ | |||
/* The GL_COMPILE and GL_COMPILE_AND_EXECUTE cases. These | |||
* could be handled by the above code, but it gets a little | |||
* complex. The generated list is still of good quality | |||
* this way. | |||
*/ | |||
gl_Begin( ctx, mode ); | |||
for (i=0;i<count;i++) { | |||
gl_ArrayElement( ctx, start+i ); | |||
} | |||
gl_End( ctx ); | |||
} | |||
else | |||
{ | |||
/* The degenerate case where vertices are not enabled - only | |||
* need to process the very final array element, as all of the | |||
* preceding ones would be overwritten anyway. | |||
*/ | |||
gl_Begin( ctx, mode ); | |||
gl_ArrayElement( ctx, start+count ); | |||
gl_End( ctx ); | |||
} | |||
} | |||
/* KW: Exactly fakes the effects of calling glArrayElement multiple times. | |||
*/ | |||
#if 1 | |||
#define DRAW_ELT(FUNC, TYPE) \ | |||
static void FUNC( GLcontext *ctx, GLenum mode, \ | |||
TYPE *indices, GLuint count ) \ | |||
{ \ | |||
GLuint i,j; \ | |||
\ | |||
gl_Begin( ctx, mode ); \ | |||
\ | |||
for (j = 0 ; j < count ; ) { \ | |||
struct immediate *IM = ctx->input; \ | |||
GLuint start = IM->Start; \ | |||
GLuint nr = MIN2( VB_MAX, count - j + start ); \ | |||
GLuint sf = IM->Flag[start]; \ | |||
IM->FlushElt |= IM->ArrayEltFlush; \ | |||
\ | |||
for (i = start ; i < nr ; i++) { \ | |||
IM->Elt[i] = (GLuint) *indices++; \ | |||
IM->Flag[i] = VERT_ELT; \ | |||
} \ | |||
\ | |||
if (j == 0) IM->Flag[start] |= sf; \ | |||
\ | |||
IM->Count = nr; \ | |||
j += nr - start; \ | |||
\ | |||
if (j == count) \ | |||
gl_End( ctx ); \ | |||
_mesa_maybe_transform_vb( IM ); \ | |||
} \ | |||
} | |||
#else | |||
#define DRAW_ELT(FUNC, TYPE) \ | |||
static void FUNC( GLcontext *ctx, GLenum mode, \ | |||
TYPE *indices, GLuint count ) \ | |||
{ \ | |||
int i; \ | |||
glBegin(mode); \ | |||
for (i = 0 ; i < count ; i++) \ | |||
glArrayElement( indices[i] ); \ | |||
glEnd(); \ | |||
} | |||
#endif | |||
DRAW_ELT( draw_elt_ubyte, GLubyte ) | |||
DRAW_ELT( draw_elt_ushort, GLushort ) | |||
DRAW_ELT( draw_elt_uint, GLuint ) | |||
static GLuint natural_stride[0x10] = | |||
{ | |||
sizeof(GLbyte), /* 0 */ | |||
sizeof(GLubyte), /* 1 */ | |||
sizeof(GLshort), /* 2 */ | |||
sizeof(GLushort), /* 3 */ | |||
sizeof(GLint), /* 4 */ | |||
sizeof(GLuint), /* 5 */ | |||
sizeof(GLfloat), /* 6 */ | |||
2 * sizeof(GLbyte), /* 7 */ | |||
3 * sizeof(GLbyte), /* 8 */ | |||
4 * sizeof(GLbyte), /* 9 */ | |||
sizeof(GLdouble), /* a */ | |||
0, /* b */ | |||
0, /* c */ | |||
0, /* d */ | |||
0, /* e */ | |||
0 /* f */ | |||
}; | |||
void | |||
_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) | |||
{ | |||
GET_CURRENT_CONTEXT(ctx); | |||
struct gl_cva *cva; | |||
cva = &ctx->CVA; | |||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawElements"); | |||
if (count <= 0) { | |||
if (count < 0) | |||
gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); | |||
return; | |||
} | |||
if (mode < 0 || mode > GL_POLYGON) { | |||
gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); | |||
return; | |||
} | |||
if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT) | |||
{ | |||
gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); | |||
return; | |||
} | |||
if (ctx->NewState) | |||
gl_update_state(ctx); | |||
if (ctx->CompileCVAFlag) | |||
{ | |||
/* Treat VERT_ELT like a special client array. | |||
*/ | |||
ctx->Array._NewArrayState |= VERT_ELT; | |||
ctx->Array._Summary |= VERT_ELT; | |||
ctx->Array._Flags |= VERT_ELT; | |||
cva->elt_mode = mode; | |||
cva->elt_count = count; | |||
cva->Elt.Type = type; | |||
cva->Elt.Ptr = (void *) indices; | |||
cva->Elt.StrideB = natural_stride[TYPE_IDX(type)]; | |||
cva->EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)]; | |||
if (!cva->pre.pipeline_valid) | |||
gl_build_precalc_pipeline( ctx ); | |||
else if (MESA_VERBOSE & VERBOSE_PIPELINE) | |||
fprintf(stderr, ": dont rebuild\n"); | |||
gl_cva_force_precalc( ctx ); | |||
/* Did we 'precalculate' the render op? | |||
*/ | |||
if (ctx->CVA.pre.ops & PIPE_OP_RENDER) { | |||
ctx->Array._NewArrayState |= VERT_ELT; | |||
ctx->Array._Summary &= ~VERT_ELT; | |||
ctx->Array._Flags &= ~VERT_ELT; | |||
return; | |||
} | |||
if ( (MESA_VERBOSE&VERBOSE_VARRAY) ) | |||
printf("using immediate\n"); | |||
} | |||
/* Otherwise, have to use the immediate path to render. | |||
*/ | |||
switch (type) { | |||
case GL_UNSIGNED_BYTE: | |||
{ | |||
GLubyte *ub_indices = (GLubyte *) indices; | |||
if (ctx->Array._Summary & VERT_OBJ_ANY) { | |||
draw_elt_ubyte( ctx, mode, ub_indices, count ); | |||
} else { | |||
gl_ArrayElement( ctx, (GLuint) ub_indices[count-1] ); | |||
} | |||
} | |||
break; | |||
case GL_UNSIGNED_SHORT: | |||
{ | |||
GLushort *us_indices = (GLushort *) indices; | |||
if (ctx->Array._Summary & VERT_OBJ_ANY) { | |||
draw_elt_ushort( ctx, mode, us_indices, count ); | |||
} else { | |||
gl_ArrayElement( ctx, (GLuint) us_indices[count-1] ); | |||
} | |||
} | |||
break; | |||
case GL_UNSIGNED_INT: | |||
{ | |||
GLuint *ui_indices = (GLuint *) indices; | |||
if (ctx->Array._Summary & VERT_OBJ_ANY) { | |||
draw_elt_uint( ctx, mode, ui_indices, count ); | |||
} else { | |||
gl_ArrayElement( ctx, ui_indices[count-1] ); | |||
} | |||
} | |||
break; | |||
default: | |||
gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); | |||
break; | |||
} | |||
if (ctx->CompileCVAFlag) { | |||
ctx->Array._NewArrayState |= VERT_ELT; | |||
ctx->Array._Summary &= ~VERT_ELT; | |||
} | |||
} | |||
void | |||
_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) | |||
@@ -1307,81 +692,3 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) | |||
void | |||
_mesa_DrawRangeElements(GLenum mode, GLuint start, | |||
GLuint end, GLsizei count, | |||
GLenum type, const GLvoid *indices) | |||
{ | |||
GET_CURRENT_CONTEXT(ctx); | |||
if (end < start) { | |||
gl_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements( end < start )"); | |||
return; | |||
} | |||
#if 0 | |||
/* | |||
* XXX something in locked arrays is broken! If start = 0, | |||
* end = 1 and count = 2 we'll take the LockArrays path and | |||
* get incorrect results. See Scott McMillan's bug of 3 Jan 2000. | |||
* For now, don't use locked arrays. | |||
*/ | |||
if (!ctx->Array.LockCount && 2*count > (GLint) 3*(end-start)) { | |||
glLockArraysEXT( start, end ); | |||
glDrawElements( mode, count, type, indices ); | |||
glUnlockArraysEXT(); | |||
} else { | |||
glDrawElements( mode, count, type, indices ); | |||
} | |||
#else | |||
glDrawElements( mode, count, type, indices ); | |||
#endif | |||
} | |||
void gl_update_client_state( GLcontext *ctx ) | |||
{ | |||
static const GLuint sz_flags[5] = { | |||
0, | |||
0, | |||
VERT_OBJ_2, | |||
VERT_OBJ_23, | |||
VERT_OBJ_234 | |||
}; | |||
static const GLuint tc_flags[5] = { | |||
0, | |||
VERT_TEX0_12, | |||
VERT_TEX0_12, | |||
VERT_TEX0_123, | |||
VERT_TEX0_1234 | |||
}; | |||
GLint i; | |||
ctx->Array._Flags = 0; | |||
ctx->Array._Summary = 0; | |||
ctx->input->ArrayIncr = 0; | |||
if (ctx->Array.Normal.Enabled) ctx->Array._Flags |= VERT_NORM; | |||
if (ctx->Array.Color.Enabled) ctx->Array._Flags |= VERT_RGBA; | |||
if (ctx->Array.SecondaryColor.Enabled) ctx->Array._Flags |= VERT_SPEC_RGB; | |||
if (ctx->Array.FogCoord.Enabled) ctx->Array._Flags |= VERT_FOG_COORD; | |||
if (ctx->Array.Index.Enabled) ctx->Array._Flags |= VERT_INDEX; | |||
if (ctx->Array.EdgeFlag.Enabled) ctx->Array._Flags |= VERT_EDGE; | |||
if (ctx->Array.Vertex.Enabled) { | |||
ctx->Array._Flags |= sz_flags[ctx->Array.Vertex.Size]; | |||
ctx->input->ArrayIncr = 1; | |||
} | |||
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { | |||
if (ctx->Array.TexCoord[i].Enabled) { | |||
ctx->Array._Flags |= (tc_flags[ctx->Array.TexCoord[i].Size] << (i * NR_TEXSIZE_BITS)); | |||
} | |||
} | |||
/* Not really important any more: | |||
*/ | |||
ctx->Array._Summary = ctx->Array._Flags & VERT_DATA; | |||
ctx->input->ArrayAndFlags = ~ctx->Array._Flags; | |||
ctx->input->ArrayEltFlush = !(ctx->CompileCVAFlag); | |||
} | |||
@@ -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 |
@@ -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); | |||
} |
@@ -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); */ | |||
} |
@@ -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 */ |
@@ -0,0 +1,128 @@ | |||
/* $Id: m_dotprod_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
* Version: 3.1 | |||
* | |||
* Copyright (C) 1999 Brian Paul All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/* | |||
* New (3.1) transformation code written by Keith Whitwell. | |||
*/ | |||
/* Note - respects the stride of the output vector. | |||
*/ | |||
static void TAG(dotprod_vec2)( GLvector4f *out_vec, | |||
GLuint elt, | |||
const GLvector4f *coord_vec, | |||
const GLfloat plane[4], | |||
const GLubyte mask[]) | |||
{ | |||
GLuint stride = coord_vec->stride; | |||
GLfloat *coord = coord_vec->start; | |||
GLuint count = coord_vec->count; | |||
GLuint outstride = out_vec->stride; | |||
GLfloat *out = out_vec->start + elt; | |||
GLuint i; | |||
const GLfloat plane0 = plane[0], plane1 = plane[1], plane3 = plane[3]; | |||
(void) mask; | |||
for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { | |||
CULL_CHECK { | |||
*out = (coord[0] * plane0 + | |||
coord[1] * plane1 + | |||
plane3); | |||
} | |||
} | |||
out_vec->count = coord_vec->count; | |||
} | |||
static void TAG(dotprod_vec3)( GLvector4f *out_vec, | |||
GLuint elt, | |||
const GLvector4f *coord_vec, | |||
const GLfloat plane[4], | |||
const GLubyte mask[]) | |||
{ | |||
GLuint stride = coord_vec->stride; | |||
GLfloat *coord = coord_vec->start; | |||
GLuint count = coord_vec->count; | |||
GLuint outstride = out_vec->stride; | |||
GLfloat *out = out_vec->start + elt; | |||
GLuint i; | |||
const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; | |||
const GLfloat plane3 = plane[3]; | |||
(void) mask; | |||
for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { | |||
CULL_CHECK { | |||
*out = (coord[0] * plane0 + | |||
coord[1] * plane1 + | |||
coord[2] * plane2 + | |||
plane3); | |||
} | |||
} | |||
out_vec->count = coord_vec->count; | |||
} | |||
static void TAG(dotprod_vec4)( GLvector4f *out_vec, | |||
GLuint elt, | |||
const GLvector4f *coord_vec, | |||
const GLfloat plane[4], | |||
const GLubyte mask[]) | |||
{ | |||
GLuint stride = coord_vec->stride; | |||
GLfloat *coord = coord_vec->start; | |||
GLuint count = coord_vec->count; | |||
GLuint outstride = out_vec->stride; | |||
GLfloat *out = out_vec->start + elt; | |||
GLuint i; | |||
const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; | |||
const GLfloat plane3 = plane[3]; | |||
(void) mask; | |||
for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { | |||
CULL_CHECK { | |||
*out = (coord[0] * plane0 + | |||
coord[1] * plane1 + | |||
coord[2] * plane2 + | |||
coord[3] * plane3); | |||
} | |||
} | |||
out_vec->count = coord_vec->count; | |||
} | |||
static void TAG(init_dotprod)( void ) | |||
{ | |||
gl_dotprod_tab[IDX&1][2] = TAG(dotprod_vec2); | |||
gl_dotprod_tab[IDX&1][3] = TAG(dotprod_vec3); | |||
gl_dotprod_tab[IDX&1][4] = TAG(dotprod_vec4); | |||
} |
@@ -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 |
@@ -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); | |||
} |
@@ -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 | |||
@@ -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(); | |||
} |
@@ -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 |
@@ -0,0 +1,367 @@ | |||
/* $Id: m_vector.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
* Version: 3.5 | |||
* | |||
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/* | |||
* New (3.1) transformation code written by Keith Whitwell. | |||
*/ | |||
#include "glheader.h" | |||
#include "macros.h" | |||
#include "mem.h" | |||
#include "m_vector.h" | |||
/* | |||
* Given a vector [count][4] of floats, set all the [][elt] values | |||
* to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3). | |||
*/ | |||
void gl_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) | |||
{ | |||
static const GLubyte elem_bits[4] = { | |||
VEC_DIRTY_0, | |||
VEC_DIRTY_1, | |||
VEC_DIRTY_2, | |||
VEC_DIRTY_3 | |||
}; | |||
static const GLfloat clean[4] = { 0, 0, 0, 1 }; | |||
const GLfloat v = clean[elt]; | |||
GLfloat (*data)[4] = (GLfloat (*)[4])vec->start; | |||
GLuint i; | |||
for (i = 0 ; i < count ; i++) | |||
data[i][elt] = v; | |||
vec->flags &= ~elem_bits[elt]; | |||
} | |||
static const GLubyte size_bits[5] = { | |||
0, | |||
VEC_SIZE_1, | |||
VEC_SIZE_2, | |||
VEC_SIZE_3, | |||
VEC_SIZE_4, | |||
}; | |||
/* | |||
* Initialize GLvector objects. | |||
* Input: v - the vector object to initialize. | |||
* flags - bitwise-OR of VEC_* flags | |||
* storage - pointer to storage for the vector's data | |||
*/ | |||
void gl_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] ) | |||
{ | |||
v->stride = 4 * sizeof(GLfloat); | |||
v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */ | |||
v->data = storage; | |||
v->start = (GLfloat *) storage; | |||
v->count = 0; | |||
v->flags = size_bits[4] | flags | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*storage)[3] ) | |||
{ | |||
v->stride = 3 * sizeof(GLfloat); | |||
v->data = storage; | |||
v->start = (GLfloat *) storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector1f_init( GLvector1f *v, GLuint flags, GLfloat *storage ) | |||
{ | |||
v->stride = 1*sizeof(GLfloat); | |||
v->data = storage; | |||
v->start = (GLfloat *)storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector4ub_init( GLvector4ub *v, GLuint flags, GLubyte (*storage)[4] ) | |||
{ | |||
v->stride = 4 * sizeof(GLubyte); | |||
v->data = storage; | |||
v->start = (GLubyte *) storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage ) | |||
{ | |||
v->stride = 1 * sizeof(GLubyte); | |||
v->data = storage; | |||
v->start = (GLubyte *) storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage ) | |||
{ | |||
v->stride = 1 * sizeof(GLuint); | |||
v->data = storage; | |||
v->start = (GLuint *) storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_GOOD_STRIDE; | |||
} | |||
/* | |||
* Initialize GLvector objects and allocate storage. | |||
* Input: v - the vector object | |||
* sz - unused???? | |||
* flags - bitwise-OR of VEC_* flags | |||
* count - number of elements to allocate in vector | |||
* alignment - desired memory alignment for the data (in bytes) | |||
*/ | |||
void gl_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, | |||
GLuint alignment ) | |||
{ | |||
v->stride = 4 * sizeof(GLfloat); | |||
v->size = 2; | |||
v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLfloat), alignment ); | |||
v->start = (GLfloat *) v->storage; | |||
v->data = (GLfloat (*)[4]) v->storage; | |||
v->count = 0; | |||
v->flags = size_bits[4] | flags | VEC_MALLOC | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count, | |||
GLuint alignment ) | |||
{ | |||
v->stride = 3 * sizeof(GLfloat); | |||
v->storage = ALIGN_MALLOC( count * 3 * sizeof(GLfloat), alignment ); | |||
v->start = (GLfloat *) v->storage; | |||
v->data = (GLfloat (*)[3]) v->storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count, | |||
GLuint alignment ) | |||
{ | |||
v->stride = sizeof(GLfloat); | |||
v->storage = v->start = (GLfloat *) | |||
ALIGN_MALLOC( count * sizeof(GLfloat), alignment ); | |||
v->data = v->start; | |||
v->count = 0; | |||
v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count, | |||
GLuint alignment ) | |||
{ | |||
v->stride = 4 * sizeof(GLubyte); | |||
v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLubyte), alignment ); | |||
v->start = (GLubyte *) v->storage; | |||
v->data = (GLubyte (*)[4]) v->storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count, | |||
GLuint alignment ) | |||
{ | |||
v->stride = 1 * sizeof(GLubyte); | |||
v->storage = ALIGN_MALLOC( count * sizeof(GLubyte), alignment ); | |||
v->start = (GLubyte *) v->storage; | |||
v->data = (GLubyte *) v->storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; | |||
} | |||
void gl_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count, | |||
GLuint alignment ) | |||
{ | |||
v->stride = 1 * sizeof(GLuint); | |||
v->storage = ALIGN_MALLOC( count * sizeof(GLuint), alignment ); | |||
v->start = (GLuint *) v->storage; | |||
v->data = (GLuint *) v->storage; | |||
v->count = 0; | |||
v->flags = flags | VEC_MALLOC | VEC_GOOD_STRIDE; | |||
} | |||
/* | |||
* Vector deallocation. Free whatever memory is pointed to by the | |||
* vector's storage field if the VEC_MALLOC flag is set. | |||
* DO NOT free the GLvector object itself, though. | |||
*/ | |||
void gl_vector4f_free( GLvector4f *v ) | |||
{ | |||
if (v->flags & VEC_MALLOC) { | |||
ALIGN_FREE( v->storage ); | |||
v->data = NULL; | |||
v->start = NULL; | |||
v->storage = NULL; | |||
v->flags &= ~VEC_MALLOC; | |||
} | |||
} | |||
void gl_vector3f_free( GLvector3f *v ) | |||
{ | |||
if (v->flags & VEC_MALLOC) { | |||
ALIGN_FREE( v->storage ); | |||
v->data = 0; | |||
v->start = 0; | |||
v->storage = 0; | |||
v->flags &= ~VEC_MALLOC; | |||
} | |||
} | |||
void gl_vector1f_free( GLvector1f *v ) | |||
{ | |||
if (v->flags & VEC_MALLOC) { | |||
ALIGN_FREE( v->storage ); | |||
v->data = NULL; | |||
v->start = NULL; | |||
v->storage = NULL; | |||
v->flags &= ~VEC_MALLOC; | |||
} | |||
} | |||
void gl_vector4ub_free( GLvector4ub *v ) | |||
{ | |||
if (v->flags & VEC_MALLOC) { | |||
ALIGN_FREE( v->storage ); | |||
v->data = NULL; | |||
v->start = NULL; | |||
v->storage = NULL; | |||
v->flags &= ~VEC_MALLOC; | |||
} | |||
} | |||
void gl_vector1ub_free( GLvector1ub *v ) | |||
{ | |||
if (v->flags & VEC_MALLOC) { | |||
ALIGN_FREE( v->storage ); | |||
v->data = NULL; | |||
v->start = NULL; | |||
v->storage = NULL; | |||
v->flags &= ~VEC_MALLOC; | |||
} | |||
} | |||
void gl_vector1ui_free( GLvector1ui *v ) | |||
{ | |||
if (v->flags & VEC_MALLOC) { | |||
ALIGN_FREE( v->storage ); | |||
v->data = NULL; | |||
v->start = NULL; | |||
v->storage = NULL; | |||
v->flags &= ~VEC_MALLOC; | |||
} | |||
} | |||
/* | |||
* For debugging | |||
*/ | |||
void gl_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling ) | |||
{ | |||
GLfloat c[4] = { 0, 0, 0, 1 }; | |||
const char *templates[5] = { | |||
"%d:\t0, 0, 0, 1\n", | |||
"%d:\t%f, 0, 0, 1\n", | |||
"%d:\t%f, %f, 0, 1\n", | |||
"%d:\t%f, %f, %f, 1\n", | |||
"%d:\t%f, %f, %f, %f\n" | |||
}; | |||
const char *t = templates[v->size]; | |||
GLfloat *d = (GLfloat *)v->data; | |||
GLuint j, i = 0, count; | |||
printf("data-start\n"); | |||
for ( ; d != v->start ; STRIDE_F(d, v->stride), i++) | |||
printf( t, i, d[0], d[1], d[2], d[3]); | |||
printf("start-count(%u)\n", v->count); | |||
count = i + v->count; | |||
if (culling) { | |||
for ( ; i < count ; STRIDE_F(d, v->stride), i++) | |||
if (cullmask[i]) | |||
printf( t, i, d[0], d[1], d[2], d[3]); | |||
} | |||
else { | |||
for ( ; i < count ; STRIDE_F(d, v->stride), i++) | |||
printf( t, i, d[0], d[1], d[2], d[3]); | |||
} | |||
for (j = v->size ; j < 4; j++) { | |||
if ((v->flags & (1<<j)) == 0) { | |||
printf("checking col %u is clean as advertised ", j); | |||
for (i = 0, d = (GLfloat *) v->data ; | |||
i < count && d[j] == c[j] ; | |||
i++, STRIDE_F(d, v->stride)) {}; | |||
if (i == count) | |||
printf(" --> ok\n"); | |||
else | |||
printf(" --> Failed at %u ******\n", i); | |||
} | |||
} | |||
} | |||
/* | |||
* For debugging | |||
*/ | |||
void gl_vector3f_print( GLvector3f *v, GLubyte *cullmask, GLboolean culling ) | |||
{ | |||
GLfloat *d = (GLfloat *)v->data; | |||
GLuint i = 0, count; | |||
printf("data-start\n"); | |||
for ( ; d != v->start ; STRIDE_F(d,v->stride), i++) | |||
printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); | |||
printf("start-count(%u)\n", v->count); | |||
count = i + v->count; | |||
if (culling) { | |||
for ( ; i < count ; STRIDE_F(d,v->stride), i++) | |||
if (cullmask[i]) | |||
printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); | |||
} | |||
else { | |||
for ( ; i < count ; STRIDE_F(d,v->stride), i++) | |||
printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); | |||
} | |||
} |
@@ -0,0 +1,188 @@ | |||
/* $Id: m_vector.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
* Version: 3.5 | |||
* | |||
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/* | |||
* New (3.1) transformation code written by Keith Whitwell. | |||
*/ | |||
#ifndef _M_VECTOR_H_ | |||
#define _M_VECTOR_H_ | |||
#include "glheader.h" | |||
#define VEC_DIRTY_0 0x1 /* dirty flags not really used any more */ | |||
#define VEC_DIRTY_1 0x2 | |||
#define VEC_DIRTY_2 0x4 | |||
#define VEC_DIRTY_3 0x8 | |||
#define VEC_MALLOC 0x10 /* storage field points to self-allocated mem*/ | |||
#define VEC_WRITABLE 0x20 /* keep both + and - bits for easy testing */ | |||
#define VEC_NOT_WRITABLE 0x40 | |||
#define VEC_GOOD_STRIDE 0x80 | |||
#define VEC_BAD_STRIDE 0x100 | |||
#define VEC_WRITABLE_FLAGS (VEC_WRITABLE|VEC_NOT_WRITABLE) | |||
#define VEC_STRIDE_FLAGS (VEC_GOOD_STRIDE|VEC_BAD_STRIDE) | |||
#define VEC_SIZE_1 VEC_DIRTY_0 | |||
#define VEC_SIZE_2 (VEC_DIRTY_0|VEC_DIRTY_1) | |||
#define VEC_SIZE_3 (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2) | |||
#define VEC_SIZE_4 (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2|VEC_DIRTY_3) | |||
/* Wrap all the information about vectors up in a struct. Has | |||
* additional fields compared to the other vectors to help us track of | |||
* different vertex sizes, and whether we need to clean columns out | |||
* because they contain non-(0,0,0,1) values. | |||
* | |||
* The start field is used to reserve data for copied vertices at the | |||
* end of gl_transform_vb, and avoids the need for a multiplication in | |||
* the transformation routines. | |||
*/ | |||
typedef struct { | |||
GLfloat (*data)[4]; /* may be malloc'd or point to client data */ | |||
GLfloat *start; /* points somewhere inside of <data> */ | |||
GLuint count; /* size of the vector (in elements) */ | |||
GLuint stride; /* stride from one element to the next (in bytes) */ | |||
GLuint size; /* 2-4 for vertices and 1-4 for texcoords */ | |||
GLuint flags; /* which columns are dirty */ | |||
void *storage; /* self-allocated storage */ | |||
} GLvector4f; | |||
extern void gl_vector4f_init( GLvector4f *v, GLuint flags, | |||
GLfloat (*storage)[4] ); | |||
extern void gl_vector4f_alloc( GLvector4f *v, GLuint flags, | |||
GLuint count, GLuint alignment ); | |||
extern void gl_vector4f_free( GLvector4f *v ); | |||
extern void gl_vector4f_print( GLvector4f *v, GLubyte *, GLboolean ); | |||
extern void gl_vector4f_clean_elem( GLvector4f *vec, GLuint nr, GLuint elt ); | |||
/* Could use a single vector type for normals and vertices, but | |||
* this way avoids some casts. | |||
*/ | |||
typedef struct { | |||
GLfloat (*data)[3]; | |||
GLfloat *start; | |||
GLuint count; | |||
GLuint stride; | |||
GLuint flags; | |||
void *storage; | |||
} GLvector3f; | |||
extern void gl_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*)[3] ); | |||
extern void gl_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count, | |||
GLuint alignment ); | |||
extern void gl_vector3f_free( GLvector3f *v ); | |||
extern void gl_vector3f_print( GLvector3f *v, GLubyte *, GLboolean ); | |||
typedef struct { | |||
GLfloat *data; | |||
GLfloat *start; | |||
GLuint count; | |||
GLuint stride; | |||
GLuint flags; | |||
void *storage; | |||
} GLvector1f; | |||
extern void gl_vector1f_free( GLvector1f *v ); | |||
extern void gl_vector1f_init( GLvector1f *v, GLuint flags, GLfloat * ); | |||
extern void gl_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count, | |||
GLuint alignment ); | |||
/* For 4ub rgba values. | |||
*/ | |||
typedef struct { | |||
GLubyte (*data)[4]; | |||
GLubyte *start; | |||
GLuint count; | |||
GLuint stride; | |||
GLuint flags; | |||
void *storage; | |||
} GLvector4ub; | |||
extern void gl_vector4ub_init( GLvector4ub *v, GLuint flags, | |||
GLubyte (*storage)[4] ); | |||
extern void gl_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count, | |||
GLuint alignment ); | |||
extern void gl_vector4ub_free( GLvector4ub * ); | |||
/* For 1ub values, eg edgeflag. | |||
*/ | |||
typedef struct { | |||
GLubyte *data; | |||
GLubyte *start; | |||
GLuint count; | |||
GLuint stride; | |||
GLuint flags; | |||
void *storage; | |||
} GLvector1ub; | |||
extern void gl_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage); | |||
extern void gl_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count, | |||
GLuint alignment ); | |||
extern void gl_vector1ub_free( GLvector1ub * ); | |||
/* For, eg Index, Array element. | |||
*/ | |||
typedef struct { | |||
GLuint *data; | |||
GLuint *start; | |||
GLuint count; | |||
GLuint stride; | |||
GLuint flags; | |||
void *storage; | |||
} GLvector1ui; | |||
extern void gl_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage ); | |||
extern void gl_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count, | |||
GLuint alignment ); | |||
extern void gl_vector1ui_free( GLvector1ui * ); | |||
/* | |||
* Given vector <v>, return a pointer (cast to <type *> to the <i>-th element. | |||
* | |||
* End up doing a lot of slow imuls if not careful. | |||
*/ | |||
#define VEC_ELT( v, type, i ) \ | |||
( (type *) ( ((GLbyte *) ((v)->data)) + (i) * (v)->stride) ) | |||
#endif |
@@ -0,0 +1,251 @@ | |||
/* $Id: m_xform.c,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
* Version: 3.5 | |||
* | |||
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/* | |||
* Matrix/vertex/vector transformation stuff | |||
* | |||
* | |||
* NOTES: | |||
* 1. 4x4 transformation matrices are stored in memory in column major order. | |||
* 2. Points/vertices are to be thought of as column vectors. | |||
* 3. Transformation of a point p by a matrix M is: p' = M * p | |||
*/ | |||
#include "glheader.h" | |||
#include "macros.h" | |||
#include "mmath.h" | |||
#include "m_matrix.h" | |||
#include "m_xform.h" | |||
#ifdef DEBUG | |||
#include "m_debug_xform.h" | |||
#endif | |||
#ifdef USE_X86_ASM | |||
#include "X86/common_x86_asm.h" | |||
#endif | |||
clip_func gl_clip_tab[5]; | |||
dotprod_func gl_dotprod_tab[2][5]; | |||
vec_copy_func gl_copy_tab[2][0x10]; | |||
normal_func gl_normal_tab[0xf][0x4]; | |||
transform_func **(gl_transform_tab[2]); | |||
static transform_func *cull_transform_tab[5]; | |||
static transform_func *raw_transform_tab[5]; | |||
/* Raw data format used for: | |||
* - Object-to-eye transform prior to culling, although this too | |||
* could be culled under some circumstances. | |||
* - Eye-to-clip transform (via the function above). | |||
* - Cliptesting | |||
* - And everything else too, if culling happens to be disabled. | |||
*/ | |||
#define TAG(x) x##_raw | |||
#define TAG2(x,y) x##y##_raw | |||
#define IDX 0 | |||
#define STRIDE_LOOP for (i=0;i<count;i++, STRIDE_F(from, stride)) | |||
#define LOOP for (i=0;i<n;i++) | |||
#define CULL_CHECK | |||
#define CLIP_CHECK | |||
#define ARGS | |||
#include "m_xform_tmp.h" | |||
#include "m_clip_tmp.h" | |||
#include "m_norm_tmp.h" | |||
#include "m_dotprod_tmp.h" | |||
#include "m_copy_tmp.h" | |||
#undef TAG | |||
#undef TAG2 | |||
#undef LOOP | |||
#undef CULL_CHECK | |||
#undef CLIP_CHECK | |||
#undef ARGS | |||
#undef IDX | |||
/* Culled data used for: | |||
* - texture transformations | |||
* - viewport map transformation | |||
* - normal transformations prior to lighting | |||
* - user cliptests | |||
*/ | |||
#define TAG(x) x##_masked | |||
#define TAG2(x,y) x##y##_masked | |||
#define IDX 1 | |||
#define STRIDE_LOOP for (i=0;i<count;i++, STRIDE_F(from, stride)) | |||
#define LOOP for (i=0;i<n;i++) | |||
#define CULL_CHECK if (mask[i]) | |||
#define CLIP_CHECK if ((mask[i] & flag) == 0) | |||
#define ARGS , const GLubyte mask[] | |||
#include "m_xform_tmp.h" | |||
#include "m_norm_tmp.h" | |||
#include "m_dotprod_tmp.h" | |||
#include "m_copy_tmp.h" | |||
#undef TAG | |||
#undef TAG2 | |||
#undef LOOP | |||
#undef CULL_CHECK | |||
#undef CLIP_CHECK | |||
#undef ARGS | |||
#undef IDX | |||
GLvector4f *gl_project_points( GLvector4f *proj_vec, | |||
const GLvector4f *clip_vec ) | |||
{ | |||
const GLuint stride = clip_vec->stride; | |||
const GLfloat *from = (GLfloat *)clip_vec->start; | |||
const GLuint count = clip_vec->count; | |||
GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; | |||
GLuint i; | |||
for (i = 0 ; i < count ; i++, STRIDE_F(from, stride)) | |||
{ | |||
GLfloat oow = 1.0F / from[3]; | |||
vProj[i][3] = oow; | |||
vProj[i][0] = from[0] * oow; | |||
vProj[i][1] = from[1] * oow; | |||
vProj[i][2] = from[2] * oow; | |||
} | |||
proj_vec->flags |= VEC_SIZE_4; | |||
proj_vec->size = 3; | |||
proj_vec->count = clip_vec->count; | |||
return proj_vec; | |||
} | |||
/* | |||
* Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix. This | |||
* function is used for transforming clipping plane equations and spotlight | |||
* directions. | |||
* Mathematically, u = v * m. | |||
* Input: v - input vector | |||
* m - transformation matrix | |||
* Output: u - transformed vector | |||
*/ | |||
void gl_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] ) | |||
{ | |||
GLfloat v0=v[0], v1=v[1], v2=v[2], v3=v[3]; | |||
#define M(row,col) m[row + col*4] | |||
u[0] = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + v3 * M(3,0); | |||
u[1] = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + v3 * M(3,1); | |||
u[2] = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + v3 * M(3,2); | |||
u[3] = v0 * M(0,3) + v1 * M(1,3) + v2 * M(2,3) + v3 * M(3,3); | |||
#undef M | |||
} | |||
/* Useful for one-off point transformations, as in clipping. | |||
* Note that because the matrix isn't analyzed we do too many | |||
* multiplies, and that the result is always 4-clean. | |||
*/ | |||
void gl_transform_point_sz( GLfloat Q[4], const GLfloat M[16], | |||
const GLfloat P[4], GLuint sz ) | |||
{ | |||
if (Q == P) | |||
return; | |||
if (sz == 4) | |||
{ | |||
Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; | |||
Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; | |||
Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; | |||
Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3]; | |||
} | |||
else if (sz == 3) | |||
{ | |||
Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; | |||
Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; | |||
Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; | |||
Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15]; | |||
} | |||
else if (sz == 2) | |||
{ | |||
Q[0] = M[0] * P[0] + M[4] * P[1] + M[12]; | |||
Q[1] = M[1] * P[0] + M[5] * P[1] + M[13]; | |||
Q[2] = M[2] * P[0] + M[6] * P[1] + M[14]; | |||
Q[3] = M[3] * P[0] + M[7] * P[1] + M[15]; | |||
} | |||
else if (sz == 1) | |||
{ | |||
Q[0] = M[0] * P[0] + M[12]; | |||
Q[1] = M[1] * P[0] + M[13]; | |||
Q[2] = M[2] * P[0] + M[14]; | |||
Q[3] = M[3] * P[0] + M[15]; | |||
} | |||
} | |||
/* | |||
* This is called only once. It initializes several tables with pointers | |||
* to optimized transformation functions. This is where we can test for | |||
* AMD 3Dnow! capability, Intel Katmai, etc. and hook in the right code. | |||
*/ | |||
void | |||
_math_init_transformation( void ) | |||
{ | |||
gl_transform_tab[0] = raw_transform_tab; | |||
gl_transform_tab[1] = cull_transform_tab; | |||
init_c_transformations_raw(); | |||
init_c_transformations_masked(); | |||
init_c_norm_transform_raw(); | |||
init_c_norm_transform_masked(); | |||
init_c_cliptest_raw(); | |||
init_copy0_raw(); | |||
init_copy0_masked(); | |||
init_dotprod_raw(); | |||
init_dotprod_masked(); | |||
#ifdef DEBUG | |||
gl_test_all_transform_functions( "default" ); | |||
gl_test_all_normal_transform_functions( "default" ); | |||
#endif | |||
#ifdef USE_X86_ASM | |||
gl_init_all_x86_transform_asm(); | |||
#endif | |||
} | |||
void | |||
_math_init( void ) | |||
{ | |||
_math_init_transformation(); | |||
_math_init_translate(); | |||
_math_init_vertices(); | |||
} |
@@ -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 |
@@ -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 | |||
} |
@@ -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; |
@@ -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" |
@@ -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" |
@@ -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. |
@@ -29,6 +29,8 @@ | |||
#include "macros.h" | |||
#include "types.h" | |||
#include "tnl/t_context.h" | |||
#include "ss_triangle.h" | |||
#include "ss_context.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; | |||
@@ -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" | |||
@@ -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)); |
@@ -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 | |||
} |
@@ -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 |
@@ -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; | |||
} | |||
@@ -0,0 +1,59 @@ | |||
/* $Id: t_pipeline.h,v 1.1 2000/11/16 21:05:42 keithw Exp $ */ | |||
/* | |||
* Mesa 3-D graphics library | |||
* Version: 3.5 | |||
* | |||
* Copyright (C) 1999 Brian Paul All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* | |||
* Author: | |||
* Keith Whitwell <keithw@valinux.com> | |||
*/ | |||
#ifndef _T_PIPELINE_H_ | |||
#define _T_PIPELINE_H_ | |||
#include "types.h" | |||
#include "t_context.h" | |||
extern void gl_update_materials( struct vertex_buffer *VB); | |||
extern void _tnl_pipeline_init( GLcontext *ctx ); | |||
extern void gl_update_pipelines( GLcontext *ctx ); | |||
extern void gl_build_precalc_pipeline( GLcontext *ctx ); | |||
extern void gl_build_immediate_pipeline( GLcontext *ctx ); | |||
extern void gl_print_vert_flags( const char *name, GLuint flags ); | |||
extern void gl_print_pipeline( GLcontext *ctx, struct gl_pipeline *p ); | |||
extern void gl_print_active_pipeline( GLcontext *ctx, struct gl_pipeline *p ); | |||
extern void gl_run_pipeline( struct vertex_buffer *VB ); | |||
extern void gl_clean_color( struct vertex_buffer *VB ); | |||
extern void gl_reset_cva_vb( struct vertex_buffer *VB, GLuint stages ); | |||
extern void gl_print_pipe_ops( const char *msg, GLuint flags ); | |||
#endif |
@@ -0,0 +1,48 @@ | |||
/* | |||
* Mesa 3-D graphics library | |||
* Version: 3.5 | |||
* | |||
* Copyright (C) 1999 Brian Paul All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* Authors: | |||
* Keith Whitwell <keithw@valinux.com> | |||
*/ | |||
#ifndef _TNL_H | |||
#define _TNL_H | |||
#include "types.h" | |||
/* These are the public-access functions exported from tnl. (Many | |||
* more are currently hooked into dispatch directly by core code.) | |||
*/ | |||
extern GLboolean | |||
_tnl_CreateContext( GLcontext *ctx ); | |||
extern void | |||
_tnl_DestroyContext( GLcontext *ctx ); | |||
extern void | |||
_tnl_InvalidateState( GLcontext *ctx, GLuint new_state ); | |||
#endif |
@@ -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 | |||
@@ -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 ); |
@@ -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 |
@@ -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 | |||