aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-09-08 10:54:11 +0200
committermarha <marha@users.sourceforge.net>2011-09-08 10:54:11 +0200
commit23a7aebae0a742d94ffe2304357dcc1234a99155 (patch)
tree08dbd7956bbd1c5717967a4f904f8383139bbe1e
parent53da0b7e7c183ea15692234332b3e337b3fb0cc0 (diff)
downloadvcxsrv-23a7aebae0a742d94ffe2304357dcc1234a99155.tar.gz
vcxsrv-23a7aebae0a742d94ffe2304357dcc1234a99155.tar.bz2
vcxsrv-23a7aebae0a742d94ffe2304357dcc1234a99155.zip
mesa git update 8 sep 2011
-rw-r--r--mesalib/docs/README.3DFX830
-rw-r--r--mesalib/docs/README.AMIWIN181
-rw-r--r--mesalib/docs/README.DJ275
-rw-r--r--mesalib/docs/README.GGI26
-rw-r--r--mesalib/docs/README.LYNXOS64
-rw-r--r--mesalib/docs/README.NeXT6
-rw-r--r--mesalib/docs/README.OS296
-rw-r--r--mesalib/docs/README.OpenStep35
-rw-r--r--mesalib/docs/README.WINDML146
-rw-r--r--mesalib/docs/games.html3
-rw-r--r--mesalib/docs/libraries.html3
-rw-r--r--mesalib/docs/lists.html11
-rw-r--r--mesalib/docs/modelers.html5
-rw-r--r--mesalib/docs/relnotes-7.12.html64
-rw-r--r--mesalib/docs/relnotes.html1
-rw-r--r--mesalib/docs/science.html7
-rw-r--r--mesalib/docs/systems.html27
-rw-r--r--mesalib/docs/utility.html3
-rw-r--r--mesalib/include/GL/glfbdev.h152
-rw-r--r--mesalib/scons/crossmingw.py8
-rw-r--r--mesalib/scons/gallium.py10
-rw-r--r--mesalib/src/glsl/ir_reader.cpp7
-rw-r--r--mesalib/src/mesa/drivers/common/driverfuncs.c5
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c55
-rw-r--r--mesalib/src/mesa/drivers/common/meta.h20
-rw-r--r--mesalib/src/mesa/main/colortab.c689
-rw-r--r--mesalib/src/mesa/main/colortab.h160
-rw-r--r--mesalib/src/mesa/main/dd.h23
-rw-r--r--mesalib/src/mesa/main/enable.c8
-rw-r--r--mesalib/src/mesa/main/extensions.c4
-rw-r--r--mesalib/src/mesa/main/formats.c1
-rw-r--r--mesalib/src/mesa/main/framebuffer.c2
-rw-r--r--mesalib/src/mesa/main/get.c1
-rw-r--r--mesalib/src/mesa/main/image.c27
-rw-r--r--mesalib/src/mesa/main/image.h349
-rw-r--r--mesalib/src/mesa/main/mtypes.h87
-rw-r--r--mesalib/src/mesa/main/pack.c52
-rw-r--r--mesalib/src/mesa/main/pixeltransfer.c873
-rw-r--r--mesalib/src/mesa/main/pixeltransfer.h171
-rw-r--r--mesalib/src/mesa/main/texformat.c7
-rw-r--r--mesalib/src/mesa/main/texgetimage.c71
-rw-r--r--mesalib/src/mesa/main/teximage.c25
-rw-r--r--mesalib/src/mesa/main/texobj.c3
-rw-r--r--mesalib/src/mesa/main/texparam.c6
-rw-r--r--mesalib/src/mesa/main/texstate.c10
-rw-r--r--mesalib/src/mesa/main/texstore.c2
-rw-r--r--mesalib/src/mesa/main/varray.c15
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_eglimage.c339
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_fbo.c15
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_fbo.h180
-rw-r--r--mesalib/src/mesa/swrast/s_drawpix.c2
-rw-r--r--mesalib/src/mesa/swrast/s_texfilter.c7416
-rw-r--r--mesalib/src/mesa/vbo/vbo_attrib_tmp.h12
53 files changed, 4793 insertions, 7797 deletions
diff --git a/mesalib/docs/README.3DFX b/mesalib/docs/README.3DFX
deleted file mode 100644
index 7feda6f33..000000000
--- a/mesalib/docs/README.3DFX
+++ /dev/null
@@ -1,830 +0,0 @@
-
- 3Dfx Glide device driver
-
-
-
-Requirements:
--------------
-
-A Voodoo-based videocard/accelerator
-DOS (with DJGPP), Windows9x/2k (with MinGW), Linux
-Glide3x library for your OS
-
-http://sourceforge.net/projects/glide/
-
-
-
-How to compile:
----------------
-
-DJGPP:
- Place the Glide3 SDK in the top Mesa directory:
- $(MESA)/glide3/include/
- 3dfx.h, g3ext.h, glide.h, glidesys.h, glideutl.h, sst1vid.h
- $(MESA)/glide3/lib/
- libgld3x.a, libgld3i.a, glide3x.dxe
- Type:
- make -f Makefile.DJ X86=1 FX=1
- Look into the makefile for further information.
-
-MinGW:
- Place the Glide3 SDK in the top Mesa directory:
- $(MESA)/glide3/include/
- 3dfx.h, g3ext.h, glide.h, glidesys.h, glideutl.h, sst1vid.h
- $(MESA)/glide3/lib/
- libglide3x.a, glide3x.dll
- Type:
- make -f Makefile.mgw X86=1 FX=1
- Look into the makefile for further information.
-
-Linux:
- Place the Glide3 SDK in /usr/local/glide
- /usr/local/glide/include/
- 3dfx.h, g3ext.h, glide.h, glidesys.h, glideutl.h, sst1vid.h
- /usr/local/glide/lib/
- libglide3x.a, libglide3x.so
- Type:
- make linux-glide
- or
- make linux-x86-glide
-
-
-
-Compilation defines:
---------------------
-
-FX_DEBUG
- enable driver debug code
-FX_TRAP_GLIDE
- enable Glide trace code
-FX_PACKEDCOLOR
- use packed color in vertex structure
-FX_TC_NAPALM
- map GL_COMPRESSED_RGB[A] to FXT1. Works with VSA100-based cards only.
-FX_COMPRESS_S3TC_AS_FXT1_HACK
- map S3TC to FXT1
-FX_RESCALE_BIG_TEXURES_HACK
- fake textures larger than HW can support
- (see MESA_FX_MAXLOD environment variable)
-
-
-
-Environment variables:
-----------------------
-
-The following environment variables affect MesaFX. Those that affect Glide
-only, are beyond the scope of this section. Entries that don't have a "Value"
-field, can have any value whatsoever
- ex: set MESA_FX_IGNORE_CMBEXT=y
-
-"Note" (*) means that the environment variable affects Glide, too; also, if
-the var is not found in the environment, it is searched in windoze registry.
-"Note" (!) means that the environment variable is not working as expected;
-may have undefined effects, might have effects only at Glide level or might
-not have any effect whatsoever. Caveat emptor! Those are to be revised soon.
-
-It is recommended to leave the envvars alone, so that Mesa/Glide will run with
-default values. Use them only when you experience crashes or strange behavior.
-
-FX_GLIDE_NUM_TMU
- OS: all
- HW: dual-TMU cards (Voodoo2, Avenger, Napalm)
- Desc: force single-TMU
- Note: (*)
- Value: "1"
-FX_GLIDE_SWAPPENDINGCOUNT
- OS: all
- HW: all
- Desc: max # of buffers allowed to build up
- Note: (*) (!)
- Value: "0", "1", "2", "3", "4", "5" or "6"
-FX_GLIDE_SWAPINTERVAL
- OS: all
- HW: all
- Desc: number of vertical retraces to wait before swapping
- Note: (*) (!) works only at Glide-level?
-SSTH3_SLI_AA_CONFIGURATION
- OS: all
- HW: VSA100-based cards
- Desc: SLI/AA setup
- Note: (*) (!) works only at Glide-level?
- Value:
- 1, 2, 4 chip cards
- "0" - SLI & AA disable
- "1" - SLI disabled, 2 sample AA enabled
- 2, 4 chip cards
- "2" - 2-way SLI enabled, AA disabled
- "3" - 2-way SLI enabled, 2 sample AA enabled
- "4" - SLI disabled, 4 sample AA enabled
- 4 chip cards
- "5" - 4-way SLI enabled, AA disabled
- "6" - 4-way SLI enabled, 2 sample AA enabled
- "7" - 2-way SLI enabled, 4 sample AA enabled
- "8" - SLI disabled, 8 sample AA enabled
-SST_DUALHEAD
- OS: win32
- HW: ?
- Desc: ?
- Note: (!) disabled?
-MESA_FX_NO_SIGNALS
- OS: linux
- HW: all
- Desc: avoid installing signals
- Note: (!) untested!
-MESA_FX_INFO
- OS: all
- HW: all
- Desc: verbose to stderr
- Value: any; special value "r" to redirect stderr to MESA.LOG
-MESA_FX_NOSNAP
- OS: all
- HW: Voodoo1, Rush, Banshee
- Desc: do not snap vertices inside Mesa
- Note: to be used with Glide3x that snaps vertices internally
-MESA_FX_POINTCAST
- OS: all
- HW: dual-TMU cards (some Voodoo1, Voodoo2, Avenger, Napalm)
- Desc: try to use pointcast palette
- Note: may give adverse effects on UMA cards (Avenger, Napalm)
-MESA_FX_IGNORE_PALEXT
- OS: all
- HW: all
- Desc: disable 6666 palette
-MESA_FX_IGNORE_PIXEXT
- OS: all
- HW: Napalm
- Desc: force 565 16bpp mode (traditional Voodoo, no 32/15bpp)
-MESA_FX_IGNORE_TEXFMT
- OS: all
- HW: Napalm
- Desc: disable 32bit textures
-MESA_FX_IGNORE_CMBEXT
- OS: all
- HW: Napalm
- Desc: disable Napalm combiners (color/alpha/texture)
- Note: this option allows dual-TMU cards perform single-pass
- trilinear, but some advanced (multi)texturing modes
- won't work (GL_EXT_texture_env_combine)
-MESA_FX_IGNORE_MIREXT
- OS: all
- HW: all
- Desc: disable mirror extension
-MESA_FX_IGNORE_TEXUMA
- OS: all
- HW: all
- Desc: disable UMA
-MESA_FX_IGNORE_TEXUS2
- OS: all
- HW: all
- Desc: disable Texus2
-MESA_FX_MAXLOD
- OS: all
- HW: non VSA-100 cards
- Desc: enable large texture support using SW rescaling
- Value:
- "9" - 512x512 textures
- "10" - 1024x1024 textures
- "11" - 2048x2048 textures
-MESA_FX_ALLOW_VP
- OS: all
- HW: all
- Desc: allow vertex program extensions
-MESA_GLX_FX
- OS: linux
- HW: Voodoo1, Rush, Voodoo2
- Desc: display mode
- Note: (!) experimental
- Value:
- "w" - windowed mode
- "f" - fullscreen mode
- "d" - disable glide driver
- OS: win32
- HW: Rush, Banshee, Avenger, Napalm
- Desc: display mode
- Note: (!) experimental
- Value:
- "w" - windowed mode
-
-
-
-Contact:
---------
-
-Daniel Borca <dborca 'at' users 'dot' sourceforge 'dot' net>
-Hiroshi Morii <koolsmoky 'at' users 'dot' sourceforge 'dot' net>
-
-
-
-WARNING! The info below this line is outdated (yet some of it useful). WARNING!
-*******************************************************************************
-
-
-
-Info for Mesa 4.1
------------------
-
-The 3dfx Glide driver in Mesa is disabled by default. Not too many people
-use this driver anymore and at some point down the road it will be dropped.
-
-To use/enable the Glide driver either do this:
-
-'./configure --with-glide=DIR' Where DIR is the location of Glide, like
- /usr/ or /usr/local
-
-OR
-
-'make linux-x86-glide' If using the old-style Makefile system.
-
-The rest of this file hasn't changed since Mesa 3.3. Some of it's out of
-date, but some is still valid.
-
-
-
-What do you need ?
-------------------
-
- - A PC with a 3Dfx Voodoo1/2 Graphics or Voodoo Rush based board
- (Pure3D, Monster 3D, R3D, Obsidian, Stingray 128/3D, etc.).
- The Quantum3D Obsidian3D-2 X-24 requires some special env. setting
- under Linux (more information in the "Useful Glide Environment
- Variables");
-
- - The 3Dfx Glide library 2.3 or later for your OS (the 2.4 works fine).
- The Voodoo2 requires the Glide library 2.51. The Glide 3.1 is not
- compatible with the Glide 2.x so it doesn't work with the current
- version of the driver;
-
- - A compiler supported by the Glide library (Micro$oft VC++ (tested),
- Watcom (tested), GCC for Linux (tested), etc.);
-
- - It's nice to have two monitors - one for your normal graphics
- card and one for your 3Dfx card. If something goes wrong with
- an application using the 3Dfx hardware you can still see your
- normal screen in order to recover.
-
-
-
-Tested on:
-----------
- Windows 95 - David Bucciarelli
- Windows NT - Henri Fousse
- MS-DOS
- Linux - Daryll Strauss, Brian Paul, David Bucciarelli
- FreeBSD
- BeOS - Duncan Wilcox
- MacOS - Fazekas Miklos
-
-
-What is able to do ?
---------------------
-
- - It is able accelerate points, lines and polygon with flat
- shading, gouraud shading, Z-buffer, texture mapping, blending, fog and
- antialiasing (when possible). There is also the support for rendering
- in a window with a slow trick for the Voodoo Graphics (available only
- for Linux) and at full speed with the Voodoo Rush chipset.
- Under Linux is also possible to switch on-the-fly between the fullscreen
- and in-window rendering hack.
- There is also the support for using more than one Voodoo Graphics in the
- some application/PC (you can create one context for each board and use
- multiple video outputs for driving monitors, videoprojectors or HMDs).
- The driver is able to fallback to pure software rendering when afeature
- isn't supported by the Voodoo hardware (however software rendering is
- very slow compared to hardware supported rendering)
-
-
-
-How to compile:
----------------
-
-Linux:
-------
- Here are the basic steps for using the 3Dfx hardware with Mesa
- on Linux:
-
- - You'll need the Glide library and headers. Mesa expects:
- /usr/local/glide/include/*.h // all the Glide headers
- /usr/local/glide/lib/libglide2x.so
-
- If your Glide libraries and headers are in a different directory
- you'll have to modify the Mesa-config and mklib.glide files.
-
- - Unpack the MesaLib-3.1.tar.gz and MesaDemos-3.1.tar.gz archives;
-
- - If you're going to use a newer Mesa/Glide driver than v0.27 then
- unpack the new driver archive over the Mesa directory.
-
- - In the Mesa-3.1 directory type "make linux-glide"
-
- - Compilation _should_ finish without errors;
-
- - Set your LD_LIBRARY_PATH environment variable so that the
- libglide2x.so and Mesa library files can be found. For example:
- setenv LD_LIBRARY_PATH "/usr/local/glide/lib:/SOMEDIR/Mesa-3.1/lib"
-
- - You'll have to run Glide-based programs as root or set the suid
- bit on executables;
-
- - Try a demo:
- cd gdemos
- su
- setenv MESA_GLX_FX f
- ./gears (hit ESC to exit)
-
- - You can find the demos especially designed for the Voodoo driver in
- in the Mesa-3.1/3Dfx/demos directory (type "make" in order to compile
- everything).
-
-MacOS:
-------
- Check the WEB page at http://valerie.inf.elte.hu/~boga/Mesa.html
-
-MS Windows:
------------
-
- For the MSVC++:
- - The glide2x.lib have to be in the default MSVC++ lib directory;
-
- - The Glide headers have to be in the default MSVC++ include directory;
-
- - You must have the vcvars32.bat script in your PATH;
-
- - Go to the directory Mesa-3.1 and run the mesafx.bat;
-
- - The script will compile everything (Mesa-3.1/lib/OpenGL32.{lib,dll},
- Mesa-3.1/lib/GLU32.{lib,dll}, Mesa-3.1/lib/GLUT32.{lib,dll} and
- Voodoo demos);
-
- - At the end, you will be in the Mesa-3.1/3Dfx/demos directory;
-
- - Try some demo (fire.exe, teapot.exe, etc.) in order to check if
- everything is OK (you can use Alt-Tab or Ctrl-F9 to switch between
- the Voodoo screen and the windows desktop);
-
- - Remember to copy the Mesa OpenGL32.dll, GLU32.dll and GLUT32.dll in the
- some directory were you run your Mesa based applications.
-
- - I think that you can easy change the Makefile.fx files in order
- to work with other kind of compilers;
-
- - To discover how open the 3Dfx screen, read the sources under
- the Mesa-3.1/3Dfx/demos directory. You can use the GLUT library or
- the Diego Picciani's wgl emulator.
-
- NOTE: the MSVC++ 5.0 optimizer is really buggy. Also if you install the
- SP3, you could have some problem (you can disable optimization in order
- solve these kind of problems).
-
-
-Doing more with Mesa & Linux Glide:
------------------------------------
-
- The MESA_GLX_FX environment variable can be used to coax most
- GLX-based programs into using Glide (and the __GLUT library
- is GLX-based__).
-
- Full-screen 3Dfx rendering:
- ---------------------------
-
- 1. Set the MESA_GLX_FX variable to "fullscreen":
-
- ksh:
- export MESA_GLX_FX = "fullscreen"
- csh:
- setenv MESA_GLX_FX fullscreen
-
- 2. As root, run a GLX-based program (any GLUT demo on Linux).
-
- 3. Be careful: once the 3Dfx screen appears you won't be able
- to see the GLUT windows on your X display. This can make using
- the mouse tricky! One solution is to hook up your 3Dfx card to
- a second monitor. If you can do this then set these env vars
- first:
-
- setenv SST_VGA_PASS 1
- setenv SST_NOSHUTDOWN
-
- or for the Voodoo2:
-
- setenv SSTV2_VGA_PASS 1
- setenv SSTV2_NOSHUTDOWN
-
- Rendering into an X window with the help of the Voodoo hardware:
- ----------------------------------------------------------------
-
- 1. Start your X server in 16 bpp mode (XFree86: startx -- -bpp 16)
- in order to have the best performance and the best visual
- quality. However you can use any visual depth supported by X.
-
- 2. Set the following environment variables:
- export MESA_GLX_FX="window" # to enable window rendering
- export SST_VGA_PASS=1 # to stop video signal switching
- export SST_NOSHUTDOWN=1 # to stop video signal switching
- OR
- setenv MESA_GLX_FX window
- setenv SST_VGA_PASS 1
- setenv SST_NOSHUTDOWN 1
-
- (the Voodoo2 requires to use "SSTV2_" instead "SST_").
-
- 3. As root, try running a GLX-based program
-
- How does it work? We use the 3Dfx hardware to do rendering then
- copy the image from the 3Dfx frame buffer into an X window when
- the SwapBuffers() function is called. The problem with this
- idea is it's slow. The image must be copied from the 3Dfx frame
- buffer to main memory then copied into the X window (and when the X
- visual depth doesn't match the Voodoo framebufffer bit per pixel, it
- is required also a pixel format translation).
-
- NOTE: the in-window rendering feature only works with double-buffering.
-
-
- On the fly switching between in window rendering and full screen rendering
- --------------------------------------------------------------------------
-
- The Mesa 2.6 has introduced the capability of switching
- on-the-fly between the fullscreen/fullspeed rendering and the in-window
- hack and vice versa. The on-the-fly switching requires a direct support
- by the application but it is really easy to add. You have to start
- your X server in 16 bpp mode and to add the following lines to your
- application:
-
- #if defined(FX) && define(XMESA)
- #include <GL/xmesa.h>
-
- static int fullscreen=1;
- #endif
-
- ...
-
- /* In the GLUT keyboard event callback */
-
- #if defined(FX) && !define(WIN32)
- case ' ':
- fullscreen=(!fullscreen);
- XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
- break;
- #endif
- ...
-
- See the 3Dfx/demos/tunnel.c program
- for an example. You have to set the -DXMESA flag in the Makefile's COPTS
- to enable it.
-
- Rendering into an X window with the X11 software driver:
- --------------------------------------------------------
-
- Set the MESA_GLX_FX variable to "disable" your GLX-based program will use
- the X11 software driver (the 3Dfx hardware isn't used at all).
-
-
-
-Useful Glide Environment Variables:
------------------------------------
-
- - To disable the 3Dfx logo, set the FX_GLIDE_NO_SPLASH variable.
-
- - To disable video signal switching:
- setenv SST_VGA_PASS 1
- setenv SST_NOSHUTDOWN
- or for the Voodoo2:
- setenv SSTV2_VGA_PASS 1
- setenv SSTV2_NOSHUTDOWN
-
- - To set the default screen refresh rate:
- setenv SST_SCREENREFRESH=75
-
- the supported values are 60, 70, 72, 75, 80, 85, 90, 100, 120.
-
- - To force the Mesa library to swap buffers as fast as possible,
- without any vertical blanking synchronization (useful for benchmarks):
- setenv FX_GLIDE_SWAPINTERVAL 0
- setenv SST_SWAP_EN_WAIT_ON_VIDSYNC 0
-
- - You can slight improve the performances of your Voodoo1 board with
- the following env. var.:
- setenv SST_FASTMEM 1
- setenv SST_PCIRD 1
- setenv SST_GRXCLK 57
-
- (don't use this setting with the Quantum3D 100SB or with any other
- SLI configuration: it will hang everything !).
- The following setting can be used with the Voodoo2:
- setenv SSTV2_FASTMEM_RAS_READS=1
- setenv SSTV2_FASTPCIRD=1
- setenv SSTV2_GRXCLK=95
-
- - The Quantum3D Obsidian3D-2 X-24 requires some special env. setting
- in order to work under Linux:
-
- export SSTV2_FT_CLKDEL=5
- export SSTV2_TF0_CLKDEL=7
- export SSTV2_TF1_CLKDEL=7
- export SSTV2_TF2_CLKDEL=7
- export SSTV2_SLIM_VIN_CLKDEL=3
- export SSTV2_SLIM_VOUT_CLKDEL=2
- export SSTV2_SLIS_VIN_CLKDEL=3
- export SSTV2_SLIS_VOUT_CLKDEL=2
-
- (Thanks to Phil Ross for this trick).
-
-
-
-
-The Mesa/Voodoo Environment Variables:
---------------------------------------
-
- - Only for Windows/Voodoo Rush users, if you define the
- env. var. MESA_WGL_FX:
- export MESA_WGL_FX=fullscreen
- you will get fullscreen rendering;
-
- - Only for Windows/Voodoo Rush users, if you define the
- env. var. MESA_WGL_FX:
- export MESA_WGL_FX=window
- you will get window rendering (default value);
-
- - Only for Linux users, you can find more informations about
- the env. var. MESA_GLX_FX in the "Doing more with Mesa & Linux Glide"
- section;
-
- - If you define the env. var. MESA_FX_SWAP_PENDING:
- export MESA_FX_SWAP_PENDING=4
- you will able to set the maximum number of swapbuffers
- commands in the Voodoo FIFO after a swapbuffer (default value: 2);
-
- - If you define the env. var. MESA_FX_INFO:
- export MESA_FX_INFO=1
- you will get some useful statistic.
-
- - If you define the env. var. MESA_FX_NO_SIGNALS:
- export MESA_FX_NO_SIGNALS=1
- Mesa/FX will not install atexit() or signal() handlers.
-
-
-
-Know BUGS and Problems:
------------------------
-
- - fog doesn't work in the right way when using the glDepthRange() function;
-
- - Maximum texture size: 256x256 (this is an hardware limit);
-
- - Texture border aren't yet supported;
-
- - A GL_BLEND in a glTexEnv() is not supported (it is an hardware limit);
-
- - Use the glBindTexture extension (standard in OpenGL 1.1) for texture
- mapping (the old way: glTexImage inside a display list, download
- the texture map each time that you call the display list !!!);
-
- - Stencil buffer and Accumulation buffer are emulated in software (they are not
- directly supported by the Hardware);
-
- - Color index mode not implemented (this is an hardware limit);
-
- - Thre is an know bug in the Linux Glide library so the in-window-rendering hack
- and any other operations that requires to read the Voodoo frame buffer
- (like the accumulation buffer support) doesn't work on Voodoo SLI cards.
-
- - The driver switch to pure software (_slow_) rendering when:
-
- - Stencil enabled;
- - Using the Accumulation buffer;
- - Blend enabled and blend equation != GL_FUNC_ADD_EXT;
- - Color logic operation enabled and color logic operation != GL_COPY;
- - Using GL_SEPARATE_SPECULAR_COLOR;
- - The four values of glColorMask() aren't the some;
- - Texture 1D or 3D enabled;
- - Texture function is GL_BLEND;
- - Using the Multitexture extension with Voodoo cards with only one TMU;
- - Using the Multitexture extension with Voodoo cards with more than
- one TMU, and texture function isn't GL_MODULATE;
- - Point size is != 1.0 or point params vector != (1.0,0.0,0.0);
- - Line width != 1.0 or using stipple lines.
- - Using polygon offset or stipple polygons;
-
- NOTE: this is list is not yet complete.
-
-
-Hints and Special Features:
----------------------------
-
- - Under Linux and with a Voodoo Graphics board, you can use
- XMesaSetFXmode(XMESA_FX_FULLSCREEN or XMESA_FX_WINDOW) in order to
- switch on the fly between fullscreen rendering and the in-window-rendering
- hack.
-
- - The driver is able to use all the texture memory available: 2/4MB on
- Voodoo1 boards and 8MB (!) on high-end Voodoo1 and Voodoo2 boards.
-
- - Trilinear filtering is fully supported on Voodoo boards with two TMUs
- (high-end Voodoo1 boards and Voodoo2 boards). When only one TMU is
- available the driver fallback to bilinear filter also if you ask
- for trilinear filtering.
-
- - The Voodoo driver support multiple Voodoo Graphics boards in the
- some PC. Using this feature, you can write applications that use
- multiple monitors, videoprojectors or HMDs for the output. See
- Mesa-3.1/3Dfx/demos/tunnel2.c for an example of how setup one
- context for each board.
-
- - The v0.19 introduces 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 MBs of texture maps also with a 2MB
- of texture memory (the texture memory manager will do automatically
- all the swap out/swap in
- texture memory work). The new texture memory manager has also
- solved a lot of other bugs/no specs compliance/problems
- related to the texture memory usage.
-
- - Use triangles and quads strip: they are a LOT faster than sparse
- triangles and quads.
-
- - The Voodoo driver supports the GL_EXT_paletted_texture. it works
- only with GL_COLOR_INDEX8_EXT, GL_RGBA palettes and the alpha value
- is ignored because this is a limitation of the current Glide
- version and of the Voodoo hardware. See Mesa-3.1/3Dfx/demos/paltex.c for
- a demo of this extension.
-
- - The Voodoo driver directly supports 3Dfx Global Palette extension.
- It was written for GLQuake and I think that it isn't a good idea
- to use this extension for any other purpose (it is a trick). See
- Mesa-3.1/3Dfx/demos/glbpaltex.c for a demo of this extension.
-
- - The Voodoo driver chooses the screen resolution according to the
- requested window size. If you open a 640x480 window, you will get
- a 640x480 screen resolution, if you open a 800x600 window, you
- will get a 800x600 screen resolution, etc.
- Most GLUT demos support the '-geometry' option, so you can choose
- the screen resolution: 'tunnel -geometry 800x600'.
- Clearly, you Voodoo board must have enough framebuffer RAM (otherwise
- the window creation will fail).
-
- - The 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.
-
-Did you find a lot BUGs and problems ? Good, send me an email.
-
-
-
-FAQ:
-----
-
-For a complete FAQ check the Bernd Kreimeier's Linux 3Dfx HOWTO
-available at http://www.gamers.org/dEngine/xf3D (it includes also
-a lot of informations not strictly related to Linux, so it can be
-useful also if you don't use Linux)
-
-1. What is 3Dfx?
-
-3Dfx Interactive, Inc. is the company which builds the VooDoo 3-D graphics
-chipset (and others) used in popular PC cards such as the Diamond Monster 3D
-and the Orchid Righteous 3D (more informations at http://www.3dfx.com).
-
-
-2. What is Glide?
-
-Glide is a "thin" programming interface for the 3Dfx hardware. It was
-originally written for Windows/Intel but has been ported to Linux/Intel
-by Daryll Strauss.
-
-3Dfx, Inc. should be applauded for allowing the Linux version of Glide
-to be written.
-
-You can directly program with the Glide library if you wish. You can
-obtain Glide from the "Developer" section of the 3Dfx website: www.3dfx.com
-There's a Linux/Glide newsgroup at news://news.3dfx.com/3dfx.glide.linux
-
-
-3. What is fxmesa?
-
-"fxmesa" is the name of the Mesa device driver for the 3Dfx Glide library.
-It was written by David Bucciarelli and others. It works on both Linux
-and Windows. Basically, it allows you to write and run OpenGL-style programs
-on the 3Dfx hardware.
-
-
-4. What is GLQuake?
-
-Quake is a very popular game from id software, Inc. See www.idsoftware.com
-GLQuake is a version of Quake written for OpenGL. There is now a Linux
-version of GLQuake with works with the Mesa/3Dfx/Glide combo.
-
-Here's what you need to run GLQuake on Linux:
- PC with 100MHz Pentium or better
- a 3Dfx-based card
- Mesa 3.1 libraries: libMesaGL.so libMesaGLU.so
- Glide 2.4 libraries: libglide2x.so libtexus.so
- GLQuake for Linux.
-
-Also, the windows version of GLQuake works fine with the Mesa OpenGL32.dll,
-you have only to copy the Mesa-3.1/lib/OpenGL32.dll in the GLQuake directory
-in order to test 'MesaQuake'.
-
-
-5. What is GLUT?
-
-GLUT is Mark Kilgard's OpenGL Utility Toolkit. It provides an API for
-writing portable OpenGL programs with support for multiple windows, pop-
-up menus, event handling, etc.
-
-Check the Mark's home page for more informations (http://reality.sgi.com/mjk_asd).
-
-Every OpenGL programmer should check out GLUT.
-
-GLUT on Linux uses GLX.
-
-
-6. What is GLX?
-
-GLX is the OpenGL extension to the X Window System. I defines both a
-programming API (glX*() functions) and a network protocol. Mesa implements
-an emulation of GLX on Linux. A real GLX implementation would requires
-hooks into the X server. The 3Dfx hardware can be used with GLX-based
-programs via the MESA_GLX_FX environment variable.
-
-
-7. Is the Voodoo driver able to use the 4Mb texture memory of
-the Pure3D boards ?
-
-Yes, the Voodoo driver v0.20 includes the support for Voodoo
-Graphics boards with more than 2Mb of texture memory.
-
-
-8. Do the Voodoo driver support the Voodoo Rush under Windows ?
-
-Yes, Diego Picciani has developed the support for the Voodoo
-Rush but David Bucciarelli has a Pure3D and a Monster3D and Brian Paul
-has a Monster3D, so the new versions of the Mesa/Voodoo sometime are
-not tested with the Voodoo Rush.
-
-
-9. Do the Voodoo driver support the Voodoo Rush under Linux ?
-
-No because the Linux Glide doesn't (yet) support the Voodoo Rush.
-
-
-10. Can I sell my Mesa/Voodoo based software and include
-a binary copy of the Mesa in order to make the software
-working out of the box ?
-
-Yes.
-
-
-11. Which is the best make target for compiling the Mesa for
-Linux GLQuake ('make linux-glide', 'make linux-386-glide', etc.) ?
-
-'make linux-386-opt-glide' for Voodoo1 and 'make linux-386-opt-V2-glide'
-for Voodoo2 boards because it doesn't include the '-fPIC'
-option (4-5% faster).
-
-
-12. Can I use a Mesa compiled with a 'make linux-386-opt-V2-glide'
-for my applications/programs/demos ?
-
-Yes, there is only one constrain: you can't run two Mesa applications
-at the some time. This isn't a big issue with the today Voodoo Graphics.
-
-
-Thanks to:
-----------
-
-Henri Fousse (he has written several parts of the v0.15 and the old GLUT
- emulator for Win);
-
-Diego Picciani (he has developed all the Voodoo Rush support and the wgl
- emulator);
-
-Daryll Strauss (for the Linux Glide and the first Linux support);
-
-Brian Paul (of course);
-
-Dave 'Zoid' Kirsch (for the Linux GLQuake and Linux Quake2test/Q2 ports)
-
-Bernd Kreimeier (for the Linux 3Dfx HOWTO and for pushing companies to offer
- a better Linux support)
-
-3Dfx and Quantum3D (for actively supporting Linux)
-
-The most update places where find Mesa VooDoo driver related informations are
-the Mesa mailing list and my driver WEB page
-(http://www-hmw.caribel.pisa.it/fxmesa/index.shtml)
-
-
-David Bucciarelli (davibu@tin.it)
-
-Humanware s.r.l.
-Via XXIV Maggio 62
-Pisa, Italy
-Tel./Fax +39-50-554108
-email: info.hmw@plus.it
-www: www-hmw.caribel.pisa.it
diff --git a/mesalib/docs/README.AMIWIN b/mesalib/docs/README.AMIWIN
deleted file mode 100644
index 47cf696cc..000000000
--- a/mesalib/docs/README.AMIWIN
+++ /dev/null
@@ -1,181 +0,0 @@
-AMIGA AMIWIN PORT of MESA: THE OPENGL SOFTWARE EMULATION
-========================================================
-Port by Victor Ng-Thow-Hing (victorng@dgp.toronto.edu)
-Original Author (Brian Paul (brianp@ssec.wisc.edu)
-
-Dec.1 , 1995: Port of release Mesa 1.2.5
- - Modifications made to minimize changes to Mesa distribution.
-
-Nov.25, 1995: Port of release Mesa 1.2.4
-
-
-HISTORY
-=======
-As a 3D graphics progammer, I was increasingly frustrated to see OpenGL
-appearing on so many platforms EXCEPT the Amiga. Up to now, the task
-of porting OpenGL directly from native Amiga drawing routines seemed like
-a daunting task. However, two important events made this port possible.
-
-First of all, Brian Paul wrote Mesa, the OpenGL software emulator that
-can be found on many platforms - except the Amiga and Atari (who cares
-about the latter!). This was pretty ironic considering that Mesa was
-originally prototyped on an Amiga! The second great event was when
-Holger Kruse developed AmiWin, the X11R6 server for the Amiga (definitely
-register for this great piece of software) and released a development kit
-so one could compile X programs with SAS/C.
-
-Since Mesa had X routines as its primitive drawing operations, this made
-a marriage of Mesa and Amiwin feasible. I copied over the sources from
-an ftp site, played with the code, wrote some Smakefiles, and voila,
-I had OpenGL programs displaying on my Amiga.
-
-Although the speed is nothing to be impressed about, this port can be
-potentially useful to those who want to quickly test their code in
-wireframe or perhaps learn more about programming with the OpenGL API.
-
-I hope Amiga developers will continue to write excellent software for
-their machine, especially more X clients for Amiwin. If you have any
-solutions so some of my problems in the porting notes, please send me
-some email!
-
-See you around,
-Vic.
-
-HOW TO CREATE THE LIBRARIES AND SAMPLE CODE
-===========================================
-
-Just run the shell script mklib.amiwin in the mesa directory. This will
-make all the libraries and copy them into the mesa/lib directory. If you
-don't want to compile everything, just go to the desired directory and
-type smake in that directory.
-
-Change any of the variables in the smakefiles as necessary. You will REQUIRE
-the Amiwin development kit to compile these libraries since you need X11.LIB
-and the shareable X libraries. Some examples require the AmiTCP4.0
-net.lib static link library and related header files for unix related
-header files and functions like sleep().
-
-HOW TO USE THE MESA LIBRARIES
-=============================
-
-Study the Smakefiles in the demos, samples and book directories for the
-proper SAS/C options and linkable libraries to use. Basically aux calls
-require Mesaaux.LIB, gl calls require MesaGL.LIB, glu calls MesaGLU.LIB,
-tk calls Mesatk.LIB. There is a preliminary port of MesaGLUT.LIB toolkit
-available in the lib directory with the other Mesa libraries. However,
-it seems to cause crashes on some of the sample code. Someone else may want
-to attempt a more stable port.
-
-PORTING NOTES TO AMIWIN
-=======================
-
-My strategy of porting was to leave as much of the code untouched as
-possible. I surrounded any amiga specific changes with
-#ifdef AMIWIN ... #endif or #ifndef AMIWIN ... #endif preprocessor
-symbols. The code was ported on an Amiga 2000, with Fusion 40 accelerator
-and a Picasso II graphics card. The SAS/C 6.56 compiler was used, with
-the AmiWin 2.16 X development kit.
-
-All compilations were done for a 68040 CPU with 68882 math coprocessor for
-maximum speed. Please edit the smakefile for other compilers.
-I wrote smakefiles for the directories I ported. I omitted the Windows
-and Widgets directories. The former is for MS Windows and the latter
-requires Motif, which is not easily available for the Amiga.
-
-Here are the changes I did per directory:
-
-* mesa
-Nov. 25, 1995 v 1.2.4
- - added a mklib.amiwin shell script that will make all the libraries and
- sample code for Mesa
- - created this readme file: readme.AMIGA
-
-* mesa/include
-Dec. 1, 1995 v 1.2.5
- - added the following to GL/xmesa.h
- #ifdef AMIWIN
- #include <pragmas/xlib_pragmas.h>
- extern struct Library *XLibBase;
- #endif
-NET CHANGE: xmesa.h
-
-* mesa/src
-Nov. 25, 1995 v 1.2.4
- - added the necessary pragma calls for X functions to the following:
- xmesa1.c, xmesa2.c, xmesa3.c, xfonts.c, glx.c
- This prevents undefined symbols errors during the linking phase for
- X library calls
- - created smakefile
-Dec. 1, 1995 v 1.2.5
- - removed AMIWIN includes from xmesa1.c, xmesa2.c, xmesa3.c, xfonts.c,
- glx.c since they are now defined in include/GL/xmesa.h
-NET CHANGE: smakefile
-
-* mesa/src-tk
-Nov. 25, 1995 v 1.2.4
- - added the necessary pragma calls for X functions to the following:
- private.h
- - created smakefile
-Dec. 1, 1995 v 1.2.5
- - removed AMIWIN includes from private.h since it is now defined in
- include/GL/xmesa.h
-NET CHANGE: smakefile
-
-* mesa/src-glu
-Nov. 25, 1995 v 1.2.4
- - created smakefile
-NET CHANGE: smakefile
-
-* mesa/src-aux
-Nov. 25, 1995 v 1.2.4
- - added the necessary pragma calls for X functions to the following:
- glaux.c
- - created smakefile
-NET CHANGE: glaux.c, smakefile
-
-* mesa/demos
-Nov. 25, 1995 v 1.2.4
- - added the necessary pragma calls for X functions to the following:
- xdemo.c, glxdemo.c, offset.c
- - created smakefile
- - put #ifndef AMIWIN ... #endif around sleep() calls in xdemo.c since
- they are not part of AmigaDOS.
-Dec. 1, 1995 v 1.2.5
- - removed AMIWIN defines from xdemo.c, glxdemo.c, offset.c since
- already defined in include/GL/xmesa.h
- - modified Smakefile to include header and includes from the AmiTCP4.0
- net.lib linkable library to provide unix-compatible sys/time.h and
- the sleep() function
- - removed AMIWIN defines in xdemo.c since sleep() now defined
-NET CHANGE: smakefile
-
-* mesa/samples
-Nov. 25, 1995 v 1.2.4
- - added the necessary pragma calls for X functions to the following:
- oglinfo.c
- - created smakefile
- - put #ifndef AMIWIN ... #endif around sleep() in blendxor.c
- - removed olympic from smakefile targets since <sys/time.h> not defined
-Dec. 1, 1995 v 1.2.5
- - removed AMIWIN defines from oglinfo.c, since already defined in
- include/GL/xmesa.h
- - modified Smakefile to include header and includes from the AmiTCP4.0
- net.lib linkable library to provide unix-compatible sys/time.h and
- the sleep() function
- - removed AMIWIN defines in blendxor.c for sleep()
- - added AMIWIN defines around _MACHTEN_ in olympic.c since xrandom()
- functions are not defined in any libraries
- - added olympic back into the Smakefile targets
-NET CHANGE: smakefile, olympic.c
-
-* mesa/book
-Nov. 25, 1995 v 1.2.4
-- created smakefile
-- removed accpersp and dof from smakefile targets since the SAS/C compile seems to
- confuse the near,far variables with near/far memory models.
-NET CHANGE: smakefile
-
-* mesa/windows
-Dec. 1, 1995 v 1.2.5
-- Removed directory to save space since this is only needed for Windows based
- machines.
diff --git a/mesalib/docs/README.DJ b/mesalib/docs/README.DJ
deleted file mode 100644
index 5f783ac53..000000000
--- a/mesalib/docs/README.DJ
+++ /dev/null
@@ -1,275 +0,0 @@
- Mesa 6.5 DOS/DJGPP Port v1.8
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-
-Description:
-~~~~~~~~~~~~
-
-Well, guess what... this is the DOS port of Mesa 6.5, for DJGPP fans... Whoa!
-The driver uses OSMesa to draw off screen, and then blits the buffer. This is
-not terribly efficient, and has some drawbacks, but saves maintenance costs.
-
-
-
-Legal:
-~~~~~~
-
-Mesa copyright applies.
-
-
-
-Installation:
-~~~~~~~~~~~~~
-
-Unzip and type:
-
- make -f Makefile.DJ [OPTIONS...]
-
-Available options:
-
- Environment variables:
- CPU optimize for the given processor.
- default = pentium
- GLIDE path to Glide3 SDK; used with FX.
- default = $(TOP)/glide3
- FX=1 build for 3dfx Glide3. Note that this disables
- compilation of most DMesa code and requires fxMesa.
- As a consequence, you'll need the DJGPP Glide3
- library to build any application.
- default = no
- X86=1 optimize for x86 (if possible, use MMX, SSE, 3DNow).
- default = no
-
- Targets:
- all: build everything
- libgl: build GL
- libglu: build GLU
- libglut: build GLUT
- clean: remove object files
- realclean: remove all generated files
-
-
-
-Tested on:
- Video card: Radeon 9500
- DJGPP: djdev 2.04 + gcc v4.1.0 + make v3.80
- OS: DOS, Win98SE, WinXP (using Videoport driver)
-
-
-
-FAQ:
-~~~~
-
-1. Compilation
-
- Q) `make' barfs and exits because it cannot find some stupid file.
- A) You need LFN support.
- A) When compiling for Glide (FX=1), pay attention to Glide path.
-
- Q) Libraries built OK, but linker complains about `vsnprintf' every time I
- compile some demo.
- A) Upgrade to DJGPP 2.04.
- A) Add `vsnprintf.c' to the CORE_SOURCES in `src/Makefile.DJ' (untested!).
- A) Patch `src/mesa/main/imports.c' with the following line:
- #define vsnprintf(buf, max, fmt, arg) vsprintf(buf, fmt, arg)
- This hack should be safe in 90% of the cases, but if anything goes wrong,
- don't come back to me crying.
-
- Q) `make' complains about DXE3 or something, yet it builds the libraries.
- A) DXE3 refers to the DJGPP dynamic modules. You'll need either the latest
- DJGPP distro, or download the separate package from my web page. Read the
- DXE3 documentation on how to use them.
- A) When compiling for Glide (FX=1), make sure `glide3x.dxe' can be found in
- LD_LIBRARY_PATH (or top `lib' directory).
-
-2. Using Mesa for DJGPP
-
- Q) Every test I tried crashes badly.
- A) If you have compiled with SSE and you're running under plain DOS, you
- have to disable SSE at run-time. See environment variables below.
-
- Q) DMesa is so SLOOOW! The Win32 OpenGL performs so much better...
- A) Is that a question? If you have a 3dfx Voodoo (any model), you're
- lucky (check http://sourceforge.net/projects/glide for the DJGPP port).
- If you haven't, sorry; everything is done in software.
-
- Q) I tried to set refresh rate w/ DMesa, but without success.
- A) Refresh rate control works only for VESA 3.0 and the 3dfx driver (in
- which case FX_GLIDE_REFRESH will be overwritten if it is defined and
- is not 0).
-
- Q) I made a simple application and it does nothing. It exits right away. Not
- even a blank screen.
- A) Software drivers (VESA/VGA/NUL) must to be constructed as single-buffered
- visuals. However, DMesaSwapBuffers must be called to get any output.
- A) Another weird "feature" is that buffer width must be multiple of 8 (I'm a
- lazy programmer and I found that the easiest way to keep buffer handling
- at peak performance ;-).
-
- Q) I'm getting a "bad font!" fatal error.
- A) Always use GLUT_STROKE_* and GLUT_BITMAP_* constants when dealing with
- GLUT fonts. If you're using `glut.dxe', then make sure GLUT_STROKE_* and
- GLUT_BITMAP_* are mapped to integer constants, not to the actual font
- address (same mechanism used for Win32 _DLL).
-
- Q) What is NUL driver good for, if I don't get any output at all?
- A) For debugging. The NUL driver is very much like OSMesa. Everything is
- done just the same as VESA/VGA drivers, only it doesn't touch your video
- hardware. You can query the actual buffer by issuing:
- DMesaGetIntegerv(DMESA_GET_BUFFER_ADDR, &buffer);
- and dump it to a file.
-
- Q) How do I query for a list of available video modes to choose as a visual?
- A) This is an ugly hack, for which I'm sure I'll burn in hell.
- First, query for a list of modes:
- n = DMesaGetIntegerv(DMESA_GET_VIDEO_MODES, NULL);
- If `n' is strictly positive, you allocate an array of pointers to a given
- struct (which is guaranteed to be extended only - not changed in future):
- struct {
- int xres, yres;
- int bpp;
- } **l = malloc(n * sizeof(void *));
- Now pass the newly allocated buffer to fill in:
- DMesaGetIntegerv(DMESA_GET_VIDEO_MODES, (GLint *)l);
- And collect the info:
- for (i = 0; i < n; i++) {
- printf("%dx%d:%d\n", l[i]->xres, l[i]->yres, l[i]->bpp);
- }
-
- Q) The GLUT is incomplete.
- A) See below.
-
-
-
-libGLUT (the toolkit):
-~~~~~~~~~~~~~~~~~~~~~~
-
-Well, this "skeletal" GLUT implementation was taken from AllegGL project and
-heavily changed. Thanks should go to Bernhard Tschirren, Mark Kilgard, Brian
-Paul and probably others (or probably not ;-). GLUT functionality will be
-extended only on an "as needed" basis.
-
-GLUT talks to hardware via PC_HW package which was put together from various
-pieces I wrote long time ago. It consists from the keyboard, mouse and timer
-drivers.
-
-My keyboard driver used only scancodes; as GLUT requires ASCII values for keys,
-I borrowed the translation tables (and maybe more) from Allegro -- many thanks
-to Shawn Hargreaves et co. Ctrl-Alt-Del (plus Ctrl-Alt-End, for Windows users)
-will shut down the GLUT engine unconditionally: it will raise SIGINT, which in
-turn will (hopefully) call the destructors, thus cleaning up your/my mess ;-)
-NB: since the DJGPP guys ensured signal handlers won't go beyond program's
-space (and since dynamic modules shall) the SIGINT can't be hooked (well, it
-can, but it is useless), therefore you must live with the 'Exiting due to
-signal SIGINT' message...
-
-The mouse driver is far from complete (lack of drawing, etc), but is enough to
-make almost all the demos work. Supports the CuteMouse WheelAPI.
-
-The timer is pretty versatile for it supports multiple timers with different
-frequencies. While not being the most accurate timer in the known universe, I
-think it's OK. Take this example: you have timer A with a very high rate, and
-then you have timer B with very low rate compared to A; now, A ticks OK, but
-timer B will probably loose precision!
-
-As an addition, stdout and stderr are redirected and dumped upon exit. This
-means that `printf' can be safely called during graphics. A bit of a hack, I
-know, because all messages come in bulk, but I think it's better than nothing.
-"Borrowed" from LIBRHUTI (Robert Hoehne).
-
-Window creating defaults: (0, 0, 300, 300), 16bpp. However, the video mode is
-chosen in such a way that first window will fit. If you need high resolution
-with small windows, set initial position far to the right (or way down); then
-you can move them back to any position right before the main loop.
-
-
-
-Environment variables:
-~~~~~~~~~~~~~~~~~~~~~~
- DMESA_NULDRV - (any value) force NUL driver
- GLUT_FPS - print frames/second statistics to stderr
- MESA_NO_SSE - (any value) safe option under pure DOS
- DMESA_GLUT_REFRESH - set vertical screen refresh rate (VESA3)
- DMESA_GLUT_BPP - set default bits per pixel (VGA needs 8)
- DMESA_GLUT_ALPHA - set default alpha bits (8)
- DMESA_GLUT_DEPTH - set default depth bits (16)
- DMESA_GLUT_STENCIL - set default stencil bits (8)
- DMESA_GLUT_ACCUM - set default accum bits (16)
-
-
-
-History:
-~~~~~~~~
-
-v1.0 (mar-2002)
- initial release
-
-v1.1 (sep-2002)
- + added 3dfx Glide3 support
- + added refresh rate control
- + added fonts in GLUT
- * lots of minor changes
-
-v1.2 (nov-2002)
- * synced w/ Mesa-4.1
- - removed dmesadxe.h
-
-v1.3 (mar-2003)
- + enabled OpenGL 1.4 support
- + added MMX clear/blit routines
- + enabled SGI's GLU compilation
- + added samples makefile
- + added new GLUT functions
- + added color-index modes
- + added Matrox Millennium MGA2064W driver
- + added 8bit FakeColor (thanks to Neil Funk)
- + added VGA support (to keep Ben Decker happy)
- ! fixed some compilation errors (reported by Chan Kar Heng)
- * optimized driver for faster callback access... yeah, right :)
- * overhauled virtual buffer and internal video drivers
- * better fxMesa integration
- * revamped GLUT
- * switched to DXE3
-
-v1.4 (dec-2003)
- + enabled GLUT fonts with DXE
- + truly added multi-window support in GLUT (for Adrian Woodward)
- * accomodated makefiles with the new sourcetree
- * fixed some ALPHA issues
- * minor changes to PC_HW/timer interface
- x hacked and slashed the 3dfx driver (w/ help from Hiroshi Morii)
-
-v1.5 (jan-2004)
- + added interface to query available "visuals" (GLFW - Marcus Geelnard)
- + added GLUT timer callback
- - removed Matrox Millennium MGA2064W driver
- x more changes to the 3dfx driver
-
-v1.6 (aug-2004)
- + implemented NUL driver
- + added DMesaGetProcAddress and glutGetProcAddress
- * reorganized fxMesa wrapper to handle multiple contexts
- ! fixed a horrible bug in VGA initialization routine
- ! fixed partial clears
-
-v1.7 (???-2005)
- + enabled OpenGL 2.0 support
- + added support for sw texture compression
- + added FreeGLUT specific functions
- * no more GLX sources in DOS GLUT
- * made GLUT timer callbacks less accurate but safer
-
-v1.8 (apr-2006)
- * killed lots of code, the driver is now a front-end to OSMesa
- * fixed problem with WinNT (http://www.volny.cz/martin.sulak/)
- - removed 3dfx Glide3 support (temporarily?)
-
-
-
-Contact:
-~~~~~~~~
-
-Name: Daniel Borca
-E-mail: dborca@users.sourceforge.net
-WWW: http://www.geocities.com/dborca/
diff --git a/mesalib/docs/README.GGI b/mesalib/docs/README.GGI
deleted file mode 100644
index ddb67725f..000000000
--- a/mesalib/docs/README.GGI
+++ /dev/null
@@ -1,26 +0,0 @@
-GGIMesa for LibGGI 2.x
-
-Requirements:
--------------
-LibGGI 2.0 or greater
-
-Installation:
--------------
-To install GGIMesa, follow the instructions in INSTALL.GNU. If you
-wish to install GGIGLUT as well, first install GGIMesa and then run
-
-make
-make install (must be root)
-
-in ggi/ggiglut.
-
-Notes:
-------
-
-* Set the environment variables GGIMESA_DEBUG and/or GGIGLUT_DEBUG
-to 255 to see lots of debugging output.
-
-* GGIGLUT contains support for all of the GLUT 3.6 API except for the
-high-level primitive drawing functions, but many of the functions (in
-particular the menu drawing functions) are just stubs.
-
diff --git a/mesalib/docs/README.LYNXOS b/mesalib/docs/README.LYNXOS
deleted file mode 100644
index e3ab9804b..000000000
--- a/mesalib/docs/README.LYNXOS
+++ /dev/null
@@ -1,64 +0,0 @@
-
-Mesa 3.0 for LynxOS builds in the following way:
-
-make lynxos
-
-This will build all the libraries and demo applications. You should have
-around 400 megabytes free for everything since everything is done with
-static
-libraries.
-
-Before using this make file however, you should perform the following
-actions:
-0) cd to the Mesa-3.0 directory
-1) Copy the GL directory under the include directory to /usr/include.
-2) Copy the files in the lib directory to /lib.
-3) Make links so that the Mesa libraries look like ordinary OpenGL
-libraries
-in /lib. This is important for compatibility with other OpenGL apps. This
-is done as follows:
-
-cd /lib
-ln -s libMesaGL.a libGL.a
-ln -s libMesaGLU.a libGLU.a
-
-Mesa 3.0 includes the GLUT (GL Utility Toolkit) by default.
-The demo applications are done using this toolkit.
-
-Mesa makefiles for building their apps could be used as well, but the
-following one is much more concise. Note that the order of the X libraries
-is important to the linker so that all symbols get resolved correctly.
-Changing the order may result in having to list a library twice to make
-sure all linkages are made correctly.
-
-----cut here for Makefile -----
-
-FILES = your_app.x
-
-SPECIAL_INCLUDES = -I/usr/include/GL
-
-SPECIAL_CFLAGS = -g -ansi -pedantic -funroll-loops -ffast-math -DSHM
-
-SPECIAL_LIBS = -lglut -lGLU -lGL -lm -L/usr/X11/lib -lXext -lXmu -lXi \
--lX11 -lbsd -g
-
-STANDARD_OFILES = $(FILES:.x=.o)
-
-%.o: %.c
- gcc -c $(SPECIAL_CFLAGS) $(SPECIAL_INCLUDES) $< -o $@
-
-all: $(STANDARD_OFILES)
- gcc -o your_app $(STANDARD_OFILES) $(SPECIAL_LIBS)
-
-
-----cut here for Makefile-----
-
-I have tested Mesa under LynxOS 3.0 and 3.01. It should build fine under
-other
-versions as well. Note, however, that LynxOS versions prior to 3.0 are not
-binary compatible, so you will have to rebuild from source.
-
-
-Vik Sohal
-vik@lynx.com
-January 13, 1999
diff --git a/mesalib/docs/README.NeXT b/mesalib/docs/README.NeXT
deleted file mode 100644
index 1ad9a9e5c..000000000
--- a/mesalib/docs/README.NeXT
+++ /dev/null
@@ -1,6 +0,0 @@
-The NeXT support has now been incorporated into the OpenStep support.
-You can build NeXT libraries simply by typing "make next", though before
-linking they will need to be ranlib'd by hand. For more information see
-the README.OpenStep file, together with the README files in OpenStep/Old_Demos.
-
--Pete French. (pete@ohm.york.ac.uk) 28/5/1998
diff --git a/mesalib/docs/README.OS2 b/mesalib/docs/README.OS2
deleted file mode 100644
index b3374ea23..000000000
--- a/mesalib/docs/README.OS2
+++ /dev/null
@@ -1,96 +0,0 @@
- README for port of Mesa 3.x to XFree86 on OS/2 (X/2)
- (as of 19990514)
-
-
- Contents:
-
- 1) Binary release
- 2) Building from sources
- 3) History
- 4) Todo
- 5) Mesa Home Page
-
-
-1) Binary release
-
- Though the Mesa sources should build in a quite reasonable time even on
- a 585 class machine a binary relase is available (check topic 4) for an URL)
- This package includes:
-
- - lib/MesaGL.dll, MesaGL.a
- - lib/MesaGLU.dll, MesaGLU.a
- - lib/glut.dll, glut.a
- - include/GL/*.h
-
- Installing this in your XFree86 tree will enable you to build and
- run all applications compatible with Mesa (and the current DLL
- interface, of course ;-)
- As usual the OMF-style libraries can be created using emxomf.
- (e.g. "emxomf foo.a" creates the foo.lib omf-style library).
- The static libraries are rarely used and you have to rebuild
- Mesa to get them. They're a supported target, so you get
- them in a straightforward way (see below).
-
- The testing of these libraries was limited to the supplied
- demos/examples and a quite small number of third-party apps.
- No warranty ... as usual ... ;-)
-
-
-2) Instructions to build Mesa 3.x for XFree86/OS2 from sources:
-
- Except the official Mesa source distribution you need:
- - a recent version of XFree86 (3.3.x or above) including
- the programming libraries
- - EMX 0.9c (0.9d might work, never checked)
- - GNU make
- - REXX (!)
-
- The creation of the DLLs as well as of the static libraries
- (if you want to have them) is handled in "mklib-emx.cmd",
- a small REXX script. Perhaps not the best idea, but this
- way it fits best in the scheme used to build libraries
- on all platforms in Mesa 3.x.
-
- To actually build the libraries and demos, check mklib-emx.cmd
- and modify it as desired. Then type
- make os2-x11
- and wait for completion ;-)
-
-
-3) History
-
- Initially Darren Abbott (abbott@hiwaay.net) ported Mesa versions 2.x
- to XFree86 OS/2. This port might still be available from
- http://fly.HiWAAY.net/~abbott/xfree86-os2/xfree86.html
-
- The current port picked up things during the beta test for 3.0.
- No major changes in the source were done. The build mechanism under OS/2
- has been made very similar to other platforms (if you treat mklib-emx.cmd
- as a "black box").
- Advantage is that X/2 is now a valid target and all files are
- integrated in the official source distribution.
- Disadvantage is that this port (i.e. the DLLs' interface itself) is
- definitly NOT COMPATIBLE to those of version 2.x.
- It's uncertain whether this would be at all possible but since there
- a _very_ few those apps it's not worth to find out anyway.
- Also some libs (MesaTK, MesaAUX) are withdrawn from the Mesa distribution,
- and accordingly from the OS/2 port.
-
-4) Todo
-
- By now binary compatiblity is ensured by using the function names
- as entry points instead of ordinals. This might cost performance and
- is subject to change in future. In addition the supplied X86 assembler
- source is not used yet.
-
-5) Mesa Home Page
-
- You can get the source code and more information about Mesa from
- http://www.mesa3d.org/
-
- The OS/2 ports should be available from
- http://r350.ee.ntu.edu.tw/~hcchu/os2/ports
-
---
-Alexander Mai
-st002279@hrzpub.tu-darmstadt.de
diff --git a/mesalib/docs/README.OpenStep b/mesalib/docs/README.OpenStep
deleted file mode 100644
index a566eca67..000000000
--- a/mesalib/docs/README.OpenStep
+++ /dev/null
@@ -1,35 +0,0 @@
-This is a port of the GL and GLU libraries to NeXT/Apple object
-orientated systems. As these systems have their own window handling
-systems we simply use the offscreen rendering capability of Mesa
-to generate bitmaps which may then be displayed by the application
-with a View as required. Example pieces of code may be found in the
-OpenStep directory.
-
-Sadly there are now a proliferation of different system that we need to
-support compilation for: The original NextStep system, The OpenStep
-system, the Rhapsody/Mac OS X system and also the windows implementations
-of the latter two systems. This version of the code has been compiled and
-tested under the following architectures:
-
- NextStep 3.3
- OpenStep 4.2
- Rhapsody DR2
- WebObjects for NT 3.5
- WebObjects for NT 4.0
-
-All tests were done with Intel processors. Feedback on other systems would,
-however, be appreciated !
-
-On UNIX systems simply type "make openstep". Under Windows systems
-with WebObjects run the "win32-openstep.sh" script from within the Bourne
-shell provided with the development environment. In both cases this will
-build the libraries and place them into the "lib" directory. Some examples
-may be found in the OpenStep directory showing how to use the code in an
-actual application (MesaView) as well as some command line demos.
-
-The CC variable may be specified on the command line for doing such things
-as building FFAT libraries or using alternative compilers to the standard 'cc'
-e.g. make CC='cc -arch m68k -arch i386' openstep" will build the libraries
-with both intel and motorola architectures.
-
--Pete French. (pete@ohm.york.ac.uk) 7/6/1999
diff --git a/mesalib/docs/README.WINDML b/mesalib/docs/README.WINDML
deleted file mode 100644
index 448db71f8..000000000
--- a/mesalib/docs/README.WINDML
+++ /dev/null
@@ -1,146 +0,0 @@
-
- WindML Driver for Mesa 4.0
-
-
-Requirements
-------------
-
-Tornado 2 + WindML, Cumulative Patchs are recommended.
-
-I suppose you have a valid WindML installation. Double buffer hardware
-gives better performance than double buffer software so if you can
-compile your WindML driver with this option, just do it. I/O
-redirection is adviced in target server.
-
-
-Tested on
----------
-
-During the development, my main target was a CoolMonster:
-- Video card: CT69000
-- CPU: PENTIUM 266MHz
-
-and my host a Windows NT + Tornado 2.
-
-
-Installation
-------------
-
-1. Mesa sources must be in root directory (C:\)
-
-2. Add the following line to your torVars.bat:
-set MESA_BASE=C:\Mesa
-
-OR copy the new torVars.bat in your bin path:
-c:/Mesa/src/ugl/tornado/torVars.sample ->
-/mnt/nt/Tornado/host/x86-win32/bin/torVars (for example)
-
-3. In a command prompt:
-$ torVars
-$ cd c:\Mesa
-$ make -f Makefile.ugl CPU=PENTIUM
-
-Take a long while...
-
-5. Include all the files from ugldemos folder to build some downloadable
- application modules
-
-4. Download UGL/Mesa object files on target
-
-For example via the WindShell:
-ld < c:\Tornado\target\lib\objMesaGL.o
-ld < c:\Tornado\target\lib\objMesaUGL.o
-ld < c:\Tornado\target\lib\objMesaGLU.o
-ld < c:\Tornado\target\lib\objGLUTshapes.o
-ld < c:\Tornado\target\lib\objMesaOS.o
-
-You can put the previous lines in a file and use:
-< filename
-
-6. Download the application modules.
-
-7. In WindShell, run:
--> uglalldemos
-
-During the show some messages will appear, it provides some useful
-information on key management.
-
-
-Coding
-------
-
-Sample Usage:
-
-In addition to the usual ugl calls to initialize UGL, (may be find an
-input driver), you must do the following to use the UGL/Mesa interface:
-
-1. Call uglMesaCreateContext() to create a UGL/Mesa rendering context,
- given the display format.
-
-2. Call uglMesaMakeCurrent() to bind the UGL/Mesa buffers to an
- UGL/Mesa Context and to make the context the current one.
-
-3. Make gl* calls to render your graphics.
-
-4. Use uglMesaSwapBuffers() when double buffering to swap front/back buffers.
-
-5. Before the UGL is destroyed, call MesaDestroyContext().
-
-6. Before exiting, call if required uglEventQDestroy and then
- uglDeinitialize();
-
-Limitations
------------
-
-I found the following limitations in my driver :
- - Color Indexed management is only in 8 bits
- - It's possible to mix UGL/OpenGL application with a software
- double buffer
-
-Modifications
-------------
-
-New files in Mesa:
-- Makefile.ugl
-- rules.windmlmesa
-- docs/README.UGL
-- include/GL/uglmesa.h
-- si-glu/Makefile.ugl
-- src/Makefile.ugl
-- src/ugl/torGLUTShapesInit.c
-- src/ugl/torMesaUGLInit.c
-- src/ugl/ugl_api.c
-- src/ugl/ugl_dd.c
-- src/ugl/ugl_glutshapes.c
-- src/ugl/ugl_line.c
-- src/ugl/ugl_span.c
-- src/ugl/ugl_tri.c
-- src/ugl/uglmesaP.h
-- ugldemos/*
-
-Modified files in Tornado 2.0:
-- c:\Tornado\host\x86-win32\bin\torVars.bat
-rem Command line build environments
-set WIND_HOST_TYPE=x86-win32
-set WIND_BASE=C:\Tornado
-set MESA_BASE=C:\Mesa
-set PATH=%WIND_BASE%\host\%WIND_HOST_TYPE%\bin;%PATH%
-- c:\Tornado\target\config\comps\VxWorks\01uglmesa.cdf
-- c:\Tornado\target\h\GL\*
-
-Todo
-----
-- GCC 2.96, ASM compilation
-
-Thanks to:
-----------
-
-Precision Insight team for their great job around Mesa, XFree, and DRI.
-Wind River Systems to take me as an intern.
-
-
-Stephane Raimbault
-<stephane.raimbault@windriver.com>
-<stephane.raimbault@deesse.univ-lemans.fr>
-
-July 24, 2001
diff --git a/mesalib/docs/games.html b/mesalib/docs/games.html
index dcf5cf2d0..82e3d09a4 100644
--- a/mesalib/docs/games.html
+++ b/mesalib/docs/games.html
@@ -29,7 +29,6 @@
simulator
</li><li><a href="http://freetrek.linuxgames.com/" target="_parent">Free Trek</a> - Star
Trek battle simulator
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html">Gepetto</a> - Dance Choreography
</li><li><a href="http://glchess.sourceforge.net/" target="_parent">GLChess</a> - chess game
</li><li><a href="http://heretic.linuxgames.com/" target="_parent">GLHeretic</a> - Heretic
for Linux
@@ -61,4 +60,4 @@
</li></ul>
-</body></html> \ No newline at end of file
+</body></html>
diff --git a/mesalib/docs/libraries.html b/mesalib/docs/libraries.html
index eaeb0451a..1c425cf1b 100644
--- a/mesalib/docs/libraries.html
+++ b/mesalib/docs/libraries.html
@@ -47,11 +47,10 @@ Open SG PLUS</a> - a scene-graph library
<li><a href="http://sgl.sourceforge.net/" target="_parent">SGL</a> - a 3D Scene Graph Library
<li><a href="http://www.lal.in2p3.fr/SI/SoFree/" target="_parent">SoFree</a> - a free implementation of Open Inventor
<li><a href="http://togl.sourceforge.net/" target="_parent">Togl</a> - Tcl/Tk widget for OpenGL
-<li><a href="http://mesa3d.sourceforge.net/notfound.html">VLE</a> - Virtual Reality Toolkit
<li><a href="http://www.int.com/" target="_parent">View3D Widget</a> - 3-D GUI widget
<li><a href="http://www.vtk.org/" target="_parent">VTK</a> - Visualization Toolkit
<li><a href="http://home.earthlink.net/%7Erzeh/YAJOGLB/doc/YAJOGLB.html" target="_parent">YAJOGL</a> - Yet Another Java GL Binding.
</ul>
-</body></html> \ No newline at end of file
+</body></html>
diff --git a/mesalib/docs/lists.html b/mesalib/docs/lists.html
index 148789153..033b0b70a 100644
--- a/mesalib/docs/lists.html
+++ b/mesalib/docs/lists.html
@@ -37,6 +37,13 @@ versions are sent to this list. Very low traffic.
</ul>
<p>
+<b>NOTE</b>: You <b>must</b> subscribe to these lists in order to post to them.
+If you try to post to a list and you're not a subscriber (or if you try to post
+from a different email address than you subscribed with) your posting will be
+held for an indefinite period or may be discarded entirely.
+</p>
+
+<p>
Follow the links above for list archives.
</p>
@@ -55,10 +62,6 @@ kernels, see the
DRI wiki</a>.
</p>
-<p>
-<b>Notice</b>: You must subscribe to these lists in order to post to them.
-</p>
-
<br>
diff --git a/mesalib/docs/modelers.html b/mesalib/docs/modelers.html
index aae968695..2e90a5268 100644
--- a/mesalib/docs/modelers.html
+++ b/mesalib/docs/modelers.html
@@ -11,7 +11,6 @@
<ul>
<li><a href="http://www.aqsis.org/" target="_parent">Aqsis</a> - a RenderMan compatible renderer</li>
<li><a href="http://www.ac3d.org/" target="_parent">AC3D</a> - 3-D modeler
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html">ARCAD</a> - CAD program
</li><li><a href="http://www.mediascape.com/" target="_parent">Artstream</a> - provides
functionality like Corel Draw and Illustrator
</li><li><a href="http://www.blender.org/" target="_parent">Blender</a> - 3-D animation
@@ -27,7 +26,6 @@
exploration
</li><li><a href="http://innovation3d.sourceforge.net/" target="_parent">Innovation3D</a>
- 3D modeling program
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html" target="_parent">KWRL</a> - VRML browser
</li><li><a href="http://www.openvrml.org/" target="_parent">LibVRML97/Lookat</a>
- VRML viewer
</li><li><a href="http://aig.cs.man.ac.uk/systems/Maverik/" target="_parent">Maverik</a>
@@ -40,7 +38,6 @@
3D</a> - 3D modeler/animator
</li><li><a href="http://mindseye.sourceforge.net/" target="_parent">Mindseye</a> - Rendering/Modeling
Package
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html">Moonlight Atelier</a> - modeling and rendering package
</li><li><a href="http://www.neuralvr.com/" target="_parent">Pansophica</a> - Virtual Reality web organizer
</li><li><a href="http://www.sim.no/reducer.html" target="_parent">Rational Reducer</a>
- polygon reduction tool
@@ -52,14 +49,12 @@
- inside-out sphere visualization
</li><li><a href="http://www.cs.kuleuven.ac.be/cwis/research/graphics/3DOM/" target="_parent">3Dom</a>
- 3-D modeler
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html">3D Studio file viewer</a> - by David Farrell
</li><li><a href="http://www.microform.se/" target="_parent">VARKON</a> - product engineering,
design, modeling
</li><li><a href="http://www.sim.no/vrmlview.html" target="_parent">VRMLview</a> - VRML
model viewer
</li><li><a href="http://www.iicm.edu/vrwave/" target="_parent">VRWave</a> - a VRML 2.0
browser
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html">VRweb</a> - VRML browser
</li><li><a href="http://www.csv.ica.uni-stuttgart.de/vrml/dune/" target="_parent">white_dune</a>
- graphical VRML97 Editor and animation tool
</li></ul>
diff --git a/mesalib/docs/relnotes-7.12.html b/mesalib/docs/relnotes-7.12.html
new file mode 100644
index 000000000..ac20788ef
--- /dev/null
+++ b/mesalib/docs/relnotes-7.12.html
@@ -0,0 +1,64 @@
+<HTML>
+
+<head>
+<TITLE>Mesa Release Notes</TITLE>
+<link rel="stylesheet" type="text/css" href="mesa.css">
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+</head>
+
+<BODY>
+
+<body bgcolor="#eeeeee">
+
+<H1>Mesa 7.12 Release Notes / (release date TBD)</H1>
+
+<p>
+Mesa 7.12 is a new development release.
+People who are concerned with stability and reliability should stick
+with a previous release or wait for Mesa 7.12.1.
+</p>
+<p>
+Mesa 7.12 implements the OpenGL 2.1 API, but the version reported by
+glGetString(GL_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 2.1.
+</p>
+<p>
+See the <a href="install.html">Compiling/Installing page</a> for prerequisites
+for DRI hardware acceleration.
+</p>
+
+
+<h2>MD5 checksums</h2>
+<pre>
+tbd
+</pre>
+
+
+<h2>New features</h2>
+<ul>
+</ul>
+
+
+<h2>Bug fixes</h2>
+<ul>
+</ul>
+
+
+<h2>Changes</h2>
+<ul>
+<li>Removed all DRI drivers that did not support DRI2. Specifically,
+ i810, mach64, mga, r128, savage, sis, tdfx, and unichrome were
+ removed.</li>
+<li>Removed support for BeOS.</li>
+<li>Removed the obsolete (and unmaintained) Windows "gldirect" and
+ "ICD" drivers.</li>
+<li>Removed the linux-fbdev software driver.</li>
+<li>Removed all remnants of paletted texture support. As required by
+ desktop OpenGL, <tt>GL_COLOR_INDEX</tt> data can still be uploaded
+ to a color (e.g., RGBA) texture. However, the data cannot be stored
+ internally as color-index.</li>
+</ul>
+
+
+</body>
+</html>
diff --git a/mesalib/docs/relnotes.html b/mesalib/docs/relnotes.html
index e1f0c3299..7e02172ed 100644
--- a/mesalib/docs/relnotes.html
+++ b/mesalib/docs/relnotes.html
@@ -13,6 +13,7 @@ The release notes summarize what's new or changed in each Mesa release.
</p>
<UL>
+<LI><A HREF="relnotes-7.12.html">7.12 release notes</A>
<LI><A HREF="relnotes-7.11.html">7.11 release notes</A>
<LI><A HREF="relnotes-7.10.3.html">7.10.3 release notes</A>
<LI><A HREF="relnotes-7.10.2.html">7.10.2 release notes</A>
diff --git a/mesalib/docs/science.html b/mesalib/docs/science.html
index f55cf3124..0b3384303 100644
--- a/mesalib/docs/science.html
+++ b/mesalib/docs/science.html
@@ -10,7 +10,6 @@
<ul>
<li><a href="http://www.softintegration.com/products/toolkit/opengl/" target="_parent">Ch</a> - OpenGL bindings for the Ch C/C++ interpreter
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html">CLEO3D</a> - event displayer for the CLEOIII detector
</li><li><a href="http://www.bioz.unibas.ch/%7Exray/dino/" target="_parent">DINO</a> - Visualizing
Structural Biology
</li><li><a href="http://www-xdiv.lanl.gov/XCM/gmv/GMVHome.html" target="_parent">General
@@ -34,7 +33,7 @@
- a real-time, interactive relativistic simulator
</li><li><a href="http://linkwinds.jpl.nasa.gov/" target="_parent">LinkWinds</a> - scientific
vis
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html" target="_parent">MathGL3d</a> - Mathematica viewer
+ </li><li><a href="http://phong.informatik.uni-leipzig.de/~kuska/mathgl3dv3/index.htm" target="_parent">MathGL3d</a> - Mathematica viewer
</li><li><a href="http://www.mathworks.com/products/matlab" target="_parent">Mathworks</a>
- mathematics and visualization
</li><li><a href="http://www-rocq.inria.fr/gamma/medit/medit.html" target="_parent">Medit</a> - 3D surface mesh viewer
@@ -50,7 +49,6 @@
</li>
<li><a href="http://www.paraview.org/" target="_parent">ParaView</a> - Scientific visualization package
</li>
- <li><a href="http://mesa3d.sourceforge.net/notfound.html">PHLEX</a> - Finite element vis
</li><li><a href="http://root.cern.ch/" target="_parent">ROOT</a> - Object Oriented Data
Analysis Framework
</li><li><a href="http://www.slffea.com/" target="_parent">SLFFEA</a> - GNU finite element
@@ -59,7 +57,6 @@
modeling
</li><li><a href="http://www1.las.es/%7Eamil/ssystem" target="_parent">Ssystem</a> - solar
system simulation
- </li><li><a href="http://mesa3d.sourceforge.net/notfound.html">SPARROW</a> - robot simulation
</li><li><a href="http://www.ssec.wisc.edu/%7Ebillh/vis5d.html" target="_parent">Vis5D</a>
- atmospheric visualization
</li><li><a href="http://www.ks.uiuc.edu/Research/vmd/" target="_parent">VMD</a> - molecular
@@ -69,4 +66,4 @@
</li></ul>
-</body></html> \ No newline at end of file
+</body></html>
diff --git a/mesalib/docs/systems.html b/mesalib/docs/systems.html
index 03db779a1..035a48962 100644
--- a/mesalib/docs/systems.html
+++ b/mesalib/docs/systems.html
@@ -38,32 +38,5 @@ and Unix-like operating systems
<LI>DEC VMS <A HREF="README.VMS">(README.VMS)</A>
</UL>
-
-<h2>Deprecated Systems</h2>
-
-<p>
-These drivers have not been maintained and are being deprecated.
-They can be saved if someone steps up to help.
-</p>
-
-<UL>
-<LI>3dfx/Glide <A HREF="README.3DFX">(README.3DFX)</A>
-<LI>GGI <A HREF="README.GGI">(README.GGI)</A>
-<LI>Amiga Amiwin <A HREF="README.AMIWIN">(README.AMIWIN)</A>
-<LI>Direct3D driver <A HREF="README.D3D">(README.D3D)</A>
-<LI>DJGPP <A HREF="README.DJ">(README.DJ)</A>
-<LI>LynxOS <A HREF="README.LYNXOS">(README.LYNXOS)</A>
-<LI>Mingw32 <A HREF="README.MINGW32">(README.MINGW32)</A>
-<LI>NeXT <A HREF="README.NeXT">(README.NeXT)</A>
-<LI>OpenStep <A HREF="README.OpenStep">(README.OpenStep)</A>
-<LI>OS/2 <A HREF="README.OS2">(README.OS2)</A>
-<LI>WindML <A HREF="README.WINDML">(README.WINDML)</A>
-</UL>
-
-And for historical reference:
-<UL>
-<LI><a href="http://utah-glx.sourceforge.net/" target="_parent">Utah GLX drivers</a>
-</UL>
-
</body>
</html>
diff --git a/mesalib/docs/utility.html b/mesalib/docs/utility.html
index c7cad0114..dfb4a909f 100644
--- a/mesalib/docs/utility.html
+++ b/mesalib/docs/utility.html
@@ -25,9 +25,6 @@
<li><a href="http://threedsia.sourceforge.net/"
target="_parent">3Dsia</a> - 3D user interface
-<li><a href="http://mesa3d.sourceforge.net/notfound.html">VRML Site
-Map</a> - 3D GUI
-
<li><a href="http://www.vros.com/" target="_parent">VR/OS</a> - VR
user interface
diff --git a/mesalib/include/GL/glfbdev.h b/mesalib/include/GL/glfbdev.h
deleted file mode 100644
index 452a643a4..000000000
--- a/mesalib/include/GL/glfbdev.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 1999-2005 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 GLFBDEV_H
-#define GLFBDEV_H
-
-
-/* for size_t */
-#include <stdlib.h>
-
-/* avoid including linux/fb.h */
-struct fb_fix_screeninfo;
-struct fb_var_screeninfo;
-
-
-/* public types */
-typedef struct GLFBDevVisualRec *GLFBDevVisualPtr;
-typedef struct GLFBDevBufferRec *GLFBDevBufferPtr;
-typedef struct GLFBDevContextRec *GLFBDevContextPtr;
-
-
-/* API version */
-#define GLFBDEV_VERSION_1_0 1
-
-
-/* For glFBDevCreateVisual */
-#define GLFBDEV_DOUBLE_BUFFER 100
-#define GLFBDEV_COLOR_INDEX 101
-#define GLFBDEV_DEPTH_SIZE 102
-#define GLFBDEV_STENCIL_SIZE 103
-#define GLFBDEV_ACCUM_SIZE 104
-#define GLFBDEV_LEVEL 105
-#define GLFBDEV_MULTISAMPLE 106
-#define GLFBDEV_NONE 0
-
-/* For glFBDevGetString */
-#define GLFBDEV_VERSION 200
-#define GLFBDEV_VENDOR 201
-
-
-/* Misc functions */
-
-extern const char *
-glFBDevGetString( int str );
-
-
-typedef void (*GLFBDevProc)();
-
-
-extern GLFBDevProc
-glFBDevGetProcAddress( const char *procName );
-
-
-
-/**
- * Create a GLFBDevVisual.
- * \param fixInfo - needed to get the visual types, etc.
- * \param varInfo - needed to get the bits_per_pixel, etc.
- * \param attribs - for requesting depth, stencil, accum buffers, etc.
- */
-extern GLFBDevVisualPtr
-glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
- const struct fb_var_screeninfo *varInfo,
- const int *attribs );
-
-extern void
-glFBDevDestroyVisual( GLFBDevVisualPtr visual );
-
-extern int
-glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual, int attrib);
-
-
-
-/**
- * Create a GLFBDevBuffer.
- * \param fixInfo, varInfo - needed in order to get the screen size
- * (resolution), etc.
- * \param visual - as returned by glFBDevCreateVisual()
- * \param frontBuffer - address of front color buffer
- * \param backBuffer - address of back color buffer (may be NULL)
- * \param size - size of the color buffer(s) in bytes.
- */
-extern GLFBDevBufferPtr
-glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
- const struct fb_var_screeninfo *varInfo,
- const GLFBDevVisualPtr visual,
- void *frontBuffer, void *backBuffer, size_t size );
-
-extern void
-glFBDevDestroyBuffer( GLFBDevBufferPtr buffer );
-
-extern int
-glFBDevGetBufferAttrib( const GLFBDevBufferPtr buffer, int attrib);
-
-extern GLFBDevBufferPtr
-glFBDevGetCurrentDrawBuffer( void );
-
-extern GLFBDevBufferPtr
-glFBDevGetCurrentReadBuffer( void );
-
-extern void
-glFBDevSwapBuffers( GLFBDevBufferPtr buffer );
-
-
-
-/**
- * Create a GLFBDevContext.
- * \param visual - as created by glFBDevCreateVisual.
- * \param share - specifies another context with which to share textures,
- * display lists, etc. (may be NULL).
- */
-extern GLFBDevContextPtr
-glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share );
-
-extern void
-glFBDevDestroyContext( GLFBDevContextPtr context );
-
-extern int
-glFBDevGetContextAttrib( const GLFBDevContextPtr context, int attrib);
-
-extern GLFBDevContextPtr
-glFBDevGetCurrentContext( void );
-
-extern int
-glFBDevMakeCurrent( GLFBDevContextPtr context,
- GLFBDevBufferPtr drawBuffer,
- GLFBDevBufferPtr readBuffer );
-
-
-#endif /* GLFBDEV_H */
diff --git a/mesalib/scons/crossmingw.py b/mesalib/scons/crossmingw.py
index 949fc4fb1..893002f64 100644
--- a/mesalib/scons/crossmingw.py
+++ b/mesalib/scons/crossmingw.py
@@ -225,14 +225,6 @@ def generate(env):
# default in recent gcc versions
env.AppendUnique(CCFLAGS = ['-gstabs'])
- env.AppendUnique(CPPDEFINES = [('__MSVCRT_VERSION__', '0x0700')])
- #env.AppendUnique(LIBS = ['iberty'])
- env.AppendUnique(SHLINKFLAGS = ['-Wl,--enable-stdcall-fixup'])
- #env.AppendUnique(SHLINKFLAGS = ['-Wl,--kill-at'])
-
- # Avoid depending on gcc runtime DLLs
- env.AppendUnique(LINKFLAGS = ['-static-libgcc'])
-
env.AddMethod(compile_without_gstabs, 'compile_without_gstabs')
def exists(env):
diff --git a/mesalib/scons/gallium.py b/mesalib/scons/gallium.py
index 7135251d7..dc77904f0 100644
--- a/mesalib/scons/gallium.py
+++ b/mesalib/scons/gallium.py
@@ -279,6 +279,8 @@ def generate(env):
('_WIN32_WINNT', '0x0601'),
('WINVER', '0x0601'),
]
+ if gcc:
+ cppdefines += [('__MSVCRT_VERSION__', '0x0700')]
if msvc and env['toolchain'] != 'winddk':
cppdefines += [
'VC_EXTRALEAN',
@@ -532,6 +534,14 @@ def generate(env):
pass
else:
env['_LIBFLAGS'] = '-Wl,--start-group ' + env['_LIBFLAGS'] + ' -Wl,--end-group'
+ if env['platform'] == 'windows':
+ # Avoid depending on gcc runtime DLLs
+ linkflags += ['-static-libgcc']
+ if env['machine'] == 'x86_64':
+ linkflags += ['-static-libstdc++']
+ # Handle the @xx symbol munging of DLL exports
+ shlinkflags += ['-Wl,--enable-stdcall-fixup']
+ #shlinkflags += ['-Wl,--kill-at']
if msvc:
if env['build'] == 'release':
# enable Link-time Code Generation
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index 22009eebc..2d0bccb78 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -777,7 +777,7 @@ ir_reader::read_constant(s_expression *expr)
ir_constant_data data = { { 0 } };
// Read in list of values (at most 16).
- int k = 0;
+ unsigned k = 0;
foreach_iter(exec_list_iterator, it, values->subexpressions) {
if (k >= 16) {
ir_read_error(values, "expected at most 16 numbers");
@@ -820,6 +820,11 @@ ir_reader::read_constant(s_expression *expr)
}
++k;
}
+ if (k != type->components()) {
+ ir_read_error(values, "expected %u constant values, found %u",
+ type->components(), k);
+ return NULL;
+ }
return new(mem_ctx) ir_constant(type, &data);
}
diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c
index 78caa0542..6484d284d 100644
--- a/mesalib/src/mesa/drivers/common/driverfuncs.c
+++ b/mesalib/src/mesa/drivers/common/driverfuncs.c
@@ -118,11 +118,6 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->UnmapTexture = NULL;
driver->TextureMemCpy = memcpy;
driver->IsTextureResident = NULL;
- driver->UpdateTexturePalette = NULL;
-
- /* imaging */
- driver->CopyColorTable = _mesa_meta_CopyColorTable;
- driver->CopyColorSubTable = _mesa_meta_CopyColorSubTable;
/* Vertex/fragment programs */
driver->BindProgram = NULL;
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index 291d91212..ad04d369f 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -2939,58 +2939,3 @@ _mesa_meta_CopyTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
copy_tex_sub_image(ctx, 3, target, level, xoffset, yoffset, zoffset,
x, y, width, height);
}
-
-
-void
-_mesa_meta_CopyColorTable(struct gl_context *ctx,
- GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width)
-{
- GLfloat *buf;
-
- buf = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
- if (!buf) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorTable");
- return;
- }
-
- /*
- * Read image from framebuffer (disable pixel transfer ops)
- */
- _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE | MESA_META_PIXEL_TRANSFER);
- ctx->Driver.ReadPixels(ctx, x, y, width, 1,
- GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
-
- _mesa_ColorTable(target, internalformat, width, GL_RGBA, GL_FLOAT, buf);
-
- _mesa_meta_end(ctx);
-
- free(buf);
-}
-
-
-void
-_mesa_meta_CopyColorSubTable(struct gl_context *ctx,GLenum target, GLsizei start,
- GLint x, GLint y, GLsizei width)
-{
- GLfloat *buf;
-
- buf = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
- if (!buf) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorSubTable");
- return;
- }
-
- /*
- * Read image from framebuffer (disable pixel transfer ops)
- */
- _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE | MESA_META_PIXEL_TRANSFER);
- ctx->Driver.ReadPixels(ctx, x, y, width, 1,
- GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
-
- _mesa_ColorSubTable(target, start, width, GL_RGBA, GL_FLOAT, buf);
-
- _mesa_meta_end(ctx);
-
- free(buf);
-}
diff --git a/mesalib/src/mesa/drivers/common/meta.h b/mesalib/src/mesa/drivers/common/meta.h
index ac20e370e..9a92613c4 100644
--- a/mesalib/src/mesa/drivers/common/meta.h
+++ b/mesalib/src/mesa/drivers/common/meta.h
@@ -121,24 +121,4 @@ _mesa_meta_CopyTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
GLint x, GLint y,
GLsizei width, GLsizei height);
-extern void
-_mesa_meta_CopyColorTable(struct gl_context *ctx,
- GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width);
-
-extern void
-_mesa_meta_CopyColorSubTable(struct gl_context *ctx,GLenum target, GLsizei start,
- GLint x, GLint y, GLsizei width);
-
-extern void
-_mesa_meta_CopyConvolutionFilter1D(struct gl_context *ctx, GLenum target,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width);
-
-extern void
-_mesa_meta_CopyConvolutionFilter2D(struct gl_context *ctx, GLenum target,
- GLenum internalFormat, GLint x, GLint y,
- GLsizei width, GLsizei height);
-
-
#endif /* META_H */
diff --git a/mesalib/src/mesa/main/colortab.c b/mesalib/src/mesa/main/colortab.c
index ddb0f1f65..f20dee677 100644
--- a/mesalib/src/mesa/main/colortab.c
+++ b/mesalib/src/mesa/main/colortab.c
@@ -41,361 +41,14 @@
#if FEATURE_colortable
-
-/**
- * Given an internalFormat token passed to glColorTable,
- * return the corresponding base format.
- * Return -1 if invalid token.
- */
-static GLint
-base_colortab_format( GLenum format )
-{
- switch (format) {
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- return GL_ALPHA;
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- return GL_LUMINANCE;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- return GL_LUMINANCE_ALPHA;
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- return GL_INTENSITY;
- case GL_RGB:
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- return GL_RGB;
- case GL_RGBA:
- case GL_RGBA2:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- return GL_RGBA;
- default:
- return -1; /* error */
- }
-}
-
-
-
-/**
- * Examine table's format and set the component sizes accordingly.
- */
-static void
-set_component_sizes( struct gl_color_table *table )
-{
- /* assuming the ubyte table */
- const GLubyte sz = 8;
-
- switch (table->_BaseFormat) {
- case GL_ALPHA:
- table->RedSize = 0;
- table->GreenSize = 0;
- table->BlueSize = 0;
- table->AlphaSize = sz;
- table->IntensitySize = 0;
- table->LuminanceSize = 0;
- break;
- case GL_LUMINANCE:
- table->RedSize = 0;
- table->GreenSize = 0;
- table->BlueSize = 0;
- table->AlphaSize = 0;
- table->IntensitySize = 0;
- table->LuminanceSize = sz;
- break;
- case GL_LUMINANCE_ALPHA:
- table->RedSize = 0;
- table->GreenSize = 0;
- table->BlueSize = 0;
- table->AlphaSize = sz;
- table->IntensitySize = 0;
- table->LuminanceSize = sz;
- break;
- case GL_INTENSITY:
- table->RedSize = 0;
- table->GreenSize = 0;
- table->BlueSize = 0;
- table->AlphaSize = 0;
- table->IntensitySize = sz;
- table->LuminanceSize = 0;
- break;
- case GL_RGB:
- table->RedSize = sz;
- table->GreenSize = sz;
- table->BlueSize = sz;
- table->AlphaSize = 0;
- table->IntensitySize = 0;
- table->LuminanceSize = 0;
- break;
- case GL_RGBA:
- table->RedSize = sz;
- table->GreenSize = sz;
- table->BlueSize = sz;
- table->AlphaSize = sz;
- table->IntensitySize = 0;
- table->LuminanceSize = 0;
- break;
- default:
- _mesa_problem(NULL, "unexpected format in set_component_sizes");
- }
-}
-
-
-
-/**
- * Update/replace all or part of a color table. Helper function
- * used by _mesa_ColorTable() and _mesa_ColorSubTable().
- * The table->Table buffer should already be allocated.
- * \param start first entry to update
- * \param count number of entries to update
- * \param format format of user-provided table data
- * \param type datatype of user-provided table data
- * \param data user-provided table data
- * \param [rgba]Scale - RGBA scale factors
- * \param [rgba]Bias - RGBA bias factors
- */
-static void
-store_colortable_entries(struct gl_context *ctx, struct gl_color_table *table,
- GLsizei start, GLsizei count,
- GLenum format, GLenum type, const GLvoid *data,
- GLfloat rScale, GLfloat rBias,
- GLfloat gScale, GLfloat gBias,
- GLfloat bScale, GLfloat bBias,
- GLfloat aScale, GLfloat aBias)
-{
- data = _mesa_map_validate_pbo_source(ctx,
- 1, &ctx->Unpack, count, 1, 1,
- format, type, INT_MAX, data,
- "glColor[Sub]Table");
- if (!data)
- return;
-
- {
- /* convert user-provided data to GLfloat values */
- GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4];
- GLfloat *tableF;
- GLint i;
-
- _mesa_unpack_color_span_float(ctx,
- count, /* number of pixels */
- table->_BaseFormat, /* dest format */
- tempTab, /* dest address */
- format, type, /* src format/type */
- data, /* src data */
- &ctx->Unpack,
- IMAGE_CLAMP_BIT); /* transfer ops */
-
- /* the destination */
- tableF = table->TableF;
-
- /* Apply scale & bias & clamp now */
- switch (table->_BaseFormat) {
- case GL_INTENSITY:
- for (i = 0; i < count; i++) {
- GLuint j = start + i;
- tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
- }
- break;
- case GL_LUMINANCE:
- for (i = 0; i < count; i++) {
- GLuint j = start + i;
- tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
- }
- break;
- case GL_ALPHA:
- for (i = 0; i < count; i++) {
- GLuint j = start + i;
- tableF[j] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F);
- }
- break;
- case GL_LUMINANCE_ALPHA:
- for (i = 0; i < count; i++) {
- GLuint j = start + i;
- tableF[j*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F);
- tableF[j*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F);
- }
- break;
- case GL_RGB:
- for (i = 0; i < count; i++) {
- GLuint j = start + i;
- tableF[j*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F);
- tableF[j*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F);
- tableF[j*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F);
- }
- break;
- case GL_RGBA:
- for (i = 0; i < count; i++) {
- GLuint j = start + i;
- tableF[j*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F);
- tableF[j*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F);
- tableF[j*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F);
- tableF[j*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F);
- }
- break;
- default:
- _mesa_problem(ctx, "Bad format in store_colortable_entries");
- return;
- }
- }
-
- /* update the ubyte table */
- {
- const GLint comps = _mesa_components_in_format(table->_BaseFormat);
- const GLfloat *tableF = table->TableF + start * comps;
- GLubyte *tableUB = table->TableUB + start * comps;
- GLint i;
- for (i = 0; i < count * comps; i++) {
- CLAMPED_FLOAT_TO_UBYTE(tableUB[i], tableF[i]);
- }
- }
-
- _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
-}
-
-
-
void GLAPIENTRY
_mesa_ColorTable( GLenum target, GLenum internalFormat,
GLsizei width, GLenum format, GLenum type,
const GLvoid *data )
{
- static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 };
- static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 };
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
- struct gl_texture_object *texObj = NULL;
- struct gl_color_table *table = NULL;
- GLboolean proxy = GL_FALSE;
- GLint baseFormat;
- const GLfloat *scale = one, *bias = zero;
- GLint comps;
-
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
-
- switch (target) {
- case GL_SHARED_TEXTURE_PALETTE_EXT:
- table = &ctx->Texture.Palette;
- break;
- default:
- /* try texture targets */
- {
- struct gl_texture_object *texobj
- = _mesa_select_tex_object(ctx, texUnit, target);
- if (texobj) {
- table = &texobj->Palette;
- proxy = _mesa_is_proxy_texture(target);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
- return;
- }
- }
- }
-
- assert(table);
-
- if (!_mesa_is_legal_format_and_type(ctx, format, type) ||
- format == GL_INTENSITY) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)");
- return;
- }
-
- baseFormat = base_colortab_format(internalFormat);
- if (baseFormat < 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)");
- return;
- }
-
- if (width < 0 || (width != 0 && !_mesa_is_pow_two(width))) {
- /* error */
- if (proxy) {
- table->Size = 0;
- table->InternalFormat = (GLenum) 0;
- table->_BaseFormat = (GLenum) 0;
- }
- else {
- _mesa_error(ctx, GL_INVALID_VALUE, "glColorTable(width=%d)", width);
- }
- return;
- }
-
- if (width > (GLsizei) ctx->Const.MaxColorTableSize) {
- if (proxy) {
- table->Size = 0;
- table->InternalFormat = (GLenum) 0;
- table->_BaseFormat = (GLenum) 0;
- }
- else {
- _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)");
- }
- return;
- }
-
- table->Size = width;
- table->InternalFormat = internalFormat;
- table->_BaseFormat = (GLenum) baseFormat;
-
- comps = _mesa_components_in_format(table->_BaseFormat);
- assert(comps > 0); /* error should have been caught sooner */
-
- if (!proxy) {
- _mesa_free_colortable_data(table);
-
- if (width > 0) {
- table->TableF = (GLfloat *) malloc(comps * width * sizeof(GLfloat));
- table->TableUB = (GLubyte *) malloc(comps * width * sizeof(GLubyte));
-
- if (!table->TableF || !table->TableUB) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable");
- return;
- }
-
- store_colortable_entries(ctx, table,
- 0, width, /* start, count */
- format, type, data,
- scale[0], bias[0],
- scale[1], bias[1],
- scale[2], bias[2],
- scale[3], bias[3]);
- }
- } /* proxy */
-
- /* do this after the table's Type and Format are set */
- set_component_sizes(table);
-
- if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
- /* texture object palette, texObj==NULL means the shared palette */
- if (ctx->Driver.UpdateTexturePalette) {
- (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
- }
- }
-
- ctx->NewState |= _NEW_PIXEL;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
}
@@ -405,73 +58,9 @@ _mesa_ColorSubTable( GLenum target, GLsizei start,
GLsizei count, GLenum format, GLenum type,
const GLvoid *data )
{
- static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 };
- static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 };
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
- struct gl_texture_object *texObj = NULL;
- struct gl_color_table *table = NULL;
- const GLfloat *scale = one, *bias = zero;
-
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- switch (target) {
- case GL_SHARED_TEXTURE_PALETTE_EXT:
- table = &ctx->Texture.Palette;
- break;
- default:
- /* try texture targets */
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- if (texObj && !_mesa_is_proxy_texture(target)) {
- table = &texObj->Palette;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
- return;
- }
- }
-
- assert(table);
-
- if (!_mesa_is_legal_format_and_type(ctx, format, type) ||
- format == GL_INTENSITY) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable(format or type)");
- return;
- }
-
- if (count < 1) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
- return;
- }
-
- /* error should have been caught sooner */
- assert(_mesa_components_in_format(table->_BaseFormat) > 0);
-
- if (start + count > (GLint) table->Size) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
- return;
- }
-
- if (!table->TableF || !table->TableUB) {
- /* a GL_OUT_OF_MEMORY error would have been recorded previously */
- return;
- }
-
- store_colortable_entries(ctx, table, start, count,
- format, type, data,
- scale[0], bias[0],
- scale[1], bias[1],
- scale[2], bias[2],
- scale[3], bias[3]);
-
- if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
- /* per-texture object palette */
- if (ctx->Driver.UpdateTexturePalette) {
- (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
- }
- }
-
- ctx->NewState |= _NEW_PIXEL;
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
}
@@ -482,12 +71,7 @@ _mesa_CopyColorTable(GLenum target, GLenum internalformat,
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (!ctx->ReadBuffer->_ColorReadBuffer) {
- return; /* no readbuffer - OK */
- }
-
- ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width );
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyColorTable(target)");
}
@@ -498,12 +82,7 @@ _mesa_CopyColorSubTable(GLenum target, GLsizei start,
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (!ctx->ReadBuffer->_ColorReadBuffer) {
- return; /* no readbuffer - OK */
- }
-
- ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width );
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyColorSubTable(target)");
}
@@ -513,120 +92,8 @@ _mesa_GetnColorTableARB( GLenum target, GLenum format, GLenum type,
GLsizei bufSize, GLvoid *data )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
- struct gl_color_table *table = NULL;
- GLfloat rgba[MAX_COLOR_TABLE_SIZE][4];
- GLbitfield transferOps = 0;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (ctx->NewState) {
- _mesa_update_state(ctx);
- }
-
- switch (target) {
- case GL_SHARED_TEXTURE_PALETTE_EXT:
- table = &ctx->Texture.Palette;
- break;
- default:
- /* try texture targets */
- {
- struct gl_texture_object *texobj
- = _mesa_select_tex_object(ctx, texUnit, target);
- if (texobj && !_mesa_is_proxy_texture(target)) {
- table = &texobj->Palette;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
- return;
- }
- }
- }
-
- ASSERT(table);
-
- if (table->Size <= 0) {
- return;
- }
-
- switch (table->_BaseFormat) {
- case GL_ALPHA:
- {
- GLuint i;
- for (i = 0; i < table->Size; i++) {
- rgba[i][RCOMP] = 0;
- rgba[i][GCOMP] = 0;
- rgba[i][BCOMP] = 0;
- rgba[i][ACOMP] = table->TableF[i];
- }
- }
- break;
- case GL_LUMINANCE:
- {
- GLuint i;
- for (i = 0; i < table->Size; i++) {
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] = table->TableF[i];
- rgba[i][ACOMP] = 1.0F;
- }
- }
- break;
- case GL_LUMINANCE_ALPHA:
- {
- GLuint i;
- for (i = 0; i < table->Size; i++) {
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] = table->TableF[i*2+0];
- rgba[i][ACOMP] = table->TableF[i*2+1];
- }
- }
- break;
- case GL_INTENSITY:
- {
- GLuint i;
- for (i = 0; i < table->Size; i++) {
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] =
- rgba[i][ACOMP] = table->TableF[i];
- }
- }
- break;
- case GL_RGB:
- {
- GLuint i;
- for (i = 0; i < table->Size; i++) {
- rgba[i][RCOMP] = table->TableF[i*3+0];
- rgba[i][GCOMP] = table->TableF[i*3+1];
- rgba[i][BCOMP] = table->TableF[i*3+2];
- rgba[i][ACOMP] = 1.0F;
- }
- }
- break;
- case GL_RGBA:
- memcpy(rgba, table->TableF, 4 * table->Size * sizeof(GLfloat));
- break;
- default:
- _mesa_problem(ctx, "bad table format in glGetColorTable");
- return;
- }
-
- data = _mesa_map_validate_pbo_dest(ctx,
- 1, &ctx->Pack, table->Size, 1, 1,
- format, type, bufSize, data,
- "glGetColorTable");
- if (!data)
- return;
-
- /* TODO: is this correct? */
- if(ctx->Color._ClampReadColor)
- transferOps |= IMAGE_CLAMP_BIT;
-
- _mesa_pack_rgba_span_float(ctx, table->Size, rgba,
- format, type, data, &ctx->Pack, transferOps);
-
- _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetnColorTableARB(target)");
}
@@ -634,7 +101,9 @@ static void GLAPIENTRY
_mesa_GetColorTable( GLenum target, GLenum format,
GLenum type, GLvoid *data )
{
- _mesa_GetnColorTableARB(target, format, type, INT_MAX, data);
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
}
@@ -664,61 +133,8 @@ static void GLAPIENTRY
_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
- struct gl_color_table *table = NULL;
ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- switch (target) {
- case GL_SHARED_TEXTURE_PALETTE_EXT:
- table = &ctx->Texture.Palette;
- break;
- default:
- /* try texture targets */
- {
- struct gl_texture_object *texobj
- = _mesa_select_tex_object(ctx, texUnit, target);
- if (texobj) {
- table = &texobj->Palette;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetColorTableParameterfv(target)");
- return;
- }
- }
- }
-
- assert(table);
-
- switch (pname) {
- case GL_COLOR_TABLE_FORMAT:
- *params = (GLfloat) table->InternalFormat;
- break;
- case GL_COLOR_TABLE_WIDTH:
- *params = (GLfloat) table->Size;
- break;
- case GL_COLOR_TABLE_RED_SIZE:
- *params = (GLfloat) table->RedSize;
- break;
- case GL_COLOR_TABLE_GREEN_SIZE:
- *params = (GLfloat) table->GreenSize;
- break;
- case GL_COLOR_TABLE_BLUE_SIZE:
- *params = (GLfloat) table->BlueSize;
- break;
- case GL_COLOR_TABLE_ALPHA_SIZE:
- *params = (GLfloat) table->AlphaSize;
- break;
- case GL_COLOR_TABLE_LUMINANCE_SIZE:
- *params = (GLfloat) table->LuminanceSize;
- break;
- case GL_COLOR_TABLE_INTENSITY_SIZE:
- *params = (GLfloat) table->IntensitySize;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(pname)" );
- return;
- }
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)");
}
@@ -727,61 +143,8 @@ static void GLAPIENTRY
_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
- struct gl_color_table *table = NULL;
ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- switch (target) {
- case GL_SHARED_TEXTURE_PALETTE_EXT:
- table = &ctx->Texture.Palette;
- break;
- default:
- /* Try texture targets */
- {
- struct gl_texture_object *texobj
- = _mesa_select_tex_object(ctx, texUnit, target);
- if (texobj) {
- table = &texobj->Palette;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetColorTableParameteriv(target)");
- return;
- }
- }
- }
-
- assert(table);
-
- switch (pname) {
- case GL_COLOR_TABLE_FORMAT:
- *params = table->InternalFormat;
- break;
- case GL_COLOR_TABLE_WIDTH:
- *params = table->Size;
- break;
- case GL_COLOR_TABLE_RED_SIZE:
- *params = table->RedSize;
- break;
- case GL_COLOR_TABLE_GREEN_SIZE:
- *params = table->GreenSize;
- break;
- case GL_COLOR_TABLE_BLUE_SIZE:
- *params = table->BlueSize;
- break;
- case GL_COLOR_TABLE_ALPHA_SIZE:
- *params = table->AlphaSize;
- break;
- case GL_COLOR_TABLE_LUMINANCE_SIZE:
- *params = table->LuminanceSize;
- break;
- case GL_COLOR_TABLE_INTENSITY_SIZE:
- *params = table->IntensitySize;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(pname)" );
- return;
- }
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)");
}
@@ -804,33 +167,3 @@ _mesa_init_colortable_dispatch(struct _glapi_table *disp)
#endif /* FEATURE_colortable */
-
-
-/**********************************************************************/
-/***** Initialization *****/
-/**********************************************************************/
-
-
-void
-_mesa_init_colortable( struct gl_color_table *p )
-{
- p->TableF = NULL;
- p->TableUB = NULL;
- p->Size = 0;
- p->InternalFormat = GL_RGBA;
-}
-
-
-
-void
-_mesa_free_colortable_data( struct gl_color_table *p )
-{
- if (p->TableF) {
- free(p->TableF);
- p->TableF = NULL;
- }
- if (p->TableUB) {
- free(p->TableUB);
- p->TableUB = NULL;
- }
-}
diff --git a/mesalib/src/mesa/main/colortab.h b/mesalib/src/mesa/main/colortab.h
index 81b4e008b..b0d2b5db8 100644
--- a/mesalib/src/mesa/main/colortab.h
+++ b/mesalib/src/mesa/main/colortab.h
@@ -1,84 +1,76 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 1999-2006 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 COLORTAB_H
-#define COLORTAB_H
-
-
-#include "compiler.h"
-#include "glheader.h"
-#include "mfeatures.h"
-
-struct _glapi_table;
-struct gl_color_table;
-
-#if FEATURE_colortable
-
-extern void GLAPIENTRY
-_mesa_ColorTable( GLenum target, GLenum internalformat,
- GLsizei width, GLenum format, GLenum type,
- const GLvoid *table );
-
-extern void GLAPIENTRY
-_mesa_ColorSubTable( GLenum target, GLsizei start,
- GLsizei count, GLenum format, GLenum type,
- const GLvoid *table );
-
-extern void
-_mesa_init_colortable_dispatch(struct _glapi_table *disp);
-
-#else /* FEATURE_colortable */
-
-static INLINE void GLAPIENTRY
-_mesa_ColorTable( GLenum target, GLenum internalformat,
- GLsizei width, GLenum format, GLenum type,
- const GLvoid *table )
-{
- ASSERT_NO_FEATURE();
-}
-
-static INLINE void GLAPIENTRY
-_mesa_ColorSubTable( GLenum target, GLsizei start,
- GLsizei count, GLenum format, GLenum type,
- const GLvoid *table )
-{
- ASSERT_NO_FEATURE();
-}
-
-static INLINE void
-_mesa_init_colortable_dispatch(struct _glapi_table *disp)
-{
-}
-
-#endif /* FEATURE_colortable */
-
-
-extern void
-_mesa_init_colortable( struct gl_color_table *table );
-
-extern void
-_mesa_free_colortable_data( struct gl_color_table *table );
-
-#endif /* COLORTAB_H */
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.2
+ *
+ * Copyright (C) 1999-2006 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 COLORTAB_H
+#define COLORTAB_H
+
+
+#include "compiler.h"
+#include "glheader.h"
+#include "mfeatures.h"
+
+struct _glapi_table;
+
+#if FEATURE_colortable
+
+extern void GLAPIENTRY
+_mesa_ColorTable( GLenum target, GLenum internalformat,
+ GLsizei width, GLenum format, GLenum type,
+ const GLvoid *table );
+
+extern void GLAPIENTRY
+_mesa_ColorSubTable( GLenum target, GLsizei start,
+ GLsizei count, GLenum format, GLenum type,
+ const GLvoid *table );
+
+extern void
+_mesa_init_colortable_dispatch(struct _glapi_table *disp);
+
+#else /* FEATURE_colortable */
+
+static INLINE void GLAPIENTRY
+_mesa_ColorTable( GLenum target, GLenum internalformat,
+ GLsizei width, GLenum format, GLenum type,
+ const GLvoid *table )
+{
+ ASSERT_NO_FEATURE();
+}
+
+static INLINE void GLAPIENTRY
+_mesa_ColorSubTable( GLenum target, GLsizei start,
+ GLsizei count, GLenum format, GLenum type,
+ const GLvoid *table )
+{
+ ASSERT_NO_FEATURE();
+}
+
+static INLINE void
+_mesa_init_colortable_dispatch(struct _glapi_table *disp)
+{
+}
+
+#endif /* FEATURE_colortable */
+
+#endif /* COLORTAB_H */
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index b9305addc..b77e4f092 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -523,29 +523,6 @@ struct dd_function_table {
*/
GLboolean (*IsTextureResident)( struct gl_context *ctx,
struct gl_texture_object *t );
-
- /**
- * Called when the texture's color lookup table is changed.
- *
- * If \p tObj is NULL then the shared texture palette
- * gl_texture_object::Palette is to be updated.
- */
- void (*UpdateTexturePalette)( struct gl_context *ctx,
- struct gl_texture_object *tObj );
- /*@}*/
-
-
- /**
- * \name Imaging functionality
- */
- /*@{*/
- void (*CopyColorTable)( struct gl_context *ctx,
- GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width );
-
- void (*CopyColorSubTable)( struct gl_context *ctx,
- GLenum target, GLsizei start,
- GLint x, GLint y, GLsizei width );
/*@}*/
diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c
index 3ba4df634..4bf1809e7 100644
--- a/mesalib/src/mesa/main/enable.c
+++ b/mesalib/src/mesa/main/enable.c
@@ -576,12 +576,6 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
FLUSH_VERTICES(ctx, _NEW_SCISSOR);
ctx->Scissor.Enabled = state;
break;
- case GL_SHARED_TEXTURE_PALETTE_EXT:
- if (ctx->Texture.SharedPalette == state)
- return;
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- ctx->Texture.SharedPalette = state;
- break;
case GL_STENCIL_TEST:
if (ctx->Stencil.Enabled == state)
return;
@@ -1175,8 +1169,6 @@ _mesa_IsEnabled( GLenum cap )
return ctx->Transform.RescaleNormals;
case GL_SCISSOR_TEST:
return ctx->Scissor.Enabled;
- case GL_SHARED_TEXTURE_PALETTE_EXT:
- return ctx->Texture.SharedPalette;
case GL_STENCIL_TEST:
return ctx->Stencil.Enabled;
case GL_TEXTURE_1D:
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 14b0cf9ac..1903a503c 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -172,7 +172,6 @@ static const struct extension extension_table[] = {
{ "GL_EXT_packed_depth_stencil", o(EXT_packed_depth_stencil), GL, 2005 },
{ "GL_EXT_packed_float", o(EXT_packed_float), GL, 2004 },
{ "GL_EXT_packed_pixels", o(EXT_packed_pixels), GL, 1997 },
- { "GL_EXT_paletted_texture", o(EXT_paletted_texture), GL, 1995 },
{ "GL_EXT_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 },
{ "GL_EXT_point_parameters", o(EXT_point_parameters), GL, 1997 },
{ "GL_EXT_polygon_offset", o(EXT_polygon_offset), GL, 1995 },
@@ -182,7 +181,6 @@ static const struct extension extension_table[] = {
{ "GL_EXT_separate_shader_objects", o(EXT_separate_shader_objects), GL, 2008 },
{ "GL_EXT_separate_specular_color", o(EXT_separate_specular_color), GL, 1997 },
{ "GL_EXT_shadow_funcs", o(EXT_shadow_funcs), GL, 2002 },
- { "GL_EXT_shared_texture_palette", o(EXT_shared_texture_palette), GL, 2000 },
{ "GL_EXT_stencil_two_side", o(EXT_stencil_two_side), GL, 2001 },
{ "GL_EXT_stencil_wrap", o(EXT_stencil_wrap), GL, 2002 },
{ "GL_EXT_subtexture", o(EXT_subtexture), GL, 1995 },
@@ -488,7 +486,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
#endif
/*ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;*/
ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
- ctx->Extensions.EXT_paletted_texture = GL_TRUE;
#if FEATURE_EXT_pixel_buffer_object
ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
#endif
@@ -496,7 +493,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
ctx->Extensions.EXT_provoking_vertex = GL_TRUE;
ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
ctx->Extensions.EXT_secondary_color = GL_TRUE;
- ctx->Extensions.EXT_shared_texture_palette = GL_TRUE;
ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
ctx->Extensions.EXT_texture_array = GL_TRUE;
diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c
index c0fcf9cd4..c6634c458 100644
--- a/mesalib/src/mesa/main/formats.c
+++ b/mesalib/src/mesa/main/formats.c
@@ -1175,7 +1175,6 @@ _mesa_get_format_bits(gl_format format, GLenum pname)
case GL_TEXTURE_LUMINANCE_SIZE:
return info->LuminanceBits;
case GL_INDEX_BITS:
- case GL_TEXTURE_INDEX_SIZE_EXT:
return info->IndexBits;
case GL_DEPTH_BITS:
case GL_TEXTURE_DEPTH_SIZE_ARB:
diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c
index 23fa1b2c1..42da17678 100644
--- a/mesalib/src/mesa/main/framebuffer.c
+++ b/mesalib/src/mesa/main/framebuffer.c
@@ -888,7 +888,6 @@ _mesa_source_buffer_exists(struct gl_context *ctx, GLenum format)
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
- case GL_COLOR_INDEX:
case GL_RED_INTEGER_EXT:
case GL_GREEN_INTEGER_EXT:
case GL_BLUE_INTEGER_EXT:
@@ -976,7 +975,6 @@ _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
- case GL_COLOR_INDEX:
case GL_RED_INTEGER_EXT:
case GL_GREEN_INTEGER_EXT:
case GL_BLUE_INTEGER_EXT:
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index d32c68a53..069254b18 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -857,7 +857,6 @@ static const struct value_desc values[] = {
{ GL_RENDER_MODE, CONTEXT_ENUM(RenderMode), NO_EXTRA },
{ GL_RGBA_MODE, CONST(1), NO_EXTRA },
{ GL_SELECTION_BUFFER_SIZE, CONTEXT_INT(Select.BufferSize), NO_EXTRA },
- { GL_SHARED_TEXTURE_PALETTE_EXT, CONTEXT_BOOL(Texture.SharedPalette), NO_EXTRA },
{ GL_STEREO, BUFFER_INT(Visual.stereoMode), NO_EXTRA },
diff --git a/mesalib/src/mesa/main/image.c b/mesalib/src/mesa/main/image.c
index 37127dcb7..3e75e7c6b 100644
--- a/mesalib/src/mesa/main/image.c
+++ b/mesalib/src/mesa/main/image.c
@@ -249,12 +249,6 @@ _mesa_components_in_format( GLenum format )
{
switch (format) {
case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX8_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
@@ -863,27 +857,6 @@ _mesa_is_color_format(GLenum format)
/**
- * Test if the given image format is a color index format.
- */
-GLboolean
-_mesa_is_index_format(GLenum format)
-{
- switch (format) {
- case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX8_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
* Test if the given image format is a depth component format.
*/
GLboolean
diff --git a/mesalib/src/mesa/main/image.h b/mesalib/src/mesa/main/image.h
index 6fa93924c..46adaec41 100644
--- a/mesalib/src/mesa/main/image.h
+++ b/mesalib/src/mesa/main/image.h
@@ -1,176 +1,173 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2008 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 IMAGE_H
-#define IMAGE_H
-
-
-#include "glheader.h"
-
-struct gl_context;
-struct gl_pixelstore_attrib;
-
-extern void
-_mesa_swap2( GLushort *p, GLuint n );
-
-extern void
-_mesa_swap4( GLuint *p, GLuint n );
-
-extern GLboolean
-_mesa_type_is_packed(GLenum type);
-
-extern GLint
-_mesa_sizeof_type( GLenum type );
-
-extern GLint
-_mesa_sizeof_packed_type( GLenum type );
-
-extern GLint
-_mesa_components_in_format( GLenum format );
-
-extern GLint
-_mesa_bytes_per_pixel( GLenum format, GLenum type );
-
-extern GLboolean
-_mesa_is_legal_format_and_type(const struct gl_context *ctx,
- GLenum format, GLenum type);
-
-extern GLboolean
-_mesa_is_color_format(GLenum format);
-
-extern GLboolean
-_mesa_is_index_format(GLenum format);
-
-extern GLboolean
-_mesa_is_depth_format(GLenum format);
-
-extern GLboolean
-_mesa_is_stencil_format(GLenum format);
-
-extern GLboolean
-_mesa_is_ycbcr_format(GLenum format);
-
-extern GLboolean
-_mesa_is_depthstencil_format(GLenum format);
-
-extern GLboolean
-_mesa_is_depth_or_stencil_format(GLenum format);
-
-extern GLboolean
-_mesa_is_dudv_format(GLenum format);
-
-extern GLboolean
-_mesa_is_integer_format(GLenum format);
-
-extern GLboolean
-_mesa_is_compressed_format(struct gl_context *ctx, GLenum format);
-
-extern GLvoid *
-_mesa_image_address( GLuint dimensions,
- const struct gl_pixelstore_attrib *packing,
- const GLvoid *image,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- GLint img, GLint row, GLint column );
-
-extern GLvoid *
-_mesa_image_address1d( const struct gl_pixelstore_attrib *packing,
- const GLvoid *image,
- GLsizei width,
- GLenum format, GLenum type,
- GLint column );
-
-extern GLvoid *
-_mesa_image_address2d( const struct gl_pixelstore_attrib *packing,
- const GLvoid *image,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- GLint row, GLint column );
-
-extern GLvoid *
-_mesa_image_address3d( const struct gl_pixelstore_attrib *packing,
- const GLvoid *image,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- GLint img, GLint row, GLint column );
-
-
-extern GLint
-_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
- GLint width, GLenum format, GLenum type );
-
-
-extern GLint
-_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
- GLint width, GLint height,
- GLenum format, GLenum type );
-
-
-extern void
-_mesa_expand_bitmap(GLsizei width, GLsizei height,
- const struct gl_pixelstore_attrib *unpack,
- const GLubyte *bitmap,
- GLubyte *destBuffer, GLint destStride,
- GLubyte onValue);
-
-
-extern void
-_mesa_convert_colors(GLenum srcType, const GLvoid *src,
- GLenum dstType, GLvoid *dst,
- GLuint count, const GLubyte mask[]);
-
-
-extern GLboolean
-_mesa_clip_drawpixels(const struct gl_context *ctx,
- GLint *destX, GLint *destY,
- GLsizei *width, GLsizei *height,
- struct gl_pixelstore_attrib *unpack);
-
-
-extern GLboolean
-_mesa_clip_readpixels(const struct gl_context *ctx,
- GLint *srcX, GLint *srcY,
- GLsizei *width, GLsizei *height,
- struct gl_pixelstore_attrib *pack);
-
-extern GLboolean
-_mesa_clip_copytexsubimage(const struct gl_context *ctx,
- GLint *destX, GLint *destY,
- GLint *srcX, GLint *srcY,
- GLsizei *width, GLsizei *height);
-
-extern GLboolean
-_mesa_clip_to_region(GLint xmin, GLint ymin,
- GLint xmax, GLint ymax,
- GLint *x, GLint *y,
- GLsizei *width, GLsizei *height );
-
-extern GLboolean
-_mesa_clip_blit(struct gl_context *ctx,
- GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
- GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1);
-
-
-#endif
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2008 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 IMAGE_H
+#define IMAGE_H
+
+
+#include "glheader.h"
+
+struct gl_context;
+struct gl_pixelstore_attrib;
+
+extern void
+_mesa_swap2( GLushort *p, GLuint n );
+
+extern void
+_mesa_swap4( GLuint *p, GLuint n );
+
+extern GLboolean
+_mesa_type_is_packed(GLenum type);
+
+extern GLint
+_mesa_sizeof_type( GLenum type );
+
+extern GLint
+_mesa_sizeof_packed_type( GLenum type );
+
+extern GLint
+_mesa_components_in_format( GLenum format );
+
+extern GLint
+_mesa_bytes_per_pixel( GLenum format, GLenum type );
+
+extern GLboolean
+_mesa_is_legal_format_and_type(const struct gl_context *ctx,
+ GLenum format, GLenum type);
+
+extern GLboolean
+_mesa_is_color_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depth_format(GLenum format);
+
+extern GLboolean
+_mesa_is_stencil_format(GLenum format);
+
+extern GLboolean
+_mesa_is_ycbcr_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depthstencil_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depth_or_stencil_format(GLenum format);
+
+extern GLboolean
+_mesa_is_dudv_format(GLenum format);
+
+extern GLboolean
+_mesa_is_integer_format(GLenum format);
+
+extern GLboolean
+_mesa_is_compressed_format(struct gl_context *ctx, GLenum format);
+
+extern GLvoid *
+_mesa_image_address( GLuint dimensions,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint img, GLint row, GLint column );
+
+extern GLvoid *
+_mesa_image_address1d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width,
+ GLenum format, GLenum type,
+ GLint column );
+
+extern GLvoid *
+_mesa_image_address2d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint row, GLint column );
+
+extern GLvoid *
+_mesa_image_address3d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint img, GLint row, GLint column );
+
+
+extern GLint
+_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
+ GLint width, GLenum format, GLenum type );
+
+
+extern GLint
+_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
+ GLint width, GLint height,
+ GLenum format, GLenum type );
+
+
+extern void
+_mesa_expand_bitmap(GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap,
+ GLubyte *destBuffer, GLint destStride,
+ GLubyte onValue);
+
+
+extern void
+_mesa_convert_colors(GLenum srcType, const GLvoid *src,
+ GLenum dstType, GLvoid *dst,
+ GLuint count, const GLubyte mask[]);
+
+
+extern GLboolean
+_mesa_clip_drawpixels(const struct gl_context *ctx,
+ GLint *destX, GLint *destY,
+ GLsizei *width, GLsizei *height,
+ struct gl_pixelstore_attrib *unpack);
+
+
+extern GLboolean
+_mesa_clip_readpixels(const struct gl_context *ctx,
+ GLint *srcX, GLint *srcY,
+ GLsizei *width, GLsizei *height,
+ struct gl_pixelstore_attrib *pack);
+
+extern GLboolean
+_mesa_clip_copytexsubimage(const struct gl_context *ctx,
+ GLint *destX, GLint *destY,
+ GLint *srcX, GLint *srcY,
+ GLsizei *width, GLsizei *height);
+
+extern GLboolean
+_mesa_clip_to_region(GLint xmin, GLint ymin,
+ GLint xmax, GLint ymax,
+ GLint *x, GLint *y,
+ GLsizei *width, GLsizei *height );
+
+extern GLboolean
+_mesa_clip_blit(struct gl_context *ctx,
+ GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+ GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1);
+
+
+#endif
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index ad5979796..ae500b4c2 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -215,7 +215,9 @@ typedef enum
/**
- * Indexes for vertex program result attributes
+ * Indexes for vertex program result attributes. Note that
+ * _mesa_vert_result_to_frag_attrib() and _mesa_frag_attrib_to_vert_result() make
+ * assumptions about the layout of this enum.
*/
typedef enum
{
@@ -313,7 +315,9 @@ typedef enum
/**
- * Indexes for fragment program input attributes.
+ * Indexes for fragment program input attributes. Note that
+ * _mesa_vert_result_to_frag_attrib() and frag_attrib_to_vert_result() make
+ * assumptions about the layout of this enum.
*/
typedef enum
{
@@ -335,6 +339,48 @@ typedef enum
FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
} gl_frag_attrib;
+
+/**
+ * Convert from a gl_vert_result value to the corresponding gl_frag_attrib.
+ *
+ * VERT_RESULT_HPOS is converted to FRAG_ATTRIB_WPOS.
+ *
+ * gl_vert_result values which have no corresponding gl_frag_attrib
+ * (VERT_RESULT_PSIZ, VERT_RESULT_BFC0, VERT_RESULT_BFC1, and
+ * VERT_RESULT_EDGE) are converted to a value of -1.
+ */
+static INLINE int
+_mesa_vert_result_to_frag_attrib(gl_vert_result vert_result)
+{
+ if (vert_result >= VERT_RESULT_VAR0)
+ return vert_result - VERT_RESULT_VAR0 + FRAG_ATTRIB_VAR0;
+ else if (vert_result <= VERT_RESULT_TEX7)
+ return vert_result;
+ else
+ return -1;
+}
+
+
+/**
+ * Convert from a gl_frag_attrib value to the corresponding gl_vert_result.
+ *
+ * FRAG_ATTRIB_WPOS is converted to VERT_RESULT_HPOS.
+ *
+ * gl_frag_attrib values which have no corresponding gl_vert_result
+ * (FRAG_ATTRIB_FACE and FRAG_ATTRIB_PNTC) are converted to a value of -1.
+ */
+static INLINE int
+_mesa_frag_attrib_to_vert_result(gl_frag_attrib frag_attrib)
+{
+ if (frag_attrib <= FRAG_ATTRIB_TEX7)
+ return frag_attrib;
+ else if (frag_attrib >= FRAG_ATTRIB_VAR0)
+ return frag_attrib - FRAG_ATTRIB_VAR0 + VERT_RESULT_VAR0;
+ else
+ return -1;
+}
+
+
/**
* Bitflags for fragment program input attributes.
*/
@@ -524,25 +570,6 @@ struct gl_config
/**
- * Data structure for color tables
- */
-struct gl_color_table
-{
- GLenum InternalFormat; /**< The user-specified format */
- GLenum _BaseFormat; /**< GL_ALPHA, GL_RGBA, GL_RGB, etc */
- GLuint Size; /**< number of entries in table */
- GLfloat *TableF; /**< Color table, floating point values */
- GLubyte *TableUB; /**< Color table, ubyte values */
- GLubyte RedSize;
- GLubyte GreenSize;
- GLubyte BlueSize;
- GLubyte AlphaSize;
- GLubyte LuminanceSize;
- GLubyte IntensitySize;
-};
-
-
-/**
* \name Bit flags used for updating material values.
*/
/*@{*/
@@ -1255,9 +1282,9 @@ struct gl_texture_image
GLint InternalFormat; /**< Internal format as given by the user */
GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_ALPHA,
* GL_LUMINANCE, GL_LUMINANCE_ALPHA,
- * GL_INTENSITY, GL_COLOR_INDEX,
- * GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT
- * only. Used for choosing TexEnv arithmetic.
+ * GL_INTENSITY, GL_DEPTH_COMPONENT or
+ * GL_DEPTH_STENCIL_EXT only. Used for
+ * choosing TexEnv arithmetic.
*/
gl_format TexFormat; /**< The actual texture memory format */
@@ -1354,8 +1381,7 @@ struct gl_sampler_object
/**
* Texture object state. Contains the array of mipmap images, border color,
- * wrap modes, filter modes, shadow/texcompare state, and the per-texture
- * color palette.
+ * wrap modes, filter modes, and shadow/texcompare state.
*/
struct gl_texture_object
{
@@ -1386,9 +1412,6 @@ struct gl_texture_object
struct gl_buffer_object *BufferObject;
GLenum BufferObjectFormat;
- /** GL_EXT_paletted_texture */
- struct gl_color_table Palette;
-
/**
* \name For device driver.
* Note: instead of attaching driver data to this pointer, it's preferable
@@ -1504,10 +1527,6 @@ struct gl_texture_attrib
/** GL_ARB_seamless_cubemap */
GLboolean CubeMapSeamless;
- /** GL_EXT_shared_texture_palette */
- GLboolean SharedPalette;
- struct gl_color_table Palette;
-
/** Texture units/samplers used by vertex or fragment texturing */
GLbitfield _EnabledUnits;
@@ -2852,7 +2871,6 @@ struct gl_extensions
GLboolean EXT_gpu_program_parameters;
GLboolean EXT_gpu_shader4;
GLboolean EXT_multi_draw_arrays;
- GLboolean EXT_paletted_texture;
GLboolean EXT_packed_depth_stencil;
GLboolean EXT_packed_float;
GLboolean EXT_packed_pixels;
@@ -2865,7 +2883,6 @@ struct gl_extensions
GLboolean EXT_secondary_color;
GLboolean EXT_separate_shader_objects;
GLboolean EXT_separate_specular_color;
- GLboolean EXT_shared_texture_palette;
GLboolean EXT_stencil_wrap;
GLboolean EXT_stencil_two_side;
GLboolean EXT_subtexture;
diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c
index 7de1d05b9..fd3f89d82 100644
--- a/mesalib/src/mesa/main/pack.c
+++ b/mesalib/src/mesa/main/pack.c
@@ -3459,8 +3459,7 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx,
dstFormat == GL_RED ||
dstFormat == GL_RG ||
dstFormat == GL_RGB ||
- dstFormat == GL_RGBA ||
- dstFormat == GL_COLOR_INDEX);
+ dstFormat == GL_RGBA);
ASSERT(srcFormat == GL_RED ||
srcFormat == GL_GREEN ||
@@ -3646,24 +3645,11 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx,
extract_uint_indexes(n, indexes, srcFormat, srcType, source,
srcPacking);
- if (dstFormat == GL_COLOR_INDEX) {
- GLuint i;
- _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
- /* convert to GLchan and return */
- for (i = 0; i < n; i++) {
- dest[i] = (GLchan) (indexes[i] & 0xff);
- }
- free(indexes);
- free(rgba);
- return;
- }
- else {
- /* Convert indexes to RGBA */
- if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
- _mesa_shift_and_offset_ci(ctx, n, indexes);
- }
- _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
- }
+ /* Convert indexes to RGBA */
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ _mesa_shift_and_offset_ci(ctx, n, indexes);
+ }
+ _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
/* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
* with color indexes.
@@ -3773,8 +3759,7 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
dstFormat == GL_RED ||
dstFormat == GL_RG ||
dstFormat == GL_RGB ||
- dstFormat == GL_RGBA ||
- dstFormat == GL_COLOR_INDEX);
+ dstFormat == GL_RGBA);
ASSERT(srcFormat == GL_RED ||
srcFormat == GL_GREEN ||
@@ -3855,24 +3840,11 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
extract_uint_indexes(n, indexes, srcFormat, srcType, source,
srcPacking);
- if (dstFormat == GL_COLOR_INDEX) {
- GLuint i;
- _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
- /* convert to GLchan and return */
- for (i = 0; i < n; i++) {
- dest[i] = (GLchan) (indexes[i] & 0xff);
- }
- free(indexes);
- free(rgba);
- return;
- }
- else {
- /* Convert indexes to RGBA */
- if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
- _mesa_shift_and_offset_ci(ctx, n, indexes);
- }
- _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
- }
+ /* Convert indexes to RGBA */
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ _mesa_shift_and_offset_ci(ctx, n, indexes);
+ }
+ _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
/* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
* with color indexes.
diff --git a/mesalib/src/mesa/main/pixeltransfer.c b/mesalib/src/mesa/main/pixeltransfer.c
index 092ee3a14..5e881436a 100644
--- a/mesalib/src/mesa/main/pixeltransfer.c
+++ b/mesalib/src/mesa/main/pixeltransfer.c
@@ -1,567 +1,306 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009-2010 VMware, Inc. 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
- * THE AUTHORS 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.
- */
-
-
-/**
- * \file pixeltransfer.c
- * Pixel transfer operations (scale, bias, table lookups, etc)
- */
-
-
-#include "glheader.h"
-#include "colormac.h"
-#include "pixeltransfer.h"
-#include "imports.h"
-#include "mtypes.h"
-
-
-/*
- * Apply scale and bias factors to an array of RGBA pixels.
- */
-void
-_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
- GLfloat rScale, GLfloat gScale,
- GLfloat bScale, GLfloat aScale,
- GLfloat rBias, GLfloat gBias,
- GLfloat bBias, GLfloat aBias)
-{
- if (rScale != 1.0 || rBias != 0.0) {
- GLuint i;
- for (i = 0; i < n; i++) {
- rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
- }
- }
- if (gScale != 1.0 || gBias != 0.0) {
- GLuint i;
- for (i = 0; i < n; i++) {
- rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
- }
- }
- if (bScale != 1.0 || bBias != 0.0) {
- GLuint i;
- for (i = 0; i < n; i++) {
- rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
- }
- }
- if (aScale != 1.0 || aBias != 0.0) {
- GLuint i;
- for (i = 0; i < n; i++) {
- rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
- }
- }
-}
-
-
-/*
- * Apply pixel mapping to an array of floating point RGBA pixels.
- */
-void
-_mesa_map_rgba( const struct gl_context *ctx, GLuint n, GLfloat rgba[][4] )
-{
- const GLfloat rscale = (GLfloat) (ctx->PixelMaps.RtoR.Size - 1);
- const GLfloat gscale = (GLfloat) (ctx->PixelMaps.GtoG.Size - 1);
- const GLfloat bscale = (GLfloat) (ctx->PixelMaps.BtoB.Size - 1);
- const GLfloat ascale = (GLfloat) (ctx->PixelMaps.AtoA.Size - 1);
- const GLfloat *rMap = ctx->PixelMaps.RtoR.Map;
- const GLfloat *gMap = ctx->PixelMaps.GtoG.Map;
- const GLfloat *bMap = ctx->PixelMaps.BtoB.Map;
- const GLfloat *aMap = ctx->PixelMaps.AtoA.Map;
- GLuint i;
- for (i=0;i<n;i++) {
- GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
- GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
- GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
- GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
- rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
- rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
- rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
- rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
- }
-}
-
-/**
- * Apply a color table lookup to an array of floating point RGBA colors.
- */
-void
-_mesa_lookup_rgba_float(const struct gl_color_table *table,
- GLuint n, GLfloat rgba[][4])
-{
- const GLint max = table->Size - 1;
- const GLfloat scale = (GLfloat) max;
- const GLfloat *lut = table->TableF;
- GLuint i;
-
- if (!table->TableF || table->Size == 0)
- return;
-
- switch (table->_BaseFormat) {
- case GL_INTENSITY:
- /* replace RGBA with I */
- for (i = 0; i < n; i++) {
- GLint j = IROUND(rgba[i][RCOMP] * scale);
- GLfloat c = lut[CLAMP(j, 0, max)];
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] =
- rgba[i][ACOMP] = c;
- }
- break;
- case GL_LUMINANCE:
- /* replace RGB with L */
- for (i = 0; i < n; i++) {
- GLint j = IROUND(rgba[i][RCOMP] * scale);
- GLfloat c = lut[CLAMP(j, 0, max)];
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] = c;
- }
- break;
- case GL_ALPHA:
- /* replace A with A */
- for (i = 0; i < n; i++) {
- GLint j = IROUND(rgba[i][ACOMP] * scale);
- rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
- }
- break;
- case GL_LUMINANCE_ALPHA:
- /* replace RGBA with LLLA */
- for (i = 0; i < n; i++) {
- GLint jL = IROUND(rgba[i][RCOMP] * scale);
- GLint jA = IROUND(rgba[i][ACOMP] * scale);
- GLfloat luminance, alpha;
- jL = CLAMP(jL, 0, max);
- jA = CLAMP(jA, 0, max);
- luminance = lut[jL * 2 + 0];
- alpha = lut[jA * 2 + 1];
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] = luminance;
- rgba[i][ACOMP] = alpha;;
- }
- break;
- case GL_RED:
- /* replace RGB with RGB */
- for (i = 0; i < n; i++) {
- GLint jR = IROUND(rgba[i][RCOMP] * scale);
- jR = CLAMP(jR, 0, max);
- rgba[i][RCOMP] = lut[jR * 3 + 0];
- }
- break;
- case GL_RG:
- /* replace RG with RG */
- for (i = 0; i < n; i++) {
- GLint jR = IROUND(rgba[i][RCOMP] * scale);
- GLint jG = IROUND(rgba[i][GCOMP] * scale);
- jR = CLAMP(jR, 0, max);
- jG = CLAMP(jG, 0, max);
- rgba[i][RCOMP] = lut[jR * 3 + 0];
- rgba[i][GCOMP] = lut[jG * 3 + 1];
- }
- break;
- case GL_RGB:
- /* replace RGB with RGB */
- for (i = 0; i < n; i++) {
- GLint jR = IROUND(rgba[i][RCOMP] * scale);
- GLint jG = IROUND(rgba[i][GCOMP] * scale);
- GLint jB = IROUND(rgba[i][BCOMP] * scale);
- jR = CLAMP(jR, 0, max);
- jG = CLAMP(jG, 0, max);
- jB = CLAMP(jB, 0, max);
- rgba[i][RCOMP] = lut[jR * 3 + 0];
- rgba[i][GCOMP] = lut[jG * 3 + 1];
- rgba[i][BCOMP] = lut[jB * 3 + 2];
- }
- break;
- case GL_RGBA:
- /* replace RGBA with RGBA */
- for (i = 0; i < n; i++) {
- GLint jR = IROUND(rgba[i][RCOMP] * scale);
- GLint jG = IROUND(rgba[i][GCOMP] * scale);
- GLint jB = IROUND(rgba[i][BCOMP] * scale);
- GLint jA = IROUND(rgba[i][ACOMP] * scale);
- jR = CLAMP(jR, 0, max);
- jG = CLAMP(jG, 0, max);
- jB = CLAMP(jB, 0, max);
- jA = CLAMP(jA, 0, max);
- rgba[i][RCOMP] = lut[jR * 4 + 0];
- rgba[i][GCOMP] = lut[jG * 4 + 1];
- rgba[i][BCOMP] = lut[jB * 4 + 2];
- rgba[i][ACOMP] = lut[jA * 4 + 3];
- }
- break;
- default:
- _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float");
- return;
- }
-}
-
-
-
-/**
- * Apply a color table lookup to an array of ubyte/RGBA colors.
- */
-void
-_mesa_lookup_rgba_ubyte(const struct gl_color_table *table,
- GLuint n, GLubyte rgba[][4])
-{
- const GLubyte *lut = table->TableUB;
- const GLfloat scale = (GLfloat) (table->Size - 1) / (GLfloat)255.0;
- GLuint i;
-
- if (!table->TableUB || table->Size == 0)
- return;
-
- switch (table->_BaseFormat) {
- case GL_INTENSITY:
- /* replace RGBA with I */
- if (table->Size == 256) {
- for (i = 0; i < n; i++) {
- const GLubyte c = lut[rgba[i][RCOMP]];
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] =
- rgba[i][ACOMP] = c;
- }
- }
- else {
- for (i = 0; i < n; i++) {
- GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] =
- rgba[i][ACOMP] = lut[j];
- }
- }
- break;
- case GL_LUMINANCE:
- /* replace RGB with L */
- if (table->Size == 256) {
- for (i = 0; i < n; i++) {
- const GLubyte c = lut[rgba[i][RCOMP]];
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] = c;
- }
- }
- else {
- for (i = 0; i < n; i++) {
- GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] = lut[j];
- }
- }
- break;
- case GL_ALPHA:
- /* replace A with A */
- if (table->Size == 256) {
- for (i = 0; i < n; i++) {
- rgba[i][ACOMP] = lut[rgba[i][ACOMP]];
- }
- }
- else {
- for (i = 0; i < n; i++) {
- GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
- rgba[i][ACOMP] = lut[j];
- }
- }
- break;
- case GL_LUMINANCE_ALPHA:
- /* replace RGBA with LLLA */
- if (table->Size == 256) {
- for (i = 0; i < n; i++) {
- GLubyte l = lut[rgba[i][RCOMP] * 2 + 0];
- GLubyte a = lut[rgba[i][ACOMP] * 2 + 1];;
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] = l;
- rgba[i][ACOMP] = a;
- }
- }
- else {
- for (i = 0; i < n; i++) {
- GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
- GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
- GLubyte luminance = lut[jL * 2 + 0];
- GLubyte alpha = lut[jA * 2 + 1];
- rgba[i][RCOMP] =
- rgba[i][GCOMP] =
- rgba[i][BCOMP] = luminance;
- rgba[i][ACOMP] = alpha;
- }
- }
- break;
- case GL_RGB:
- if (table->Size == 256) {
- for (i = 0; i < n; i++) {
- rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0];
- rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1];
- rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2];
- }
- }
- else {
- for (i = 0; i < n; i++) {
- GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
- GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
- GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
- rgba[i][RCOMP] = lut[jR * 3 + 0];
- rgba[i][GCOMP] = lut[jG * 3 + 1];
- rgba[i][BCOMP] = lut[jB * 3 + 2];
- }
- }
- break;
- case GL_RGBA:
- if (table->Size == 256) {
- for (i = 0; i < n; i++) {
- rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0];
- rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1];
- rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2];
- rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3];
- }
- }
- else {
- for (i = 0; i < n; i++) {
- GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
- GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
- GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
- GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
- CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
- CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
- CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
- CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
- }
- }
- break;
- default:
- _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan");
- return;
- }
-}
-
-
-
-/*
- * Map color indexes to float rgba values.
- */
-void
-_mesa_map_ci_to_rgba( const struct gl_context *ctx, GLuint n,
- const GLuint index[], GLfloat rgba[][4] )
-{
- GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
- GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
- GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
- GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
- const GLfloat *rMap = ctx->PixelMaps.ItoR.Map;
- const GLfloat *gMap = ctx->PixelMaps.ItoG.Map;
- const GLfloat *bMap = ctx->PixelMaps.ItoB.Map;
- const GLfloat *aMap = ctx->PixelMaps.ItoA.Map;
- GLuint i;
- for (i=0;i<n;i++) {
- rgba[i][RCOMP] = rMap[index[i] & rmask];
- rgba[i][GCOMP] = gMap[index[i] & gmask];
- rgba[i][BCOMP] = bMap[index[i] & bmask];
- rgba[i][ACOMP] = aMap[index[i] & amask];
- }
-}
-
-
-/**
- * Map ubyte color indexes to ubyte/RGBA values.
- */
-void
-_mesa_map_ci8_to_rgba8(const struct gl_context *ctx,
- GLuint n, const GLubyte index[],
- GLubyte rgba[][4])
-{
- GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
- GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
- GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
- GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
- const GLubyte *rMap = ctx->PixelMaps.ItoR.Map8;
- const GLubyte *gMap = ctx->PixelMaps.ItoG.Map8;
- const GLubyte *bMap = ctx->PixelMaps.ItoB.Map8;
- const GLubyte *aMap = ctx->PixelMaps.ItoA.Map8;
- GLuint i;
- for (i=0;i<n;i++) {
- rgba[i][RCOMP] = rMap[index[i] & rmask];
- rgba[i][GCOMP] = gMap[index[i] & gmask];
- rgba[i][BCOMP] = bMap[index[i] & bmask];
- rgba[i][ACOMP] = aMap[index[i] & amask];
- }
-}
-
-
-void
-_mesa_scale_and_bias_depth(const struct gl_context *ctx, GLuint n,
- GLfloat depthValues[])
-{
- const GLfloat scale = ctx->Pixel.DepthScale;
- const GLfloat bias = ctx->Pixel.DepthBias;
- GLuint i;
- for (i = 0; i < n; i++) {
- GLfloat d = depthValues[i] * scale + bias;
- depthValues[i] = CLAMP(d, 0.0F, 1.0F);
- }
-}
-
-
-void
-_mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n,
- GLuint depthValues[])
-{
- const GLdouble max = (double) 0xffffffff;
- const GLdouble scale = ctx->Pixel.DepthScale;
- const GLdouble bias = ctx->Pixel.DepthBias * max;
- GLuint i;
- for (i = 0; i < n; i++) {
- GLdouble d = (GLdouble) depthValues[i] * scale + bias;
- d = CLAMP(d, 0.0, max);
- depthValues[i] = (GLuint) d;
- }
-}
-
-/**
- * Apply various pixel transfer operations to an array of RGBA pixels
- * as indicated by the transferOps bitmask
- */
-void
-_mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps,
- GLuint n, GLfloat rgba[][4])
-{
- /* scale & bias */
- if (transferOps & IMAGE_SCALE_BIAS_BIT) {
- _mesa_scale_and_bias_rgba(n, rgba,
- ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
- ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
- ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
- ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
- }
- /* color map lookup */
- if (transferOps & IMAGE_MAP_COLOR_BIT) {
- _mesa_map_rgba( ctx, n, rgba );
- }
-
- /* clamping to [0,1] */
- if (transferOps & IMAGE_CLAMP_BIT) {
- GLuint i;
- for (i = 0; i < n; i++) {
- rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
- rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
- rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
- rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
- }
- }
-}
-
-
-/*
- * Apply color index shift and offset to an array of pixels.
- */
-void
-_mesa_shift_and_offset_ci(const struct gl_context *ctx,
- GLuint n, GLuint indexes[])
-{
- GLint shift = ctx->Pixel.IndexShift;
- GLint offset = ctx->Pixel.IndexOffset;
- GLuint i;
- if (shift > 0) {
- for (i=0;i<n;i++) {
- indexes[i] = (indexes[i] << shift) + offset;
- }
- }
- else if (shift < 0) {
- shift = -shift;
- for (i=0;i<n;i++) {
- indexes[i] = (indexes[i] >> shift) + offset;
- }
- }
- else {
- for (i=0;i<n;i++) {
- indexes[i] = indexes[i] + offset;
- }
- }
-}
-
-
-
-/**
- * Apply color index shift, offset and table lookup to an array
- * of color indexes;
- */
-void
-_mesa_apply_ci_transfer_ops(const struct gl_context *ctx,
- GLbitfield transferOps,
- GLuint n, GLuint indexes[])
-{
- if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
- _mesa_shift_and_offset_ci(ctx, n, indexes);
- }
- if (transferOps & IMAGE_MAP_COLOR_BIT) {
- const GLuint mask = ctx->PixelMaps.ItoI.Size - 1;
- GLuint i;
- for (i = 0; i < n; i++) {
- const GLuint j = indexes[i] & mask;
- indexes[i] = IROUND(ctx->PixelMaps.ItoI.Map[j]);
- }
- }
-}
-
-
-/**
- * Apply stencil index shift, offset and table lookup to an array
- * of stencil values.
- */
-void
-_mesa_apply_stencil_transfer_ops(const struct gl_context *ctx, GLuint n,
- GLstencil stencil[])
-{
- if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) {
- const GLint offset = ctx->Pixel.IndexOffset;
- GLint shift = ctx->Pixel.IndexShift;
- GLuint i;
- if (shift > 0) {
- for (i = 0; i < n; i++) {
- stencil[i] = (stencil[i] << shift) + offset;
- }
- }
- else if (shift < 0) {
- shift = -shift;
- for (i = 0; i < n; i++) {
- stencil[i] = (stencil[i] >> shift) + offset;
- }
- }
- else {
- for (i = 0; i < n; i++) {
- stencil[i] = stencil[i] + offset;
- }
- }
- }
- if (ctx->Pixel.MapStencilFlag) {
- GLuint mask = ctx->PixelMaps.StoS.Size - 1;
- GLuint i;
- for (i = 0; i < n; i++) {
- stencil[i] = (GLstencil)ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
- }
- }
-}
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009-2010 VMware, Inc. 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
+ * THE AUTHORS 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.
+ */
+
+
+/**
+ * \file pixeltransfer.c
+ * Pixel transfer operations (scale, bias, table lookups, etc)
+ */
+
+
+#include "glheader.h"
+#include "colormac.h"
+#include "pixeltransfer.h"
+#include "imports.h"
+#include "mtypes.h"
+
+
+/*
+ * Apply scale and bias factors to an array of RGBA pixels.
+ */
+void
+_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
+ GLfloat rScale, GLfloat gScale,
+ GLfloat bScale, GLfloat aScale,
+ GLfloat rBias, GLfloat gBias,
+ GLfloat bBias, GLfloat aBias)
+{
+ if (rScale != 1.0 || rBias != 0.0) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
+ }
+ }
+ if (gScale != 1.0 || gBias != 0.0) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
+ }
+ }
+ if (bScale != 1.0 || bBias != 0.0) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
+ }
+ }
+ if (aScale != 1.0 || aBias != 0.0) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
+ }
+ }
+}
+
+
+/*
+ * Apply pixel mapping to an array of floating point RGBA pixels.
+ */
+void
+_mesa_map_rgba( const struct gl_context *ctx, GLuint n, GLfloat rgba[][4] )
+{
+ const GLfloat rscale = (GLfloat) (ctx->PixelMaps.RtoR.Size - 1);
+ const GLfloat gscale = (GLfloat) (ctx->PixelMaps.GtoG.Size - 1);
+ const GLfloat bscale = (GLfloat) (ctx->PixelMaps.BtoB.Size - 1);
+ const GLfloat ascale = (GLfloat) (ctx->PixelMaps.AtoA.Size - 1);
+ const GLfloat *rMap = ctx->PixelMaps.RtoR.Map;
+ const GLfloat *gMap = ctx->PixelMaps.GtoG.Map;
+ const GLfloat *bMap = ctx->PixelMaps.BtoB.Map;
+ const GLfloat *aMap = ctx->PixelMaps.AtoA.Map;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
+ GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
+ GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
+ GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
+ rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
+ rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
+ rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
+ rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
+ }
+}
+
+/*
+ * Map color indexes to float rgba values.
+ */
+void
+_mesa_map_ci_to_rgba( const struct gl_context *ctx, GLuint n,
+ const GLuint index[], GLfloat rgba[][4] )
+{
+ GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
+ GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
+ GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
+ GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
+ const GLfloat *rMap = ctx->PixelMaps.ItoR.Map;
+ const GLfloat *gMap = ctx->PixelMaps.ItoG.Map;
+ const GLfloat *bMap = ctx->PixelMaps.ItoB.Map;
+ const GLfloat *aMap = ctx->PixelMaps.ItoA.Map;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ rgba[i][RCOMP] = rMap[index[i] & rmask];
+ rgba[i][GCOMP] = gMap[index[i] & gmask];
+ rgba[i][BCOMP] = bMap[index[i] & bmask];
+ rgba[i][ACOMP] = aMap[index[i] & amask];
+ }
+}
+
+
+/**
+ * Map ubyte color indexes to ubyte/RGBA values.
+ */
+void
+_mesa_map_ci8_to_rgba8(const struct gl_context *ctx,
+ GLuint n, const GLubyte index[],
+ GLubyte rgba[][4])
+{
+ GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
+ GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
+ GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
+ GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
+ const GLubyte *rMap = ctx->PixelMaps.ItoR.Map8;
+ const GLubyte *gMap = ctx->PixelMaps.ItoG.Map8;
+ const GLubyte *bMap = ctx->PixelMaps.ItoB.Map8;
+ const GLubyte *aMap = ctx->PixelMaps.ItoA.Map8;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ rgba[i][RCOMP] = rMap[index[i] & rmask];
+ rgba[i][GCOMP] = gMap[index[i] & gmask];
+ rgba[i][BCOMP] = bMap[index[i] & bmask];
+ rgba[i][ACOMP] = aMap[index[i] & amask];
+ }
+}
+
+
+void
+_mesa_scale_and_bias_depth(const struct gl_context *ctx, GLuint n,
+ GLfloat depthValues[])
+{
+ const GLfloat scale = ctx->Pixel.DepthScale;
+ const GLfloat bias = ctx->Pixel.DepthBias;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLfloat d = depthValues[i] * scale + bias;
+ depthValues[i] = CLAMP(d, 0.0F, 1.0F);
+ }
+}
+
+
+void
+_mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n,
+ GLuint depthValues[])
+{
+ const GLdouble max = (double) 0xffffffff;
+ const GLdouble scale = ctx->Pixel.DepthScale;
+ const GLdouble bias = ctx->Pixel.DepthBias * max;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLdouble d = (GLdouble) depthValues[i] * scale + bias;
+ d = CLAMP(d, 0.0, max);
+ depthValues[i] = (GLuint) d;
+ }
+}
+
+/**
+ * Apply various pixel transfer operations to an array of RGBA pixels
+ * as indicated by the transferOps bitmask
+ */
+void
+_mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps,
+ GLuint n, GLfloat rgba[][4])
+{
+ /* scale & bias */
+ if (transferOps & IMAGE_SCALE_BIAS_BIT) {
+ _mesa_scale_and_bias_rgba(n, rgba,
+ ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
+ ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
+ ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
+ ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
+ }
+ /* color map lookup */
+ if (transferOps & IMAGE_MAP_COLOR_BIT) {
+ _mesa_map_rgba( ctx, n, rgba );
+ }
+
+ /* clamping to [0,1] */
+ if (transferOps & IMAGE_CLAMP_BIT) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
+ rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
+ rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
+ rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
+ }
+ }
+}
+
+
+/*
+ * Apply color index shift and offset to an array of pixels.
+ */
+void
+_mesa_shift_and_offset_ci(const struct gl_context *ctx,
+ GLuint n, GLuint indexes[])
+{
+ GLint shift = ctx->Pixel.IndexShift;
+ GLint offset = ctx->Pixel.IndexOffset;
+ GLuint i;
+ if (shift > 0) {
+ for (i=0;i<n;i++) {
+ indexes[i] = (indexes[i] << shift) + offset;
+ }
+ }
+ else if (shift < 0) {
+ shift = -shift;
+ for (i=0;i<n;i++) {
+ indexes[i] = (indexes[i] >> shift) + offset;
+ }
+ }
+ else {
+ for (i=0;i<n;i++) {
+ indexes[i] = indexes[i] + offset;
+ }
+ }
+}
+
+
+
+/**
+ * Apply color index shift, offset and table lookup to an array
+ * of color indexes;
+ */
+void
+_mesa_apply_ci_transfer_ops(const struct gl_context *ctx,
+ GLbitfield transferOps,
+ GLuint n, GLuint indexes[])
+{
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ _mesa_shift_and_offset_ci(ctx, n, indexes);
+ }
+ if (transferOps & IMAGE_MAP_COLOR_BIT) {
+ const GLuint mask = ctx->PixelMaps.ItoI.Size - 1;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLuint j = indexes[i] & mask;
+ indexes[i] = IROUND(ctx->PixelMaps.ItoI.Map[j]);
+ }
+ }
+}
+
+
+/**
+ * Apply stencil index shift, offset and table lookup to an array
+ * of stencil values.
+ */
+void
+_mesa_apply_stencil_transfer_ops(const struct gl_context *ctx, GLuint n,
+ GLstencil stencil[])
+{
+ if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) {
+ const GLint offset = ctx->Pixel.IndexOffset;
+ GLint shift = ctx->Pixel.IndexShift;
+ GLuint i;
+ if (shift > 0) {
+ for (i = 0; i < n; i++) {
+ stencil[i] = (stencil[i] << shift) + offset;
+ }
+ }
+ else if (shift < 0) {
+ shift = -shift;
+ for (i = 0; i < n; i++) {
+ stencil[i] = (stencil[i] >> shift) + offset;
+ }
+ }
+ else {
+ for (i = 0; i < n; i++) {
+ stencil[i] = stencil[i] + offset;
+ }
+ }
+ }
+ if (ctx->Pixel.MapStencilFlag) {
+ GLuint mask = ctx->PixelMaps.StoS.Size - 1;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ stencil[i] = (GLstencil)ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
+ }
+ }
+}
diff --git a/mesalib/src/mesa/main/pixeltransfer.h b/mesalib/src/mesa/main/pixeltransfer.h
index c00da3f2a..8af2e9ee2 100644
--- a/mesalib/src/mesa/main/pixeltransfer.h
+++ b/mesalib/src/mesa/main/pixeltransfer.h
@@ -1,90 +1,81 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009-2010 VMware, Inc. 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
- * THE AUTHORS 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 PIXELTRANSFER_H
-#define PIXELTRANSFER_H
-
-
-#include "mtypes.h"
-
-
-extern void
-_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
- GLfloat rScale, GLfloat gScale,
- GLfloat bScale, GLfloat aScale,
- GLfloat rBias, GLfloat gBias,
- GLfloat bBias, GLfloat aBias);
-
-extern void
-_mesa_map_rgba(const struct gl_context *ctx, GLuint n, GLfloat rgba[][4]);
-
-extern void
-_mesa_lookup_rgba_float(const struct gl_color_table *table,
- GLuint n, GLfloat rgba[][4]);
-
-extern void
-_mesa_lookup_rgba_ubyte(const struct gl_color_table *table,
- GLuint n, GLubyte rgba[][4]);
-
-
-extern void
-_mesa_map_ci_to_rgba(const struct gl_context *ctx,
- GLuint n, const GLuint index[], GLfloat rgba[][4]);
-
-
-extern void
-_mesa_map_ci8_to_rgba8(const struct gl_context *ctx,
- GLuint n, const GLubyte index[],
- GLubyte rgba[][4]);
-
-
-extern void
-_mesa_scale_and_bias_depth(const struct gl_context *ctx, GLuint n,
- GLfloat depthValues[]);
-
-extern void
-_mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n,
- GLuint depthValues[]);
-
-extern void
-_mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps,
- GLuint n, GLfloat rgba[][4]);
-
-extern void
-_mesa_shift_and_offset_ci(const struct gl_context *ctx,
- GLuint n, GLuint indexes[]);
-
-extern void
-_mesa_apply_ci_transfer_ops(const struct gl_context *ctx,
- GLbitfield transferOps,
- GLuint n, GLuint indexes[]);
-
-
-extern void
-_mesa_apply_stencil_transfer_ops(const struct gl_context *ctx, GLuint n,
- GLstencil stencil[]);
-
-
-#endif
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009-2010 VMware, Inc. 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
+ * THE AUTHORS 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 PIXELTRANSFER_H
+#define PIXELTRANSFER_H
+
+
+#include "mtypes.h"
+
+
+extern void
+_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
+ GLfloat rScale, GLfloat gScale,
+ GLfloat bScale, GLfloat aScale,
+ GLfloat rBias, GLfloat gBias,
+ GLfloat bBias, GLfloat aBias);
+
+extern void
+_mesa_map_rgba(const struct gl_context *ctx, GLuint n, GLfloat rgba[][4]);
+
+extern void
+_mesa_map_ci_to_rgba(const struct gl_context *ctx,
+ GLuint n, const GLuint index[], GLfloat rgba[][4]);
+
+
+extern void
+_mesa_map_ci8_to_rgba8(const struct gl_context *ctx,
+ GLuint n, const GLubyte index[],
+ GLubyte rgba[][4]);
+
+
+extern void
+_mesa_scale_and_bias_depth(const struct gl_context *ctx, GLuint n,
+ GLfloat depthValues[]);
+
+extern void
+_mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n,
+ GLuint depthValues[]);
+
+extern void
+_mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps,
+ GLuint n, GLfloat rgba[][4]);
+
+extern void
+_mesa_shift_and_offset_ci(const struct gl_context *ctx,
+ GLuint n, GLuint indexes[]);
+
+extern void
+_mesa_apply_ci_transfer_ops(const struct gl_context *ctx,
+ GLbitfield transferOps,
+ GLuint n, GLuint indexes[]);
+
+
+extern void
+_mesa_apply_stencil_transfer_ops(const struct gl_context *ctx, GLuint n,
+ GLstencil stencil[]);
+
+
+#endif
diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c
index 075c40c86..4f02720ce 100644
--- a/mesalib/src/mesa/main/texformat.c
+++ b/mesalib/src/mesa/main/texformat.c
@@ -197,13 +197,6 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
RETURN_IF_SUPPORTED(MESA_FORMAT_I8);
break;
- case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
- case GL_COLOR_INDEX8_EXT:
default:
; /* fallthrough */
}
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c
index b2ebb0de4..99ace91a9 100644
--- a/mesalib/src/mesa/main/texgetimage.c
+++ b/mesalib/src/mesa/main/texgetimage.c
@@ -65,55 +65,6 @@ type_with_negative_values(GLenum type)
/**
- * glGetTexImage for color index pixels.
- */
-static void
-get_tex_color_index(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
- const GLint rowstride = texImage->RowStride;
- const GLuint indexBits =
- _mesa_get_format_bits(texImage->TexFormat, GL_TEXTURE_INDEX_SIZE_EXT);
- const GLbitfield transferOps = 0x0;
- GLint img, row, col;
-
- for (img = 0; img < depth; img++) {
- for (row = 0; row < height; row++) {
- GLuint indexRow[MAX_WIDTH] = { 0 };
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
- assert(dest);
-
- if (indexBits == 8) {
- const GLubyte *src = (const GLubyte *) texImage->Data;
- src += rowstride * (img * height + row);
- for (col = 0; col < width; col++) {
- indexRow[col] = src[col];
- }
- }
- else if (indexBits == 16) {
- const GLushort *src = (const GLushort *) texImage->Data;
- src += rowstride * (img * height + row);
- for (col = 0; col < width; col++) {
- indexRow[col] = src[col];
- }
- }
- else {
- _mesa_problem(ctx, "Color index problem in _mesa_GetTexImage");
- }
- _mesa_pack_index_span(ctx, width, type, dest,
- indexRow, &ctx->Pack, transferOps);
- }
- }
-}
-
-
-/**
* glGetTexImage for depth/Z pixels.
*/
static void
@@ -457,9 +408,6 @@ _mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
if (get_tex_memcpy(ctx, format, type, pixels, texObj, texImage)) {
/* all done */
}
- else if (format == GL_COLOR_INDEX) {
- get_tex_color_index(ctx, dimensions, format, type, pixels, texImage);
- }
else if (format == GL_DEPTH_COMPONENT) {
get_tex_depth(ctx, dimensions, format, type, pixels, texImage);
}
@@ -567,16 +515,12 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
}
if (_mesa_components_in_format(format) <= 0 ||
- format == GL_STENCIL_INDEX) {
+ format == GL_STENCIL_INDEX ||
+ format == GL_COLOR_INDEX) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
return GL_TRUE;
}
- if (!ctx->Extensions.EXT_paletted_texture && _mesa_is_index_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
if (!ctx->Extensions.ARB_depth_texture && _mesa_is_depth_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
@@ -615,17 +559,10 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
/* Make sure the requested image format is compatible with the
- * texture's format. Note that a color index texture can be converted
- * to RGBA so that combo is allowed.
+ * texture's format.
*/
if (_mesa_is_color_format(format)
- && !_mesa_is_color_format(baseFormat)
- && !_mesa_is_index_format(baseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (_mesa_is_index_format(format)
- && !_mesa_is_index_format(baseFormat)) {
+ && !_mesa_is_color_format(baseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 886e52114..cb4a5b4e4 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -159,21 +159,6 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
}
}
- if (ctx->Extensions.EXT_paletted_texture) {
- switch (internalFormat) {
- case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX8_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
- return GL_COLOR_INDEX;
- default:
- ; /* fallthrough */
- }
- }
-
if (ctx->Extensions.ARB_depth_texture) {
switch (internalFormat) {
case GL_DEPTH_COMPONENT:
@@ -1554,7 +1539,13 @@ texture_error_check( struct gl_context *ctx,
const GLenum proxyTarget = get_proxy_target(target);
const GLboolean isProxy = target == proxyTarget;
GLboolean sizeOK = GL_TRUE;
- GLboolean colorFormat, indexFormat;
+ GLboolean colorFormat;
+
+ /* Even though there are no color-index textures, we still have to support
+ * uploading color-index data and remapping it to RGB via the
+ * GL_PIXEL_MAP_I_TO_[RGBA] tables.
+ */
+ const GLboolean indexFormat = (format == GL_COLOR_INDEX);
/* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
@@ -1635,9 +1626,7 @@ texture_error_check( struct gl_context *ctx,
/* make sure internal format and format basically agree */
colorFormat = _mesa_is_color_format(format);
- indexFormat = _mesa_is_index_format(format);
if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
- (_mesa_is_index_format(internalFormat) && !indexFormat) ||
(_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
(_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
(_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index 078a43ab1..1168f1842 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -198,8 +198,6 @@ _mesa_delete_texture_object(struct gl_context *ctx,
*/
texObj->Target = 0x99;
- _mesa_free_colortable_data(&texObj->Palette);
-
/* free the texture images */
for (face = 0; face < 6; face++) {
for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
@@ -258,7 +256,6 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
dest->_MaxLevel = src->_MaxLevel;
dest->_MaxLambda = src->_MaxLambda;
dest->GenerateMipmap = src->GenerateMipmap;
- dest->Palette = src->Palette;
dest->_Complete = src->_Complete;
COPY_4V(dest->Swizzle, src->Swizzle);
dest->_Swizzle = src->_Swizzle;
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index bbbb306b2..19a01a14d 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -987,12 +987,6 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
}
}
break;
- case GL_TEXTURE_INDEX_SIZE_EXT:
- if (img->_BaseFormat == GL_COLOR_INDEX)
- *params = _mesa_get_format_bits(texFormat, pname);
- else
- *params = 0;
- break;
case GL_TEXTURE_DEPTH_SIZE_ARB:
if (!ctx->Extensions.ARB_depth_texture)
goto invalid_pname;
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index 1810b88b2..e02f16240 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -75,7 +75,6 @@ _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
dst->Texture._GenFlags = src->Texture._GenFlags;
dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
- dst->Texture.SharedPalette = src->Texture.SharedPalette;
/* per-unit state */
for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
@@ -402,11 +401,8 @@ update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
else {
const struct gl_texture_object *texObj = texUnit->_Current;
GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
- if (format == GL_COLOR_INDEX) {
- format = GL_RGBA; /* a bit of a hack */
- }
- else if (format == GL_DEPTH_COMPONENT ||
- format == GL_DEPTH_STENCIL_EXT) {
+
+ if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
format = texObj->Sampler.DepthMode;
}
calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
@@ -778,8 +774,6 @@ _mesa_init_texture(struct gl_context *ctx)
/* Texture group */
ctx->Texture.CurrentUnit = 0; /* multitexture */
ctx->Texture._EnabledUnits = 0x0;
- ctx->Texture.SharedPalette = GL_FALSE;
- _mesa_init_colortable(&ctx->Texture.Palette);
for (u = 0; u < Elements(ctx->Texture.Unit); u++)
init_texture_unit(ctx, u);
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index e9915a7f0..2cdc8ed67 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -340,7 +340,6 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
logicalBaseFormat == GL_LUMINANCE ||
logicalBaseFormat == GL_ALPHA ||
logicalBaseFormat == GL_INTENSITY ||
- logicalBaseFormat == GL_COLOR_INDEX ||
logicalBaseFormat == GL_DEPTH_COMPONENT);
ASSERT(textureBaseFormat == GL_RGBA ||
@@ -351,7 +350,6 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
textureBaseFormat == GL_LUMINANCE ||
textureBaseFormat == GL_ALPHA ||
textureBaseFormat == GL_INTENSITY ||
- textureBaseFormat == GL_COLOR_INDEX ||
textureBaseFormat == GL_DEPTH_COMPONENT);
tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c
index 9c9d0d66e..13b3405e5 100644
--- a/mesalib/src/mesa/main/varray.c
+++ b/mesalib/src/mesa/main/varray.c
@@ -160,10 +160,17 @@ update_array(struct gl_context *ctx,
if (ctx->Extensions.EXT_vertex_array_bgra &&
sizeMax == BGRA_OR_4 &&
size == GL_BGRA) {
- if (type != GL_UNSIGNED_BYTE &&
- (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
- (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
- type != GL_INT_2_10_10_10_REV))) {
+ GLboolean bgra_error = GL_FALSE;
+
+ if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
+ if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
+ type != GL_INT_2_10_10_10_REV &&
+ type != GL_UNSIGNED_BYTE)
+ bgra_error = GL_TRUE;
+ } else if (type != GL_UNSIGNED_BYTE)
+ bgra_error = GL_TRUE;
+
+ if (bgra_error) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func);
return;
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_eglimage.c b/mesalib/src/mesa/state_tracker/st_cb_eglimage.c
index d7518c0b4..531296fb3 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_eglimage.c
@@ -1,170 +1,169 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * 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
- * THE AUTHORS OR COPYRIGHT HOLDERS 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:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include "main/mfeatures.h"
-#include "main/texobj.h"
-#include "main/texfetch.h"
-#include "main/teximage.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "st_cb_eglimage.h"
-#include "st_cb_fbo.h"
-#include "st_context.h"
-#include "st_texture.h"
-#include "st_format.h"
-#include "st_manager.h"
-
-#if FEATURE_OES_EGL_image
-
-/**
- * Return the base format just like _mesa_base_fbo_format does.
- */
-static GLenum
-st_pipe_format_to_base_format(enum pipe_format format)
-{
- GLenum base_format;
-
- if (util_format_is_depth_or_stencil(format)) {
- if (util_format_is_depth_and_stencil(format)) {
- base_format = GL_DEPTH_STENCIL;
- }
- else {
- if (format == PIPE_FORMAT_S8_USCALED)
- base_format = GL_STENCIL_INDEX;
- else
- base_format = GL_DEPTH_COMPONENT;
- }
- }
- else {
- /* is this enough? */
- if (util_format_has_alpha(format))
- base_format = GL_RGBA;
- else
- base_format = GL_RGB;
- }
-
- return base_format;
-}
-
-static void
-st_egl_image_target_renderbuffer_storage(struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLeglImageOES image_handle)
-{
- struct st_context *st = st_context(ctx);
- struct st_renderbuffer *strb = st_renderbuffer(rb);
- struct pipe_surface *ps;
- unsigned usage;
-
- usage = PIPE_BIND_RENDER_TARGET;
- ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage);
- if (ps) {
- strb->Base.Width = ps->width;
- strb->Base.Height = ps->height;
- strb->Base.Format = st_pipe_format_to_mesa_format(ps->format);
- strb->Base.DataType = st_format_datatype(ps->format);
- strb->Base._BaseFormat = st_pipe_format_to_base_format(ps->format);
- strb->Base.InternalFormat = strb->Base._BaseFormat;
-
- pipe_surface_reference(&strb->surface, ps);
- pipe_resource_reference(&strb->texture, ps->texture);
-
- pipe_surface_reference(&ps, NULL);
- }
-}
-
-static void
-st_bind_surface(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- struct pipe_surface *ps)
-{
- struct st_texture_object *stObj;
- struct st_texture_image *stImage;
- GLenum internalFormat;
- gl_format texFormat;
-
- /* map pipe format to base format */
- if (util_format_get_component_bits(ps->format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
- internalFormat = GL_RGBA;
- else
- internalFormat = GL_RGB;
-
- stObj = st_texture_object(texObj);
- stImage = st_texture_image(texImage);
-
- /* switch to surface based */
- if (!stObj->surface_based) {
- _mesa_clear_texture_object(ctx, texObj);
- stObj->surface_based = GL_TRUE;
- }
-
- texFormat = st_pipe_format_to_mesa_format(ps->format);
-
- _mesa_init_teximage_fields(ctx, target, texImage,
- ps->width, ps->height, 1, 0, internalFormat,
- texFormat);
-
- /* FIXME create a non-default sampler view from the pipe_surface? */
- pipe_resource_reference(&stObj->pt, ps->texture);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
- pipe_resource_reference(&stImage->pt, stObj->pt);
-
- stObj->width0 = ps->width;
- stObj->height0 = ps->height;
- stObj->depth0 = 1;
-
- _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
-}
-
-static void
-st_egl_image_target_texture_2d(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- GLeglImageOES image_handle)
-{
- struct st_context *st = st_context(ctx);
- struct pipe_surface *ps;
- unsigned usage;
-
- usage = PIPE_BIND_SAMPLER_VIEW;
- ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage);
- if (ps) {
- st_bind_surface(ctx, target, texObj, texImage, ps);
- pipe_surface_reference(&ps, NULL);
- }
-}
-
-void
-st_init_eglimage_functions(struct dd_function_table *functions)
-{
- functions->EGLImageTargetTexture2D = st_egl_image_target_texture_2d;
- functions->EGLImageTargetRenderbufferStorage = st_egl_image_target_renderbuffer_storage;
-}
-
-#endif /* FEATURE_OES_EGL_image */
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "main/mfeatures.h"
+#include "main/texobj.h"
+#include "main/teximage.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "st_cb_eglimage.h"
+#include "st_cb_fbo.h"
+#include "st_context.h"
+#include "st_texture.h"
+#include "st_format.h"
+#include "st_manager.h"
+
+#if FEATURE_OES_EGL_image
+
+/**
+ * Return the base format just like _mesa_base_fbo_format does.
+ */
+static GLenum
+st_pipe_format_to_base_format(enum pipe_format format)
+{
+ GLenum base_format;
+
+ if (util_format_is_depth_or_stencil(format)) {
+ if (util_format_is_depth_and_stencil(format)) {
+ base_format = GL_DEPTH_STENCIL;
+ }
+ else {
+ if (format == PIPE_FORMAT_S8_USCALED)
+ base_format = GL_STENCIL_INDEX;
+ else
+ base_format = GL_DEPTH_COMPONENT;
+ }
+ }
+ else {
+ /* is this enough? */
+ if (util_format_has_alpha(format))
+ base_format = GL_RGBA;
+ else
+ base_format = GL_RGB;
+ }
+
+ return base_format;
+}
+
+static void
+st_egl_image_target_renderbuffer_storage(struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ GLeglImageOES image_handle)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_renderbuffer *strb = st_renderbuffer(rb);
+ struct pipe_surface *ps;
+ unsigned usage;
+
+ usage = PIPE_BIND_RENDER_TARGET;
+ ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage);
+ if (ps) {
+ strb->Base.Width = ps->width;
+ strb->Base.Height = ps->height;
+ strb->Base.Format = st_pipe_format_to_mesa_format(ps->format);
+ strb->Base.DataType = st_format_datatype(ps->format);
+ strb->Base._BaseFormat = st_pipe_format_to_base_format(ps->format);
+ strb->Base.InternalFormat = strb->Base._BaseFormat;
+
+ pipe_surface_reference(&strb->surface, ps);
+ pipe_resource_reference(&strb->texture, ps->texture);
+
+ pipe_surface_reference(&ps, NULL);
+ }
+}
+
+static void
+st_bind_surface(struct gl_context *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ struct pipe_surface *ps)
+{
+ struct st_texture_object *stObj;
+ struct st_texture_image *stImage;
+ GLenum internalFormat;
+ gl_format texFormat;
+
+ /* map pipe format to base format */
+ if (util_format_get_component_bits(ps->format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
+ internalFormat = GL_RGBA;
+ else
+ internalFormat = GL_RGB;
+
+ stObj = st_texture_object(texObj);
+ stImage = st_texture_image(texImage);
+
+ /* switch to surface based */
+ if (!stObj->surface_based) {
+ _mesa_clear_texture_object(ctx, texObj);
+ stObj->surface_based = GL_TRUE;
+ }
+
+ texFormat = st_pipe_format_to_mesa_format(ps->format);
+
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ ps->width, ps->height, 1, 0, internalFormat,
+ texFormat);
+
+ /* FIXME create a non-default sampler view from the pipe_surface? */
+ pipe_resource_reference(&stObj->pt, ps->texture);
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ pipe_resource_reference(&stImage->pt, stObj->pt);
+
+ stObj->width0 = ps->width;
+ stObj->height0 = ps->height;
+ stObj->depth0 = 1;
+
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
+}
+
+static void
+st_egl_image_target_texture_2d(struct gl_context *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ GLeglImageOES image_handle)
+{
+ struct st_context *st = st_context(ctx);
+ struct pipe_surface *ps;
+ unsigned usage;
+
+ usage = PIPE_BIND_SAMPLER_VIEW;
+ ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage);
+ if (ps) {
+ st_bind_surface(ctx, target, texObj, texImage, ps);
+ pipe_surface_reference(&ps, NULL);
+ }
+}
+
+void
+st_init_eglimage_functions(struct dd_function_table *functions)
+{
+ functions->EGLImageTargetTexture2D = st_egl_image_target_texture_2d;
+ functions->EGLImageTargetRenderbufferStorage = st_egl_image_target_renderbuffer_storage;
+}
+
+#endif /* FEATURE_OES_EGL_image */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c
index 5b9e20374..d43f67ac9 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c
@@ -112,7 +112,6 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx,
*/
pipe_surface_reference( &strb->surface, NULL );
pipe_resource_reference( &strb->texture, NULL );
- pipe_sampler_view_reference(&strb->sampler_view, NULL);
/* Setup new texture template.
*/
@@ -165,7 +164,6 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb)
ASSERT(strb);
pipe_surface_reference(&strb->surface, NULL);
pipe_resource_reference(&strb->texture, NULL);
- pipe_sampler_view_reference(&strb->sampler_view, NULL);
free(strb->data);
free(strb);
}
@@ -388,9 +386,6 @@ st_render_texture(struct gl_context *ctx,
pipe_surface_reference(&strb->surface, NULL);
- pipe_sampler_view_reference(&strb->sampler_view,
- st_get_texture_sampler_view(stObj, pipe));
-
assert(strb->rtt_level <= strb->texture->last_level);
/* new surface for rendering into the texture */
@@ -650,14 +645,4 @@ void st_init_fbo_functions(struct dd_function_table *functions)
functions->ReadBuffer = st_ReadBuffer;
}
-/* XXX unused ? */
-struct pipe_sampler_view *
-st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb,
- struct pipe_context *pipe)
-{
- if (!rb->sampler_view) {
- rb->sampler_view = st_create_texture_sampler_view(pipe, rb->texture);
- }
- return rb->sampler_view;
-}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.h b/mesalib/src/mesa/state_tracker/st_cb_fbo.h
index 228be8fed..1afa3fe6e 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_fbo.h
+++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.h
@@ -1,96 +1,84 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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, sub license, 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 ST_CB_FBO_H
-#define ST_CB_FBO_H
-
-#include "main/compiler.h"
-#include "main/glheader.h"
-#include "main/mtypes.h"
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_format.h"
-
-struct dd_function_table;
-struct pipe_context;
-
-/**
- * Derived renderbuffer class. Just need to add a pointer to the
- * pipe surface.
- */
-struct st_renderbuffer
-{
- struct gl_renderbuffer Base;
- struct pipe_resource *texture;
- struct pipe_surface *surface; /* temporary view into texture */
- struct pipe_sampler_view *sampler_view;
- enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */
- GLboolean defined; /**< defined contents? */
-
- /**
- * Used only when hardware accumulation buffers are not supported.
- */
- boolean software;
- size_t stride;
- void *data;
-
- struct st_texture_object *rtt; /**< GL render to texture's texture */
- int rtt_level, rtt_face, rtt_slice;
-
- /** Render to texture state */
- struct pipe_resource *texture_save;
- struct pipe_surface *surface_save;
- struct pipe_sampler_view *sampler_view_save;
-};
-
-
-static INLINE struct st_renderbuffer *
-st_renderbuffer(struct gl_renderbuffer *rb)
-{
- return (struct st_renderbuffer *) rb;
-}
-
-
-extern struct gl_renderbuffer *
-st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw);
-
-extern void
-st_init_fbo_functions(struct dd_function_table *functions);
-
-/* XXX unused ? */
-extern struct pipe_sampler_view *
-st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb,
- struct pipe_context *pipe);
-
-
-extern GLboolean
-st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth,
- const struct gl_renderbuffer_attachment *stencil);
-
-
-#endif /* ST_CB_FBO_H */
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 ST_CB_FBO_H
+#define ST_CB_FBO_H
+
+#include "main/compiler.h"
+#include "main/glheader.h"
+#include "main/mtypes.h"
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+
+struct dd_function_table;
+struct pipe_context;
+
+/**
+ * Derived renderbuffer class. Just need to add a pointer to the
+ * pipe surface.
+ */
+struct st_renderbuffer
+{
+ struct gl_renderbuffer Base;
+ struct pipe_resource *texture;
+ struct pipe_surface *surface; /* temporary view into texture */
+ enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */
+ GLboolean defined; /**< defined contents? */
+
+ /**
+ * Used only when hardware accumulation buffers are not supported.
+ */
+ boolean software;
+ size_t stride;
+ void *data;
+
+ struct st_texture_object *rtt; /**< GL render to texture's texture */
+ int rtt_level, rtt_face, rtt_slice;
+};
+
+
+static INLINE struct st_renderbuffer *
+st_renderbuffer(struct gl_renderbuffer *rb)
+{
+ return (struct st_renderbuffer *) rb;
+}
+
+
+extern struct gl_renderbuffer *
+st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw);
+
+extern void
+st_init_fbo_functions(struct dd_function_table *functions);
+
+extern GLboolean
+st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth,
+ const struct gl_renderbuffer_attachment *stencil);
+
+
+#endif /* ST_CB_FBO_H */
diff --git a/mesalib/src/mesa/swrast/s_drawpix.c b/mesalib/src/mesa/swrast/s_drawpix.c
index 11c63457f..63bfa79b5 100644
--- a/mesalib/src/mesa/swrast/s_drawpix.c
+++ b/mesalib/src/mesa/swrast/s_drawpix.c
@@ -335,7 +335,7 @@ draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y,
? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
const GLvoid *source = _mesa_image_address2d(unpack, pixels,
width, height,
- GL_COLOR_INDEX, type,
+ GL_STENCIL_INDEX, type,
row, skipPixels);
_mesa_unpack_stencil_span(ctx, spanWidth, destType, values,
type, source, unpack,
diff --git a/mesalib/src/mesa/swrast/s_texfilter.c b/mesalib/src/mesa/swrast/s_texfilter.c
index 237e5d28a..ad31e3778 100644
--- a/mesalib/src/mesa/swrast/s_texfilter.c
+++ b/mesalib/src/mesa/swrast/s_texfilter.c
@@ -1,3710 +1,3706 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 1999-2008 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.
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/colormac.h"
-#include "main/imports.h"
-
-#include "s_context.h"
-#include "s_texfilter.h"
-
-
-/*
- * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes
- * see 1-pixel bands of improperly weighted linear-filtered textures.
- * The tests/texwrap.c demo is a good test.
- * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
- * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
- */
-#define FRAC(f) ((f) - IFLOOR(f))
-
-
-
-/**
- * Linear interpolation macro
- */
-#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) )
-
-
-/**
- * Do 2D/biliner interpolation of float values.
- * v00, v10, v01 and v11 are typically four texture samples in a square/box.
- * a and b are the horizontal and vertical interpolants.
- * It's important that this function is inlined when compiled with
- * optimization! If we find that's not true on some systems, convert
- * to a macro.
- */
-static INLINE GLfloat
-lerp_2d(GLfloat a, GLfloat b,
- GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11)
-{
- const GLfloat temp0 = LERP(a, v00, v10);
- const GLfloat temp1 = LERP(a, v01, v11);
- return LERP(b, temp0, temp1);
-}
-
-
-/**
- * Do 3D/trilinear interpolation of float values.
- * \sa lerp_2d
- */
-static INLINE GLfloat
-lerp_3d(GLfloat a, GLfloat b, GLfloat c,
- GLfloat v000, GLfloat v100, GLfloat v010, GLfloat v110,
- GLfloat v001, GLfloat v101, GLfloat v011, GLfloat v111)
-{
- const GLfloat temp00 = LERP(a, v000, v100);
- const GLfloat temp10 = LERP(a, v010, v110);
- const GLfloat temp01 = LERP(a, v001, v101);
- const GLfloat temp11 = LERP(a, v011, v111);
- const GLfloat temp0 = LERP(b, temp00, temp10);
- const GLfloat temp1 = LERP(b, temp01, temp11);
- return LERP(c, temp0, temp1);
-}
-
-
-/**
- * Do linear interpolation of colors.
- */
-static INLINE void
-lerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4])
-{
- result[0] = LERP(t, a[0], b[0]);
- result[1] = LERP(t, a[1], b[1]);
- result[2] = LERP(t, a[2], b[2]);
- result[3] = LERP(t, a[3], b[3]);
-}
-
-
-/**
- * Do bilinear interpolation of colors.
- */
-static INLINE void
-lerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b,
- const GLfloat t00[4], const GLfloat t10[4],
- const GLfloat t01[4], const GLfloat t11[4])
-{
- result[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]);
- result[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]);
- result[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]);
- result[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]);
-}
-
-
-/**
- * Do trilinear interpolation of colors.
- */
-static INLINE void
-lerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c,
- const GLfloat t000[4], const GLfloat t100[4],
- const GLfloat t010[4], const GLfloat t110[4],
- const GLfloat t001[4], const GLfloat t101[4],
- const GLfloat t011[4], const GLfloat t111[4])
-{
- GLuint k;
- /* compiler should unroll these short loops */
- for (k = 0; k < 4; k++) {
- result[k] = lerp_3d(a, b, c, t000[k], t100[k], t010[k], t110[k],
- t001[k], t101[k], t011[k], t111[k]);
- }
-}
-
-
-/**
- * Used for GL_REPEAT wrap mode. Using A % B doesn't produce the
- * right results for A<0. Casting to A to be unsigned only works if B
- * is a power of two. Adding a bias to A (which is a multiple of B)
- * avoids the problems with A < 0 (for reasonable A) without using a
- * conditional.
- */
-#define REMAINDER(A, B) (((A) + (B) * 1024) % (B))
-
-
-/**
- * Used to compute texel locations for linear sampling.
- * Input:
- * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER
- * s = texcoord in [0,1]
- * size = width (or height or depth) of texture
- * Output:
- * i0, i1 = returns two nearest texel indexes
- * weight = returns blend factor between texels
- */
-static INLINE void
-linear_texel_locations(GLenum wrapMode,
- const struct gl_texture_image *img,
- GLint size, GLfloat s,
- GLint *i0, GLint *i1, GLfloat *weight)
-{
- GLfloat u;
- switch (wrapMode) {
- case GL_REPEAT:
- u = s * size - 0.5F;
- if (img->_IsPowerOfTwo) {
- *i0 = IFLOOR(u) & (size - 1);
- *i1 = (*i0 + 1) & (size - 1);
- }
- else {
- *i0 = REMAINDER(IFLOOR(u), size);
- *i1 = REMAINDER(*i0 + 1, size);
- }
- break;
- case GL_CLAMP_TO_EDGE:
- if (s <= 0.0F)
- u = 0.0F;
- else if (s >= 1.0F)
- u = (GLfloat) size;
- else
- u = s * size;
- u -= 0.5F;
- *i0 = IFLOOR(u);
- *i1 = *i0 + 1;
- if (*i0 < 0)
- *i0 = 0;
- if (*i1 >= (GLint) size)
- *i1 = size - 1;
- break;
- case GL_CLAMP_TO_BORDER:
- {
- const GLfloat min = -1.0F / (2.0F * size);
- const GLfloat max = 1.0F - min;
- if (s <= min)
- u = min * size;
- else if (s >= max)
- u = max * size;
- else
- u = s * size;
- u -= 0.5F;
- *i0 = IFLOOR(u);
- *i1 = *i0 + 1;
- }
- break;
- case GL_MIRRORED_REPEAT:
- {
- const GLint flr = IFLOOR(s);
- if (flr & 1)
- u = 1.0F - (s - (GLfloat) flr);
- else
- u = s - (GLfloat) flr;
- u = (u * size) - 0.5F;
- *i0 = IFLOOR(u);
- *i1 = *i0 + 1;
- if (*i0 < 0)
- *i0 = 0;
- if (*i1 >= (GLint) size)
- *i1 = size - 1;
- }
- break;
- case GL_MIRROR_CLAMP_EXT:
- u = FABSF(s);
- if (u >= 1.0F)
- u = (GLfloat) size;
- else
- u *= size;
- u -= 0.5F;
- *i0 = IFLOOR(u);
- *i1 = *i0 + 1;
- break;
- case GL_MIRROR_CLAMP_TO_EDGE_EXT:
- u = FABSF(s);
- if (u >= 1.0F)
- u = (GLfloat) size;
- else
- u *= size;
- u -= 0.5F;
- *i0 = IFLOOR(u);
- *i1 = *i0 + 1;
- if (*i0 < 0)
- *i0 = 0;
- if (*i1 >= (GLint) size)
- *i1 = size - 1;
- break;
- case GL_MIRROR_CLAMP_TO_BORDER_EXT:
- {
- const GLfloat min = -1.0F / (2.0F * size);
- const GLfloat max = 1.0F - min;
- u = FABSF(s);
- if (u <= min)
- u = min * size;
- else if (u >= max)
- u = max * size;
- else
- u *= size;
- u -= 0.5F;
- *i0 = IFLOOR(u);
- *i1 = *i0 + 1;
- }
- break;
- case GL_CLAMP:
- if (s <= 0.0F)
- u = 0.0F;
- else if (s >= 1.0F)
- u = (GLfloat) size;
- else
- u = s * size;
- u -= 0.5F;
- *i0 = IFLOOR(u);
- *i1 = *i0 + 1;
- break;
- default:
- _mesa_problem(NULL, "Bad wrap mode");
- u = 0.0F;
- }
- *weight = FRAC(u);
-}
-
-
-/**
- * Used to compute texel location for nearest sampling.
- */
-static INLINE GLint
-nearest_texel_location(GLenum wrapMode,
- const struct gl_texture_image *img,
- GLint size, GLfloat s)
-{
- GLint i;
-
- switch (wrapMode) {
- case GL_REPEAT:
- /* s limited to [0,1) */
- /* i limited to [0,size-1] */
- i = IFLOOR(s * size);
- if (img->_IsPowerOfTwo)
- i &= (size - 1);
- else
- i = REMAINDER(i, size);
- return i;
- case GL_CLAMP_TO_EDGE:
- {
- /* s limited to [min,max] */
- /* i limited to [0, size-1] */
- const GLfloat min = 1.0F / (2.0F * size);
- const GLfloat max = 1.0F - min;
- if (s < min)
- i = 0;
- else if (s > max)
- i = size - 1;
- else
- i = IFLOOR(s * size);
- }
- return i;
- case GL_CLAMP_TO_BORDER:
- {
- /* s limited to [min,max] */
- /* i limited to [-1, size] */
- const GLfloat min = -1.0F / (2.0F * size);
- const GLfloat max = 1.0F - min;
- if (s <= min)
- i = -1;
- else if (s >= max)
- i = size;
- else
- i = IFLOOR(s * size);
- }
- return i;
- case GL_MIRRORED_REPEAT:
- {
- const GLfloat min = 1.0F / (2.0F * size);
- const GLfloat max = 1.0F - min;
- const GLint flr = IFLOOR(s);
- GLfloat u;
- if (flr & 1)
- u = 1.0F - (s - (GLfloat) flr);
- else
- u = s - (GLfloat) flr;
- if (u < min)
- i = 0;
- else if (u > max)
- i = size - 1;
- else
- i = IFLOOR(u * size);
- }
- return i;
- case GL_MIRROR_CLAMP_EXT:
- {
- /* s limited to [0,1] */
- /* i limited to [0,size-1] */
- const GLfloat u = FABSF(s);
- if (u <= 0.0F)
- i = 0;
- else if (u >= 1.0F)
- i = size - 1;
- else
- i = IFLOOR(u * size);
- }
- return i;
- case GL_MIRROR_CLAMP_TO_EDGE_EXT:
- {
- /* s limited to [min,max] */
- /* i limited to [0, size-1] */
- const GLfloat min = 1.0F / (2.0F * size);
- const GLfloat max = 1.0F - min;
- const GLfloat u = FABSF(s);
- if (u < min)
- i = 0;
- else if (u > max)
- i = size - 1;
- else
- i = IFLOOR(u * size);
- }
- return i;
- case GL_MIRROR_CLAMP_TO_BORDER_EXT:
- {
- /* s limited to [min,max] */
- /* i limited to [0, size-1] */
- const GLfloat min = -1.0F / (2.0F * size);
- const GLfloat max = 1.0F - min;
- const GLfloat u = FABSF(s);
- if (u < min)
- i = -1;
- else if (u > max)
- i = size;
- else
- i = IFLOOR(u * size);
- }
- return i;
- case GL_CLAMP:
- /* s limited to [0,1] */
- /* i limited to [0,size-1] */
- if (s <= 0.0F)
- i = 0;
- else if (s >= 1.0F)
- i = size - 1;
- else
- i = IFLOOR(s * size);
- return i;
- default:
- _mesa_problem(NULL, "Bad wrap mode");
- return 0;
- }
-}
-
-
-/* Power of two image sizes only */
-static INLINE void
-linear_repeat_texel_location(GLuint size, GLfloat s,
- GLint *i0, GLint *i1, GLfloat *weight)
-{
- GLfloat u = s * size - 0.5F;
- *i0 = IFLOOR(u) & (size - 1);
- *i1 = (*i0 + 1) & (size - 1);
- *weight = FRAC(u);
-}
-
-
-/**
- * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode.
- */
-static INLINE GLint
-clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max)
-{
- switch (wrapMode) {
- case GL_CLAMP:
- return IFLOOR( CLAMP(coord, 0.0F, max - 1) );
- case GL_CLAMP_TO_EDGE:
- return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) );
- case GL_CLAMP_TO_BORDER:
- return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) );
- default:
- _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest");
- return 0;
- }
-}
-
-
-/**
- * As above, but GL_LINEAR filtering.
- */
-static INLINE void
-clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max,
- GLint *i0out, GLint *i1out, GLfloat *weight)
-{
- GLfloat fcol;
- GLint i0, i1;
- switch (wrapMode) {
- case GL_CLAMP:
- /* Not exactly what the spec says, but it matches NVIDIA output */
- fcol = CLAMP(coord - 0.5F, 0.0F, max - 1);
- i0 = IFLOOR(fcol);
- i1 = i0 + 1;
- break;
- case GL_CLAMP_TO_EDGE:
- fcol = CLAMP(coord, 0.5F, max - 0.5F);
- fcol -= 0.5F;
- i0 = IFLOOR(fcol);
- i1 = i0 + 1;
- if (i1 > max - 1)
- i1 = max - 1;
- break;
- case GL_CLAMP_TO_BORDER:
- fcol = CLAMP(coord, -0.5F, max + 0.5F);
- fcol -= 0.5F;
- i0 = IFLOOR(fcol);
- i1 = i0 + 1;
- break;
- default:
- _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear");
- i0 = i1 = 0;
- fcol = 0.0F;
- }
- *i0out = i0;
- *i1out = i1;
- *weight = FRAC(fcol);
-}
-
-
-/**
- * Compute slice/image to use for 1D or 2D array texture.
- */
-static INLINE GLint
-tex_array_slice(GLfloat coord, GLsizei size)
-{
- GLint slice = IFLOOR(coord + 0.5f);
- slice = CLAMP(slice, 0, size - 1);
- return slice;
-}
-
-
-/**
- * Compute nearest integer texcoords for given texobj and coordinate.
- * NOTE: only used for depth texture sampling.
- */
-static INLINE void
-nearest_texcoord(const struct gl_texture_object *texObj,
- GLuint level,
- const GLfloat texcoord[4],
- GLint *i, GLint *j, GLint *k)
-{
- const struct gl_texture_image *img = texObj->Image[0][level];
- const GLint width = img->Width;
- const GLint height = img->Height;
- const GLint depth = img->Depth;
-
- switch (texObj->Target) {
- case GL_TEXTURE_RECTANGLE_ARB:
- *i = clamp_rect_coord_nearest(texObj->Sampler.WrapS, texcoord[0], width);
- *j = clamp_rect_coord_nearest(texObj->Sampler.WrapT, texcoord[1], height);
- *k = 0;
- break;
- case GL_TEXTURE_1D:
- *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]);
- *j = 0;
- *k = 0;
- break;
- case GL_TEXTURE_2D:
- *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]);
- *j = nearest_texel_location(texObj->Sampler.WrapT, img, height, texcoord[1]);
- *k = 0;
- break;
- case GL_TEXTURE_1D_ARRAY_EXT:
- *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]);
- *j = tex_array_slice(texcoord[1], height);
- *k = 0;
- break;
- case GL_TEXTURE_2D_ARRAY_EXT:
- *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]);
- *j = nearest_texel_location(texObj->Sampler.WrapT, img, height, texcoord[1]);
- *k = tex_array_slice(texcoord[2], depth);
- break;
- default:
- *i = *j = *k = 0;
- }
-}
-
-
-/**
- * Compute linear integer texcoords for given texobj and coordinate.
- * NOTE: only used for depth texture sampling.
- */
-static INLINE void
-linear_texcoord(const struct gl_texture_object *texObj,
- GLuint level,
- const GLfloat texcoord[4],
- GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice,
- GLfloat *wi, GLfloat *wj)
-{
- const struct gl_texture_image *img = texObj->Image[0][level];
- const GLint width = img->Width;
- const GLint height = img->Height;
- const GLint depth = img->Depth;
-
- switch (texObj->Target) {
- case GL_TEXTURE_RECTANGLE_ARB:
- clamp_rect_coord_linear(texObj->Sampler.WrapS, texcoord[0],
- width, i0, i1, wi);
- clamp_rect_coord_linear(texObj->Sampler.WrapT, texcoord[1],
- height, j0, j1, wj);
- *slice = 0;
- break;
-
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- linear_texel_locations(texObj->Sampler.WrapS, img, width,
- texcoord[0], i0, i1, wi);
- linear_texel_locations(texObj->Sampler.WrapT, img, height,
- texcoord[1], j0, j1, wj);
- *slice = 0;
- break;
-
- case GL_TEXTURE_1D_ARRAY_EXT:
- linear_texel_locations(texObj->Sampler.WrapS, img, width,
- texcoord[0], i0, i1, wi);
- *j0 = tex_array_slice(texcoord[1], height);
- *j1 = *j0;
- *slice = 0;
- break;
-
- case GL_TEXTURE_2D_ARRAY_EXT:
- linear_texel_locations(texObj->Sampler.WrapS, img, width,
- texcoord[0], i0, i1, wi);
- linear_texel_locations(texObj->Sampler.WrapT, img, height,
- texcoord[1], j0, j1, wj);
- *slice = tex_array_slice(texcoord[2], depth);
- break;
-
- default:
- *slice = 0;
- }
-}
-
-
-
-/**
- * For linear interpolation between mipmap levels N and N+1, this function
- * computes N.
- */
-static INLINE GLint
-linear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda)
-{
- if (lambda < 0.0F)
- return tObj->BaseLevel;
- else if (lambda > tObj->_MaxLambda)
- return (GLint) (tObj->BaseLevel + tObj->_MaxLambda);
- else
- return (GLint) (tObj->BaseLevel + lambda);
-}
-
-
-/**
- * Compute the nearest mipmap level to take texels from.
- */
-static INLINE GLint
-nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda)
-{
- GLfloat l;
- GLint level;
- if (lambda <= 0.5F)
- l = 0.0F;
- else if (lambda > tObj->_MaxLambda + 0.4999F)
- l = tObj->_MaxLambda + 0.4999F;
- else
- l = lambda;
- level = (GLint) (tObj->BaseLevel + l + 0.5F);
- if (level > tObj->_MaxLevel)
- level = tObj->_MaxLevel;
- return level;
-}
-
-
-
-/*
- * Bitflags for texture border color sampling.
- */
-#define I0BIT 1
-#define I1BIT 2
-#define J0BIT 4
-#define J1BIT 8
-#define K0BIT 16
-#define K1BIT 32
-
-
-
-/**
- * The lambda[] array values are always monotonic. Either the whole span
- * will be minified, magnified, or split between the two. This function
- * determines the subranges in [0, n-1] that are to be minified or magnified.
- */
-static INLINE void
-compute_min_mag_ranges(const struct gl_texture_object *tObj,
- GLuint n, const GLfloat lambda[],
- GLuint *minStart, GLuint *minEnd,
- GLuint *magStart, GLuint *magEnd)
-{
- GLfloat minMagThresh;
-
- /* we shouldn't be here if minfilter == magfilter */
- ASSERT(tObj->Sampler.MinFilter != tObj->Sampler.MagFilter);
-
- /* This bit comes from the OpenGL spec: */
- if (tObj->Sampler.MagFilter == GL_LINEAR
- && (tObj->Sampler.MinFilter == GL_NEAREST_MIPMAP_NEAREST ||
- tObj->Sampler.MinFilter == GL_NEAREST_MIPMAP_LINEAR)) {
- minMagThresh = 0.5F;
- }
- else {
- minMagThresh = 0.0F;
- }
-
-#if 0
- /* DEBUG CODE: Verify that lambda[] is monotonic.
- * We can't really use this because the inaccuracy in the LOG2 function
- * causes this test to fail, yet the resulting texturing is correct.
- */
- if (n > 1) {
- GLuint i;
- printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);
- if (lambda[0] >= lambda[n-1]) { /* decreasing */
- for (i = 0; i < n - 1; i++) {
- ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));
- }
- }
- else { /* increasing */
- for (i = 0; i < n - 1; i++) {
- ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));
- }
- }
- }
-#endif /* DEBUG */
-
- if (lambda[0] <= minMagThresh && (n <= 1 || lambda[n-1] <= minMagThresh)) {
- /* magnification for whole span */
- *magStart = 0;
- *magEnd = n;
- *minStart = *minEnd = 0;
- }
- else if (lambda[0] > minMagThresh && (n <=1 || lambda[n-1] > minMagThresh)) {
- /* minification for whole span */
- *minStart = 0;
- *minEnd = n;
- *magStart = *magEnd = 0;
- }
- else {
- /* a mix of minification and magnification */
- GLuint i;
- if (lambda[0] > minMagThresh) {
- /* start with minification */
- for (i = 1; i < n; i++) {
- if (lambda[i] <= minMagThresh)
- break;
- }
- *minStart = 0;
- *minEnd = i;
- *magStart = i;
- *magEnd = n;
- }
- else {
- /* start with magnification */
- for (i = 1; i < n; i++) {
- if (lambda[i] > minMagThresh)
- break;
- }
- *magStart = 0;
- *magEnd = i;
- *minStart = i;
- *minEnd = n;
- }
- }
-
-#if 0
- /* Verify the min/mag Start/End values
- * We don't use this either (see above)
- */
- {
- GLint i;
- for (i = 0; i < n; i++) {
- if (lambda[i] > minMagThresh) {
- /* minification */
- ASSERT(i >= *minStart);
- ASSERT(i < *minEnd);
- }
- else {
- /* magnification */
- ASSERT(i >= *magStart);
- ASSERT(i < *magEnd);
- }
- }
- }
-#endif
-}
-
-
-/**
- * When we sample the border color, it must be interpreted according to
- * the base texture format. Ex: if the texture base format it GL_ALPHA,
- * we return (0,0,0,BorderAlpha).
- */
-static INLINE void
-get_border_color(const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- GLfloat rgba[4])
-{
- switch (img->_BaseFormat) {
- case GL_RGB:
- rgba[0] = tObj->Sampler.BorderColor.f[0];
- rgba[1] = tObj->Sampler.BorderColor.f[1];
- rgba[2] = tObj->Sampler.BorderColor.f[2];
- rgba[3] = 1.0F;
- break;
- case GL_ALPHA:
- rgba[0] = rgba[1] = rgba[2] = 0.0;
- rgba[3] = tObj->Sampler.BorderColor.f[3];
- break;
- case GL_LUMINANCE:
- rgba[0] = rgba[1] = rgba[2] = tObj->Sampler.BorderColor.f[0];
- rgba[3] = 1.0;
- break;
- case GL_LUMINANCE_ALPHA:
- rgba[0] = rgba[1] = rgba[2] = tObj->Sampler.BorderColor.f[0];
- rgba[3] = tObj->Sampler.BorderColor.f[3];
- break;
- case GL_INTENSITY:
- rgba[0] = rgba[1] = rgba[2] = rgba[3] = tObj->Sampler.BorderColor.f[0];
- break;
- default:
- COPY_4V(rgba, tObj->Sampler.BorderColor.f);
- }
-}
-
-
-/**********************************************************************/
-/* 1-D Texture Sampling Functions */
-/**********************************************************************/
-
-/**
- * Return the texture sample for coordinate (s) using GL_NEAREST filter.
- */
-static INLINE void
-sample_1d_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4], GLfloat rgba[4])
-{
- const GLint width = img->Width2; /* without border, power of two */
- GLint i;
- i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
- /* skip over the border, if any */
- i += img->Border;
- if (i < 0 || i >= (GLint) img->Width) {
- /* Need this test for GL_CLAMP_TO_BORDER mode */
- get_border_color(tObj, img, rgba);
- }
- else {
- img->FetchTexelf(img, i, 0, 0, rgba);
- }
-}
-
-
-/**
- * Return the texture sample for coordinate (s) using GL_LINEAR filter.
- */
-static INLINE void
-sample_1d_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4], GLfloat rgba[4])
-{
- const GLint width = img->Width2;
- GLint i0, i1;
- GLbitfield useBorderColor = 0x0;
- GLfloat a;
- GLfloat t0[4], t1[4]; /* texels */
-
- linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
-
- if (img->Border) {
- i0 += img->Border;
- i1 += img->Border;
- }
- else {
- if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
- if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
- }
-
- /* fetch texel colors */
- if (useBorderColor & I0BIT) {
- get_border_color(tObj, img, t0);
- }
- else {
- img->FetchTexelf(img, i0, 0, 0, t0);
- }
- if (useBorderColor & I1BIT) {
- get_border_color(tObj, img, t1);
- }
- else {
- img->FetchTexelf(img, i1, 0, 0, t1);
- }
-
- lerp_rgba(rgba, a, t0, t1);
-}
-
-
-static void
-sample_1d_nearest_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_1d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
- }
-}
-
-
-static void
-sample_1d_linear_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_1d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
- }
-}
-
-
-static void
-sample_1d_nearest_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4];
- const GLfloat f = FRAC(lambda[i]);
- sample_1d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
- sample_1d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-static void
-sample_1d_linear_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4];
- const GLfloat f = FRAC(lambda[i]);
- sample_1d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
- sample_1d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-/** Sample 1D texture, nearest filtering for both min/magnification */
-static void
-sample_nearest_1d( struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4] )
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_1d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-/** Sample 1D texture, linear filtering for both min/magnification */
-static void
-sample_linear_1d( struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4] )
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_1d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-/** Sample 1D texture, using lambda to choose between min/magnification */
-static void
-sample_lambda_1d( struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4] )
-{
- GLuint minStart, minEnd; /* texels with minification */
- GLuint magStart, magEnd; /* texels with magnification */
- GLuint i;
-
- ASSERT(lambda != NULL);
- compute_min_mag_ranges(tObj, n, lambda,
- &minStart, &minEnd, &magStart, &magEnd);
-
- if (minStart < minEnd) {
- /* do the minified texels */
- const GLuint m = minEnd - minStart;
- switch (tObj->Sampler.MinFilter) {
- case GL_NEAREST:
- for (i = minStart; i < minEnd; i++)
- sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_LINEAR:
- for (i = minStart; i < minEnd; i++)
- sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_1d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_1d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_1d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_1d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- default:
- _mesa_problem(ctx, "Bad min filter in sample_1d_texture");
- return;
- }
- }
-
- if (magStart < magEnd) {
- /* do the magnified texels */
- switch (tObj->Sampler.MagFilter) {
- case GL_NEAREST:
- for (i = magStart; i < magEnd; i++)
- sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_LINEAR:
- for (i = magStart; i < magEnd; i++)
- sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- default:
- _mesa_problem(ctx, "Bad mag filter in sample_1d_texture");
- return;
- }
- }
-}
-
-
-/**********************************************************************/
-/* 2-D Texture Sampling Functions */
-/**********************************************************************/
-
-
-/**
- * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
- */
-static INLINE void
-sample_2d_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[])
-{
- const GLint width = img->Width2; /* without border, power of two */
- const GLint height = img->Height2; /* without border, power of two */
- GLint i, j;
- (void) ctx;
-
- i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
- j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]);
-
- /* skip over the border, if any */
- i += img->Border;
- j += img->Border;
-
- if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) {
- /* Need this test for GL_CLAMP_TO_BORDER mode */
- get_border_color(tObj, img, rgba);
- }
- else {
- img->FetchTexelf(img, i, j, 0, rgba);
- }
-}
-
-
-/**
- * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
- * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
- */
-static INLINE void
-sample_2d_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[])
-{
- const GLint width = img->Width2;
- const GLint height = img->Height2;
- GLint i0, j0, i1, j1;
- GLbitfield useBorderColor = 0x0;
- GLfloat a, b;
- GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */
-
- linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
- linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b);
-
- if (img->Border) {
- i0 += img->Border;
- i1 += img->Border;
- j0 += img->Border;
- j1 += img->Border;
- }
- else {
- if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
- if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
- if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
- if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
- }
-
- /* fetch four texel colors */
- if (useBorderColor & (I0BIT | J0BIT)) {
- get_border_color(tObj, img, t00);
- }
- else {
- img->FetchTexelf(img, i0, j0, 0, t00);
- }
- if (useBorderColor & (I1BIT | J0BIT)) {
- get_border_color(tObj, img, t10);
- }
- else {
- img->FetchTexelf(img, i1, j0, 0, t10);
- }
- if (useBorderColor & (I0BIT | J1BIT)) {
- get_border_color(tObj, img, t01);
- }
- else {
- img->FetchTexelf(img, i0, j1, 0, t01);
- }
- if (useBorderColor & (I1BIT | J1BIT)) {
- get_border_color(tObj, img, t11);
- }
- else {
- img->FetchTexelf(img, i1, j1, 0, t11);
- }
-
- lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
-}
-
-
-/**
- * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT.
- * We don't have to worry about the texture border.
- */
-static INLINE void
-sample_2d_linear_repeat(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[])
-{
- const GLint width = img->Width2;
- const GLint height = img->Height2;
- GLint i0, j0, i1, j1;
- GLfloat wi, wj;
- GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */
-
- (void) ctx;
-
- ASSERT(tObj->Sampler.WrapS == GL_REPEAT);
- ASSERT(tObj->Sampler.WrapT == GL_REPEAT);
- ASSERT(img->Border == 0);
- ASSERT(img->_BaseFormat != GL_COLOR_INDEX);
- ASSERT(img->_IsPowerOfTwo);
-
- linear_repeat_texel_location(width, texcoord[0], &i0, &i1, &wi);
- linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj);
-
- img->FetchTexelf(img, i0, j0, 0, t00);
- img->FetchTexelf(img, i1, j0, 0, t10);
- img->FetchTexelf(img, i0, j1, 0, t01);
- img->FetchTexelf(img, i1, j1, 0, t11);
-
- lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11);
-}
-
-
-static void
-sample_2d_nearest_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_2d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
- }
-}
-
-
-static void
-sample_2d_linear_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_2d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
- }
-}
-
-
-static void
-sample_2d_nearest_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_2d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_2d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
- sample_2d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-static void
-sample_2d_linear_mipmap_linear( struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4] )
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_2d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_2d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
- sample_2d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-static void
-sample_2d_linear_mipmap_linear_repeat(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- ASSERT(tObj->Sampler.WrapS == GL_REPEAT);
- ASSERT(tObj->Sampler.WrapT == GL_REPEAT);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ],
- texcoord[i], t0);
- sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level+1],
- texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-/** Sample 2D texture, nearest filtering for both min/magnification */
-static void
-sample_nearest_2d(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-/** Sample 2D texture, linear filtering for both min/magnification */
-static void
-sample_linear_2d(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- if (tObj->Sampler.WrapS == GL_REPEAT &&
- tObj->Sampler.WrapT == GL_REPEAT &&
- image->_IsPowerOfTwo &&
- image->Border == 0) {
- for (i = 0; i < n; i++) {
- sample_2d_linear_repeat(ctx, tObj, image, texcoords[i], rgba[i]);
- }
- }
- else {
- for (i = 0; i < n; i++) {
- sample_2d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
- }
- }
-}
-
-
-/**
- * Optimized 2-D texture sampling:
- * S and T wrap mode == GL_REPEAT
- * GL_NEAREST min/mag filter
- * No border,
- * RowStride == Width,
- * Format = GL_RGB
- */
-static void
-opt_sample_rgb_2d(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];
- const GLfloat width = (GLfloat) img->Width;
- const GLfloat height = (GLfloat) img->Height;
- const GLint colMask = img->Width - 1;
- const GLint rowMask = img->Height - 1;
- const GLint shift = img->WidthLog2;
- GLuint k;
- (void) ctx;
- (void) lambda;
- ASSERT(tObj->Sampler.WrapS==GL_REPEAT);
- ASSERT(tObj->Sampler.WrapT==GL_REPEAT);
- ASSERT(img->Border==0);
- ASSERT(img->TexFormat == MESA_FORMAT_RGB888);
- ASSERT(img->_IsPowerOfTwo);
-
- for (k=0; k<n; k++) {
- GLint i = IFLOOR(texcoords[k][0] * width) & colMask;
- GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;
- GLint pos = (j << shift) | i;
- GLubyte *texel = ((GLubyte *) img->Data) + 3*pos;
- rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]);
- rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]);
- rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]);
- rgba[k][ACOMP] = 1.0F;
- }
-}
-
-
-/**
- * Optimized 2-D texture sampling:
- * S and T wrap mode == GL_REPEAT
- * GL_NEAREST min/mag filter
- * No border
- * RowStride == Width,
- * Format = GL_RGBA
- */
-static void
-opt_sample_rgba_2d(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];
- const GLfloat width = (GLfloat) img->Width;
- const GLfloat height = (GLfloat) img->Height;
- const GLint colMask = img->Width - 1;
- const GLint rowMask = img->Height - 1;
- const GLint shift = img->WidthLog2;
- GLuint i;
- (void) ctx;
- (void) lambda;
- ASSERT(tObj->Sampler.WrapS==GL_REPEAT);
- ASSERT(tObj->Sampler.WrapT==GL_REPEAT);
- ASSERT(img->Border==0);
- ASSERT(img->TexFormat == MESA_FORMAT_RGBA8888);
- ASSERT(img->_IsPowerOfTwo);
-
- for (i = 0; i < n; i++) {
- const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;
- const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;
- const GLint pos = (row << shift) | col;
- const GLuint texel = *((GLuint *) img->Data + pos);
- rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24) );
- rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff );
- rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >> 8) & 0xff );
- rgba[i][ACOMP] = UBYTE_TO_FLOAT( (texel ) & 0xff );
- }
-}
-
-
-/** Sample 2D texture, using lambda to choose between min/magnification */
-static void
-sample_lambda_2d(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];
- GLuint minStart, minEnd; /* texels with minification */
- GLuint magStart, magEnd; /* texels with magnification */
-
- const GLboolean repeatNoBorderPOT = (tObj->Sampler.WrapS == GL_REPEAT)
- && (tObj->Sampler.WrapT == GL_REPEAT)
- && (tImg->Border == 0 && (tImg->Width == tImg->RowStride))
- && (tImg->_BaseFormat != GL_COLOR_INDEX)
- && tImg->_IsPowerOfTwo;
-
- ASSERT(lambda != NULL);
- compute_min_mag_ranges(tObj, n, lambda,
- &minStart, &minEnd, &magStart, &magEnd);
-
- if (minStart < minEnd) {
- /* do the minified texels */
- const GLuint m = minEnd - minStart;
- switch (tObj->Sampler.MinFilter) {
- case GL_NEAREST:
- if (repeatNoBorderPOT) {
- switch (tImg->TexFormat) {
- case MESA_FORMAT_RGB888:
- opt_sample_rgb_2d(ctx, tObj, m, texcoords + minStart,
- NULL, rgba + minStart);
- break;
- case MESA_FORMAT_RGBA8888:
- opt_sample_rgba_2d(ctx, tObj, m, texcoords + minStart,
- NULL, rgba + minStart);
- break;
- default:
- sample_nearest_2d(ctx, tObj, m, texcoords + minStart,
- NULL, rgba + minStart );
- }
- }
- else {
- sample_nearest_2d(ctx, tObj, m, texcoords + minStart,
- NULL, rgba + minStart);
- }
- break;
- case GL_LINEAR:
- sample_linear_2d(ctx, tObj, m, texcoords + minStart,
- NULL, rgba + minStart);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_2d_nearest_mipmap_nearest(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_2d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_2d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- if (repeatNoBorderPOT)
- sample_2d_linear_mipmap_linear_repeat(ctx, tObj, m,
- texcoords + minStart, lambda + minStart, rgba + minStart);
- else
- sample_2d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- default:
- _mesa_problem(ctx, "Bad min filter in sample_2d_texture");
- return;
- }
- }
-
- if (magStart < magEnd) {
- /* do the magnified texels */
- const GLuint m = magEnd - magStart;
-
- switch (tObj->Sampler.MagFilter) {
- case GL_NEAREST:
- if (repeatNoBorderPOT) {
- switch (tImg->TexFormat) {
- case MESA_FORMAT_RGB888:
- opt_sample_rgb_2d(ctx, tObj, m, texcoords + magStart,
- NULL, rgba + magStart);
- break;
- case MESA_FORMAT_RGBA8888:
- opt_sample_rgba_2d(ctx, tObj, m, texcoords + magStart,
- NULL, rgba + magStart);
- break;
- default:
- sample_nearest_2d(ctx, tObj, m, texcoords + magStart,
- NULL, rgba + magStart );
- }
- }
- else {
- sample_nearest_2d(ctx, tObj, m, texcoords + magStart,
- NULL, rgba + magStart);
- }
- break;
- case GL_LINEAR:
- sample_linear_2d(ctx, tObj, m, texcoords + magStart,
- NULL, rgba + magStart);
- break;
- default:
- _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d");
- }
- }
-}
-
-
-/* For anisotropic filtering */
-#define WEIGHT_LUT_SIZE 1024
-
-static GLfloat *weightLut = NULL;
-
-/**
- * Creates the look-up table used to speed-up EWA sampling
- */
-static void
-create_filter_table(void)
-{
- GLuint i;
- if (!weightLut) {
- weightLut = (GLfloat *) malloc(WEIGHT_LUT_SIZE * sizeof(GLfloat));
-
- for (i = 0; i < WEIGHT_LUT_SIZE; ++i) {
- GLfloat alpha = 2;
- GLfloat r2 = (GLfloat) i / (GLfloat) (WEIGHT_LUT_SIZE - 1);
- GLfloat weight = (GLfloat) exp(-alpha * r2);
- weightLut[i] = weight;
- }
- }
-}
-
-
-/**
- * Elliptical weighted average (EWA) filter for producing high quality
- * anisotropic filtered results.
- * Based on the Higher Quality Elliptical Weighted Avarage Filter
- * published by Paul S. Heckbert in his Master's Thesis
- * "Fundamentals of Texture Mapping and Image Warping" (1989)
- */
-static void
-sample_2d_ewa(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const GLfloat texcoord[4],
- const GLfloat dudx, const GLfloat dvdx,
- const GLfloat dudy, const GLfloat dvdy, const GLint lod,
- GLfloat rgba[])
-{
- GLint level = lod > 0 ? lod : 0;
- GLfloat scaling = 1.0 / (1 << level);
- const struct gl_texture_image *img = tObj->Image[0][level];
- const struct gl_texture_image *mostDetailedImage =
- tObj->Image[0][tObj->BaseLevel];
- GLfloat tex_u=-0.5 + texcoord[0] * mostDetailedImage->WidthScale * scaling;
- GLfloat tex_v=-0.5 + texcoord[1] * mostDetailedImage->HeightScale * scaling;
-
- GLfloat ux = dudx * scaling;
- GLfloat vx = dvdx * scaling;
- GLfloat uy = dudy * scaling;
- GLfloat vy = dvdy * scaling;
-
- /* compute ellipse coefficients to bound the region:
- * A*x*x + B*x*y + C*y*y = F.
- */
- GLfloat A = vx*vx+vy*vy+1;
- GLfloat B = -2*(ux*vx+uy*vy);
- GLfloat C = ux*ux+uy*uy+1;
- GLfloat F = A*C-B*B/4.0;
-
- /* check if it is an ellipse */
- /* ASSERT(F > 0.0); */
-
- /* Compute the ellipse's (u,v) bounding box in texture space */
- GLfloat d = -B*B+4.0*C*A;
- GLfloat box_u = 2.0 / d * sqrt(d*C*F); /* box_u -> half of bbox with */
- GLfloat box_v = 2.0 / d * sqrt(A*d*F); /* box_v -> half of bbox height */
-
- GLint u0 = floor(tex_u - box_u);
- GLint u1 = ceil (tex_u + box_u);
- GLint v0 = floor(tex_v - box_v);
- GLint v1 = ceil (tex_v + box_v);
-
- GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
- GLfloat newCoord[2];
- GLfloat den = 0.0F;
- GLfloat ddq;
- GLfloat U = u0 - tex_u;
- GLint v;
-
- /* Scale ellipse formula to directly index the Filter Lookup Table.
- * i.e. scale so that F = WEIGHT_LUT_SIZE-1
- */
- double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F;
- A *= formScale;
- B *= formScale;
- C *= formScale;
- /* F *= formScale; */ /* no need to scale F as we don't use it below here */
-
- /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse
- * and incrementally update the value of Ax^2+Bxy*Cy^2; when this
- * value, q, is less than F, we're inside the ellipse
- */
- ddq = 2 * A;
- for (v = v0; v <= v1; ++v) {
- GLfloat V = v - tex_v;
- GLfloat dq = A * (2 * U + 1) + B * V;
- GLfloat q = (C * V + B * U) * V + A * U * U;
-
- GLint u;
- for (u = u0; u <= u1; ++u) {
- /* Note that the ellipse has been pre-scaled so F = WEIGHT_LUT_SIZE - 1 */
- if (q < WEIGHT_LUT_SIZE) {
- /* as a LUT is used, q must never be negative;
- * should not happen, though
- */
- const GLint qClamped = q >= 0.0F ? q : 0;
- GLfloat weight = weightLut[qClamped];
-
- newCoord[0] = u / ((GLfloat) img->Width2);
- newCoord[1] = v / ((GLfloat) img->Height2);
-
- sample_2d_nearest(ctx, tObj, img, newCoord, rgba);
- num[0] += weight * rgba[0];
- num[1] += weight * rgba[1];
- num[2] += weight * rgba[2];
- num[3] += weight * rgba[3];
-
- den += weight;
- }
- q += dq;
- dq += ddq;
- }
- }
-
- if (den <= 0.0F) {
- /* Reaching this place would mean
- * that no pixels intersected the ellipse.
- * This should never happen because
- * the filter we use always
- * intersects at least one pixel.
- */
-
- /*rgba[0]=0;
- rgba[1]=0;
- rgba[2]=0;
- rgba[3]=0;*/
- /* not enough pixels in resampling, resort to direct interpolation */
- sample_2d_linear(ctx, tObj, img, texcoord, rgba);
- return;
- }
-
- rgba[0] = num[0] / den;
- rgba[1] = num[1] / den;
- rgba[2] = num[2] / den;
- rgba[3] = num[3] / den;
-}
-
-
-/**
- * Anisotropic filtering using footprint assembly as outlined in the
- * EXT_texture_filter_anisotropic spec:
- * http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt
- * Faster than EWA but has less quality (more aliasing effects)
- */
-static void
-sample_2d_footprint(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const GLfloat texcoord[4],
- const GLfloat dudx, const GLfloat dvdx,
- const GLfloat dudy, const GLfloat dvdy, const GLint lod,
- GLfloat rgba[])
-{
- GLint level = lod > 0 ? lod : 0;
- GLfloat scaling = 1.0F / (1 << level);
- const struct gl_texture_image *img = tObj->Image[0][level];
-
- GLfloat ux = dudx * scaling;
- GLfloat vx = dvdx * scaling;
- GLfloat uy = dudy * scaling;
- GLfloat vy = dvdy * scaling;
-
- GLfloat Px2 = ux * ux + vx * vx; /* squared length of dx */
- GLfloat Py2 = uy * uy + vy * vy; /* squared length of dy */
-
- GLint numSamples;
- GLfloat ds;
- GLfloat dt;
-
- GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
- GLfloat newCoord[2];
- GLint s;
-
- /* Calculate the per anisotropic sample offsets in s,t space. */
- if (Px2 > Py2) {
- numSamples = ceil(SQRTF(Px2));
- ds = ux / ((GLfloat) img->Width2);
- dt = vx / ((GLfloat) img->Height2);
- }
- else {
- numSamples = ceil(SQRTF(Py2));
- ds = uy / ((GLfloat) img->Width2);
- dt = vy / ((GLfloat) img->Height2);
- }
-
- for (s = 0; s<numSamples; s++) {
- newCoord[0] = texcoord[0] + ds * ((GLfloat)(s+1) / (numSamples+1) -0.5);
- newCoord[1] = texcoord[1] + dt * ((GLfloat)(s+1) / (numSamples+1) -0.5);
-
- sample_2d_linear(ctx, tObj, img, newCoord, rgba);
- num[0] += rgba[0];
- num[1] += rgba[1];
- num[2] += rgba[2];
- num[3] += rgba[3];
- }
-
- rgba[0] = num[0] / numSamples;
- rgba[1] = num[1] / numSamples;
- rgba[2] = num[2] / numSamples;
- rgba[3] = num[3] / numSamples;
-}
-
-
-/**
- * Returns the index of the specified texture object in the
- * gl_context texture unit array.
- */
-static INLINE GLuint
-texture_unit_index(const struct gl_context *ctx,
- const struct gl_texture_object *tObj)
-{
- const GLuint maxUnit
- = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
- GLuint u;
-
- /* XXX CoordUnits vs. ImageUnits */
- for (u = 0; u < maxUnit; u++) {
- if (ctx->Texture.Unit[u]._Current == tObj)
- break; /* found */
- }
- if (u >= maxUnit)
- u = 0; /* not found, use 1st one; should never happen */
-
- return u;
-}
-
-
-/**
- * Sample 2D texture using an anisotropic filter.
- * NOTE: the const GLfloat lambda_iso[] parameter does *NOT* contain
- * the lambda float array but a "hidden" SWspan struct which is required
- * by this function but is not available in the texture_sample_func signature.
- * See _swrast_texture_span( struct gl_context *ctx, SWspan *span ) on how
- * this function is called.
- */
-static void
-sample_lambda_2d_aniso(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoords[][4],
- const GLfloat lambda_iso[], GLfloat rgba[][4])
-{
- const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];
- const GLfloat maxEccentricity =
- tObj->Sampler.MaxAnisotropy * tObj->Sampler.MaxAnisotropy;
-
- /* re-calculate the lambda values so that they are usable with anisotropic
- * filtering
- */
- SWspan *span = (SWspan *)lambda_iso; /* access the "hidden" SWspan struct */
-
- /* based on interpolate_texcoords(struct gl_context *ctx, SWspan *span)
- * in swrast/s_span.c
- */
-
- /* find the texture unit index by looking up the current texture object
- * from the context list of available texture objects.
- */
- const GLuint u = texture_unit_index(ctx, tObj);
- const GLuint attr = FRAG_ATTRIB_TEX0 + u;
- GLfloat texW, texH;
-
- const GLfloat dsdx = span->attrStepX[attr][0];
- const GLfloat dsdy = span->attrStepY[attr][0];
- const GLfloat dtdx = span->attrStepX[attr][1];
- const GLfloat dtdy = span->attrStepY[attr][1];
- const GLfloat dqdx = span->attrStepX[attr][3];
- const GLfloat dqdy = span->attrStepY[attr][3];
- GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx;
- GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx;
- GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx;
-
- /* from swrast/s_texcombine.c _swrast_texture_span */
- const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
- const GLboolean adjustLOD =
- (texUnit->LodBias + tObj->Sampler.LodBias != 0.0F)
- || (tObj->Sampler.MinLod != -1000.0 || tObj->Sampler.MaxLod != 1000.0);
-
- GLuint i;
-
- /* on first access create the lookup table containing the filter weights. */
- if (!weightLut) {
- create_filter_table();
- }
-
- texW = tImg->WidthScale;
- texH = tImg->HeightScale;
-
- for (i = 0; i < n; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
-
- GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
- GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
- GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
- GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
-
- /* note: instead of working with Px and Py, we will use the
- * squared length instead, to avoid sqrt.
- */
- GLfloat Px2 = dudx * dudx + dvdx * dvdx;
- GLfloat Py2 = dudy * dudy + dvdy * dvdy;
-
- GLfloat Pmax2;
- GLfloat Pmin2;
- GLfloat e;
- GLfloat lod;
-
- s += dsdx;
- t += dtdx;
- q += dqdx;
-
- if (Px2 < Py2) {
- Pmax2 = Py2;
- Pmin2 = Px2;
- }
- else {
- Pmax2 = Px2;
- Pmin2 = Py2;
- }
-
- /* if the eccentricity of the ellipse is too big, scale up the shorter
- * of the two vectors to limit the maximum amount of work per pixel
- */
- e = Pmax2 / Pmin2;
- if (e > maxEccentricity) {
- /* GLfloat s=e / maxEccentricity;
- minor[0] *= s;
- minor[1] *= s;
- Pmin2 *= s; */
- Pmin2 = Pmax2 / maxEccentricity;
- }
-
- /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid
- * this since 0.5*log(x) = log(sqrt(x))
- */
- lod = 0.5 * LOG2(Pmin2);
-
- if (adjustLOD) {
- /* from swrast/s_texcombine.c _swrast_texture_span */
- if (texUnit->LodBias + tObj->Sampler.LodBias != 0.0F) {
- /* apply LOD bias, but don't clamp yet */
- const GLfloat bias =
- CLAMP(texUnit->LodBias + tObj->Sampler.LodBias,
- -ctx->Const.MaxTextureLodBias,
- ctx->Const.MaxTextureLodBias);
- lod += bias;
-
- if (tObj->Sampler.MinLod != -1000.0 ||
- tObj->Sampler.MaxLod != 1000.0) {
- /* apply LOD clamping to lambda */
- lod = CLAMP(lod, tObj->Sampler.MinLod, tObj->Sampler.MaxLod);
- }
- }
- }
-
- /* If the ellipse covers the whole image, we can
- * simply return the average of the whole image.
- */
- if (lod >= tObj->_MaxLevel) {
- sample_2d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoords[i], rgba[i]);
- }
- else {
- /* don't bother interpolating between multiple LODs; it doesn't
- * seem to be worth the extra running time.
- */
- sample_2d_ewa(ctx, tObj, texcoords[i],
- dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]);
-
- /* unused: */
- (void) sample_2d_footprint;
- /*
- sample_2d_footprint(ctx, tObj, texcoords[i],
- dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]);
- */
- }
- }
-}
-
-
-
-/**********************************************************************/
-/* 3-D Texture Sampling Functions */
-/**********************************************************************/
-
-/**
- * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
- */
-static INLINE void
-sample_3d_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[4])
-{
- const GLint width = img->Width2; /* without border, power of two */
- const GLint height = img->Height2; /* without border, power of two */
- const GLint depth = img->Depth2; /* without border, power of two */
- GLint i, j, k;
- (void) ctx;
-
- i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
- j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]);
- k = nearest_texel_location(tObj->Sampler.WrapR, img, depth, texcoord[2]);
-
- if (i < 0 || i >= (GLint) img->Width ||
- j < 0 || j >= (GLint) img->Height ||
- k < 0 || k >= (GLint) img->Depth) {
- /* Need this test for GL_CLAMP_TO_BORDER mode */
- get_border_color(tObj, img, rgba);
- }
- else {
- img->FetchTexelf(img, i, j, k, rgba);
- }
-}
-
-
-/**
- * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
- */
-static void
-sample_3d_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[4])
-{
- const GLint width = img->Width2;
- const GLint height = img->Height2;
- const GLint depth = img->Depth2;
- GLint i0, j0, k0, i1, j1, k1;
- GLbitfield useBorderColor = 0x0;
- GLfloat a, b, c;
- GLfloat t000[4], t010[4], t001[4], t011[4];
- GLfloat t100[4], t110[4], t101[4], t111[4];
-
- linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
- linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b);
- linear_texel_locations(tObj->Sampler.WrapR, img, depth, texcoord[2], &k0, &k1, &c);
-
- if (img->Border) {
- i0 += img->Border;
- i1 += img->Border;
- j0 += img->Border;
- j1 += img->Border;
- k0 += img->Border;
- k1 += img->Border;
- }
- else {
- /* check if sampling texture border color */
- if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
- if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
- if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
- if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
- if (k0 < 0 || k0 >= depth) useBorderColor |= K0BIT;
- if (k1 < 0 || k1 >= depth) useBorderColor |= K1BIT;
- }
-
- /* Fetch texels */
- if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {
- get_border_color(tObj, img, t000);
- }
- else {
- img->FetchTexelf(img, i0, j0, k0, t000);
- }
- if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
- get_border_color(tObj, img, t100);
- }
- else {
- img->FetchTexelf(img, i1, j0, k0, t100);
- }
- if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
- get_border_color(tObj, img, t010);
- }
- else {
- img->FetchTexelf(img, i0, j1, k0, t010);
- }
- if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
- get_border_color(tObj, img, t110);
- }
- else {
- img->FetchTexelf(img, i1, j1, k0, t110);
- }
-
- if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
- get_border_color(tObj, img, t001);
- }
- else {
- img->FetchTexelf(img, i0, j0, k1, t001);
- }
- if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
- get_border_color(tObj, img, t101);
- }
- else {
- img->FetchTexelf(img, i1, j0, k1, t101);
- }
- if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
- get_border_color(tObj, img, t011);
- }
- else {
- img->FetchTexelf(img, i0, j1, k1, t011);
- }
- if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
- get_border_color(tObj, img, t111);
- }
- else {
- img->FetchTexelf(img, i1, j1, k1, t111);
- }
-
- /* trilinear interpolation of samples */
- lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111);
-}
-
-
-static void
-sample_3d_nearest_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4] )
-{
- GLuint i;
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_3d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
- }
-}
-
-
-static void
-sample_3d_linear_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_3d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
- }
-}
-
-
-static void
-sample_3d_nearest_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_3d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
- sample_3d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-static void
-sample_3d_linear_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_3d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
- sample_3d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-/** Sample 3D texture, nearest filtering for both min/magnification */
-static void
-sample_nearest_3d(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-/** Sample 3D texture, linear filtering for both min/magnification */
-static void
-sample_linear_3d(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_3d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-/** Sample 3D texture, using lambda to choose between min/magnification */
-static void
-sample_lambda_3d(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint minStart, minEnd; /* texels with minification */
- GLuint magStart, magEnd; /* texels with magnification */
- GLuint i;
-
- ASSERT(lambda != NULL);
- compute_min_mag_ranges(tObj, n, lambda,
- &minStart, &minEnd, &magStart, &magEnd);
-
- if (minStart < minEnd) {
- /* do the minified texels */
- GLuint m = minEnd - minStart;
- switch (tObj->Sampler.MinFilter) {
- case GL_NEAREST:
- for (i = minStart; i < minEnd; i++)
- sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_LINEAR:
- for (i = minStart; i < minEnd; i++)
- sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_3d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_3d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_3d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_3d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- default:
- _mesa_problem(ctx, "Bad min filter in sample_3d_texture");
- return;
- }
- }
-
- if (magStart < magEnd) {
- /* do the magnified texels */
- switch (tObj->Sampler.MagFilter) {
- case GL_NEAREST:
- for (i = magStart; i < magEnd; i++)
- sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_LINEAR:
- for (i = magStart; i < magEnd; i++)
- sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- default:
- _mesa_problem(ctx, "Bad mag filter in sample_3d_texture");
- return;
- }
- }
-}
-
-
-/**********************************************************************/
-/* Texture Cube Map Sampling Functions */
-/**********************************************************************/
-
-/**
- * Choose one of six sides of a texture cube map given the texture
- * coord (rx,ry,rz). Return pointer to corresponding array of texture
- * images.
- */
-static const struct gl_texture_image **
-choose_cube_face(const struct gl_texture_object *texObj,
- const GLfloat texcoord[4], GLfloat newCoord[4])
-{
- /*
- major axis
- direction target sc tc ma
- ---------- ------------------------------- --- --- ---
- +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
- -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
- +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
- -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
- +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
- -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
- */
- const GLfloat rx = texcoord[0];
- const GLfloat ry = texcoord[1];
- const GLfloat rz = texcoord[2];
- const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
- GLuint face;
- GLfloat sc, tc, ma;
-
- if (arx >= ary && arx >= arz) {
- if (rx >= 0.0F) {
- face = FACE_POS_X;
- sc = -rz;
- tc = -ry;
- ma = arx;
- }
- else {
- face = FACE_NEG_X;
- sc = rz;
- tc = -ry;
- ma = arx;
- }
- }
- else if (ary >= arx && ary >= arz) {
- if (ry >= 0.0F) {
- face = FACE_POS_Y;
- sc = rx;
- tc = rz;
- ma = ary;
- }
- else {
- face = FACE_NEG_Y;
- sc = rx;
- tc = -rz;
- ma = ary;
- }
- }
- else {
- if (rz > 0.0F) {
- face = FACE_POS_Z;
- sc = rx;
- tc = -ry;
- ma = arz;
- }
- else {
- face = FACE_NEG_Z;
- sc = -rx;
- tc = -ry;
- ma = arz;
- }
- }
-
- {
- const float ima = 1.0F / ma;
- newCoord[0] = ( sc * ima + 1.0F ) * 0.5F;
- newCoord[1] = ( tc * ima + 1.0F ) * 0.5F;
- }
-
- return (const struct gl_texture_image **) texObj->Image[face];
-}
-
-
-static void
-sample_nearest_cube(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint i;
- (void) lambda;
- for (i = 0; i < n; i++) {
- const struct gl_texture_image **images;
- GLfloat newCoord[4];
- images = choose_cube_face(tObj, texcoords[i], newCoord);
- sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
- newCoord, rgba[i]);
- }
-}
-
-
-static void
-sample_linear_cube(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- (void) lambda;
- for (i = 0; i < n; i++) {
- const struct gl_texture_image **images;
- GLfloat newCoord[4];
- images = choose_cube_face(tObj, texcoords[i], newCoord);
- sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
- newCoord, rgba[i]);
- }
-}
-
-
-static void
-sample_cube_nearest_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- const struct gl_texture_image **images;
- GLfloat newCoord[4];
- GLint level;
- images = choose_cube_face(tObj, texcoord[i], newCoord);
-
- /* XXX we actually need to recompute lambda here based on the newCoords.
- * But we would need the texcoords of adjacent fragments to compute that
- * properly, and we don't have those here.
- * For now, do an approximation: subtracting 1 from the chosen mipmap
- * level seems to work in some test cases.
- * The same adjustment is done in the next few functions.
- */
- level = nearest_mipmap_level(tObj, lambda[i]);
- level = MAX2(level - 1, 0);
-
- sample_2d_nearest(ctx, tObj, images[level], newCoord, rgba[i]);
- }
-}
-
-
-static void
-sample_cube_linear_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- const struct gl_texture_image **images;
- GLfloat newCoord[4];
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- level = MAX2(level - 1, 0); /* see comment above */
- images = choose_cube_face(tObj, texcoord[i], newCoord);
- sample_2d_linear(ctx, tObj, images[level], newCoord, rgba[i]);
- }
-}
-
-
-static void
-sample_cube_nearest_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- const struct gl_texture_image **images;
- GLfloat newCoord[4];
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- level = MAX2(level - 1, 0); /* see comment above */
- images = choose_cube_face(tObj, texcoord[i], newCoord);
- if (level >= tObj->_MaxLevel) {
- sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel],
- newCoord, rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_2d_nearest(ctx, tObj, images[level ], newCoord, t0);
- sample_2d_nearest(ctx, tObj, images[level+1], newCoord, t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-static void
-sample_cube_linear_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- const struct gl_texture_image **images;
- GLfloat newCoord[4];
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- level = MAX2(level - 1, 0); /* see comment above */
- images = choose_cube_face(tObj, texcoord[i], newCoord);
- if (level >= tObj->_MaxLevel) {
- sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel],
- newCoord, rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4];
- const GLfloat f = FRAC(lambda[i]);
- sample_2d_linear(ctx, tObj, images[level ], newCoord, t0);
- sample_2d_linear(ctx, tObj, images[level+1], newCoord, t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-/** Sample cube texture, using lambda to choose between min/magnification */
-static void
-sample_lambda_cube(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint minStart, minEnd; /* texels with minification */
- GLuint magStart, magEnd; /* texels with magnification */
-
- ASSERT(lambda != NULL);
- compute_min_mag_ranges(tObj, n, lambda,
- &minStart, &minEnd, &magStart, &magEnd);
-
- if (minStart < minEnd) {
- /* do the minified texels */
- const GLuint m = minEnd - minStart;
- switch (tObj->Sampler.MinFilter) {
- case GL_NEAREST:
- sample_nearest_cube(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR:
- sample_linear_cube(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_cube_nearest_mipmap_nearest(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_cube_linear_mipmap_nearest(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_cube_nearest_mipmap_linear(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_cube_linear_mipmap_linear(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- default:
- _mesa_problem(ctx, "Bad min filter in sample_lambda_cube");
- }
- }
-
- if (magStart < magEnd) {
- /* do the magnified texels */
- const GLuint m = magEnd - magStart;
- switch (tObj->Sampler.MagFilter) {
- case GL_NEAREST:
- sample_nearest_cube(ctx, tObj, m, texcoords + magStart,
- lambda + magStart, rgba + magStart);
- break;
- case GL_LINEAR:
- sample_linear_cube(ctx, tObj, m, texcoords + magStart,
- lambda + magStart, rgba + magStart);
- break;
- default:
- _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube");
- }
- }
-}
-
-
-/**********************************************************************/
-/* Texture Rectangle Sampling Functions */
-/**********************************************************************/
-
-
-static void
-sample_nearest_rect(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- const struct gl_texture_image *img = tObj->Image[0][0];
- const GLint width = img->Width;
- const GLint height = img->Height;
- GLuint i;
-
- (void) ctx;
- (void) lambda;
-
- ASSERT(tObj->Sampler.WrapS == GL_CLAMP ||
- tObj->Sampler.WrapS == GL_CLAMP_TO_EDGE ||
- tObj->Sampler.WrapS == GL_CLAMP_TO_BORDER);
- ASSERT(tObj->Sampler.WrapT == GL_CLAMP ||
- tObj->Sampler.WrapT == GL_CLAMP_TO_EDGE ||
- tObj->Sampler.WrapT == GL_CLAMP_TO_BORDER);
- ASSERT(img->_BaseFormat != GL_COLOR_INDEX);
-
- for (i = 0; i < n; i++) {
- GLint row, col;
- col = clamp_rect_coord_nearest(tObj->Sampler.WrapS, texcoords[i][0], width);
- row = clamp_rect_coord_nearest(tObj->Sampler.WrapT, texcoords[i][1], height);
- if (col < 0 || col >= width || row < 0 || row >= height)
- get_border_color(tObj, img, rgba[i]);
- else
- img->FetchTexelf(img, col, row, 0, rgba[i]);
- }
-}
-
-
-static void
-sample_linear_rect(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- const struct gl_texture_image *img = tObj->Image[0][0];
- const GLint width = img->Width;
- const GLint height = img->Height;
- GLuint i;
-
- (void) ctx;
- (void) lambda;
-
- ASSERT(tObj->Sampler.WrapS == GL_CLAMP ||
- tObj->Sampler.WrapS == GL_CLAMP_TO_EDGE ||
- tObj->Sampler.WrapS == GL_CLAMP_TO_BORDER);
- ASSERT(tObj->Sampler.WrapT == GL_CLAMP ||
- tObj->Sampler.WrapT == GL_CLAMP_TO_EDGE ||
- tObj->Sampler.WrapT == GL_CLAMP_TO_BORDER);
- ASSERT(img->_BaseFormat != GL_COLOR_INDEX);
-
- for (i = 0; i < n; i++) {
- GLint i0, j0, i1, j1;
- GLfloat t00[4], t01[4], t10[4], t11[4];
- GLfloat a, b;
- GLbitfield useBorderColor = 0x0;
-
- clamp_rect_coord_linear(tObj->Sampler.WrapS, texcoords[i][0], width,
- &i0, &i1, &a);
- clamp_rect_coord_linear(tObj->Sampler.WrapT, texcoords[i][1], height,
- &j0, &j1, &b);
-
- /* compute integer rows/columns */
- if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
- if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
- if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
- if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
-
- /* get four texel samples */
- if (useBorderColor & (I0BIT | J0BIT))
- get_border_color(tObj, img, t00);
- else
- img->FetchTexelf(img, i0, j0, 0, t00);
-
- if (useBorderColor & (I1BIT | J0BIT))
- get_border_color(tObj, img, t10);
- else
- img->FetchTexelf(img, i1, j0, 0, t10);
-
- if (useBorderColor & (I0BIT | J1BIT))
- get_border_color(tObj, img, t01);
- else
- img->FetchTexelf(img, i0, j1, 0, t01);
-
- if (useBorderColor & (I1BIT | J1BIT))
- get_border_color(tObj, img, t11);
- else
- img->FetchTexelf(img, i1, j1, 0, t11);
-
- lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11);
- }
-}
-
-
-/** Sample Rect texture, using lambda to choose between min/magnification */
-static void
-sample_lambda_rect(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint minStart, minEnd, magStart, magEnd;
-
- /* We only need lambda to decide between minification and magnification.
- * There is no mipmapping with rectangular textures.
- */
- compute_min_mag_ranges(tObj, n, lambda,
- &minStart, &minEnd, &magStart, &magEnd);
-
- if (minStart < minEnd) {
- if (tObj->Sampler.MinFilter == GL_NEAREST) {
- sample_nearest_rect(ctx, tObj, minEnd - minStart,
- texcoords + minStart, NULL, rgba + minStart);
- }
- else {
- sample_linear_rect(ctx, tObj, minEnd - minStart,
- texcoords + minStart, NULL, rgba + minStart);
- }
- }
- if (magStart < magEnd) {
- if (tObj->Sampler.MagFilter == GL_NEAREST) {
- sample_nearest_rect(ctx, tObj, magEnd - magStart,
- texcoords + magStart, NULL, rgba + magStart);
- }
- else {
- sample_linear_rect(ctx, tObj, magEnd - magStart,
- texcoords + magStart, NULL, rgba + magStart);
- }
- }
-}
-
-
-/**********************************************************************/
-/* 2D Texture Array Sampling Functions */
-/**********************************************************************/
-
-/**
- * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
- */
-static void
-sample_2d_array_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[4])
-{
- const GLint width = img->Width2; /* without border, power of two */
- const GLint height = img->Height2; /* without border, power of two */
- const GLint depth = img->Depth;
- GLint i, j;
- GLint array;
- (void) ctx;
-
- i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
- j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]);
- array = tex_array_slice(texcoord[2], depth);
-
- if (i < 0 || i >= (GLint) img->Width ||
- j < 0 || j >= (GLint) img->Height ||
- array < 0 || array >= (GLint) img->Depth) {
- /* Need this test for GL_CLAMP_TO_BORDER mode */
- get_border_color(tObj, img, rgba);
- }
- else {
- img->FetchTexelf(img, i, j, array, rgba);
- }
-}
-
-
-/**
- * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
- */
-static void
-sample_2d_array_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[4])
-{
- const GLint width = img->Width2;
- const GLint height = img->Height2;
- const GLint depth = img->Depth;
- GLint i0, j0, i1, j1;
- GLint array;
- GLbitfield useBorderColor = 0x0;
- GLfloat a, b;
- GLfloat t00[4], t01[4], t10[4], t11[4];
-
- linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
- linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b);
- array = tex_array_slice(texcoord[2], depth);
-
- if (array < 0 || array >= depth) {
- COPY_4V(rgba, tObj->Sampler.BorderColor.f);
- }
- else {
- if (img->Border) {
- i0 += img->Border;
- i1 += img->Border;
- j0 += img->Border;
- j1 += img->Border;
- }
- else {
- /* check if sampling texture border color */
- if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
- if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
- if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
- if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
- }
-
- /* Fetch texels */
- if (useBorderColor & (I0BIT | J0BIT)) {
- get_border_color(tObj, img, t00);
- }
- else {
- img->FetchTexelf(img, i0, j0, array, t00);
- }
- if (useBorderColor & (I1BIT | J0BIT)) {
- get_border_color(tObj, img, t10);
- }
- else {
- img->FetchTexelf(img, i1, j0, array, t10);
- }
- if (useBorderColor & (I0BIT | J1BIT)) {
- get_border_color(tObj, img, t01);
- }
- else {
- img->FetchTexelf(img, i0, j1, array, t01);
- }
- if (useBorderColor & (I1BIT | J1BIT)) {
- get_border_color(tObj, img, t11);
- }
- else {
- img->FetchTexelf(img, i1, j1, array, t11);
- }
-
- /* trilinear interpolation of samples */
- lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
- }
-}
-
-
-static void
-sample_2d_array_nearest_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i],
- rgba[i]);
- }
-}
-
-
-static void
-sample_2d_array_linear_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_2d_array_linear(ctx, tObj, tObj->Image[0][level],
- texcoord[i], rgba[i]);
- }
-}
-
-
-static void
-sample_2d_array_nearest_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ],
- texcoord[i], t0);
- sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level+1],
- texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-static void
-sample_2d_array_linear_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ],
- texcoord[i], t0);
- sample_2d_array_linear(ctx, tObj, tObj->Image[0][level+1],
- texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-/** Sample 2D Array texture, nearest filtering for both min/magnification */
-static void
-sample_nearest_2d_array(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_2d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-
-/** Sample 2D Array texture, linear filtering for both min/magnification */
-static void
-sample_linear_2d_array(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_2d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-/** Sample 2D Array texture, using lambda to choose between min/magnification */
-static void
-sample_lambda_2d_array(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint minStart, minEnd; /* texels with minification */
- GLuint magStart, magEnd; /* texels with magnification */
- GLuint i;
-
- ASSERT(lambda != NULL);
- compute_min_mag_ranges(tObj, n, lambda,
- &minStart, &minEnd, &magStart, &magEnd);
-
- if (minStart < minEnd) {
- /* do the minified texels */
- GLuint m = minEnd - minStart;
- switch (tObj->Sampler.MinFilter) {
- case GL_NEAREST:
- for (i = minStart; i < minEnd; i++)
- sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_LINEAR:
- for (i = minStart; i < minEnd; i++)
- sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_2d_array_nearest_mipmap_nearest(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart,
- rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_2d_array_linear_mipmap_nearest(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart,
- rgba + minStart);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_2d_array_nearest_mipmap_linear(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart,
- rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_2d_array_linear_mipmap_linear(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart,
- rgba + minStart);
- break;
- default:
- _mesa_problem(ctx, "Bad min filter in sample_2d_array_texture");
- return;
- }
- }
-
- if (magStart < magEnd) {
- /* do the magnified texels */
- switch (tObj->Sampler.MagFilter) {
- case GL_NEAREST:
- for (i = magStart; i < magEnd; i++)
- sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_LINEAR:
- for (i = magStart; i < magEnd; i++)
- sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- default:
- _mesa_problem(ctx, "Bad mag filter in sample_2d_array_texture");
- return;
- }
- }
-}
-
-
-
-
-/**********************************************************************/
-/* 1D Texture Array Sampling Functions */
-/**********************************************************************/
-
-/**
- * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
- */
-static void
-sample_1d_array_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[4])
-{
- const GLint width = img->Width2; /* without border, power of two */
- const GLint height = img->Height;
- GLint i;
- GLint array;
- (void) ctx;
-
- i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
- array = tex_array_slice(texcoord[1], height);
-
- if (i < 0 || i >= (GLint) img->Width ||
- array < 0 || array >= (GLint) img->Height) {
- /* Need this test for GL_CLAMP_TO_BORDER mode */
- get_border_color(tObj, img, rgba);
- }
- else {
- img->FetchTexelf(img, i, array, 0, rgba);
- }
-}
-
-
-/**
- * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
- */
-static void
-sample_1d_array_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- const GLfloat texcoord[4],
- GLfloat rgba[4])
-{
- const GLint width = img->Width2;
- const GLint height = img->Height;
- GLint i0, i1;
- GLint array;
- GLbitfield useBorderColor = 0x0;
- GLfloat a;
- GLfloat t0[4], t1[4];
-
- linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
- array = tex_array_slice(texcoord[1], height);
-
- if (img->Border) {
- i0 += img->Border;
- i1 += img->Border;
- }
- else {
- /* check if sampling texture border color */
- if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
- if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
- }
-
- if (array < 0 || array >= height) useBorderColor |= K0BIT;
-
- /* Fetch texels */
- if (useBorderColor & (I0BIT | K0BIT)) {
- get_border_color(tObj, img, t0);
- }
- else {
- img->FetchTexelf(img, i0, array, 0, t0);
- }
- if (useBorderColor & (I1BIT | K0BIT)) {
- get_border_color(tObj, img, t1);
- }
- else {
- img->FetchTexelf(img, i1, array, 0, t1);
- }
-
- /* bilinear interpolation of samples */
- lerp_rgba(rgba, a, t0, t1);
-}
-
-
-static void
-sample_1d_array_nearest_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i],
- rgba[i]);
- }
-}
-
-
-static void
-sample_1d_array_linear_mipmap_nearest(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = nearest_mipmap_level(tObj, lambda[i]);
- sample_1d_array_linear(ctx, tObj, tObj->Image[0][level],
- texcoord[i], rgba[i]);
- }
-}
-
-
-static void
-sample_1d_array_nearest_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
- sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-static void
-sample_1d_array_linear_mipmap_linear(struct gl_context *ctx,
- const struct gl_texture_object *tObj,
- GLuint n, const GLfloat texcoord[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- ASSERT(lambda != NULL);
- for (i = 0; i < n; i++) {
- GLint level = linear_mipmap_level(tObj, lambda[i]);
- if (level >= tObj->_MaxLevel) {
- sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
- texcoord[i], rgba[i]);
- }
- else {
- GLfloat t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda[i]);
- sample_1d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
- sample_1d_array_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
- lerp_rgba(rgba[i], f, t0, t1);
- }
- }
-}
-
-
-/** Sample 1D Array texture, nearest filtering for both min/magnification */
-static void
-sample_nearest_1d_array(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_1d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-/** Sample 1D Array texture, linear filtering for both min/magnification */
-static void
-sample_linear_1d_array(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4],
- const GLfloat lambda[], GLfloat rgba[][4])
-{
- GLuint i;
- struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
- (void) lambda;
- for (i = 0; i < n; i++) {
- sample_1d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]);
- }
-}
-
-
-/** Sample 1D Array texture, using lambda to choose between min/magnification */
-static void
-sample_lambda_1d_array(struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint minStart, minEnd; /* texels with minification */
- GLuint magStart, magEnd; /* texels with magnification */
- GLuint i;
-
- ASSERT(lambda != NULL);
- compute_min_mag_ranges(tObj, n, lambda,
- &minStart, &minEnd, &magStart, &magEnd);
-
- if (minStart < minEnd) {
- /* do the minified texels */
- GLuint m = minEnd - minStart;
- switch (tObj->Sampler.MinFilter) {
- case GL_NEAREST:
- for (i = minStart; i < minEnd; i++)
- sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_LINEAR:
- for (i = minStart; i < minEnd; i++)
- sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_1d_array_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_1d_array_linear_mipmap_nearest(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart,
- rgba + minStart);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_1d_array_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
- lambda + minStart, rgba + minStart);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_1d_array_linear_mipmap_linear(ctx, tObj, m,
- texcoords + minStart,
- lambda + minStart,
- rgba + minStart);
- break;
- default:
- _mesa_problem(ctx, "Bad min filter in sample_1d_array_texture");
- return;
- }
- }
-
- if (magStart < magEnd) {
- /* do the magnified texels */
- switch (tObj->Sampler.MagFilter) {
- case GL_NEAREST:
- for (i = magStart; i < magEnd; i++)
- sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- case GL_LINEAR:
- for (i = magStart; i < magEnd; i++)
- sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
- texcoords[i], rgba[i]);
- break;
- default:
- _mesa_problem(ctx, "Bad mag filter in sample_1d_array_texture");
- return;
- }
- }
-}
-
-
-/**
- * Compare texcoord against depth sample. Return 1.0 or the ambient value.
- */
-static INLINE GLfloat
-shadow_compare(GLenum function, GLfloat coord, GLfloat depthSample,
- GLfloat ambient)
-{
- switch (function) {
- case GL_LEQUAL:
- return (coord <= depthSample) ? 1.0F : ambient;
- case GL_GEQUAL:
- return (coord >= depthSample) ? 1.0F : ambient;
- case GL_LESS:
- return (coord < depthSample) ? 1.0F : ambient;
- case GL_GREATER:
- return (coord > depthSample) ? 1.0F : ambient;
- case GL_EQUAL:
- return (coord == depthSample) ? 1.0F : ambient;
- case GL_NOTEQUAL:
- return (coord != depthSample) ? 1.0F : ambient;
- case GL_ALWAYS:
- return 1.0F;
- case GL_NEVER:
- return ambient;
- case GL_NONE:
- return depthSample;
- default:
- _mesa_problem(NULL, "Bad compare func in shadow_compare");
- return ambient;
- }
-}
-
-
-/**
- * Compare texcoord against four depth samples.
- */
-static INLINE GLfloat
-shadow_compare4(GLenum function, GLfloat coord,
- GLfloat depth00, GLfloat depth01,
- GLfloat depth10, GLfloat depth11,
- GLfloat ambient, GLfloat wi, GLfloat wj)
-{
- const GLfloat d = (1.0F - (GLfloat) ambient) * 0.25F;
- GLfloat luminance = 1.0F;
-
- switch (function) {
- case GL_LEQUAL:
- if (coord > depth00) luminance -= d;
- if (coord > depth01) luminance -= d;
- if (coord > depth10) luminance -= d;
- if (coord > depth11) luminance -= d;
- return luminance;
- case GL_GEQUAL:
- if (coord < depth00) luminance -= d;
- if (coord < depth01) luminance -= d;
- if (coord < depth10) luminance -= d;
- if (coord < depth11) luminance -= d;
- return luminance;
- case GL_LESS:
- if (coord >= depth00) luminance -= d;
- if (coord >= depth01) luminance -= d;
- if (coord >= depth10) luminance -= d;
- if (coord >= depth11) luminance -= d;
- return luminance;
- case GL_GREATER:
- if (coord <= depth00) luminance -= d;
- if (coord <= depth01) luminance -= d;
- if (coord <= depth10) luminance -= d;
- if (coord <= depth11) luminance -= d;
- return luminance;
- case GL_EQUAL:
- if (coord != depth00) luminance -= d;
- if (coord != depth01) luminance -= d;
- if (coord != depth10) luminance -= d;
- if (coord != depth11) luminance -= d;
- return luminance;
- case GL_NOTEQUAL:
- if (coord == depth00) luminance -= d;
- if (coord == depth01) luminance -= d;
- if (coord == depth10) luminance -= d;
- if (coord == depth11) luminance -= d;
- return luminance;
- case GL_ALWAYS:
- return 1.0F;
- case GL_NEVER:
- return ambient;
- case GL_NONE:
- /* ordinary bilinear filtering */
- return lerp_2d(wi, wj, depth00, depth10, depth01, depth11);
- default:
- _mesa_problem(NULL, "Bad compare func in sample_compare4");
- return ambient;
- }
-}
-
-
-/**
- * Choose the mipmap level to use when sampling from a depth texture.
- */
-static int
-choose_depth_texture_level(const struct gl_texture_object *tObj, GLfloat lambda)
-{
- GLint level;
-
- if (tObj->Sampler.MinFilter == GL_NEAREST || tObj->Sampler.MinFilter == GL_LINEAR) {
- /* no mipmapping - use base level */
- level = tObj->BaseLevel;
- }
- else {
- /* choose mipmap level */
- lambda = CLAMP(lambda, tObj->Sampler.MinLod, tObj->Sampler.MaxLod);
- level = (GLint) lambda;
- level = CLAMP(level, tObj->BaseLevel, tObj->_MaxLevel);
- }
-
- return level;
-}
-
-
-/**
- * Sample a shadow/depth texture. This function is incomplete. It doesn't
- * check for minification vs. magnification, etc.
- */
-static void
-sample_depth_texture( struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat texel[][4] )
-{
- const GLint level = choose_depth_texture_level(tObj, lambda[0]);
- const struct gl_texture_image *img = tObj->Image[0][level];
- const GLint width = img->Width;
- const GLint height = img->Height;
- const GLint depth = img->Depth;
- const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT)
- ? 3 : 2;
- GLfloat ambient;
- GLenum function;
- GLfloat result;
-
- ASSERT(img->_BaseFormat == GL_DEPTH_COMPONENT ||
- img->_BaseFormat == GL_DEPTH_STENCIL_EXT);
-
- ASSERT(tObj->Target == GL_TEXTURE_1D ||
- tObj->Target == GL_TEXTURE_2D ||
- tObj->Target == GL_TEXTURE_RECTANGLE_NV ||
- tObj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
- tObj->Target == GL_TEXTURE_2D_ARRAY_EXT);
-
- ambient = tObj->Sampler.CompareFailValue;
-
- /* XXXX if tObj->Sampler.MinFilter != tObj->Sampler.MagFilter, we're ignoring lambda */
-
- function = (tObj->Sampler.CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) ?
- tObj->Sampler.CompareFunc : GL_NONE;
-
- if (tObj->Sampler.MagFilter == GL_NEAREST) {
- GLuint i;
- for (i = 0; i < n; i++) {
- GLfloat depthSample, depthRef;
- GLint col, row, slice;
-
- nearest_texcoord(tObj, level, texcoords[i], &col, &row, &slice);
-
- if (col >= 0 && row >= 0 && col < width && row < height &&
- slice >= 0 && slice < depth) {
- img->FetchTexelf(img, col, row, slice, &depthSample);
- }
- else {
- depthSample = tObj->Sampler.BorderColor.f[0];
- }
-
- depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F);
-
- result = shadow_compare(function, depthRef, depthSample, ambient);
-
- switch (tObj->Sampler.DepthMode) {
- case GL_LUMINANCE:
- ASSIGN_4V(texel[i], result, result, result, 1.0F);
- break;
- case GL_INTENSITY:
- ASSIGN_4V(texel[i], result, result, result, result);
- break;
- case GL_ALPHA:
- ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result);
- break;
- case GL_RED:
- ASSIGN_4V(texel[i], result, 0.0F, 0.0F, 1.0F);
- break;
- default:
- _mesa_problem(ctx, "Bad depth texture mode");
- }
- }
- }
- else {
- GLuint i;
- ASSERT(tObj->Sampler.MagFilter == GL_LINEAR);
- for (i = 0; i < n; i++) {
- GLfloat depth00, depth01, depth10, depth11, depthRef;
- GLint i0, i1, j0, j1;
- GLint slice;
- GLfloat wi, wj;
- GLuint useBorderTexel;
-
- linear_texcoord(tObj, level, texcoords[i], &i0, &i1, &j0, &j1, &slice,
- &wi, &wj);
-
- useBorderTexel = 0;
- if (img->Border) {
- i0 += img->Border;
- i1 += img->Border;
- if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
- j0 += img->Border;
- j1 += img->Border;
- }
- }
- else {
- if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT;
- if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT;
- if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT;
- if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT;
- }
-
- if (slice < 0 || slice >= (GLint) depth) {
- depth00 = tObj->Sampler.BorderColor.f[0];
- depth01 = tObj->Sampler.BorderColor.f[0];
- depth10 = tObj->Sampler.BorderColor.f[0];
- depth11 = tObj->Sampler.BorderColor.f[0];
- }
- else {
- /* get four depth samples from the texture */
- if (useBorderTexel & (I0BIT | J0BIT)) {
- depth00 = tObj->Sampler.BorderColor.f[0];
- }
- else {
- img->FetchTexelf(img, i0, j0, slice, &depth00);
- }
- if (useBorderTexel & (I1BIT | J0BIT)) {
- depth10 = tObj->Sampler.BorderColor.f[0];
- }
- else {
- img->FetchTexelf(img, i1, j0, slice, &depth10);
- }
-
- if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
- if (useBorderTexel & (I0BIT | J1BIT)) {
- depth01 = tObj->Sampler.BorderColor.f[0];
- }
- else {
- img->FetchTexelf(img, i0, j1, slice, &depth01);
- }
- if (useBorderTexel & (I1BIT | J1BIT)) {
- depth11 = tObj->Sampler.BorderColor.f[0];
- }
- else {
- img->FetchTexelf(img, i1, j1, slice, &depth11);
- }
- }
- else {
- depth01 = depth00;
- depth11 = depth10;
- }
- }
-
- depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F);
-
- result = shadow_compare4(function, depthRef,
- depth00, depth01, depth10, depth11,
- ambient, wi, wj);
-
- switch (tObj->Sampler.DepthMode) {
- case GL_LUMINANCE:
- ASSIGN_4V(texel[i], result, result, result, 1.0F);
- break;
- case GL_INTENSITY:
- ASSIGN_4V(texel[i], result, result, result, result);
- break;
- case GL_ALPHA:
- ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result);
- break;
- default:
- _mesa_problem(ctx, "Bad depth texture mode");
- }
-
- } /* for */
- } /* if filter */
-}
-
-
-/**
- * We use this function when a texture object is in an "incomplete" state.
- * When a fragment program attempts to sample an incomplete texture we
- * return black (see issue 23 in GL_ARB_fragment_program spec).
- * Note: fragment programs don't observe the texture enable/disable flags.
- */
-static void
-null_sample_func( struct gl_context *ctx,
- const struct gl_texture_object *tObj, GLuint n,
- const GLfloat texcoords[][4], const GLfloat lambda[],
- GLfloat rgba[][4])
-{
- GLuint i;
- (void) ctx;
- (void) tObj;
- (void) texcoords;
- (void) lambda;
- for (i = 0; i < n; i++) {
- rgba[i][RCOMP] = 0;
- rgba[i][GCOMP] = 0;
- rgba[i][BCOMP] = 0;
- rgba[i][ACOMP] = 1.0;
- }
-}
-
-
-/**
- * Choose the texture sampling function for the given texture object.
- */
-texture_sample_func
-_swrast_choose_texture_sample_func( struct gl_context *ctx,
- const struct gl_texture_object *t )
-{
- if (!t || !t->_Complete) {
- return &null_sample_func;
- }
- else {
- const GLboolean needLambda =
- (GLboolean) (t->Sampler.MinFilter != t->Sampler.MagFilter);
- const GLenum format = t->Image[0][t->BaseLevel]->_BaseFormat;
-
- switch (t->Target) {
- case GL_TEXTURE_1D:
- if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
- return &sample_depth_texture;
- }
- else if (needLambda) {
- return &sample_lambda_1d;
- }
- else if (t->Sampler.MinFilter == GL_LINEAR) {
- return &sample_linear_1d;
- }
- else {
- ASSERT(t->Sampler.MinFilter == GL_NEAREST);
- return &sample_nearest_1d;
- }
- case GL_TEXTURE_2D:
- if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
- return &sample_depth_texture;
- }
- else if (needLambda) {
- /* Anisotropic filtering extension. Activated only if mipmaps are used */
- if (t->Sampler.MaxAnisotropy > 1.0 &&
- t->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
- return &sample_lambda_2d_aniso;
- }
- return &sample_lambda_2d;
- }
- else if (t->Sampler.MinFilter == GL_LINEAR) {
- return &sample_linear_2d;
- }
- else {
- /* check for a few optimized cases */
- const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
- ASSERT(t->Sampler.MinFilter == GL_NEAREST);
- if (t->Sampler.WrapS == GL_REPEAT &&
- t->Sampler.WrapT == GL_REPEAT &&
- img->_IsPowerOfTwo &&
- img->Border == 0 &&
- img->TexFormat == MESA_FORMAT_RGB888) {
- return &opt_sample_rgb_2d;
- }
- else if (t->Sampler.WrapS == GL_REPEAT &&
- t->Sampler.WrapT == GL_REPEAT &&
- img->_IsPowerOfTwo &&
- img->Border == 0 &&
- img->TexFormat == MESA_FORMAT_RGBA8888) {
- return &opt_sample_rgba_2d;
- }
- else {
- return &sample_nearest_2d;
- }
- }
- case GL_TEXTURE_3D:
- if (needLambda) {
- return &sample_lambda_3d;
- }
- else if (t->Sampler.MinFilter == GL_LINEAR) {
- return &sample_linear_3d;
- }
- else {
- ASSERT(t->Sampler.MinFilter == GL_NEAREST);
- return &sample_nearest_3d;
- }
- case GL_TEXTURE_CUBE_MAP:
- if (needLambda) {
- return &sample_lambda_cube;
- }
- else if (t->Sampler.MinFilter == GL_LINEAR) {
- return &sample_linear_cube;
- }
- else {
- ASSERT(t->Sampler.MinFilter == GL_NEAREST);
- return &sample_nearest_cube;
- }
- case GL_TEXTURE_RECTANGLE_NV:
- if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
- return &sample_depth_texture;
- }
- else if (needLambda) {
- return &sample_lambda_rect;
- }
- else if (t->Sampler.MinFilter == GL_LINEAR) {
- return &sample_linear_rect;
- }
- else {
- ASSERT(t->Sampler.MinFilter == GL_NEAREST);
- return &sample_nearest_rect;
- }
- case GL_TEXTURE_1D_ARRAY_EXT:
- if (needLambda) {
- return &sample_lambda_1d_array;
- }
- else if (t->Sampler.MinFilter == GL_LINEAR) {
- return &sample_linear_1d_array;
- }
- else {
- ASSERT(t->Sampler.MinFilter == GL_NEAREST);
- return &sample_nearest_1d_array;
- }
- case GL_TEXTURE_2D_ARRAY_EXT:
- if (needLambda) {
- return &sample_lambda_2d_array;
- }
- else if (t->Sampler.MinFilter == GL_LINEAR) {
- return &sample_linear_2d_array;
- }
- else {
- ASSERT(t->Sampler.MinFilter == GL_NEAREST);
- return &sample_nearest_2d_array;
- }
- default:
- _mesa_problem(ctx,
- "invalid target in _swrast_choose_texture_sample_func");
- return &null_sample_func;
- }
- }
-}
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.3
+ *
+ * Copyright (C) 1999-2008 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.
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/colormac.h"
+#include "main/imports.h"
+
+#include "s_context.h"
+#include "s_texfilter.h"
+
+
+/*
+ * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes
+ * see 1-pixel bands of improperly weighted linear-filtered textures.
+ * The tests/texwrap.c demo is a good test.
+ * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
+ * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
+ */
+#define FRAC(f) ((f) - IFLOOR(f))
+
+
+
+/**
+ * Linear interpolation macro
+ */
+#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) )
+
+
+/**
+ * Do 2D/biliner interpolation of float values.
+ * v00, v10, v01 and v11 are typically four texture samples in a square/box.
+ * a and b are the horizontal and vertical interpolants.
+ * It's important that this function is inlined when compiled with
+ * optimization! If we find that's not true on some systems, convert
+ * to a macro.
+ */
+static INLINE GLfloat
+lerp_2d(GLfloat a, GLfloat b,
+ GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11)
+{
+ const GLfloat temp0 = LERP(a, v00, v10);
+ const GLfloat temp1 = LERP(a, v01, v11);
+ return LERP(b, temp0, temp1);
+}
+
+
+/**
+ * Do 3D/trilinear interpolation of float values.
+ * \sa lerp_2d
+ */
+static INLINE GLfloat
+lerp_3d(GLfloat a, GLfloat b, GLfloat c,
+ GLfloat v000, GLfloat v100, GLfloat v010, GLfloat v110,
+ GLfloat v001, GLfloat v101, GLfloat v011, GLfloat v111)
+{
+ const GLfloat temp00 = LERP(a, v000, v100);
+ const GLfloat temp10 = LERP(a, v010, v110);
+ const GLfloat temp01 = LERP(a, v001, v101);
+ const GLfloat temp11 = LERP(a, v011, v111);
+ const GLfloat temp0 = LERP(b, temp00, temp10);
+ const GLfloat temp1 = LERP(b, temp01, temp11);
+ return LERP(c, temp0, temp1);
+}
+
+
+/**
+ * Do linear interpolation of colors.
+ */
+static INLINE void
+lerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4])
+{
+ result[0] = LERP(t, a[0], b[0]);
+ result[1] = LERP(t, a[1], b[1]);
+ result[2] = LERP(t, a[2], b[2]);
+ result[3] = LERP(t, a[3], b[3]);
+}
+
+
+/**
+ * Do bilinear interpolation of colors.
+ */
+static INLINE void
+lerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b,
+ const GLfloat t00[4], const GLfloat t10[4],
+ const GLfloat t01[4], const GLfloat t11[4])
+{
+ result[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]);
+ result[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]);
+ result[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]);
+ result[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]);
+}
+
+
+/**
+ * Do trilinear interpolation of colors.
+ */
+static INLINE void
+lerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c,
+ const GLfloat t000[4], const GLfloat t100[4],
+ const GLfloat t010[4], const GLfloat t110[4],
+ const GLfloat t001[4], const GLfloat t101[4],
+ const GLfloat t011[4], const GLfloat t111[4])
+{
+ GLuint k;
+ /* compiler should unroll these short loops */
+ for (k = 0; k < 4; k++) {
+ result[k] = lerp_3d(a, b, c, t000[k], t100[k], t010[k], t110[k],
+ t001[k], t101[k], t011[k], t111[k]);
+ }
+}
+
+
+/**
+ * Used for GL_REPEAT wrap mode. Using A % B doesn't produce the
+ * right results for A<0. Casting to A to be unsigned only works if B
+ * is a power of two. Adding a bias to A (which is a multiple of B)
+ * avoids the problems with A < 0 (for reasonable A) without using a
+ * conditional.
+ */
+#define REMAINDER(A, B) (((A) + (B) * 1024) % (B))
+
+
+/**
+ * Used to compute texel locations for linear sampling.
+ * Input:
+ * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER
+ * s = texcoord in [0,1]
+ * size = width (or height or depth) of texture
+ * Output:
+ * i0, i1 = returns two nearest texel indexes
+ * weight = returns blend factor between texels
+ */
+static INLINE void
+linear_texel_locations(GLenum wrapMode,
+ const struct gl_texture_image *img,
+ GLint size, GLfloat s,
+ GLint *i0, GLint *i1, GLfloat *weight)
+{
+ GLfloat u;
+ switch (wrapMode) {
+ case GL_REPEAT:
+ u = s * size - 0.5F;
+ if (img->_IsPowerOfTwo) {
+ *i0 = IFLOOR(u) & (size - 1);
+ *i1 = (*i0 + 1) & (size - 1);
+ }
+ else {
+ *i0 = REMAINDER(IFLOOR(u), size);
+ *i1 = REMAINDER(*i0 + 1, size);
+ }
+ break;
+ case GL_CLAMP_TO_EDGE:
+ if (s <= 0.0F)
+ u = 0.0F;
+ else if (s >= 1.0F)
+ u = (GLfloat) size;
+ else
+ u = s * size;
+ u -= 0.5F;
+ *i0 = IFLOOR(u);
+ *i1 = *i0 + 1;
+ if (*i0 < 0)
+ *i0 = 0;
+ if (*i1 >= (GLint) size)
+ *i1 = size - 1;
+ break;
+ case GL_CLAMP_TO_BORDER:
+ {
+ const GLfloat min = -1.0F / (2.0F * size);
+ const GLfloat max = 1.0F - min;
+ if (s <= min)
+ u = min * size;
+ else if (s >= max)
+ u = max * size;
+ else
+ u = s * size;
+ u -= 0.5F;
+ *i0 = IFLOOR(u);
+ *i1 = *i0 + 1;
+ }
+ break;
+ case GL_MIRRORED_REPEAT:
+ {
+ const GLint flr = IFLOOR(s);
+ if (flr & 1)
+ u = 1.0F - (s - (GLfloat) flr);
+ else
+ u = s - (GLfloat) flr;
+ u = (u * size) - 0.5F;
+ *i0 = IFLOOR(u);
+ *i1 = *i0 + 1;
+ if (*i0 < 0)
+ *i0 = 0;
+ if (*i1 >= (GLint) size)
+ *i1 = size - 1;
+ }
+ break;
+ case GL_MIRROR_CLAMP_EXT:
+ u = FABSF(s);
+ if (u >= 1.0F)
+ u = (GLfloat) size;
+ else
+ u *= size;
+ u -= 0.5F;
+ *i0 = IFLOOR(u);
+ *i1 = *i0 + 1;
+ break;
+ case GL_MIRROR_CLAMP_TO_EDGE_EXT:
+ u = FABSF(s);
+ if (u >= 1.0F)
+ u = (GLfloat) size;
+ else
+ u *= size;
+ u -= 0.5F;
+ *i0 = IFLOOR(u);
+ *i1 = *i0 + 1;
+ if (*i0 < 0)
+ *i0 = 0;
+ if (*i1 >= (GLint) size)
+ *i1 = size - 1;
+ break;
+ case GL_MIRROR_CLAMP_TO_BORDER_EXT:
+ {
+ const GLfloat min = -1.0F / (2.0F * size);
+ const GLfloat max = 1.0F - min;
+ u = FABSF(s);
+ if (u <= min)
+ u = min * size;
+ else if (u >= max)
+ u = max * size;
+ else
+ u *= size;
+ u -= 0.5F;
+ *i0 = IFLOOR(u);
+ *i1 = *i0 + 1;
+ }
+ break;
+ case GL_CLAMP:
+ if (s <= 0.0F)
+ u = 0.0F;
+ else if (s >= 1.0F)
+ u = (GLfloat) size;
+ else
+ u = s * size;
+ u -= 0.5F;
+ *i0 = IFLOOR(u);
+ *i1 = *i0 + 1;
+ break;
+ default:
+ _mesa_problem(NULL, "Bad wrap mode");
+ u = 0.0F;
+ }
+ *weight = FRAC(u);
+}
+
+
+/**
+ * Used to compute texel location for nearest sampling.
+ */
+static INLINE GLint
+nearest_texel_location(GLenum wrapMode,
+ const struct gl_texture_image *img,
+ GLint size, GLfloat s)
+{
+ GLint i;
+
+ switch (wrapMode) {
+ case GL_REPEAT:
+ /* s limited to [0,1) */
+ /* i limited to [0,size-1] */
+ i = IFLOOR(s * size);
+ if (img->_IsPowerOfTwo)
+ i &= (size - 1);
+ else
+ i = REMAINDER(i, size);
+ return i;
+ case GL_CLAMP_TO_EDGE:
+ {
+ /* s limited to [min,max] */
+ /* i limited to [0, size-1] */
+ const GLfloat min = 1.0F / (2.0F * size);
+ const GLfloat max = 1.0F - min;
+ if (s < min)
+ i = 0;
+ else if (s > max)
+ i = size - 1;
+ else
+ i = IFLOOR(s * size);
+ }
+ return i;
+ case GL_CLAMP_TO_BORDER:
+ {
+ /* s limited to [min,max] */
+ /* i limited to [-1, size] */
+ const GLfloat min = -1.0F / (2.0F * size);
+ const GLfloat max = 1.0F - min;
+ if (s <= min)
+ i = -1;
+ else if (s >= max)
+ i = size;
+ else
+ i = IFLOOR(s * size);
+ }
+ return i;
+ case GL_MIRRORED_REPEAT:
+ {
+ const GLfloat min = 1.0F / (2.0F * size);
+ const GLfloat max = 1.0F - min;
+ const GLint flr = IFLOOR(s);
+ GLfloat u;
+ if (flr & 1)
+ u = 1.0F - (s - (GLfloat) flr);
+ else
+ u = s - (GLfloat) flr;
+ if (u < min)
+ i = 0;
+ else if (u > max)
+ i = size - 1;
+ else
+ i = IFLOOR(u * size);
+ }
+ return i;
+ case GL_MIRROR_CLAMP_EXT:
+ {
+ /* s limited to [0,1] */
+ /* i limited to [0,size-1] */
+ const GLfloat u = FABSF(s);
+ if (u <= 0.0F)
+ i = 0;
+ else if (u >= 1.0F)
+ i = size - 1;
+ else
+ i = IFLOOR(u * size);
+ }
+ return i;
+ case GL_MIRROR_CLAMP_TO_EDGE_EXT:
+ {
+ /* s limited to [min,max] */
+ /* i limited to [0, size-1] */
+ const GLfloat min = 1.0F / (2.0F * size);
+ const GLfloat max = 1.0F - min;
+ const GLfloat u = FABSF(s);
+ if (u < min)
+ i = 0;
+ else if (u > max)
+ i = size - 1;
+ else
+ i = IFLOOR(u * size);
+ }
+ return i;
+ case GL_MIRROR_CLAMP_TO_BORDER_EXT:
+ {
+ /* s limited to [min,max] */
+ /* i limited to [0, size-1] */
+ const GLfloat min = -1.0F / (2.0F * size);
+ const GLfloat max = 1.0F - min;
+ const GLfloat u = FABSF(s);
+ if (u < min)
+ i = -1;
+ else if (u > max)
+ i = size;
+ else
+ i = IFLOOR(u * size);
+ }
+ return i;
+ case GL_CLAMP:
+ /* s limited to [0,1] */
+ /* i limited to [0,size-1] */
+ if (s <= 0.0F)
+ i = 0;
+ else if (s >= 1.0F)
+ i = size - 1;
+ else
+ i = IFLOOR(s * size);
+ return i;
+ default:
+ _mesa_problem(NULL, "Bad wrap mode");
+ return 0;
+ }
+}
+
+
+/* Power of two image sizes only */
+static INLINE void
+linear_repeat_texel_location(GLuint size, GLfloat s,
+ GLint *i0, GLint *i1, GLfloat *weight)
+{
+ GLfloat u = s * size - 0.5F;
+ *i0 = IFLOOR(u) & (size - 1);
+ *i1 = (*i0 + 1) & (size - 1);
+ *weight = FRAC(u);
+}
+
+
+/**
+ * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode.
+ */
+static INLINE GLint
+clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max)
+{
+ switch (wrapMode) {
+ case GL_CLAMP:
+ return IFLOOR( CLAMP(coord, 0.0F, max - 1) );
+ case GL_CLAMP_TO_EDGE:
+ return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) );
+ case GL_CLAMP_TO_BORDER:
+ return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) );
+ default:
+ _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest");
+ return 0;
+ }
+}
+
+
+/**
+ * As above, but GL_LINEAR filtering.
+ */
+static INLINE void
+clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max,
+ GLint *i0out, GLint *i1out, GLfloat *weight)
+{
+ GLfloat fcol;
+ GLint i0, i1;
+ switch (wrapMode) {
+ case GL_CLAMP:
+ /* Not exactly what the spec says, but it matches NVIDIA output */
+ fcol = CLAMP(coord - 0.5F, 0.0F, max - 1);
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+ break;
+ case GL_CLAMP_TO_EDGE:
+ fcol = CLAMP(coord, 0.5F, max - 0.5F);
+ fcol -= 0.5F;
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+ if (i1 > max - 1)
+ i1 = max - 1;
+ break;
+ case GL_CLAMP_TO_BORDER:
+ fcol = CLAMP(coord, -0.5F, max + 0.5F);
+ fcol -= 0.5F;
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+ break;
+ default:
+ _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear");
+ i0 = i1 = 0;
+ fcol = 0.0F;
+ }
+ *i0out = i0;
+ *i1out = i1;
+ *weight = FRAC(fcol);
+}
+
+
+/**
+ * Compute slice/image to use for 1D or 2D array texture.
+ */
+static INLINE GLint
+tex_array_slice(GLfloat coord, GLsizei size)
+{
+ GLint slice = IFLOOR(coord + 0.5f);
+ slice = CLAMP(slice, 0, size - 1);
+ return slice;
+}
+
+
+/**
+ * Compute nearest integer texcoords for given texobj and coordinate.
+ * NOTE: only used for depth texture sampling.
+ */
+static INLINE void
+nearest_texcoord(const struct gl_texture_object *texObj,
+ GLuint level,
+ const GLfloat texcoord[4],
+ GLint *i, GLint *j, GLint *k)
+{
+ const struct gl_texture_image *img = texObj->Image[0][level];
+ const GLint width = img->Width;
+ const GLint height = img->Height;
+ const GLint depth = img->Depth;
+
+ switch (texObj->Target) {
+ case GL_TEXTURE_RECTANGLE_ARB:
+ *i = clamp_rect_coord_nearest(texObj->Sampler.WrapS, texcoord[0], width);
+ *j = clamp_rect_coord_nearest(texObj->Sampler.WrapT, texcoord[1], height);
+ *k = 0;
+ break;
+ case GL_TEXTURE_1D:
+ *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]);
+ *j = 0;
+ *k = 0;
+ break;
+ case GL_TEXTURE_2D:
+ *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]);
+ *j = nearest_texel_location(texObj->Sampler.WrapT, img, height, texcoord[1]);
+ *k = 0;
+ break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]);
+ *j = tex_array_slice(texcoord[1], height);
+ *k = 0;
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]);
+ *j = nearest_texel_location(texObj->Sampler.WrapT, img, height, texcoord[1]);
+ *k = tex_array_slice(texcoord[2], depth);
+ break;
+ default:
+ *i = *j = *k = 0;
+ }
+}
+
+
+/**
+ * Compute linear integer texcoords for given texobj and coordinate.
+ * NOTE: only used for depth texture sampling.
+ */
+static INLINE void
+linear_texcoord(const struct gl_texture_object *texObj,
+ GLuint level,
+ const GLfloat texcoord[4],
+ GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice,
+ GLfloat *wi, GLfloat *wj)
+{
+ const struct gl_texture_image *img = texObj->Image[0][level];
+ const GLint width = img->Width;
+ const GLint height = img->Height;
+ const GLint depth = img->Depth;
+
+ switch (texObj->Target) {
+ case GL_TEXTURE_RECTANGLE_ARB:
+ clamp_rect_coord_linear(texObj->Sampler.WrapS, texcoord[0],
+ width, i0, i1, wi);
+ clamp_rect_coord_linear(texObj->Sampler.WrapT, texcoord[1],
+ height, j0, j1, wj);
+ *slice = 0;
+ break;
+
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ linear_texel_locations(texObj->Sampler.WrapS, img, width,
+ texcoord[0], i0, i1, wi);
+ linear_texel_locations(texObj->Sampler.WrapT, img, height,
+ texcoord[1], j0, j1, wj);
+ *slice = 0;
+ break;
+
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ linear_texel_locations(texObj->Sampler.WrapS, img, width,
+ texcoord[0], i0, i1, wi);
+ *j0 = tex_array_slice(texcoord[1], height);
+ *j1 = *j0;
+ *slice = 0;
+ break;
+
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ linear_texel_locations(texObj->Sampler.WrapS, img, width,
+ texcoord[0], i0, i1, wi);
+ linear_texel_locations(texObj->Sampler.WrapT, img, height,
+ texcoord[1], j0, j1, wj);
+ *slice = tex_array_slice(texcoord[2], depth);
+ break;
+
+ default:
+ *slice = 0;
+ }
+}
+
+
+
+/**
+ * For linear interpolation between mipmap levels N and N+1, this function
+ * computes N.
+ */
+static INLINE GLint
+linear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda)
+{
+ if (lambda < 0.0F)
+ return tObj->BaseLevel;
+ else if (lambda > tObj->_MaxLambda)
+ return (GLint) (tObj->BaseLevel + tObj->_MaxLambda);
+ else
+ return (GLint) (tObj->BaseLevel + lambda);
+}
+
+
+/**
+ * Compute the nearest mipmap level to take texels from.
+ */
+static INLINE GLint
+nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda)
+{
+ GLfloat l;
+ GLint level;
+ if (lambda <= 0.5F)
+ l = 0.0F;
+ else if (lambda > tObj->_MaxLambda + 0.4999F)
+ l = tObj->_MaxLambda + 0.4999F;
+ else
+ l = lambda;
+ level = (GLint) (tObj->BaseLevel + l + 0.5F);
+ if (level > tObj->_MaxLevel)
+ level = tObj->_MaxLevel;
+ return level;
+}
+
+
+
+/*
+ * Bitflags for texture border color sampling.
+ */
+#define I0BIT 1
+#define I1BIT 2
+#define J0BIT 4
+#define J1BIT 8
+#define K0BIT 16
+#define K1BIT 32
+
+
+
+/**
+ * The lambda[] array values are always monotonic. Either the whole span
+ * will be minified, magnified, or split between the two. This function
+ * determines the subranges in [0, n-1] that are to be minified or magnified.
+ */
+static INLINE void
+compute_min_mag_ranges(const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat lambda[],
+ GLuint *minStart, GLuint *minEnd,
+ GLuint *magStart, GLuint *magEnd)
+{
+ GLfloat minMagThresh;
+
+ /* we shouldn't be here if minfilter == magfilter */
+ ASSERT(tObj->Sampler.MinFilter != tObj->Sampler.MagFilter);
+
+ /* This bit comes from the OpenGL spec: */
+ if (tObj->Sampler.MagFilter == GL_LINEAR
+ && (tObj->Sampler.MinFilter == GL_NEAREST_MIPMAP_NEAREST ||
+ tObj->Sampler.MinFilter == GL_NEAREST_MIPMAP_LINEAR)) {
+ minMagThresh = 0.5F;
+ }
+ else {
+ minMagThresh = 0.0F;
+ }
+
+#if 0
+ /* DEBUG CODE: Verify that lambda[] is monotonic.
+ * We can't really use this because the inaccuracy in the LOG2 function
+ * causes this test to fail, yet the resulting texturing is correct.
+ */
+ if (n > 1) {
+ GLuint i;
+ printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);
+ if (lambda[0] >= lambda[n-1]) { /* decreasing */
+ for (i = 0; i < n - 1; i++) {
+ ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));
+ }
+ }
+ else { /* increasing */
+ for (i = 0; i < n - 1; i++) {
+ ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));
+ }
+ }
+ }
+#endif /* DEBUG */
+
+ if (lambda[0] <= minMagThresh && (n <= 1 || lambda[n-1] <= minMagThresh)) {
+ /* magnification for whole span */
+ *magStart = 0;
+ *magEnd = n;
+ *minStart = *minEnd = 0;
+ }
+ else if (lambda[0] > minMagThresh && (n <=1 || lambda[n-1] > minMagThresh)) {
+ /* minification for whole span */
+ *minStart = 0;
+ *minEnd = n;
+ *magStart = *magEnd = 0;
+ }
+ else {
+ /* a mix of minification and magnification */
+ GLuint i;
+ if (lambda[0] > minMagThresh) {
+ /* start with minification */
+ for (i = 1; i < n; i++) {
+ if (lambda[i] <= minMagThresh)
+ break;
+ }
+ *minStart = 0;
+ *minEnd = i;
+ *magStart = i;
+ *magEnd = n;
+ }
+ else {
+ /* start with magnification */
+ for (i = 1; i < n; i++) {
+ if (lambda[i] > minMagThresh)
+ break;
+ }
+ *magStart = 0;
+ *magEnd = i;
+ *minStart = i;
+ *minEnd = n;
+ }
+ }
+
+#if 0
+ /* Verify the min/mag Start/End values
+ * We don't use this either (see above)
+ */
+ {
+ GLint i;
+ for (i = 0; i < n; i++) {
+ if (lambda[i] > minMagThresh) {
+ /* minification */
+ ASSERT(i >= *minStart);
+ ASSERT(i < *minEnd);
+ }
+ else {
+ /* magnification */
+ ASSERT(i >= *magStart);
+ ASSERT(i < *magEnd);
+ }
+ }
+ }
+#endif
+}
+
+
+/**
+ * When we sample the border color, it must be interpreted according to
+ * the base texture format. Ex: if the texture base format it GL_ALPHA,
+ * we return (0,0,0,BorderAlpha).
+ */
+static INLINE void
+get_border_color(const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ GLfloat rgba[4])
+{
+ switch (img->_BaseFormat) {
+ case GL_RGB:
+ rgba[0] = tObj->Sampler.BorderColor.f[0];
+ rgba[1] = tObj->Sampler.BorderColor.f[1];
+ rgba[2] = tObj->Sampler.BorderColor.f[2];
+ rgba[3] = 1.0F;
+ break;
+ case GL_ALPHA:
+ rgba[0] = rgba[1] = rgba[2] = 0.0;
+ rgba[3] = tObj->Sampler.BorderColor.f[3];
+ break;
+ case GL_LUMINANCE:
+ rgba[0] = rgba[1] = rgba[2] = tObj->Sampler.BorderColor.f[0];
+ rgba[3] = 1.0;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ rgba[0] = rgba[1] = rgba[2] = tObj->Sampler.BorderColor.f[0];
+ rgba[3] = tObj->Sampler.BorderColor.f[3];
+ break;
+ case GL_INTENSITY:
+ rgba[0] = rgba[1] = rgba[2] = rgba[3] = tObj->Sampler.BorderColor.f[0];
+ break;
+ default:
+ COPY_4V(rgba, tObj->Sampler.BorderColor.f);
+ }
+}
+
+
+/**********************************************************************/
+/* 1-D Texture Sampling Functions */
+/**********************************************************************/
+
+/**
+ * Return the texture sample for coordinate (s) using GL_NEAREST filter.
+ */
+static INLINE void
+sample_1d_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4], GLfloat rgba[4])
+{
+ const GLint width = img->Width2; /* without border, power of two */
+ GLint i;
+ i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
+ /* skip over the border, if any */
+ i += img->Border;
+ if (i < 0 || i >= (GLint) img->Width) {
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ get_border_color(tObj, img, rgba);
+ }
+ else {
+ img->FetchTexelf(img, i, 0, 0, rgba);
+ }
+}
+
+
+/**
+ * Return the texture sample for coordinate (s) using GL_LINEAR filter.
+ */
+static INLINE void
+sample_1d_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4], GLfloat rgba[4])
+{
+ const GLint width = img->Width2;
+ GLint i0, i1;
+ GLbitfield useBorderColor = 0x0;
+ GLfloat a;
+ GLfloat t0[4], t1[4]; /* texels */
+
+ linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
+
+ if (img->Border) {
+ i0 += img->Border;
+ i1 += img->Border;
+ }
+ else {
+ if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
+ }
+
+ /* fetch texel colors */
+ if (useBorderColor & I0BIT) {
+ get_border_color(tObj, img, t0);
+ }
+ else {
+ img->FetchTexelf(img, i0, 0, 0, t0);
+ }
+ if (useBorderColor & I1BIT) {
+ get_border_color(tObj, img, t1);
+ }
+ else {
+ img->FetchTexelf(img, i1, 0, 0, t1);
+ }
+
+ lerp_rgba(rgba, a, t0, t1);
+}
+
+
+static void
+sample_1d_nearest_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_1d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_1d_linear_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_1d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_1d_nearest_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4];
+ const GLfloat f = FRAC(lambda[i]);
+ sample_1d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_1d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_1d_linear_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4];
+ const GLfloat f = FRAC(lambda[i]);
+ sample_1d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_1d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+/** Sample 1D texture, nearest filtering for both min/magnification */
+static void
+sample_nearest_1d( struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4] )
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_1d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/** Sample 1D texture, linear filtering for both min/magnification */
+static void
+sample_linear_1d( struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4] )
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_1d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/** Sample 1D texture, using lambda to choose between min/magnification */
+static void
+sample_lambda_1d( struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4] )
+{
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+ GLuint i;
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ const GLuint m = minEnd - minStart;
+ switch (tObj->Sampler.MinFilter) {
+ case GL_NEAREST:
+ for (i = minStart; i < minEnd; i++)
+ sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = minStart; i < minEnd; i++)
+ sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_1d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_1d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_1d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_1d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_1d_texture");
+ return;
+ }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ switch (tObj->Sampler.MagFilter) {
+ case GL_NEAREST:
+ for (i = magStart; i < magEnd; i++)
+ sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = magStart; i < magEnd; i++)
+ sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_1d_texture");
+ return;
+ }
+ }
+}
+
+
+/**********************************************************************/
+/* 2-D Texture Sampling Functions */
+/**********************************************************************/
+
+
+/**
+ * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
+ */
+static INLINE void
+sample_2d_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[])
+{
+ const GLint width = img->Width2; /* without border, power of two */
+ const GLint height = img->Height2; /* without border, power of two */
+ GLint i, j;
+ (void) ctx;
+
+ i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
+ j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]);
+
+ /* skip over the border, if any */
+ i += img->Border;
+ j += img->Border;
+
+ if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) {
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ get_border_color(tObj, img, rgba);
+ }
+ else {
+ img->FetchTexelf(img, i, j, 0, rgba);
+ }
+}
+
+
+/**
+ * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
+ * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
+ */
+static INLINE void
+sample_2d_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[])
+{
+ const GLint width = img->Width2;
+ const GLint height = img->Height2;
+ GLint i0, j0, i1, j1;
+ GLbitfield useBorderColor = 0x0;
+ GLfloat a, b;
+ GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */
+
+ linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
+ linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b);
+
+ if (img->Border) {
+ i0 += img->Border;
+ i1 += img->Border;
+ j0 += img->Border;
+ j1 += img->Border;
+ }
+ else {
+ if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
+ if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
+ if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
+ }
+
+ /* fetch four texel colors */
+ if (useBorderColor & (I0BIT | J0BIT)) {
+ get_border_color(tObj, img, t00);
+ }
+ else {
+ img->FetchTexelf(img, i0, j0, 0, t00);
+ }
+ if (useBorderColor & (I1BIT | J0BIT)) {
+ get_border_color(tObj, img, t10);
+ }
+ else {
+ img->FetchTexelf(img, i1, j0, 0, t10);
+ }
+ if (useBorderColor & (I0BIT | J1BIT)) {
+ get_border_color(tObj, img, t01);
+ }
+ else {
+ img->FetchTexelf(img, i0, j1, 0, t01);
+ }
+ if (useBorderColor & (I1BIT | J1BIT)) {
+ get_border_color(tObj, img, t11);
+ }
+ else {
+ img->FetchTexelf(img, i1, j1, 0, t11);
+ }
+
+ lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
+}
+
+
+/**
+ * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT.
+ * We don't have to worry about the texture border.
+ */
+static INLINE void
+sample_2d_linear_repeat(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[])
+{
+ const GLint width = img->Width2;
+ const GLint height = img->Height2;
+ GLint i0, j0, i1, j1;
+ GLfloat wi, wj;
+ GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */
+
+ (void) ctx;
+
+ ASSERT(tObj->Sampler.WrapS == GL_REPEAT);
+ ASSERT(tObj->Sampler.WrapT == GL_REPEAT);
+ ASSERT(img->Border == 0);
+ ASSERT(img->_IsPowerOfTwo);
+
+ linear_repeat_texel_location(width, texcoord[0], &i0, &i1, &wi);
+ linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj);
+
+ img->FetchTexelf(img, i0, j0, 0, t00);
+ img->FetchTexelf(img, i1, j0, 0, t10);
+ img->FetchTexelf(img, i0, j1, 0, t01);
+ img->FetchTexelf(img, i1, j1, 0, t11);
+
+ lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11);
+}
+
+
+static void
+sample_2d_nearest_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_2d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_2d_linear_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_2d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_2d_nearest_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_2d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_2d_linear_mipmap_linear( struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4] )
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_2d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_2d_linear_mipmap_linear_repeat(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ ASSERT(tObj->Sampler.WrapS == GL_REPEAT);
+ ASSERT(tObj->Sampler.WrapT == GL_REPEAT);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ],
+ texcoord[i], t0);
+ sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level+1],
+ texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+/** Sample 2D texture, nearest filtering for both min/magnification */
+static void
+sample_nearest_2d(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/** Sample 2D texture, linear filtering for both min/magnification */
+static void
+sample_linear_2d(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ if (tObj->Sampler.WrapS == GL_REPEAT &&
+ tObj->Sampler.WrapT == GL_REPEAT &&
+ image->_IsPowerOfTwo &&
+ image->Border == 0) {
+ for (i = 0; i < n; i++) {
+ sample_2d_linear_repeat(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+ }
+ else {
+ for (i = 0; i < n; i++) {
+ sample_2d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+ }
+}
+
+
+/**
+ * Optimized 2-D texture sampling:
+ * S and T wrap mode == GL_REPEAT
+ * GL_NEAREST min/mag filter
+ * No border,
+ * RowStride == Width,
+ * Format = GL_RGB
+ */
+static void
+opt_sample_rgb_2d(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];
+ const GLfloat width = (GLfloat) img->Width;
+ const GLfloat height = (GLfloat) img->Height;
+ const GLint colMask = img->Width - 1;
+ const GLint rowMask = img->Height - 1;
+ const GLint shift = img->WidthLog2;
+ GLuint k;
+ (void) ctx;
+ (void) lambda;
+ ASSERT(tObj->Sampler.WrapS==GL_REPEAT);
+ ASSERT(tObj->Sampler.WrapT==GL_REPEAT);
+ ASSERT(img->Border==0);
+ ASSERT(img->TexFormat == MESA_FORMAT_RGB888);
+ ASSERT(img->_IsPowerOfTwo);
+
+ for (k=0; k<n; k++) {
+ GLint i = IFLOOR(texcoords[k][0] * width) & colMask;
+ GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;
+ GLint pos = (j << shift) | i;
+ GLubyte *texel = ((GLubyte *) img->Data) + 3*pos;
+ rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]);
+ rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]);
+ rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]);
+ rgba[k][ACOMP] = 1.0F;
+ }
+}
+
+
+/**
+ * Optimized 2-D texture sampling:
+ * S and T wrap mode == GL_REPEAT
+ * GL_NEAREST min/mag filter
+ * No border
+ * RowStride == Width,
+ * Format = GL_RGBA
+ */
+static void
+opt_sample_rgba_2d(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];
+ const GLfloat width = (GLfloat) img->Width;
+ const GLfloat height = (GLfloat) img->Height;
+ const GLint colMask = img->Width - 1;
+ const GLint rowMask = img->Height - 1;
+ const GLint shift = img->WidthLog2;
+ GLuint i;
+ (void) ctx;
+ (void) lambda;
+ ASSERT(tObj->Sampler.WrapS==GL_REPEAT);
+ ASSERT(tObj->Sampler.WrapT==GL_REPEAT);
+ ASSERT(img->Border==0);
+ ASSERT(img->TexFormat == MESA_FORMAT_RGBA8888);
+ ASSERT(img->_IsPowerOfTwo);
+
+ for (i = 0; i < n; i++) {
+ const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;
+ const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;
+ const GLint pos = (row << shift) | col;
+ const GLuint texel = *((GLuint *) img->Data + pos);
+ rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24) );
+ rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff );
+ rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >> 8) & 0xff );
+ rgba[i][ACOMP] = UBYTE_TO_FLOAT( (texel ) & 0xff );
+ }
+}
+
+
+/** Sample 2D texture, using lambda to choose between min/magnification */
+static void
+sample_lambda_2d(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+
+ const GLboolean repeatNoBorderPOT = (tObj->Sampler.WrapS == GL_REPEAT)
+ && (tObj->Sampler.WrapT == GL_REPEAT)
+ && (tImg->Border == 0 && (tImg->Width == tImg->RowStride))
+ && tImg->_IsPowerOfTwo;
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ const GLuint m = minEnd - minStart;
+ switch (tObj->Sampler.MinFilter) {
+ case GL_NEAREST:
+ if (repeatNoBorderPOT) {
+ switch (tImg->TexFormat) {
+ case MESA_FORMAT_RGB888:
+ opt_sample_rgb_2d(ctx, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart);
+ break;
+ case MESA_FORMAT_RGBA8888:
+ opt_sample_rgba_2d(ctx, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart);
+ break;
+ default:
+ sample_nearest_2d(ctx, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart );
+ }
+ }
+ else {
+ sample_nearest_2d(ctx, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart);
+ }
+ break;
+ case GL_LINEAR:
+ sample_linear_2d(ctx, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_2d_nearest_mipmap_nearest(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_2d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_2d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ if (repeatNoBorderPOT)
+ sample_2d_linear_mipmap_linear_repeat(ctx, tObj, m,
+ texcoords + minStart, lambda + minStart, rgba + minStart);
+ else
+ sample_2d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_2d_texture");
+ return;
+ }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ const GLuint m = magEnd - magStart;
+
+ switch (tObj->Sampler.MagFilter) {
+ case GL_NEAREST:
+ if (repeatNoBorderPOT) {
+ switch (tImg->TexFormat) {
+ case MESA_FORMAT_RGB888:
+ opt_sample_rgb_2d(ctx, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart);
+ break;
+ case MESA_FORMAT_RGBA8888:
+ opt_sample_rgba_2d(ctx, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart);
+ break;
+ default:
+ sample_nearest_2d(ctx, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart );
+ }
+ }
+ else {
+ sample_nearest_2d(ctx, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart);
+ }
+ break;
+ case GL_LINEAR:
+ sample_linear_2d(ctx, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d");
+ }
+ }
+}
+
+
+/* For anisotropic filtering */
+#define WEIGHT_LUT_SIZE 1024
+
+static GLfloat *weightLut = NULL;
+
+/**
+ * Creates the look-up table used to speed-up EWA sampling
+ */
+static void
+create_filter_table(void)
+{
+ GLuint i;
+ if (!weightLut) {
+ weightLut = (GLfloat *) malloc(WEIGHT_LUT_SIZE * sizeof(GLfloat));
+
+ for (i = 0; i < WEIGHT_LUT_SIZE; ++i) {
+ GLfloat alpha = 2;
+ GLfloat r2 = (GLfloat) i / (GLfloat) (WEIGHT_LUT_SIZE - 1);
+ GLfloat weight = (GLfloat) exp(-alpha * r2);
+ weightLut[i] = weight;
+ }
+ }
+}
+
+
+/**
+ * Elliptical weighted average (EWA) filter for producing high quality
+ * anisotropic filtered results.
+ * Based on the Higher Quality Elliptical Weighted Avarage Filter
+ * published by Paul S. Heckbert in his Master's Thesis
+ * "Fundamentals of Texture Mapping and Image Warping" (1989)
+ */
+static void
+sample_2d_ewa(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const GLfloat texcoord[4],
+ const GLfloat dudx, const GLfloat dvdx,
+ const GLfloat dudy, const GLfloat dvdy, const GLint lod,
+ GLfloat rgba[])
+{
+ GLint level = lod > 0 ? lod : 0;
+ GLfloat scaling = 1.0 / (1 << level);
+ const struct gl_texture_image *img = tObj->Image[0][level];
+ const struct gl_texture_image *mostDetailedImage =
+ tObj->Image[0][tObj->BaseLevel];
+ GLfloat tex_u=-0.5 + texcoord[0] * mostDetailedImage->WidthScale * scaling;
+ GLfloat tex_v=-0.5 + texcoord[1] * mostDetailedImage->HeightScale * scaling;
+
+ GLfloat ux = dudx * scaling;
+ GLfloat vx = dvdx * scaling;
+ GLfloat uy = dudy * scaling;
+ GLfloat vy = dvdy * scaling;
+
+ /* compute ellipse coefficients to bound the region:
+ * A*x*x + B*x*y + C*y*y = F.
+ */
+ GLfloat A = vx*vx+vy*vy+1;
+ GLfloat B = -2*(ux*vx+uy*vy);
+ GLfloat C = ux*ux+uy*uy+1;
+ GLfloat F = A*C-B*B/4.0;
+
+ /* check if it is an ellipse */
+ /* ASSERT(F > 0.0); */
+
+ /* Compute the ellipse's (u,v) bounding box in texture space */
+ GLfloat d = -B*B+4.0*C*A;
+ GLfloat box_u = 2.0 / d * sqrt(d*C*F); /* box_u -> half of bbox with */
+ GLfloat box_v = 2.0 / d * sqrt(A*d*F); /* box_v -> half of bbox height */
+
+ GLint u0 = floor(tex_u - box_u);
+ GLint u1 = ceil (tex_u + box_u);
+ GLint v0 = floor(tex_v - box_v);
+ GLint v1 = ceil (tex_v + box_v);
+
+ GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
+ GLfloat newCoord[2];
+ GLfloat den = 0.0F;
+ GLfloat ddq;
+ GLfloat U = u0 - tex_u;
+ GLint v;
+
+ /* Scale ellipse formula to directly index the Filter Lookup Table.
+ * i.e. scale so that F = WEIGHT_LUT_SIZE-1
+ */
+ double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F;
+ A *= formScale;
+ B *= formScale;
+ C *= formScale;
+ /* F *= formScale; */ /* no need to scale F as we don't use it below here */
+
+ /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse
+ * and incrementally update the value of Ax^2+Bxy*Cy^2; when this
+ * value, q, is less than F, we're inside the ellipse
+ */
+ ddq = 2 * A;
+ for (v = v0; v <= v1; ++v) {
+ GLfloat V = v - tex_v;
+ GLfloat dq = A * (2 * U + 1) + B * V;
+ GLfloat q = (C * V + B * U) * V + A * U * U;
+
+ GLint u;
+ for (u = u0; u <= u1; ++u) {
+ /* Note that the ellipse has been pre-scaled so F = WEIGHT_LUT_SIZE - 1 */
+ if (q < WEIGHT_LUT_SIZE) {
+ /* as a LUT is used, q must never be negative;
+ * should not happen, though
+ */
+ const GLint qClamped = q >= 0.0F ? q : 0;
+ GLfloat weight = weightLut[qClamped];
+
+ newCoord[0] = u / ((GLfloat) img->Width2);
+ newCoord[1] = v / ((GLfloat) img->Height2);
+
+ sample_2d_nearest(ctx, tObj, img, newCoord, rgba);
+ num[0] += weight * rgba[0];
+ num[1] += weight * rgba[1];
+ num[2] += weight * rgba[2];
+ num[3] += weight * rgba[3];
+
+ den += weight;
+ }
+ q += dq;
+ dq += ddq;
+ }
+ }
+
+ if (den <= 0.0F) {
+ /* Reaching this place would mean
+ * that no pixels intersected the ellipse.
+ * This should never happen because
+ * the filter we use always
+ * intersects at least one pixel.
+ */
+
+ /*rgba[0]=0;
+ rgba[1]=0;
+ rgba[2]=0;
+ rgba[3]=0;*/
+ /* not enough pixels in resampling, resort to direct interpolation */
+ sample_2d_linear(ctx, tObj, img, texcoord, rgba);
+ return;
+ }
+
+ rgba[0] = num[0] / den;
+ rgba[1] = num[1] / den;
+ rgba[2] = num[2] / den;
+ rgba[3] = num[3] / den;
+}
+
+
+/**
+ * Anisotropic filtering using footprint assembly as outlined in the
+ * EXT_texture_filter_anisotropic spec:
+ * http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt
+ * Faster than EWA but has less quality (more aliasing effects)
+ */
+static void
+sample_2d_footprint(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const GLfloat texcoord[4],
+ const GLfloat dudx, const GLfloat dvdx,
+ const GLfloat dudy, const GLfloat dvdy, const GLint lod,
+ GLfloat rgba[])
+{
+ GLint level = lod > 0 ? lod : 0;
+ GLfloat scaling = 1.0F / (1 << level);
+ const struct gl_texture_image *img = tObj->Image[0][level];
+
+ GLfloat ux = dudx * scaling;
+ GLfloat vx = dvdx * scaling;
+ GLfloat uy = dudy * scaling;
+ GLfloat vy = dvdy * scaling;
+
+ GLfloat Px2 = ux * ux + vx * vx; /* squared length of dx */
+ GLfloat Py2 = uy * uy + vy * vy; /* squared length of dy */
+
+ GLint numSamples;
+ GLfloat ds;
+ GLfloat dt;
+
+ GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
+ GLfloat newCoord[2];
+ GLint s;
+
+ /* Calculate the per anisotropic sample offsets in s,t space. */
+ if (Px2 > Py2) {
+ numSamples = ceil(SQRTF(Px2));
+ ds = ux / ((GLfloat) img->Width2);
+ dt = vx / ((GLfloat) img->Height2);
+ }
+ else {
+ numSamples = ceil(SQRTF(Py2));
+ ds = uy / ((GLfloat) img->Width2);
+ dt = vy / ((GLfloat) img->Height2);
+ }
+
+ for (s = 0; s<numSamples; s++) {
+ newCoord[0] = texcoord[0] + ds * ((GLfloat)(s+1) / (numSamples+1) -0.5);
+ newCoord[1] = texcoord[1] + dt * ((GLfloat)(s+1) / (numSamples+1) -0.5);
+
+ sample_2d_linear(ctx, tObj, img, newCoord, rgba);
+ num[0] += rgba[0];
+ num[1] += rgba[1];
+ num[2] += rgba[2];
+ num[3] += rgba[3];
+ }
+
+ rgba[0] = num[0] / numSamples;
+ rgba[1] = num[1] / numSamples;
+ rgba[2] = num[2] / numSamples;
+ rgba[3] = num[3] / numSamples;
+}
+
+
+/**
+ * Returns the index of the specified texture object in the
+ * gl_context texture unit array.
+ */
+static INLINE GLuint
+texture_unit_index(const struct gl_context *ctx,
+ const struct gl_texture_object *tObj)
+{
+ const GLuint maxUnit
+ = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
+ GLuint u;
+
+ /* XXX CoordUnits vs. ImageUnits */
+ for (u = 0; u < maxUnit; u++) {
+ if (ctx->Texture.Unit[u]._Current == tObj)
+ break; /* found */
+ }
+ if (u >= maxUnit)
+ u = 0; /* not found, use 1st one; should never happen */
+
+ return u;
+}
+
+
+/**
+ * Sample 2D texture using an anisotropic filter.
+ * NOTE: the const GLfloat lambda_iso[] parameter does *NOT* contain
+ * the lambda float array but a "hidden" SWspan struct which is required
+ * by this function but is not available in the texture_sample_func signature.
+ * See _swrast_texture_span( struct gl_context *ctx, SWspan *span ) on how
+ * this function is called.
+ */
+static void
+sample_lambda_2d_aniso(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoords[][4],
+ const GLfloat lambda_iso[], GLfloat rgba[][4])
+{
+ const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];
+ const GLfloat maxEccentricity =
+ tObj->Sampler.MaxAnisotropy * tObj->Sampler.MaxAnisotropy;
+
+ /* re-calculate the lambda values so that they are usable with anisotropic
+ * filtering
+ */
+ SWspan *span = (SWspan *)lambda_iso; /* access the "hidden" SWspan struct */
+
+ /* based on interpolate_texcoords(struct gl_context *ctx, SWspan *span)
+ * in swrast/s_span.c
+ */
+
+ /* find the texture unit index by looking up the current texture object
+ * from the context list of available texture objects.
+ */
+ const GLuint u = texture_unit_index(ctx, tObj);
+ const GLuint attr = FRAG_ATTRIB_TEX0 + u;
+ GLfloat texW, texH;
+
+ const GLfloat dsdx = span->attrStepX[attr][0];
+ const GLfloat dsdy = span->attrStepY[attr][0];
+ const GLfloat dtdx = span->attrStepX[attr][1];
+ const GLfloat dtdy = span->attrStepY[attr][1];
+ const GLfloat dqdx = span->attrStepX[attr][3];
+ const GLfloat dqdy = span->attrStepY[attr][3];
+ GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx;
+ GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx;
+ GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx;
+
+ /* from swrast/s_texcombine.c _swrast_texture_span */
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
+ const GLboolean adjustLOD =
+ (texUnit->LodBias + tObj->Sampler.LodBias != 0.0F)
+ || (tObj->Sampler.MinLod != -1000.0 || tObj->Sampler.MaxLod != 1000.0);
+
+ GLuint i;
+
+ /* on first access create the lookup table containing the filter weights. */
+ if (!weightLut) {
+ create_filter_table();
+ }
+
+ texW = tImg->WidthScale;
+ texH = tImg->HeightScale;
+
+ for (i = 0; i < n; i++) {
+ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+
+ GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
+ GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
+ GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
+ GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
+
+ /* note: instead of working with Px and Py, we will use the
+ * squared length instead, to avoid sqrt.
+ */
+ GLfloat Px2 = dudx * dudx + dvdx * dvdx;
+ GLfloat Py2 = dudy * dudy + dvdy * dvdy;
+
+ GLfloat Pmax2;
+ GLfloat Pmin2;
+ GLfloat e;
+ GLfloat lod;
+
+ s += dsdx;
+ t += dtdx;
+ q += dqdx;
+
+ if (Px2 < Py2) {
+ Pmax2 = Py2;
+ Pmin2 = Px2;
+ }
+ else {
+ Pmax2 = Px2;
+ Pmin2 = Py2;
+ }
+
+ /* if the eccentricity of the ellipse is too big, scale up the shorter
+ * of the two vectors to limit the maximum amount of work per pixel
+ */
+ e = Pmax2 / Pmin2;
+ if (e > maxEccentricity) {
+ /* GLfloat s=e / maxEccentricity;
+ minor[0] *= s;
+ minor[1] *= s;
+ Pmin2 *= s; */
+ Pmin2 = Pmax2 / maxEccentricity;
+ }
+
+ /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid
+ * this since 0.5*log(x) = log(sqrt(x))
+ */
+ lod = 0.5 * LOG2(Pmin2);
+
+ if (adjustLOD) {
+ /* from swrast/s_texcombine.c _swrast_texture_span */
+ if (texUnit->LodBias + tObj->Sampler.LodBias != 0.0F) {
+ /* apply LOD bias, but don't clamp yet */
+ const GLfloat bias =
+ CLAMP(texUnit->LodBias + tObj->Sampler.LodBias,
+ -ctx->Const.MaxTextureLodBias,
+ ctx->Const.MaxTextureLodBias);
+ lod += bias;
+
+ if (tObj->Sampler.MinLod != -1000.0 ||
+ tObj->Sampler.MaxLod != 1000.0) {
+ /* apply LOD clamping to lambda */
+ lod = CLAMP(lod, tObj->Sampler.MinLod, tObj->Sampler.MaxLod);
+ }
+ }
+ }
+
+ /* If the ellipse covers the whole image, we can
+ * simply return the average of the whole image.
+ */
+ if (lod >= tObj->_MaxLevel) {
+ sample_2d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoords[i], rgba[i]);
+ }
+ else {
+ /* don't bother interpolating between multiple LODs; it doesn't
+ * seem to be worth the extra running time.
+ */
+ sample_2d_ewa(ctx, tObj, texcoords[i],
+ dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]);
+
+ /* unused: */
+ (void) sample_2d_footprint;
+ /*
+ sample_2d_footprint(ctx, tObj, texcoords[i],
+ dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]);
+ */
+ }
+ }
+}
+
+
+
+/**********************************************************************/
+/* 3-D Texture Sampling Functions */
+/**********************************************************************/
+
+/**
+ * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
+ */
+static INLINE void
+sample_3d_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[4])
+{
+ const GLint width = img->Width2; /* without border, power of two */
+ const GLint height = img->Height2; /* without border, power of two */
+ const GLint depth = img->Depth2; /* without border, power of two */
+ GLint i, j, k;
+ (void) ctx;
+
+ i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
+ j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]);
+ k = nearest_texel_location(tObj->Sampler.WrapR, img, depth, texcoord[2]);
+
+ if (i < 0 || i >= (GLint) img->Width ||
+ j < 0 || j >= (GLint) img->Height ||
+ k < 0 || k >= (GLint) img->Depth) {
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ get_border_color(tObj, img, rgba);
+ }
+ else {
+ img->FetchTexelf(img, i, j, k, rgba);
+ }
+}
+
+
+/**
+ * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
+ */
+static void
+sample_3d_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[4])
+{
+ const GLint width = img->Width2;
+ const GLint height = img->Height2;
+ const GLint depth = img->Depth2;
+ GLint i0, j0, k0, i1, j1, k1;
+ GLbitfield useBorderColor = 0x0;
+ GLfloat a, b, c;
+ GLfloat t000[4], t010[4], t001[4], t011[4];
+ GLfloat t100[4], t110[4], t101[4], t111[4];
+
+ linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
+ linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b);
+ linear_texel_locations(tObj->Sampler.WrapR, img, depth, texcoord[2], &k0, &k1, &c);
+
+ if (img->Border) {
+ i0 += img->Border;
+ i1 += img->Border;
+ j0 += img->Border;
+ j1 += img->Border;
+ k0 += img->Border;
+ k1 += img->Border;
+ }
+ else {
+ /* check if sampling texture border color */
+ if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
+ if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
+ if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
+ if (k0 < 0 || k0 >= depth) useBorderColor |= K0BIT;
+ if (k1 < 0 || k1 >= depth) useBorderColor |= K1BIT;
+ }
+
+ /* Fetch texels */
+ if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {
+ get_border_color(tObj, img, t000);
+ }
+ else {
+ img->FetchTexelf(img, i0, j0, k0, t000);
+ }
+ if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
+ get_border_color(tObj, img, t100);
+ }
+ else {
+ img->FetchTexelf(img, i1, j0, k0, t100);
+ }
+ if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
+ get_border_color(tObj, img, t010);
+ }
+ else {
+ img->FetchTexelf(img, i0, j1, k0, t010);
+ }
+ if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
+ get_border_color(tObj, img, t110);
+ }
+ else {
+ img->FetchTexelf(img, i1, j1, k0, t110);
+ }
+
+ if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
+ get_border_color(tObj, img, t001);
+ }
+ else {
+ img->FetchTexelf(img, i0, j0, k1, t001);
+ }
+ if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
+ get_border_color(tObj, img, t101);
+ }
+ else {
+ img->FetchTexelf(img, i1, j0, k1, t101);
+ }
+ if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
+ get_border_color(tObj, img, t011);
+ }
+ else {
+ img->FetchTexelf(img, i0, j1, k1, t011);
+ }
+ if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
+ get_border_color(tObj, img, t111);
+ }
+ else {
+ img->FetchTexelf(img, i1, j1, k1, t111);
+ }
+
+ /* trilinear interpolation of samples */
+ lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111);
+}
+
+
+static void
+sample_3d_nearest_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4] )
+{
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_3d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_3d_linear_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_3d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_3d_nearest_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_3d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_3d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_3d_linear_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_3d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_3d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+/** Sample 3D texture, nearest filtering for both min/magnification */
+static void
+sample_nearest_3d(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/** Sample 3D texture, linear filtering for both min/magnification */
+static void
+sample_linear_3d(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_3d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/** Sample 3D texture, using lambda to choose between min/magnification */
+static void
+sample_lambda_3d(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+ GLuint i;
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ GLuint m = minEnd - minStart;
+ switch (tObj->Sampler.MinFilter) {
+ case GL_NEAREST:
+ for (i = minStart; i < minEnd; i++)
+ sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = minStart; i < minEnd; i++)
+ sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_3d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_3d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_3d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_3d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_3d_texture");
+ return;
+ }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ switch (tObj->Sampler.MagFilter) {
+ case GL_NEAREST:
+ for (i = magStart; i < magEnd; i++)
+ sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = magStart; i < magEnd; i++)
+ sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_3d_texture");
+ return;
+ }
+ }
+}
+
+
+/**********************************************************************/
+/* Texture Cube Map Sampling Functions */
+/**********************************************************************/
+
+/**
+ * Choose one of six sides of a texture cube map given the texture
+ * coord (rx,ry,rz). Return pointer to corresponding array of texture
+ * images.
+ */
+static const struct gl_texture_image **
+choose_cube_face(const struct gl_texture_object *texObj,
+ const GLfloat texcoord[4], GLfloat newCoord[4])
+{
+ /*
+ major axis
+ direction target sc tc ma
+ ---------- ------------------------------- --- --- ---
+ +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
+ -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
+ +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
+ -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
+ +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
+ -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
+ */
+ const GLfloat rx = texcoord[0];
+ const GLfloat ry = texcoord[1];
+ const GLfloat rz = texcoord[2];
+ const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
+ GLuint face;
+ GLfloat sc, tc, ma;
+
+ if (arx >= ary && arx >= arz) {
+ if (rx >= 0.0F) {
+ face = FACE_POS_X;
+ sc = -rz;
+ tc = -ry;
+ ma = arx;
+ }
+ else {
+ face = FACE_NEG_X;
+ sc = rz;
+ tc = -ry;
+ ma = arx;
+ }
+ }
+ else if (ary >= arx && ary >= arz) {
+ if (ry >= 0.0F) {
+ face = FACE_POS_Y;
+ sc = rx;
+ tc = rz;
+ ma = ary;
+ }
+ else {
+ face = FACE_NEG_Y;
+ sc = rx;
+ tc = -rz;
+ ma = ary;
+ }
+ }
+ else {
+ if (rz > 0.0F) {
+ face = FACE_POS_Z;
+ sc = rx;
+ tc = -ry;
+ ma = arz;
+ }
+ else {
+ face = FACE_NEG_Z;
+ sc = -rx;
+ tc = -ry;
+ ma = arz;
+ }
+ }
+
+ {
+ const float ima = 1.0F / ma;
+ newCoord[0] = ( sc * ima + 1.0F ) * 0.5F;
+ newCoord[1] = ( tc * ima + 1.0F ) * 0.5F;
+ }
+
+ return (const struct gl_texture_image **) texObj->Image[face];
+}
+
+
+static void
+sample_nearest_cube(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint i;
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ images = choose_cube_face(tObj, texcoords[i], newCoord);
+ sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
+ newCoord, rgba[i]);
+ }
+}
+
+
+static void
+sample_linear_cube(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ images = choose_cube_face(tObj, texcoords[i], newCoord);
+ sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
+ newCoord, rgba[i]);
+ }
+}
+
+
+static void
+sample_cube_nearest_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ GLint level;
+ images = choose_cube_face(tObj, texcoord[i], newCoord);
+
+ /* XXX we actually need to recompute lambda here based on the newCoords.
+ * But we would need the texcoords of adjacent fragments to compute that
+ * properly, and we don't have those here.
+ * For now, do an approximation: subtracting 1 from the chosen mipmap
+ * level seems to work in some test cases.
+ * The same adjustment is done in the next few functions.
+ */
+ level = nearest_mipmap_level(tObj, lambda[i]);
+ level = MAX2(level - 1, 0);
+
+ sample_2d_nearest(ctx, tObj, images[level], newCoord, rgba[i]);
+ }
+}
+
+
+static void
+sample_cube_linear_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ level = MAX2(level - 1, 0); /* see comment above */
+ images = choose_cube_face(tObj, texcoord[i], newCoord);
+ sample_2d_linear(ctx, tObj, images[level], newCoord, rgba[i]);
+ }
+}
+
+
+static void
+sample_cube_nearest_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ level = MAX2(level - 1, 0); /* see comment above */
+ images = choose_cube_face(tObj, texcoord[i], newCoord);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel],
+ newCoord, rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_nearest(ctx, tObj, images[level ], newCoord, t0);
+ sample_2d_nearest(ctx, tObj, images[level+1], newCoord, t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_cube_linear_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ level = MAX2(level - 1, 0); /* see comment above */
+ images = choose_cube_face(tObj, texcoord[i], newCoord);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel],
+ newCoord, rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4];
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_linear(ctx, tObj, images[level ], newCoord, t0);
+ sample_2d_linear(ctx, tObj, images[level+1], newCoord, t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+/** Sample cube texture, using lambda to choose between min/magnification */
+static void
+sample_lambda_cube(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ const GLuint m = minEnd - minStart;
+ switch (tObj->Sampler.MinFilter) {
+ case GL_NEAREST:
+ sample_nearest_cube(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR:
+ sample_linear_cube(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_cube_nearest_mipmap_nearest(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_cube_linear_mipmap_nearest(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_cube_nearest_mipmap_linear(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_cube_linear_mipmap_linear(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_lambda_cube");
+ }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ const GLuint m = magEnd - magStart;
+ switch (tObj->Sampler.MagFilter) {
+ case GL_NEAREST:
+ sample_nearest_cube(ctx, tObj, m, texcoords + magStart,
+ lambda + magStart, rgba + magStart);
+ break;
+ case GL_LINEAR:
+ sample_linear_cube(ctx, tObj, m, texcoords + magStart,
+ lambda + magStart, rgba + magStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube");
+ }
+ }
+}
+
+
+/**********************************************************************/
+/* Texture Rectangle Sampling Functions */
+/**********************************************************************/
+
+
+static void
+sample_nearest_rect(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ const struct gl_texture_image *img = tObj->Image[0][0];
+ const GLint width = img->Width;
+ const GLint height = img->Height;
+ GLuint i;
+
+ (void) ctx;
+ (void) lambda;
+
+ ASSERT(tObj->Sampler.WrapS == GL_CLAMP ||
+ tObj->Sampler.WrapS == GL_CLAMP_TO_EDGE ||
+ tObj->Sampler.WrapS == GL_CLAMP_TO_BORDER);
+ ASSERT(tObj->Sampler.WrapT == GL_CLAMP ||
+ tObj->Sampler.WrapT == GL_CLAMP_TO_EDGE ||
+ tObj->Sampler.WrapT == GL_CLAMP_TO_BORDER);
+
+ for (i = 0; i < n; i++) {
+ GLint row, col;
+ col = clamp_rect_coord_nearest(tObj->Sampler.WrapS, texcoords[i][0], width);
+ row = clamp_rect_coord_nearest(tObj->Sampler.WrapT, texcoords[i][1], height);
+ if (col < 0 || col >= width || row < 0 || row >= height)
+ get_border_color(tObj, img, rgba[i]);
+ else
+ img->FetchTexelf(img, col, row, 0, rgba[i]);
+ }
+}
+
+
+static void
+sample_linear_rect(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ const struct gl_texture_image *img = tObj->Image[0][0];
+ const GLint width = img->Width;
+ const GLint height = img->Height;
+ GLuint i;
+
+ (void) ctx;
+ (void) lambda;
+
+ ASSERT(tObj->Sampler.WrapS == GL_CLAMP ||
+ tObj->Sampler.WrapS == GL_CLAMP_TO_EDGE ||
+ tObj->Sampler.WrapS == GL_CLAMP_TO_BORDER);
+ ASSERT(tObj->Sampler.WrapT == GL_CLAMP ||
+ tObj->Sampler.WrapT == GL_CLAMP_TO_EDGE ||
+ tObj->Sampler.WrapT == GL_CLAMP_TO_BORDER);
+
+ for (i = 0; i < n; i++) {
+ GLint i0, j0, i1, j1;
+ GLfloat t00[4], t01[4], t10[4], t11[4];
+ GLfloat a, b;
+ GLbitfield useBorderColor = 0x0;
+
+ clamp_rect_coord_linear(tObj->Sampler.WrapS, texcoords[i][0], width,
+ &i0, &i1, &a);
+ clamp_rect_coord_linear(tObj->Sampler.WrapT, texcoords[i][1], height,
+ &j0, &j1, &b);
+
+ /* compute integer rows/columns */
+ if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
+ if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
+ if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
+
+ /* get four texel samples */
+ if (useBorderColor & (I0BIT | J0BIT))
+ get_border_color(tObj, img, t00);
+ else
+ img->FetchTexelf(img, i0, j0, 0, t00);
+
+ if (useBorderColor & (I1BIT | J0BIT))
+ get_border_color(tObj, img, t10);
+ else
+ img->FetchTexelf(img, i1, j0, 0, t10);
+
+ if (useBorderColor & (I0BIT | J1BIT))
+ get_border_color(tObj, img, t01);
+ else
+ img->FetchTexelf(img, i0, j1, 0, t01);
+
+ if (useBorderColor & (I1BIT | J1BIT))
+ get_border_color(tObj, img, t11);
+ else
+ img->FetchTexelf(img, i1, j1, 0, t11);
+
+ lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11);
+ }
+}
+
+
+/** Sample Rect texture, using lambda to choose between min/magnification */
+static void
+sample_lambda_rect(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint minStart, minEnd, magStart, magEnd;
+
+ /* We only need lambda to decide between minification and magnification.
+ * There is no mipmapping with rectangular textures.
+ */
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ if (tObj->Sampler.MinFilter == GL_NEAREST) {
+ sample_nearest_rect(ctx, tObj, minEnd - minStart,
+ texcoords + minStart, NULL, rgba + minStart);
+ }
+ else {
+ sample_linear_rect(ctx, tObj, minEnd - minStart,
+ texcoords + minStart, NULL, rgba + minStart);
+ }
+ }
+ if (magStart < magEnd) {
+ if (tObj->Sampler.MagFilter == GL_NEAREST) {
+ sample_nearest_rect(ctx, tObj, magEnd - magStart,
+ texcoords + magStart, NULL, rgba + magStart);
+ }
+ else {
+ sample_linear_rect(ctx, tObj, magEnd - magStart,
+ texcoords + magStart, NULL, rgba + magStart);
+ }
+ }
+}
+
+
+/**********************************************************************/
+/* 2D Texture Array Sampling Functions */
+/**********************************************************************/
+
+/**
+ * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
+ */
+static void
+sample_2d_array_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[4])
+{
+ const GLint width = img->Width2; /* without border, power of two */
+ const GLint height = img->Height2; /* without border, power of two */
+ const GLint depth = img->Depth;
+ GLint i, j;
+ GLint array;
+ (void) ctx;
+
+ i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
+ j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]);
+ array = tex_array_slice(texcoord[2], depth);
+
+ if (i < 0 || i >= (GLint) img->Width ||
+ j < 0 || j >= (GLint) img->Height ||
+ array < 0 || array >= (GLint) img->Depth) {
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ get_border_color(tObj, img, rgba);
+ }
+ else {
+ img->FetchTexelf(img, i, j, array, rgba);
+ }
+}
+
+
+/**
+ * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
+ */
+static void
+sample_2d_array_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[4])
+{
+ const GLint width = img->Width2;
+ const GLint height = img->Height2;
+ const GLint depth = img->Depth;
+ GLint i0, j0, i1, j1;
+ GLint array;
+ GLbitfield useBorderColor = 0x0;
+ GLfloat a, b;
+ GLfloat t00[4], t01[4], t10[4], t11[4];
+
+ linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
+ linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b);
+ array = tex_array_slice(texcoord[2], depth);
+
+ if (array < 0 || array >= depth) {
+ COPY_4V(rgba, tObj->Sampler.BorderColor.f);
+ }
+ else {
+ if (img->Border) {
+ i0 += img->Border;
+ i1 += img->Border;
+ j0 += img->Border;
+ j1 += img->Border;
+ }
+ else {
+ /* check if sampling texture border color */
+ if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
+ if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
+ if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
+ }
+
+ /* Fetch texels */
+ if (useBorderColor & (I0BIT | J0BIT)) {
+ get_border_color(tObj, img, t00);
+ }
+ else {
+ img->FetchTexelf(img, i0, j0, array, t00);
+ }
+ if (useBorderColor & (I1BIT | J0BIT)) {
+ get_border_color(tObj, img, t10);
+ }
+ else {
+ img->FetchTexelf(img, i1, j0, array, t10);
+ }
+ if (useBorderColor & (I0BIT | J1BIT)) {
+ get_border_color(tObj, img, t01);
+ }
+ else {
+ img->FetchTexelf(img, i0, j1, array, t01);
+ }
+ if (useBorderColor & (I1BIT | J1BIT)) {
+ get_border_color(tObj, img, t11);
+ }
+ else {
+ img->FetchTexelf(img, i1, j1, array, t11);
+ }
+
+ /* trilinear interpolation of samples */
+ lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
+ }
+}
+
+
+static void
+sample_2d_array_nearest_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i],
+ rgba[i]);
+ }
+}
+
+
+static void
+sample_2d_array_linear_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][level],
+ texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_2d_array_nearest_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ],
+ texcoord[i], t0);
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level+1],
+ texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_2d_array_linear_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ],
+ texcoord[i], t0);
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][level+1],
+ texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+/** Sample 2D Array texture, nearest filtering for both min/magnification */
+static void
+sample_nearest_2d_array(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_2d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+
+/** Sample 2D Array texture, linear filtering for both min/magnification */
+static void
+sample_linear_2d_array(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_2d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/** Sample 2D Array texture, using lambda to choose between min/magnification */
+static void
+sample_lambda_2d_array(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+ GLuint i;
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ GLuint m = minEnd - minStart;
+ switch (tObj->Sampler.MinFilter) {
+ case GL_NEAREST:
+ for (i = minStart; i < minEnd; i++)
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = minStart; i < minEnd; i++)
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_2d_array_nearest_mipmap_nearest(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_2d_array_linear_mipmap_nearest(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_2d_array_nearest_mipmap_linear(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_2d_array_linear_mipmap_linear(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_2d_array_texture");
+ return;
+ }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ switch (tObj->Sampler.MagFilter) {
+ case GL_NEAREST:
+ for (i = magStart; i < magEnd; i++)
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = magStart; i < magEnd; i++)
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_2d_array_texture");
+ return;
+ }
+ }
+}
+
+
+
+
+/**********************************************************************/
+/* 1D Texture Array Sampling Functions */
+/**********************************************************************/
+
+/**
+ * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
+ */
+static void
+sample_1d_array_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[4])
+{
+ const GLint width = img->Width2; /* without border, power of two */
+ const GLint height = img->Height;
+ GLint i;
+ GLint array;
+ (void) ctx;
+
+ i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]);
+ array = tex_array_slice(texcoord[1], height);
+
+ if (i < 0 || i >= (GLint) img->Width ||
+ array < 0 || array >= (GLint) img->Height) {
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ get_border_color(tObj, img, rgba);
+ }
+ else {
+ img->FetchTexelf(img, i, array, 0, rgba);
+ }
+}
+
+
+/**
+ * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
+ */
+static void
+sample_1d_array_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLfloat rgba[4])
+{
+ const GLint width = img->Width2;
+ const GLint height = img->Height;
+ GLint i0, i1;
+ GLint array;
+ GLbitfield useBorderColor = 0x0;
+ GLfloat a;
+ GLfloat t0[4], t1[4];
+
+ linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a);
+ array = tex_array_slice(texcoord[1], height);
+
+ if (img->Border) {
+ i0 += img->Border;
+ i1 += img->Border;
+ }
+ else {
+ /* check if sampling texture border color */
+ if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
+ }
+
+ if (array < 0 || array >= height) useBorderColor |= K0BIT;
+
+ /* Fetch texels */
+ if (useBorderColor & (I0BIT | K0BIT)) {
+ get_border_color(tObj, img, t0);
+ }
+ else {
+ img->FetchTexelf(img, i0, array, 0, t0);
+ }
+ if (useBorderColor & (I1BIT | K0BIT)) {
+ get_border_color(tObj, img, t1);
+ }
+ else {
+ img->FetchTexelf(img, i1, array, 0, t1);
+ }
+
+ /* bilinear interpolation of samples */
+ lerp_rgba(rgba, a, t0, t1);
+}
+
+
+static void
+sample_1d_array_nearest_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i],
+ rgba[i]);
+ }
+}
+
+
+static void
+sample_1d_array_linear_mipmap_nearest(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][level],
+ texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_1d_array_nearest_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_1d_array_linear_mipmap_linear(struct gl_context *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLfloat t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+/** Sample 1D Array texture, nearest filtering for both min/magnification */
+static void
+sample_nearest_1d_array(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_1d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/** Sample 1D Array texture, linear filtering for both min/magnification */
+static void
+sample_linear_1d_array(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLfloat rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ sample_1d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/** Sample 1D Array texture, using lambda to choose between min/magnification */
+static void
+sample_lambda_1d_array(struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+ GLuint i;
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ GLuint m = minEnd - minStart;
+ switch (tObj->Sampler.MinFilter) {
+ case GL_NEAREST:
+ for (i = minStart; i < minEnd; i++)
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = minStart; i < minEnd; i++)
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_1d_array_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_1d_array_linear_mipmap_nearest(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_1d_array_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_1d_array_linear_mipmap_linear(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_1d_array_texture");
+ return;
+ }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ switch (tObj->Sampler.MagFilter) {
+ case GL_NEAREST:
+ for (i = magStart; i < magEnd; i++)
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = magStart; i < magEnd; i++)
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_1d_array_texture");
+ return;
+ }
+ }
+}
+
+
+/**
+ * Compare texcoord against depth sample. Return 1.0 or the ambient value.
+ */
+static INLINE GLfloat
+shadow_compare(GLenum function, GLfloat coord, GLfloat depthSample,
+ GLfloat ambient)
+{
+ switch (function) {
+ case GL_LEQUAL:
+ return (coord <= depthSample) ? 1.0F : ambient;
+ case GL_GEQUAL:
+ return (coord >= depthSample) ? 1.0F : ambient;
+ case GL_LESS:
+ return (coord < depthSample) ? 1.0F : ambient;
+ case GL_GREATER:
+ return (coord > depthSample) ? 1.0F : ambient;
+ case GL_EQUAL:
+ return (coord == depthSample) ? 1.0F : ambient;
+ case GL_NOTEQUAL:
+ return (coord != depthSample) ? 1.0F : ambient;
+ case GL_ALWAYS:
+ return 1.0F;
+ case GL_NEVER:
+ return ambient;
+ case GL_NONE:
+ return depthSample;
+ default:
+ _mesa_problem(NULL, "Bad compare func in shadow_compare");
+ return ambient;
+ }
+}
+
+
+/**
+ * Compare texcoord against four depth samples.
+ */
+static INLINE GLfloat
+shadow_compare4(GLenum function, GLfloat coord,
+ GLfloat depth00, GLfloat depth01,
+ GLfloat depth10, GLfloat depth11,
+ GLfloat ambient, GLfloat wi, GLfloat wj)
+{
+ const GLfloat d = (1.0F - (GLfloat) ambient) * 0.25F;
+ GLfloat luminance = 1.0F;
+
+ switch (function) {
+ case GL_LEQUAL:
+ if (coord > depth00) luminance -= d;
+ if (coord > depth01) luminance -= d;
+ if (coord > depth10) luminance -= d;
+ if (coord > depth11) luminance -= d;
+ return luminance;
+ case GL_GEQUAL:
+ if (coord < depth00) luminance -= d;
+ if (coord < depth01) luminance -= d;
+ if (coord < depth10) luminance -= d;
+ if (coord < depth11) luminance -= d;
+ return luminance;
+ case GL_LESS:
+ if (coord >= depth00) luminance -= d;
+ if (coord >= depth01) luminance -= d;
+ if (coord >= depth10) luminance -= d;
+ if (coord >= depth11) luminance -= d;
+ return luminance;
+ case GL_GREATER:
+ if (coord <= depth00) luminance -= d;
+ if (coord <= depth01) luminance -= d;
+ if (coord <= depth10) luminance -= d;
+ if (coord <= depth11) luminance -= d;
+ return luminance;
+ case GL_EQUAL:
+ if (coord != depth00) luminance -= d;
+ if (coord != depth01) luminance -= d;
+ if (coord != depth10) luminance -= d;
+ if (coord != depth11) luminance -= d;
+ return luminance;
+ case GL_NOTEQUAL:
+ if (coord == depth00) luminance -= d;
+ if (coord == depth01) luminance -= d;
+ if (coord == depth10) luminance -= d;
+ if (coord == depth11) luminance -= d;
+ return luminance;
+ case GL_ALWAYS:
+ return 1.0F;
+ case GL_NEVER:
+ return ambient;
+ case GL_NONE:
+ /* ordinary bilinear filtering */
+ return lerp_2d(wi, wj, depth00, depth10, depth01, depth11);
+ default:
+ _mesa_problem(NULL, "Bad compare func in sample_compare4");
+ return ambient;
+ }
+}
+
+
+/**
+ * Choose the mipmap level to use when sampling from a depth texture.
+ */
+static int
+choose_depth_texture_level(const struct gl_texture_object *tObj, GLfloat lambda)
+{
+ GLint level;
+
+ if (tObj->Sampler.MinFilter == GL_NEAREST || tObj->Sampler.MinFilter == GL_LINEAR) {
+ /* no mipmapping - use base level */
+ level = tObj->BaseLevel;
+ }
+ else {
+ /* choose mipmap level */
+ lambda = CLAMP(lambda, tObj->Sampler.MinLod, tObj->Sampler.MaxLod);
+ level = (GLint) lambda;
+ level = CLAMP(level, tObj->BaseLevel, tObj->_MaxLevel);
+ }
+
+ return level;
+}
+
+
+/**
+ * Sample a shadow/depth texture. This function is incomplete. It doesn't
+ * check for minification vs. magnification, etc.
+ */
+static void
+sample_depth_texture( struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat texel[][4] )
+{
+ const GLint level = choose_depth_texture_level(tObj, lambda[0]);
+ const struct gl_texture_image *img = tObj->Image[0][level];
+ const GLint width = img->Width;
+ const GLint height = img->Height;
+ const GLint depth = img->Depth;
+ const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT)
+ ? 3 : 2;
+ GLfloat ambient;
+ GLenum function;
+ GLfloat result;
+
+ ASSERT(img->_BaseFormat == GL_DEPTH_COMPONENT ||
+ img->_BaseFormat == GL_DEPTH_STENCIL_EXT);
+
+ ASSERT(tObj->Target == GL_TEXTURE_1D ||
+ tObj->Target == GL_TEXTURE_2D ||
+ tObj->Target == GL_TEXTURE_RECTANGLE_NV ||
+ tObj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
+ tObj->Target == GL_TEXTURE_2D_ARRAY_EXT);
+
+ ambient = tObj->Sampler.CompareFailValue;
+
+ /* XXXX if tObj->Sampler.MinFilter != tObj->Sampler.MagFilter, we're ignoring lambda */
+
+ function = (tObj->Sampler.CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) ?
+ tObj->Sampler.CompareFunc : GL_NONE;
+
+ if (tObj->Sampler.MagFilter == GL_NEAREST) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLfloat depthSample, depthRef;
+ GLint col, row, slice;
+
+ nearest_texcoord(tObj, level, texcoords[i], &col, &row, &slice);
+
+ if (col >= 0 && row >= 0 && col < width && row < height &&
+ slice >= 0 && slice < depth) {
+ img->FetchTexelf(img, col, row, slice, &depthSample);
+ }
+ else {
+ depthSample = tObj->Sampler.BorderColor.f[0];
+ }
+
+ depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F);
+
+ result = shadow_compare(function, depthRef, depthSample, ambient);
+
+ switch (tObj->Sampler.DepthMode) {
+ case GL_LUMINANCE:
+ ASSIGN_4V(texel[i], result, result, result, 1.0F);
+ break;
+ case GL_INTENSITY:
+ ASSIGN_4V(texel[i], result, result, result, result);
+ break;
+ case GL_ALPHA:
+ ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result);
+ break;
+ case GL_RED:
+ ASSIGN_4V(texel[i], result, 0.0F, 0.0F, 1.0F);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad depth texture mode");
+ }
+ }
+ }
+ else {
+ GLuint i;
+ ASSERT(tObj->Sampler.MagFilter == GL_LINEAR);
+ for (i = 0; i < n; i++) {
+ GLfloat depth00, depth01, depth10, depth11, depthRef;
+ GLint i0, i1, j0, j1;
+ GLint slice;
+ GLfloat wi, wj;
+ GLuint useBorderTexel;
+
+ linear_texcoord(tObj, level, texcoords[i], &i0, &i1, &j0, &j1, &slice,
+ &wi, &wj);
+
+ useBorderTexel = 0;
+ if (img->Border) {
+ i0 += img->Border;
+ i1 += img->Border;
+ if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
+ j0 += img->Border;
+ j1 += img->Border;
+ }
+ }
+ else {
+ if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT;
+ if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT;
+ if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT;
+ if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT;
+ }
+
+ if (slice < 0 || slice >= (GLint) depth) {
+ depth00 = tObj->Sampler.BorderColor.f[0];
+ depth01 = tObj->Sampler.BorderColor.f[0];
+ depth10 = tObj->Sampler.BorderColor.f[0];
+ depth11 = tObj->Sampler.BorderColor.f[0];
+ }
+ else {
+ /* get four depth samples from the texture */
+ if (useBorderTexel & (I0BIT | J0BIT)) {
+ depth00 = tObj->Sampler.BorderColor.f[0];
+ }
+ else {
+ img->FetchTexelf(img, i0, j0, slice, &depth00);
+ }
+ if (useBorderTexel & (I1BIT | J0BIT)) {
+ depth10 = tObj->Sampler.BorderColor.f[0];
+ }
+ else {
+ img->FetchTexelf(img, i1, j0, slice, &depth10);
+ }
+
+ if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
+ if (useBorderTexel & (I0BIT | J1BIT)) {
+ depth01 = tObj->Sampler.BorderColor.f[0];
+ }
+ else {
+ img->FetchTexelf(img, i0, j1, slice, &depth01);
+ }
+ if (useBorderTexel & (I1BIT | J1BIT)) {
+ depth11 = tObj->Sampler.BorderColor.f[0];
+ }
+ else {
+ img->FetchTexelf(img, i1, j1, slice, &depth11);
+ }
+ }
+ else {
+ depth01 = depth00;
+ depth11 = depth10;
+ }
+ }
+
+ depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F);
+
+ result = shadow_compare4(function, depthRef,
+ depth00, depth01, depth10, depth11,
+ ambient, wi, wj);
+
+ switch (tObj->Sampler.DepthMode) {
+ case GL_LUMINANCE:
+ ASSIGN_4V(texel[i], result, result, result, 1.0F);
+ break;
+ case GL_INTENSITY:
+ ASSIGN_4V(texel[i], result, result, result, result);
+ break;
+ case GL_ALPHA:
+ ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad depth texture mode");
+ }
+
+ } /* for */
+ } /* if filter */
+}
+
+
+/**
+ * We use this function when a texture object is in an "incomplete" state.
+ * When a fragment program attempts to sample an incomplete texture we
+ * return black (see issue 23 in GL_ARB_fragment_program spec).
+ * Note: fragment programs don't observe the texture enable/disable flags.
+ */
+static void
+null_sample_func( struct gl_context *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLfloat rgba[][4])
+{
+ GLuint i;
+ (void) ctx;
+ (void) tObj;
+ (void) texcoords;
+ (void) lambda;
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = 0;
+ rgba[i][GCOMP] = 0;
+ rgba[i][BCOMP] = 0;
+ rgba[i][ACOMP] = 1.0;
+ }
+}
+
+
+/**
+ * Choose the texture sampling function for the given texture object.
+ */
+texture_sample_func
+_swrast_choose_texture_sample_func( struct gl_context *ctx,
+ const struct gl_texture_object *t )
+{
+ if (!t || !t->_Complete) {
+ return &null_sample_func;
+ }
+ else {
+ const GLboolean needLambda =
+ (GLboolean) (t->Sampler.MinFilter != t->Sampler.MagFilter);
+ const GLenum format = t->Image[0][t->BaseLevel]->_BaseFormat;
+
+ switch (t->Target) {
+ case GL_TEXTURE_1D:
+ if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
+ return &sample_depth_texture;
+ }
+ else if (needLambda) {
+ return &sample_lambda_1d;
+ }
+ else if (t->Sampler.MinFilter == GL_LINEAR) {
+ return &sample_linear_1d;
+ }
+ else {
+ ASSERT(t->Sampler.MinFilter == GL_NEAREST);
+ return &sample_nearest_1d;
+ }
+ case GL_TEXTURE_2D:
+ if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
+ return &sample_depth_texture;
+ }
+ else if (needLambda) {
+ /* Anisotropic filtering extension. Activated only if mipmaps are used */
+ if (t->Sampler.MaxAnisotropy > 1.0 &&
+ t->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
+ return &sample_lambda_2d_aniso;
+ }
+ return &sample_lambda_2d;
+ }
+ else if (t->Sampler.MinFilter == GL_LINEAR) {
+ return &sample_linear_2d;
+ }
+ else {
+ /* check for a few optimized cases */
+ const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
+ ASSERT(t->Sampler.MinFilter == GL_NEAREST);
+ if (t->Sampler.WrapS == GL_REPEAT &&
+ t->Sampler.WrapT == GL_REPEAT &&
+ img->_IsPowerOfTwo &&
+ img->Border == 0 &&
+ img->TexFormat == MESA_FORMAT_RGB888) {
+ return &opt_sample_rgb_2d;
+ }
+ else if (t->Sampler.WrapS == GL_REPEAT &&
+ t->Sampler.WrapT == GL_REPEAT &&
+ img->_IsPowerOfTwo &&
+ img->Border == 0 &&
+ img->TexFormat == MESA_FORMAT_RGBA8888) {
+ return &opt_sample_rgba_2d;
+ }
+ else {
+ return &sample_nearest_2d;
+ }
+ }
+ case GL_TEXTURE_3D:
+ if (needLambda) {
+ return &sample_lambda_3d;
+ }
+ else if (t->Sampler.MinFilter == GL_LINEAR) {
+ return &sample_linear_3d;
+ }
+ else {
+ ASSERT(t->Sampler.MinFilter == GL_NEAREST);
+ return &sample_nearest_3d;
+ }
+ case GL_TEXTURE_CUBE_MAP:
+ if (needLambda) {
+ return &sample_lambda_cube;
+ }
+ else if (t->Sampler.MinFilter == GL_LINEAR) {
+ return &sample_linear_cube;
+ }
+ else {
+ ASSERT(t->Sampler.MinFilter == GL_NEAREST);
+ return &sample_nearest_cube;
+ }
+ case GL_TEXTURE_RECTANGLE_NV:
+ if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
+ return &sample_depth_texture;
+ }
+ else if (needLambda) {
+ return &sample_lambda_rect;
+ }
+ else if (t->Sampler.MinFilter == GL_LINEAR) {
+ return &sample_linear_rect;
+ }
+ else {
+ ASSERT(t->Sampler.MinFilter == GL_NEAREST);
+ return &sample_nearest_rect;
+ }
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ if (needLambda) {
+ return &sample_lambda_1d_array;
+ }
+ else if (t->Sampler.MinFilter == GL_LINEAR) {
+ return &sample_linear_1d_array;
+ }
+ else {
+ ASSERT(t->Sampler.MinFilter == GL_NEAREST);
+ return &sample_nearest_1d_array;
+ }
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ if (needLambda) {
+ return &sample_lambda_2d_array;
+ }
+ else if (t->Sampler.MinFilter == GL_LINEAR) {
+ return &sample_linear_2d_array;
+ }
+ else {
+ ASSERT(t->Sampler.MinFilter == GL_NEAREST);
+ return &sample_nearest_2d_array;
+ }
+ default:
+ _mesa_problem(ctx,
+ "invalid target in _swrast_choose_texture_sample_func");
+ return &null_sample_func;
+ }
+ }
+}
diff --git a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
index d6448dfb6..65717eb45 100644
--- a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
+++ b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
@@ -59,12 +59,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define MAT_ATTR( A, N, V ) ATTR( A, N, (V)[0], (V)[1], (V)[2], (V)[3] )
-static inline float conv_ui10_to_norm_float(unsigned ui10)
+static INLINE float conv_ui10_to_norm_float(unsigned ui10)
{
return (float)(ui10) / 1023.0;
}
-static inline float conv_ui2_to_norm_float(unsigned ui2)
+static INLINE float conv_ui2_to_norm_float(unsigned ui2)
{
return (float)(ui2) / 3.0;
}
@@ -91,28 +91,28 @@ static inline float conv_ui2_to_norm_float(unsigned ui2)
struct attr_bits_10 {signed int x:10;};
struct attr_bits_2 {signed int x:2;};
-static inline float conv_i10_to_i(int i10)
+static INLINE float conv_i10_to_i(int i10)
{
struct attr_bits_10 val;
val.x = i10;
return (float)val.x;
}
-static inline float conv_i2_to_i(int i2)
+static INLINE float conv_i2_to_i(int i2)
{
struct attr_bits_2 val;
val.x = i2;
return (float)val.x;
}
-static inline float conv_i10_to_norm_float(int i10)
+static INLINE float conv_i10_to_norm_float(int i10)
{
struct attr_bits_10 val;
val.x = i10;
return (2.0F * (float)val.x + 1.0F) * (1.0F / 511.0F);
}
-static inline float conv_i2_to_norm_float(int i2)
+static INLINE float conv_i2_to_norm_float(int i2)
{
struct attr_bits_2 val;
val.x = i2;