aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c2410
-rw-r--r--mesalib/src/mesa/main/accum.c245
-rw-r--r--mesalib/src/mesa/main/debug.c3
-rw-r--r--mesalib/src/mesa/main/extensions.c1849
-rw-r--r--mesalib/src/mesa/main/fbobject.c4795
-rw-r--r--mesalib/src/mesa/main/mtypes.h6731
-rw-r--r--mesalib/src/mesa/main/texparam.c2883
7 files changed, 9465 insertions, 9451 deletions
diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c
index 0a508355c..171585dcf 100644
--- a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c
+++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c
@@ -1,1206 +1,1204 @@
-/****************************************************************************
-*
-* Mesa 3-D graphics library
-* Direct3D Driver Interface
-*
-* ========================================================================
-*
-* Copyright (C) 1991-2004 SciTech Software, 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
-* SCITECH SOFTWARE INC 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.
-*
-* ======================================================================
-*
-* Language: ANSI C
-* Environment: Windows 9x/2000/XP/XBox (Win32)
-*
-* Description: Driver interface code to Mesa
-*
-****************************************************************************/
-
-//#include <windows.h>
-#include "dglcontext.h"
-#include "ddlog.h"
-#include "gld_dx9.h"
-
-#include "glheader.h"
-#include "context.h"
-#include "colormac.h"
-#include "depth.h"
-#include "extensions.h"
-#include "macros.h"
-#include "matrix.h"
-// #include "mem.h"
-//#include "mmath.h"
-#include "mtypes.h"
-#include "texformat.h"
-#include "teximage.h"
-#include "texstore.h"
-#include "vbo/vbo.h"
-#include "swrast_setup/swrast_setup.h"
-#include "swrast_setup/ss_context.h"
-#include "tnl/tnl.h"
-#include "tnl/t_context.h"
-#include "tnl/t_pipeline.h"
-
-extern BOOL dglSwapBuffers(HDC hDC);
-
-// HACK: Hack the _33 member of the OpenGL perspective projection matrix
-const float _fPersp_33 = 1.6f;
-
-//---------------------------------------------------------------------------
-// Internal functions
-//---------------------------------------------------------------------------
-
-void _gld_mesa_warning(
- __struct gl_context *gc,
- char *str)
-{
- // Intercept Mesa's internal warning mechanism
- gldLogPrintf(GLDLOG_WARN, "Mesa warning: %s", str);
-}
-
-//---------------------------------------------------------------------------
-
-void _gld_mesa_fatal(
- __struct gl_context *gc,
- char *str)
-{
- // Intercept Mesa's internal fatal-message mechanism
- gldLogPrintf(GLDLOG_CRITICAL, "Mesa FATAL: %s", str);
-
- // Mesa calls abort(0) here.
- ddlogClose();
- exit(0);
-}
-
-//---------------------------------------------------------------------------
-
-D3DSTENCILOP _gldConvertStencilOp(
- GLenum StencilOp)
-{
- // Used by Stencil: pass, fail and zfail
-
- switch (StencilOp) {
- case GL_KEEP:
- return D3DSTENCILOP_KEEP;
- case GL_ZERO:
- return D3DSTENCILOP_ZERO;
- case GL_REPLACE:
- return D3DSTENCILOP_REPLACE;
- case GL_INCR:
- return D3DSTENCILOP_INCRSAT;
- case GL_DECR:
- return D3DSTENCILOP_DECRSAT;
- case GL_INVERT:
- return D3DSTENCILOP_INVERT;
- case GL_INCR_WRAP_EXT: // GL_EXT_stencil_wrap
- return D3DSTENCILOP_INCR;
- case GL_DECR_WRAP_EXT: // GL_EXT_stencil_wrap
- return D3DSTENCILOP_DECR;
- }
-
-#ifdef _DEBUG
- gldLogMessage(GLDLOG_ERROR, "_gldConvertStencilOp: Unknown StencilOp\n");
-#endif
-
- return D3DSTENCILOP_KEEP;
-}
-
-//---------------------------------------------------------------------------
-
-D3DCMPFUNC _gldConvertCompareFunc(
- GLenum CmpFunc)
-{
- // Used for Alpha func, depth func and stencil func.
-
- switch (CmpFunc) {
- case GL_NEVER:
- return D3DCMP_NEVER;
- case GL_LESS:
- return D3DCMP_LESS;
- case GL_EQUAL:
- return D3DCMP_EQUAL;
- case GL_LEQUAL:
- return D3DCMP_LESSEQUAL;
- case GL_GREATER:
- return D3DCMP_GREATER;
- case GL_NOTEQUAL:
- return D3DCMP_NOTEQUAL;
- case GL_GEQUAL:
- return D3DCMP_GREATEREQUAL;
- case GL_ALWAYS:
- return D3DCMP_ALWAYS;
- };
-
-#ifdef _DEBUG
- gldLogMessage(GLDLOG_ERROR, "_gldConvertCompareFunc: Unknown CompareFunc\n");
-#endif
-
- return D3DCMP_ALWAYS;
-}
-
-//---------------------------------------------------------------------------
-
-D3DBLEND _gldConvertBlendFunc(
- GLenum blend,
- GLenum DefaultBlend)
-{
- switch (blend) {
- case GL_ZERO:
- return D3DBLEND_ZERO;
- case GL_ONE:
- return D3DBLEND_ONE;
- case GL_DST_COLOR:
- return D3DBLEND_DESTCOLOR;
- case GL_SRC_COLOR:
- return D3DBLEND_SRCCOLOR;
- case GL_ONE_MINUS_DST_COLOR:
- return D3DBLEND_INVDESTCOLOR;
- case GL_ONE_MINUS_SRC_COLOR:
- return D3DBLEND_INVSRCCOLOR;
- case GL_SRC_ALPHA:
- return D3DBLEND_SRCALPHA;
- case GL_ONE_MINUS_SRC_ALPHA:
- return D3DBLEND_INVSRCALPHA;
- case GL_DST_ALPHA:
- return D3DBLEND_DESTALPHA;
- case GL_ONE_MINUS_DST_ALPHA:
- return D3DBLEND_INVDESTALPHA;
- case GL_SRC_ALPHA_SATURATE:
- return D3DBLEND_SRCALPHASAT;
- }
-
-#ifdef _DEBUG
- gldLogMessage(GLDLOG_ERROR, "_gldConvertBlendFunc: Unknown BlendFunc\n");
-#endif
-
- return DefaultBlend;
-}
-
-//---------------------------------------------------------------------------
-// Misc. functions
-//---------------------------------------------------------------------------
-
-void gld_Noop_DX9(
- struct gl_context *ctx)
-{
-#ifdef _DEBUG
- gldLogMessage(GLDLOG_ERROR, "gld_Noop called!\n");
-#endif
-}
-
-//---------------------------------------------------------------------------
-
-void gld_Error_DX9(
- struct gl_context *ctx)
-{
-#ifdef _DEBUG
- // Quite useless.
-// gldLogMessage(GLDLOG_ERROR, "ctx->Driver.Error called!\n");
-#endif
-}
-
-//---------------------------------------------------------------------------
-// Required Mesa functions
-//---------------------------------------------------------------------------
-
-static GLboolean gld_set_draw_buffer_DX9(
- struct gl_context *ctx,
- GLenum mode)
-{
- (void) ctx;
- if ((mode==GL_FRONT_LEFT) || (mode == GL_BACK_LEFT)) {
- return GL_TRUE;
- }
- else {
- return GL_FALSE;
- }
-}
-
-//---------------------------------------------------------------------------
-
-static void gld_set_read_buffer_DX9(
- struct gl_context *ctx,
- struct gl_framebuffer *buffer,
- GLenum mode)
-{
- /* separate read buffer not supported */
-/*
- ASSERT(buffer == ctx->DrawBuffer);
- ASSERT(mode == GL_FRONT_LEFT);
-*/
-}
-
-//---------------------------------------------------------------------------
-
-void gld_Clear_DX9(
- struct gl_context *ctx,
- GLbitfield mask,
- GLboolean all,
- GLint x,
- GLint y,
- GLint width,
- GLint height)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- DWORD dwFlags = 0;
- D3DCOLOR Color = 0;
- float Z = 0.0f;
- DWORD Stencil = 0;
- D3DRECT d3dClearRect;
-
- // TODO: Colourmask
- const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0];
-
- if (!gld->pDev)
- return;
-
- if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
- GLubyte col[4];
- CLAMPED_FLOAT_TO_UBYTE(col[0], ctx->Color.ClearColor[0]);
- CLAMPED_FLOAT_TO_UBYTE(col[1], ctx->Color.ClearColor[1]);
- CLAMPED_FLOAT_TO_UBYTE(col[2], ctx->Color.ClearColor[2]);
- CLAMPED_FLOAT_TO_UBYTE(col[3], ctx->Color.ClearColor[3]);
- dwFlags |= D3DCLEAR_TARGET;
- Color = D3DCOLOR_RGBA(col[0], col[1], col[2], col[3]);
- }
-
- if (mask & DD_DEPTH_BIT) {
- // D3D8 will fail the Clear call if we try and clear a
- // depth buffer and we haven't created one.
- // Also, some apps try and clear a depth buffer,
- // when a depth buffer hasn't been requested by the app.
- if (ctx->Visual.depthBits == 0) {
- mask &= ~DD_DEPTH_BIT; // Remove depth bit from mask
- } else {
- dwFlags |= D3DCLEAR_ZBUFFER;
- Z = ctx->Depth.Clear;
- }
- }
-
- if (mask & DD_STENCIL_BIT) {
- if (ctx->Visual.stencilBits == 0) {
- // No stencil bits in depth buffer
- mask &= ~DD_STENCIL_BIT; // Remove stencil bit from mask
- } else {
- dwFlags |= D3DCLEAR_STENCIL;
- Stencil = ctx->Stencil.Clear;
- }
- }
-
- // Some apps do really weird things with the rect, such as Quake3.
- if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) {
- all = GL_TRUE;
- }
-
- if (!all) {
- // Calculate clear subrect
- d3dClearRect.x1 = x;
- d3dClearRect.y1 = gldCtx->dwHeight - (y + height);
- d3dClearRect.x2 = x + width;
- d3dClearRect.y2 = d3dClearRect.y1 + height;
-// gldLogPrintf(GLDLOG_INFO, "Rect %d,%d %d,%d", x,y,width,height);
- }
-
- // dwFlags will be zero if there's nothing to clear
- if (dwFlags) {
- _GLD_DX9_DEV(Clear(
- gld->pDev,
- all ? 0 : 1,
- all ? NULL : &d3dClearRect,
- dwFlags,
- Color, Z, Stencil));
- }
-
- if (mask & DD_ACCUM_BIT) {
- // Clear accumulation buffer
- }
-}
-
-//---------------------------------------------------------------------------
-
-// Mesa 5: Parameter change
-static void gld_buffer_size_DX9(
-// struct gl_context *ctx,
- struct gl_framebuffer *fb,
- GLuint *width,
- GLuint *height)
-{
-// GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
-
- *width = fb->Width; // gldCtx->dwWidth;
- *height = fb->Height; // gldCtx->dwHeight;
-}
-
-//---------------------------------------------------------------------------
-
-static void gld_Finish_DX9(
- struct gl_context *ctx)
-{
-}
-
-//---------------------------------------------------------------------------
-
-static void gld_Flush_DX9(
- struct gl_context *ctx)
-{
- GLD_context *gld = GLD_GET_CONTEXT(ctx);
-
- // TODO: Detect apps that glFlush() then SwapBuffers() ?
-
- if (gld->EmulateSingle) {
- // Emulating a single-buffered context.
- // [Direct3D doesn't allow rendering to front buffer]
- dglSwapBuffers(gld->hDC);
- }
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_STENCIL(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- // Two-sided stencil. New for Mesa 5
- const GLuint uiFace = 0UL;
-
- struct gl_stencil_attrib *pStencil = &ctx->Stencil;
-
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILENABLE, pStencil->Enabled ? TRUE : FALSE));
- if (pStencil->Enabled) {
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFUNC, _gldConvertCompareFunc(pStencil->Function[uiFace])));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILREF, pStencil->Ref[uiFace]));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILMASK, pStencil->ValueMask[uiFace]));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILWRITEMASK, pStencil->WriteMask[uiFace]));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFAIL, _gldConvertStencilOp(pStencil->FailFunc[uiFace])));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILZFAIL, _gldConvertStencilOp(pStencil->ZFailFunc[uiFace])));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILPASS, _gldConvertStencilOp(pStencil->ZPassFunc[uiFace])));
- }
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_COLOR(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- DWORD dwFlags = 0;
- D3DBLEND src;
- D3DBLEND dest;
-
- // Alpha func
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAFUNC, _gldConvertCompareFunc(ctx->Color.AlphaFunc)));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAREF, (DWORD)ctx->Color.AlphaRef));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHATESTENABLE, ctx->Color.AlphaEnabled));
-
- // Blend func
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHABLENDENABLE, ctx->Color.BlendEnabled));
- src = _gldConvertBlendFunc(ctx->Color.BlendSrcRGB, GL_ONE);
- dest = _gldConvertBlendFunc(ctx->Color.BlendDstRGB, GL_ZERO);
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SRCBLEND, src));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DESTBLEND, dest));
-
- // Color mask
- if (ctx->Color.ColorMask[0][0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
- if (ctx->Color.ColorMask[0][1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
- if (ctx->Color.ColorMask[0][2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
- if (ctx->Color.ColorMask[0][3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags));
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_DEPTH(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZENABLE, ctx->Depth.Test ? D3DZB_TRUE : D3DZB_FALSE));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZFUNC, _gldConvertCompareFunc(ctx->Depth.Func)));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZWRITEENABLE, ctx->Depth.Mask ? TRUE : FALSE));
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_POLYGON(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- D3DFILLMODE d3dFillMode = D3DFILL_SOLID;
- D3DCULL d3dCullMode = D3DCULL_NONE;
- float fOffset = 0; // Changed from int to float for DX9
-
- // Fillmode
- switch (ctx->Polygon.FrontMode) {
- case GL_POINT:
- d3dFillMode = D3DFILL_POINT;
- break;
- case GL_LINE:
- d3dFillMode = D3DFILL_WIREFRAME;
- break;
- case GL_FILL:
- d3dFillMode = D3DFILL_SOLID;
- break;
- }
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FILLMODE, d3dFillMode));
-
- if (ctx->Polygon.CullFlag) {
- switch (ctx->Polygon.CullFaceMode) {
- case GL_BACK:
- if (ctx->Polygon.FrontFace == GL_CCW)
- d3dCullMode = D3DCULL_CW;
- else
- d3dCullMode = D3DCULL_CCW;
- break;
- case GL_FRONT:
- if (ctx->Polygon.FrontFace == GL_CCW)
- d3dCullMode = D3DCULL_CCW;
- else
- d3dCullMode = D3DCULL_CW;
- break;
- case GL_FRONT_AND_BACK:
- d3dCullMode = D3DCULL_NONE;
- break;
- default:
- break;
- }
- } else {
- d3dCullMode = D3DCULL_NONE;
- }
-// d3dCullMode = D3DCULL_NONE; // FOR DEBUGGING
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CULLMODE, d3dCullMode));
-
- // Polygon offset
- // ZBIAS ranges from 0 to 16 and can only move towards the viewer
- // Mesa5: ctx->Polygon._OffsetAny removed
- if (ctx->Polygon.OffsetFill) {
- fOffset = ctx->Polygon.OffsetUnits;
-// if (iOffset < 0.0f)
-// iOffset = -iOffset;
-// else
-// iOffset = 0.0f; // D3D can't push away
- }
- // NOTE: SetRenderState() required a DWORD, so need to cast
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DEPTHBIAS, *((DWORD*)&fOffset)));
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_FOG(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- D3DCOLOR d3dFogColour;
- D3DFOGMODE d3dFogMode = D3DFOG_LINEAR;
-
- // TODO: Fog is calculated seperately in the Mesa pipeline
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, FALSE));
- return;
-
- // Fog enable
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, ctx->Fog.Enabled));
- if (!ctx->Fog.Enabled) {
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, D3DFOG_NONE));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE));
- return; // If disabled, don't bother setting any fog state
- }
-
- // Fog colour
- d3dFogColour = D3DCOLOR_COLORVALUE( ctx->Fog.Color[0],
- ctx->Fog.Color[1],
- ctx->Fog.Color[2],
- ctx->Fog.Color[3]);
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGCOLOR, d3dFogColour));
-
- // Fog density
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density))));
-
- // Fog start
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGSTART, *((DWORD*) (&ctx->Fog.Start))));
-
- // Fog end
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGEND, *((DWORD*) (&ctx->Fog.End))));
-
- // Fog mode
- switch (ctx->Fog.Mode) {
- case GL_LINEAR:
- d3dFogMode = D3DFOG_LINEAR;
- break;
- case GL_EXP:
- d3dFogMode = D3DFOG_EXP;
- break;
- case GL_EXP2:
- d3dFogMode = D3DFOG_EXP2;
- break;
- }
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, d3dFogMode));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE));
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_LIGHT(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
- DWORD dwSpecularEnable;
-
- // Shademode
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT));
-
- // Separate specular colour
- if (ctx->Light.Enabled)
- dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE;
- else
- dwSpecularEnable = FALSE;
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SPECULARENABLE, dwSpecularEnable));
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_MODELVIEW(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- D3DMATRIX m;
- //GLfloat *pM = ctx->ModelView.m;
- // Mesa5: Model-view is now a stack
- GLfloat *pM = ctx->ModelviewMatrixStack.Top->m;
- m._11 = pM[0];
- m._12 = pM[1];
- m._13 = pM[2];
- m._14 = pM[3];
- m._21 = pM[4];
- m._22 = pM[5];
- m._23 = pM[6];
- m._24 = pM[7];
- m._31 = pM[8];
- m._32 = pM[9];
- m._33 = pM[10];
- m._34 = pM[11];
- m._41 = pM[12];
- m._42 = pM[13];
- m._43 = pM[14];
- m._44 = pM[15];
-
- gld->matModelView = m;
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_PROJECTION(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- D3DMATRIX m;
- //GLfloat *pM = ctx->ProjectionMatrix.m;
- // Mesa 5: Now a stack
- GLfloat *pM = ctx->ProjectionMatrixStack.Top->m;
- m._11 = pM[0];
- m._12 = pM[1];
- m._13 = pM[2];
- m._14 = pM[3];
-
- m._21 = pM[4];
- m._22 = pM[5];
- m._23 = pM[6];
- m._24 = pM[7];
-
- m._31 = pM[8];
- m._32 = pM[9];
- m._33 = pM[10] / _fPersp_33; // / 1.6f;
- m._34 = pM[11];
-
- m._41 = pM[12];
- m._42 = pM[13];
- m._43 = pM[14] / 2.0f;
- m._44 = pM[15];
-
- gld->matProjection = m;
-}
-
-//---------------------------------------------------------------------------
-/*
-void gldFrustumHook_DX9(
- GLdouble left,
- GLdouble right,
- GLdouble bottom,
- GLdouble top,
- GLdouble nearval,
- GLdouble farval)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- // Pass values on to Mesa first (in case we mess with them)
- _mesa_Frustum(left, right, bottom, top, nearval, farval);
-
- _fPersp_33 = farval / (nearval - farval);
-
-// ddlogPrintf(GLDLOG_SYSTEM, "Frustum: %f", farval/nearval);
-}
-
-//---------------------------------------------------------------------------
-
-void gldOrthoHook_DX9(
- GLdouble left,
- GLdouble right,
- GLdouble bottom,
- GLdouble top,
- GLdouble nearval,
- GLdouble farval)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- // Pass values on to Mesa first (in case we mess with them)
- _mesa_Ortho(left, right, bottom, top, nearval, farval);
-
- _fPersp_33 = 1.6f;
-
-// ddlogPrintf(GLDLOG_SYSTEM, "Ortho: %f", farval/nearval);
-}
-*/
-//---------------------------------------------------------------------------
-
-void gld_NEW_VIEWPORT(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- D3DVIEWPORT9 d3dvp;
-// GLint x, y;
-// GLsizei w, h;
-
- // Set depth range
- _GLD_DX9_DEV(GetViewport(gld->pDev, &d3dvp));
- // D3D can't do Quake1/Quake2 z-trick
- if (ctx->Viewport.Near <= ctx->Viewport.Far) {
- d3dvp.MinZ = ctx->Viewport.Near;
- d3dvp.MaxZ = ctx->Viewport.Far;
- } else {
- d3dvp.MinZ = ctx->Viewport.Far;
- d3dvp.MaxZ = ctx->Viewport.Near;
- }
-/* x = ctx->Viewport.X;
- y = ctx->Viewport.Y;
- w = ctx->Viewport.Width;
- h = ctx->Viewport.Height;
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (w > gldCtx->dwWidth) w = gldCtx->dwWidth;
- if (h > gldCtx->dwHeight) h = gldCtx->dwHeight;
- // Ditto for D3D viewport dimensions
- if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x;
- if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y;
- d3dvp.X = x;
- d3dvp.Y = gldCtx->dwHeight - (y + h);
- d3dvp.Width = w;
- d3dvp.Height = h;*/
- _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp));
-
-// gld->fFlipWindowY = (float)gldCtx->dwHeight;
-}
-
-//---------------------------------------------------------------------------
-
-void gld_NEW_SCISSOR(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- // Bail if IHV driver cannot scissor
- if (!gld->bCanScissor)
- return;
-
- // Set scissor rect
- if (ctx->Scissor.Enabled) {
- RECT rcRect;
- // Keep in mind that RECT's need an extra row and column
- rcRect.left = ctx->Scissor.X;
- rcRect.right = ctx->Scissor.X + ctx->Scissor.Width; // + 1;
- rcRect.top = gldCtx->dwHeight - (ctx->Scissor.Y + ctx->Scissor.Height);
- rcRect.bottom = rcRect.top + ctx->Scissor.Height;
- IDirect3DDevice9_SetScissorRect(gld->pDev, &rcRect);
- }
-
- // Enable/disable scissor as required
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SCISSORTESTENABLE, ctx->Scissor.Enabled));
-}
-
-//---------------------------------------------------------------------------
-
-__inline BOOL _gldAnyEvalEnabled(
- struct gl_context *ctx)
-{
- struct gl_eval_attrib *eval = &ctx->Eval;
-
- if ((eval->AutoNormal) ||
- (eval->Map1Color4) ||
- (eval->Map1Index) ||
- (eval->Map1Normal) ||
- (eval->Map1TextureCoord1) ||
- (eval->Map1TextureCoord2) ||
- (eval->Map1TextureCoord3) ||
- (eval->Map1TextureCoord4) ||
- (eval->Map1Vertex3) ||
- (eval->Map1Vertex4) ||
- (eval->Map2Color4) ||
- (eval->Map2Index) ||
- (eval->Map2Normal) ||
- (eval->Map2TextureCoord1) ||
- (eval->Map2TextureCoord2) ||
- (eval->Map2TextureCoord3) ||
- (eval->Map2TextureCoord4) ||
- (eval->Map2Vertex3) ||
- (eval->Map2Vertex4)
- )
- return TRUE;
-
- return FALSE;
-}
-
-//---------------------------------------------------------------------------
-
-BOOL _gldChooseInternalPipeline(
- struct gl_context *ctx,
- GLD_driver_dx9 *gld)
-{
-// return TRUE; // DEBUGGING: ALWAYS USE MESA
-// return FALSE; // DEBUGGING: ALWAYS USE D3D
-
- if ((glb.dwTnL == GLDS_TNL_MESA) || (gld->bHasHWTnL == FALSE))
- {
- gld->PipelineUsage.qwMesa.QuadPart++;
- return TRUE; // Force Mesa TnL
- }
-
- if ((ctx->Light.Enabled) ||
- (1) ||
- (ctx->Texture._TexGenEnabled) ||
- (ctx->Texture._TexMatEnabled) ||
-// (ctx->Transform._AnyClip) ||
- (ctx->Scissor.Enabled) ||
- _gldAnyEvalEnabled(ctx) // Put this last so we can early-out
- )
- {
- gld->PipelineUsage.qwMesa.QuadPart++;
- return TRUE;
- }
-
- gld->PipelineUsage.qwD3DFVF.QuadPart++;
- return FALSE;
-
-/* // Force Mesa pipeline?
- if (glb.dwTnL == GLDS_TNL_MESA) {
- gld->PipelineUsage.dwMesa.QuadPart++;
- return GLD_PIPELINE_MESA;
- }
-
- // Test for functionality not exposed in the D3D pathways
- if ((ctx->Texture._GenFlags)) {
- gld->PipelineUsage.dwMesa.QuadPart++;
- return GLD_PIPELINE_MESA;
- }
-
- // Now decide if vertex shader can be used.
- // If two sided lighting is enabled then we must either
- // use Mesa TnL or the vertex shader
- if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
- if (gld->VStwosidelight.hShader && !ctx->Fog.Enabled) {
- // Use Vertex Shader
- gld->PipelineUsage.dwD3D2SVS.QuadPart++;
- return GLD_PIPELINE_D3D_VS_TWOSIDE;
- } else {
- // Use Mesa TnL
- gld->PipelineUsage.dwMesa.QuadPart++;
- return GLD_PIPELINE_MESA;
- }
- }
-
- // Must be D3D fixed-function pipeline
- gld->PipelineUsage.dwD3DFVF.QuadPart++;
- return GLD_PIPELINE_D3D_FVF;
-*/
-}
-
-//---------------------------------------------------------------------------
-
-void gld_update_state_DX9(
- struct gl_context *ctx,
- GLuint new_state)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- GLD_pb_dx9 *gldPB;
-
- if (!gld || !gld->pDev)
- return;
-
- _swsetup_InvalidateState( ctx, new_state );
- _vbo_InvalidateState( ctx, new_state );
- _tnl_InvalidateState( ctx, new_state );
-
- // SetupIndex will be used in the pipelines for choosing setup function
- if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) ||
- (ctx->Fog.Enabled))
- {
- if (ctx->_TriangleCaps & DD_FLATSHADE)
- gld->iSetupFunc = GLD_SI_FLAT_EXTRAS;
- else
- gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS;
- } else {
- if (ctx->_TriangleCaps & DD_FLATSHADE)
- gld->iSetupFunc = GLD_SI_FLAT; // Setup flat shade + texture
- else
- gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture
- }
-
- gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld);
- if (gld->bUseMesaTnL) {
- gldPB = &gld->PB2d;
- _GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, TRUE));
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, FALSE));
- _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL));
- _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF));
- } else {
- gldPB = &gld->PB3d;
- _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, TRUE));
-// if (gld->TnLPipeline == GLD_PIPELINE_D3D_VS_TWOSIDE) {
-// _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware));
-// _GLD_DX9_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader));
-// } else {
-// _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->bHasHWTnL));
- _GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, !gld->bHasHWTnL));
- _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL));
- _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF));
-// }
- }
-
-#define _GLD_TEST_STATE(a) \
- if (new_state & (a)) { \
- gld##a(ctx); \
- new_state &= ~(a); \
- }
-
-#define _GLD_TEST_STATE_DX9(a) \
- if (new_state & (a)) { \
- gld##a##_DX9(ctx); \
- new_state &= ~(a); \
- }
-
-#define _GLD_IGNORE_STATE(a) new_state &= ~(a);
-
-// if (!gld->bUseMesaTnL) {
- // Not required if Mesa is doing the TnL.
- // Problem: If gld->bUseMesaTnL is TRUE when these are signaled,
- // then we'll miss updating the D3D TnL pipeline.
- // Therefore, don't test for gld->bUseMesaTnL
- _GLD_TEST_STATE(_NEW_MODELVIEW);
- _GLD_TEST_STATE(_NEW_PROJECTION);
-// }
-
- _GLD_TEST_STATE_DX9(_NEW_TEXTURE); // extern, so guard with _DX9
- _GLD_TEST_STATE(_NEW_COLOR);
- _GLD_TEST_STATE(_NEW_DEPTH);
- _GLD_TEST_STATE(_NEW_POLYGON);
- _GLD_TEST_STATE(_NEW_STENCIL);
- _GLD_TEST_STATE(_NEW_FOG);
- _GLD_TEST_STATE(_NEW_LIGHT);
- _GLD_TEST_STATE(_NEW_VIEWPORT);
-
- _GLD_IGNORE_STATE(_NEW_TRANSFORM);
-
- // Scissor Test: New for DX9
- _GLD_TEST_STATE(_NEW_SCISSOR);
-
-// Stubs for future use.
-/* _GLD_TEST_STATE(_NEW_TEXTURE_MATRIX);
- _GLD_TEST_STATE(_NEW_COLOR_MATRIX);
- _GLD_TEST_STATE(_NEW_ACCUM);
- _GLD_TEST_STATE(_NEW_EVAL);
- _GLD_TEST_STATE(_NEW_HINT);
- _GLD_TEST_STATE(_NEW_LINE);
- _GLD_TEST_STATE(_NEW_PIXEL);
- _GLD_TEST_STATE(_NEW_POINT);
- _GLD_TEST_STATE(_NEW_POLYGONSTIPPLE);
- _GLD_TEST_STATE(_NEW_PACKUNPACK);
- _GLD_TEST_STATE(_NEW_ARRAY);
- _GLD_TEST_STATE(_NEW_RENDERMODE);
- _GLD_TEST_STATE(_NEW_BUFFERS);
- _GLD_TEST_STATE(_NEW_MULTISAMPLE);
-*/
-
-// For debugging.
-#if 0
-#define _GLD_TEST_UNHANDLED_STATE(a) \
- if (new_state & (a)) { \
- gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n"); \
- }
- _GLD_TEST_UNHANDLED_STATE(_NEW_TEXTURE_MATRIX);
- _GLD_TEST_UNHANDLED_STATE(_NEW_COLOR_MATRIX);
- _GLD_TEST_UNHANDLED_STATE(_NEW_ACCUM);
- _GLD_TEST_UNHANDLED_STATE(_NEW_EVAL);
- _GLD_TEST_UNHANDLED_STATE(_NEW_HINT);
- _GLD_TEST_UNHANDLED_STATE(_NEW_LINE);
- _GLD_TEST_UNHANDLED_STATE(_NEW_PIXEL);
- _GLD_TEST_UNHANDLED_STATE(_NEW_POINT);
- _GLD_TEST_UNHANDLED_STATE(_NEW_POLYGONSTIPPLE);
-// _GLD_TEST_UNHANDLED_STATE(_NEW_SCISSOR);
- _GLD_TEST_UNHANDLED_STATE(_NEW_PACKUNPACK);
- _GLD_TEST_UNHANDLED_STATE(_NEW_ARRAY);
- _GLD_TEST_UNHANDLED_STATE(_NEW_RENDERMODE);
- _GLD_TEST_UNHANDLED_STATE(_NEW_BUFFERS);
- _GLD_TEST_UNHANDLED_STATE(_NEW_MULTISAMPLE);
-#undef _GLD_UNHANDLED_STATE
-#endif
-
-#undef _GLD_TEST_STATE
-}
-
-//---------------------------------------------------------------------------
-// Viewport
-//---------------------------------------------------------------------------
-
-void gld_Viewport_DX9(
- struct gl_context *ctx,
- GLint x,
- GLint y,
- GLsizei w,
- GLsizei h)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- D3DVIEWPORT9 d3dvp;
-
- if (!gld || !gld->pDev)
- return;
-
- // This is a hack. When the app is minimized, Mesa passes
- // w=1 and h=1 for viewport dimensions. Without this test
- // we get a GPF in gld_wgl_resize_buffers().
- if ((w==1) && (h==1))
- return;
-
- // Call ResizeBuffersMESA. This function will early-out
- // if no resize is needed.
- //ctx->Driver.ResizeBuffersMESA(ctx);
- // Mesa 5: Changed parameters
- ctx->Driver.ResizeBuffers(gldCtx->glBuffer);
-
-#if 0
- ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h);
-#endif
-
- // ** D3D viewport must not be outside the render target surface **
- // Sanity check the GL viewport dimensions
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (w > gldCtx->dwWidth) w = gldCtx->dwWidth;
- if (h > gldCtx->dwHeight) h = gldCtx->dwHeight;
- // Ditto for D3D viewport dimensions
- if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x;
- if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y;
-
- d3dvp.X = x;
- d3dvp.Y = gldCtx->dwHeight - (y + h);
- d3dvp.Width = w;
- d3dvp.Height = h;
- if (ctx->Viewport.Near <= ctx->Viewport.Far) {
- d3dvp.MinZ = ctx->Viewport.Near;
- d3dvp.MaxZ = ctx->Viewport.Far;
- } else {
- d3dvp.MinZ = ctx->Viewport.Far;
- d3dvp.MaxZ = ctx->Viewport.Near;
- }
-
- // TODO: DEBUGGING
-// d3dvp.MinZ = 0.0f;
-// d3dvp.MaxZ = 1.0f;
-
- _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp));
-
-}
-
-//---------------------------------------------------------------------------
-
-extern BOOL dglWglResizeBuffers(struct gl_context *ctx, BOOL bDefaultDriver);
-
-// Mesa 5: Parameter change
-void gldResizeBuffers_DX9(
-// struct gl_context *ctx)
- struct gl_framebuffer *fb)
-{
- GET_CURRENT_CONTEXT(ctx);
- dglWglResizeBuffers(ctx, TRUE);
-}
-
-//---------------------------------------------------------------------------
-#ifdef _DEBUG
-// This is only for debugging.
-// To use, plug into ctx->Driver.Enable pointer below.
-void gld_Enable(
- struct gl_context *ctx,
- GLenum e,
- GLboolean b)
-{
- char buf[1024];
- sprintf(buf, "Enable: %s (%s)\n", _mesa_lookup_enum_by_nr(e), b?"TRUE":"FALSE");
- ddlogMessage(DDLOG_SYSTEM, buf);
-}
-#endif
-//---------------------------------------------------------------------------
-// Driver pointer setup
-//---------------------------------------------------------------------------
-
-extern const GLubyte* _gldGetStringGeneric(struct gl_context*, GLenum);
-
-void gldSetupDriverPointers_DX9(
- struct gl_context *ctx)
-{
- GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
- GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
-
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- // Mandatory functions
- ctx->Driver.GetString = _gldGetStringGeneric;
- ctx->Driver.UpdateState = gld_update_state_DX9;
- ctx->Driver.Clear = gld_Clear_DX9;
- ctx->Driver.DrawBuffer = gld_set_draw_buffer_DX9;
- ctx->Driver.GetBufferSize = gld_buffer_size_DX9;
- ctx->Driver.Finish = gld_Finish_DX9;
- ctx->Driver.Flush = gld_Flush_DX9;
- ctx->Driver.Error = gld_Error_DX9;
-
- // Hardware accumulation buffer
- ctx->Driver.Accum = NULL; // TODO: gld_Accum;
-
- // Bitmap functions
- ctx->Driver.CopyPixels = gld_CopyPixels_DX9;
- ctx->Driver.DrawPixels = gld_DrawPixels_DX9;
- ctx->Driver.ReadPixels = gld_ReadPixels_DX9;
- ctx->Driver.Bitmap = gld_Bitmap_DX9;
-
- // Buffer resize
- ctx->Driver.ResizeBuffers = gldResizeBuffers_DX9;
-
- // Texture image functions
- ctx->Driver.ChooseTextureFormat = gld_ChooseTextureFormat_DX9;
- ctx->Driver.TexImage1D = gld_TexImage1D_DX9;
- ctx->Driver.TexImage2D = gld_TexImage2D_DX9;
- ctx->Driver.TexImage3D = _mesa_store_teximage3d;
- ctx->Driver.TexSubImage1D = gld_TexSubImage1D_DX9;
- ctx->Driver.TexSubImage2D = gld_TexSubImage2D_DX9;
- ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
-
- ctx->Driver.CopyTexImage1D = gldCopyTexImage1D_DX9; //NULL;
- ctx->Driver.CopyTexImage2D = gldCopyTexImage2D_DX9; //NULL;
- ctx->Driver.CopyTexSubImage1D = gldCopyTexSubImage1D_DX9; //NULL;
- ctx->Driver.CopyTexSubImage2D = gldCopyTexSubImage2D_DX9; //NULL;
- ctx->Driver.CopyTexSubImage3D = gldCopyTexSubImage3D_DX9;
- ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
-
- // Texture object functions
- ctx->Driver.BindTexture = NULL;
- ctx->Driver.NewTextureObject = NULL; // Not yet implemented by Mesa!;
- ctx->Driver.DeleteTexture = gld_DeleteTexture_DX9;
- ctx->Driver.PrioritizeTexture = NULL;
-
- // Imaging functionality
- ctx->Driver.CopyColorTable = NULL;
- ctx->Driver.CopyColorSubTable = NULL;
- ctx->Driver.CopyConvolutionFilter1D = NULL;
- ctx->Driver.CopyConvolutionFilter2D = NULL;
-
- // State changing functions
- ctx->Driver.AlphaFunc = NULL; //gld_AlphaFunc;
- ctx->Driver.BlendFuncSeparate = NULL; //gld_BlendFunc;
- ctx->Driver.ClearColor = NULL; //gld_ClearColor;
- ctx->Driver.ClearDepth = NULL; //gld_ClearDepth;
- ctx->Driver.ClearStencil = NULL; //gld_ClearStencil;
- ctx->Driver.ColorMask = NULL; //gld_ColorMask;
- ctx->Driver.CullFace = NULL; //gld_CullFace;
- ctx->Driver.ClipPlane = NULL; //gld_ClipPlane;
- ctx->Driver.FrontFace = NULL; //gld_FrontFace;
- ctx->Driver.DepthFunc = NULL; //gld_DepthFunc;
- ctx->Driver.DepthMask = NULL; //gld_DepthMask;
- ctx->Driver.DepthRange = NULL;
- ctx->Driver.Enable = NULL; //gld_Enable;
- ctx->Driver.Fogfv = NULL; //gld_Fogfv;
- ctx->Driver.Hint = NULL; //gld_Hint;
- ctx->Driver.Lightfv = NULL; //gld_Lightfv;
- ctx->Driver.LightModelfv = NULL; //gld_LightModelfv;
- ctx->Driver.LineStipple = NULL; //gld_LineStipple;
- ctx->Driver.LineWidth = NULL; //gld_LineWidth;
- ctx->Driver.LogicOpcode = NULL; //gld_LogicOpcode;
- ctx->Driver.PointParameterfv = NULL; //gld_PointParameterfv;
- ctx->Driver.PointSize = NULL; //gld_PointSize;
- ctx->Driver.PolygonMode = NULL; //gld_PolygonMode;
- ctx->Driver.PolygonOffset = NULL; //gld_PolygonOffset;
- ctx->Driver.PolygonStipple = NULL; //gld_PolygonStipple;
- ctx->Driver.RenderMode = NULL; //gld_RenderMode;
- ctx->Driver.Scissor = NULL; //gld_Scissor;
- ctx->Driver.ShadeModel = NULL; //gld_ShadeModel;
- ctx->Driver.StencilFunc = NULL; //gld_StencilFunc;
- ctx->Driver.StencilMask = NULL; //gld_StencilMask;
- ctx->Driver.StencilOp = NULL; //gld_StencilOp;
- ctx->Driver.TexGen = NULL; //gld_TexGen;
- ctx->Driver.TexEnv = NULL;
- ctx->Driver.TexParameter = NULL;
- ctx->Driver.TextureMatrix = NULL; //gld_TextureMatrix;
- ctx->Driver.Viewport = gld_Viewport_DX9;
-
- _swsetup_Wakeup(ctx);
-
- tnl->Driver.RunPipeline = _tnl_run_pipeline;
- tnl->Driver.Render.ResetLineStipple = gld_ResetLineStipple_DX9;
- tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
- tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
-
- // Hook into glFrustum() and glOrtho()
-// ctx->Exec->Frustum = gldFrustumHook_DX9;
-// ctx->Exec->Ortho = gldOrthoHook_DX9;
-
-}
-
-//---------------------------------------------------------------------------
+/****************************************************************************
+*
+* Mesa 3-D graphics library
+* Direct3D Driver Interface
+*
+* ========================================================================
+*
+* Copyright (C) 1991-2004 SciTech Software, 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
+* SCITECH SOFTWARE INC 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.
+*
+* ======================================================================
+*
+* Language: ANSI C
+* Environment: Windows 9x/2000/XP/XBox (Win32)
+*
+* Description: Driver interface code to Mesa
+*
+****************************************************************************/
+
+//#include <windows.h>
+#include "dglcontext.h"
+#include "ddlog.h"
+#include "gld_dx9.h"
+
+#include "glheader.h"
+#include "context.h"
+#include "colormac.h"
+#include "depth.h"
+#include "extensions.h"
+#include "macros.h"
+#include "matrix.h"
+// #include "mem.h"
+//#include "mmath.h"
+#include "mtypes.h"
+#include "texformat.h"
+#include "teximage.h"
+#include "texstore.h"
+#include "vbo/vbo.h"
+#include "swrast_setup/swrast_setup.h"
+#include "swrast_setup/ss_context.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+extern BOOL dglSwapBuffers(HDC hDC);
+
+// HACK: Hack the _33 member of the OpenGL perspective projection matrix
+const float _fPersp_33 = 1.6f;
+
+//---------------------------------------------------------------------------
+// Internal functions
+//---------------------------------------------------------------------------
+
+void _gld_mesa_warning(
+ __struct gl_context *gc,
+ char *str)
+{
+ // Intercept Mesa's internal warning mechanism
+ gldLogPrintf(GLDLOG_WARN, "Mesa warning: %s", str);
+}
+
+//---------------------------------------------------------------------------
+
+void _gld_mesa_fatal(
+ __struct gl_context *gc,
+ char *str)
+{
+ // Intercept Mesa's internal fatal-message mechanism
+ gldLogPrintf(GLDLOG_CRITICAL, "Mesa FATAL: %s", str);
+
+ // Mesa calls abort(0) here.
+ ddlogClose();
+ exit(0);
+}
+
+//---------------------------------------------------------------------------
+
+D3DSTENCILOP _gldConvertStencilOp(
+ GLenum StencilOp)
+{
+ // Used by Stencil: pass, fail and zfail
+
+ switch (StencilOp) {
+ case GL_KEEP:
+ return D3DSTENCILOP_KEEP;
+ case GL_ZERO:
+ return D3DSTENCILOP_ZERO;
+ case GL_REPLACE:
+ return D3DSTENCILOP_REPLACE;
+ case GL_INCR:
+ return D3DSTENCILOP_INCRSAT;
+ case GL_DECR:
+ return D3DSTENCILOP_DECRSAT;
+ case GL_INVERT:
+ return D3DSTENCILOP_INVERT;
+ case GL_INCR_WRAP_EXT: // GL_EXT_stencil_wrap
+ return D3DSTENCILOP_INCR;
+ case GL_DECR_WRAP_EXT: // GL_EXT_stencil_wrap
+ return D3DSTENCILOP_DECR;
+ }
+
+#ifdef _DEBUG
+ gldLogMessage(GLDLOG_ERROR, "_gldConvertStencilOp: Unknown StencilOp\n");
+#endif
+
+ return D3DSTENCILOP_KEEP;
+}
+
+//---------------------------------------------------------------------------
+
+D3DCMPFUNC _gldConvertCompareFunc(
+ GLenum CmpFunc)
+{
+ // Used for Alpha func, depth func and stencil func.
+
+ switch (CmpFunc) {
+ case GL_NEVER:
+ return D3DCMP_NEVER;
+ case GL_LESS:
+ return D3DCMP_LESS;
+ case GL_EQUAL:
+ return D3DCMP_EQUAL;
+ case GL_LEQUAL:
+ return D3DCMP_LESSEQUAL;
+ case GL_GREATER:
+ return D3DCMP_GREATER;
+ case GL_NOTEQUAL:
+ return D3DCMP_NOTEQUAL;
+ case GL_GEQUAL:
+ return D3DCMP_GREATEREQUAL;
+ case GL_ALWAYS:
+ return D3DCMP_ALWAYS;
+ };
+
+#ifdef _DEBUG
+ gldLogMessage(GLDLOG_ERROR, "_gldConvertCompareFunc: Unknown CompareFunc\n");
+#endif
+
+ return D3DCMP_ALWAYS;
+}
+
+//---------------------------------------------------------------------------
+
+D3DBLEND _gldConvertBlendFunc(
+ GLenum blend,
+ GLenum DefaultBlend)
+{
+ switch (blend) {
+ case GL_ZERO:
+ return D3DBLEND_ZERO;
+ case GL_ONE:
+ return D3DBLEND_ONE;
+ case GL_DST_COLOR:
+ return D3DBLEND_DESTCOLOR;
+ case GL_SRC_COLOR:
+ return D3DBLEND_SRCCOLOR;
+ case GL_ONE_MINUS_DST_COLOR:
+ return D3DBLEND_INVDESTCOLOR;
+ case GL_ONE_MINUS_SRC_COLOR:
+ return D3DBLEND_INVSRCCOLOR;
+ case GL_SRC_ALPHA:
+ return D3DBLEND_SRCALPHA;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ return D3DBLEND_INVSRCALPHA;
+ case GL_DST_ALPHA:
+ return D3DBLEND_DESTALPHA;
+ case GL_ONE_MINUS_DST_ALPHA:
+ return D3DBLEND_INVDESTALPHA;
+ case GL_SRC_ALPHA_SATURATE:
+ return D3DBLEND_SRCALPHASAT;
+ }
+
+#ifdef _DEBUG
+ gldLogMessage(GLDLOG_ERROR, "_gldConvertBlendFunc: Unknown BlendFunc\n");
+#endif
+
+ return DefaultBlend;
+}
+
+//---------------------------------------------------------------------------
+// Misc. functions
+//---------------------------------------------------------------------------
+
+void gld_Noop_DX9(
+ struct gl_context *ctx)
+{
+#ifdef _DEBUG
+ gldLogMessage(GLDLOG_ERROR, "gld_Noop called!\n");
+#endif
+}
+
+//---------------------------------------------------------------------------
+
+void gld_Error_DX9(
+ struct gl_context *ctx)
+{
+#ifdef _DEBUG
+ // Quite useless.
+// gldLogMessage(GLDLOG_ERROR, "ctx->Driver.Error called!\n");
+#endif
+}
+
+//---------------------------------------------------------------------------
+// Required Mesa functions
+//---------------------------------------------------------------------------
+
+static GLboolean gld_set_draw_buffer_DX9(
+ struct gl_context *ctx,
+ GLenum mode)
+{
+ (void) ctx;
+ if ((mode==GL_FRONT_LEFT) || (mode == GL_BACK_LEFT)) {
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+//---------------------------------------------------------------------------
+
+static void gld_set_read_buffer_DX9(
+ struct gl_context *ctx,
+ struct gl_framebuffer *buffer,
+ GLenum mode)
+{
+ /* separate read buffer not supported */
+/*
+ ASSERT(buffer == ctx->DrawBuffer);
+ ASSERT(mode == GL_FRONT_LEFT);
+*/
+}
+
+//---------------------------------------------------------------------------
+
+void gld_Clear_DX9(
+ struct gl_context *ctx,
+ GLbitfield mask,
+ GLboolean all,
+ GLint x,
+ GLint y,
+ GLint width,
+ GLint height)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ DWORD dwFlags = 0;
+ D3DCOLOR Color = 0;
+ float Z = 0.0f;
+ DWORD Stencil = 0;
+ D3DRECT d3dClearRect;
+
+ // TODO: Colourmask
+ const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0];
+
+ if (!gld->pDev)
+ return;
+
+ if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
+ GLubyte col[4];
+ CLAMPED_FLOAT_TO_UBYTE(col[0], ctx->Color.ClearColor[0]);
+ CLAMPED_FLOAT_TO_UBYTE(col[1], ctx->Color.ClearColor[1]);
+ CLAMPED_FLOAT_TO_UBYTE(col[2], ctx->Color.ClearColor[2]);
+ CLAMPED_FLOAT_TO_UBYTE(col[3], ctx->Color.ClearColor[3]);
+ dwFlags |= D3DCLEAR_TARGET;
+ Color = D3DCOLOR_RGBA(col[0], col[1], col[2], col[3]);
+ }
+
+ if (mask & DD_DEPTH_BIT) {
+ // D3D8 will fail the Clear call if we try and clear a
+ // depth buffer and we haven't created one.
+ // Also, some apps try and clear a depth buffer,
+ // when a depth buffer hasn't been requested by the app.
+ if (ctx->Visual.depthBits == 0) {
+ mask &= ~DD_DEPTH_BIT; // Remove depth bit from mask
+ } else {
+ dwFlags |= D3DCLEAR_ZBUFFER;
+ Z = ctx->Depth.Clear;
+ }
+ }
+
+ if (mask & DD_STENCIL_BIT) {
+ if (ctx->Visual.stencilBits == 0) {
+ // No stencil bits in depth buffer
+ mask &= ~DD_STENCIL_BIT; // Remove stencil bit from mask
+ } else {
+ dwFlags |= D3DCLEAR_STENCIL;
+ Stencil = ctx->Stencil.Clear;
+ }
+ }
+
+ // Some apps do really weird things with the rect, such as Quake3.
+ if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) {
+ all = GL_TRUE;
+ }
+
+ if (!all) {
+ // Calculate clear subrect
+ d3dClearRect.x1 = x;
+ d3dClearRect.y1 = gldCtx->dwHeight - (y + height);
+ d3dClearRect.x2 = x + width;
+ d3dClearRect.y2 = d3dClearRect.y1 + height;
+// gldLogPrintf(GLDLOG_INFO, "Rect %d,%d %d,%d", x,y,width,height);
+ }
+
+ // dwFlags will be zero if there's nothing to clear
+ if (dwFlags) {
+ _GLD_DX9_DEV(Clear(
+ gld->pDev,
+ all ? 0 : 1,
+ all ? NULL : &d3dClearRect,
+ dwFlags,
+ Color, Z, Stencil));
+ }
+
+ if (mask & DD_ACCUM_BIT) {
+ // Clear accumulation buffer
+ }
+}
+
+//---------------------------------------------------------------------------
+
+// Mesa 5: Parameter change
+static void gld_buffer_size_DX9(
+// struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLuint *width,
+ GLuint *height)
+{
+// GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+
+ *width = fb->Width; // gldCtx->dwWidth;
+ *height = fb->Height; // gldCtx->dwHeight;
+}
+
+//---------------------------------------------------------------------------
+
+static void gld_Finish_DX9(
+ struct gl_context *ctx)
+{
+}
+
+//---------------------------------------------------------------------------
+
+static void gld_Flush_DX9(
+ struct gl_context *ctx)
+{
+ GLD_context *gld = GLD_GET_CONTEXT(ctx);
+
+ // TODO: Detect apps that glFlush() then SwapBuffers() ?
+
+ if (gld->EmulateSingle) {
+ // Emulating a single-buffered context.
+ // [Direct3D doesn't allow rendering to front buffer]
+ dglSwapBuffers(gld->hDC);
+ }
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_STENCIL(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ // Two-sided stencil. New for Mesa 5
+ const GLuint uiFace = 0UL;
+
+ struct gl_stencil_attrib *pStencil = &ctx->Stencil;
+
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILENABLE, pStencil->Enabled ? TRUE : FALSE));
+ if (pStencil->Enabled) {
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFUNC, _gldConvertCompareFunc(pStencil->Function[uiFace])));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILREF, pStencil->Ref[uiFace]));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILMASK, pStencil->ValueMask[uiFace]));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILWRITEMASK, pStencil->WriteMask[uiFace]));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFAIL, _gldConvertStencilOp(pStencil->FailFunc[uiFace])));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILZFAIL, _gldConvertStencilOp(pStencil->ZFailFunc[uiFace])));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILPASS, _gldConvertStencilOp(pStencil->ZPassFunc[uiFace])));
+ }
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_COLOR(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ DWORD dwFlags = 0;
+ D3DBLEND src;
+ D3DBLEND dest;
+
+ // Alpha func
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAFUNC, _gldConvertCompareFunc(ctx->Color.AlphaFunc)));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAREF, (DWORD)ctx->Color.AlphaRef));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHATESTENABLE, ctx->Color.AlphaEnabled));
+
+ // Blend func
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHABLENDENABLE, ctx->Color.BlendEnabled));
+ src = _gldConvertBlendFunc(ctx->Color.BlendSrcRGB, GL_ONE);
+ dest = _gldConvertBlendFunc(ctx->Color.BlendDstRGB, GL_ZERO);
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SRCBLEND, src));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DESTBLEND, dest));
+
+ // Color mask
+ if (ctx->Color.ColorMask[0][0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
+ if (ctx->Color.ColorMask[0][1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
+ if (ctx->Color.ColorMask[0][2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
+ if (ctx->Color.ColorMask[0][3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags));
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_DEPTH(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZENABLE, ctx->Depth.Test ? D3DZB_TRUE : D3DZB_FALSE));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZFUNC, _gldConvertCompareFunc(ctx->Depth.Func)));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZWRITEENABLE, ctx->Depth.Mask ? TRUE : FALSE));
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_POLYGON(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ D3DFILLMODE d3dFillMode = D3DFILL_SOLID;
+ D3DCULL d3dCullMode = D3DCULL_NONE;
+ float fOffset = 0; // Changed from int to float for DX9
+
+ // Fillmode
+ switch (ctx->Polygon.FrontMode) {
+ case GL_POINT:
+ d3dFillMode = D3DFILL_POINT;
+ break;
+ case GL_LINE:
+ d3dFillMode = D3DFILL_WIREFRAME;
+ break;
+ case GL_FILL:
+ d3dFillMode = D3DFILL_SOLID;
+ break;
+ }
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FILLMODE, d3dFillMode));
+
+ if (ctx->Polygon.CullFlag) {
+ switch (ctx->Polygon.CullFaceMode) {
+ case GL_BACK:
+ if (ctx->Polygon.FrontFace == GL_CCW)
+ d3dCullMode = D3DCULL_CW;
+ else
+ d3dCullMode = D3DCULL_CCW;
+ break;
+ case GL_FRONT:
+ if (ctx->Polygon.FrontFace == GL_CCW)
+ d3dCullMode = D3DCULL_CCW;
+ else
+ d3dCullMode = D3DCULL_CW;
+ break;
+ case GL_FRONT_AND_BACK:
+ d3dCullMode = D3DCULL_NONE;
+ break;
+ default:
+ break;
+ }
+ } else {
+ d3dCullMode = D3DCULL_NONE;
+ }
+// d3dCullMode = D3DCULL_NONE; // FOR DEBUGGING
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CULLMODE, d3dCullMode));
+
+ // Polygon offset
+ // ZBIAS ranges from 0 to 16 and can only move towards the viewer
+ // Mesa5: ctx->Polygon._OffsetAny removed
+ if (ctx->Polygon.OffsetFill) {
+ fOffset = ctx->Polygon.OffsetUnits;
+// if (iOffset < 0.0f)
+// iOffset = -iOffset;
+// else
+// iOffset = 0.0f; // D3D can't push away
+ }
+ // NOTE: SetRenderState() required a DWORD, so need to cast
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DEPTHBIAS, *((DWORD*)&fOffset)));
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_FOG(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ D3DCOLOR d3dFogColour;
+ D3DFOGMODE d3dFogMode = D3DFOG_LINEAR;
+
+ // TODO: Fog is calculated seperately in the Mesa pipeline
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, FALSE));
+ return;
+
+ // Fog enable
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, ctx->Fog.Enabled));
+ if (!ctx->Fog.Enabled) {
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, D3DFOG_NONE));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE));
+ return; // If disabled, don't bother setting any fog state
+ }
+
+ // Fog colour
+ d3dFogColour = D3DCOLOR_COLORVALUE( ctx->Fog.Color[0],
+ ctx->Fog.Color[1],
+ ctx->Fog.Color[2],
+ ctx->Fog.Color[3]);
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGCOLOR, d3dFogColour));
+
+ // Fog density
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density))));
+
+ // Fog start
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGSTART, *((DWORD*) (&ctx->Fog.Start))));
+
+ // Fog end
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGEND, *((DWORD*) (&ctx->Fog.End))));
+
+ // Fog mode
+ switch (ctx->Fog.Mode) {
+ case GL_LINEAR:
+ d3dFogMode = D3DFOG_LINEAR;
+ break;
+ case GL_EXP:
+ d3dFogMode = D3DFOG_EXP;
+ break;
+ case GL_EXP2:
+ d3dFogMode = D3DFOG_EXP2;
+ break;
+ }
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, d3dFogMode));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE));
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_LIGHT(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+ DWORD dwSpecularEnable;
+
+ // Shademode
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT));
+
+ // Separate specular colour
+ if (ctx->Light.Enabled)
+ dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE;
+ else
+ dwSpecularEnable = FALSE;
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SPECULARENABLE, dwSpecularEnable));
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_MODELVIEW(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ D3DMATRIX m;
+ //GLfloat *pM = ctx->ModelView.m;
+ // Mesa5: Model-view is now a stack
+ GLfloat *pM = ctx->ModelviewMatrixStack.Top->m;
+ m._11 = pM[0];
+ m._12 = pM[1];
+ m._13 = pM[2];
+ m._14 = pM[3];
+ m._21 = pM[4];
+ m._22 = pM[5];
+ m._23 = pM[6];
+ m._24 = pM[7];
+ m._31 = pM[8];
+ m._32 = pM[9];
+ m._33 = pM[10];
+ m._34 = pM[11];
+ m._41 = pM[12];
+ m._42 = pM[13];
+ m._43 = pM[14];
+ m._44 = pM[15];
+
+ gld->matModelView = m;
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_PROJECTION(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ D3DMATRIX m;
+ //GLfloat *pM = ctx->ProjectionMatrix.m;
+ // Mesa 5: Now a stack
+ GLfloat *pM = ctx->ProjectionMatrixStack.Top->m;
+ m._11 = pM[0];
+ m._12 = pM[1];
+ m._13 = pM[2];
+ m._14 = pM[3];
+
+ m._21 = pM[4];
+ m._22 = pM[5];
+ m._23 = pM[6];
+ m._24 = pM[7];
+
+ m._31 = pM[8];
+ m._32 = pM[9];
+ m._33 = pM[10] / _fPersp_33; // / 1.6f;
+ m._34 = pM[11];
+
+ m._41 = pM[12];
+ m._42 = pM[13];
+ m._43 = pM[14] / 2.0f;
+ m._44 = pM[15];
+
+ gld->matProjection = m;
+}
+
+//---------------------------------------------------------------------------
+/*
+void gldFrustumHook_DX9(
+ GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble nearval,
+ GLdouble farval)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ // Pass values on to Mesa first (in case we mess with them)
+ _mesa_Frustum(left, right, bottom, top, nearval, farval);
+
+ _fPersp_33 = farval / (nearval - farval);
+
+// ddlogPrintf(GLDLOG_SYSTEM, "Frustum: %f", farval/nearval);
+}
+
+//---------------------------------------------------------------------------
+
+void gldOrthoHook_DX9(
+ GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble nearval,
+ GLdouble farval)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ // Pass values on to Mesa first (in case we mess with them)
+ _mesa_Ortho(left, right, bottom, top, nearval, farval);
+
+ _fPersp_33 = 1.6f;
+
+// ddlogPrintf(GLDLOG_SYSTEM, "Ortho: %f", farval/nearval);
+}
+*/
+//---------------------------------------------------------------------------
+
+void gld_NEW_VIEWPORT(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ D3DVIEWPORT9 d3dvp;
+// GLint x, y;
+// GLsizei w, h;
+
+ // Set depth range
+ _GLD_DX9_DEV(GetViewport(gld->pDev, &d3dvp));
+ // D3D can't do Quake1/Quake2 z-trick
+ if (ctx->Viewport.Near <= ctx->Viewport.Far) {
+ d3dvp.MinZ = ctx->Viewport.Near;
+ d3dvp.MaxZ = ctx->Viewport.Far;
+ } else {
+ d3dvp.MinZ = ctx->Viewport.Far;
+ d3dvp.MaxZ = ctx->Viewport.Near;
+ }
+/* x = ctx->Viewport.X;
+ y = ctx->Viewport.Y;
+ w = ctx->Viewport.Width;
+ h = ctx->Viewport.Height;
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (w > gldCtx->dwWidth) w = gldCtx->dwWidth;
+ if (h > gldCtx->dwHeight) h = gldCtx->dwHeight;
+ // Ditto for D3D viewport dimensions
+ if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x;
+ if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y;
+ d3dvp.X = x;
+ d3dvp.Y = gldCtx->dwHeight - (y + h);
+ d3dvp.Width = w;
+ d3dvp.Height = h;*/
+ _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp));
+
+// gld->fFlipWindowY = (float)gldCtx->dwHeight;
+}
+
+//---------------------------------------------------------------------------
+
+void gld_NEW_SCISSOR(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ // Bail if IHV driver cannot scissor
+ if (!gld->bCanScissor)
+ return;
+
+ // Set scissor rect
+ if (ctx->Scissor.Enabled) {
+ RECT rcRect;
+ // Keep in mind that RECT's need an extra row and column
+ rcRect.left = ctx->Scissor.X;
+ rcRect.right = ctx->Scissor.X + ctx->Scissor.Width; // + 1;
+ rcRect.top = gldCtx->dwHeight - (ctx->Scissor.Y + ctx->Scissor.Height);
+ rcRect.bottom = rcRect.top + ctx->Scissor.Height;
+ IDirect3DDevice9_SetScissorRect(gld->pDev, &rcRect);
+ }
+
+ // Enable/disable scissor as required
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SCISSORTESTENABLE, ctx->Scissor.Enabled));
+}
+
+//---------------------------------------------------------------------------
+
+__inline BOOL _gldAnyEvalEnabled(
+ struct gl_context *ctx)
+{
+ struct gl_eval_attrib *eval = &ctx->Eval;
+
+ if ((eval->AutoNormal) ||
+ (eval->Map1Color4) ||
+ (eval->Map1Index) ||
+ (eval->Map1Normal) ||
+ (eval->Map1TextureCoord1) ||
+ (eval->Map1TextureCoord2) ||
+ (eval->Map1TextureCoord3) ||
+ (eval->Map1TextureCoord4) ||
+ (eval->Map1Vertex3) ||
+ (eval->Map1Vertex4) ||
+ (eval->Map2Color4) ||
+ (eval->Map2Index) ||
+ (eval->Map2Normal) ||
+ (eval->Map2TextureCoord1) ||
+ (eval->Map2TextureCoord2) ||
+ (eval->Map2TextureCoord3) ||
+ (eval->Map2TextureCoord4) ||
+ (eval->Map2Vertex3) ||
+ (eval->Map2Vertex4)
+ )
+ return TRUE;
+
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
+BOOL _gldChooseInternalPipeline(
+ struct gl_context *ctx,
+ GLD_driver_dx9 *gld)
+{
+// return TRUE; // DEBUGGING: ALWAYS USE MESA
+// return FALSE; // DEBUGGING: ALWAYS USE D3D
+
+ if ((glb.dwTnL == GLDS_TNL_MESA) || (gld->bHasHWTnL == FALSE))
+ {
+ gld->PipelineUsage.qwMesa.QuadPart++;
+ return TRUE; // Force Mesa TnL
+ }
+
+ if ((ctx->Light.Enabled) ||
+ (1) ||
+ (ctx->Texture._TexGenEnabled) ||
+ (ctx->Texture._TexMatEnabled) ||
+// (ctx->Transform._AnyClip) ||
+ (ctx->Scissor.Enabled) ||
+ _gldAnyEvalEnabled(ctx) // Put this last so we can early-out
+ )
+ {
+ gld->PipelineUsage.qwMesa.QuadPart++;
+ return TRUE;
+ }
+
+ gld->PipelineUsage.qwD3DFVF.QuadPart++;
+ return FALSE;
+
+/* // Force Mesa pipeline?
+ if (glb.dwTnL == GLDS_TNL_MESA) {
+ gld->PipelineUsage.dwMesa.QuadPart++;
+ return GLD_PIPELINE_MESA;
+ }
+
+ // Test for functionality not exposed in the D3D pathways
+ if ((ctx->Texture._GenFlags)) {
+ gld->PipelineUsage.dwMesa.QuadPart++;
+ return GLD_PIPELINE_MESA;
+ }
+
+ // Now decide if vertex shader can be used.
+ // If two sided lighting is enabled then we must either
+ // use Mesa TnL or the vertex shader
+ if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
+ if (gld->VStwosidelight.hShader && !ctx->Fog.Enabled) {
+ // Use Vertex Shader
+ gld->PipelineUsage.dwD3D2SVS.QuadPart++;
+ return GLD_PIPELINE_D3D_VS_TWOSIDE;
+ } else {
+ // Use Mesa TnL
+ gld->PipelineUsage.dwMesa.QuadPart++;
+ return GLD_PIPELINE_MESA;
+ }
+ }
+
+ // Must be D3D fixed-function pipeline
+ gld->PipelineUsage.dwD3DFVF.QuadPart++;
+ return GLD_PIPELINE_D3D_FVF;
+*/
+}
+
+//---------------------------------------------------------------------------
+
+void gld_update_state_DX9(
+ struct gl_context *ctx,
+ GLuint new_state)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLD_pb_dx9 *gldPB;
+
+ if (!gld || !gld->pDev)
+ return;
+
+ _swsetup_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+
+ // SetupIndex will be used in the pipelines for choosing setup function
+ if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) ||
+ (ctx->Fog.Enabled))
+ {
+ if (ctx->_TriangleCaps & DD_FLATSHADE)
+ gld->iSetupFunc = GLD_SI_FLAT_EXTRAS;
+ else
+ gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS;
+ } else {
+ if (ctx->_TriangleCaps & DD_FLATSHADE)
+ gld->iSetupFunc = GLD_SI_FLAT; // Setup flat shade + texture
+ else
+ gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture
+ }
+
+ gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld);
+ if (gld->bUseMesaTnL) {
+ gldPB = &gld->PB2d;
+ _GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, TRUE));
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, FALSE));
+ _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL));
+ _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF));
+ } else {
+ gldPB = &gld->PB3d;
+ _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, TRUE));
+// if (gld->TnLPipeline == GLD_PIPELINE_D3D_VS_TWOSIDE) {
+// _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware));
+// _GLD_DX9_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader));
+// } else {
+// _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->bHasHWTnL));
+ _GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, !gld->bHasHWTnL));
+ _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL));
+ _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF));
+// }
+ }
+
+#define _GLD_TEST_STATE(a) \
+ if (new_state & (a)) { \
+ gld##a(ctx); \
+ new_state &= ~(a); \
+ }
+
+#define _GLD_TEST_STATE_DX9(a) \
+ if (new_state & (a)) { \
+ gld##a##_DX9(ctx); \
+ new_state &= ~(a); \
+ }
+
+#define _GLD_IGNORE_STATE(a) new_state &= ~(a);
+
+// if (!gld->bUseMesaTnL) {
+ // Not required if Mesa is doing the TnL.
+ // Problem: If gld->bUseMesaTnL is TRUE when these are signaled,
+ // then we'll miss updating the D3D TnL pipeline.
+ // Therefore, don't test for gld->bUseMesaTnL
+ _GLD_TEST_STATE(_NEW_MODELVIEW);
+ _GLD_TEST_STATE(_NEW_PROJECTION);
+// }
+
+ _GLD_TEST_STATE_DX9(_NEW_TEXTURE); // extern, so guard with _DX9
+ _GLD_TEST_STATE(_NEW_COLOR);
+ _GLD_TEST_STATE(_NEW_DEPTH);
+ _GLD_TEST_STATE(_NEW_POLYGON);
+ _GLD_TEST_STATE(_NEW_STENCIL);
+ _GLD_TEST_STATE(_NEW_FOG);
+ _GLD_TEST_STATE(_NEW_LIGHT);
+ _GLD_TEST_STATE(_NEW_VIEWPORT);
+
+ _GLD_IGNORE_STATE(_NEW_TRANSFORM);
+
+ // Scissor Test: New for DX9
+ _GLD_TEST_STATE(_NEW_SCISSOR);
+
+// Stubs for future use.
+/* _GLD_TEST_STATE(_NEW_TEXTURE_MATRIX);
+ _GLD_TEST_STATE(_NEW_COLOR_MATRIX);
+ _GLD_TEST_STATE(_NEW_EVAL);
+ _GLD_TEST_STATE(_NEW_HINT);
+ _GLD_TEST_STATE(_NEW_LINE);
+ _GLD_TEST_STATE(_NEW_PIXEL);
+ _GLD_TEST_STATE(_NEW_POINT);
+ _GLD_TEST_STATE(_NEW_POLYGONSTIPPLE);
+ _GLD_TEST_STATE(_NEW_PACKUNPACK);
+ _GLD_TEST_STATE(_NEW_ARRAY);
+ _GLD_TEST_STATE(_NEW_RENDERMODE);
+ _GLD_TEST_STATE(_NEW_BUFFERS);
+ _GLD_TEST_STATE(_NEW_MULTISAMPLE);
+*/
+
+// For debugging.
+#if 0
+#define _GLD_TEST_UNHANDLED_STATE(a) \
+ if (new_state & (a)) { \
+ gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n"); \
+ }
+ _GLD_TEST_UNHANDLED_STATE(_NEW_TEXTURE_MATRIX);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_COLOR_MATRIX);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_EVAL);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_HINT);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_LINE);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_PIXEL);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_POINT);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_POLYGONSTIPPLE);
+// _GLD_TEST_UNHANDLED_STATE(_NEW_SCISSOR);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_PACKUNPACK);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_ARRAY);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_RENDERMODE);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_BUFFERS);
+ _GLD_TEST_UNHANDLED_STATE(_NEW_MULTISAMPLE);
+#undef _GLD_UNHANDLED_STATE
+#endif
+
+#undef _GLD_TEST_STATE
+}
+
+//---------------------------------------------------------------------------
+// Viewport
+//---------------------------------------------------------------------------
+
+void gld_Viewport_DX9(
+ struct gl_context *ctx,
+ GLint x,
+ GLint y,
+ GLsizei w,
+ GLsizei h)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ D3DVIEWPORT9 d3dvp;
+
+ if (!gld || !gld->pDev)
+ return;
+
+ // This is a hack. When the app is minimized, Mesa passes
+ // w=1 and h=1 for viewport dimensions. Without this test
+ // we get a GPF in gld_wgl_resize_buffers().
+ if ((w==1) && (h==1))
+ return;
+
+ // Call ResizeBuffersMESA. This function will early-out
+ // if no resize is needed.
+ //ctx->Driver.ResizeBuffersMESA(ctx);
+ // Mesa 5: Changed parameters
+ ctx->Driver.ResizeBuffers(gldCtx->glBuffer);
+
+#if 0
+ ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h);
+#endif
+
+ // ** D3D viewport must not be outside the render target surface **
+ // Sanity check the GL viewport dimensions
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (w > gldCtx->dwWidth) w = gldCtx->dwWidth;
+ if (h > gldCtx->dwHeight) h = gldCtx->dwHeight;
+ // Ditto for D3D viewport dimensions
+ if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x;
+ if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y;
+
+ d3dvp.X = x;
+ d3dvp.Y = gldCtx->dwHeight - (y + h);
+ d3dvp.Width = w;
+ d3dvp.Height = h;
+ if (ctx->Viewport.Near <= ctx->Viewport.Far) {
+ d3dvp.MinZ = ctx->Viewport.Near;
+ d3dvp.MaxZ = ctx->Viewport.Far;
+ } else {
+ d3dvp.MinZ = ctx->Viewport.Far;
+ d3dvp.MaxZ = ctx->Viewport.Near;
+ }
+
+ // TODO: DEBUGGING
+// d3dvp.MinZ = 0.0f;
+// d3dvp.MaxZ = 1.0f;
+
+ _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp));
+
+}
+
+//---------------------------------------------------------------------------
+
+extern BOOL dglWglResizeBuffers(struct gl_context *ctx, BOOL bDefaultDriver);
+
+// Mesa 5: Parameter change
+void gldResizeBuffers_DX9(
+// struct gl_context *ctx)
+ struct gl_framebuffer *fb)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ dglWglResizeBuffers(ctx, TRUE);
+}
+
+//---------------------------------------------------------------------------
+#ifdef _DEBUG
+// This is only for debugging.
+// To use, plug into ctx->Driver.Enable pointer below.
+void gld_Enable(
+ struct gl_context *ctx,
+ GLenum e,
+ GLboolean b)
+{
+ char buf[1024];
+ sprintf(buf, "Enable: %s (%s)\n", _mesa_lookup_enum_by_nr(e), b?"TRUE":"FALSE");
+ ddlogMessage(DDLOG_SYSTEM, buf);
+}
+#endif
+//---------------------------------------------------------------------------
+// Driver pointer setup
+//---------------------------------------------------------------------------
+
+extern const GLubyte* _gldGetStringGeneric(struct gl_context*, GLenum);
+
+void gldSetupDriverPointers_DX9(
+ struct gl_context *ctx)
+{
+ GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
+ GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
+
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ // Mandatory functions
+ ctx->Driver.GetString = _gldGetStringGeneric;
+ ctx->Driver.UpdateState = gld_update_state_DX9;
+ ctx->Driver.Clear = gld_Clear_DX9;
+ ctx->Driver.DrawBuffer = gld_set_draw_buffer_DX9;
+ ctx->Driver.GetBufferSize = gld_buffer_size_DX9;
+ ctx->Driver.Finish = gld_Finish_DX9;
+ ctx->Driver.Flush = gld_Flush_DX9;
+ ctx->Driver.Error = gld_Error_DX9;
+
+ // Hardware accumulation buffer
+ ctx->Driver.Accum = NULL; // TODO: gld_Accum;
+
+ // Bitmap functions
+ ctx->Driver.CopyPixels = gld_CopyPixels_DX9;
+ ctx->Driver.DrawPixels = gld_DrawPixels_DX9;
+ ctx->Driver.ReadPixels = gld_ReadPixels_DX9;
+ ctx->Driver.Bitmap = gld_Bitmap_DX9;
+
+ // Buffer resize
+ ctx->Driver.ResizeBuffers = gldResizeBuffers_DX9;
+
+ // Texture image functions
+ ctx->Driver.ChooseTextureFormat = gld_ChooseTextureFormat_DX9;
+ ctx->Driver.TexImage1D = gld_TexImage1D_DX9;
+ ctx->Driver.TexImage2D = gld_TexImage2D_DX9;
+ ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ ctx->Driver.TexSubImage1D = gld_TexSubImage1D_DX9;
+ ctx->Driver.TexSubImage2D = gld_TexSubImage2D_DX9;
+ ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+
+ ctx->Driver.CopyTexImage1D = gldCopyTexImage1D_DX9; //NULL;
+ ctx->Driver.CopyTexImage2D = gldCopyTexImage2D_DX9; //NULL;
+ ctx->Driver.CopyTexSubImage1D = gldCopyTexSubImage1D_DX9; //NULL;
+ ctx->Driver.CopyTexSubImage2D = gldCopyTexSubImage2D_DX9; //NULL;
+ ctx->Driver.CopyTexSubImage3D = gldCopyTexSubImage3D_DX9;
+ ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
+ // Texture object functions
+ ctx->Driver.BindTexture = NULL;
+ ctx->Driver.NewTextureObject = NULL; // Not yet implemented by Mesa!;
+ ctx->Driver.DeleteTexture = gld_DeleteTexture_DX9;
+ ctx->Driver.PrioritizeTexture = NULL;
+
+ // Imaging functionality
+ ctx->Driver.CopyColorTable = NULL;
+ ctx->Driver.CopyColorSubTable = NULL;
+ ctx->Driver.CopyConvolutionFilter1D = NULL;
+ ctx->Driver.CopyConvolutionFilter2D = NULL;
+
+ // State changing functions
+ ctx->Driver.AlphaFunc = NULL; //gld_AlphaFunc;
+ ctx->Driver.BlendFuncSeparate = NULL; //gld_BlendFunc;
+ ctx->Driver.ClearColor = NULL; //gld_ClearColor;
+ ctx->Driver.ClearDepth = NULL; //gld_ClearDepth;
+ ctx->Driver.ClearStencil = NULL; //gld_ClearStencil;
+ ctx->Driver.ColorMask = NULL; //gld_ColorMask;
+ ctx->Driver.CullFace = NULL; //gld_CullFace;
+ ctx->Driver.ClipPlane = NULL; //gld_ClipPlane;
+ ctx->Driver.FrontFace = NULL; //gld_FrontFace;
+ ctx->Driver.DepthFunc = NULL; //gld_DepthFunc;
+ ctx->Driver.DepthMask = NULL; //gld_DepthMask;
+ ctx->Driver.DepthRange = NULL;
+ ctx->Driver.Enable = NULL; //gld_Enable;
+ ctx->Driver.Fogfv = NULL; //gld_Fogfv;
+ ctx->Driver.Hint = NULL; //gld_Hint;
+ ctx->Driver.Lightfv = NULL; //gld_Lightfv;
+ ctx->Driver.LightModelfv = NULL; //gld_LightModelfv;
+ ctx->Driver.LineStipple = NULL; //gld_LineStipple;
+ ctx->Driver.LineWidth = NULL; //gld_LineWidth;
+ ctx->Driver.LogicOpcode = NULL; //gld_LogicOpcode;
+ ctx->Driver.PointParameterfv = NULL; //gld_PointParameterfv;
+ ctx->Driver.PointSize = NULL; //gld_PointSize;
+ ctx->Driver.PolygonMode = NULL; //gld_PolygonMode;
+ ctx->Driver.PolygonOffset = NULL; //gld_PolygonOffset;
+ ctx->Driver.PolygonStipple = NULL; //gld_PolygonStipple;
+ ctx->Driver.RenderMode = NULL; //gld_RenderMode;
+ ctx->Driver.Scissor = NULL; //gld_Scissor;
+ ctx->Driver.ShadeModel = NULL; //gld_ShadeModel;
+ ctx->Driver.StencilFunc = NULL; //gld_StencilFunc;
+ ctx->Driver.StencilMask = NULL; //gld_StencilMask;
+ ctx->Driver.StencilOp = NULL; //gld_StencilOp;
+ ctx->Driver.TexGen = NULL; //gld_TexGen;
+ ctx->Driver.TexEnv = NULL;
+ ctx->Driver.TexParameter = NULL;
+ ctx->Driver.TextureMatrix = NULL; //gld_TextureMatrix;
+ ctx->Driver.Viewport = gld_Viewport_DX9;
+
+ _swsetup_Wakeup(ctx);
+
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
+ tnl->Driver.Render.ResetLineStipple = gld_ResetLineStipple_DX9;
+ tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
+ tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
+
+ // Hook into glFrustum() and glOrtho()
+// ctx->Exec->Frustum = gldFrustumHook_DX9;
+// ctx->Exec->Ortho = gldOrthoHook_DX9;
+
+}
+
+//---------------------------------------------------------------------------
diff --git a/mesalib/src/mesa/main/accum.c b/mesalib/src/mesa/main/accum.c
index 752ef70b8..6a83930a1 100644
--- a/mesalib/src/mesa/main/accum.c
+++ b/mesalib/src/mesa/main/accum.c
@@ -1,123 +1,122 @@
-/*
- * 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.
- */
-
-#include "glheader.h"
-#include "accum.h"
-#include "context.h"
-#include "imports.h"
-#include "macros.h"
-#include "mfeatures.h"
-#include "state.h"
-#include "mtypes.h"
-#include "main/dispatch.h"
-
-
-#if FEATURE_accum
-
-
-void GLAPIENTRY
-_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
-{
- GLfloat tmp[4];
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- tmp[0] = CLAMP( red, -1.0F, 1.0F );
- tmp[1] = CLAMP( green, -1.0F, 1.0F );
- tmp[2] = CLAMP( blue, -1.0F, 1.0F );
- tmp[3] = CLAMP( alpha, -1.0F, 1.0F );
-
- if (TEST_EQ_4V(tmp, ctx->Accum.ClearColor))
- return;
-
- FLUSH_VERTICES(ctx, _NEW_ACCUM);
- COPY_4FV( ctx->Accum.ClearColor, tmp );
-}
-
-
-static void GLAPIENTRY
-_mesa_Accum( GLenum op, GLfloat value )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- switch (op) {
- case GL_ADD:
- case GL_MULT:
- case GL_ACCUM:
- case GL_LOAD:
- case GL_RETURN:
- /* OK */
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glAccum(op)");
- return;
- }
-
- if (ctx->DrawBuffer->Visual.haveAccumBuffer == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glAccum(no accum buffer)");
- return;
- }
-
- if (ctx->DrawBuffer != ctx->ReadBuffer) {
- /* See GLX_SGI_make_current_read or WGL_ARB_make_current_read,
- * or GL_EXT_framebuffer_blit.
- */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glAccum(different read/draw buffers)");
- return;
- }
-
- if (ctx->NewState)
- _mesa_update_state(ctx);
-
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glAccum(incomplete framebuffer)");
- return;
- }
-
- if (ctx->RenderMode == GL_RENDER) {
- ctx->Driver.Accum(ctx, op, value);
- }
-}
-
-
-void
-_mesa_init_accum_dispatch(struct _glapi_table *disp)
-{
- SET_Accum(disp, _mesa_Accum);
- SET_ClearAccum(disp, _mesa_ClearAccum);
-}
-
-
-#endif /* FEATURE_accum */
-
-
-void
-_mesa_init_accum( struct gl_context *ctx )
-{
- /* Accumulate buffer group */
- ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 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.
+ */
+
+#include "glheader.h"
+#include "accum.h"
+#include "context.h"
+#include "imports.h"
+#include "macros.h"
+#include "mfeatures.h"
+#include "state.h"
+#include "mtypes.h"
+#include "main/dispatch.h"
+
+
+#if FEATURE_accum
+
+
+void GLAPIENTRY
+_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
+{
+ GLfloat tmp[4];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ tmp[0] = CLAMP( red, -1.0F, 1.0F );
+ tmp[1] = CLAMP( green, -1.0F, 1.0F );
+ tmp[2] = CLAMP( blue, -1.0F, 1.0F );
+ tmp[3] = CLAMP( alpha, -1.0F, 1.0F );
+
+ if (TEST_EQ_4V(tmp, ctx->Accum.ClearColor))
+ return;
+
+ COPY_4FV( ctx->Accum.ClearColor, tmp );
+}
+
+
+static void GLAPIENTRY
+_mesa_Accum( GLenum op, GLfloat value )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ switch (op) {
+ case GL_ADD:
+ case GL_MULT:
+ case GL_ACCUM:
+ case GL_LOAD:
+ case GL_RETURN:
+ /* OK */
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glAccum(op)");
+ return;
+ }
+
+ if (ctx->DrawBuffer->Visual.haveAccumBuffer == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glAccum(no accum buffer)");
+ return;
+ }
+
+ if (ctx->DrawBuffer != ctx->ReadBuffer) {
+ /* See GLX_SGI_make_current_read or WGL_ARB_make_current_read,
+ * or GL_EXT_framebuffer_blit.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glAccum(different read/draw buffers)");
+ return;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glAccum(incomplete framebuffer)");
+ return;
+ }
+
+ if (ctx->RenderMode == GL_RENDER) {
+ ctx->Driver.Accum(ctx, op, value);
+ }
+}
+
+
+void
+_mesa_init_accum_dispatch(struct _glapi_table *disp)
+{
+ SET_Accum(disp, _mesa_Accum);
+ SET_ClearAccum(disp, _mesa_ClearAccum);
+}
+
+
+#endif /* FEATURE_accum */
+
+
+void
+_mesa_init_accum( struct gl_context *ctx )
+{
+ /* Accumulate buffer group */
+ ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
+}
diff --git a/mesalib/src/mesa/main/debug.c b/mesalib/src/mesa/main/debug.c
index a6a909b48..c1118504f 100644
--- a/mesalib/src/mesa/main/debug.c
+++ b/mesalib/src/mesa/main/debug.c
@@ -65,13 +65,12 @@ void
_mesa_print_state( const char *msg, GLuint state )
{
_mesa_debug(NULL,
- "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
msg,
state,
(state & _NEW_MODELVIEW) ? "ctx->ModelView, " : "",
(state & _NEW_PROJECTION) ? "ctx->Projection, " : "",
(state & _NEW_TEXTURE_MATRIX) ? "ctx->TextureMatrix, " : "",
- (state & _NEW_ACCUM) ? "ctx->Accum, " : "",
(state & _NEW_COLOR) ? "ctx->Color, " : "",
(state & _NEW_DEPTH) ? "ctx->Depth, " : "",
(state & _NEW_EVAL) ? "ctx->Eval/EvalMap, " : "",
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 1b8dff0c6..7d15e3a50 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -1,924 +1,925 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.6
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 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
- * 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.
- */
-
-
-/**
- * \file
- * \brief Extension handling
- */
-
-
-#include "glheader.h"
-#include "imports.h"
-#include "context.h"
-#include "extensions.h"
-#include "mfeatures.h"
-#include "mtypes.h"
-
-enum {
- DISABLE = 0,
- GL = 1 << API_OPENGL,
- ES1 = 1 << API_OPENGLES,
- ES2 = 1 << API_OPENGLES2,
-};
-
-/**
- * \brief An element of the \c extension_table.
- */
-struct extension {
- /** Name of extension, such as "GL_ARB_depth_clamp". */
- const char *name;
-
- /** Offset (in bytes) of the corresponding member in struct gl_extensions. */
- size_t offset;
-
- /** Set of API's in which the extension exists, as a bitset. */
- uint8_t api_set;
-};
-
-
-/**
- * Given a member \c x of struct gl_extensions, return offset of
- * \c x in bytes.
- */
-#define o(x) offsetof(struct gl_extensions, x)
-
-
-/**
- * \brief Table of supported OpenGL extensions for all API's.
- *
- * Note: The GL_MESAX_* extensions are placeholders for future ARB extensions.
- */
-static const struct extension extension_table[] = {
- /* ARB Extensions */
- { "GL_ARB_ES2_compatibility", o(ARB_ES2_compatibility), GL },
- { "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL },
- { "GL_ARB_copy_buffer", o(ARB_copy_buffer), GL },
- { "GL_ARB_depth_buffer_float", o(ARB_depth_buffer_float), GL },
- { "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL },
- { "GL_ARB_depth_texture", o(ARB_depth_texture), GL },
- { "GL_ARB_draw_buffers", o(ARB_draw_buffers), GL },
- { "GL_ARB_draw_buffers_blend", o(ARB_draw_buffers_blend), GL },
- { "GL_ARB_draw_elements_base_vertex", o(ARB_draw_elements_base_vertex), GL },
- { "GL_ARB_draw_instanced", o(ARB_draw_instanced), GL },
- { "GL_ARB_explicit_attrib_location", o(ARB_explicit_attrib_location), GL },
- { "GL_ARB_fragment_coord_conventions", o(ARB_fragment_coord_conventions), GL },
- { "GL_ARB_fragment_program", o(ARB_fragment_program), GL },
- { "GL_ARB_fragment_program_shadow", o(ARB_fragment_program_shadow), GL },
- { "GL_ARB_fragment_shader", o(ARB_fragment_shader), GL },
- { "GL_ARB_framebuffer_object", o(ARB_framebuffer_object), GL },
- { "GL_ARB_half_float_pixel", o(ARB_half_float_pixel), GL },
- { "GL_ARB_half_float_vertex", o(ARB_half_float_vertex), GL },
- { "GL_ARB_instanced_arrays", o(ARB_instanced_arrays), GL },
- { "GL_ARB_map_buffer_range", o(ARB_map_buffer_range), GL },
- { "GL_ARB_multisample", o(ARB_multisample), GL },
- { "GL_ARB_multitexture", o(ARB_multitexture), GL },
- { "GL_ARB_occlusion_query2", o(ARB_occlusion_query2), GL },
- { "GL_ARB_occlusion_query", o(ARB_occlusion_query), GL },
- { "GL_ARB_pixel_buffer_object", o(EXT_pixel_buffer_object), GL },
- { "GL_ARB_point_parameters", o(EXT_point_parameters), GL },
- { "GL_ARB_point_sprite", o(ARB_point_sprite), GL },
- { "GL_ARB_provoking_vertex", o(EXT_provoking_vertex), GL },
- { "GL_ARB_sampler_objects", o(ARB_sampler_objects), GL },
- { "GL_ARB_seamless_cube_map", o(ARB_seamless_cube_map), GL },
- { "GL_ARB_shader_objects", o(ARB_shader_objects), GL },
- { "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL },
- { "GL_ARB_shading_language_100", o(ARB_shading_language_100), GL },
- { "GL_ARB_shadow_ambient", o(ARB_shadow_ambient), GL },
- { "GL_ARB_shadow", o(ARB_shadow), GL },
- { "GL_ARB_sync", o(ARB_sync), GL },
- { "GL_ARB_texture_border_clamp", o(ARB_texture_border_clamp), GL },
- { "GL_ARB_texture_buffer_object", o(ARB_texture_buffer_object), GL },
- { "GL_ARB_texture_compression", o(ARB_texture_compression), GL },
- { "GL_ARB_texture_compression_rgtc", o(ARB_texture_compression_rgtc), GL },
- { "GL_ARB_texture_cube_map", o(ARB_texture_cube_map), GL },
- { "GL_ARB_texture_env_add", o(EXT_texture_env_add), GL },
- { "GL_ARB_texture_env_combine", o(ARB_texture_env_combine), GL },
- { "GL_ARB_texture_env_crossbar", o(ARB_texture_env_crossbar), GL },
- { "GL_ARB_texture_env_dot3", o(ARB_texture_env_dot3), GL },
- { "GL_ARB_texture_mirrored_repeat", o(ARB_texture_mirrored_repeat), GL },
- { "GL_ARB_texture_multisample", o(ARB_texture_multisample), GL },
- { "GL_ARB_texture_non_power_of_two", o(ARB_texture_non_power_of_two), GL },
- { "GL_ARB_texture_rectangle", o(NV_texture_rectangle), GL },
- { "GL_ARB_texture_rgb10_a2ui", o(ARB_texture_rgb10_a2ui), GL },
- { "GL_ARB_texture_rg", o(ARB_texture_rg), GL },
- { "GL_ARB_texture_swizzle", o(EXT_texture_swizzle), GL },
- { "GL_ARB_transform_feedback2", o(ARB_transform_feedback2), GL },
- { "GL_ARB_transpose_matrix", o(ARB_transpose_matrix), GL },
- { "GL_ARB_uniform_buffer_object", o(ARB_uniform_buffer_object), GL },
- { "GL_ARB_vertex_array_bgra", o(EXT_vertex_array_bgra), GL },
- { "GL_ARB_vertex_array_object", o(ARB_vertex_array_object), GL },
- { "GL_ARB_vertex_buffer_object", o(ARB_vertex_buffer_object), GL },
- { "GL_ARB_vertex_program", o(ARB_vertex_program), GL },
- { "GL_ARB_vertex_shader", o(ARB_vertex_shader), GL },
- { "GL_ARB_vertex_type_2_10_10_10_rev", o(ARB_vertex_type_2_10_10_10_rev), GL },
- { "GL_ARB_window_pos", o(ARB_window_pos), GL },
-
- /* EXT extensions */
- { "GL_EXT_abgr", o(EXT_abgr), GL },
- { "GL_EXT_bgra", o(EXT_bgra), GL },
- { "GL_EXT_blend_color", o(EXT_blend_color), GL },
- { "GL_EXT_blend_equation_separate", o(EXT_blend_equation_separate), GL },
- { "GL_EXT_blend_func_separate", o(EXT_blend_func_separate), GL },
- { "GL_EXT_blend_logic_op", o(EXT_blend_logic_op), GL },
- { "GL_EXT_blend_minmax", o(EXT_blend_minmax), GL | ES1 | ES2 },
- { "GL_EXT_blend_subtract", o(EXT_blend_subtract), GL },
- { "GL_EXT_clip_volume_hint", o(EXT_clip_volume_hint), GL },
- { "GL_EXT_compiled_vertex_array", o(EXT_compiled_vertex_array), GL },
- { "GL_EXT_copy_texture", o(EXT_copy_texture), GL },
- { "GL_EXT_depth_bounds_test", o(EXT_depth_bounds_test), GL },
- { "GL_EXT_draw_buffers2", o(EXT_draw_buffers2), GL },
- { "GL_EXT_draw_instanced", o(ARB_draw_instanced), GL },
- { "GL_EXT_draw_range_elements", o(EXT_draw_range_elements), GL },
- { "GL_EXT_fog_coord", o(EXT_fog_coord), GL },
- { "GL_EXT_framebuffer_blit", o(EXT_framebuffer_blit), GL },
- { "GL_EXT_framebuffer_multisample", o(EXT_framebuffer_multisample), GL },
- { "GL_EXT_framebuffer_object", o(EXT_framebuffer_object), GL },
- { "GL_EXT_framebuffer_sRGB", o(EXT_framebuffer_sRGB), GL },
- { "GL_EXT_gpu_program_parameters", o(EXT_gpu_program_parameters), GL },
- { "GL_EXT_gpu_shader4", o(EXT_gpu_shader4), GL },
- { "GL_EXT_multi_draw_arrays", o(EXT_multi_draw_arrays), GL | ES1 | ES2 },
- { "GL_EXT_packed_depth_stencil", o(EXT_packed_depth_stencil), GL },
- { "GL_EXT_packed_float", o(EXT_packed_float), GL },
- { "GL_EXT_packed_pixels", o(EXT_packed_pixels), GL },
- { "GL_EXT_paletted_texture", o(EXT_paletted_texture), GL },
- { "GL_EXT_pixel_buffer_object", o(EXT_pixel_buffer_object), GL },
- { "GL_EXT_point_parameters", o(EXT_point_parameters), GL },
- { "GL_EXT_polygon_offset", o(EXT_polygon_offset), GL },
- { "GL_EXT_provoking_vertex", o(EXT_provoking_vertex), GL },
- { "GL_EXT_rescale_normal", o(EXT_rescale_normal), GL },
- { "GL_EXT_secondary_color", o(EXT_secondary_color), GL },
- { "GL_EXT_separate_shader_objects", o(EXT_separate_shader_objects), GL },
- { "GL_EXT_separate_specular_color", o(EXT_separate_specular_color), GL },
- { "GL_EXT_shadow_funcs", o(EXT_shadow_funcs), GL },
- { "GL_EXT_shared_texture_palette", o(EXT_shared_texture_palette), GL },
- { "GL_EXT_stencil_two_side", o(EXT_stencil_two_side), GL },
- { "GL_EXT_stencil_wrap", o(EXT_stencil_wrap), GL },
- { "GL_EXT_subtexture", o(EXT_subtexture), GL },
- { "GL_EXT_texture3D", o(EXT_texture3D), GL },
- { "GL_EXT_texture_array", o(EXT_texture_array), GL },
- { "GL_EXT_texture_compression_dxt1", o(EXT_texture_compression_s3tc), GL | ES1 | ES2 },
- { "GL_EXT_texture_compression_rgtc", o(ARB_texture_compression_rgtc), GL },
- { "GL_EXT_texture_compression_s3tc", o(EXT_texture_compression_s3tc), GL },
- { "GL_EXT_texture_cube_map", o(ARB_texture_cube_map), GL },
- { "GL_EXT_texture_edge_clamp", o(SGIS_texture_edge_clamp), GL },
- { "GL_EXT_texture_env_add", o(EXT_texture_env_add), GL },
- { "GL_EXT_texture_env_combine", o(EXT_texture_env_combine), GL },
- { "GL_EXT_texture_env_dot3", o(EXT_texture_env_dot3), GL },
- { "GL_EXT_texture_filter_anisotropic", o(EXT_texture_filter_anisotropic), GL | ES1 | ES2 },
- { "GL_EXT_texture_format_BGRA8888", o(EXT_texture_format_BGRA8888), ES1 | ES2 },
- { "GL_EXT_texture_integer", o(EXT_texture_integer), GL },
- { "GL_EXT_texture_lod_bias", o(EXT_texture_lod_bias), GL | ES1 },
- { "GL_EXT_texture_mirror_clamp", o(EXT_texture_mirror_clamp), GL },
- { "GL_EXT_texture_object", o(EXT_texture_object), GL },
- { "GL_EXT_texture", o(EXT_texture), GL },
- { "GL_EXT_texture_rectangle", o(NV_texture_rectangle), GL },
- { "GL_EXT_texture_shared_exponent", o(EXT_texture_shared_exponent), GL },
- { "GL_EXT_texture_sRGB", o(EXT_texture_sRGB), GL },
- { "GL_EXT_texture_sRGB_decode", o(EXT_texture_sRGB_decode), GL },
- { "GL_EXT_texture_swizzle", o(EXT_texture_swizzle), GL },
- { "GL_EXT_texture_type_2_10_10_10_REV", o(dummy_true), ES2 },
- { "GL_EXT_timer_query", o(EXT_timer_query), GL },
- { "GL_EXT_transform_feedback", o(EXT_transform_feedback), GL },
- { "GL_EXT_vertex_array_bgra", o(EXT_vertex_array_bgra), GL },
- { "GL_EXT_vertex_array", o(EXT_vertex_array), GL },
- { "GL_EXT_vertex_array_set", o(EXT_vertex_array_set), GL },
-
- /* OES extensions */
- { "GL_OES_blend_equation_separate", o(EXT_blend_equation_separate), ES1 },
- { "GL_OES_blend_func_separate", o(EXT_blend_func_separate), ES1 },
- { "GL_OES_blend_subtract", o(EXT_blend_subtract), ES1 },
- { "GL_OES_byte_coordinates", o(dummy_true), ES1 },
- { "GL_OES_compressed_paletted_texture", o(dummy_false), DISABLE },
- { "GL_OES_depth24", o(EXT_framebuffer_object), ES1 | ES2 },
- { "GL_OES_depth32", o(dummy_false), DISABLE },
- { "GL_OES_depth_texture", o(ARB_depth_texture), ES2 },
-#if FEATURE_OES_draw_texture
- { "GL_OES_draw_texture", o(OES_draw_texture), ES1 | ES2 },
-#endif
-#if FEATURE_OES_EGL_image
- /* FIXME: Mesa expects GL_OES_EGL_image to be available in OpenGL contexts. */
- { "GL_OES_EGL_image", o(OES_EGL_image), GL | ES1 | ES2 },
-#endif
- { "GL_OES_element_index_uint", o(EXT_vertex_array), ES1 | ES2 },
- { "GL_OES_fbo_render_mipmap", o(EXT_framebuffer_object), ES1 | ES2 },
- { "GL_OES_fixed_point", o(dummy_true), ES1 },
- { "GL_OES_framebuffer_object", o(EXT_framebuffer_object), ES1 },
- { "GL_OES_mapbuffer", o(ARB_vertex_buffer_object), ES1 | ES2 },
- { "GL_OES_matrix_get", o(dummy_true), ES1 },
- { "GL_OES_packed_depth_stencil", o(EXT_packed_depth_stencil), ES1 | ES2 },
- { "GL_OES_point_size_array", o(dummy_true), ES1 },
- { "GL_OES_point_sprite", o(ARB_point_sprite), ES1 },
- { "GL_OES_query_matrix", o(dummy_true), ES1 },
- { "GL_OES_read_format", o(OES_read_format), GL | ES1 },
- { "GL_OES_rgb8_rgba8", o(EXT_framebuffer_object), ES1 | ES2 },
- { "GL_OES_single_precision", o(dummy_true), ES1 },
- { "GL_OES_standard_derivatives", o(OES_standard_derivatives), ES2 },
- { "GL_OES_stencil1", o(dummy_false), DISABLE },
- { "GL_OES_stencil4", o(dummy_false), DISABLE },
- { "GL_OES_stencil8", o(EXT_framebuffer_object), ES1 | ES2 },
- { "GL_OES_stencil_wrap", o(EXT_stencil_wrap), ES1 },
- /* GL_OES_texture_3D is disabled due to missing GLSL support. */
- { "GL_OES_texture_3D", o(EXT_texture3D), DISABLE },
- { "GL_OES_texture_cube_map", o(ARB_texture_cube_map), ES1 },
- { "GL_OES_texture_env_crossbar", o(ARB_texture_env_crossbar), ES1 },
- { "GL_OES_texture_mirrored_repeat", o(ARB_texture_mirrored_repeat), ES1 },
- { "GL_OES_texture_npot", o(ARB_texture_non_power_of_two), ES2 },
-
- /* Vendor extensions */
- { "GL_3DFX_texture_compression_FXT1", o(TDFX_texture_compression_FXT1), GL },
- { "GL_APPLE_client_storage", o(APPLE_client_storage), GL },
- { "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), GL },
- { "GL_APPLE_packed_pixels", o(APPLE_packed_pixels), GL },
- { "GL_APPLE_vertex_array_object", o(APPLE_vertex_array_object), GL },
- { "GL_ATI_blend_equation_separate", o(EXT_blend_equation_separate), GL },
- { "GL_ATI_envmap_bumpmap", o(ATI_envmap_bumpmap), GL },
- { "GL_ATI_fragment_shader", o(ATI_fragment_shader), GL },
- { "GL_ATI_separate_stencil", o(ATI_separate_stencil), GL },
- { "GL_ATI_texture_env_combine3", o(ATI_texture_env_combine3), GL },
- { "GL_ATI_texture_mirror_once", o(ATI_texture_mirror_once), GL },
- { "GL_IBM_multimode_draw_arrays", o(IBM_multimode_draw_arrays), GL },
- { "GL_IBM_rasterpos_clip", o(IBM_rasterpos_clip), GL },
- { "GL_IBM_texture_mirrored_repeat", o(ARB_texture_mirrored_repeat), GL },
- { "GL_INGR_blend_func_separate", o(EXT_blend_func_separate), GL },
- { "GL_MESA_pack_invert", o(MESA_pack_invert), GL },
- { "GL_MESA_resize_buffers", o(MESA_resize_buffers), GL },
- { "GL_MESA_texture_array", o(MESA_texture_array), GL },
- { "GL_MESA_texture_signed_rgba", o(MESA_texture_signed_rgba), GL },
- { "GL_MESA_window_pos", o(ARB_window_pos), GL },
- { "GL_MESAX_texture_float", o(ARB_texture_float), GL },
- { "GL_MESA_ycbcr_texture", o(MESA_ycbcr_texture), GL },
- { "GL_NV_blend_square", o(NV_blend_square), GL },
- { "GL_NV_conditional_render", o(NV_conditional_render), GL },
- { "GL_NV_depth_clamp", o(ARB_depth_clamp), GL },
- { "GL_NV_fragment_program", o(NV_fragment_program), GL },
- { "GL_NV_fragment_program_option", o(NV_fragment_program_option), GL },
- { "GL_NV_light_max_exponent", o(NV_light_max_exponent), GL },
- { "GL_NV_packed_depth_stencil", o(EXT_packed_depth_stencil), GL },
- { "GL_NV_point_sprite", o(NV_point_sprite), GL },
- { "GL_NV_primitive_restart", o(NV_primitive_restart), GL },
- { "GL_NV_texgen_reflection", o(NV_texgen_reflection), GL },
- { "GL_NV_texture_env_combine4", o(NV_texture_env_combine4), GL },
- { "GL_NV_texture_rectangle", o(NV_texture_rectangle), GL },
- { "GL_NV_vertex_program1_1", o(NV_vertex_program1_1), GL },
- { "GL_NV_vertex_program", o(NV_vertex_program), GL },
- { "GL_S3_s3tc", o(S3_s3tc), GL },
- { "GL_SGIS_generate_mipmap", o(SGIS_generate_mipmap), GL },
- { "GL_SGIS_texture_border_clamp", o(ARB_texture_border_clamp), GL },
- { "GL_SGIS_texture_edge_clamp", o(SGIS_texture_edge_clamp), GL },
- { "GL_SGIS_texture_lod", o(SGIS_texture_lod), GL },
- { "GL_SGI_texture_color_table", o(SGI_texture_color_table), GL },
- { "GL_SUN_multi_draw_arrays", o(EXT_multi_draw_arrays), GL },
-
- { 0, 0, 0 },
-};
-
-
-/**
- * Given an extension name, lookup up the corresponding member of struct
- * gl_extensions and return that member's offset (in bytes). If the name is
- * not found in the \c extension_table, return 0.
- *
- * \param name Name of extension.
- * \return Offset of member in struct gl_extensions.
- */
-static size_t
-name_to_offset(const char* name)
-{
- const struct extension *i;
-
- if (name == 0)
- return 0;
-
- for (i = extension_table; i->name != 0; ++i) {
- if (strcmp(name, i->name) == 0)
- return i->offset;
- }
-
- return 0;
-}
-
-
-/**
- * \brief Extensions enabled by default.
- *
- * These extensions are enabled by _mesa_init_extensions().
- *
- * XXX: Should these defaults also apply to GLES?
- */
-static const size_t default_extensions[] = {
- o(ARB_copy_buffer),
- o(ARB_draw_buffers),
- o(ARB_multisample),
- o(ARB_texture_compression),
- o(ARB_transpose_matrix),
- o(ARB_vertex_buffer_object),
- o(ARB_window_pos),
-
- o(EXT_abgr),
- o(EXT_bgra),
- o(EXT_compiled_vertex_array),
- o(EXT_copy_texture),
- o(EXT_draw_range_elements),
- o(EXT_multi_draw_arrays),
- o(EXT_packed_pixels),
- o(EXT_polygon_offset),
- o(EXT_rescale_normal),
- o(EXT_separate_specular_color),
- o(EXT_subtexture),
- o(EXT_texture),
- o(EXT_texture3D),
- o(EXT_texture_object),
- o(EXT_vertex_array),
-
- o(OES_read_format),
- o(OES_standard_derivatives),
-
- /* Vendor Extensions */
- o(APPLE_packed_pixels),
- o(IBM_multimode_draw_arrays),
- o(IBM_rasterpos_clip),
- o(NV_light_max_exponent),
- o(NV_texgen_reflection),
- o(SGIS_generate_mipmap),
- o(SGIS_texture_edge_clamp),
- o(SGIS_texture_lod),
-
- 0,
-};
-
-
-/**
- * Enable all extensions suitable for a software-only renderer.
- * This is a convenience function used by the XMesa, OSMesa, GGI drivers, etc.
- */
-void
-_mesa_enable_sw_extensions(struct gl_context *ctx)
-{
- /*ctx->Extensions.ARB_copy_buffer = GL_TRUE;*/
- ctx->Extensions.ARB_depth_clamp = GL_TRUE;
- ctx->Extensions.ARB_depth_texture = GL_TRUE;
- /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
- ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
- ctx->Extensions.ARB_draw_instanced = GL_TRUE;
- ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
- ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
-#if FEATURE_ARB_fragment_program
- ctx->Extensions.ARB_fragment_program = GL_TRUE;
- ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
-#endif
-#if FEATURE_ARB_fragment_shader
- ctx->Extensions.ARB_fragment_shader = GL_TRUE;
-#endif
-#if FEATURE_ARB_framebuffer_object
- ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
-#endif
-#if FEATURE_ARB_geometry_shader4 && 0
- /* XXX re-enable when GLSL compiler again supports geometry shaders */
- ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
-#endif
- ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
- ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
- ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
- ctx->Extensions.ARB_multitexture = GL_TRUE;
-#if FEATURE_queryobj
- ctx->Extensions.ARB_occlusion_query = GL_TRUE;
- ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
-#endif
- ctx->Extensions.ARB_point_sprite = GL_TRUE;
-#if FEATURE_ARB_shader_objects
- ctx->Extensions.ARB_shader_objects = GL_TRUE;
- ctx->Extensions.EXT_separate_shader_objects = GL_TRUE;
-#endif
-#if FEATURE_ARB_shading_language_100
- ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
-#endif
- ctx->Extensions.ARB_shadow = GL_TRUE;
- ctx->Extensions.ARB_shadow_ambient = GL_TRUE;
- ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
- ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
- ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
- ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
- ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
- /*ctx->Extensions.ARB_texture_float = GL_TRUE;*/
- ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
- ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
- ctx->Extensions.ARB_texture_rg = GL_TRUE;
- ctx->Extensions.ARB_vertex_array_object = GL_TRUE;
-#if FEATURE_ARB_vertex_program
- ctx->Extensions.ARB_vertex_program = GL_TRUE;
-#endif
-#if FEATURE_ARB_vertex_shader
- ctx->Extensions.ARB_vertex_shader = GL_TRUE;
-#endif
-#if FEATURE_ARB_vertex_buffer_object
- /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
-#endif
-#if FEATURE_ARB_sync
- ctx->Extensions.ARB_sync = GL_TRUE;
-#endif
- ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
-#if FEATURE_APPLE_object_purgeable
- ctx->Extensions.APPLE_object_purgeable = GL_TRUE;
-#endif
- ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE;
-#if FEATURE_ATI_fragment_shader
- ctx->Extensions.ATI_fragment_shader = GL_TRUE;
-#endif
- ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE;
- ctx->Extensions.ATI_texture_mirror_once = GL_TRUE;
- ctx->Extensions.ATI_separate_stencil = GL_TRUE;
- ctx->Extensions.EXT_blend_color = GL_TRUE;
- ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
- ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
- ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
- ctx->Extensions.EXT_blend_minmax = GL_TRUE;
- ctx->Extensions.EXT_blend_subtract = GL_TRUE;
- ctx->Extensions.EXT_depth_bounds_test = GL_TRUE;
- ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
- ctx->Extensions.EXT_fog_coord = GL_TRUE;
-#if FEATURE_EXT_framebuffer_object
- ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
-#endif
-#if FEATURE_EXT_framebuffer_blit
- ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
-#endif
-#if FEATURE_ARB_framebuffer_object
- ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
-#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
- ctx->Extensions.EXT_point_parameters = GL_TRUE;
- 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;
- ctx->Extensions.EXT_texture_env_add = GL_TRUE;
- ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
- ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
- ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
- ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
-#if FEATURE_EXT_texture_sRGB
- ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
- ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
-#endif
- ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
-#if FEATURE_EXT_transform_feedback
- /*ctx->Extensions.EXT_transform_feedback = GL_TRUE;*/
-#endif
- ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
- /*ctx->Extensions.IBM_multimode_draw_arrays = GL_TRUE;*/
- ctx->Extensions.MESA_pack_invert = GL_TRUE;
- ctx->Extensions.MESA_resize_buffers = GL_TRUE;
- ctx->Extensions.MESA_texture_array = GL_TRUE;
- ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
- ctx->Extensions.NV_blend_square = GL_TRUE;
- ctx->Extensions.NV_conditional_render = GL_TRUE;
- /*ctx->Extensions.NV_light_max_exponent = GL_TRUE;*/
- ctx->Extensions.NV_point_sprite = GL_TRUE;
- ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
- ctx->Extensions.NV_texture_rectangle = GL_TRUE;
- /*ctx->Extensions.NV_texgen_reflection = GL_TRUE;*/
-#if FEATURE_NV_vertex_program
- ctx->Extensions.NV_vertex_program = GL_TRUE;
- ctx->Extensions.NV_vertex_program1_1 = GL_TRUE;
-#endif
-#if FEATURE_NV_fragment_program
- ctx->Extensions.NV_fragment_program = GL_TRUE;
-#endif
-#if FEATURE_NV_fragment_program && FEATURE_ARB_fragment_program
- ctx->Extensions.NV_fragment_program_option = GL_TRUE;
-#endif
- ctx->Extensions.SGI_texture_color_table = GL_TRUE;
- /*ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;*/
- ctx->Extensions.SGIS_texture_edge_clamp = GL_TRUE;
-#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
- ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
-#endif
-#if FEATURE_texture_fxt1
- _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1");
-#endif
-#if FEATURE_texture_s3tc
- if (ctx->Mesa_DXTn) {
- _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
- _mesa_enable_extension(ctx, "GL_S3_s3tc");
- }
-#endif
-}
-
-
-/**
- * Enable common EXT extensions in the ARB_imaging subset.
- */
-void
-_mesa_enable_imaging_extensions(struct gl_context *ctx)
-{
- ctx->Extensions.EXT_blend_color = GL_TRUE;
- ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
- ctx->Extensions.EXT_blend_minmax = GL_TRUE;
- ctx->Extensions.EXT_blend_subtract = GL_TRUE;
-}
-
-
-
-/**
- * Enable all OpenGL 1.3 features and extensions.
- * A convenience function to be called by drivers.
- */
-void
-_mesa_enable_1_3_extensions(struct gl_context *ctx)
-{
- /*ctx->Extensions.ARB_multisample = GL_TRUE;*/
- ctx->Extensions.ARB_multitexture = GL_TRUE;
- ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
- /*ctx->Extensions.ARB_texture_compression = GL_TRUE;*/
- ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
- ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
- ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
- ctx->Extensions.EXT_texture_env_add = GL_TRUE;
- /*ctx->Extensions.ARB_transpose_matrix = GL_TRUE;*/
-}
-
-
-
-/**
- * Enable all OpenGL 1.4 features and extensions.
- * A convenience function to be called by drivers.
- */
-void
-_mesa_enable_1_4_extensions(struct gl_context *ctx)
-{
- ctx->Extensions.ARB_depth_texture = GL_TRUE;
- ctx->Extensions.ARB_shadow = GL_TRUE;
- ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
- ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
- ctx->Extensions.ARB_window_pos = GL_TRUE;
- ctx->Extensions.EXT_blend_color = GL_TRUE;
- ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
- ctx->Extensions.EXT_blend_minmax = GL_TRUE;
- ctx->Extensions.EXT_blend_subtract = GL_TRUE;
- ctx->Extensions.EXT_fog_coord = GL_TRUE;
- /*ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;*/
- ctx->Extensions.EXT_point_parameters = GL_TRUE;
- ctx->Extensions.EXT_secondary_color = GL_TRUE;
- ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
- ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
- /*ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;*/
-}
-
-
-/**
- * Enable all OpenGL 1.5 features and extensions.
- * A convenience function to be called by drivers.
- */
-void
-_mesa_enable_1_5_extensions(struct gl_context *ctx)
-{
- ctx->Extensions.ARB_occlusion_query = GL_TRUE;
- /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
- ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
-}
-
-
-/**
- * Enable all OpenGL 2.0 features and extensions.
- * A convenience function to be called by drivers.
- */
-void
-_mesa_enable_2_0_extensions(struct gl_context *ctx)
-{
- /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
-#if FEATURE_ARB_fragment_shader
- ctx->Extensions.ARB_fragment_shader = GL_TRUE;
-#endif
- ctx->Extensions.ARB_point_sprite = GL_TRUE;
- ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
- ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
-#if FEATURE_ARB_shader_objects
- ctx->Extensions.ARB_shader_objects = GL_TRUE;
-#endif
-#if FEATURE_ARB_shading_language_100
- ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
-#endif
- ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
-#if FEATURE_ARB_vertex_shader
- ctx->Extensions.ARB_vertex_shader = GL_TRUE;
-#endif
-}
-
-
-/**
- * Enable all OpenGL 2.1 features and extensions.
- * A convenience function to be called by drivers.
- */
-void
-_mesa_enable_2_1_extensions(struct gl_context *ctx)
-{
-#if FEATURE_EXT_pixel_buffer_object
- ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
-#endif
-#if FEATURE_EXT_texture_sRGB
- ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
-#endif
-}
-
-
-/**
- * Either enable or disable the named extension.
- * \return GL_TRUE for success, GL_FALSE if invalid extension name
- */
-static GLboolean
-set_extension( struct gl_context *ctx, const char *name, GLboolean state )
-{
- size_t offset;
-
- if (ctx->Extensions.String) {
- /* The string was already queried - can't change it now! */
- _mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name);
- return GL_FALSE;
- }
-
- offset = name_to_offset(name);
- if (offset == 0) {
- _mesa_problem(ctx, "Trying to enable/disable unknown extension %s",
- name);
- return GL_FALSE;
- } else if (offset == o(dummy_true) && state == GL_FALSE) {
- _mesa_problem(ctx, "Trying to disable a permanently enabled extension: "
- "%s", name);
- return GL_FALSE;
- } else {
- GLboolean *base = (GLboolean *) &ctx->Extensions;
- base[offset] = state;
- return GL_TRUE;
- }
-}
-
-
-/**
- * Enable the named extension.
- * Typically called by drivers.
- */
-void
-_mesa_enable_extension( struct gl_context *ctx, const char *name )
-{
- if (!set_extension(ctx, name, GL_TRUE))
- _mesa_problem(ctx, "Trying to enable unknown extension: %s", name);
-}
-
-
-/**
- * Disable the named extension.
- * XXX is this really needed???
- */
-void
-_mesa_disable_extension( struct gl_context *ctx, const char *name )
-{
- if (!set_extension(ctx, name, GL_FALSE))
- _mesa_problem(ctx, "Trying to disable unknown extension: %s", name);
-}
-
-
-/**
- * Test if the named extension is enabled in this context.
- */
-GLboolean
-_mesa_extension_is_enabled( struct gl_context *ctx, const char *name )
-{
- size_t offset;
- GLboolean *base;
-
- if (name == 0)
- return GL_FALSE;
-
- offset = name_to_offset(name);
- if (offset == 0)
- return GL_FALSE;
- base = (GLboolean *) &ctx->Extensions;
- return base[offset];
-}
-
-
-/**
- * Append string 'b' onto string 'a'. Free 'a' and return new string.
- */
-static char *
-append(const char *a, const char *b)
-{
- const GLuint aLen = a ? strlen(a) : 0;
- const GLuint bLen = b ? strlen(b) : 0;
- char *s = calloc(1, aLen + bLen + 1);
- if (s) {
- if (a)
- memcpy(s, a, aLen);
- if (b)
- memcpy(s + aLen, b, bLen);
- s[aLen + bLen] = '\0';
- }
- if (a)
- free((void *) a);
- return s;
-}
-
-
-/**
- * Check the MESA_EXTENSION_OVERRIDE env var.
- * For extension names that are recognized, turn them on. For extension
- * names that are recognized and prefixed with '-', turn them off.
- * Return a string of the unknown/leftover names.
- *
- * Returnd string needs to be freed.
- */
-static char *
-get_extension_override( struct gl_context *ctx )
-{
- const char *envExt = _mesa_getenv("MESA_EXTENSION_OVERRIDE");
- char *extraExt = NULL;
- char ext[1000];
- GLuint extLen = 0;
- GLuint i;
- GLboolean disableExt = GL_FALSE;
-
- if (!envExt)
- return NULL;
-
- for (i = 0; ; i++) {
- if (envExt[i] == '\0' || envExt[i] == ' ') {
- /* terminate/process 'ext' if extLen > 0 */
- if (extLen > 0) {
- assert(extLen < sizeof(ext));
- /* enable extension named by 'ext' */
- ext[extLen] = 0;
- if (!set_extension(ctx, ext, !disableExt)) {
- /* unknown extension name, append it to extraExt */
- if (extraExt) {
- extraExt = append(extraExt, " ");
- }
- extraExt = append(extraExt, ext);
- }
- extLen = 0;
- disableExt = GL_FALSE;
- }
- if (envExt[i] == '\0')
- break;
- }
- else if (envExt[i] == '-') {
- disableExt = GL_TRUE;
- }
- else {
- /* accumulate this non-space character */
- ext[extLen++] = envExt[i];
- }
- }
-
- return extraExt;
-}
-
-
-/**
- * \brief Initialize extension tables and enable default extensions.
- *
- * This should be called during context initialization.
- * Note: Sets gl_extensions.dummy_true to true.
- */
-void
-_mesa_init_extensions( struct gl_context *ctx )
-{
- GLboolean *base = (GLboolean *) &ctx->Extensions;
- GLboolean *sentinel = base + o(extension_sentinel);
- GLboolean *i;
- const size_t *j;
-
- /* First, turn all extensions off. */
- for (i = base; i != sentinel; ++i)
- *i = GL_FALSE;
-
- /* Then, selectively turn default extensions on. */
- ctx->Extensions.dummy_true = GL_TRUE;
- for (j = default_extensions; *j != 0; ++j)
- base[*j] = GL_TRUE;
-}
-
-
-/**
- * Construct the GL_EXTENSIONS string. Called the first time that
- * glGetString(GL_EXTENSIONS) is called.
- */
-GLubyte*
-_mesa_make_extension_string(struct gl_context *ctx)
-{
- /* The extension string. */
- char *exts = 0;
- /* Length of extension string. */
- size_t length = 0;
- /* String of extra extensions. */
- char *extra_extensions = get_extension_override(ctx);
- GLboolean *base = (GLboolean *) &ctx->Extensions;
- const struct extension *i;
-
- /* Compute length of the extension string. */
- for (i = extension_table; i->name != 0; ++i) {
- if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
- length += strlen(i->name) + 1; /* +1 for space */
- }
- }
- if (extra_extensions != NULL)
- length += 1 + strlen(extra_extensions); /* +1 for space */
-
- exts = (char *) calloc(length + 1, sizeof(char));
- if (exts == NULL) {
- free(extra_extensions);
- return NULL;
- }
-
- /* Build the extension string.*/
- for (i = extension_table; i->name != 0; ++i) {
- if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
- strcat(exts, i->name);
- strcat(exts, " ");
- }
- }
- if (extra_extensions != 0) {
- strcat(exts, extra_extensions);
- free(extra_extensions);
- }
-
- return (GLubyte *) exts;
-}
-
-/**
- * Return number of enabled extensions.
- */
-GLuint
-_mesa_get_extension_count(struct gl_context *ctx)
-{
- GLboolean *base;
- const struct extension *i;
-
- /* only count once */
- if (ctx->Extensions.Count != 0)
- return ctx->Extensions.Count;
-
- base = (GLboolean *) &ctx->Extensions;
- for (i = extension_table; i->name != 0; ++i) {
- if (base[i->offset]) {
- ctx->Extensions.Count++;
- }
- }
- return ctx->Extensions.Count;
-}
-
-/**
- * Return name of i-th enabled extension
- */
-const GLubyte *
-_mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
-{
- const GLboolean *base;
- size_t n;
- const struct extension *i;
-
- if (index < 0)
- return NULL;
-
- base = (GLboolean*) &ctx->Extensions;
- n = 0;
- for (i = extension_table; i->name != 0; ++i) {
- if (n == index && base[i->offset]) {
- return (GLubyte*) i->name;
- } else if (base[i->offset]) {
- ++n;
- }
- }
-
- return NULL;
-}
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.6
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 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
+ * 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.
+ */
+
+
+/**
+ * \file
+ * \brief Extension handling
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "extensions.h"
+#include "mfeatures.h"
+#include "mtypes.h"
+
+enum {
+ DISABLE = 0,
+ GL = 1 << API_OPENGL,
+ ES1 = 1 << API_OPENGLES,
+ ES2 = 1 << API_OPENGLES2,
+};
+
+/**
+ * \brief An element of the \c extension_table.
+ */
+struct extension {
+ /** Name of extension, such as "GL_ARB_depth_clamp". */
+ const char *name;
+
+ /** Offset (in bytes) of the corresponding member in struct gl_extensions. */
+ size_t offset;
+
+ /** Set of API's in which the extension exists, as a bitset. */
+ uint8_t api_set;
+};
+
+
+/**
+ * Given a member \c x of struct gl_extensions, return offset of
+ * \c x in bytes.
+ */
+#define o(x) offsetof(struct gl_extensions, x)
+
+
+/**
+ * \brief Table of supported OpenGL extensions for all API's.
+ *
+ * Note: The GL_MESAX_* extensions are placeholders for future ARB extensions.
+ */
+static const struct extension extension_table[] = {
+ /* ARB Extensions */
+ { "GL_ARB_ES2_compatibility", o(ARB_ES2_compatibility), GL },
+ { "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL },
+ { "GL_ARB_copy_buffer", o(ARB_copy_buffer), GL },
+ { "GL_ARB_depth_buffer_float", o(ARB_depth_buffer_float), GL },
+ { "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL },
+ { "GL_ARB_depth_texture", o(ARB_depth_texture), GL },
+ { "GL_ARB_draw_buffers", o(ARB_draw_buffers), GL },
+ { "GL_ARB_draw_buffers_blend", o(ARB_draw_buffers_blend), GL },
+ { "GL_ARB_draw_elements_base_vertex", o(ARB_draw_elements_base_vertex), GL },
+ { "GL_ARB_draw_instanced", o(ARB_draw_instanced), GL },
+ { "GL_ARB_explicit_attrib_location", o(ARB_explicit_attrib_location), GL },
+ { "GL_ARB_fragment_coord_conventions", o(ARB_fragment_coord_conventions), GL },
+ { "GL_ARB_fragment_program", o(ARB_fragment_program), GL },
+ { "GL_ARB_fragment_program_shadow", o(ARB_fragment_program_shadow), GL },
+ { "GL_ARB_fragment_shader", o(ARB_fragment_shader), GL },
+ { "GL_ARB_framebuffer_object", o(ARB_framebuffer_object), GL },
+ { "GL_ARB_framebuffer_sRGB", o(EXT_framebuffer_sRGB), GL },
+ { "GL_ARB_half_float_pixel", o(ARB_half_float_pixel), GL },
+ { "GL_ARB_half_float_vertex", o(ARB_half_float_vertex), GL },
+ { "GL_ARB_instanced_arrays", o(ARB_instanced_arrays), GL },
+ { "GL_ARB_map_buffer_range", o(ARB_map_buffer_range), GL },
+ { "GL_ARB_multisample", o(ARB_multisample), GL },
+ { "GL_ARB_multitexture", o(ARB_multitexture), GL },
+ { "GL_ARB_occlusion_query2", o(ARB_occlusion_query2), GL },
+ { "GL_ARB_occlusion_query", o(ARB_occlusion_query), GL },
+ { "GL_ARB_pixel_buffer_object", o(EXT_pixel_buffer_object), GL },
+ { "GL_ARB_point_parameters", o(EXT_point_parameters), GL },
+ { "GL_ARB_point_sprite", o(ARB_point_sprite), GL },
+ { "GL_ARB_provoking_vertex", o(EXT_provoking_vertex), GL },
+ { "GL_ARB_sampler_objects", o(ARB_sampler_objects), GL },
+ { "GL_ARB_seamless_cube_map", o(ARB_seamless_cube_map), GL },
+ { "GL_ARB_shader_objects", o(ARB_shader_objects), GL },
+ { "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL },
+ { "GL_ARB_shading_language_100", o(ARB_shading_language_100), GL },
+ { "GL_ARB_shadow_ambient", o(ARB_shadow_ambient), GL },
+ { "GL_ARB_shadow", o(ARB_shadow), GL },
+ { "GL_ARB_sync", o(ARB_sync), GL },
+ { "GL_ARB_texture_border_clamp", o(ARB_texture_border_clamp), GL },
+ { "GL_ARB_texture_buffer_object", o(ARB_texture_buffer_object), GL },
+ { "GL_ARB_texture_compression", o(ARB_texture_compression), GL },
+ { "GL_ARB_texture_compression_rgtc", o(ARB_texture_compression_rgtc), GL },
+ { "GL_ARB_texture_cube_map", o(ARB_texture_cube_map), GL },
+ { "GL_ARB_texture_env_add", o(EXT_texture_env_add), GL },
+ { "GL_ARB_texture_env_combine", o(ARB_texture_env_combine), GL },
+ { "GL_ARB_texture_env_crossbar", o(ARB_texture_env_crossbar), GL },
+ { "GL_ARB_texture_env_dot3", o(ARB_texture_env_dot3), GL },
+ { "GL_ARB_texture_mirrored_repeat", o(ARB_texture_mirrored_repeat), GL },
+ { "GL_ARB_texture_multisample", o(ARB_texture_multisample), GL },
+ { "GL_ARB_texture_non_power_of_two", o(ARB_texture_non_power_of_two), GL },
+ { "GL_ARB_texture_rectangle", o(NV_texture_rectangle), GL },
+ { "GL_ARB_texture_rgb10_a2ui", o(ARB_texture_rgb10_a2ui), GL },
+ { "GL_ARB_texture_rg", o(ARB_texture_rg), GL },
+ { "GL_ARB_texture_swizzle", o(EXT_texture_swizzle), GL },
+ { "GL_ARB_transform_feedback2", o(ARB_transform_feedback2), GL },
+ { "GL_ARB_transpose_matrix", o(ARB_transpose_matrix), GL },
+ { "GL_ARB_uniform_buffer_object", o(ARB_uniform_buffer_object), GL },
+ { "GL_ARB_vertex_array_bgra", o(EXT_vertex_array_bgra), GL },
+ { "GL_ARB_vertex_array_object", o(ARB_vertex_array_object), GL },
+ { "GL_ARB_vertex_buffer_object", o(ARB_vertex_buffer_object), GL },
+ { "GL_ARB_vertex_program", o(ARB_vertex_program), GL },
+ { "GL_ARB_vertex_shader", o(ARB_vertex_shader), GL },
+ { "GL_ARB_vertex_type_2_10_10_10_rev", o(ARB_vertex_type_2_10_10_10_rev), GL },
+ { "GL_ARB_window_pos", o(ARB_window_pos), GL },
+
+ /* EXT extensions */
+ { "GL_EXT_abgr", o(EXT_abgr), GL },
+ { "GL_EXT_bgra", o(EXT_bgra), GL },
+ { "GL_EXT_blend_color", o(EXT_blend_color), GL },
+ { "GL_EXT_blend_equation_separate", o(EXT_blend_equation_separate), GL },
+ { "GL_EXT_blend_func_separate", o(EXT_blend_func_separate), GL },
+ { "GL_EXT_blend_logic_op", o(EXT_blend_logic_op), GL },
+ { "GL_EXT_blend_minmax", o(EXT_blend_minmax), GL | ES1 | ES2 },
+ { "GL_EXT_blend_subtract", o(EXT_blend_subtract), GL },
+ { "GL_EXT_clip_volume_hint", o(EXT_clip_volume_hint), GL },
+ { "GL_EXT_compiled_vertex_array", o(EXT_compiled_vertex_array), GL },
+ { "GL_EXT_copy_texture", o(EXT_copy_texture), GL },
+ { "GL_EXT_depth_bounds_test", o(EXT_depth_bounds_test), GL },
+ { "GL_EXT_draw_buffers2", o(EXT_draw_buffers2), GL },
+ { "GL_EXT_draw_instanced", o(ARB_draw_instanced), GL },
+ { "GL_EXT_draw_range_elements", o(EXT_draw_range_elements), GL },
+ { "GL_EXT_fog_coord", o(EXT_fog_coord), GL },
+ { "GL_EXT_framebuffer_blit", o(EXT_framebuffer_blit), GL },
+ { "GL_EXT_framebuffer_multisample", o(EXT_framebuffer_multisample), GL },
+ { "GL_EXT_framebuffer_object", o(EXT_framebuffer_object), GL },
+ { "GL_EXT_framebuffer_sRGB", o(EXT_framebuffer_sRGB), GL },
+ { "GL_EXT_gpu_program_parameters", o(EXT_gpu_program_parameters), GL },
+ { "GL_EXT_gpu_shader4", o(EXT_gpu_shader4), GL },
+ { "GL_EXT_multi_draw_arrays", o(EXT_multi_draw_arrays), GL | ES1 | ES2 },
+ { "GL_EXT_packed_depth_stencil", o(EXT_packed_depth_stencil), GL },
+ { "GL_EXT_packed_float", o(EXT_packed_float), GL },
+ { "GL_EXT_packed_pixels", o(EXT_packed_pixels), GL },
+ { "GL_EXT_paletted_texture", o(EXT_paletted_texture), GL },
+ { "GL_EXT_pixel_buffer_object", o(EXT_pixel_buffer_object), GL },
+ { "GL_EXT_point_parameters", o(EXT_point_parameters), GL },
+ { "GL_EXT_polygon_offset", o(EXT_polygon_offset), GL },
+ { "GL_EXT_provoking_vertex", o(EXT_provoking_vertex), GL },
+ { "GL_EXT_rescale_normal", o(EXT_rescale_normal), GL },
+ { "GL_EXT_secondary_color", o(EXT_secondary_color), GL },
+ { "GL_EXT_separate_shader_objects", o(EXT_separate_shader_objects), GL },
+ { "GL_EXT_separate_specular_color", o(EXT_separate_specular_color), GL },
+ { "GL_EXT_shadow_funcs", o(EXT_shadow_funcs), GL },
+ { "GL_EXT_shared_texture_palette", o(EXT_shared_texture_palette), GL },
+ { "GL_EXT_stencil_two_side", o(EXT_stencil_two_side), GL },
+ { "GL_EXT_stencil_wrap", o(EXT_stencil_wrap), GL },
+ { "GL_EXT_subtexture", o(EXT_subtexture), GL },
+ { "GL_EXT_texture3D", o(EXT_texture3D), GL },
+ { "GL_EXT_texture_array", o(EXT_texture_array), GL },
+ { "GL_EXT_texture_compression_dxt1", o(EXT_texture_compression_s3tc), GL | ES1 | ES2 },
+ { "GL_EXT_texture_compression_rgtc", o(ARB_texture_compression_rgtc), GL },
+ { "GL_EXT_texture_compression_s3tc", o(EXT_texture_compression_s3tc), GL },
+ { "GL_EXT_texture_cube_map", o(ARB_texture_cube_map), GL },
+ { "GL_EXT_texture_edge_clamp", o(SGIS_texture_edge_clamp), GL },
+ { "GL_EXT_texture_env_add", o(EXT_texture_env_add), GL },
+ { "GL_EXT_texture_env_combine", o(EXT_texture_env_combine), GL },
+ { "GL_EXT_texture_env_dot3", o(EXT_texture_env_dot3), GL },
+ { "GL_EXT_texture_filter_anisotropic", o(EXT_texture_filter_anisotropic), GL | ES1 | ES2 },
+ { "GL_EXT_texture_format_BGRA8888", o(EXT_texture_format_BGRA8888), ES1 | ES2 },
+ { "GL_EXT_texture_integer", o(EXT_texture_integer), GL },
+ { "GL_EXT_texture_lod_bias", o(EXT_texture_lod_bias), GL | ES1 },
+ { "GL_EXT_texture_mirror_clamp", o(EXT_texture_mirror_clamp), GL },
+ { "GL_EXT_texture_object", o(EXT_texture_object), GL },
+ { "GL_EXT_texture", o(EXT_texture), GL },
+ { "GL_EXT_texture_rectangle", o(NV_texture_rectangle), GL },
+ { "GL_EXT_texture_shared_exponent", o(EXT_texture_shared_exponent), GL },
+ { "GL_EXT_texture_sRGB", o(EXT_texture_sRGB), GL },
+ { "GL_EXT_texture_sRGB_decode", o(EXT_texture_sRGB_decode), GL },
+ { "GL_EXT_texture_swizzle", o(EXT_texture_swizzle), GL },
+ { "GL_EXT_texture_type_2_10_10_10_REV", o(dummy_true), ES2 },
+ { "GL_EXT_timer_query", o(EXT_timer_query), GL },
+ { "GL_EXT_transform_feedback", o(EXT_transform_feedback), GL },
+ { "GL_EXT_vertex_array_bgra", o(EXT_vertex_array_bgra), GL },
+ { "GL_EXT_vertex_array", o(EXT_vertex_array), GL },
+ { "GL_EXT_vertex_array_set", o(EXT_vertex_array_set), GL },
+
+ /* OES extensions */
+ { "GL_OES_blend_equation_separate", o(EXT_blend_equation_separate), ES1 },
+ { "GL_OES_blend_func_separate", o(EXT_blend_func_separate), ES1 },
+ { "GL_OES_blend_subtract", o(EXT_blend_subtract), ES1 },
+ { "GL_OES_byte_coordinates", o(dummy_true), ES1 },
+ { "GL_OES_compressed_paletted_texture", o(dummy_false), DISABLE },
+ { "GL_OES_depth24", o(EXT_framebuffer_object), ES1 | ES2 },
+ { "GL_OES_depth32", o(dummy_false), DISABLE },
+ { "GL_OES_depth_texture", o(ARB_depth_texture), ES2 },
+#if FEATURE_OES_draw_texture
+ { "GL_OES_draw_texture", o(OES_draw_texture), ES1 | ES2 },
+#endif
+#if FEATURE_OES_EGL_image
+ /* FIXME: Mesa expects GL_OES_EGL_image to be available in OpenGL contexts. */
+ { "GL_OES_EGL_image", o(OES_EGL_image), GL | ES1 | ES2 },
+#endif
+ { "GL_OES_element_index_uint", o(EXT_vertex_array), ES1 | ES2 },
+ { "GL_OES_fbo_render_mipmap", o(EXT_framebuffer_object), ES1 | ES2 },
+ { "GL_OES_fixed_point", o(dummy_true), ES1 },
+ { "GL_OES_framebuffer_object", o(EXT_framebuffer_object), ES1 },
+ { "GL_OES_mapbuffer", o(ARB_vertex_buffer_object), ES1 | ES2 },
+ { "GL_OES_matrix_get", o(dummy_true), ES1 },
+ { "GL_OES_packed_depth_stencil", o(EXT_packed_depth_stencil), ES1 | ES2 },
+ { "GL_OES_point_size_array", o(dummy_true), ES1 },
+ { "GL_OES_point_sprite", o(ARB_point_sprite), ES1 },
+ { "GL_OES_query_matrix", o(dummy_true), ES1 },
+ { "GL_OES_read_format", o(OES_read_format), GL | ES1 },
+ { "GL_OES_rgb8_rgba8", o(EXT_framebuffer_object), ES1 | ES2 },
+ { "GL_OES_single_precision", o(dummy_true), ES1 },
+ { "GL_OES_standard_derivatives", o(OES_standard_derivatives), ES2 },
+ { "GL_OES_stencil1", o(dummy_false), DISABLE },
+ { "GL_OES_stencil4", o(dummy_false), DISABLE },
+ { "GL_OES_stencil8", o(EXT_framebuffer_object), ES1 | ES2 },
+ { "GL_OES_stencil_wrap", o(EXT_stencil_wrap), ES1 },
+ /* GL_OES_texture_3D is disabled due to missing GLSL support. */
+ { "GL_OES_texture_3D", o(EXT_texture3D), DISABLE },
+ { "GL_OES_texture_cube_map", o(ARB_texture_cube_map), ES1 },
+ { "GL_OES_texture_env_crossbar", o(ARB_texture_env_crossbar), ES1 },
+ { "GL_OES_texture_mirrored_repeat", o(ARB_texture_mirrored_repeat), ES1 },
+ { "GL_OES_texture_npot", o(ARB_texture_non_power_of_two), ES2 },
+
+ /* Vendor extensions */
+ { "GL_3DFX_texture_compression_FXT1", o(TDFX_texture_compression_FXT1), GL },
+ { "GL_APPLE_client_storage", o(APPLE_client_storage), GL },
+ { "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), GL },
+ { "GL_APPLE_packed_pixels", o(APPLE_packed_pixels), GL },
+ { "GL_APPLE_vertex_array_object", o(APPLE_vertex_array_object), GL },
+ { "GL_ATI_blend_equation_separate", o(EXT_blend_equation_separate), GL },
+ { "GL_ATI_envmap_bumpmap", o(ATI_envmap_bumpmap), GL },
+ { "GL_ATI_fragment_shader", o(ATI_fragment_shader), GL },
+ { "GL_ATI_separate_stencil", o(ATI_separate_stencil), GL },
+ { "GL_ATI_texture_env_combine3", o(ATI_texture_env_combine3), GL },
+ { "GL_ATI_texture_mirror_once", o(ATI_texture_mirror_once), GL },
+ { "GL_IBM_multimode_draw_arrays", o(IBM_multimode_draw_arrays), GL },
+ { "GL_IBM_rasterpos_clip", o(IBM_rasterpos_clip), GL },
+ { "GL_IBM_texture_mirrored_repeat", o(ARB_texture_mirrored_repeat), GL },
+ { "GL_INGR_blend_func_separate", o(EXT_blend_func_separate), GL },
+ { "GL_MESA_pack_invert", o(MESA_pack_invert), GL },
+ { "GL_MESA_resize_buffers", o(MESA_resize_buffers), GL },
+ { "GL_MESA_texture_array", o(MESA_texture_array), GL },
+ { "GL_MESA_texture_signed_rgba", o(MESA_texture_signed_rgba), GL },
+ { "GL_MESA_window_pos", o(ARB_window_pos), GL },
+ { "GL_MESAX_texture_float", o(ARB_texture_float), GL },
+ { "GL_MESA_ycbcr_texture", o(MESA_ycbcr_texture), GL },
+ { "GL_NV_blend_square", o(NV_blend_square), GL },
+ { "GL_NV_conditional_render", o(NV_conditional_render), GL },
+ { "GL_NV_depth_clamp", o(ARB_depth_clamp), GL },
+ { "GL_NV_fragment_program", o(NV_fragment_program), GL },
+ { "GL_NV_fragment_program_option", o(NV_fragment_program_option), GL },
+ { "GL_NV_light_max_exponent", o(NV_light_max_exponent), GL },
+ { "GL_NV_packed_depth_stencil", o(EXT_packed_depth_stencil), GL },
+ { "GL_NV_point_sprite", o(NV_point_sprite), GL },
+ { "GL_NV_primitive_restart", o(NV_primitive_restart), GL },
+ { "GL_NV_texgen_reflection", o(NV_texgen_reflection), GL },
+ { "GL_NV_texture_env_combine4", o(NV_texture_env_combine4), GL },
+ { "GL_NV_texture_rectangle", o(NV_texture_rectangle), GL },
+ { "GL_NV_vertex_program1_1", o(NV_vertex_program1_1), GL },
+ { "GL_NV_vertex_program", o(NV_vertex_program), GL },
+ { "GL_S3_s3tc", o(S3_s3tc), GL },
+ { "GL_SGIS_generate_mipmap", o(SGIS_generate_mipmap), GL },
+ { "GL_SGIS_texture_border_clamp", o(ARB_texture_border_clamp), GL },
+ { "GL_SGIS_texture_edge_clamp", o(SGIS_texture_edge_clamp), GL },
+ { "GL_SGIS_texture_lod", o(SGIS_texture_lod), GL },
+ { "GL_SGI_texture_color_table", o(SGI_texture_color_table), GL },
+ { "GL_SUN_multi_draw_arrays", o(EXT_multi_draw_arrays), GL },
+
+ { 0, 0, 0 },
+};
+
+
+/**
+ * Given an extension name, lookup up the corresponding member of struct
+ * gl_extensions and return that member's offset (in bytes). If the name is
+ * not found in the \c extension_table, return 0.
+ *
+ * \param name Name of extension.
+ * \return Offset of member in struct gl_extensions.
+ */
+static size_t
+name_to_offset(const char* name)
+{
+ const struct extension *i;
+
+ if (name == 0)
+ return 0;
+
+ for (i = extension_table; i->name != 0; ++i) {
+ if (strcmp(name, i->name) == 0)
+ return i->offset;
+ }
+
+ return 0;
+}
+
+
+/**
+ * \brief Extensions enabled by default.
+ *
+ * These extensions are enabled by _mesa_init_extensions().
+ *
+ * XXX: Should these defaults also apply to GLES?
+ */
+static const size_t default_extensions[] = {
+ o(ARB_copy_buffer),
+ o(ARB_draw_buffers),
+ o(ARB_multisample),
+ o(ARB_texture_compression),
+ o(ARB_transpose_matrix),
+ o(ARB_vertex_buffer_object),
+ o(ARB_window_pos),
+
+ o(EXT_abgr),
+ o(EXT_bgra),
+ o(EXT_compiled_vertex_array),
+ o(EXT_copy_texture),
+ o(EXT_draw_range_elements),
+ o(EXT_multi_draw_arrays),
+ o(EXT_packed_pixels),
+ o(EXT_polygon_offset),
+ o(EXT_rescale_normal),
+ o(EXT_separate_specular_color),
+ o(EXT_subtexture),
+ o(EXT_texture),
+ o(EXT_texture3D),
+ o(EXT_texture_object),
+ o(EXT_vertex_array),
+
+ o(OES_read_format),
+ o(OES_standard_derivatives),
+
+ /* Vendor Extensions */
+ o(APPLE_packed_pixels),
+ o(IBM_multimode_draw_arrays),
+ o(IBM_rasterpos_clip),
+ o(NV_light_max_exponent),
+ o(NV_texgen_reflection),
+ o(SGIS_generate_mipmap),
+ o(SGIS_texture_edge_clamp),
+ o(SGIS_texture_lod),
+
+ 0,
+};
+
+
+/**
+ * Enable all extensions suitable for a software-only renderer.
+ * This is a convenience function used by the XMesa, OSMesa, GGI drivers, etc.
+ */
+void
+_mesa_enable_sw_extensions(struct gl_context *ctx)
+{
+ /*ctx->Extensions.ARB_copy_buffer = GL_TRUE;*/
+ ctx->Extensions.ARB_depth_clamp = GL_TRUE;
+ ctx->Extensions.ARB_depth_texture = GL_TRUE;
+ /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
+ ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
+ ctx->Extensions.ARB_draw_instanced = GL_TRUE;
+ ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
+ ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
+#if FEATURE_ARB_fragment_program
+ ctx->Extensions.ARB_fragment_program = GL_TRUE;
+ ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
+#endif
+#if FEATURE_ARB_fragment_shader
+ ctx->Extensions.ARB_fragment_shader = GL_TRUE;
+#endif
+#if FEATURE_ARB_framebuffer_object
+ ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
+#endif
+#if FEATURE_ARB_geometry_shader4 && 0
+ /* XXX re-enable when GLSL compiler again supports geometry shaders */
+ ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
+#endif
+ ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
+ ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
+ ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
+ ctx->Extensions.ARB_multitexture = GL_TRUE;
+#if FEATURE_queryobj
+ ctx->Extensions.ARB_occlusion_query = GL_TRUE;
+ ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
+#endif
+ ctx->Extensions.ARB_point_sprite = GL_TRUE;
+#if FEATURE_ARB_shader_objects
+ ctx->Extensions.ARB_shader_objects = GL_TRUE;
+ ctx->Extensions.EXT_separate_shader_objects = GL_TRUE;
+#endif
+#if FEATURE_ARB_shading_language_100
+ ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
+#endif
+ ctx->Extensions.ARB_shadow = GL_TRUE;
+ ctx->Extensions.ARB_shadow_ambient = GL_TRUE;
+ ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
+ ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
+ /*ctx->Extensions.ARB_texture_float = GL_TRUE;*/
+ ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
+ ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
+ ctx->Extensions.ARB_texture_rg = GL_TRUE;
+ ctx->Extensions.ARB_vertex_array_object = GL_TRUE;
+#if FEATURE_ARB_vertex_program
+ ctx->Extensions.ARB_vertex_program = GL_TRUE;
+#endif
+#if FEATURE_ARB_vertex_shader
+ ctx->Extensions.ARB_vertex_shader = GL_TRUE;
+#endif
+#if FEATURE_ARB_vertex_buffer_object
+ /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
+#endif
+#if FEATURE_ARB_sync
+ ctx->Extensions.ARB_sync = GL_TRUE;
+#endif
+ ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
+#if FEATURE_APPLE_object_purgeable
+ ctx->Extensions.APPLE_object_purgeable = GL_TRUE;
+#endif
+ ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE;
+#if FEATURE_ATI_fragment_shader
+ ctx->Extensions.ATI_fragment_shader = GL_TRUE;
+#endif
+ ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE;
+ ctx->Extensions.ATI_texture_mirror_once = GL_TRUE;
+ ctx->Extensions.ATI_separate_stencil = GL_TRUE;
+ ctx->Extensions.EXT_blend_color = GL_TRUE;
+ ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
+ ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
+ ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
+ ctx->Extensions.EXT_blend_minmax = GL_TRUE;
+ ctx->Extensions.EXT_blend_subtract = GL_TRUE;
+ ctx->Extensions.EXT_depth_bounds_test = GL_TRUE;
+ ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
+ ctx->Extensions.EXT_fog_coord = GL_TRUE;
+#if FEATURE_EXT_framebuffer_object
+ ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
+#endif
+#if FEATURE_EXT_framebuffer_blit
+ ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
+#endif
+#if FEATURE_ARB_framebuffer_object
+ ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
+#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
+ ctx->Extensions.EXT_point_parameters = GL_TRUE;
+ 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;
+ ctx->Extensions.EXT_texture_env_add = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
+ ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
+ ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
+#if FEATURE_EXT_texture_sRGB
+ ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
+ ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
+#endif
+ ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
+#if FEATURE_EXT_transform_feedback
+ /*ctx->Extensions.EXT_transform_feedback = GL_TRUE;*/
+#endif
+ ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
+ /*ctx->Extensions.IBM_multimode_draw_arrays = GL_TRUE;*/
+ ctx->Extensions.MESA_pack_invert = GL_TRUE;
+ ctx->Extensions.MESA_resize_buffers = GL_TRUE;
+ ctx->Extensions.MESA_texture_array = GL_TRUE;
+ ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
+ ctx->Extensions.NV_blend_square = GL_TRUE;
+ ctx->Extensions.NV_conditional_render = GL_TRUE;
+ /*ctx->Extensions.NV_light_max_exponent = GL_TRUE;*/
+ ctx->Extensions.NV_point_sprite = GL_TRUE;
+ ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
+ ctx->Extensions.NV_texture_rectangle = GL_TRUE;
+ /*ctx->Extensions.NV_texgen_reflection = GL_TRUE;*/
+#if FEATURE_NV_vertex_program
+ ctx->Extensions.NV_vertex_program = GL_TRUE;
+ ctx->Extensions.NV_vertex_program1_1 = GL_TRUE;
+#endif
+#if FEATURE_NV_fragment_program
+ ctx->Extensions.NV_fragment_program = GL_TRUE;
+#endif
+#if FEATURE_NV_fragment_program && FEATURE_ARB_fragment_program
+ ctx->Extensions.NV_fragment_program_option = GL_TRUE;
+#endif
+ ctx->Extensions.SGI_texture_color_table = GL_TRUE;
+ /*ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;*/
+ ctx->Extensions.SGIS_texture_edge_clamp = GL_TRUE;
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+ ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
+#endif
+#if FEATURE_texture_fxt1
+ _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1");
+#endif
+#if FEATURE_texture_s3tc
+ if (ctx->Mesa_DXTn) {
+ _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
+ _mesa_enable_extension(ctx, "GL_S3_s3tc");
+ }
+#endif
+}
+
+
+/**
+ * Enable common EXT extensions in the ARB_imaging subset.
+ */
+void
+_mesa_enable_imaging_extensions(struct gl_context *ctx)
+{
+ ctx->Extensions.EXT_blend_color = GL_TRUE;
+ ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
+ ctx->Extensions.EXT_blend_minmax = GL_TRUE;
+ ctx->Extensions.EXT_blend_subtract = GL_TRUE;
+}
+
+
+
+/**
+ * Enable all OpenGL 1.3 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_1_3_extensions(struct gl_context *ctx)
+{
+ /*ctx->Extensions.ARB_multisample = GL_TRUE;*/
+ ctx->Extensions.ARB_multitexture = GL_TRUE;
+ ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
+ /*ctx->Extensions.ARB_texture_compression = GL_TRUE;*/
+ ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_add = GL_TRUE;
+ /*ctx->Extensions.ARB_transpose_matrix = GL_TRUE;*/
+}
+
+
+
+/**
+ * Enable all OpenGL 1.4 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_1_4_extensions(struct gl_context *ctx)
+{
+ ctx->Extensions.ARB_depth_texture = GL_TRUE;
+ ctx->Extensions.ARB_shadow = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
+ ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
+ ctx->Extensions.ARB_window_pos = GL_TRUE;
+ ctx->Extensions.EXT_blend_color = GL_TRUE;
+ ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
+ ctx->Extensions.EXT_blend_minmax = GL_TRUE;
+ ctx->Extensions.EXT_blend_subtract = GL_TRUE;
+ ctx->Extensions.EXT_fog_coord = GL_TRUE;
+ /*ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;*/
+ ctx->Extensions.EXT_point_parameters = GL_TRUE;
+ ctx->Extensions.EXT_secondary_color = GL_TRUE;
+ ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
+ ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
+ /*ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;*/
+}
+
+
+/**
+ * Enable all OpenGL 1.5 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_1_5_extensions(struct gl_context *ctx)
+{
+ ctx->Extensions.ARB_occlusion_query = GL_TRUE;
+ /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
+ ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
+}
+
+
+/**
+ * Enable all OpenGL 2.0 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_2_0_extensions(struct gl_context *ctx)
+{
+ /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
+#if FEATURE_ARB_fragment_shader
+ ctx->Extensions.ARB_fragment_shader = GL_TRUE;
+#endif
+ ctx->Extensions.ARB_point_sprite = GL_TRUE;
+ ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
+ ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
+#if FEATURE_ARB_shader_objects
+ ctx->Extensions.ARB_shader_objects = GL_TRUE;
+#endif
+#if FEATURE_ARB_shading_language_100
+ ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
+#endif
+ ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
+#if FEATURE_ARB_vertex_shader
+ ctx->Extensions.ARB_vertex_shader = GL_TRUE;
+#endif
+}
+
+
+/**
+ * Enable all OpenGL 2.1 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_2_1_extensions(struct gl_context *ctx)
+{
+#if FEATURE_EXT_pixel_buffer_object
+ ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
+#endif
+#if FEATURE_EXT_texture_sRGB
+ ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
+#endif
+}
+
+
+/**
+ * Either enable or disable the named extension.
+ * \return GL_TRUE for success, GL_FALSE if invalid extension name
+ */
+static GLboolean
+set_extension( struct gl_context *ctx, const char *name, GLboolean state )
+{
+ size_t offset;
+
+ if (ctx->Extensions.String) {
+ /* The string was already queried - can't change it now! */
+ _mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name);
+ return GL_FALSE;
+ }
+
+ offset = name_to_offset(name);
+ if (offset == 0) {
+ _mesa_problem(ctx, "Trying to enable/disable unknown extension %s",
+ name);
+ return GL_FALSE;
+ } else if (offset == o(dummy_true) && state == GL_FALSE) {
+ _mesa_problem(ctx, "Trying to disable a permanently enabled extension: "
+ "%s", name);
+ return GL_FALSE;
+ } else {
+ GLboolean *base = (GLboolean *) &ctx->Extensions;
+ base[offset] = state;
+ return GL_TRUE;
+ }
+}
+
+
+/**
+ * Enable the named extension.
+ * Typically called by drivers.
+ */
+void
+_mesa_enable_extension( struct gl_context *ctx, const char *name )
+{
+ if (!set_extension(ctx, name, GL_TRUE))
+ _mesa_problem(ctx, "Trying to enable unknown extension: %s", name);
+}
+
+
+/**
+ * Disable the named extension.
+ * XXX is this really needed???
+ */
+void
+_mesa_disable_extension( struct gl_context *ctx, const char *name )
+{
+ if (!set_extension(ctx, name, GL_FALSE))
+ _mesa_problem(ctx, "Trying to disable unknown extension: %s", name);
+}
+
+
+/**
+ * Test if the named extension is enabled in this context.
+ */
+GLboolean
+_mesa_extension_is_enabled( struct gl_context *ctx, const char *name )
+{
+ size_t offset;
+ GLboolean *base;
+
+ if (name == 0)
+ return GL_FALSE;
+
+ offset = name_to_offset(name);
+ if (offset == 0)
+ return GL_FALSE;
+ base = (GLboolean *) &ctx->Extensions;
+ return base[offset];
+}
+
+
+/**
+ * Append string 'b' onto string 'a'. Free 'a' and return new string.
+ */
+static char *
+append(const char *a, const char *b)
+{
+ const GLuint aLen = a ? strlen(a) : 0;
+ const GLuint bLen = b ? strlen(b) : 0;
+ char *s = calloc(1, aLen + bLen + 1);
+ if (s) {
+ if (a)
+ memcpy(s, a, aLen);
+ if (b)
+ memcpy(s + aLen, b, bLen);
+ s[aLen + bLen] = '\0';
+ }
+ if (a)
+ free((void *) a);
+ return s;
+}
+
+
+/**
+ * Check the MESA_EXTENSION_OVERRIDE env var.
+ * For extension names that are recognized, turn them on. For extension
+ * names that are recognized and prefixed with '-', turn them off.
+ * Return a string of the unknown/leftover names.
+ *
+ * Returnd string needs to be freed.
+ */
+static char *
+get_extension_override( struct gl_context *ctx )
+{
+ const char *envExt = _mesa_getenv("MESA_EXTENSION_OVERRIDE");
+ char *extraExt = NULL;
+ char ext[1000];
+ GLuint extLen = 0;
+ GLuint i;
+ GLboolean disableExt = GL_FALSE;
+
+ if (!envExt)
+ return NULL;
+
+ for (i = 0; ; i++) {
+ if (envExt[i] == '\0' || envExt[i] == ' ') {
+ /* terminate/process 'ext' if extLen > 0 */
+ if (extLen > 0) {
+ assert(extLen < sizeof(ext));
+ /* enable extension named by 'ext' */
+ ext[extLen] = 0;
+ if (!set_extension(ctx, ext, !disableExt)) {
+ /* unknown extension name, append it to extraExt */
+ if (extraExt) {
+ extraExt = append(extraExt, " ");
+ }
+ extraExt = append(extraExt, ext);
+ }
+ extLen = 0;
+ disableExt = GL_FALSE;
+ }
+ if (envExt[i] == '\0')
+ break;
+ }
+ else if (envExt[i] == '-') {
+ disableExt = GL_TRUE;
+ }
+ else {
+ /* accumulate this non-space character */
+ ext[extLen++] = envExt[i];
+ }
+ }
+
+ return extraExt;
+}
+
+
+/**
+ * \brief Initialize extension tables and enable default extensions.
+ *
+ * This should be called during context initialization.
+ * Note: Sets gl_extensions.dummy_true to true.
+ */
+void
+_mesa_init_extensions( struct gl_context *ctx )
+{
+ GLboolean *base = (GLboolean *) &ctx->Extensions;
+ GLboolean *sentinel = base + o(extension_sentinel);
+ GLboolean *i;
+ const size_t *j;
+
+ /* First, turn all extensions off. */
+ for (i = base; i != sentinel; ++i)
+ *i = GL_FALSE;
+
+ /* Then, selectively turn default extensions on. */
+ ctx->Extensions.dummy_true = GL_TRUE;
+ for (j = default_extensions; *j != 0; ++j)
+ base[*j] = GL_TRUE;
+}
+
+
+/**
+ * Construct the GL_EXTENSIONS string. Called the first time that
+ * glGetString(GL_EXTENSIONS) is called.
+ */
+GLubyte*
+_mesa_make_extension_string(struct gl_context *ctx)
+{
+ /* The extension string. */
+ char *exts = 0;
+ /* Length of extension string. */
+ size_t length = 0;
+ /* String of extra extensions. */
+ char *extra_extensions = get_extension_override(ctx);
+ GLboolean *base = (GLboolean *) &ctx->Extensions;
+ const struct extension *i;
+
+ /* Compute length of the extension string. */
+ for (i = extension_table; i->name != 0; ++i) {
+ if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
+ length += strlen(i->name) + 1; /* +1 for space */
+ }
+ }
+ if (extra_extensions != NULL)
+ length += 1 + strlen(extra_extensions); /* +1 for space */
+
+ exts = (char *) calloc(length + 1, sizeof(char));
+ if (exts == NULL) {
+ free(extra_extensions);
+ return NULL;
+ }
+
+ /* Build the extension string.*/
+ for (i = extension_table; i->name != 0; ++i) {
+ if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
+ strcat(exts, i->name);
+ strcat(exts, " ");
+ }
+ }
+ if (extra_extensions != 0) {
+ strcat(exts, extra_extensions);
+ free(extra_extensions);
+ }
+
+ return (GLubyte *) exts;
+}
+
+/**
+ * Return number of enabled extensions.
+ */
+GLuint
+_mesa_get_extension_count(struct gl_context *ctx)
+{
+ GLboolean *base;
+ const struct extension *i;
+
+ /* only count once */
+ if (ctx->Extensions.Count != 0)
+ return ctx->Extensions.Count;
+
+ base = (GLboolean *) &ctx->Extensions;
+ for (i = extension_table; i->name != 0; ++i) {
+ if (base[i->offset]) {
+ ctx->Extensions.Count++;
+ }
+ }
+ return ctx->Extensions.Count;
+}
+
+/**
+ * Return name of i-th enabled extension
+ */
+const GLubyte *
+_mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
+{
+ const GLboolean *base;
+ size_t n;
+ const struct extension *i;
+
+ if (index < 0)
+ return NULL;
+
+ base = (GLboolean*) &ctx->Extensions;
+ n = 0;
+ for (i = extension_table; i->name != 0; ++i) {
+ if (n == index && base[i->offset]) {
+ return (GLubyte*) i->name;
+ } else if (base[i->offset]) {
+ ++n;
+ }
+ }
+
+ return NULL;
+}
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 97b99fde5..17c629544 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -1,2394 +1,2401 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 1999-2009 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
- * 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.
- */
-
-
-/*
- * GL_EXT/ARB_framebuffer_object extensions
- *
- * Authors:
- * Brian Paul
- */
-
-
-#include "buffers.h"
-#include "context.h"
-#include "enums.h"
-#include "fbobject.h"
-#include "formats.h"
-#include "framebuffer.h"
-#include "hash.h"
-#include "macros.h"
-#include "mfeatures.h"
-#include "mtypes.h"
-#include "renderbuffer.h"
-#include "state.h"
-#include "teximage.h"
-#include "texobj.h"
-
-
-/** Set this to 1 to help debug FBO incompleteness problems */
-#define DEBUG_FBO 0
-
-/** Set this to 1 to debug/log glBlitFramebuffer() calls */
-#define DEBUG_BLIT 0
-
-
-/**
- * Notes:
- *
- * None of the GL_EXT_framebuffer_object functions are compiled into
- * display lists.
- */
-
-
-
-/*
- * When glGenRender/FramebuffersEXT() is called we insert pointers to
- * these placeholder objects into the hash table.
- * Later, when the object ID is first bound, we replace the placeholder
- * with the real frame/renderbuffer.
- */
-static struct gl_framebuffer DummyFramebuffer;
-static struct gl_renderbuffer DummyRenderbuffer;
-
-/* We bind this framebuffer when applications pass a NULL
- * drawable/surface in make current. */
-static struct gl_framebuffer IncompleteFramebuffer;
-
-
-#define IS_CUBE_FACE(TARGET) \
- ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \
- (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
-
-
-static void
-delete_dummy_renderbuffer(struct gl_renderbuffer *rb)
-{
- /* no op */
-}
-
-static void
-delete_dummy_framebuffer(struct gl_framebuffer *fb)
-{
- /* no op */
-}
-
-
-void
-_mesa_init_fbobjects(struct gl_context *ctx)
-{
- _glthread_INIT_MUTEX(DummyFramebuffer.Mutex);
- _glthread_INIT_MUTEX(DummyRenderbuffer.Mutex);
- _glthread_INIT_MUTEX(IncompleteFramebuffer.Mutex);
- DummyFramebuffer.Delete = delete_dummy_framebuffer;
- DummyRenderbuffer.Delete = delete_dummy_renderbuffer;
- IncompleteFramebuffer.Delete = delete_dummy_framebuffer;
-}
-
-struct gl_framebuffer *
-_mesa_get_incomplete_framebuffer(void)
-{
- return &IncompleteFramebuffer;
-}
-
-/**
- * Helper routine for getting a gl_renderbuffer.
- */
-struct gl_renderbuffer *
-_mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id)
-{
- struct gl_renderbuffer *rb;
-
- if (id == 0)
- return NULL;
-
- rb = (struct gl_renderbuffer *)
- _mesa_HashLookup(ctx->Shared->RenderBuffers, id);
- return rb;
-}
-
-
-/**
- * Helper routine for getting a gl_framebuffer.
- */
-struct gl_framebuffer *
-_mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id)
-{
- struct gl_framebuffer *fb;
-
- if (id == 0)
- return NULL;
-
- fb = (struct gl_framebuffer *)
- _mesa_HashLookup(ctx->Shared->FrameBuffers, id);
- return fb;
-}
-
-
-/**
- * Mark the given framebuffer as invalid. This will force the
- * test for framebuffer completeness to be done before the framebuffer
- * is used.
- */
-static void
-invalidate_framebuffer(struct gl_framebuffer *fb)
-{
- fb->_Status = 0; /* "indeterminate" */
-}
-
-
-/**
- * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
- * gl_renderbuffer_attachment object.
- * This function is only used for user-created FB objects, not the
- * default / window-system FB object.
- * If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to
- * the depth buffer attachment point.
- */
-struct gl_renderbuffer_attachment *
-_mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
- GLenum attachment)
-{
- GLuint i;
-
- assert(fb->Name > 0);
-
- switch (attachment) {
- case GL_COLOR_ATTACHMENT0_EXT:
- case GL_COLOR_ATTACHMENT1_EXT:
- case GL_COLOR_ATTACHMENT2_EXT:
- case GL_COLOR_ATTACHMENT3_EXT:
- case GL_COLOR_ATTACHMENT4_EXT:
- case GL_COLOR_ATTACHMENT5_EXT:
- case GL_COLOR_ATTACHMENT6_EXT:
- case GL_COLOR_ATTACHMENT7_EXT:
- case GL_COLOR_ATTACHMENT8_EXT:
- case GL_COLOR_ATTACHMENT9_EXT:
- case GL_COLOR_ATTACHMENT10_EXT:
- case GL_COLOR_ATTACHMENT11_EXT:
- case GL_COLOR_ATTACHMENT12_EXT:
- case GL_COLOR_ATTACHMENT13_EXT:
- case GL_COLOR_ATTACHMENT14_EXT:
- case GL_COLOR_ATTACHMENT15_EXT:
- i = attachment - GL_COLOR_ATTACHMENT0_EXT;
- if (i >= ctx->Const.MaxColorAttachments) {
- return NULL;
- }
- return &fb->Attachment[BUFFER_COLOR0 + i];
- case GL_DEPTH_STENCIL_ATTACHMENT:
- /* fall-through */
- case GL_DEPTH_BUFFER:
- /* fall-through / new in GL 3.0 */
- case GL_DEPTH_ATTACHMENT_EXT:
- return &fb->Attachment[BUFFER_DEPTH];
- case GL_STENCIL_BUFFER:
- /* fall-through / new in GL 3.0 */
- case GL_STENCIL_ATTACHMENT_EXT:
- return &fb->Attachment[BUFFER_STENCIL];
- default:
- return NULL;
- }
-}
-
-
-/**
- * As above, but only used for getting attachments of the default /
- * window-system framebuffer (not user-created framebuffer objects).
- */
-static struct gl_renderbuffer_attachment *
-_mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
- GLenum attachment)
-{
- assert(fb->Name == 0);
-
- switch (attachment) {
- case GL_FRONT_LEFT:
- return &fb->Attachment[BUFFER_FRONT_LEFT];
- case GL_FRONT_RIGHT:
- return &fb->Attachment[BUFFER_FRONT_RIGHT];
- case GL_BACK_LEFT:
- return &fb->Attachment[BUFFER_BACK_LEFT];
- case GL_BACK_RIGHT:
- return &fb->Attachment[BUFFER_BACK_RIGHT];
- case GL_AUX0:
- if (fb->Visual.numAuxBuffers == 1) {
- return &fb->Attachment[BUFFER_AUX0];
- }
- return NULL;
- case GL_DEPTH_BUFFER:
- /* fall-through / new in GL 3.0 */
- case GL_DEPTH_ATTACHMENT_EXT:
- return &fb->Attachment[BUFFER_DEPTH];
- case GL_STENCIL_BUFFER:
- /* fall-through / new in GL 3.0 */
- case GL_STENCIL_ATTACHMENT_EXT:
- return &fb->Attachment[BUFFER_STENCIL];
- default:
- return NULL;
- }
-}
-
-
-
-/**
- * Remove any texture or renderbuffer attached to the given attachment
- * point. Update reference counts, etc.
- */
-void
-_mesa_remove_attachment(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att)
-{
- if (att->Type == GL_TEXTURE) {
- ASSERT(att->Texture);
- if (ctx->Driver.FinishRenderTexture) {
- /* tell driver that we're done rendering to this texture. */
- ctx->Driver.FinishRenderTexture(ctx, att);
- }
- _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
- ASSERT(!att->Texture);
- }
- if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
- ASSERT(!att->Texture);
- _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
- ASSERT(!att->Renderbuffer);
- }
- att->Type = GL_NONE;
- att->Complete = GL_TRUE;
-}
-
-
-/**
- * Bind a texture object to an attachment point.
- * The previous binding, if any, will be removed first.
- */
-void
-_mesa_set_texture_attachment(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer_attachment *att,
- struct gl_texture_object *texObj,
- GLenum texTarget, GLuint level, GLuint zoffset)
-{
- if (att->Texture == texObj) {
- /* re-attaching same texture */
- ASSERT(att->Type == GL_TEXTURE);
- if (ctx->Driver.FinishRenderTexture)
- ctx->Driver.FinishRenderTexture(ctx, att);
- }
- else {
- /* new attachment */
- if (ctx->Driver.FinishRenderTexture && att->Texture)
- ctx->Driver.FinishRenderTexture(ctx, att);
- _mesa_remove_attachment(ctx, att);
- att->Type = GL_TEXTURE;
- assert(!att->Texture);
- _mesa_reference_texobj(&att->Texture, texObj);
- }
-
- /* always update these fields */
- att->TextureLevel = level;
- att->CubeMapFace = _mesa_tex_target_to_face(texTarget);
- att->Zoffset = zoffset;
- att->Complete = GL_FALSE;
-
- if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
- ctx->Driver.RenderTexture(ctx, fb, att);
- }
-
- invalidate_framebuffer(fb);
-}
-
-
-/**
- * Bind a renderbuffer to an attachment point.
- * The previous binding, if any, will be removed first.
- */
-void
-_mesa_set_renderbuffer_attachment(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att,
- struct gl_renderbuffer *rb)
-{
- /* XXX check if re-doing same attachment, exit early */
- _mesa_remove_attachment(ctx, att);
- att->Type = GL_RENDERBUFFER_EXT;
- att->Texture = NULL; /* just to be safe */
- att->Complete = GL_FALSE;
- _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
-}
-
-
-/**
- * Fallback for ctx->Driver.FramebufferRenderbuffer()
- * Attach a renderbuffer object to a framebuffer object.
- */
-void
-_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- GLenum attachment, struct gl_renderbuffer *rb)
-{
- struct gl_renderbuffer_attachment *att;
-
- _glthread_LOCK_MUTEX(fb->Mutex);
-
- att = _mesa_get_attachment(ctx, fb, attachment);
- ASSERT(att);
- if (rb) {
- _mesa_set_renderbuffer_attachment(ctx, att, rb);
- if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
- /* do stencil attachment here (depth already done above) */
- att = _mesa_get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT);
- assert(att);
- _mesa_set_renderbuffer_attachment(ctx, att, rb);
- }
- }
- else {
- _mesa_remove_attachment(ctx, att);
- }
-
- invalidate_framebuffer(fb);
-
- _glthread_UNLOCK_MUTEX(fb->Mutex);
-}
-
-
-/**
- * For debug only.
- */
-static void
-att_incomplete(const char *msg)
-{
-#if DEBUG_FBO
- _mesa_debug(NULL, "attachment incomplete: %s\n", msg);
-#else
- (void) msg;
-#endif
-}
-
-
-/**
- * For debug only.
- */
-static void
-fbo_incomplete(const char *msg, int index)
-{
-#if DEBUG_FBO
- _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
-#else
- (void) msg;
- (void) index;
-#endif
-}
-
-
-/**
- * Is the given base format a legal format for a color renderbuffer?
- */
-GLboolean
-_mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat)
-{
- switch (baseFormat) {
- case GL_RGB:
- case GL_RGBA:
- return GL_TRUE;
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- case GL_ALPHA:
- return ctx->Extensions.ARB_framebuffer_object;
- case GL_RED:
- case GL_RG:
- return ctx->Extensions.ARB_texture_rg;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Is the given base format a legal format for a depth/stencil renderbuffer?
- */
-static GLboolean
-is_legal_depth_format(const struct gl_context *ctx, GLenum baseFormat)
-{
- switch (baseFormat) {
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_STENCIL_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if an attachment point is complete and update its Complete field.
- * \param format if GL_COLOR, this is a color attachment point,
- * if GL_DEPTH, this is a depth component attachment point,
- * if GL_STENCIL, this is a stencil component attachment point.
- */
-static void
-test_attachment_completeness(const struct gl_context *ctx, GLenum format,
- struct gl_renderbuffer_attachment *att)
-{
- assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);
-
- /* assume complete */
- att->Complete = GL_TRUE;
-
- /* Look for reasons why the attachment might be incomplete */
- if (att->Type == GL_TEXTURE) {
- const struct gl_texture_object *texObj = att->Texture;
- struct gl_texture_image *texImage;
- GLenum baseFormat;
-
- if (!texObj) {
- att_incomplete("no texobj");
- att->Complete = GL_FALSE;
- return;
- }
-
- texImage = texObj->Image[att->CubeMapFace][att->TextureLevel];
- if (!texImage) {
- att_incomplete("no teximage");
- att->Complete = GL_FALSE;
- return;
- }
- if (texImage->Width < 1 || texImage->Height < 1) {
- att_incomplete("teximage width/height=0");
- printf("texobj = %u\n", texObj->Name);
- printf("level = %d\n", att->TextureLevel);
- att->Complete = GL_FALSE;
- return;
- }
- if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) {
- att_incomplete("bad z offset");
- att->Complete = GL_FALSE;
- return;
- }
-
- baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
-
- if (format == GL_COLOR) {
- if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
- att_incomplete("bad format");
- att->Complete = GL_FALSE;
- return;
- }
- if (_mesa_is_format_compressed(texImage->TexFormat)) {
- att_incomplete("compressed internalformat");
- att->Complete = GL_FALSE;
- return;
- }
- }
- else if (format == GL_DEPTH) {
- if (baseFormat == GL_DEPTH_COMPONENT) {
- /* OK */
- }
- else if (ctx->Extensions.EXT_packed_depth_stencil &&
- ctx->Extensions.ARB_depth_texture &&
- baseFormat == GL_DEPTH_STENCIL_EXT) {
- /* OK */
- }
- else {
- att->Complete = GL_FALSE;
- att_incomplete("bad depth format");
- return;
- }
- }
- else {
- ASSERT(format == GL_STENCIL);
- if (ctx->Extensions.EXT_packed_depth_stencil &&
- ctx->Extensions.ARB_depth_texture &&
- baseFormat == GL_DEPTH_STENCIL_EXT) {
- /* OK */
- }
- else {
- /* no such thing as stencil-only textures */
- att_incomplete("illegal stencil texture");
- att->Complete = GL_FALSE;
- return;
- }
- }
- }
- else if (att->Type == GL_RENDERBUFFER_EXT) {
- const GLenum baseFormat =
- _mesa_get_format_base_format(att->Renderbuffer->Format);
-
- ASSERT(att->Renderbuffer);
- if (!att->Renderbuffer->InternalFormat ||
- att->Renderbuffer->Width < 1 ||
- att->Renderbuffer->Height < 1) {
- att_incomplete("0x0 renderbuffer");
- att->Complete = GL_FALSE;
- return;
- }
- if (format == GL_COLOR) {
- if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
- att_incomplete("bad renderbuffer color format");
- att->Complete = GL_FALSE;
- return;
- }
- }
- else if (format == GL_DEPTH) {
- if (baseFormat == GL_DEPTH_COMPONENT) {
- /* OK */
- }
- else if (ctx->Extensions.EXT_packed_depth_stencil &&
- baseFormat == GL_DEPTH_STENCIL_EXT) {
- /* OK */
- }
- else {
- att_incomplete("bad renderbuffer depth format");
- att->Complete = GL_FALSE;
- return;
- }
- }
- else {
- assert(format == GL_STENCIL);
- if (baseFormat == GL_STENCIL_INDEX) {
- /* OK */
- }
- else if (ctx->Extensions.EXT_packed_depth_stencil &&
- baseFormat == GL_DEPTH_STENCIL_EXT) {
- /* OK */
- }
- else {
- att->Complete = GL_FALSE;
- att_incomplete("bad renderbuffer stencil format");
- return;
- }
- }
- }
- else {
- ASSERT(att->Type == GL_NONE);
- /* complete */
- return;
- }
-}
-
-
-/**
- * Test if the given framebuffer object is complete and update its
- * Status field with the results.
- * Calls the ctx->Driver.ValidateFramebuffer() function to allow the
- * driver to make hardware-specific validation/completeness checks.
- * Also update the framebuffer's Width and Height fields if the
- * framebuffer is complete.
- */
-void
-_mesa_test_framebuffer_completeness(struct gl_context *ctx,
- struct gl_framebuffer *fb)
-{
- GLuint numImages;
- GLenum intFormat = GL_NONE; /* color buffers' internal format */
- GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
- GLint numSamples = -1;
- GLint i;
- GLuint j;
-
- assert(fb->Name != 0);
-
- numImages = 0;
- fb->Width = 0;
- fb->Height = 0;
-
- /* Start at -2 to more easily loop over all attachment points.
- * -2: depth buffer
- * -1: stencil buffer
- * >=0: color buffer
- */
- for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
- struct gl_renderbuffer_attachment *att;
- GLenum f;
- gl_format mesaFormat;
-
- /*
- * XXX for ARB_fbo, only check color buffers that are named by
- * GL_READ_BUFFER and GL_DRAW_BUFFERi.
- */
-
- /* check for attachment completeness
- */
- if (i == -2) {
- att = &fb->Attachment[BUFFER_DEPTH];
- test_attachment_completeness(ctx, GL_DEPTH, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- fbo_incomplete("depth attachment incomplete", -1);
- return;
- }
- }
- else if (i == -1) {
- att = &fb->Attachment[BUFFER_STENCIL];
- test_attachment_completeness(ctx, GL_STENCIL, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- fbo_incomplete("stencil attachment incomplete", -1);
- return;
- }
- }
- else {
- att = &fb->Attachment[BUFFER_COLOR0 + i];
- test_attachment_completeness(ctx, GL_COLOR, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- fbo_incomplete("color attachment incomplete", i);
- return;
- }
- }
-
- /* get width, height, format of the renderbuffer/texture
- */
- if (att->Type == GL_TEXTURE) {
- const struct gl_texture_image *texImg
- = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
- minWidth = MIN2(minWidth, texImg->Width);
- maxWidth = MAX2(maxWidth, texImg->Width);
- minHeight = MIN2(minHeight, texImg->Height);
- maxHeight = MAX2(maxHeight, texImg->Height);
- f = texImg->_BaseFormat;
- mesaFormat = texImg->TexFormat;
- numImages++;
- if (!_mesa_is_legal_color_format(ctx, f) &&
- !is_legal_depth_format(ctx, f)) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
- fbo_incomplete("texture attachment incomplete", -1);
- return;
- }
- }
- else if (att->Type == GL_RENDERBUFFER_EXT) {
- minWidth = MIN2(minWidth, att->Renderbuffer->Width);
- maxWidth = MAX2(minWidth, att->Renderbuffer->Width);
- minHeight = MIN2(minHeight, att->Renderbuffer->Height);
- maxHeight = MAX2(minHeight, att->Renderbuffer->Height);
- f = att->Renderbuffer->InternalFormat;
- mesaFormat = att->Renderbuffer->Format;
- numImages++;
- }
- else {
- assert(att->Type == GL_NONE);
- continue;
- }
-
- if (numSamples < 0) {
- /* first buffer */
- numSamples = att->Renderbuffer->NumSamples;
- }
-
- /* check if integer color */
- fb->_IntegerColor = _mesa_is_format_integer_color(mesaFormat);
-
- /* Error-check width, height, format, samples
- */
- if (numImages == 1) {
- /* save format, num samples */
- if (i >= 0) {
- intFormat = f;
- }
- }
- else {
- if (!ctx->Extensions.ARB_framebuffer_object) {
- /* check that width, height, format are same */
- if (minWidth != maxWidth || minHeight != maxHeight) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
- fbo_incomplete("width or height mismatch", -1);
- return;
- }
- /* check that all color buffer have same format */
- if (intFormat != GL_NONE && f != intFormat) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
- fbo_incomplete("format mismatch", -1);
- return;
- }
- }
- if (att->Renderbuffer &&
- att->Renderbuffer->NumSamples != numSamples) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
- fbo_incomplete("inconsistant number of samples", i);
- return;
- }
-
- }
- }
-
-#if FEATURE_GL
- if (ctx->API == API_OPENGL) {
- /* Check that all DrawBuffers are present */
- for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) {
- if (fb->ColorDrawBuffer[j] != GL_NONE) {
- const struct gl_renderbuffer_attachment *att
- = _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer[j]);
- assert(att);
- if (att->Type == GL_NONE) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
- fbo_incomplete("missing drawbuffer", j);
- return;
- }
- }
- }
-
- /* Check that the ReadBuffer is present */
- if (fb->ColorReadBuffer != GL_NONE) {
- const struct gl_renderbuffer_attachment *att
- = _mesa_get_attachment(ctx, fb, fb->ColorReadBuffer);
- assert(att);
- if (att->Type == GL_NONE) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
- fbo_incomplete("missing readbuffer", -1);
- return;
- }
- }
- }
-#else
- (void) j;
-#endif
-
- if (numImages == 0) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
- fbo_incomplete("no attachments", -1);
- return;
- }
-
- /* Provisionally set status = COMPLETE ... */
- fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
-
- /* ... but the driver may say the FB is incomplete.
- * Drivers will most likely set the status to GL_FRAMEBUFFER_UNSUPPORTED
- * if anything.
- */
- if (ctx->Driver.ValidateFramebuffer) {
- ctx->Driver.ValidateFramebuffer(ctx, fb);
- if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- fbo_incomplete("driver marked FBO as incomplete", -1);
- }
- }
-
- if (fb->_Status == GL_FRAMEBUFFER_COMPLETE_EXT) {
- /*
- * Note that if ARB_framebuffer_object is supported and the attached
- * renderbuffers/textures are different sizes, the framebuffer
- * width/height will be set to the smallest width/height.
- */
- fb->Width = minWidth;
- fb->Height = minHeight;
-
- /* finally, update the visual info for the framebuffer */
- _mesa_update_framebuffer_visual(ctx, fb);
- }
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsRenderbufferEXT(GLuint renderbuffer)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (renderbuffer) {
- struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
- if (rb != NULL && rb != &DummyRenderbuffer)
- return GL_TRUE;
- }
- return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
-{
- struct gl_renderbuffer *newRb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)");
- return;
- }
-
- /* No need to flush here since the render buffer binding has no
- * effect on rendering state.
- */
-
- if (renderbuffer) {
- newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
- if (newRb == &DummyRenderbuffer) {
- /* ID was reserved, but no real renderbuffer object made yet */
- newRb = NULL;
- }
- else if (!newRb && ctx->Extensions.ARB_framebuffer_object) {
- /* All RB IDs must be Gen'd */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBindRenderbuffer(buffer)");
- return;
- }
-
- if (!newRb) {
- /* create new renderbuffer object */
- newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
- if (!newRb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
- return;
- }
- ASSERT(newRb->AllocStorage);
- _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
- newRb->RefCount = 1; /* referenced by hash table */
- }
- }
- else {
- newRb = NULL;
- }
-
- ASSERT(newRb != &DummyRenderbuffer);
-
- _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
-}
-
-
-/**
- * If the given renderbuffer is anywhere attached to the framebuffer, detach
- * the renderbuffer.
- * This is used when a renderbuffer object is deleted.
- * The spec calls for unbinding.
- */
-static void
-detach_renderbuffer(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer *rb)
-{
- GLuint i;
- for (i = 0; i < BUFFER_COUNT; i++) {
- if (fb->Attachment[i].Renderbuffer == rb) {
- _mesa_remove_attachment(ctx, &fb->Attachment[i]);
- }
- }
- invalidate_framebuffer(fb);
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
-{
- GLint i;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- for (i = 0; i < n; i++) {
- if (renderbuffers[i] > 0) {
- struct gl_renderbuffer *rb;
- rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
- if (rb) {
- /* check if deleting currently bound renderbuffer object */
- if (rb == ctx->CurrentRenderbuffer) {
- /* bind default */
- ASSERT(rb->RefCount >= 2);
- _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
- }
-
- if (ctx->DrawBuffer->Name) {
- detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
- }
- if (ctx->ReadBuffer->Name && ctx->ReadBuffer != ctx->DrawBuffer) {
- detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
- }
-
- /* Remove from hash table immediately, to free the ID.
- * But the object will not be freed until it's no longer
- * referenced anywhere else.
- */
- _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
-
- if (rb != &DummyRenderbuffer) {
- /* no longer referenced by hash table */
- _mesa_reference_renderbuffer(&rb, NULL);
- }
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLuint first;
- GLint i;
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
- return;
- }
-
- if (!renderbuffers)
- return;
-
- first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);
-
- for (i = 0; i < n; i++) {
- GLuint name = first + i;
- renderbuffers[i] = name;
- /* insert dummy placeholder into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- }
-}
-
-
-/**
- * Given an internal format token for a renderbuffer, return the
- * corresponding base format.
- */
-GLenum
-_mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
-{
- GLenum baseFormat;
-
- switch (internalFormat) {
- case GL_RGBA16_SNORM:
- /* This is used internally by Mesa for accum buffers. */
- return GL_RGBA;
- case GL_STENCIL_INDEX:
- case GL_STENCIL_INDEX1_EXT:
- case GL_STENCIL_INDEX4_EXT:
- case GL_STENCIL_INDEX8_EXT:
- case GL_STENCIL_INDEX16_EXT:
- /* This is not a valid texture internalFormat, but valid for
- * renderbuffers.
- */
- return GL_STENCIL_INDEX;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- /* This is an override of _mesa_base_tex_format's check that
- * ARB_depth_texture is present. We allow depth RBs without it.
- */
- return GL_DEPTH_COMPONENT;
- }
-
- baseFormat = _mesa_base_tex_format(ctx, internalFormat);
- if (baseFormat < 0)
- return 0;
-
- return baseFormat;
-}
-
-
-/** sentinal value, see below */
-#define NO_SAMPLES 1000
-
-
-/**
- * Helper function used by _mesa_RenderbufferStorageEXT() and
- * _mesa_RenderbufferStorageMultisample().
- * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorageEXT().
- */
-static void
-renderbuffer_storage(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei samples)
-{
- const char *func = samples == NO_SAMPLES ?
- "glRenderbufferStorage" : "RenderbufferStorageMultisample";
- struct gl_renderbuffer *rb;
- GLenum baseFormat;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
- return;
- }
-
- baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
- if (baseFormat == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat)", func);
- return;
- }
-
- if (baseFormat != GL_DEPTH_COMPONENT &&
- baseFormat != GL_STENCIL_INDEX &&
- baseFormat != GL_DEPTH_STENCIL &&
- !_mesa_is_legal_color_format(ctx, baseFormat)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat)", func);
- return;
- }
-
- if (width < 1 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(width)", func);
- return;
- }
-
- if (height < 1 || height > (GLsizei) ctx->Const.MaxRenderbufferSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(height)", func);
- return;
- }
-
- if (samples == NO_SAMPLES) {
- /* NumSamples == 0 indicates non-multisampling */
- samples = 0;
- }
- else if (samples > (GLsizei) ctx->Const.MaxSamples) {
- /* note: driver may choose to use more samples than what's requested */
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func);
- return;
- }
-
- rb = ctx->CurrentRenderbuffer;
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (rb->InternalFormat == internalFormat &&
- rb->Width == (GLuint) width &&
- rb->Height == (GLuint) height) {
- /* no change in allocation needed */
- return;
- }
-
- /* These MUST get set by the AllocStorage func */
- rb->Format = MESA_FORMAT_NONE;
- rb->NumSamples = samples;
-
- /* Now allocate the storage */
- ASSERT(rb->AllocStorage);
- if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
- /* No error - check/set fields now */
- assert(rb->Format != MESA_FORMAT_NONE);
- assert(rb->Width == (GLuint) width);
- assert(rb->Height == (GLuint) height);
- rb->InternalFormat = internalFormat;
- rb->_BaseFormat = baseFormat;
- assert(rb->_BaseFormat != 0);
- }
- else {
- /* Probably ran out of memory - clear the fields */
- rb->Width = 0;
- rb->Height = 0;
- rb->Format = MESA_FORMAT_NONE;
- rb->InternalFormat = GL_NONE;
- rb->_BaseFormat = GL_NONE;
- rb->NumSamples = 0;
- }
-
- /*
- test_framebuffer_completeness(ctx, fb);
- */
- /* XXX if this renderbuffer is attached anywhere, invalidate attachment
- * points???
- */
-}
-
-
-#if FEATURE_OES_EGL_image
-void GLAPIENTRY
-_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
-{
- struct gl_renderbuffer *rb;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (!ctx->Extensions.OES_EGL_image) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glEGLImageTargetRenderbufferStorageOES(unsupported)");
- return;
- }
-
- if (target != GL_RENDERBUFFER) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "EGLImageTargetRenderbufferStorageOES");
- return;
- }
-
- rb = ctx->CurrentRenderbuffer;
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "EGLImageTargetRenderbufferStorageOES");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- ctx->Driver.EGLImageTargetRenderbufferStorage(ctx, rb, image);
-}
-#endif
-
-
-/**
- * Helper function for _mesa_GetRenderbufferParameterivEXT() and
- * _mesa_GetFramebufferAttachmentParameterivEXT()
- * We have to be careful to respect the base format. For example, if a
- * renderbuffer/texture was created with internalFormat=GL_RGB but the
- * driver actually chose a GL_RGBA format, when the user queries ALPHA_SIZE
- * we need to return zero.
- */
-static GLint
-get_component_bits(GLenum pname, GLenum baseFormat, gl_format format)
-{
- switch (pname) {
- case GL_RENDERBUFFER_RED_SIZE_EXT:
- case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
- if (baseFormat == GL_RGB || baseFormat == GL_RGBA ||
- baseFormat == GL_RG || baseFormat == GL_RED)
- return _mesa_get_format_bits(format, pname);
- else
- return 0;
- case GL_RENDERBUFFER_GREEN_SIZE_EXT:
- case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
- if (baseFormat == GL_RGB || baseFormat == GL_RGBA || baseFormat == GL_RG)
- return _mesa_get_format_bits(format, pname);
- else
- return 0;
- case GL_RENDERBUFFER_BLUE_SIZE_EXT:
- case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
- if (baseFormat == GL_RGB || baseFormat == GL_RGBA)
- return _mesa_get_format_bits(format, pname);
- else
- return 0;
- case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
- case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
- if (baseFormat == GL_RGBA || baseFormat == GL_ALPHA ||
- baseFormat == GL_LUMINANCE_ALPHA)
- return _mesa_get_format_bits(format, pname);
- else
- return 0;
- case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
- case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
- if (baseFormat == GL_DEPTH_COMPONENT || baseFormat == GL_DEPTH_STENCIL)
- return _mesa_get_format_bits(format, pname);
- else
- return 0;
- case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
- case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
- if (baseFormat == GL_STENCIL_INDEX || baseFormat == GL_DEPTH_STENCIL)
- return _mesa_get_format_bits(format, pname);
- else
- return 0;
- default:
- return 0;
- }
-}
-
-
-
-void GLAPIENTRY
-_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- /* GL_ARB_fbo says calling this function is equivalent to calling
- * glRenderbufferStorageMultisample() with samples=0. We pass in
- * a token value here just for error reporting purposes.
- */
- renderbuffer_storage(target, internalFormat, width, height, NO_SAMPLES);
-}
-
-
-void GLAPIENTRY
-_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
- GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- renderbuffer_storage(target, internalFormat, width, height, samples);
-}
-
-
-/**
- * OpenGL ES version of glRenderBufferStorage.
- */
-void GLAPIENTRY
-_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- switch (internalFormat) {
- case GL_RGB565:
- /* XXX this confuses GL_RENDERBUFFER_INTERNAL_FORMAT_OES */
- /* choose a closest format */
- internalFormat = GL_RGB5;
- break;
- default:
- break;
- }
-
- renderbuffer_storage(target, internalFormat, width, height, 0);
-}
-
-
-void GLAPIENTRY
-_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
-{
- struct gl_renderbuffer *rb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetRenderbufferParameterivEXT(target)");
- return;
- }
-
- rb = ctx->CurrentRenderbuffer;
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetRenderbufferParameterivEXT");
- return;
- }
-
- /* No need to flush here since we're just quering state which is
- * not effected by rendering.
- */
-
- switch (pname) {
- case GL_RENDERBUFFER_WIDTH_EXT:
- *params = rb->Width;
- return;
- case GL_RENDERBUFFER_HEIGHT_EXT:
- *params = rb->Height;
- return;
- case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
- *params = rb->InternalFormat;
- return;
- case GL_RENDERBUFFER_RED_SIZE_EXT:
- case GL_RENDERBUFFER_GREEN_SIZE_EXT:
- case GL_RENDERBUFFER_BLUE_SIZE_EXT:
- case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
- case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
- case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
- *params = get_component_bits(pname, rb->_BaseFormat, rb->Format);
- break;
- case GL_RENDERBUFFER_SAMPLES:
- if (ctx->Extensions.ARB_framebuffer_object) {
- *params = rb->NumSamples;
- break;
- }
- /* fallthrough */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetRenderbufferParameterivEXT(target)");
- return;
- }
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsFramebufferEXT(GLuint framebuffer)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (framebuffer) {
- struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer);
- if (rb != NULL && rb != &DummyFramebuffer)
- return GL_TRUE;
- }
- return GL_FALSE;
-}
-
-
-/**
- * Check if any of the attachments of the given framebuffer are textures
- * (render to texture). Call ctx->Driver.RenderTexture() for such
- * attachments.
- */
-static void
-check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
-{
- GLuint i;
- ASSERT(ctx->Driver.RenderTexture);
-
- if (fb->Name == 0)
- return; /* can't render to texture with winsys framebuffers */
-
- for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att = fb->Attachment + i;
- struct gl_texture_object *texObj = att->Texture;
- if (texObj
- && texObj->Image[att->CubeMapFace][att->TextureLevel]) {
- ctx->Driver.RenderTexture(ctx, fb, att);
- }
- }
-}
-
-
-/**
- * Examine all the framebuffer's attachments to see if any are textures.
- * If so, call ctx->Driver.FinishRenderTexture() for each texture to
- * notify the device driver that the texture image may have changed.
- */
-static void
-check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
-{
- if (fb->Name == 0)
- return; /* can't render to texture with winsys framebuffers */
-
- if (ctx->Driver.FinishRenderTexture) {
- GLuint i;
- for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att = fb->Attachment + i;
- if (att->Texture && att->Renderbuffer) {
- ctx->Driver.FinishRenderTexture(ctx, att);
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
-{
- struct gl_framebuffer *newDrawFb, *newReadFb;
- struct gl_framebuffer *oldDrawFb, *oldReadFb;
- GLboolean bindReadBuf, bindDrawBuf;
- GET_CURRENT_CONTEXT(ctx);
-
-#ifdef DEBUG
- if (ctx->Extensions.ARB_framebuffer_object) {
- ASSERT(ctx->Extensions.EXT_framebuffer_object);
- ASSERT(ctx->Extensions.EXT_framebuffer_blit);
- }
-#endif
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (!ctx->Extensions.EXT_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBindFramebufferEXT(unsupported)");
- return;
- }
-
- switch (target) {
-#if FEATURE_EXT_framebuffer_blit
- case GL_DRAW_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
- return;
- }
- bindDrawBuf = GL_TRUE;
- bindReadBuf = GL_FALSE;
- break;
- case GL_READ_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
- return;
- }
- bindDrawBuf = GL_FALSE;
- bindReadBuf = GL_TRUE;
- break;
-#endif
- case GL_FRAMEBUFFER_EXT:
- bindDrawBuf = GL_TRUE;
- bindReadBuf = GL_TRUE;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
- return;
- }
-
- if (framebuffer) {
- /* Binding a user-created framebuffer object */
- newDrawFb = _mesa_lookup_framebuffer(ctx, framebuffer);
- if (newDrawFb == &DummyFramebuffer) {
- /* ID was reserved, but no real framebuffer object made yet */
- newDrawFb = NULL;
- }
- else if (!newDrawFb && ctx->Extensions.ARB_framebuffer_object) {
- /* All FBO IDs must be Gen'd */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebuffer(buffer)");
- return;
- }
-
- if (!newDrawFb) {
- /* create new framebuffer object */
- newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
- if (!newDrawFb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
- return;
- }
- _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb);
- }
- newReadFb = newDrawFb;
- }
- else {
- /* Binding the window system framebuffer (which was originally set
- * with MakeCurrent).
- */
- newDrawFb = ctx->WinSysDrawBuffer;
- newReadFb = ctx->WinSysReadBuffer;
- }
-
- ASSERT(newDrawFb);
- ASSERT(newDrawFb != &DummyFramebuffer);
-
- /* save pointers to current/old framebuffers */
- oldDrawFb = ctx->DrawBuffer;
- oldReadFb = ctx->ReadBuffer;
-
- /* check if really changing bindings */
- if (oldDrawFb == newDrawFb)
- bindDrawBuf = GL_FALSE;
- if (oldReadFb == newReadFb)
- bindReadBuf = GL_FALSE;
-
- /*
- * OK, now bind the new Draw/Read framebuffers, if they're changing.
- *
- * We also check if we're beginning and/or ending render-to-texture.
- * When a framebuffer with texture attachments is unbound, call
- * ctx->Driver.FinishRenderTexture().
- * When a framebuffer with texture attachments is bound, call
- * ctx->Driver.RenderTexture().
- *
- * Note that if the ReadBuffer has texture attachments we don't consider
- * that a render-to-texture case.
- */
- if (bindReadBuf) {
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- /* check if old readbuffer was render-to-texture */
- check_end_texture_render(ctx, oldReadFb);
-
- _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb);
- }
-
- if (bindDrawBuf) {
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- /* check if old read/draw buffers were render-to-texture */
- if (!bindReadBuf)
- check_end_texture_render(ctx, oldReadFb);
-
- if (oldDrawFb != oldReadFb)
- check_end_texture_render(ctx, oldDrawFb);
-
- /* check if newly bound framebuffer has any texture attachments */
- check_begin_texture_render(ctx, newDrawFb);
-
- _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb);
- }
-
- if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) {
- ctx->Driver.BindFramebuffer(ctx, target, newDrawFb, newReadFb);
- }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
-{
- GLint i;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- for (i = 0; i < n; i++) {
- if (framebuffers[i] > 0) {
- struct gl_framebuffer *fb;
- fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
- if (fb) {
- ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
-
- /* check if deleting currently bound framebuffer object */
- if (ctx->Extensions.EXT_framebuffer_blit) {
- /* separate draw/read binding points */
- if (fb == ctx->DrawBuffer) {
- /* bind default */
- ASSERT(fb->RefCount >= 2);
- _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
- }
- if (fb == ctx->ReadBuffer) {
- /* bind default */
- ASSERT(fb->RefCount >= 2);
- _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
- }
- }
- else {
- /* only one binding point for read/draw buffers */
- if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) {
- /* bind default */
- ASSERT(fb->RefCount >= 2);
- _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
- }
-
- /* remove from hash table immediately, to free the ID */
- _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
-
- if (fb != &DummyFramebuffer) {
- /* But the object will not be freed until it's no longer
- * bound in any context.
- */
- _mesa_reference_framebuffer(&fb, NULL);
- }
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLuint first;
- GLint i;
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
- return;
- }
-
- if (!framebuffers)
- return;
-
- first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);
-
- for (i = 0; i < n; i++) {
- GLuint name = first + i;
- framebuffers[i] = name;
- /* insert dummy placeholder into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- }
-}
-
-
-
-GLenum GLAPIENTRY
-_mesa_CheckFramebufferStatusEXT(GLenum target)
-{
- struct gl_framebuffer *buffer;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
-
- switch (target) {
-#if FEATURE_EXT_framebuffer_blit
- case GL_DRAW_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
- return 0;
- }
- buffer = ctx->DrawBuffer;
- break;
- case GL_READ_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
- return 0;
- }
- buffer = ctx->ReadBuffer;
- break;
-#endif
- case GL_FRAMEBUFFER_EXT:
- buffer = ctx->DrawBuffer;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
- return 0; /* formerly GL_FRAMEBUFFER_STATUS_ERROR_EXT */
- }
-
- if (buffer->Name == 0) {
- /* The window system / default framebuffer is always complete */
- return GL_FRAMEBUFFER_COMPLETE_EXT;
- }
-
- /* No need to flush here */
-
- if (buffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
- _mesa_test_framebuffer_completeness(ctx, buffer);
- }
-
- return buffer->_Status;
-}
-
-
-
-/**
- * Common code called by glFramebufferTexture1D/2D/3DEXT().
- */
-static void
-framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
- GLenum attachment, GLenum textarget, GLuint texture,
- GLint level, GLint zoffset)
-{
- struct gl_renderbuffer_attachment *att;
- struct gl_texture_object *texObj = NULL;
- struct gl_framebuffer *fb;
- GLboolean error = GL_FALSE;
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- switch (target) {
- case GL_READ_FRAMEBUFFER_EXT:
- error = !ctx->Extensions.EXT_framebuffer_blit;
- fb = ctx->ReadBuffer;
- break;
- case GL_DRAW_FRAMEBUFFER_EXT:
- error = !ctx->Extensions.EXT_framebuffer_blit;
- /* fall-through */
- case GL_FRAMEBUFFER_EXT:
- fb = ctx->DrawBuffer;
- break;
- default:
- error = GL_TRUE;
- }
-
- if (error) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture%sEXT(target=0x%x)", caller, target);
- return;
- }
-
- ASSERT(fb);
-
- /* check framebuffer binding */
- if (fb->Name == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%sEXT", caller);
- return;
- }
-
-
- /* The textarget, level, and zoffset parameters are only validated if
- * texture is non-zero.
- */
- if (texture) {
- GLboolean err = GL_TRUE;
-
- texObj = _mesa_lookup_texture(ctx, texture);
- if (texObj != NULL) {
- if (textarget == 0) {
- /* XXX what's the purpose of this? */
- err = (texObj->Target != GL_TEXTURE_3D) &&
- (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
- (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT);
- }
- else {
- err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
- ? !IS_CUBE_FACE(textarget)
- : (texObj->Target != textarget);
- }
- }
- else {
- /* can't render to a non-existant texture */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%sEXT(non existant texture)",
- caller);
- return;
- }
-
- if (err) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%sEXT(texture target mismatch)",
- caller);
- return;
- }
-
- if (texObj->Target == GL_TEXTURE_3D) {
- const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
- if (zoffset < 0 || zoffset >= maxSize) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%sEXT(zoffset)", caller);
- return;
- }
- }
- else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
- (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
- if (zoffset < 0 || zoffset >= ctx->Const.MaxArrayTextureLayers) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%sEXT(layer)", caller);
- return;
- }
- }
-
- if ((level < 0) ||
- (level >= _mesa_max_texture_levels(ctx, texObj->Target))) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%sEXT(level)", caller);
- return;
- }
- }
-
- att = _mesa_get_attachment(ctx, fb, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture%sEXT(attachment)", caller);
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- _glthread_LOCK_MUTEX(fb->Mutex);
- if (texObj) {
- _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
- level, zoffset);
- /* Set the render-to-texture flag. We'll check this flag in
- * glTexImage() and friends to determine if we need to revalidate
- * any FBOs that might be rendering into this texture.
- * This flag never gets cleared since it's non-trivial to determine
- * when all FBOs might be done rendering to this texture. That's OK
- * though since it's uncommon to render to a texture then repeatedly
- * call glTexImage() to change images in the texture.
- */
- texObj->_RenderToTexture = GL_TRUE;
- }
- else {
- _mesa_remove_attachment(ctx, att);
- }
-
- invalidate_framebuffer(fb);
-
- _glthread_UNLOCK_MUTEX(fb->Mutex);
-}
-
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if ((texture != 0) && (textarget != GL_TEXTURE_1D)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture1DEXT(textarget)");
- return;
- }
-
- framebuffer_texture(ctx, "1D", target, attachment, textarget, texture,
- level, 0);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if ((texture != 0) &&
- (textarget != GL_TEXTURE_2D) &&
- (textarget != GL_TEXTURE_RECTANGLE_ARB) &&
- (!IS_CUBE_FACE(textarget))) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture2DEXT(textarget=0x%x)", textarget);
- return;
- }
-
- framebuffer_texture(ctx, "2D", target, attachment, textarget, texture,
- level, 0);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture,
- GLint level, GLint zoffset)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if ((texture != 0) && (textarget != GL_TEXTURE_3D)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture3DEXT(textarget)");
- return;
- }
-
- framebuffer_texture(ctx, "3D", target, attachment, textarget, texture,
- level, zoffset);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferTextureLayerEXT(GLenum target, GLenum attachment,
- GLuint texture, GLint level, GLint layer)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- framebuffer_texture(ctx, "Layer", target, attachment, 0, texture,
- level, layer);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
- GLenum renderbufferTarget,
- GLuint renderbuffer)
-{
- struct gl_renderbuffer_attachment *att;
- struct gl_framebuffer *fb;
- struct gl_renderbuffer *rb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- switch (target) {
-#if FEATURE_EXT_framebuffer_blit
- case GL_DRAW_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(target)");
- return;
- }
- fb = ctx->DrawBuffer;
- break;
- case GL_READ_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(target)");
- return;
- }
- fb = ctx->ReadBuffer;
- break;
-#endif
- case GL_FRAMEBUFFER_EXT:
- fb = ctx->DrawBuffer;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(target)");
- return;
- }
-
- if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(renderbufferTarget)");
- return;
- }
-
- if (fb->Name == 0) {
- /* Can't attach new renderbuffers to a window system framebuffer */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
- return;
- }
-
- att = _mesa_get_attachment(ctx, fb, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(invalid attachment %s)",
- _mesa_lookup_enum_by_nr(attachment));
- return;
- }
-
- if (renderbuffer) {
- rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbufferEXT(non-existant"
- " renderbuffer %u)", renderbuffer);
- return;
- }
- else if (rb == &DummyRenderbuffer) {
- /* This is what NVIDIA does */
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferRenderbufferEXT(renderbuffer %u)",
- renderbuffer);
- return;
- }
- }
- else {
- /* remove renderbuffer attachment */
- rb = NULL;
- }
-
- if (attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
- rb && rb->Format != MESA_FORMAT_NONE) {
- /* make sure the renderbuffer is a depth/stencil format */
- const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
- if (baseFormat != GL_DEPTH_STENCIL) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbufferEXT(renderbuffer"
- " is not DEPTH_STENCIL format)");
- return;
- }
- }
-
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- assert(ctx->Driver.FramebufferRenderbuffer);
- ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb);
-
- /* Some subsequent GL commands may depend on the framebuffer's visual
- * after the binding is updated. Update visual info now.
- */
- _mesa_update_framebuffer_visual(ctx, fb);
-}
-
-
-void GLAPIENTRY
-_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
- GLenum pname, GLint *params)
-{
- const struct gl_renderbuffer_attachment *att;
- struct gl_framebuffer *buffer;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- switch (target) {
-#if FEATURE_EXT_framebuffer_blit
- case GL_DRAW_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(target)");
- return;
- }
- buffer = ctx->DrawBuffer;
- break;
- case GL_READ_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(target)");
- return;
- }
- buffer = ctx->ReadBuffer;
- break;
-#endif
- case GL_FRAMEBUFFER_EXT:
- buffer = ctx->DrawBuffer;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(target)");
- return;
- }
-
- if (buffer->Name == 0) {
- /* the default / window-system FBO */
- att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
- }
- else {
- /* user-created framebuffer FBO */
- att = _mesa_get_attachment(ctx, buffer, attachment);
- }
-
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(attachment)");
- return;
- }
-
- if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
- /* the depth and stencil attachments must point to the same buffer */
- const struct gl_renderbuffer_attachment *depthAtt, *stencilAtt;
- depthAtt = _mesa_get_attachment(ctx, buffer, GL_DEPTH_ATTACHMENT);
- stencilAtt = _mesa_get_attachment(ctx, buffer, GL_STENCIL_ATTACHMENT);
- if (depthAtt->Renderbuffer != stencilAtt->Renderbuffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameterivEXT(DEPTH/STENCIL"
- " attachments differ)");
- return;
- }
- }
-
- /* No need to flush here */
-
- switch (pname) {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
- *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type;
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
- if (att->Type == GL_RENDERBUFFER_EXT) {
- *params = att->Renderbuffer->Name;
- }
- else if (att->Type == GL_TEXTURE) {
- *params = att->Texture->Name;
- }
- else {
- assert(att->Type == GL_NONE);
- *params = 0;
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
- if (att->Type == GL_TEXTURE) {
- *params = att->TextureLevel;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
- if (att->Type == GL_TEXTURE) {
- if (att->Texture && att->Texture->Target == GL_TEXTURE_CUBE_MAP) {
- *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace;
- }
- else {
- *params = 0;
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
- if (att->Type == GL_TEXTURE) {
- if (att->Texture && att->Texture->Target == GL_TEXTURE_3D) {
- *params = att->Zoffset;
- }
- else {
- *params = 0;
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
- if (!ctx->Extensions.ARB_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else {
- *params = _mesa_get_format_color_encoding(att->Renderbuffer->Format);
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
- if (!ctx->Extensions.ARB_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- return;
- }
- else {
- gl_format format = att->Renderbuffer->Format;
- if (format == MESA_FORMAT_CI8 || format == MESA_FORMAT_S8) {
- /* special cases */
- *params = GL_INDEX;
- }
- else {
- *params = _mesa_get_format_datatype(format);
- }
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
- if (!ctx->Extensions.ARB_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else if (att->Texture) {
- const struct gl_texture_image *texImage =
- _mesa_select_tex_image(ctx, att->Texture, att->Texture->Target,
- att->TextureLevel);
- if (texImage) {
- *params = get_component_bits(pname, texImage->_BaseFormat,
- texImage->TexFormat);
- }
- else {
- *params = 0;
- }
- }
- else if (att->Renderbuffer) {
- *params = get_component_bits(pname, att->Renderbuffer->_BaseFormat,
- att->Renderbuffer->Format);
- }
- else {
- *params = 0;
- }
- return;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- return;
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenerateMipmapEXT(GLenum target)
-{
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_3D:
- case GL_TEXTURE_CUBE_MAP:
- /* OK, legal value */
- break;
- default:
- /* XXX need to implement GL_TEXTURE_1D_ARRAY and GL_TEXTURE_2D_ARRAY */
- _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- if (texObj->BaseLevel >= texObj->MaxLevel) {
- /* nothing to do */
- return;
- }
-
- if (texObj->Target == GL_TEXTURE_CUBE_MAP &&
- !_mesa_cube_complete(texObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGenerateMipmap(incomplete cube map)");
- return;
- }
-
- _mesa_lock_texture(ctx, texObj);
- if (target == GL_TEXTURE_CUBE_MAP) {
- GLuint face;
- for (face = 0; face < 6; face++)
- ctx->Driver.GenerateMipmap(ctx,
- GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face,
- texObj);
- }
- else {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
- _mesa_unlock_texture(ctx, texObj);
-}
-
-
-#if FEATURE_EXT_framebuffer_blit
-
-static const struct gl_renderbuffer_attachment *
-find_attachment(const struct gl_framebuffer *fb, const struct gl_renderbuffer *rb)
-{
- GLuint i;
- for (i = 0; i < Elements(fb->Attachment); i++) {
- if (fb->Attachment[i].Renderbuffer == rb)
- return &fb->Attachment[i];
- }
- return NULL;
-}
-
-
-
-/**
- * Blit rectangular region, optionally from one framebuffer to another.
- *
- * Note, if the src buffer is multisampled and the dest is not, this is
- * when the samples must be resolved to a single color.
- */
-void GLAPIENTRY
-_mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
- GL_DEPTH_BUFFER_BIT |
- GL_STENCIL_BUFFER_BIT);
- const struct gl_framebuffer *readFb, *drawFb;
- const struct gl_renderbuffer *colorReadRb, *colorDrawRb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (ctx->NewState) {
- _mesa_update_state(ctx);
- }
-
- readFb = ctx->ReadBuffer;
- drawFb = ctx->DrawBuffer;
-
- if (!readFb || !drawFb) {
- /* This will normally never happen but someday we may want to
- * support MakeCurrent() with no drawables.
- */
- return;
- }
-
- /* check for complete framebuffers */
- if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
- readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glBlitFramebufferEXT(incomplete draw/read buffers)");
- return;
- }
-
- if (filter != GL_NEAREST && filter != GL_LINEAR) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(filter)");
- return;
- }
-
- if (mask & ~legalMaskBits) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
- return;
- }
-
- /* depth/stencil must be blitted with nearest filtering */
- if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
- && filter != GL_NEAREST) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter");
- return;
- }
-
- /* get color read/draw renderbuffers */
- if (mask & GL_COLOR_BUFFER_BIT) {
- colorReadRb = readFb->_ColorReadBuffer;
- colorDrawRb = drawFb->_ColorDrawBuffers[0];
- }
- else {
- colorReadRb = colorDrawRb = NULL;
- }
-
- if (mask & GL_STENCIL_BUFFER_BIT) {
- struct gl_renderbuffer *readRb = readFb->_StencilBuffer;
- struct gl_renderbuffer *drawRb = drawFb->_StencilBuffer;
- if (!readRb ||
- !drawRb ||
- _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(stencil buffer size mismatch");
- return;
- }
- }
-
- if (mask & GL_DEPTH_BUFFER_BIT) {
- struct gl_renderbuffer *readRb = readFb->_DepthBuffer;
- struct gl_renderbuffer *drawRb = drawFb->_DepthBuffer;
- if (!readRb ||
- !drawRb ||
- _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(depth buffer size mismatch");
- return;
- }
- }
-
- if (readFb->Visual.samples > 0 &&
- drawFb->Visual.samples > 0 &&
- readFb->Visual.samples != drawFb->Visual.samples) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(mismatched samples");
- return;
- }
-
- /* extra checks for multisample copies... */
- if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
- /* src and dest region sizes must be the same */
- if (srcX1 - srcX0 != dstX1 - dstX0 ||
- srcY1 - srcY0 != dstY1 - dstY0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(bad src/dst multisample region sizes");
- return;
- }
-
- /* color formats must match */
- if (colorReadRb &&
- colorDrawRb &&
- colorReadRb->Format != colorDrawRb->Format) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(bad src/dst multisample pixel formats");
- return;
- }
- }
-
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT");
- return;
- }
-
- /* Debug code */
- if (DEBUG_BLIT) {
- printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d,"
- " 0x%x, 0x%x)\n",
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, filter);
- if (colorReadRb) {
- const struct gl_renderbuffer_attachment *att;
-
- att = find_attachment(readFb, colorReadRb);
- printf(" Src FBO %u RB %u (%dx%d) ",
- readFb->Name, colorReadRb->Name,
- colorReadRb->Width, colorReadRb->Height);
- if (att && att->Texture) {
- printf("Tex %u tgt 0x%x level %u face %u",
- att->Texture->Name,
- att->Texture->Target,
- att->TextureLevel,
- att->CubeMapFace);
- }
- printf("\n");
-
- att = find_attachment(drawFb, colorDrawRb);
- printf(" Dst FBO %u RB %u (%dx%d) ",
- drawFb->Name, colorDrawRb->Name,
- colorDrawRb->Width, colorDrawRb->Height);
- if (att && att->Texture) {
- printf("Tex %u tgt 0x%x level %u face %u",
- att->Texture->Name,
- att->Texture->Target,
- att->TextureLevel,
- att->CubeMapFace);
- }
- printf("\n");
- }
- }
-
- ASSERT(ctx->Driver.BlitFramebuffer);
- ctx->Driver.BlitFramebuffer(ctx,
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, filter);
-}
-#endif /* FEATURE_EXT_framebuffer_blit */
-
-#if FEATURE_ARB_geometry_shader4
-void GLAPIENTRY
-_mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
- GLuint texture, GLint level)
-{
- GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTextureARB "
- "not implemented!");
-}
-
-void GLAPIENTRY
-_mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
- GLuint texture, GLint level, GLenum face)
-{
- GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTextureFaceARB "
- "not implemented!");
-}
-#endif /* FEATURE_ARB_geometry_shader4 */
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2009 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
+ * 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.
+ */
+
+
+/*
+ * GL_EXT/ARB_framebuffer_object extensions
+ *
+ * Authors:
+ * Brian Paul
+ */
+
+
+#include "buffers.h"
+#include "context.h"
+#include "enums.h"
+#include "fbobject.h"
+#include "formats.h"
+#include "framebuffer.h"
+#include "hash.h"
+#include "macros.h"
+#include "mfeatures.h"
+#include "mtypes.h"
+#include "renderbuffer.h"
+#include "state.h"
+#include "teximage.h"
+#include "texobj.h"
+
+
+/** Set this to 1 to help debug FBO incompleteness problems */
+#define DEBUG_FBO 0
+
+/** Set this to 1 to debug/log glBlitFramebuffer() calls */
+#define DEBUG_BLIT 0
+
+
+/**
+ * Notes:
+ *
+ * None of the GL_EXT_framebuffer_object functions are compiled into
+ * display lists.
+ */
+
+
+
+/*
+ * When glGenRender/FramebuffersEXT() is called we insert pointers to
+ * these placeholder objects into the hash table.
+ * Later, when the object ID is first bound, we replace the placeholder
+ * with the real frame/renderbuffer.
+ */
+static struct gl_framebuffer DummyFramebuffer;
+static struct gl_renderbuffer DummyRenderbuffer;
+
+/* We bind this framebuffer when applications pass a NULL
+ * drawable/surface in make current. */
+static struct gl_framebuffer IncompleteFramebuffer;
+
+
+#define IS_CUBE_FACE(TARGET) \
+ ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \
+ (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
+
+
+static void
+delete_dummy_renderbuffer(struct gl_renderbuffer *rb)
+{
+ /* no op */
+}
+
+static void
+delete_dummy_framebuffer(struct gl_framebuffer *fb)
+{
+ /* no op */
+}
+
+
+void
+_mesa_init_fbobjects(struct gl_context *ctx)
+{
+ _glthread_INIT_MUTEX(DummyFramebuffer.Mutex);
+ _glthread_INIT_MUTEX(DummyRenderbuffer.Mutex);
+ _glthread_INIT_MUTEX(IncompleteFramebuffer.Mutex);
+ DummyFramebuffer.Delete = delete_dummy_framebuffer;
+ DummyRenderbuffer.Delete = delete_dummy_renderbuffer;
+ IncompleteFramebuffer.Delete = delete_dummy_framebuffer;
+}
+
+struct gl_framebuffer *
+_mesa_get_incomplete_framebuffer(void)
+{
+ return &IncompleteFramebuffer;
+}
+
+/**
+ * Helper routine for getting a gl_renderbuffer.
+ */
+struct gl_renderbuffer *
+_mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id)
+{
+ struct gl_renderbuffer *rb;
+
+ if (id == 0)
+ return NULL;
+
+ rb = (struct gl_renderbuffer *)
+ _mesa_HashLookup(ctx->Shared->RenderBuffers, id);
+ return rb;
+}
+
+
+/**
+ * Helper routine for getting a gl_framebuffer.
+ */
+struct gl_framebuffer *
+_mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id)
+{
+ struct gl_framebuffer *fb;
+
+ if (id == 0)
+ return NULL;
+
+ fb = (struct gl_framebuffer *)
+ _mesa_HashLookup(ctx->Shared->FrameBuffers, id);
+ return fb;
+}
+
+
+/**
+ * Mark the given framebuffer as invalid. This will force the
+ * test for framebuffer completeness to be done before the framebuffer
+ * is used.
+ */
+static void
+invalidate_framebuffer(struct gl_framebuffer *fb)
+{
+ fb->_Status = 0; /* "indeterminate" */
+}
+
+
+/**
+ * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
+ * gl_renderbuffer_attachment object.
+ * This function is only used for user-created FB objects, not the
+ * default / window-system FB object.
+ * If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to
+ * the depth buffer attachment point.
+ */
+struct gl_renderbuffer_attachment *
+_mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum attachment)
+{
+ GLuint i;
+
+ assert(fb->Name > 0);
+
+ switch (attachment) {
+ case GL_COLOR_ATTACHMENT0_EXT:
+ case GL_COLOR_ATTACHMENT1_EXT:
+ case GL_COLOR_ATTACHMENT2_EXT:
+ case GL_COLOR_ATTACHMENT3_EXT:
+ case GL_COLOR_ATTACHMENT4_EXT:
+ case GL_COLOR_ATTACHMENT5_EXT:
+ case GL_COLOR_ATTACHMENT6_EXT:
+ case GL_COLOR_ATTACHMENT7_EXT:
+ case GL_COLOR_ATTACHMENT8_EXT:
+ case GL_COLOR_ATTACHMENT9_EXT:
+ case GL_COLOR_ATTACHMENT10_EXT:
+ case GL_COLOR_ATTACHMENT11_EXT:
+ case GL_COLOR_ATTACHMENT12_EXT:
+ case GL_COLOR_ATTACHMENT13_EXT:
+ case GL_COLOR_ATTACHMENT14_EXT:
+ case GL_COLOR_ATTACHMENT15_EXT:
+ i = attachment - GL_COLOR_ATTACHMENT0_EXT;
+ if (i >= ctx->Const.MaxColorAttachments) {
+ return NULL;
+ }
+ return &fb->Attachment[BUFFER_COLOR0 + i];
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ /* fall-through */
+ case GL_DEPTH_BUFFER:
+ /* fall-through / new in GL 3.0 */
+ case GL_DEPTH_ATTACHMENT_EXT:
+ return &fb->Attachment[BUFFER_DEPTH];
+ case GL_STENCIL_BUFFER:
+ /* fall-through / new in GL 3.0 */
+ case GL_STENCIL_ATTACHMENT_EXT:
+ return &fb->Attachment[BUFFER_STENCIL];
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ * As above, but only used for getting attachments of the default /
+ * window-system framebuffer (not user-created framebuffer objects).
+ */
+static struct gl_renderbuffer_attachment *
+_mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum attachment)
+{
+ assert(fb->Name == 0);
+
+ switch (attachment) {
+ case GL_FRONT_LEFT:
+ return &fb->Attachment[BUFFER_FRONT_LEFT];
+ case GL_FRONT_RIGHT:
+ return &fb->Attachment[BUFFER_FRONT_RIGHT];
+ case GL_BACK_LEFT:
+ return &fb->Attachment[BUFFER_BACK_LEFT];
+ case GL_BACK_RIGHT:
+ return &fb->Attachment[BUFFER_BACK_RIGHT];
+ case GL_AUX0:
+ if (fb->Visual.numAuxBuffers == 1) {
+ return &fb->Attachment[BUFFER_AUX0];
+ }
+ return NULL;
+ case GL_DEPTH_BUFFER:
+ /* fall-through / new in GL 3.0 */
+ case GL_DEPTH_ATTACHMENT_EXT:
+ return &fb->Attachment[BUFFER_DEPTH];
+ case GL_STENCIL_BUFFER:
+ /* fall-through / new in GL 3.0 */
+ case GL_STENCIL_ATTACHMENT_EXT:
+ return &fb->Attachment[BUFFER_STENCIL];
+ default:
+ return NULL;
+ }
+}
+
+
+
+/**
+ * Remove any texture or renderbuffer attached to the given attachment
+ * point. Update reference counts, etc.
+ */
+void
+_mesa_remove_attachment(struct gl_context *ctx,
+ struct gl_renderbuffer_attachment *att)
+{
+ if (att->Type == GL_TEXTURE) {
+ ASSERT(att->Texture);
+ if (ctx->Driver.FinishRenderTexture) {
+ /* tell driver that we're done rendering to this texture. */
+ ctx->Driver.FinishRenderTexture(ctx, att);
+ }
+ _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
+ ASSERT(!att->Texture);
+ }
+ if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
+ ASSERT(!att->Texture);
+ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
+ ASSERT(!att->Renderbuffer);
+ }
+ att->Type = GL_NONE;
+ att->Complete = GL_TRUE;
+}
+
+
+/**
+ * Bind a texture object to an attachment point.
+ * The previous binding, if any, will be removed first.
+ */
+void
+_mesa_set_texture_attachment(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ struct gl_renderbuffer_attachment *att,
+ struct gl_texture_object *texObj,
+ GLenum texTarget, GLuint level, GLuint zoffset)
+{
+ if (att->Texture == texObj) {
+ /* re-attaching same texture */
+ ASSERT(att->Type == GL_TEXTURE);
+ if (ctx->Driver.FinishRenderTexture)
+ ctx->Driver.FinishRenderTexture(ctx, att);
+ }
+ else {
+ /* new attachment */
+ if (ctx->Driver.FinishRenderTexture && att->Texture)
+ ctx->Driver.FinishRenderTexture(ctx, att);
+ _mesa_remove_attachment(ctx, att);
+ att->Type = GL_TEXTURE;
+ assert(!att->Texture);
+ _mesa_reference_texobj(&att->Texture, texObj);
+ }
+
+ /* always update these fields */
+ att->TextureLevel = level;
+ att->CubeMapFace = _mesa_tex_target_to_face(texTarget);
+ att->Zoffset = zoffset;
+ att->Complete = GL_FALSE;
+
+ if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
+ ctx->Driver.RenderTexture(ctx, fb, att);
+ }
+
+ invalidate_framebuffer(fb);
+}
+
+
+/**
+ * Bind a renderbuffer to an attachment point.
+ * The previous binding, if any, will be removed first.
+ */
+void
+_mesa_set_renderbuffer_attachment(struct gl_context *ctx,
+ struct gl_renderbuffer_attachment *att,
+ struct gl_renderbuffer *rb)
+{
+ /* XXX check if re-doing same attachment, exit early */
+ _mesa_remove_attachment(ctx, att);
+ att->Type = GL_RENDERBUFFER_EXT;
+ att->Texture = NULL; /* just to be safe */
+ att->Complete = GL_FALSE;
+ _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
+}
+
+
+/**
+ * Fallback for ctx->Driver.FramebufferRenderbuffer()
+ * Attach a renderbuffer object to a framebuffer object.
+ */
+void
+_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLenum attachment, struct gl_renderbuffer *rb)
+{
+ struct gl_renderbuffer_attachment *att;
+
+ _glthread_LOCK_MUTEX(fb->Mutex);
+
+ att = _mesa_get_attachment(ctx, fb, attachment);
+ ASSERT(att);
+ if (rb) {
+ _mesa_set_renderbuffer_attachment(ctx, att, rb);
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
+ /* do stencil attachment here (depth already done above) */
+ att = _mesa_get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT);
+ assert(att);
+ _mesa_set_renderbuffer_attachment(ctx, att, rb);
+ }
+ }
+ else {
+ _mesa_remove_attachment(ctx, att);
+ }
+
+ invalidate_framebuffer(fb);
+
+ _glthread_UNLOCK_MUTEX(fb->Mutex);
+}
+
+
+/**
+ * For debug only.
+ */
+static void
+att_incomplete(const char *msg)
+{
+#if DEBUG_FBO
+ _mesa_debug(NULL, "attachment incomplete: %s\n", msg);
+#else
+ (void) msg;
+#endif
+}
+
+
+/**
+ * For debug only.
+ */
+static void
+fbo_incomplete(const char *msg, int index)
+{
+#if DEBUG_FBO
+ _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
+#else
+ (void) msg;
+ (void) index;
+#endif
+}
+
+
+/**
+ * Is the given base format a legal format for a color renderbuffer?
+ */
+GLboolean
+_mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat)
+{
+ switch (baseFormat) {
+ case GL_RGB:
+ case GL_RGBA:
+ return GL_TRUE;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_ALPHA:
+ return ctx->Extensions.ARB_framebuffer_object;
+ case GL_RED:
+ case GL_RG:
+ return ctx->Extensions.ARB_texture_rg;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Is the given base format a legal format for a depth/stencil renderbuffer?
+ */
+static GLboolean
+is_legal_depth_format(const struct gl_context *ctx, GLenum baseFormat)
+{
+ switch (baseFormat) {
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if an attachment point is complete and update its Complete field.
+ * \param format if GL_COLOR, this is a color attachment point,
+ * if GL_DEPTH, this is a depth component attachment point,
+ * if GL_STENCIL, this is a stencil component attachment point.
+ */
+static void
+test_attachment_completeness(const struct gl_context *ctx, GLenum format,
+ struct gl_renderbuffer_attachment *att)
+{
+ assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);
+
+ /* assume complete */
+ att->Complete = GL_TRUE;
+
+ /* Look for reasons why the attachment might be incomplete */
+ if (att->Type == GL_TEXTURE) {
+ const struct gl_texture_object *texObj = att->Texture;
+ struct gl_texture_image *texImage;
+ GLenum baseFormat;
+
+ if (!texObj) {
+ att_incomplete("no texobj");
+ att->Complete = GL_FALSE;
+ return;
+ }
+
+ texImage = texObj->Image[att->CubeMapFace][att->TextureLevel];
+ if (!texImage) {
+ att_incomplete("no teximage");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ if (texImage->Width < 1 || texImage->Height < 1) {
+ att_incomplete("teximage width/height=0");
+ printf("texobj = %u\n", texObj->Name);
+ printf("level = %d\n", att->TextureLevel);
+ att->Complete = GL_FALSE;
+ return;
+ }
+ if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) {
+ att_incomplete("bad z offset");
+ att->Complete = GL_FALSE;
+ return;
+ }
+
+ baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
+
+ if (format == GL_COLOR) {
+ if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
+ att_incomplete("bad format");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ if (_mesa_is_format_compressed(texImage->TexFormat)) {
+ att_incomplete("compressed internalformat");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ else if (format == GL_DEPTH) {
+ if (baseFormat == GL_DEPTH_COMPONENT) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ ctx->Extensions.ARB_depth_texture &&
+ baseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
+ att->Complete = GL_FALSE;
+ att_incomplete("bad depth format");
+ return;
+ }
+ }
+ else {
+ ASSERT(format == GL_STENCIL);
+ if (ctx->Extensions.EXT_packed_depth_stencil &&
+ ctx->Extensions.ARB_depth_texture &&
+ baseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
+ /* no such thing as stencil-only textures */
+ att_incomplete("illegal stencil texture");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ }
+ else if (att->Type == GL_RENDERBUFFER_EXT) {
+ const GLenum baseFormat =
+ _mesa_get_format_base_format(att->Renderbuffer->Format);
+
+ ASSERT(att->Renderbuffer);
+ if (!att->Renderbuffer->InternalFormat ||
+ att->Renderbuffer->Width < 1 ||
+ att->Renderbuffer->Height < 1) {
+ att_incomplete("0x0 renderbuffer");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ if (format == GL_COLOR) {
+ if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
+ att_incomplete("bad renderbuffer color format");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ else if (format == GL_DEPTH) {
+ if (baseFormat == GL_DEPTH_COMPONENT) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ baseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
+ att_incomplete("bad renderbuffer depth format");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ else {
+ assert(format == GL_STENCIL);
+ if (baseFormat == GL_STENCIL_INDEX) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ baseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
+ att->Complete = GL_FALSE;
+ att_incomplete("bad renderbuffer stencil format");
+ return;
+ }
+ }
+ }
+ else {
+ ASSERT(att->Type == GL_NONE);
+ /* complete */
+ return;
+ }
+}
+
+
+/**
+ * Test if the given framebuffer object is complete and update its
+ * Status field with the results.
+ * Calls the ctx->Driver.ValidateFramebuffer() function to allow the
+ * driver to make hardware-specific validation/completeness checks.
+ * Also update the framebuffer's Width and Height fields if the
+ * framebuffer is complete.
+ */
+void
+_mesa_test_framebuffer_completeness(struct gl_context *ctx,
+ struct gl_framebuffer *fb)
+{
+ GLuint numImages;
+ GLenum intFormat = GL_NONE; /* color buffers' internal format */
+ GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
+ GLint numSamples = -1;
+ GLint i;
+ GLuint j;
+
+ assert(fb->Name != 0);
+
+ numImages = 0;
+ fb->Width = 0;
+ fb->Height = 0;
+
+ /* Start at -2 to more easily loop over all attachment points.
+ * -2: depth buffer
+ * -1: stencil buffer
+ * >=0: color buffer
+ */
+ for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
+ struct gl_renderbuffer_attachment *att;
+ GLenum f;
+ gl_format mesaFormat;
+
+ /*
+ * XXX for ARB_fbo, only check color buffers that are named by
+ * GL_READ_BUFFER and GL_DRAW_BUFFERi.
+ */
+
+ /* check for attachment completeness
+ */
+ if (i == -2) {
+ att = &fb->Attachment[BUFFER_DEPTH];
+ test_attachment_completeness(ctx, GL_DEPTH, att);
+ if (!att->Complete) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
+ fbo_incomplete("depth attachment incomplete", -1);
+ return;
+ }
+ }
+ else if (i == -1) {
+ att = &fb->Attachment[BUFFER_STENCIL];
+ test_attachment_completeness(ctx, GL_STENCIL, att);
+ if (!att->Complete) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
+ fbo_incomplete("stencil attachment incomplete", -1);
+ return;
+ }
+ }
+ else {
+ att = &fb->Attachment[BUFFER_COLOR0 + i];
+ test_attachment_completeness(ctx, GL_COLOR, att);
+ if (!att->Complete) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
+ fbo_incomplete("color attachment incomplete", i);
+ return;
+ }
+ }
+
+ /* get width, height, format of the renderbuffer/texture
+ */
+ if (att->Type == GL_TEXTURE) {
+ const struct gl_texture_image *texImg
+ = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+ minWidth = MIN2(minWidth, texImg->Width);
+ maxWidth = MAX2(maxWidth, texImg->Width);
+ minHeight = MIN2(minHeight, texImg->Height);
+ maxHeight = MAX2(maxHeight, texImg->Height);
+ f = texImg->_BaseFormat;
+ mesaFormat = texImg->TexFormat;
+ numImages++;
+ if (!_mesa_is_legal_color_format(ctx, f) &&
+ !is_legal_depth_format(ctx, f)) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
+ fbo_incomplete("texture attachment incomplete", -1);
+ return;
+ }
+ }
+ else if (att->Type == GL_RENDERBUFFER_EXT) {
+ minWidth = MIN2(minWidth, att->Renderbuffer->Width);
+ maxWidth = MAX2(minWidth, att->Renderbuffer->Width);
+ minHeight = MIN2(minHeight, att->Renderbuffer->Height);
+ maxHeight = MAX2(minHeight, att->Renderbuffer->Height);
+ f = att->Renderbuffer->InternalFormat;
+ mesaFormat = att->Renderbuffer->Format;
+ numImages++;
+ }
+ else {
+ assert(att->Type == GL_NONE);
+ continue;
+ }
+
+ if (numSamples < 0) {
+ /* first buffer */
+ numSamples = att->Renderbuffer->NumSamples;
+ }
+
+ /* check if integer color */
+ fb->_IntegerColor = _mesa_is_format_integer_color(mesaFormat);
+
+ /* Error-check width, height, format, samples
+ */
+ if (numImages == 1) {
+ /* save format, num samples */
+ if (i >= 0) {
+ intFormat = f;
+ }
+ }
+ else {
+ if (!ctx->Extensions.ARB_framebuffer_object) {
+ /* check that width, height, format are same */
+ if (minWidth != maxWidth || minHeight != maxHeight) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
+ fbo_incomplete("width or height mismatch", -1);
+ return;
+ }
+ /* check that all color buffer have same format */
+ if (intFormat != GL_NONE && f != intFormat) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
+ fbo_incomplete("format mismatch", -1);
+ return;
+ }
+ }
+ if (att->Renderbuffer &&
+ att->Renderbuffer->NumSamples != numSamples) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistant number of samples", i);
+ return;
+ }
+
+ }
+ }
+
+#if FEATURE_GL
+ if (ctx->API == API_OPENGL) {
+ /* Check that all DrawBuffers are present */
+ for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) {
+ if (fb->ColorDrawBuffer[j] != GL_NONE) {
+ const struct gl_renderbuffer_attachment *att
+ = _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer[j]);
+ assert(att);
+ if (att->Type == GL_NONE) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
+ fbo_incomplete("missing drawbuffer", j);
+ return;
+ }
+ }
+ }
+
+ /* Check that the ReadBuffer is present */
+ if (fb->ColorReadBuffer != GL_NONE) {
+ const struct gl_renderbuffer_attachment *att
+ = _mesa_get_attachment(ctx, fb, fb->ColorReadBuffer);
+ assert(att);
+ if (att->Type == GL_NONE) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
+ fbo_incomplete("missing readbuffer", -1);
+ return;
+ }
+ }
+ }
+#else
+ (void) j;
+#endif
+
+ if (numImages == 0) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
+ fbo_incomplete("no attachments", -1);
+ return;
+ }
+
+ /* Provisionally set status = COMPLETE ... */
+ fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
+
+ /* ... but the driver may say the FB is incomplete.
+ * Drivers will most likely set the status to GL_FRAMEBUFFER_UNSUPPORTED
+ * if anything.
+ */
+ if (ctx->Driver.ValidateFramebuffer) {
+ ctx->Driver.ValidateFramebuffer(ctx, fb);
+ if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ fbo_incomplete("driver marked FBO as incomplete", -1);
+ }
+ }
+
+ if (fb->_Status == GL_FRAMEBUFFER_COMPLETE_EXT) {
+ /*
+ * Note that if ARB_framebuffer_object is supported and the attached
+ * renderbuffers/textures are different sizes, the framebuffer
+ * width/height will be set to the smallest width/height.
+ */
+ fb->Width = minWidth;
+ fb->Height = minHeight;
+
+ /* finally, update the visual info for the framebuffer */
+ _mesa_update_framebuffer_visual(ctx, fb);
+ }
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsRenderbufferEXT(GLuint renderbuffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ if (renderbuffer) {
+ struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+ if (rb != NULL && rb != &DummyRenderbuffer)
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
+{
+ struct gl_renderbuffer *newRb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)");
+ return;
+ }
+
+ /* No need to flush here since the render buffer binding has no
+ * effect on rendering state.
+ */
+
+ if (renderbuffer) {
+ newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+ if (newRb == &DummyRenderbuffer) {
+ /* ID was reserved, but no real renderbuffer object made yet */
+ newRb = NULL;
+ }
+ else if (!newRb && ctx->Extensions.ARB_framebuffer_object) {
+ /* All RB IDs must be Gen'd */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindRenderbuffer(buffer)");
+ return;
+ }
+
+ if (!newRb) {
+ /* create new renderbuffer object */
+ newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
+ if (!newRb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
+ return;
+ }
+ ASSERT(newRb->AllocStorage);
+ _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
+ newRb->RefCount = 1; /* referenced by hash table */
+ }
+ }
+ else {
+ newRb = NULL;
+ }
+
+ ASSERT(newRb != &DummyRenderbuffer);
+
+ _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
+}
+
+
+/**
+ * If the given renderbuffer is anywhere attached to the framebuffer, detach
+ * the renderbuffer.
+ * This is used when a renderbuffer object is deleted.
+ * The spec calls for unbinding.
+ */
+static void
+detach_renderbuffer(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ struct gl_renderbuffer *rb)
+{
+ GLuint i;
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ if (fb->Attachment[i].Renderbuffer == rb) {
+ _mesa_remove_attachment(ctx, &fb->Attachment[i]);
+ }
+ }
+ invalidate_framebuffer(fb);
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
+{
+ GLint i;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ for (i = 0; i < n; i++) {
+ if (renderbuffers[i] > 0) {
+ struct gl_renderbuffer *rb;
+ rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
+ if (rb) {
+ /* check if deleting currently bound renderbuffer object */
+ if (rb == ctx->CurrentRenderbuffer) {
+ /* bind default */
+ ASSERT(rb->RefCount >= 2);
+ _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ }
+
+ if (ctx->DrawBuffer->Name) {
+ detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
+ }
+ if (ctx->ReadBuffer->Name && ctx->ReadBuffer != ctx->DrawBuffer) {
+ detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
+ }
+
+ /* Remove from hash table immediately, to free the ID.
+ * But the object will not be freed until it's no longer
+ * referenced anywhere else.
+ */
+ _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
+
+ if (rb != &DummyRenderbuffer) {
+ /* no longer referenced by hash table */
+ _mesa_reference_renderbuffer(&rb, NULL);
+ }
+ }
+ }
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint first;
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
+ return;
+ }
+
+ if (!renderbuffers)
+ return;
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);
+
+ for (i = 0; i < n; i++) {
+ GLuint name = first + i;
+ renderbuffers[i] = name;
+ /* insert dummy placeholder into hash table */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ }
+}
+
+
+/**
+ * Given an internal format token for a renderbuffer, return the
+ * corresponding base format.
+ */
+GLenum
+_mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
+{
+ GLenum baseFormat;
+
+ switch (internalFormat) {
+ case GL_RGBA16_SNORM:
+ /* This is used internally by Mesa for accum buffers. */
+ return GL_RGBA;
+ case GL_STENCIL_INDEX:
+ case GL_STENCIL_INDEX1_EXT:
+ case GL_STENCIL_INDEX4_EXT:
+ case GL_STENCIL_INDEX8_EXT:
+ case GL_STENCIL_INDEX16_EXT:
+ /* This is not a valid texture internalFormat, but valid for
+ * renderbuffers.
+ */
+ return GL_STENCIL_INDEX;
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ /* This is an override of _mesa_base_tex_format's check that
+ * ARB_depth_texture is present. We allow depth RBs without it.
+ */
+ return GL_DEPTH_COMPONENT;
+ }
+
+ baseFormat = _mesa_base_tex_format(ctx, internalFormat);
+ if (baseFormat < 0)
+ return 0;
+
+ return baseFormat;
+}
+
+
+/** sentinal value, see below */
+#define NO_SAMPLES 1000
+
+
+/**
+ * Helper function used by _mesa_RenderbufferStorageEXT() and
+ * _mesa_RenderbufferStorageMultisample().
+ * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorageEXT().
+ */
+static void
+renderbuffer_storage(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei samples)
+{
+ const char *func = samples == NO_SAMPLES ?
+ "glRenderbufferStorage" : "RenderbufferStorageMultisample";
+ struct gl_renderbuffer *rb;
+ GLenum baseFormat;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
+ return;
+ }
+
+ baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
+ if (baseFormat == 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat)", func);
+ return;
+ }
+
+ if (baseFormat != GL_DEPTH_COMPONENT &&
+ baseFormat != GL_STENCIL_INDEX &&
+ baseFormat != GL_DEPTH_STENCIL &&
+ !_mesa_is_legal_color_format(ctx, baseFormat)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat)", func);
+ return;
+ }
+
+ if (width < 1 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(width)", func);
+ return;
+ }
+
+ if (height < 1 || height > (GLsizei) ctx->Const.MaxRenderbufferSize) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(height)", func);
+ return;
+ }
+
+ if (samples == NO_SAMPLES) {
+ /* NumSamples == 0 indicates non-multisampling */
+ samples = 0;
+ }
+ else if (samples > (GLsizei) ctx->Const.MaxSamples) {
+ /* note: driver may choose to use more samples than what's requested */
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func);
+ return;
+ }
+
+ rb = ctx->CurrentRenderbuffer;
+ if (!rb) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ if (rb->InternalFormat == internalFormat &&
+ rb->Width == (GLuint) width &&
+ rb->Height == (GLuint) height) {
+ /* no change in allocation needed */
+ return;
+ }
+
+ /* These MUST get set by the AllocStorage func */
+ rb->Format = MESA_FORMAT_NONE;
+ rb->NumSamples = samples;
+
+ /* Now allocate the storage */
+ ASSERT(rb->AllocStorage);
+ if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
+ /* No error - check/set fields now */
+ assert(rb->Format != MESA_FORMAT_NONE);
+ assert(rb->Width == (GLuint) width);
+ assert(rb->Height == (GLuint) height);
+ rb->InternalFormat = internalFormat;
+ rb->_BaseFormat = baseFormat;
+ assert(rb->_BaseFormat != 0);
+ }
+ else {
+ /* Probably ran out of memory - clear the fields */
+ rb->Width = 0;
+ rb->Height = 0;
+ rb->Format = MESA_FORMAT_NONE;
+ rb->InternalFormat = GL_NONE;
+ rb->_BaseFormat = GL_NONE;
+ rb->NumSamples = 0;
+ }
+
+ /*
+ test_framebuffer_completeness(ctx, fb);
+ */
+ /* XXX if this renderbuffer is attached anywhere, invalidate attachment
+ * points???
+ */
+}
+
+
+#if FEATURE_OES_EGL_image
+void GLAPIENTRY
+_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+ struct gl_renderbuffer *rb;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.OES_EGL_image) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glEGLImageTargetRenderbufferStorageOES(unsupported)");
+ return;
+ }
+
+ if (target != GL_RENDERBUFFER) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "EGLImageTargetRenderbufferStorageOES");
+ return;
+ }
+
+ rb = ctx->CurrentRenderbuffer;
+ if (!rb) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "EGLImageTargetRenderbufferStorageOES");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ ctx->Driver.EGLImageTargetRenderbufferStorage(ctx, rb, image);
+}
+#endif
+
+
+/**
+ * Helper function for _mesa_GetRenderbufferParameterivEXT() and
+ * _mesa_GetFramebufferAttachmentParameterivEXT()
+ * We have to be careful to respect the base format. For example, if a
+ * renderbuffer/texture was created with internalFormat=GL_RGB but the
+ * driver actually chose a GL_RGBA format, when the user queries ALPHA_SIZE
+ * we need to return zero.
+ */
+static GLint
+get_component_bits(GLenum pname, GLenum baseFormat, gl_format format)
+{
+ switch (pname) {
+ case GL_RENDERBUFFER_RED_SIZE_EXT:
+ case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+ if (baseFormat == GL_RGB || baseFormat == GL_RGBA ||
+ baseFormat == GL_RG || baseFormat == GL_RED)
+ return _mesa_get_format_bits(format, pname);
+ else
+ return 0;
+ case GL_RENDERBUFFER_GREEN_SIZE_EXT:
+ case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+ if (baseFormat == GL_RGB || baseFormat == GL_RGBA || baseFormat == GL_RG)
+ return _mesa_get_format_bits(format, pname);
+ else
+ return 0;
+ case GL_RENDERBUFFER_BLUE_SIZE_EXT:
+ case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
+ if (baseFormat == GL_RGB || baseFormat == GL_RGBA)
+ return _mesa_get_format_bits(format, pname);
+ else
+ return 0;
+ case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
+ case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+ if (baseFormat == GL_RGBA || baseFormat == GL_ALPHA ||
+ baseFormat == GL_LUMINANCE_ALPHA)
+ return _mesa_get_format_bits(format, pname);
+ else
+ return 0;
+ case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
+ case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+ if (baseFormat == GL_DEPTH_COMPONENT || baseFormat == GL_DEPTH_STENCIL)
+ return _mesa_get_format_bits(format, pname);
+ else
+ return 0;
+ case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
+ case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+ if (baseFormat == GL_STENCIL_INDEX || baseFormat == GL_DEPTH_STENCIL)
+ return _mesa_get_format_bits(format, pname);
+ else
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height)
+{
+ /* GL_ARB_fbo says calling this function is equivalent to calling
+ * glRenderbufferStorageMultisample() with samples=0. We pass in
+ * a token value here just for error reporting purposes.
+ */
+ renderbuffer_storage(target, internalFormat, width, height, NO_SAMPLES);
+}
+
+
+void GLAPIENTRY
+_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width, GLsizei height)
+{
+ renderbuffer_storage(target, internalFormat, width, height, samples);
+}
+
+
+/**
+ * OpenGL ES version of glRenderBufferStorage.
+ */
+void GLAPIENTRY
+_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height)
+{
+ switch (internalFormat) {
+ case GL_RGB565:
+ /* XXX this confuses GL_RENDERBUFFER_INTERNAL_FORMAT_OES */
+ /* choose a closest format */
+ internalFormat = GL_RGB5;
+ break;
+ default:
+ break;
+ }
+
+ renderbuffer_storage(target, internalFormat, width, height, 0);
+}
+
+
+void GLAPIENTRY
+_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ struct gl_renderbuffer *rb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetRenderbufferParameterivEXT(target)");
+ return;
+ }
+
+ rb = ctx->CurrentRenderbuffer;
+ if (!rb) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetRenderbufferParameterivEXT");
+ return;
+ }
+
+ /* No need to flush here since we're just quering state which is
+ * not effected by rendering.
+ */
+
+ switch (pname) {
+ case GL_RENDERBUFFER_WIDTH_EXT:
+ *params = rb->Width;
+ return;
+ case GL_RENDERBUFFER_HEIGHT_EXT:
+ *params = rb->Height;
+ return;
+ case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
+ *params = rb->InternalFormat;
+ return;
+ case GL_RENDERBUFFER_RED_SIZE_EXT:
+ case GL_RENDERBUFFER_GREEN_SIZE_EXT:
+ case GL_RENDERBUFFER_BLUE_SIZE_EXT:
+ case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
+ case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
+ case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
+ *params = get_component_bits(pname, rb->_BaseFormat, rb->Format);
+ break;
+ case GL_RENDERBUFFER_SAMPLES:
+ if (ctx->Extensions.ARB_framebuffer_object) {
+ *params = rb->NumSamples;
+ break;
+ }
+ /* fallthrough */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetRenderbufferParameterivEXT(target)");
+ return;
+ }
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsFramebufferEXT(GLuint framebuffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ if (framebuffer) {
+ struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer);
+ if (rb != NULL && rb != &DummyFramebuffer)
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+
+
+/**
+ * Check if any of the attachments of the given framebuffer are textures
+ * (render to texture). Call ctx->Driver.RenderTexture() for such
+ * attachments.
+ */
+static void
+check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
+{
+ GLuint i;
+ ASSERT(ctx->Driver.RenderTexture);
+
+ if (fb->Name == 0)
+ return; /* can't render to texture with winsys framebuffers */
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = fb->Attachment + i;
+ struct gl_texture_object *texObj = att->Texture;
+ if (texObj
+ && texObj->Image[att->CubeMapFace][att->TextureLevel]) {
+ ctx->Driver.RenderTexture(ctx, fb, att);
+ }
+ }
+}
+
+
+/**
+ * Examine all the framebuffer's attachments to see if any are textures.
+ * If so, call ctx->Driver.FinishRenderTexture() for each texture to
+ * notify the device driver that the texture image may have changed.
+ */
+static void
+check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
+{
+ if (fb->Name == 0)
+ return; /* can't render to texture with winsys framebuffers */
+
+ if (ctx->Driver.FinishRenderTexture) {
+ GLuint i;
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = fb->Attachment + i;
+ if (att->Texture && att->Renderbuffer) {
+ ctx->Driver.FinishRenderTexture(ctx, att);
+ }
+ }
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
+{
+ struct gl_framebuffer *newDrawFb, *newReadFb;
+ struct gl_framebuffer *oldDrawFb, *oldReadFb;
+ GLboolean bindReadBuf, bindDrawBuf;
+ GET_CURRENT_CONTEXT(ctx);
+
+#ifdef DEBUG
+ if (ctx->Extensions.ARB_framebuffer_object) {
+ ASSERT(ctx->Extensions.EXT_framebuffer_object);
+ ASSERT(ctx->Extensions.EXT_framebuffer_blit);
+ }
+#endif
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.EXT_framebuffer_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindFramebufferEXT(unsupported)");
+ return;
+ }
+
+ switch (target) {
+#if FEATURE_EXT_framebuffer_blit
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
+ return;
+ }
+ bindDrawBuf = GL_TRUE;
+ bindReadBuf = GL_FALSE;
+ break;
+ case GL_READ_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
+ return;
+ }
+ bindDrawBuf = GL_FALSE;
+ bindReadBuf = GL_TRUE;
+ break;
+#endif
+ case GL_FRAMEBUFFER_EXT:
+ bindDrawBuf = GL_TRUE;
+ bindReadBuf = GL_TRUE;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
+ return;
+ }
+
+ if (framebuffer) {
+ /* Binding a user-created framebuffer object */
+ newDrawFb = _mesa_lookup_framebuffer(ctx, framebuffer);
+ if (newDrawFb == &DummyFramebuffer) {
+ /* ID was reserved, but no real framebuffer object made yet */
+ newDrawFb = NULL;
+ }
+ else if (!newDrawFb && ctx->Extensions.ARB_framebuffer_object) {
+ /* All FBO IDs must be Gen'd */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebuffer(buffer)");
+ return;
+ }
+
+ if (!newDrawFb) {
+ /* create new framebuffer object */
+ newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
+ if (!newDrawFb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
+ return;
+ }
+ _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb);
+ }
+ newReadFb = newDrawFb;
+ }
+ else {
+ /* Binding the window system framebuffer (which was originally set
+ * with MakeCurrent).
+ */
+ newDrawFb = ctx->WinSysDrawBuffer;
+ newReadFb = ctx->WinSysReadBuffer;
+ }
+
+ ASSERT(newDrawFb);
+ ASSERT(newDrawFb != &DummyFramebuffer);
+
+ /* save pointers to current/old framebuffers */
+ oldDrawFb = ctx->DrawBuffer;
+ oldReadFb = ctx->ReadBuffer;
+
+ /* check if really changing bindings */
+ if (oldDrawFb == newDrawFb)
+ bindDrawBuf = GL_FALSE;
+ if (oldReadFb == newReadFb)
+ bindReadBuf = GL_FALSE;
+
+ /*
+ * OK, now bind the new Draw/Read framebuffers, if they're changing.
+ *
+ * We also check if we're beginning and/or ending render-to-texture.
+ * When a framebuffer with texture attachments is unbound, call
+ * ctx->Driver.FinishRenderTexture().
+ * When a framebuffer with texture attachments is bound, call
+ * ctx->Driver.RenderTexture().
+ *
+ * Note that if the ReadBuffer has texture attachments we don't consider
+ * that a render-to-texture case.
+ */
+ if (bindReadBuf) {
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ /* check if old readbuffer was render-to-texture */
+ check_end_texture_render(ctx, oldReadFb);
+
+ _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb);
+ }
+
+ if (bindDrawBuf) {
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ /* check if old read/draw buffers were render-to-texture */
+ if (!bindReadBuf)
+ check_end_texture_render(ctx, oldReadFb);
+
+ if (oldDrawFb != oldReadFb)
+ check_end_texture_render(ctx, oldDrawFb);
+
+ /* check if newly bound framebuffer has any texture attachments */
+ check_begin_texture_render(ctx, newDrawFb);
+
+ _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb);
+ }
+
+ if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) {
+ ctx->Driver.BindFramebuffer(ctx, target, newDrawFb, newReadFb);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
+{
+ GLint i;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ for (i = 0; i < n; i++) {
+ if (framebuffers[i] > 0) {
+ struct gl_framebuffer *fb;
+ fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
+ if (fb) {
+ ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
+
+ /* check if deleting currently bound framebuffer object */
+ if (ctx->Extensions.EXT_framebuffer_blit) {
+ /* separate draw/read binding points */
+ if (fb == ctx->DrawBuffer) {
+ /* bind default */
+ ASSERT(fb->RefCount >= 2);
+ _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
+ }
+ if (fb == ctx->ReadBuffer) {
+ /* bind default */
+ ASSERT(fb->RefCount >= 2);
+ _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
+ }
+ }
+ else {
+ /* only one binding point for read/draw buffers */
+ if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) {
+ /* bind default */
+ ASSERT(fb->RefCount >= 2);
+ _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+ }
+
+ /* remove from hash table immediately, to free the ID */
+ _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
+
+ if (fb != &DummyFramebuffer) {
+ /* But the object will not be freed until it's no longer
+ * bound in any context.
+ */
+ _mesa_reference_framebuffer(&fb, NULL);
+ }
+ }
+ }
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint first;
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
+ return;
+ }
+
+ if (!framebuffers)
+ return;
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);
+
+ for (i = 0; i < n; i++) {
+ GLuint name = first + i;
+ framebuffers[i] = name;
+ /* insert dummy placeholder into hash table */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ }
+}
+
+
+
+GLenum GLAPIENTRY
+_mesa_CheckFramebufferStatusEXT(GLenum target)
+{
+ struct gl_framebuffer *buffer;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+ switch (target) {
+#if FEATURE_EXT_framebuffer_blit
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
+ return 0;
+ }
+ buffer = ctx->DrawBuffer;
+ break;
+ case GL_READ_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
+ return 0;
+ }
+ buffer = ctx->ReadBuffer;
+ break;
+#endif
+ case GL_FRAMEBUFFER_EXT:
+ buffer = ctx->DrawBuffer;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
+ return 0; /* formerly GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+ }
+
+ if (buffer->Name == 0) {
+ /* The window system / default framebuffer is always complete */
+ return GL_FRAMEBUFFER_COMPLETE_EXT;
+ }
+
+ /* No need to flush here */
+
+ if (buffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
+ _mesa_test_framebuffer_completeness(ctx, buffer);
+ }
+
+ return buffer->_Status;
+}
+
+
+
+/**
+ * Common code called by glFramebufferTexture1D/2D/3DEXT().
+ */
+static void
+framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
+ GLenum attachment, GLenum textarget, GLuint texture,
+ GLint level, GLint zoffset)
+{
+ struct gl_renderbuffer_attachment *att;
+ struct gl_texture_object *texObj = NULL;
+ struct gl_framebuffer *fb;
+ GLboolean error = GL_FALSE;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+ case GL_READ_FRAMEBUFFER_EXT:
+ error = !ctx->Extensions.EXT_framebuffer_blit;
+ fb = ctx->ReadBuffer;
+ break;
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ error = !ctx->Extensions.EXT_framebuffer_blit;
+ /* fall-through */
+ case GL_FRAMEBUFFER_EXT:
+ fb = ctx->DrawBuffer;
+ break;
+ default:
+ error = GL_TRUE;
+ }
+
+ if (error) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture%sEXT(target=0x%x)", caller, target);
+ return;
+ }
+
+ ASSERT(fb);
+
+ /* check framebuffer binding */
+ if (fb->Name == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture%sEXT", caller);
+ return;
+ }
+
+
+ /* The textarget, level, and zoffset parameters are only validated if
+ * texture is non-zero.
+ */
+ if (texture) {
+ GLboolean err = GL_TRUE;
+
+ texObj = _mesa_lookup_texture(ctx, texture);
+ if (texObj != NULL) {
+ if (textarget == 0) {
+ /* XXX what's the purpose of this? */
+ err = (texObj->Target != GL_TEXTURE_3D) &&
+ (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
+ (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT);
+ }
+ else {
+ err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
+ ? !IS_CUBE_FACE(textarget)
+ : (texObj->Target != textarget);
+ }
+ }
+ else {
+ /* can't render to a non-existant texture */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture%sEXT(non existant texture)",
+ caller);
+ return;
+ }
+
+ if (err) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture%sEXT(texture target mismatch)",
+ caller);
+ return;
+ }
+
+ if (texObj->Target == GL_TEXTURE_3D) {
+ const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
+ if (zoffset < 0 || zoffset >= maxSize) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferTexture%sEXT(zoffset)", caller);
+ return;
+ }
+ }
+ else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
+ (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
+ if (zoffset < 0 || zoffset >= ctx->Const.MaxArrayTextureLayers) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferTexture%sEXT(layer)", caller);
+ return;
+ }
+ }
+
+ if ((level < 0) ||
+ (level >= _mesa_max_texture_levels(ctx, texObj->Target))) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferTexture%sEXT(level)", caller);
+ return;
+ }
+ }
+
+ att = _mesa_get_attachment(ctx, fb, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture%sEXT(attachment)", caller);
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ _glthread_LOCK_MUTEX(fb->Mutex);
+ if (texObj) {
+ _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
+ level, zoffset);
+ /* Set the render-to-texture flag. We'll check this flag in
+ * glTexImage() and friends to determine if we need to revalidate
+ * any FBOs that might be rendering into this texture.
+ * This flag never gets cleared since it's non-trivial to determine
+ * when all FBOs might be done rendering to this texture. That's OK
+ * though since it's uncommon to render to a texture then repeatedly
+ * call glTexImage() to change images in the texture.
+ */
+ texObj->_RenderToTexture = GL_TRUE;
+ }
+ else {
+ _mesa_remove_attachment(ctx, att);
+ }
+
+ invalidate_framebuffer(fb);
+
+ _glthread_UNLOCK_MUTEX(fb->Mutex);
+}
+
+
+
+void GLAPIENTRY
+_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if ((texture != 0) && (textarget != GL_TEXTURE_1D)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture1DEXT(textarget)");
+ return;
+ }
+
+ framebuffer_texture(ctx, "1D", target, attachment, textarget, texture,
+ level, 0);
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if ((texture != 0) &&
+ (textarget != GL_TEXTURE_2D) &&
+ (textarget != GL_TEXTURE_RECTANGLE_ARB) &&
+ (!IS_CUBE_FACE(textarget))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture2DEXT(textarget=0x%x)", textarget);
+ return;
+ }
+
+ framebuffer_texture(ctx, "2D", target, attachment, textarget, texture,
+ level, 0);
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level, GLint zoffset)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if ((texture != 0) && (textarget != GL_TEXTURE_3D)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture3DEXT(textarget)");
+ return;
+ }
+
+ framebuffer_texture(ctx, "3D", target, attachment, textarget, texture,
+ level, zoffset);
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTextureLayerEXT(GLenum target, GLenum attachment,
+ GLuint texture, GLint level, GLint layer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ framebuffer_texture(ctx, "Layer", target, attachment, 0, texture,
+ level, layer);
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
+ GLenum renderbufferTarget,
+ GLuint renderbuffer)
+{
+ struct gl_renderbuffer_attachment *att;
+ struct gl_framebuffer *fb;
+ struct gl_renderbuffer *rb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+#if FEATURE_EXT_framebuffer_blit
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(target)");
+ return;
+ }
+ fb = ctx->DrawBuffer;
+ break;
+ case GL_READ_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(target)");
+ return;
+ }
+ fb = ctx->ReadBuffer;
+ break;
+#endif
+ case GL_FRAMEBUFFER_EXT:
+ fb = ctx->DrawBuffer;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(target)");
+ return;
+ }
+
+ if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(renderbufferTarget)");
+ return;
+ }
+
+ if (fb->Name == 0) {
+ /* Can't attach new renderbuffers to a window system framebuffer */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
+ return;
+ }
+
+ att = _mesa_get_attachment(ctx, fb, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(invalid attachment %s)",
+ _mesa_lookup_enum_by_nr(attachment));
+ return;
+ }
+
+ if (renderbuffer) {
+ rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+ if (!rb) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferRenderbufferEXT(non-existant"
+ " renderbuffer %u)", renderbuffer);
+ return;
+ }
+ else if (rb == &DummyRenderbuffer) {
+ /* This is what NVIDIA does */
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferRenderbufferEXT(renderbuffer %u)",
+ renderbuffer);
+ return;
+ }
+ }
+ else {
+ /* remove renderbuffer attachment */
+ rb = NULL;
+ }
+
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
+ rb && rb->Format != MESA_FORMAT_NONE) {
+ /* make sure the renderbuffer is a depth/stencil format */
+ const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
+ if (baseFormat != GL_DEPTH_STENCIL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferRenderbufferEXT(renderbuffer"
+ " is not DEPTH_STENCIL format)");
+ return;
+ }
+ }
+
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ assert(ctx->Driver.FramebufferRenderbuffer);
+ ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb);
+
+ /* Some subsequent GL commands may depend on the framebuffer's visual
+ * after the binding is updated. Update visual info now.
+ */
+ _mesa_update_framebuffer_visual(ctx, fb);
+}
+
+
+void GLAPIENTRY
+_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params)
+{
+ const struct gl_renderbuffer_attachment *att;
+ struct gl_framebuffer *buffer;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+#if FEATURE_EXT_framebuffer_blit
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(target)");
+ return;
+ }
+ buffer = ctx->DrawBuffer;
+ break;
+ case GL_READ_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(target)");
+ return;
+ }
+ buffer = ctx->ReadBuffer;
+ break;
+#endif
+ case GL_FRAMEBUFFER_EXT:
+ buffer = ctx->DrawBuffer;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(target)");
+ return;
+ }
+
+ if (buffer->Name == 0) {
+ /* the default / window-system FBO */
+ att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
+ }
+ else {
+ /* user-created framebuffer FBO */
+ att = _mesa_get_attachment(ctx, buffer, attachment);
+ }
+
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(attachment)");
+ return;
+ }
+
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
+ /* the depth and stencil attachments must point to the same buffer */
+ const struct gl_renderbuffer_attachment *depthAtt, *stencilAtt;
+ depthAtt = _mesa_get_attachment(ctx, buffer, GL_DEPTH_ATTACHMENT);
+ stencilAtt = _mesa_get_attachment(ctx, buffer, GL_STENCIL_ATTACHMENT);
+ if (depthAtt->Renderbuffer != stencilAtt->Renderbuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT(DEPTH/STENCIL"
+ " attachments differ)");
+ return;
+ }
+ }
+
+ /* No need to flush here */
+
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
+ *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type;
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
+ if (att->Type == GL_RENDERBUFFER_EXT) {
+ *params = att->Renderbuffer->Name;
+ }
+ else if (att->Type == GL_TEXTURE) {
+ *params = att->Texture->Name;
+ }
+ else {
+ assert(att->Type == GL_NONE);
+ *params = 0;
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
+ if (att->Type == GL_TEXTURE) {
+ *params = att->TextureLevel;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
+ if (att->Type == GL_TEXTURE) {
+ if (att->Texture && att->Texture->Target == GL_TEXTURE_CUBE_MAP) {
+ *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace;
+ }
+ else {
+ *params = 0;
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
+ if (att->Type == GL_TEXTURE) {
+ if (att->Texture && att->Texture->Target == GL_TEXTURE_3D) {
+ *params = att->Zoffset;
+ }
+ else {
+ *params = 0;
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
+ if (!ctx->Extensions.ARB_framebuffer_object) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ else {
+ if (ctx->Extensions.EXT_framebuffer_sRGB) {
+ *params = _mesa_get_format_color_encoding(att->Renderbuffer->Format);
+ }
+ else {
+ /* According to ARB_framebuffer_sRGB, we should return LINEAR
+ * if the sRGB conversion is unsupported. */
+ *params = GL_LINEAR;
+ }
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+ if (!ctx->Extensions.ARB_framebuffer_object) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ return;
+ }
+ else {
+ gl_format format = att->Renderbuffer->Format;
+ if (format == MESA_FORMAT_CI8 || format == MESA_FORMAT_S8) {
+ /* special cases */
+ *params = GL_INDEX;
+ }
+ else {
+ *params = _mesa_get_format_datatype(format);
+ }
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+ if (!ctx->Extensions.ARB_framebuffer_object) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ else if (att->Texture) {
+ const struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, att->Texture, att->Texture->Target,
+ att->TextureLevel);
+ if (texImage) {
+ *params = get_component_bits(pname, texImage->_BaseFormat,
+ texImage->TexFormat);
+ }
+ else {
+ *params = 0;
+ }
+ }
+ else if (att->Renderbuffer) {
+ *params = get_component_bits(pname, att->Renderbuffer->_BaseFormat,
+ att->Renderbuffer->Format);
+ }
+ else {
+ *params = 0;
+ }
+ return;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GenerateMipmapEXT(GLenum target)
+{
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_CUBE_MAP:
+ /* OK, legal value */
+ break;
+ default:
+ /* XXX need to implement GL_TEXTURE_1D_ARRAY and GL_TEXTURE_2D_ARRAY */
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");
+ return;
+ }
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+
+ if (texObj->BaseLevel >= texObj->MaxLevel) {
+ /* nothing to do */
+ return;
+ }
+
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP &&
+ !_mesa_cube_complete(texObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGenerateMipmap(incomplete cube map)");
+ return;
+ }
+
+ _mesa_lock_texture(ctx, texObj);
+ if (target == GL_TEXTURE_CUBE_MAP) {
+ GLuint face;
+ for (face = 0; face < 6; face++)
+ ctx->Driver.GenerateMipmap(ctx,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face,
+ texObj);
+ }
+ else {
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+ _mesa_unlock_texture(ctx, texObj);
+}
+
+
+#if FEATURE_EXT_framebuffer_blit
+
+static const struct gl_renderbuffer_attachment *
+find_attachment(const struct gl_framebuffer *fb, const struct gl_renderbuffer *rb)
+{
+ GLuint i;
+ for (i = 0; i < Elements(fb->Attachment); i++) {
+ if (fb->Attachment[i].Renderbuffer == rb)
+ return &fb->Attachment[i];
+ }
+ return NULL;
+}
+
+
+
+/**
+ * Blit rectangular region, optionally from one framebuffer to another.
+ *
+ * Note, if the src buffer is multisampled and the dest is not, this is
+ * when the samples must be resolved to a single color.
+ */
+void GLAPIENTRY
+_mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT |
+ GL_STENCIL_BUFFER_BIT);
+ const struct gl_framebuffer *readFb, *drawFb;
+ const struct gl_renderbuffer *colorReadRb, *colorDrawRb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ readFb = ctx->ReadBuffer;
+ drawFb = ctx->DrawBuffer;
+
+ if (!readFb || !drawFb) {
+ /* This will normally never happen but someday we may want to
+ * support MakeCurrent() with no drawables.
+ */
+ return;
+ }
+
+ /* check for complete framebuffers */
+ if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
+ readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glBlitFramebufferEXT(incomplete draw/read buffers)");
+ return;
+ }
+
+ if (filter != GL_NEAREST && filter != GL_LINEAR) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(filter)");
+ return;
+ }
+
+ if (mask & ~legalMaskBits) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
+ return;
+ }
+
+ /* depth/stencil must be blitted with nearest filtering */
+ if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
+ && filter != GL_NEAREST) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter");
+ return;
+ }
+
+ /* get color read/draw renderbuffers */
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ colorReadRb = readFb->_ColorReadBuffer;
+ colorDrawRb = drawFb->_ColorDrawBuffers[0];
+ }
+ else {
+ colorReadRb = colorDrawRb = NULL;
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ struct gl_renderbuffer *readRb = readFb->_StencilBuffer;
+ struct gl_renderbuffer *drawRb = drawFb->_StencilBuffer;
+ if (!readRb ||
+ !drawRb ||
+ _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
+ _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(stencil buffer size mismatch");
+ return;
+ }
+ }
+
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ struct gl_renderbuffer *readRb = readFb->_DepthBuffer;
+ struct gl_renderbuffer *drawRb = drawFb->_DepthBuffer;
+ if (!readRb ||
+ !drawRb ||
+ _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
+ _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(depth buffer size mismatch");
+ return;
+ }
+ }
+
+ if (readFb->Visual.samples > 0 &&
+ drawFb->Visual.samples > 0 &&
+ readFb->Visual.samples != drawFb->Visual.samples) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(mismatched samples");
+ return;
+ }
+
+ /* extra checks for multisample copies... */
+ if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
+ /* src and dest region sizes must be the same */
+ if (srcX1 - srcX0 != dstX1 - dstX0 ||
+ srcY1 - srcY0 != dstY1 - dstY0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(bad src/dst multisample region sizes");
+ return;
+ }
+
+ /* color formats must match */
+ if (colorReadRb &&
+ colorDrawRb &&
+ colorReadRb->Format != colorDrawRb->Format) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(bad src/dst multisample pixel formats");
+ return;
+ }
+ }
+
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT");
+ return;
+ }
+
+ /* Debug code */
+ if (DEBUG_BLIT) {
+ printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d,"
+ " 0x%x, 0x%x)\n",
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter);
+ if (colorReadRb) {
+ const struct gl_renderbuffer_attachment *att;
+
+ att = find_attachment(readFb, colorReadRb);
+ printf(" Src FBO %u RB %u (%dx%d) ",
+ readFb->Name, colorReadRb->Name,
+ colorReadRb->Width, colorReadRb->Height);
+ if (att && att->Texture) {
+ printf("Tex %u tgt 0x%x level %u face %u",
+ att->Texture->Name,
+ att->Texture->Target,
+ att->TextureLevel,
+ att->CubeMapFace);
+ }
+ printf("\n");
+
+ att = find_attachment(drawFb, colorDrawRb);
+ printf(" Dst FBO %u RB %u (%dx%d) ",
+ drawFb->Name, colorDrawRb->Name,
+ colorDrawRb->Width, colorDrawRb->Height);
+ if (att && att->Texture) {
+ printf("Tex %u tgt 0x%x level %u face %u",
+ att->Texture->Name,
+ att->Texture->Target,
+ att->TextureLevel,
+ att->CubeMapFace);
+ }
+ printf("\n");
+ }
+ }
+
+ ASSERT(ctx->Driver.BlitFramebuffer);
+ ctx->Driver.BlitFramebuffer(ctx,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter);
+}
+#endif /* FEATURE_EXT_framebuffer_blit */
+
+#if FEATURE_ARB_geometry_shader4
+void GLAPIENTRY
+_mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
+ GLuint texture, GLint level)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTextureARB "
+ "not implemented!");
+}
+
+void GLAPIENTRY
+_mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
+ GLuint texture, GLint level, GLenum face)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTextureFaceARB "
+ "not implemented!");
+}
+#endif /* FEATURE_ARB_geometry_shader4 */
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 100694c67..4a039338d 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1,3367 +1,3364 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.7
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 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
- * 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.
- */
-
-/**
- * \file mtypes.h
- * Main Mesa data structures.
- *
- * Please try to mark derived values with a leading underscore ('_').
- */
-
-#ifndef MTYPES_H
-#define MTYPES_H
-
-
-#include "main/glheader.h"
-#include "main/config.h"
-#include "main/mfeatures.h"
-#include "glapi/glapi.h"
-#include "math/m_matrix.h" /* GLmatrix */
-#include "main/simple_list.h" /* struct simple_node */
-#include "main/formats.h" /* MESA_FORMAT_COUNT */
-
-
-/**
- * Color channel data type.
- */
-#if CHAN_BITS == 8
- typedef GLubyte GLchan;
-#define CHAN_MAX 255
-#define CHAN_MAXF 255.0F
-#define CHAN_TYPE GL_UNSIGNED_BYTE
-#elif CHAN_BITS == 16
- typedef GLushort GLchan;
-#define CHAN_MAX 65535
-#define CHAN_MAXF 65535.0F
-#define CHAN_TYPE GL_UNSIGNED_SHORT
-#elif CHAN_BITS == 32
- typedef GLfloat GLchan;
-#define CHAN_MAX 1.0
-#define CHAN_MAXF 1.0F
-#define CHAN_TYPE GL_FLOAT
-#else
-#error "illegal number of color channel bits"
-#endif
-
-
-/**
- * Stencil buffer data type.
- */
-#if STENCIL_BITS==8
- typedef GLubyte GLstencil;
-#elif STENCIL_BITS==16
- typedef GLushort GLstencil;
-#else
-# error "illegal number of stencil bits"
-#endif
-
-
-/**
- * \name 64-bit extension of GLbitfield.
- */
-/*@{*/
-typedef GLuint64 GLbitfield64;
-
-#define BITFIELD64_ONE 1ULL
-#define BITFIELD64_ALLONES ~0ULL
-
-/** Set a single bit */
-#define BITFIELD64_BIT(b) (BITFIELD64_ONE << (b))
-
-/** Set a mask of the least significant \c b bits */
-#define BITFIELD64_MASK(b) (((b) >= 64) ? BITFIELD64_ALLONES : \
- (BITFIELD64_BIT(b) - 1))
-
-/**
- * Set all bits from l (low bit) to h (high bit), inclusive.
- *
- * \note \C BITFIELD_64_RANGE(0, 63) return 64 set bits.
- */
-#define BITFIELD64_RANGE(l, h) (BITFIELD64_MASK((h) + 1) & ~BITFIELD64_MASK(l))
-/*@}*/
-
-
-/**
- * \name Some forward type declarations
- */
-/*@{*/
-struct _mesa_HashTable;
-struct gl_attrib_node;
-struct gl_list_extensions;
-struct gl_meta_state;
-struct gl_pixelstore_attrib;
-struct gl_program_cache;
-struct gl_texture_format;
-struct gl_texture_image;
-struct gl_texture_object;
-struct gl_context;
-struct st_context;
-/*@}*/
-
-
-/** Extra draw modes beyond GL_POINTS, GL_TRIANGLE_FAN, etc */
-#define PRIM_OUTSIDE_BEGIN_END (GL_POLYGON+1)
-#define PRIM_INSIDE_UNKNOWN_PRIM (GL_POLYGON+2)
-#define PRIM_UNKNOWN (GL_POLYGON+3)
-
-
-/**
- * Shader stages. Note that these will become 5 with tessellation.
- * These MUST have the same values as gallium's PIPE_SHADER_*
- */
-typedef enum
-{
- MESA_SHADER_VERTEX = 0,
- MESA_SHADER_FRAGMENT = 1,
- MESA_SHADER_GEOMETRY = 2,
- MESA_SHADER_TYPES = 3
-} gl_shader_type;
-
-
-
-/**
- * Indexes for vertex program attributes.
- * GL_NV_vertex_program aliases generic attributes over the conventional
- * attributes. In GL_ARB_vertex_program shader the aliasing is optional.
- * In GL_ARB_vertex_shader / OpenGL 2.0 the aliasing is disallowed (the
- * generic attributes are distinct/separate).
- */
-typedef enum
-{
- VERT_ATTRIB_POS = 0,
- VERT_ATTRIB_WEIGHT = 1,
- VERT_ATTRIB_NORMAL = 2,
- VERT_ATTRIB_COLOR0 = 3,
- VERT_ATTRIB_COLOR1 = 4,
- VERT_ATTRIB_FOG = 5,
- VERT_ATTRIB_COLOR_INDEX = 6,
- VERT_ATTRIB_POINT_SIZE = 6, /*alias*/
- VERT_ATTRIB_EDGEFLAG = 7,
- VERT_ATTRIB_TEX0 = 8,
- VERT_ATTRIB_TEX1 = 9,
- VERT_ATTRIB_TEX2 = 10,
- VERT_ATTRIB_TEX3 = 11,
- VERT_ATTRIB_TEX4 = 12,
- VERT_ATTRIB_TEX5 = 13,
- VERT_ATTRIB_TEX6 = 14,
- VERT_ATTRIB_TEX7 = 15,
- VERT_ATTRIB_GENERIC0 = 16,
- VERT_ATTRIB_GENERIC1 = 17,
- VERT_ATTRIB_GENERIC2 = 18,
- VERT_ATTRIB_GENERIC3 = 19,
- VERT_ATTRIB_GENERIC4 = 20,
- VERT_ATTRIB_GENERIC5 = 21,
- VERT_ATTRIB_GENERIC6 = 22,
- VERT_ATTRIB_GENERIC7 = 23,
- VERT_ATTRIB_GENERIC8 = 24,
- VERT_ATTRIB_GENERIC9 = 25,
- VERT_ATTRIB_GENERIC10 = 26,
- VERT_ATTRIB_GENERIC11 = 27,
- VERT_ATTRIB_GENERIC12 = 28,
- VERT_ATTRIB_GENERIC13 = 29,
- VERT_ATTRIB_GENERIC14 = 30,
- VERT_ATTRIB_GENERIC15 = 31,
- VERT_ATTRIB_MAX = 32
-} gl_vert_attrib;
-
-/**
- * Bitflags for vertex attributes.
- * These are used in bitfields in many places.
- */
-/*@{*/
-#define VERT_BIT_POS (1 << VERT_ATTRIB_POS)
-#define VERT_BIT_WEIGHT (1 << VERT_ATTRIB_WEIGHT)
-#define VERT_BIT_NORMAL (1 << VERT_ATTRIB_NORMAL)
-#define VERT_BIT_COLOR0 (1 << VERT_ATTRIB_COLOR0)
-#define VERT_BIT_COLOR1 (1 << VERT_ATTRIB_COLOR1)
-#define VERT_BIT_FOG (1 << VERT_ATTRIB_FOG)
-#define VERT_BIT_COLOR_INDEX (1 << VERT_ATTRIB_COLOR_INDEX)
-#define VERT_BIT_EDGEFLAG (1 << VERT_ATTRIB_EDGEFLAG)
-#define VERT_BIT_TEX0 (1 << VERT_ATTRIB_TEX0)
-#define VERT_BIT_TEX1 (1 << VERT_ATTRIB_TEX1)
-#define VERT_BIT_TEX2 (1 << VERT_ATTRIB_TEX2)
-#define VERT_BIT_TEX3 (1 << VERT_ATTRIB_TEX3)
-#define VERT_BIT_TEX4 (1 << VERT_ATTRIB_TEX4)
-#define VERT_BIT_TEX5 (1 << VERT_ATTRIB_TEX5)
-#define VERT_BIT_TEX6 (1 << VERT_ATTRIB_TEX6)
-#define VERT_BIT_TEX7 (1 << VERT_ATTRIB_TEX7)
-#define VERT_BIT_GENERIC0 (1 << VERT_ATTRIB_GENERIC0)
-#define VERT_BIT_GENERIC1 (1 << VERT_ATTRIB_GENERIC1)
-#define VERT_BIT_GENERIC2 (1 << VERT_ATTRIB_GENERIC2)
-#define VERT_BIT_GENERIC3 (1 << VERT_ATTRIB_GENERIC3)
-#define VERT_BIT_GENERIC4 (1 << VERT_ATTRIB_GENERIC4)
-#define VERT_BIT_GENERIC5 (1 << VERT_ATTRIB_GENERIC5)
-#define VERT_BIT_GENERIC6 (1 << VERT_ATTRIB_GENERIC6)
-#define VERT_BIT_GENERIC7 (1 << VERT_ATTRIB_GENERIC7)
-#define VERT_BIT_GENERIC8 (1 << VERT_ATTRIB_GENERIC8)
-#define VERT_BIT_GENERIC9 (1 << VERT_ATTRIB_GENERIC9)
-#define VERT_BIT_GENERIC10 (1 << VERT_ATTRIB_GENERIC10)
-#define VERT_BIT_GENERIC11 (1 << VERT_ATTRIB_GENERIC11)
-#define VERT_BIT_GENERIC12 (1 << VERT_ATTRIB_GENERIC12)
-#define VERT_BIT_GENERIC13 (1 << VERT_ATTRIB_GENERIC13)
-#define VERT_BIT_GENERIC14 (1 << VERT_ATTRIB_GENERIC14)
-#define VERT_BIT_GENERIC15 (1 << VERT_ATTRIB_GENERIC15)
-
-#define VERT_BIT_TEX(u) (1 << (VERT_ATTRIB_TEX0 + (u)))
-#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g)))
-/*@}*/
-
-
-/**
- * Indexes for vertex program result attributes
- */
-typedef enum
-{
- VERT_RESULT_HPOS = 0,
- VERT_RESULT_COL0 = 1,
- VERT_RESULT_COL1 = 2,
- VERT_RESULT_FOGC = 3,
- VERT_RESULT_TEX0 = 4,
- VERT_RESULT_TEX1 = 5,
- VERT_RESULT_TEX2 = 6,
- VERT_RESULT_TEX3 = 7,
- VERT_RESULT_TEX4 = 8,
- VERT_RESULT_TEX5 = 9,
- VERT_RESULT_TEX6 = 10,
- VERT_RESULT_TEX7 = 11,
- VERT_RESULT_PSIZ = 12,
- VERT_RESULT_BFC0 = 13,
- VERT_RESULT_BFC1 = 14,
- VERT_RESULT_EDGE = 15,
- VERT_RESULT_VAR0 = 16, /**< shader varying */
- VERT_RESULT_MAX = (VERT_RESULT_VAR0 + MAX_VARYING)
-} gl_vert_result;
-
-
-/*********************************************/
-
-/**
- * Indexes for geometry program attributes.
- */
-typedef enum
-{
- GEOM_ATTRIB_POSITION = 0,
- GEOM_ATTRIB_COLOR0 = 1,
- GEOM_ATTRIB_COLOR1 = 2,
- GEOM_ATTRIB_SECONDARY_COLOR0 = 3,
- GEOM_ATTRIB_SECONDARY_COLOR1 = 4,
- GEOM_ATTRIB_FOG_FRAG_COORD = 5,
- GEOM_ATTRIB_POINT_SIZE = 6,
- GEOM_ATTRIB_CLIP_VERTEX = 7,
- GEOM_ATTRIB_PRIMITIVE_ID = 8,
- GEOM_ATTRIB_TEX_COORD = 9,
-
- GEOM_ATTRIB_VAR0 = 16,
- GEOM_ATTRIB_MAX = (GEOM_ATTRIB_VAR0 + MAX_VARYING)
-} gl_geom_attrib;
-
-/**
- * Bitflags for geometry attributes.
- * These are used in bitfields in many places.
- */
-/*@{*/
-#define GEOM_BIT_COLOR0 (1 << GEOM_ATTRIB_COLOR0)
-#define GEOM_BIT_COLOR1 (1 << GEOM_ATTRIB_COLOR1)
-#define GEOM_BIT_SCOLOR0 (1 << GEOM_ATTRIB_SECONDARY_COLOR0)
-#define GEOM_BIT_SCOLOR1 (1 << GEOM_ATTRIB_SECONDARY_COLOR1)
-#define GEOM_BIT_TEX_COORD (1 << GEOM_ATTRIB_TEX_COORD)
-#define GEOM_BIT_FOG_COORD (1 << GEOM_ATTRIB_FOG_FRAG_COORD)
-#define GEOM_BIT_POSITION (1 << GEOM_ATTRIB_POSITION)
-#define GEOM_BIT_POINT_SIDE (1 << GEOM_ATTRIB_POINT_SIZE)
-#define GEOM_BIT_CLIP_VERTEX (1 << GEOM_ATTRIB_CLIP_VERTEX)
-#define GEOM_BIT_PRIM_ID (1 << GEOM_ATTRIB_PRIMITIVE_ID)
-#define GEOM_BIT_VAR0 (1 << GEOM_ATTRIB_VAR0)
-
-#define GEOM_BIT_VAR(g) (1 << (GEOM_BIT_VAR0 + (g)))
-/*@}*/
-
-
-/**
- * Indexes for geometry program result attributes
- */
-typedef enum
-{
- GEOM_RESULT_POS = 0,
- GEOM_RESULT_COL0 = 1,
- GEOM_RESULT_COL1 = 2,
- GEOM_RESULT_SCOL0 = 3,
- GEOM_RESULT_SCOL1 = 4,
- GEOM_RESULT_FOGC = 5,
- GEOM_RESULT_TEX0 = 6,
- GEOM_RESULT_TEX1 = 7,
- GEOM_RESULT_TEX2 = 8,
- GEOM_RESULT_TEX3 = 9,
- GEOM_RESULT_TEX4 = 10,
- GEOM_RESULT_TEX5 = 11,
- GEOM_RESULT_TEX6 = 12,
- GEOM_RESULT_TEX7 = 13,
- GEOM_RESULT_PSIZ = 14,
- GEOM_RESULT_CLPV = 15,
- GEOM_RESULT_PRID = 16,
- GEOM_RESULT_LAYR = 17,
- GEOM_RESULT_VAR0 = 18, /**< shader varying, should really be 16 */
- /* ### we need to -2 because var0 is 18 instead 16 like in the others */
- GEOM_RESULT_MAX = (GEOM_RESULT_VAR0 + MAX_VARYING - 2)
-} gl_geom_result;
-
-
-/**
- * Indexes for fragment program input attributes.
- */
-typedef enum
-{
- FRAG_ATTRIB_WPOS = 0,
- FRAG_ATTRIB_COL0 = 1,
- FRAG_ATTRIB_COL1 = 2,
- FRAG_ATTRIB_FOGC = 3,
- FRAG_ATTRIB_TEX0 = 4,
- FRAG_ATTRIB_TEX1 = 5,
- FRAG_ATTRIB_TEX2 = 6,
- FRAG_ATTRIB_TEX3 = 7,
- FRAG_ATTRIB_TEX4 = 8,
- FRAG_ATTRIB_TEX5 = 9,
- FRAG_ATTRIB_TEX6 = 10,
- FRAG_ATTRIB_TEX7 = 11,
- FRAG_ATTRIB_FACE = 12, /**< front/back face */
- FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */
- FRAG_ATTRIB_VAR0 = 14, /**< shader varying */
- FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
-} gl_frag_attrib;
-
-/**
- * Bitflags for fragment program input attributes.
- */
-/*@{*/
-#define FRAG_BIT_WPOS (1 << FRAG_ATTRIB_WPOS)
-#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0)
-#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1)
-#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC)
-#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE)
-#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC)
-#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0)
-#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1)
-#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2)
-#define FRAG_BIT_TEX3 (1 << FRAG_ATTRIB_TEX3)
-#define FRAG_BIT_TEX4 (1 << FRAG_ATTRIB_TEX4)
-#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5)
-#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6)
-#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7)
-#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0)
-
-#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U))
-#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V))
-
-#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \
- FRAG_BIT_TEX1| \
- FRAG_BIT_TEX2| \
- FRAG_BIT_TEX3| \
- FRAG_BIT_TEX4| \
- FRAG_BIT_TEX5| \
- FRAG_BIT_TEX6| \
- FRAG_BIT_TEX7)
-/*@}*/
-
-
-/**
- * Fragment program results
- */
-typedef enum
-{
- FRAG_RESULT_DEPTH = 0,
- FRAG_RESULT_STENCIL = 1,
- FRAG_RESULT_COLOR = 2,
- FRAG_RESULT_DATA0 = 3,
- FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
-} gl_frag_result;
-
-
-/**
- * Indexes for all renderbuffers
- */
-typedef enum
-{
- /* the four standard color buffers */
- BUFFER_FRONT_LEFT,
- BUFFER_BACK_LEFT,
- BUFFER_FRONT_RIGHT,
- BUFFER_BACK_RIGHT,
- BUFFER_DEPTH,
- BUFFER_STENCIL,
- BUFFER_ACCUM,
- /* optional aux buffer */
- BUFFER_AUX0,
- /* generic renderbuffers */
- BUFFER_COLOR0,
- BUFFER_COLOR1,
- BUFFER_COLOR2,
- BUFFER_COLOR3,
- BUFFER_COLOR4,
- BUFFER_COLOR5,
- BUFFER_COLOR6,
- BUFFER_COLOR7,
- BUFFER_COUNT
-} gl_buffer_index;
-
-/**
- * Bit flags for all renderbuffers
- */
-#define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT)
-#define BUFFER_BIT_BACK_LEFT (1 << BUFFER_BACK_LEFT)
-#define BUFFER_BIT_FRONT_RIGHT (1 << BUFFER_FRONT_RIGHT)
-#define BUFFER_BIT_BACK_RIGHT (1 << BUFFER_BACK_RIGHT)
-#define BUFFER_BIT_AUX0 (1 << BUFFER_AUX0)
-#define BUFFER_BIT_AUX1 (1 << BUFFER_AUX1)
-#define BUFFER_BIT_AUX2 (1 << BUFFER_AUX2)
-#define BUFFER_BIT_AUX3 (1 << BUFFER_AUX3)
-#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH)
-#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL)
-#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM)
-#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0)
-#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1)
-#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2)
-#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3)
-#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4)
-#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5)
-#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6)
-#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7)
-
-/**
- * Mask of all the color buffer bits (but not accum).
- */
-#define BUFFER_BITS_COLOR (BUFFER_BIT_FRONT_LEFT | \
- BUFFER_BIT_BACK_LEFT | \
- BUFFER_BIT_FRONT_RIGHT | \
- BUFFER_BIT_BACK_RIGHT | \
- BUFFER_BIT_AUX0 | \
- BUFFER_BIT_COLOR0 | \
- BUFFER_BIT_COLOR1 | \
- BUFFER_BIT_COLOR2 | \
- BUFFER_BIT_COLOR3 | \
- BUFFER_BIT_COLOR4 | \
- BUFFER_BIT_COLOR5 | \
- BUFFER_BIT_COLOR6 | \
- BUFFER_BIT_COLOR7)
-
-
-/**
- * Framebuffer configuration (aka visual / pixelformat)
- * Note: some of these fields should be boolean, but it appears that
- * code in drivers/dri/common/util.c requires int-sized fields.
- */
-struct gl_config
-{
- GLboolean rgbMode;
- GLboolean floatMode;
- GLboolean colorIndexMode; /* XXX is this used anywhere? */
- GLuint doubleBufferMode;
- GLuint stereoMode;
-
- GLboolean haveAccumBuffer;
- GLboolean haveDepthBuffer;
- GLboolean haveStencilBuffer;
-
- GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */
- GLuint redMask, greenMask, blueMask, alphaMask;
- GLint rgbBits; /* total bits for rgb */
- GLint indexBits; /* total bits for colorindex */
-
- GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
- GLint depthBits;
- GLint stencilBits;
-
- GLint numAuxBuffers;
-
- GLint level;
-
- /* EXT_visual_rating / GLX 1.2 */
- GLint visualRating;
-
- /* EXT_visual_info / GLX 1.2 */
- GLint transparentPixel;
- /* colors are floats scaled to ints */
- GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
- GLint transparentIndex;
-
- /* ARB_multisample / SGIS_multisample */
- GLint sampleBuffers;
- GLint samples;
-
- /* SGIX_pbuffer / GLX 1.3 */
- GLint maxPbufferWidth;
- GLint maxPbufferHeight;
- GLint maxPbufferPixels;
- GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */
- GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */
-
- /* OML_swap_method */
- GLint swapMethod;
-
- /* EXT_texture_from_pixmap */
- GLint bindToTextureRgb;
- GLint bindToTextureRgba;
- GLint bindToMipmapTexture;
- GLint bindToTextureTargets;
- GLint yInverted;
-
- /* EXT_framebuffer_sRGB */
- GLint sRGBCapable;
-};
-
-
-/**
- * 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.
- */
-/*@{*/
-#define MAT_ATTRIB_FRONT_AMBIENT 0
-#define MAT_ATTRIB_BACK_AMBIENT 1
-#define MAT_ATTRIB_FRONT_DIFFUSE 2
-#define MAT_ATTRIB_BACK_DIFFUSE 3
-#define MAT_ATTRIB_FRONT_SPECULAR 4
-#define MAT_ATTRIB_BACK_SPECULAR 5
-#define MAT_ATTRIB_FRONT_EMISSION 6
-#define MAT_ATTRIB_BACK_EMISSION 7
-#define MAT_ATTRIB_FRONT_SHININESS 8
-#define MAT_ATTRIB_BACK_SHININESS 9
-#define MAT_ATTRIB_FRONT_INDEXES 10
-#define MAT_ATTRIB_BACK_INDEXES 11
-#define MAT_ATTRIB_MAX 12
-
-#define MAT_ATTRIB_AMBIENT(f) (MAT_ATTRIB_FRONT_AMBIENT+(f))
-#define MAT_ATTRIB_DIFFUSE(f) (MAT_ATTRIB_FRONT_DIFFUSE+(f))
-#define MAT_ATTRIB_SPECULAR(f) (MAT_ATTRIB_FRONT_SPECULAR+(f))
-#define MAT_ATTRIB_EMISSION(f) (MAT_ATTRIB_FRONT_EMISSION+(f))
-#define MAT_ATTRIB_SHININESS(f)(MAT_ATTRIB_FRONT_SHININESS+(f))
-#define MAT_ATTRIB_INDEXES(f) (MAT_ATTRIB_FRONT_INDEXES+(f))
-
-#define MAT_INDEX_AMBIENT 0
-#define MAT_INDEX_DIFFUSE 1
-#define MAT_INDEX_SPECULAR 2
-
-#define MAT_BIT_FRONT_AMBIENT (1<<MAT_ATTRIB_FRONT_AMBIENT)
-#define MAT_BIT_BACK_AMBIENT (1<<MAT_ATTRIB_BACK_AMBIENT)
-#define MAT_BIT_FRONT_DIFFUSE (1<<MAT_ATTRIB_FRONT_DIFFUSE)
-#define MAT_BIT_BACK_DIFFUSE (1<<MAT_ATTRIB_BACK_DIFFUSE)
-#define MAT_BIT_FRONT_SPECULAR (1<<MAT_ATTRIB_FRONT_SPECULAR)
-#define MAT_BIT_BACK_SPECULAR (1<<MAT_ATTRIB_BACK_SPECULAR)
-#define MAT_BIT_FRONT_EMISSION (1<<MAT_ATTRIB_FRONT_EMISSION)
-#define MAT_BIT_BACK_EMISSION (1<<MAT_ATTRIB_BACK_EMISSION)
-#define MAT_BIT_FRONT_SHININESS (1<<MAT_ATTRIB_FRONT_SHININESS)
-#define MAT_BIT_BACK_SHININESS (1<<MAT_ATTRIB_BACK_SHININESS)
-#define MAT_BIT_FRONT_INDEXES (1<<MAT_ATTRIB_FRONT_INDEXES)
-#define MAT_BIT_BACK_INDEXES (1<<MAT_ATTRIB_BACK_INDEXES)
-
-
-#define FRONT_MATERIAL_BITS (MAT_BIT_FRONT_EMISSION | \
- MAT_BIT_FRONT_AMBIENT | \
- MAT_BIT_FRONT_DIFFUSE | \
- MAT_BIT_FRONT_SPECULAR | \
- MAT_BIT_FRONT_SHININESS | \
- MAT_BIT_FRONT_INDEXES)
-
-#define BACK_MATERIAL_BITS (MAT_BIT_BACK_EMISSION | \
- MAT_BIT_BACK_AMBIENT | \
- MAT_BIT_BACK_DIFFUSE | \
- MAT_BIT_BACK_SPECULAR | \
- MAT_BIT_BACK_SHININESS | \
- MAT_BIT_BACK_INDEXES)
-
-#define ALL_MATERIAL_BITS (FRONT_MATERIAL_BITS | BACK_MATERIAL_BITS)
-/*@}*/
-
-
-#define EXP_TABLE_SIZE 512 /**< Specular exponent lookup table sizes */
-#define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */
-
-/**
- * Material shininess lookup table.
- */
-struct gl_shine_tab
-{
- struct gl_shine_tab *next, *prev;
- GLfloat tab[SHINE_TABLE_SIZE+1];
- GLfloat shininess;
- GLuint refcount;
-};
-
-
-/**
- * Light source state.
- */
-struct gl_light
-{
- struct gl_light *next; /**< double linked list with sentinel */
- struct gl_light *prev;
-
- GLfloat Ambient[4]; /**< ambient color */
- GLfloat Diffuse[4]; /**< diffuse color */
- GLfloat Specular[4]; /**< specular color */
- GLfloat EyePosition[4]; /**< position in eye coordinates */
- GLfloat SpotDirection[4]; /**< spotlight direction in eye coordinates */
- GLfloat SpotExponent;
- GLfloat SpotCutoff; /**< in degrees */
- GLfloat _CosCutoffNeg; /**< = cos(SpotCutoff) */
- GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */
- GLfloat ConstantAttenuation;
- GLfloat LinearAttenuation;
- GLfloat QuadraticAttenuation;
- GLboolean Enabled; /**< On/off flag */
-
- /**
- * \name Derived fields
- */
- /*@{*/
- GLbitfield _Flags; /**< State */
-
- GLfloat _Position[4]; /**< position in eye/obj coordinates */
- GLfloat _VP_inf_norm[3]; /**< Norm direction to infinite light */
- GLfloat _h_inf_norm[3]; /**< Norm( _VP_inf_norm + <0,0,1> ) */
- GLfloat _NormSpotDirection[4]; /**< normalized spotlight direction */
- GLfloat _VP_inf_spot_attenuation;
-
- GLfloat _SpotExpTable[EXP_TABLE_SIZE][2]; /**< to replace a pow() call */
- GLfloat _MatAmbient[2][3]; /**< material ambient * light ambient */
- GLfloat _MatDiffuse[2][3]; /**< material diffuse * light diffuse */
- GLfloat _MatSpecular[2][3]; /**< material spec * light specular */
- GLfloat _dli; /**< CI diffuse light intensity */
- GLfloat _sli; /**< CI specular light intensity */
- /*@}*/
-};
-
-
-/**
- * Light model state.
- */
-struct gl_lightmodel
-{
- GLfloat Ambient[4]; /**< ambient color */
- GLboolean LocalViewer; /**< Local (or infinite) view point? */
- GLboolean TwoSide; /**< Two (or one) sided lighting? */
- GLenum ColorControl; /**< either GL_SINGLE_COLOR
- * or GL_SEPARATE_SPECULAR_COLOR */
-};
-
-
-/**
- * Material state.
- */
-struct gl_material
-{
- GLfloat Attrib[MAT_ATTRIB_MAX][4];
-};
-
-
-/**
- * Accumulation buffer attribute group (GL_ACCUM_BUFFER_BIT)
- */
-struct gl_accum_attrib
-{
- GLfloat ClearColor[4]; /**< Accumulation buffer clear color */
-};
-
-
-/**
- * Color buffer attribute group (GL_COLOR_BUFFER_BIT).
- */
-struct gl_colorbuffer_attrib
-{
- GLuint ClearIndex; /**< Index to use for glClear */
- GLclampf ClearColor[4]; /**< Color to use for glClear */
-
- GLuint IndexMask; /**< Color index write mask */
- GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */
-
- GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */
-
- /**
- * \name alpha testing
- */
- /*@{*/
- GLboolean AlphaEnabled; /**< Alpha test enabled flag */
- GLenum AlphaFunc; /**< Alpha test function */
- GLclampf AlphaRef; /**< Alpha reference value */
- /*@}*/
-
- /**
- * \name Blending
- */
- /*@{*/
- GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */
- GLfloat BlendColor[4]; /**< Blending color */
- struct
- {
- GLenum SrcRGB; /**< RGB blend source term */
- GLenum DstRGB; /**< RGB blend dest term */
- GLenum SrcA; /**< Alpha blend source term */
- GLenum DstA; /**< Alpha blend dest term */
- GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
- GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
- } Blend[MAX_DRAW_BUFFERS];
- /** Are the blend func terms currently different for each buffer/target? */
- GLboolean _BlendFuncPerBuffer;
- /** Are the blend equations currently different for each buffer/target? */
- GLboolean _BlendEquationPerBuffer;
- /*@}*/
-
- /**
- * \name Logic op
- */
- /*@{*/
- GLenum LogicOp; /**< Logic operator */
- GLboolean IndexLogicOpEnabled; /**< Color index logic op enabled flag */
- GLboolean ColorLogicOpEnabled; /**< RGBA logic op enabled flag */
- GLboolean _LogicOpEnabled; /**< RGBA logic op + EXT_blend_logic_op enabled flag */
- /*@}*/
-
- GLboolean DitherFlag; /**< Dither enable flag */
-
- GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
- GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
-
- GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */
-};
-
-
-/**
- * Current attribute group (GL_CURRENT_BIT).
- */
-struct gl_current_attrib
-{
- /**
- * \name Current vertex attributes.
- * \note Values are valid only after FLUSH_VERTICES has been called.
- * \note Index and Edgeflag current values are stored as floats in the
- * SIX and SEVEN attribute slots.
- */
- GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */
-
- /**
- * \name Current raster position attributes (always valid).
- * \note This set of attributes is very similar to the SWvertex struct.
- */
- /*@{*/
- GLfloat RasterPos[4];
- GLfloat RasterDistance;
- GLfloat RasterColor[4];
- GLfloat RasterSecondaryColor[4];
- GLfloat RasterTexCoords[MAX_TEXTURE_COORD_UNITS][4];
- GLboolean RasterPosValid;
- /*@}*/
-};
-
-
-/**
- * Depth buffer attribute group (GL_DEPTH_BUFFER_BIT).
- */
-struct gl_depthbuffer_attrib
-{
- GLenum Func; /**< Function for depth buffer compare */
- GLclampd Clear; /**< Value to clear depth buffer to */
- GLboolean Test; /**< Depth buffering enabled flag */
- GLboolean Mask; /**< Depth buffer writable? */
- GLboolean BoundsTest; /**< GL_EXT_depth_bounds_test */
- GLfloat BoundsMin, BoundsMax;/**< GL_EXT_depth_bounds_test */
-};
-
-
-/**
- * Evaluator attribute group (GL_EVAL_BIT).
- */
-struct gl_eval_attrib
-{
- /**
- * \name Enable bits
- */
- /*@{*/
- GLboolean Map1Color4;
- GLboolean Map1Index;
- GLboolean Map1Normal;
- GLboolean Map1TextureCoord1;
- GLboolean Map1TextureCoord2;
- GLboolean Map1TextureCoord3;
- GLboolean Map1TextureCoord4;
- GLboolean Map1Vertex3;
- GLboolean Map1Vertex4;
- GLboolean Map1Attrib[16]; /* GL_NV_vertex_program */
- GLboolean Map2Color4;
- GLboolean Map2Index;
- GLboolean Map2Normal;
- GLboolean Map2TextureCoord1;
- GLboolean Map2TextureCoord2;
- GLboolean Map2TextureCoord3;
- GLboolean Map2TextureCoord4;
- GLboolean Map2Vertex3;
- GLboolean Map2Vertex4;
- GLboolean Map2Attrib[16]; /* GL_NV_vertex_program */
- GLboolean AutoNormal;
- /*@}*/
-
- /**
- * \name Map Grid endpoints and divisions and calculated du values
- */
- /*@{*/
- GLint MapGrid1un;
- GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du;
- GLint MapGrid2un, MapGrid2vn;
- GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du;
- GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv;
- /*@}*/
-};
-
-
-/**
- * Fog attribute group (GL_FOG_BIT).
- */
-struct gl_fog_attrib
-{
- GLboolean Enabled; /**< Fog enabled flag */
- GLfloat Color[4]; /**< Fog color */
- GLfloat Density; /**< Density >= 0.0 */
- GLfloat Start; /**< Start distance in eye coords */
- GLfloat End; /**< End distance in eye coords */
- GLfloat Index; /**< Fog index */
- GLenum Mode; /**< Fog mode */
- GLboolean ColorSumEnabled;
- GLenum FogCoordinateSource; /**< GL_EXT_fog_coord */
- GLfloat _Scale; /**< (End == Start) ? 1.0 : 1.0 / (End - Start) */
-};
-
-
-/**
- * Hint attribute group (GL_HINT_BIT).
- *
- * Values are always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE.
- */
-struct gl_hint_attrib
-{
- GLenum PerspectiveCorrection;
- GLenum PointSmooth;
- GLenum LineSmooth;
- GLenum PolygonSmooth;
- GLenum Fog;
- GLenum ClipVolumeClipping; /**< GL_EXT_clip_volume_hint */
- GLenum TextureCompression; /**< GL_ARB_texture_compression */
- GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */
-};
-
-/**
- * Light state flags.
- */
-/*@{*/
-#define LIGHT_SPOT 0x1
-#define LIGHT_LOCAL_VIEWER 0x2
-#define LIGHT_POSITIONAL 0x4
-#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER)
-/*@}*/
-
-
-/**
- * Lighting attribute group (GL_LIGHT_BIT).
- */
-struct gl_light_attrib
-{
- struct gl_light Light[MAX_LIGHTS]; /**< Array of light sources */
- struct gl_lightmodel Model; /**< Lighting model */
-
- /**
- * Must flush FLUSH_VERTICES before referencing:
- */
- /*@{*/
- struct gl_material Material; /**< Includes front & back values */
- /*@}*/
-
- GLboolean Enabled; /**< Lighting enabled flag */
- GLenum ShadeModel; /**< GL_FLAT or GL_SMOOTH */
- GLenum ProvokingVertex; /**< GL_EXT_provoking_vertex */
- GLenum ColorMaterialFace; /**< GL_FRONT, BACK or FRONT_AND_BACK */
- GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */
- GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */
- GLboolean ColorMaterialEnabled;
- GLenum ClampVertexColor;
-
- struct gl_light EnabledList; /**< List sentinel */
-
- /**
- * Derived state for optimizations:
- */
- /*@{*/
- GLboolean _NeedEyeCoords;
- GLboolean _NeedVertices; /**< Use fast shader? */
- GLbitfield _Flags; /**< LIGHT_* flags, see above */
- GLfloat _BaseColor[2][3];
- /*@}*/
-};
-
-
-/**
- * Line attribute group (GL_LINE_BIT).
- */
-struct gl_line_attrib
-{
- GLboolean SmoothFlag; /**< GL_LINE_SMOOTH enabled? */
- GLboolean StippleFlag; /**< GL_LINE_STIPPLE enabled? */
- GLushort StipplePattern; /**< Stipple pattern */
- GLint StippleFactor; /**< Stipple repeat factor */
- GLfloat Width; /**< Line width */
-};
-
-
-/**
- * Display list attribute group (GL_LIST_BIT).
- */
-struct gl_list_attrib
-{
- GLuint ListBase;
-};
-
-
-/**
- * Multisample attribute group (GL_MULTISAMPLE_BIT).
- */
-struct gl_multisample_attrib
-{
- GLboolean Enabled;
- GLboolean _Enabled; /**< true if Enabled and multisample buffer */
- GLboolean SampleAlphaToCoverage;
- GLboolean SampleAlphaToOne;
- GLboolean SampleCoverage;
- GLfloat SampleCoverageValue;
- GLboolean SampleCoverageInvert;
-};
-
-
-/**
- * A pixelmap (see glPixelMap)
- */
-struct gl_pixelmap
-{
- GLint Size;
- GLfloat Map[MAX_PIXEL_MAP_TABLE];
- GLubyte Map8[MAX_PIXEL_MAP_TABLE]; /**< converted to 8-bit color */
-};
-
-
-/**
- * Collection of all pixelmaps
- */
-struct gl_pixelmaps
-{
- struct gl_pixelmap RtoR; /**< i.e. GL_PIXEL_MAP_R_TO_R */
- struct gl_pixelmap GtoG;
- struct gl_pixelmap BtoB;
- struct gl_pixelmap AtoA;
- struct gl_pixelmap ItoR;
- struct gl_pixelmap ItoG;
- struct gl_pixelmap ItoB;
- struct gl_pixelmap ItoA;
- struct gl_pixelmap ItoI;
- struct gl_pixelmap StoS;
-};
-
-
-/**
- * Pixel attribute group (GL_PIXEL_MODE_BIT).
- */
-struct gl_pixel_attrib
-{
- GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */
-
- /*--- Begin Pixel Transfer State ---*/
- /* Fields are in the order in which they're applied... */
-
- /** Scale & Bias (index shift, offset) */
- /*@{*/
- GLfloat RedBias, RedScale;
- GLfloat GreenBias, GreenScale;
- GLfloat BlueBias, BlueScale;
- GLfloat AlphaBias, AlphaScale;
- GLfloat DepthBias, DepthScale;
- GLint IndexShift, IndexOffset;
- /*@}*/
-
- /* Pixel Maps */
- /* Note: actual pixel maps are not part of this attrib group */
- GLboolean MapColorFlag;
- GLboolean MapStencilFlag;
-
- /*--- End Pixel Transfer State ---*/
-
- /** glPixelZoom */
- GLfloat ZoomX, ZoomY;
-
- /** GL_SGI_texture_color_table */
- GLfloat TextureColorTableScale[4]; /**< RGBA */
- GLfloat TextureColorTableBias[4]; /**< RGBA */
-};
-
-
-/**
- * Point attribute group (GL_POINT_BIT).
- */
-struct gl_point_attrib
-{
- GLboolean SmoothFlag; /**< True if GL_POINT_SMOOTH is enabled */
- GLfloat Size; /**< User-specified point size */
- GLfloat Params[3]; /**< GL_EXT_point_parameters */
- GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */
- GLfloat Threshold; /**< GL_EXT_point_parameters */
- GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */
- GLboolean PointSprite; /**< GL_NV/ARB_point_sprite */
- GLboolean CoordReplace[MAX_TEXTURE_COORD_UNITS]; /**< GL_ARB_point_sprite*/
- GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */
- GLenum SpriteOrigin; /**< GL_ARB_point_sprite */
-};
-
-
-/**
- * Polygon attribute group (GL_POLYGON_BIT).
- */
-struct gl_polygon_attrib
-{
- GLenum FrontFace; /**< Either GL_CW or GL_CCW */
- GLenum FrontMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
- GLenum BackMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
- GLboolean _FrontBit; /**< 0=GL_CCW, 1=GL_CW */
- GLboolean CullFlag; /**< Culling on/off flag */
- GLboolean SmoothFlag; /**< True if GL_POLYGON_SMOOTH is enabled */
- GLboolean StippleFlag; /**< True if GL_POLYGON_STIPPLE is enabled */
- GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */
- GLfloat OffsetFactor; /**< Polygon offset factor, from user */
- GLfloat OffsetUnits; /**< Polygon offset units, from user */
- GLboolean OffsetPoint; /**< Offset in GL_POINT mode */
- GLboolean OffsetLine; /**< Offset in GL_LINE mode */
- GLboolean OffsetFill; /**< Offset in GL_FILL mode */
-};
-
-
-/**
- * Scissor attributes (GL_SCISSOR_BIT).
- */
-struct gl_scissor_attrib
-{
- GLboolean Enabled; /**< Scissor test enabled? */
- GLint X, Y; /**< Lower left corner of box */
- GLsizei Width, Height; /**< Size of box */
-};
-
-
-/**
- * Stencil attribute group (GL_STENCIL_BUFFER_BIT).
- *
- * Three sets of stencil data are tracked so that OpenGL 2.0,
- * GL_EXT_stencil_two_side, and GL_ATI_separate_stencil can all be supported
- * simultaneously. In each of the stencil state arrays, element 0 corresponds
- * to GL_FRONT. Element 1 corresponds to the OpenGL 2.0 /
- * GL_ATI_separate_stencil GL_BACK state. Element 2 corresponds to the
- * GL_EXT_stencil_two_side GL_BACK state.
- *
- * The derived value \c _BackFace is either 1 or 2 depending on whether or
- * not GL_STENCIL_TEST_TWO_SIDE_EXT is enabled.
- *
- * The derived value \c _TestTwoSide is set when the front-face and back-face
- * stencil state are different.
- */
-struct gl_stencil_attrib
-{
- GLboolean Enabled; /**< Enabled flag */
- GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */
- GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */
- GLboolean _Enabled; /**< Enabled and stencil buffer present */
- GLboolean _TestTwoSide;
- GLubyte _BackFace; /**< Current back stencil state (1 or 2) */
- GLenum Function[3]; /**< Stencil function */
- GLenum FailFunc[3]; /**< Fail function */
- GLenum ZPassFunc[3]; /**< Depth buffer pass function */
- GLenum ZFailFunc[3]; /**< Depth buffer fail function */
- GLint Ref[3]; /**< Reference value */
- GLuint ValueMask[3]; /**< Value mask */
- GLuint WriteMask[3]; /**< Write mask */
- GLuint Clear; /**< Clear value */
-};
-
-
-/**
- * An index for each type of texture object. These correspond to the GL
- * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc.
- * Note: the order is from highest priority to lowest priority.
- */
-typedef enum
-{
- TEXTURE_2D_ARRAY_INDEX,
- TEXTURE_1D_ARRAY_INDEX,
- TEXTURE_CUBE_INDEX,
- TEXTURE_3D_INDEX,
- TEXTURE_RECT_INDEX,
- TEXTURE_2D_INDEX,
- TEXTURE_1D_INDEX,
- NUM_TEXTURE_TARGETS
-} gl_texture_index;
-
-
-/**
- * Bit flags for each type of texture object
- * Used for Texture.Unit[]._ReallyEnabled flags.
- */
-/*@{*/
-#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX)
-#define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX)
-#define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX)
-#define TEXTURE_3D_BIT (1 << TEXTURE_3D_INDEX)
-#define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX)
-#define TEXTURE_2D_BIT (1 << TEXTURE_2D_INDEX)
-#define TEXTURE_1D_BIT (1 << TEXTURE_1D_INDEX)
-/*@}*/
-
-
-/**
- * TexGenEnabled flags.
- */
-/*@{*/
-#define S_BIT 1
-#define T_BIT 2
-#define R_BIT 4
-#define Q_BIT 8
-#define STR_BITS (S_BIT | T_BIT | R_BIT)
-/*@}*/
-
-
-/**
- * Bit flag versions of the corresponding GL_ constants.
- */
-/*@{*/
-#define TEXGEN_SPHERE_MAP 0x1
-#define TEXGEN_OBJ_LINEAR 0x2
-#define TEXGEN_EYE_LINEAR 0x4
-#define TEXGEN_REFLECTION_MAP_NV 0x8
-#define TEXGEN_NORMAL_MAP_NV 0x10
-
-#define TEXGEN_NEED_NORMALS (TEXGEN_SPHERE_MAP | \
- TEXGEN_REFLECTION_MAP_NV | \
- TEXGEN_NORMAL_MAP_NV)
-#define TEXGEN_NEED_EYE_COORD (TEXGEN_SPHERE_MAP | \
- TEXGEN_REFLECTION_MAP_NV | \
- TEXGEN_NORMAL_MAP_NV | \
- TEXGEN_EYE_LINEAR)
-/*@}*/
-
-
-
-/** Tex-gen enabled for texture unit? */
-#define ENABLE_TEXGEN(unit) (1 << (unit))
-
-/** Non-identity texture matrix for texture unit? */
-#define ENABLE_TEXMAT(unit) (1 << (unit))
-
-
-/**
- * Texel fetch function prototype. We use texel fetch functions to
- * extract RGBA, color indexes and depth components out of 1D, 2D and 3D
- * texture images. These functions help to isolate us from the gritty
- * details of all the various texture image encodings.
- *
- * \param texImage texture image.
- * \param col texel column.
- * \param row texel row.
- * \param img texel image level/layer.
- * \param texelOut output texel (up to 4 GLchans)
- */
-typedef void (*FetchTexelFuncC)( const struct gl_texture_image *texImage,
- GLint col, GLint row, GLint img,
- GLchan *texelOut );
-
-/**
- * As above, but returns floats.
- * Used for depth component images and for upcoming signed/float
- * texture images.
- */
-typedef void (*FetchTexelFuncF)( const struct gl_texture_image *texImage,
- GLint col, GLint row, GLint img,
- GLfloat *texelOut );
-
-
-typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage,
- GLint col, GLint row, GLint img,
- const void *texel);
-
-
-/**
- * Texture image state. Describes the dimensions of a texture image,
- * the texel format and pointers to Texel Fetch functions.
- */
-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.
- */
- GLuint TexFormat; /**< The actual format: MESA_FORMAT_x */
-
- GLuint Border; /**< 0 or 1 */
- GLuint Width; /**< = 2^WidthLog2 + 2*Border */
- GLuint Height; /**< = 2^HeightLog2 + 2*Border */
- GLuint Depth; /**< = 2^DepthLog2 + 2*Border */
- GLuint Width2; /**< = Width - 2*Border */
- GLuint Height2; /**< = Height - 2*Border */
- GLuint Depth2; /**< = Depth - 2*Border */
- GLuint WidthLog2; /**< = log2(Width2) */
- GLuint HeightLog2; /**< = log2(Height2) */
- GLuint DepthLog2; /**< = log2(Depth2) */
- GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */
- GLfloat WidthScale; /**< used for mipmap LOD computation */
- GLfloat HeightScale; /**< used for mipmap LOD computation */
- GLfloat DepthScale; /**< used for mipmap LOD computation */
- GLboolean IsClientData; /**< Data owned by client? */
- GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */
-
- struct gl_texture_object *TexObject; /**< Pointer back to parent object */
-
- FetchTexelFuncC FetchTexelc; /**< GLchan texel fetch function pointer */
- FetchTexelFuncF FetchTexelf; /**< Float texel fetch function pointer */
-
- GLuint RowStride; /**< Padded width in units of texels */
- GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to
- each 2D slice in 'Data', in texels */
- GLvoid *Data; /**< Image data, accessed via FetchTexel() */
-
- /**
- * \name For device driver:
- */
- /*@{*/
- void *DriverData; /**< Arbitrary device driver data */
- /*@}*/
-};
-
-
-/**
- * Indexes for cube map faces.
- */
-typedef enum
-{
- FACE_POS_X = 0,
- FACE_NEG_X = 1,
- FACE_POS_Y = 2,
- FACE_NEG_Y = 3,
- FACE_POS_Z = 4,
- FACE_NEG_Z = 5,
- MAX_FACES = 6
-} gl_face_index;
-
-
-/**
- * Texture object state. Contains the array of mipmap images, border color,
- * wrap modes, filter modes, shadow/texcompare state, and the per-texture
- * color palette.
- */
-struct gl_texture_object
-{
- _glthread_Mutex Mutex; /**< for thread safety */
- GLint RefCount; /**< reference count */
- GLuint Name; /**< the user-visible texture object ID */
- GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
- GLfloat Priority; /**< in [0,1] */
- union {
- GLfloat f[4];
- GLuint ui[4];
- GLint i[4];
- } BorderColor; /**< Interpreted according to texture format */
- GLenum WrapS; /**< S-axis texture image wrap mode */
- GLenum WrapT; /**< T-axis texture image wrap mode */
- GLenum WrapR; /**< R-axis texture image wrap mode */
- GLenum MinFilter; /**< minification filter */
- GLenum MagFilter; /**< magnification filter */
- GLfloat MinLod; /**< min lambda, OpenGL 1.2 */
- GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */
- GLfloat LodBias; /**< OpenGL 1.4 */
- GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */
- GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
- GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
- GLenum CompareMode; /**< GL_ARB_shadow */
- GLenum CompareFunc; /**< GL_ARB_shadow */
- GLfloat CompareFailValue; /**< GL_ARB_shadow_ambient */
- GLenum DepthMode; /**< GL_ARB_depth_texture */
- GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
- GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */
- GLint CropRect[4]; /**< GL_OES_draw_texture */
- GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */
- GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */
- GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLboolean _Complete; /**< Is texture object complete? */
- GLboolean _RenderToTexture; /**< Any rendering to this texture? */
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
- GLenum sRGBDecode; /**< GL_DECODE_EXT or GL_SKIP_DECODE_EXT */
-
- /** Actual texture images, indexed by [cube face] and [mipmap level] */
- struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
-
- /** 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
- * to instead use this struct as a base class for your own texture object
- * class. Driver->NewTextureObject() can be used to implement the
- * allocation.
- */
- void *DriverData; /**< Arbitrary device driver data */
-};
-
-
-/** Up to four combiner sources are possible with GL_NV_texture_env_combine4 */
-#define MAX_COMBINER_TERMS 4
-
-
-/**
- * Texture combine environment state.
- */
-struct gl_tex_env_combine_state
-{
- GLenum ModeRGB; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
- GLenum ModeA; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
- /** Source terms: GL_PRIMARY_COLOR, GL_TEXTURE, etc */
- GLenum SourceRGB[MAX_COMBINER_TERMS];
- GLenum SourceA[MAX_COMBINER_TERMS];
- /** Source operands: GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, etc */
- GLenum OperandRGB[MAX_COMBINER_TERMS];
- GLenum OperandA[MAX_COMBINER_TERMS];
- GLuint ScaleShiftRGB; /**< 0, 1 or 2 */
- GLuint ScaleShiftA; /**< 0, 1 or 2 */
- GLuint _NumArgsRGB; /**< Number of inputs used for the RGB combiner */
- GLuint _NumArgsA; /**< Number of inputs used for the A combiner */
-};
-
-
-/**
- * Texture coord generation state.
- */
-struct gl_texgen
-{
- GLenum Mode; /**< GL_EYE_LINEAR, GL_SPHERE_MAP, etc */
- GLbitfield _ModeBit; /**< TEXGEN_x bit corresponding to Mode */
- GLfloat ObjectPlane[4];
- GLfloat EyePlane[4];
-};
-
-
-/**
- * Texture unit state. Contains enable flags, texture environment/function/
- * combiners, texgen state, pointers to current texture objects and
- * post-filter color tables.
- */
-struct gl_texture_unit
-{
- GLbitfield Enabled; /**< bitmask of TEXTURE_*_BIT flags */
- GLbitfield _ReallyEnabled; /**< 0 or exactly one of TEXTURE_*_BIT flags */
-
- GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */
- GLfloat EnvColor[4];
-
- struct gl_texgen GenS;
- struct gl_texgen GenT;
- struct gl_texgen GenR;
- struct gl_texgen GenQ;
- GLbitfield TexGenEnabled; /**< Bitwise-OR of [STRQ]_BIT values */
- GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */
-
- GLfloat LodBias; /**< for biasing mipmap levels */
- GLenum BumpTarget;
- GLfloat RotMatrix[4]; /* 2x2 matrix */
-
- /**
- * \name GL_EXT_texture_env_combine
- */
- struct gl_tex_env_combine_state Combine;
-
- /**
- * Derived state based on \c EnvMode and the \c BaseFormat of the
- * currently enabled texture.
- */
- struct gl_tex_env_combine_state _EnvMode;
-
- /**
- * Currently enabled combiner state. This will point to either
- * \c Combine or \c _EnvMode.
- */
- struct gl_tex_env_combine_state *_CurrentCombine;
-
- /** Current texture object pointers */
- struct gl_texture_object *CurrentTex[NUM_TEXTURE_TARGETS];
-
- /** Points to highest priority, complete and enabled texture object */
- struct gl_texture_object *_Current;
-
- /** GL_SGI_texture_color_table */
- /*@{*/
- struct gl_color_table ColorTable;
- struct gl_color_table ProxyColorTable;
- GLboolean ColorTableEnabled;
- /*@}*/
-};
-
-
-/**
- * Texture attribute group (GL_TEXTURE_BIT).
- */
-struct gl_texture_attrib
-{
- GLuint CurrentUnit; /**< GL_ACTIVE_TEXTURE */
- struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
- struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS];
-
- /** 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;
-
- /** Texture coord units/sets used for fragment texturing */
- GLbitfield _EnabledCoordUnits;
-
- /** Texture coord units that have texgen enabled */
- GLbitfield _TexGenEnabled;
-
- /** Texture coord units that have non-identity matrices */
- GLbitfield _TexMatEnabled;
-
- /** Bitwise-OR of all Texture.Unit[i]._GenFlags */
- GLbitfield _GenFlags;
-};
-
-
-/**
- * Transformation attribute group (GL_TRANSFORM_BIT).
- */
-struct gl_transform_attrib
-{
- GLenum MatrixMode; /**< Matrix mode */
- GLfloat EyeUserPlane[MAX_CLIP_PLANES][4]; /**< User clip planes */
- GLfloat _ClipUserPlane[MAX_CLIP_PLANES][4]; /**< derived */
- GLbitfield ClipPlanesEnabled; /**< on/off bitmask */
- GLboolean Normalize; /**< Normalize all normals? */
- GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */
- GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */
- GLboolean DepthClamp; /**< GL_ARB_depth_clamp */
-
- GLfloat CullEyePos[4];
- GLfloat CullObjPos[4];
-};
-
-
-/**
- * Viewport attribute group (GL_VIEWPORT_BIT).
- */
-struct gl_viewport_attrib
-{
- GLint X, Y; /**< position */
- GLsizei Width, Height; /**< size */
- GLfloat Near, Far; /**< Depth buffer range */
- GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */
-};
-
-
-/**
- * GL_ARB_vertex/pixel_buffer_object buffer object
- */
-struct gl_buffer_object
-{
- _glthread_Mutex Mutex;
- GLint RefCount;
- GLuint Name;
- GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */
- GLsizeiptrARB Size; /**< Size of buffer storage in bytes */
- GLubyte *Data; /**< Location of storage either in RAM or VRAM. */
- /** Fields describing a mapped buffer */
- /*@{*/
- GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */
- GLvoid *Pointer; /**< User-space address of mapping */
- GLintptr Offset; /**< Mapped offset */
- GLsizeiptr Length; /**< Mapped length */
- /*@}*/
- GLboolean Written; /**< Ever written to? (for debugging) */
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
-};
-
-
-/**
- * Client pixel packing/unpacking attributes
- */
-struct gl_pixelstore_attrib
-{
- GLint Alignment;
- GLint RowLength;
- GLint SkipPixels;
- GLint SkipRows;
- GLint ImageHeight;
- GLint SkipImages;
- GLboolean SwapBytes;
- GLboolean LsbFirst;
- GLboolean ClientStorage; /**< GL_APPLE_client_storage */
- GLboolean Invert; /**< GL_MESA_pack_invert */
- struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */
-};
-
-
-/**
- * Client vertex array attributes
- */
-struct gl_client_array
-{
- GLint Size; /**< components per element (1,2,3,4) */
- GLenum Type; /**< datatype: GL_FLOAT, GL_INT, etc */
- GLenum Format; /**< default: GL_RGBA, but may be GL_BGRA */
- GLsizei Stride; /**< user-specified stride */
- GLsizei StrideB; /**< actual stride in bytes */
- const GLubyte *Ptr; /**< Points to array data */
- GLboolean Enabled; /**< Enabled flag is a boolean */
- GLboolean Normalized; /**< GL_ARB_vertex_program */
- GLboolean Integer; /**< Integer-valued? */
- GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */
- GLuint _ElementSize; /**< size of each element in bytes */
-
- struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */
- GLuint _MaxElement; /**< max element index into array buffer + 1 */
-};
-
-
-/**
- * Collection of vertex arrays. Defined by the GL_APPLE_vertex_array_object
- * extension, but a nice encapsulation in any case.
- */
-struct gl_array_object
-{
- /** Name of the array object as received from glGenVertexArrayAPPLE. */
- GLuint Name;
-
- GLint RefCount;
- _glthread_Mutex Mutex;
- GLboolean VBOonly; /**< require all arrays to live in VBOs? */
-
- /** Conventional vertex arrays */
- /*@{*/
- struct gl_client_array Vertex;
- struct gl_client_array Weight;
- struct gl_client_array Normal;
- struct gl_client_array Color;
- struct gl_client_array SecondaryColor;
- struct gl_client_array FogCoord;
- struct gl_client_array Index;
- struct gl_client_array EdgeFlag;
- struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS];
- struct gl_client_array PointSize;
- /*@}*/
-
- /**
- * Generic arrays for vertex programs/shaders.
- * For NV vertex programs, these attributes alias and take priority
- * over the conventional attribs above. For ARB vertex programs and
- * GLSL vertex shaders, these attributes are separate.
- */
- struct gl_client_array VertexAttrib[MAX_VERTEX_GENERIC_ATTRIBS];
-
- /** Mask of _NEW_ARRAY_* values indicating which arrays are enabled */
- GLbitfield _Enabled;
-
- /**
- * Min of all enabled arrays' _MaxElement. When arrays reside inside VBOs
- * we can determine the max legal (in bounds) glDrawElements array index.
- */
- GLuint _MaxElement;
-};
-
-
-/**
- * Vertex array state
- */
-struct gl_array_attrib
-{
- /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */
- struct gl_array_object *ArrayObj;
-
- /** The default vertex array object */
- struct gl_array_object *DefaultArrayObj;
-
- /** Array objects (GL_ARB/APPLE_vertex_array_object) */
- struct _mesa_HashTable *Objects;
-
- GLint ActiveTexture; /**< Client Active Texture */
- GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */
- GLuint LockCount; /**< GL_EXT_compiled_vertex_array */
-
- /** GL 3.1 (slightly different from GL_NV_primitive_restart) */
- GLboolean PrimitiveRestart;
- GLuint RestartIndex;
-
- GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */
-
- /* GL_ARB_vertex_buffer_object */
- struct gl_buffer_object *ArrayBufferObj;
- struct gl_buffer_object *ElementArrayBufferObj;
-};
-
-
-/**
- * Feedback buffer state
- */
-struct gl_feedback
-{
- GLenum Type;
- GLbitfield _Mask; /**< FB_* bits */
- GLfloat *Buffer;
- GLuint BufferSize;
- GLuint Count;
-};
-
-
-/**
- * Selection buffer state
- */
-struct gl_selection
-{
- GLuint *Buffer; /**< selection buffer */
- GLuint BufferSize; /**< size of the selection buffer */
- GLuint BufferCount; /**< number of values in the selection buffer */
- GLuint Hits; /**< number of records in the selection buffer */
- GLuint NameStackDepth; /**< name stack depth */
- GLuint NameStack[MAX_NAME_STACK_DEPTH]; /**< name stack */
- GLboolean HitFlag; /**< hit flag */
- GLfloat HitMinZ; /**< minimum hit depth */
- GLfloat HitMaxZ; /**< maximum hit depth */
-};
-
-
-/**
- * 1-D Evaluator control points
- */
-struct gl_1d_map
-{
- GLuint Order; /**< Number of control points */
- GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */
- GLfloat *Points; /**< Points to contiguous control points */
-};
-
-
-/**
- * 2-D Evaluator control points
- */
-struct gl_2d_map
-{
- GLuint Uorder; /**< Number of control points in U dimension */
- GLuint Vorder; /**< Number of control points in V dimension */
- GLfloat u1, u2, du;
- GLfloat v1, v2, dv;
- GLfloat *Points; /**< Points to contiguous control points */
-};
-
-
-/**
- * All evaluator control point state
- */
-struct gl_evaluators
-{
- /**
- * \name 1-D maps
- */
- /*@{*/
- struct gl_1d_map Map1Vertex3;
- struct gl_1d_map Map1Vertex4;
- struct gl_1d_map Map1Index;
- struct gl_1d_map Map1Color4;
- struct gl_1d_map Map1Normal;
- struct gl_1d_map Map1Texture1;
- struct gl_1d_map Map1Texture2;
- struct gl_1d_map Map1Texture3;
- struct gl_1d_map Map1Texture4;
- struct gl_1d_map Map1Attrib[16]; /**< GL_NV_vertex_program */
- /*@}*/
-
- /**
- * \name 2-D maps
- */
- /*@{*/
- struct gl_2d_map Map2Vertex3;
- struct gl_2d_map Map2Vertex4;
- struct gl_2d_map Map2Index;
- struct gl_2d_map Map2Color4;
- struct gl_2d_map Map2Normal;
- struct gl_2d_map Map2Texture1;
- struct gl_2d_map Map2Texture2;
- struct gl_2d_map Map2Texture3;
- struct gl_2d_map Map2Texture4;
- struct gl_2d_map Map2Attrib[16]; /**< GL_NV_vertex_program */
- /*@}*/
-};
-
-
-/**
- * Names of the various vertex/fragment program register files, etc.
- *
- * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
- * All values should fit in a 4-bit field.
- *
- * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM,
- * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to
- * be "uniform" variables since they can only be set outside glBegin/End.
- * They're also all stored in the same Parameters array.
- */
-typedef enum
-{
- PROGRAM_TEMPORARY, /**< machine->Temporary[] */
- PROGRAM_INPUT, /**< machine->Inputs[] */
- PROGRAM_OUTPUT, /**< machine->Outputs[] */
- PROGRAM_VARYING, /**< machine->Inputs[]/Outputs[] */
- PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */
- PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */
- PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */
- PROGRAM_NAMED_PARAM, /**< gl_program->Parameters[] */
- PROGRAM_CONSTANT, /**< gl_program->Parameters[] */
- PROGRAM_UNIFORM, /**< gl_program->Parameters[] */
- PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */
- PROGRAM_ADDRESS, /**< machine->AddressReg */
- PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */
- PROGRAM_SYSTEM_VALUE,/**< InstanceId, PrimitiveID, etc. */
- PROGRAM_UNDEFINED, /**< Invalid/TBD value */
- PROGRAM_FILE_MAX
-} gl_register_file;
-
-
-/**
- * If the register file is PROGRAM_SYSTEM_VALUE, the register index will be
- * one of these values.
- */
-typedef enum
-{
- SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */
- SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */
- SYSTEM_VALUE_MAX /**< Number of values */
-} gl_system_value;
-
-
-/** Vertex and fragment instructions */
-struct prog_instruction;
-struct gl_program_parameter_list;
-struct gl_uniform_list;
-
-
-/**
- * Base class for any kind of program object
- */
-struct gl_program
-{
- GLuint Id;
- GLubyte *String; /**< Null-terminated program text */
- GLint RefCount;
- GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */
- GLenum Format; /**< String encoding format */
- GLboolean Resident;
-
- struct prog_instruction *Instructions;
-
- GLbitfield InputsRead; /**< Bitmask of which input regs are read */
- GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
- GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
- GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */
- GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */
- GLbitfield TexturesUsed[MAX_TEXTURE_UNITS]; /**< TEXTURE_x_BIT bitmask */
- GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */
- GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
-
-
- /** Named parameters, constants, etc. from program text */
- struct gl_program_parameter_list *Parameters;
- /** Numbered local parameters */
- GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
-
- /** Vertex/fragment shader varying vars */
- struct gl_program_parameter_list *Varying;
- /** Vertex program user-defined attributes */
- struct gl_program_parameter_list *Attributes;
-
- /** Map from sampler unit to texture unit (set by glUniform1i()) */
- GLubyte SamplerUnits[MAX_SAMPLERS];
- /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
- gl_texture_index SamplerTargets[MAX_SAMPLERS];
-
- /** Bitmask of which register files are read/written with indirect
- * addressing. Mask of (1 << PROGRAM_x) bits.
- */
- GLbitfield IndirectRegisterFiles;
-
- /** Logical counts */
- /*@{*/
- GLuint NumInstructions;
- GLuint NumTemporaries;
- GLuint NumParameters;
- GLuint NumAttributes;
- GLuint NumAddressRegs;
- GLuint NumAluInstructions;
- GLuint NumTexInstructions;
- GLuint NumTexIndirections;
- /*@}*/
- /** Native, actual h/w counts */
- /*@{*/
- GLuint NumNativeInstructions;
- GLuint NumNativeTemporaries;
- GLuint NumNativeParameters;
- GLuint NumNativeAttributes;
- GLuint NumNativeAddressRegs;
- GLuint NumNativeAluInstructions;
- GLuint NumNativeTexInstructions;
- GLuint NumNativeTexIndirections;
- /*@}*/
-};
-
-
-/** Vertex program object */
-struct gl_vertex_program
-{
- struct gl_program Base; /**< base class */
- GLboolean IsNVProgram; /**< is this a GL_NV_vertex_program program? */
- GLboolean IsPositionInvariant;
-};
-
-
-/** Geometry program object */
-struct gl_geometry_program
-{
- struct gl_program Base; /**< base class */
-
- GLint VerticesOut;
- GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
- GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
- GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
-};
-
-
-/** Fragment program object */
-struct gl_fragment_program
-{
- struct gl_program Base; /**< base class */
- GLenum FogOption;
- GLboolean UsesKill; /**< shader uses KIL instruction */
- GLboolean OriginUpperLeft;
- GLboolean PixelCenterInteger;
-};
-
-
-/**
- * State common to vertex and fragment programs.
- */
-struct gl_program_state
-{
- GLint ErrorPos; /* GL_PROGRAM_ERROR_POSITION_ARB/NV */
- const char *ErrorString; /* GL_PROGRAM_ERROR_STRING_ARB/NV */
-};
-
-
-/**
- * Context state for vertex programs.
- */
-struct gl_vertex_program_state
-{
- GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */
- GLboolean _Enabled; /**< Enabled and _valid_ user program? */
- GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */
- GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */
- struct gl_vertex_program *Current; /**< User-bound vertex program */
-
- /** Currently enabled and valid vertex program (including internal
- * programs, user-defined vertex programs and GLSL vertex shaders).
- * This is the program we must use when rendering.
- */
- struct gl_vertex_program *_Current;
-
- GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
-
- /* For GL_NV_vertex_program only: */
- GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4];
- GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4];
-
- /** Should fixed-function T&L be implemented with a vertex prog? */
- GLboolean _MaintainTnlProgram;
-
- /** Program to emulate fixed-function T&L (see above) */
- struct gl_vertex_program *_TnlProgram;
-
- /** Cache of fixed-function programs */
- struct gl_program_cache *Cache;
-
- GLboolean _Overriden;
-};
-
-
-/**
- * Context state for geometry programs.
- */
-struct gl_geometry_program_state
-{
- GLboolean Enabled; /**< GL_ARB_GEOMETRY_SHADER4 */
- GLboolean _Enabled; /**< Enabled and valid program? */
- struct gl_geometry_program *Current; /**< user-bound geometry program */
-
- /** Currently enabled and valid program (including internal programs
- * and compiled shader programs).
- */
- struct gl_geometry_program *_Current;
-
- GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
-
- /** Cache of fixed-function programs */
- struct gl_program_cache *Cache;
-};
-
-/**
- * Context state for fragment programs.
- */
-struct gl_fragment_program_state
-{
- GLboolean Enabled; /**< User-set fragment program enable flag */
- GLboolean _Enabled; /**< Enabled and _valid_ user program? */
- struct gl_fragment_program *Current; /**< User-bound fragment program */
-
- /** Currently enabled and valid fragment program (including internal
- * programs, user-defined fragment programs and GLSL fragment shaders).
- * This is the program we must use when rendering.
- */
- struct gl_fragment_program *_Current;
-
- GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
-
- /** Should fixed-function texturing be implemented with a fragment prog? */
- GLboolean _MaintainTexEnvProgram;
-
- /** Program to emulate fixed-function texture env/combine (see above) */
- struct gl_fragment_program *_TexEnvProgram;
-
- /** Cache of fixed-function programs */
- struct gl_program_cache *Cache;
-};
-
-
-/**
- * ATI_fragment_shader runtime state
- */
-#define ATI_FS_INPUT_PRIMARY 0
-#define ATI_FS_INPUT_SECONDARY 1
-
-struct atifs_instruction;
-struct atifs_setupinst;
-
-/**
- * ATI fragment shader
- */
-struct ati_fragment_shader
-{
- GLuint Id;
- GLint RefCount;
- struct atifs_instruction *Instructions[2];
- struct atifs_setupinst *SetupInst[2];
- GLfloat Constants[8][4];
- GLbitfield LocalConstDef; /**< Indicates which constants have been set */
- GLubyte numArithInstr[2];
- GLubyte regsAssigned[2];
- GLubyte NumPasses; /**< 1 or 2 */
- GLubyte cur_pass;
- GLubyte last_optype;
- GLboolean interpinp1;
- GLboolean isValid;
- GLuint swizzlerq;
-};
-
-/**
- * Context state for GL_ATI_fragment_shader
- */
-struct gl_ati_fragment_shader_state
-{
- GLboolean Enabled;
- GLboolean _Enabled; /**< enabled and valid shader? */
- GLboolean Compiling;
- GLfloat GlobalConstants[8][4];
- struct ati_fragment_shader *Current;
-};
-
-
-/**
- * Occlusion/timer query object.
- */
-struct gl_query_object
-{
- GLenum Target; /**< The query target, when active */
- GLuint Id; /**< hash table ID/name */
- GLuint64EXT Result; /**< the counter */
- GLboolean Active; /**< inside Begin/EndQuery */
- GLboolean Ready; /**< result is ready? */
-};
-
-
-/**
- * Context state for query objects.
- */
-struct gl_query_state
-{
- struct _mesa_HashTable *QueryObjects;
- struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */
- struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */
-
- /** GL_NV_conditional_render */
- struct gl_query_object *CondRenderQuery;
-
- /** GL_EXT_transform_feedback */
- struct gl_query_object *PrimitivesGenerated;
- struct gl_query_object *PrimitivesWritten;
-
- /** GL_ARB_timer_query */
- struct gl_query_object *TimeElapsed;
-
- GLenum CondRenderMode;
-};
-
-
-/** Sync object state */
-struct gl_sync_object {
- struct simple_node link;
- GLenum Type; /**< GL_SYNC_FENCE */
- GLuint Name; /**< Fence name */
- GLint RefCount; /**< Reference count */
- GLboolean DeletePending; /**< Object was deleted while there were still
- * live references (e.g., sync not yet finished)
- */
- GLenum SyncCondition;
- GLbitfield Flags; /**< Flags passed to glFenceSync */
- GLuint StatusFlag:1; /**< Has the sync object been signaled? */
-};
-
-
-/** Set by #pragma directives */
-struct gl_sl_pragmas
-{
- GLboolean IgnoreOptimize; /**< ignore #pragma optimize(on/off) ? */
- GLboolean IgnoreDebug; /**< ignore #pragma debug(on/off) ? */
- GLboolean Optimize; /**< defaults on */
- GLboolean Debug; /**< defaults off */
-};
-
-
-/**
- * A GLSL vertex or fragment shader object.
- */
-struct gl_shader
-{
- GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB (first field!) */
- GLuint Name; /**< AKA the handle */
- GLint RefCount; /**< Reference count */
- GLboolean DeletePending;
- GLboolean CompileStatus;
- GLboolean Main; /**< shader defines main() */
- GLboolean UnresolvedRefs;
- const GLchar *Source; /**< Source code string */
- GLuint SourceChecksum; /**< for debug/logging purposes */
- struct gl_program *Program; /**< Post-compile assembly code */
- GLchar *InfoLog;
- struct gl_sl_pragmas Pragmas;
-
- unsigned Version; /**< GLSL version used for linking */
-
- struct exec_list *ir;
- struct glsl_symbol_table *symbols;
-
- /** Shaders containing built-in functions that are used for linking. */
- struct gl_shader *builtins_to_link[16];
- unsigned num_builtins_to_link;
-};
-
-
-/**
- * A GLSL program object.
- * Basically a linked collection of vertex and fragment shaders.
- */
-struct gl_shader_program
-{
- GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */
- GLuint Name; /**< aka handle or ID */
- GLint RefCount; /**< Reference count */
- GLboolean DeletePending;
-
- GLuint NumShaders; /**< number of attached shaders */
- struct gl_shader **Shaders; /**< List of attached the shaders */
-
- /** User-defined attribute bindings (glBindAttribLocation) */
- struct gl_program_parameter_list *Attributes;
-
- /** Transform feedback varyings */
- struct {
- GLenum BufferMode;
- GLuint NumVarying;
- GLchar **VaryingNames; /**< Array [NumVarying] of char * */
- } TransformFeedback;
-
- /** Geometry shader state - copied into gl_geometry_program at link time */
- struct {
- GLint VerticesOut;
- GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
- GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
- GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
- } Geom;
-
- /* post-link info: */
- struct gl_vertex_program *VertexProgram; /**< Linked vertex program */
- struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
- struct gl_geometry_program *GeometryProgram; /**< Linked geometry prog */
- struct gl_uniform_list *Uniforms;
- struct gl_program_parameter_list *Varying;
- GLboolean LinkStatus; /**< GL_LINK_STATUS */
- GLboolean Validated;
- GLboolean _Used; /**< Ever used for drawing? */
- GLchar *InfoLog;
-
- unsigned Version; /**< GLSL version used for linking */
-
- /**
- * Per-stage shaders resulting from the first stage of linking.
- *
- * Set of linked shaders for this program. The array is accessed using the
- * \c MESA_SHADER_* defines. Entries for non-existent stages will be
- * \c NULL.
- */
- struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES];
-};
-
-
-#define GLSL_DUMP 0x1 /**< Dump shaders to stdout */
-#define GLSL_LOG 0x2 /**< Write shaders to files */
-#define GLSL_OPT 0x4 /**< Force optimizations (override pragmas) */
-#define GLSL_NO_OPT 0x8 /**< Force no optimizations (override pragmas) */
-#define GLSL_UNIFORMS 0x10 /**< Print glUniform calls */
-#define GLSL_NOP_VERT 0x20 /**< Force no-op vertex shaders */
-#define GLSL_NOP_FRAG 0x40 /**< Force no-op fragment shaders */
-#define GLSL_USE_PROG 0x80 /**< Log glUseProgram calls */
-
-
-/**
- * Context state for GLSL vertex/fragment shaders.
- */
-struct gl_shader_state
-{
- /**
- * Programs used for rendering
- *
- * There is a separate program set for each shader stage. If
- * GL_EXT_separate_shader_objects is not supported, each of these must point
- * to \c NULL or to the same program.
- */
- struct gl_shader_program *CurrentVertexProgram;
- struct gl_shader_program *CurrentGeometryProgram;
- struct gl_shader_program *CurrentFragmentProgram;
-
- /**
- * Program used by glUniform calls.
- *
- * Explicitly set by \c glUseProgram and \c glActiveProgramEXT.
- */
- struct gl_shader_program *ActiveProgram;
-
- void *MemPool;
-
- GLbitfield Flags; /**< Mask of GLSL_x flags */
-};
-
-/**
- * Compiler options for a single GLSL shaders type
- */
-struct gl_shader_compiler_options
-{
- /** Driver-selectable options: */
- GLboolean EmitCondCodes; /**< Use condition codes? */
- GLboolean EmitNVTempInitialization; /**< 0-fill NV temp registers */
- /**
- * Attempts to flatten all ir_if (OPCODE_IF) for GPUs that can't
- * support control flow.
- */
- GLboolean EmitNoIfs;
- GLboolean EmitNoLoops;
- GLboolean EmitNoFunctions;
- GLboolean EmitNoCont; /**< Emit CONT opcode? */
- GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */
- GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */
- GLboolean EmitNoPow; /**< Emit POW opcodes? */
-
- /**
- * \name Forms of indirect addressing the driver cannot do.
- */
- /*@{*/
- GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */
- GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */
- GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */
- GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */
- /*@}*/
-
- GLuint MaxUnrollIterations;
-
- struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */
-};
-
-/**
- * Transform feedback object state
- */
-struct gl_transform_feedback_object
-{
- GLuint Name; /**< AKA the object ID */
- GLint RefCount;
- GLboolean Active; /**< Is transform feedback enabled? */
- GLboolean Paused; /**< Is transform feedback paused? */
-
- /** The feedback buffers */
- GLuint BufferNames[MAX_FEEDBACK_ATTRIBS];
- struct gl_buffer_object *Buffers[MAX_FEEDBACK_ATTRIBS];
-
- /** Start of feedback data in dest buffer */
- GLintptr Offset[MAX_FEEDBACK_ATTRIBS];
- /** Max data to put into dest buffer (in bytes) */
- GLsizeiptr Size[MAX_FEEDBACK_ATTRIBS];
-};
-
-
-/**
- * Context state for transform feedback.
- */
-struct gl_transform_feedback
-{
- GLenum Mode; /**< GL_POINTS, GL_LINES or GL_TRIANGLES */
-
- GLboolean RasterDiscard; /**< GL_RASTERIZER_DISCARD */
-
- /** The general binding point (GL_TRANSFORM_FEEDBACK_BUFFER) */
- struct gl_buffer_object *CurrentBuffer;
-
- /** The table of all transform feedback objects */
- struct _mesa_HashTable *Objects;
-
- /** The current xform-fb object (GL_TRANSFORM_FEEDBACK_BINDING) */
- struct gl_transform_feedback_object *CurrentObject;
-
- /** The default xform-fb object (Name==0) */
- struct gl_transform_feedback_object *DefaultObject;
-};
-
-
-
-/**
- * State which can be shared by multiple contexts:
- */
-struct gl_shared_state
-{
- _glthread_Mutex Mutex; /**< for thread safety */
- GLint RefCount; /**< Reference count */
- struct _mesa_HashTable *DisplayList; /**< Display lists hash table */
- struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */
-
- /** Default texture objects (shared by all texture units) */
- struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS];
-
- /** Fallback texture used when a bound texture is incomplete */
- struct gl_texture_object *FallbackTex;
-
- /**
- * \name Thread safety and statechange notification for texture
- * objects.
- *
- * \todo Improve the granularity of locking.
- */
- /*@{*/
- _glthread_Mutex TexMutex; /**< texobj thread safety */
- GLuint TextureStateStamp; /**< state notification for shared tex */
- /*@}*/
-
- /** Default buffer object for vertex arrays that aren't in VBOs */
- struct gl_buffer_object *NullBufferObj;
-
- /**
- * \name Vertex/geometry/fragment programs
- */
- /*@{*/
- struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
- struct gl_vertex_program *DefaultVertexProgram;
- struct gl_fragment_program *DefaultFragmentProgram;
- struct gl_geometry_program *DefaultGeometryProgram;
- /*@}*/
-
- /* GL_ATI_fragment_shader */
- struct _mesa_HashTable *ATIShaders;
- struct ati_fragment_shader *DefaultFragmentShader;
-
- struct _mesa_HashTable *BufferObjects;
-
- /** Table of both gl_shader and gl_shader_program objects */
- struct _mesa_HashTable *ShaderObjects;
-
- /* GL_EXT_framebuffer_object */
- struct _mesa_HashTable *RenderBuffers;
- struct _mesa_HashTable *FrameBuffers;
-
- /* GL_ARB_sync */
- struct simple_node SyncObjects;
-
- void *DriverData; /**< Device driver shared state */
-};
-
-
-
-
-/**
- * A renderbuffer stores colors or depth values or stencil values.
- * A framebuffer object will have a collection of these.
- * Data are read/written to the buffer with a handful of Get/Put functions.
- *
- * Instances of this object are allocated with the Driver's NewRenderbuffer
- * hook. Drivers will likely wrap this class inside a driver-specific
- * class to simulate inheritance.
- */
-struct gl_renderbuffer
-{
-#define RB_MAGIC 0xaabbccdd
- int Magic; /** XXX TEMPORARY DEBUG INFO */
- _glthread_Mutex Mutex; /**< for thread safety */
- GLuint ClassID; /**< Useful for drivers */
- GLuint Name;
- GLint RefCount;
- GLuint Width, Height;
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
-
- GLenum InternalFormat; /**< The user-specified format */
- GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or
- GL_STENCIL_INDEX. */
- GLuint Format; /**< The actual format: MESA_FORMAT_x */
-
- GLubyte NumSamples;
-
- GLenum DataType; /**< Type of values passed to the Get/Put functions */
- GLvoid *Data; /**< This may not be used by some kinds of RBs */
-
- /* Used to wrap one renderbuffer around another: */
- struct gl_renderbuffer *Wrapped;
-
- /* Delete this renderbuffer */
- void (*Delete)(struct gl_renderbuffer *rb);
-
- /* Allocate new storage for this renderbuffer */
- GLboolean (*AllocStorage)(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLenum internalFormat,
- GLuint width, GLuint height);
-
- /* Lock/Unlock are called before/after calling the Get/Put functions.
- * Not sure this is the right place for these yet.
- void (*Lock)(struct gl_context *ctx, struct gl_renderbuffer *rb);
- void (*Unlock)(struct gl_context *ctx, struct gl_renderbuffer *rb);
- */
-
- /* Return a pointer to the element/pixel at (x,y).
- * Should return NULL if the buffer memory can't be directly addressed.
- */
- void *(*GetPointer)(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLint x, GLint y);
-
- /* Get/Read a row of values.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*GetRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, void *values);
-
- /* Get/Read values at arbitrary locations.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*GetValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- const GLint x[], const GLint y[], void *values);
-
- /* Put/Write a row of values.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *values, const GLubyte *mask);
-
- /* Put/Write a row of RGB values. This is a special-case routine that's
- * only used for RGBA renderbuffers when the source data is GL_RGB. That's
- * a common case for glDrawPixels and some triangle routines.
- * The values will be of format GL_RGB and type DataType.
- */
- void (*PutRowRGB)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *values, const GLubyte *mask);
-
-
- /* Put/Write a row of identical values.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutMonoRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *value, const GLubyte *mask);
-
- /* Put/Write values at arbitrary locations.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- const GLint x[], const GLint y[], const void *values,
- const GLubyte *mask);
- /* Put/Write identical values at arbitrary locations.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutMonoValues)(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- const void *value, const GLubyte *mask);
-};
-
-
-/**
- * A renderbuffer attachment points to either a texture object (and specifies
- * a mipmap level, cube face or 3D texture slice) or points to a renderbuffer.
- */
-struct gl_renderbuffer_attachment
-{
- GLenum Type; /**< \c GL_NONE or \c GL_TEXTURE or \c GL_RENDERBUFFER_EXT */
- GLboolean Complete;
-
- /**
- * If \c Type is \c GL_RENDERBUFFER_EXT, this stores a pointer to the
- * application supplied renderbuffer object.
- */
- struct gl_renderbuffer *Renderbuffer;
-
- /**
- * If \c Type is \c GL_TEXTURE, this stores a pointer to the application
- * supplied texture object.
- */
- struct gl_texture_object *Texture;
- GLuint TextureLevel; /**< Attached mipmap level. */
- GLuint CubeMapFace; /**< 0 .. 5, for cube map textures. */
- GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D
- * and 2D array textures */
-};
-
-
-/**
- * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc).
- * In C++ terms, think of this as a base class from which device drivers
- * will make derived classes.
- */
-struct gl_framebuffer
-{
- _glthread_Mutex Mutex; /**< for thread safety */
- /**
- * If zero, this is a window system framebuffer. If non-zero, this
- * is a FBO framebuffer; note that for some devices (i.e. those with
- * a natural pixel coordinate system for FBOs that differs from the
- * OpenGL/Mesa coordinate system), this means that the viewport,
- * polygon face orientation, and polygon stipple will have to be inverted.
- */
- GLuint Name;
-
- GLint RefCount;
- GLboolean DeletePending;
-
- /**
- * The framebuffer's visual. Immutable if this is a window system buffer.
- * Computed from attachments if user-made FBO.
- */
- struct gl_config Visual;
-
- GLboolean Initialized;
-
- GLuint Width, Height; /**< size of frame buffer in pixels */
-
- /** \name Drawing bounds (Intersection of buffer size and scissor box) */
- /*@{*/
- GLint _Xmin, _Xmax; /**< inclusive */
- GLint _Ymin, _Ymax; /**< exclusive */
- /*@}*/
-
- /** \name Derived Z buffer stuff */
- /*@{*/
- GLuint _DepthMax; /**< Max depth buffer value */
- GLfloat _DepthMaxF; /**< Float max depth buffer value */
- GLfloat _MRD; /**< minimum resolvable difference in Z values */
- /*@}*/
-
- /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
- GLenum _Status;
-
- /** Integer color values */
- GLboolean _IntegerColor;
-
- /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */
- struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT];
-
- /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER
- * attribute group and GL_PIXEL attribute group, respectively.
- */
- GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS];
- GLenum ColorReadBuffer;
-
- /** Computed from ColorDraw/ReadBuffer above */
- GLuint _NumColorDrawBuffers;
- GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */
- GLint _ColorReadBufferIndex; /* -1 = None */
- struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
- struct gl_renderbuffer *_ColorReadBuffer;
-
- /** The Actual depth/stencil buffers to use. May be wrappers around the
- * depth/stencil buffers attached above. */
- struct gl_renderbuffer *_DepthBuffer;
- struct gl_renderbuffer *_StencilBuffer;
-
- /** Delete this framebuffer */
- void (*Delete)(struct gl_framebuffer *fb);
-};
-
-
-/**
- * Precision info for shader datatypes. See glGetShaderPrecisionFormat().
- */
-struct gl_precision
-{
- GLushort RangeMin; /**< min value exponent */
- GLushort RangeMax; /**< max value exponent */
- GLushort Precision; /**< number of mantissa bits */
-};
-
-
-/**
- * Limits for vertex and fragment programs/shaders.
- */
-struct gl_program_constants
-{
- /* logical limits */
- GLuint MaxInstructions;
- GLuint MaxAluInstructions;
- GLuint MaxTexInstructions;
- GLuint MaxTexIndirections;
- GLuint MaxAttribs;
- GLuint MaxTemps;
- GLuint MaxAddressRegs;
- GLuint MaxParameters;
- GLuint MaxLocalParams;
- GLuint MaxEnvParams;
- /* native/hardware limits */
- GLuint MaxNativeInstructions;
- GLuint MaxNativeAluInstructions;
- GLuint MaxNativeTexInstructions;
- GLuint MaxNativeTexIndirections;
- GLuint MaxNativeAttribs;
- GLuint MaxNativeTemps;
- GLuint MaxNativeAddressRegs;
- GLuint MaxNativeParameters;
- /* For shaders */
- GLuint MaxUniformComponents;
- /* GL_ARB_geometry_shader4 */
- GLuint MaxGeometryTextureImageUnits;
- GLuint MaxGeometryVaryingComponents;
- GLuint MaxVertexVaryingComponents;
- GLuint MaxGeometryUniformComponents;
- GLuint MaxGeometryOutputVertices;
- GLuint MaxGeometryTotalOutputComponents;
- /* ES 2.0 and GL_ARB_ES2_compatibility */
- struct gl_precision LowFloat, MediumFloat, HighFloat;
- struct gl_precision LowInt, MediumInt, HighInt;
-};
-
-
-/**
- * Constants which may be overridden by device driver during context creation
- * but are never changed after that.
- */
-struct gl_constants
-{
- GLint MaxTextureMbytes; /**< Max memory per image, in MB */
- GLint MaxTextureLevels; /**< Max mipmap levels. */
- GLint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */
- GLint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */
- GLint MaxArrayTextureLayers; /**< Max layers in array textures */
- GLint MaxTextureRectSize; /**< Max rectangle texture size, in pixes */
- GLuint MaxTextureCoordUnits;
- GLuint MaxTextureImageUnits;
- GLuint MaxVertexTextureImageUnits;
- GLuint MaxCombinedTextureImageUnits;
- GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */
- GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
- GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */
-
- GLuint MaxArrayLockSize;
-
- GLint SubPixelBits;
-
- GLfloat MinPointSize, MaxPointSize; /**< aliased */
- GLfloat MinPointSizeAA, MaxPointSizeAA; /**< antialiased */
- GLfloat PointSizeGranularity;
- GLfloat MinLineWidth, MaxLineWidth; /**< aliased */
- GLfloat MinLineWidthAA, MaxLineWidthAA; /**< antialiased */
- GLfloat LineWidthGranularity;
-
- GLuint MaxColorTableSize;
-
- GLuint MaxClipPlanes;
- GLuint MaxLights;
- GLfloat MaxShininess; /**< GL_NV_light_max_exponent */
- GLfloat MaxSpotExponent; /**< GL_NV_light_max_exponent */
-
- GLuint MaxViewportWidth, MaxViewportHeight;
-
- struct gl_program_constants VertexProgram; /**< GL_ARB_vertex_program */
- struct gl_program_constants FragmentProgram; /**< GL_ARB_fragment_program */
- struct gl_program_constants GeometryProgram; /**< GL_ARB_geometry_shader4 */
- GLuint MaxProgramMatrices;
- GLuint MaxProgramMatrixStackDepth;
-
- /** vertex array / buffer object bounds checking */
- GLboolean CheckArrayBounds;
-
- GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */
-
- GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */
- GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */
- GLuint MaxSamples; /**< GL_ARB_framebuffer_object */
-
- GLuint MaxVarying; /**< Number of float[4] varying parameters */
-
- GLuint GLSLVersion; /**< GLSL version supported (ex: 120 = 1.20) */
-
- /** Which texture units support GL_ATI_envmap_bumpmap as targets */
- GLbitfield SupportedBumpUnits;
-
- /**
- * Maximum amount of time, measured in nanseconds, that the server can wait.
- */
- GLuint64 MaxServerWaitTimeout;
-
- /** GL_EXT_provoking_vertex */
- GLboolean QuadsFollowProvokingVertexConvention;
-
- /** OpenGL version 3.0 */
- GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */
-
- /** OpenGL version 3.2 */
- GLbitfield ProfileMask; /**< Mask of CONTEXT_x_PROFILE_BIT */
-
- /** GL_EXT_transform_feedback */
- GLuint MaxTransformFeedbackSeparateAttribs;
- GLuint MaxTransformFeedbackSeparateComponents;
- GLuint MaxTransformFeedbackInterleavedComponents;
-
- /** GL_EXT_gpu_shader4 */
- GLint MinProgramTexelOffset, MaxProgramTexelOffset;
-};
-
-
-/**
- * Enable flag for each OpenGL extension. Different device drivers will
- * enable different extensions at runtime.
- */
-struct gl_extensions
-{
- GLboolean dummy; /* don't remove this! */
- GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */
- GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
- GLboolean ARB_ES2_compatibility;
- GLboolean ARB_blend_func_extended;
- GLboolean ARB_copy_buffer;
- GLboolean ARB_depth_buffer_float;
- GLboolean ARB_depth_clamp;
- GLboolean ARB_depth_texture;
- GLboolean ARB_draw_buffers;
- GLboolean ARB_draw_buffers_blend;
- GLboolean ARB_draw_elements_base_vertex;
- GLboolean ARB_draw_instanced;
- GLboolean ARB_fragment_coord_conventions;
- GLboolean ARB_fragment_program;
- GLboolean ARB_fragment_program_shadow;
- GLboolean ARB_fragment_shader;
- GLboolean ARB_framebuffer_object;
- GLboolean ARB_explicit_attrib_location;
- GLboolean ARB_geometry_shader4;
- GLboolean ARB_half_float_pixel;
- GLboolean ARB_half_float_vertex;
- GLboolean ARB_instanced_arrays;
- GLboolean ARB_map_buffer_range;
- GLboolean ARB_multisample;
- GLboolean ARB_multitexture;
- GLboolean ARB_occlusion_query;
- GLboolean ARB_occlusion_query2;
- GLboolean ARB_point_sprite;
- GLboolean ARB_sampler_objects;
- GLboolean ARB_seamless_cube_map;
- GLboolean ARB_shader_objects;
- GLboolean ARB_shader_stencil_export;
- GLboolean ARB_shading_language_100;
- GLboolean ARB_shadow;
- GLboolean ARB_shadow_ambient;
- GLboolean ARB_sync;
- GLboolean ARB_texture_border_clamp;
- GLboolean ARB_texture_buffer_object;
- GLboolean ARB_texture_compression;
- GLboolean ARB_texture_compression_rgtc;
- GLboolean ARB_texture_cube_map;
- GLboolean ARB_texture_env_combine;
- GLboolean ARB_texture_env_crossbar;
- GLboolean ARB_texture_env_dot3;
- GLboolean ARB_texture_float;
- GLboolean ARB_texture_mirrored_repeat;
- GLboolean ARB_texture_multisample;
- GLboolean ARB_texture_non_power_of_two;
- GLboolean ARB_texture_rg;
- GLboolean ARB_texture_rgb10_a2ui;
- GLboolean ARB_timer_query;
- GLboolean ARB_transform_feedback2;
- GLboolean ARB_transpose_matrix;
- GLboolean ARB_uniform_buffer_object;
- GLboolean ARB_vertex_array_object;
- GLboolean ARB_vertex_buffer_object;
- GLboolean ARB_vertex_program;
- GLboolean ARB_vertex_shader;
- GLboolean ARB_vertex_type_2_10_10_10_rev;
- GLboolean ARB_window_pos;
- GLboolean EXT_abgr;
- GLboolean EXT_bgra;
- GLboolean EXT_blend_color;
- GLboolean EXT_blend_equation_separate;
- GLboolean EXT_blend_func_separate;
- GLboolean EXT_blend_logic_op;
- GLboolean EXT_blend_minmax;
- GLboolean EXT_blend_subtract;
- GLboolean EXT_clip_volume_hint;
- GLboolean EXT_compiled_vertex_array;
- GLboolean EXT_copy_texture;
- GLboolean EXT_depth_bounds_test;
- GLboolean EXT_draw_buffers2;
- GLboolean EXT_draw_range_elements;
- GLboolean EXT_fog_coord;
- GLboolean EXT_framebuffer_blit;
- GLboolean EXT_framebuffer_multisample;
- GLboolean EXT_framebuffer_object;
- GLboolean EXT_framebuffer_sRGB;
- 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;
- GLboolean EXT_pixel_buffer_object;
- GLboolean EXT_point_parameters;
- GLboolean EXT_polygon_offset;
- GLboolean EXT_provoking_vertex;
- GLboolean EXT_rescale_normal;
- GLboolean EXT_shadow_funcs;
- 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;
- GLboolean EXT_texture;
- GLboolean EXT_texture_object;
- GLboolean EXT_texture3D;
- GLboolean EXT_texture_array;
- GLboolean EXT_texture_compression_s3tc;
- GLboolean EXT_texture_env_add;
- GLboolean EXT_texture_env_combine;
- GLboolean EXT_texture_env_dot3;
- GLboolean EXT_texture_filter_anisotropic;
- GLboolean EXT_texture_integer;
- GLboolean EXT_texture_lod_bias;
- GLboolean EXT_texture_mirror_clamp;
- GLboolean EXT_texture_shared_exponent;
- GLboolean EXT_texture_sRGB;
- GLboolean EXT_texture_sRGB_decode;
- GLboolean EXT_texture_swizzle;
- GLboolean EXT_transform_feedback;
- GLboolean EXT_timer_query;
- GLboolean EXT_vertex_array;
- GLboolean EXT_vertex_array_bgra;
- GLboolean EXT_vertex_array_set;
- GLboolean OES_standard_derivatives;
- /* vendor extensions */
- GLboolean APPLE_client_storage;
- GLboolean APPLE_packed_pixels;
- GLboolean APPLE_vertex_array_object;
- GLboolean APPLE_object_purgeable;
- GLboolean ATI_envmap_bumpmap;
- GLboolean ATI_texture_mirror_once;
- GLboolean ATI_texture_env_combine3;
- GLboolean ATI_fragment_shader;
- GLboolean ATI_separate_stencil;
- GLboolean IBM_rasterpos_clip;
- GLboolean IBM_multimode_draw_arrays;
- GLboolean MESA_pack_invert;
- GLboolean MESA_resize_buffers;
- GLboolean MESA_ycbcr_texture;
- GLboolean MESA_texture_array;
- GLboolean MESA_texture_signed_rgba;
- GLboolean NV_blend_square;
- GLboolean NV_conditional_render;
- GLboolean NV_fragment_program;
- GLboolean NV_fragment_program_option;
- GLboolean NV_light_max_exponent;
- GLboolean NV_point_sprite;
- GLboolean NV_primitive_restart;
- GLboolean NV_texgen_reflection;
- GLboolean NV_texture_env_combine4;
- GLboolean NV_texture_rectangle;
- GLboolean NV_vertex_program;
- GLboolean NV_vertex_program1_1;
- GLboolean OES_read_format;
- GLboolean SGI_texture_color_table;
- GLboolean SGIS_generate_mipmap;
- GLboolean SGIS_texture_edge_clamp;
- GLboolean SGIS_texture_lod;
- GLboolean TDFX_texture_compression_FXT1;
- GLboolean S3_s3tc;
- GLboolean OES_EGL_image;
- GLboolean OES_draw_texture;
- GLboolean EXT_texture_format_BGRA8888;
- GLboolean extension_sentinel;
- /** The extension string */
- const GLubyte *String;
- /** Number of supported extensions */
- GLuint Count;
-};
-
-
-/**
- * A stack of matrices (projection, modelview, color, texture, etc).
- */
-struct gl_matrix_stack
-{
- GLmatrix *Top; /**< points into Stack */
- GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */
- GLuint Depth; /**< 0 <= Depth < MaxDepth */
- GLuint MaxDepth; /**< size of Stack[] array */
- GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */
-};
-
-
-/**
- * \name Bits for image transfer operations
- * \sa __struct gl_contextRec::ImageTransferState.
- */
-/*@{*/
-#define IMAGE_SCALE_BIAS_BIT 0x1
-#define IMAGE_SHIFT_OFFSET_BIT 0x2
-#define IMAGE_MAP_COLOR_BIT 0x4
-#define IMAGE_CLAMP_BIT 0x800
-
-
-/** Pixel Transfer ops */
-#define IMAGE_BITS (IMAGE_SCALE_BIAS_BIT | \
- IMAGE_SHIFT_OFFSET_BIT | \
- IMAGE_MAP_COLOR_BIT)
-
-/**
- * \name Bits to indicate what state has changed.
- *
- * 4 unused flags.
- */
-/*@{*/
-#define _NEW_MODELVIEW 0x1 /**< __struct gl_contextRec::ModelView */
-#define _NEW_PROJECTION 0x2 /**< __struct gl_contextRec::Projection */
-#define _NEW_TEXTURE_MATRIX 0x4 /**< __struct gl_contextRec::TextureMatrix */
-#define _NEW_ACCUM 0x10 /**< __struct gl_contextRec::Accum */
-#define _NEW_COLOR 0x20 /**< __struct gl_contextRec::Color */
-#define _NEW_DEPTH 0x40 /**< __struct gl_contextRec::Depth */
-#define _NEW_EVAL 0x80 /**< __struct gl_contextRec::Eval, __struct gl_contextRec::EvalMap */
-#define _NEW_FOG 0x100 /**< __struct gl_contextRec::Fog */
-#define _NEW_HINT 0x200 /**< __struct gl_contextRec::Hint */
-#define _NEW_LIGHT 0x400 /**< __struct gl_contextRec::Light */
-#define _NEW_LINE 0x800 /**< __struct gl_contextRec::Line */
-#define _NEW_PIXEL 0x1000 /**< __struct gl_contextRec::Pixel */
-#define _NEW_POINT 0x2000 /**< __struct gl_contextRec::Point */
-#define _NEW_POLYGON 0x4000 /**< __struct gl_contextRec::Polygon */
-#define _NEW_POLYGONSTIPPLE 0x8000 /**< __struct gl_contextRec::PolygonStipple */
-#define _NEW_SCISSOR 0x10000 /**< __struct gl_contextRec::Scissor */
-#define _NEW_STENCIL 0x20000 /**< __struct gl_contextRec::Stencil */
-#define _NEW_TEXTURE 0x40000 /**< __struct gl_contextRec::Texture */
-#define _NEW_TRANSFORM 0x80000 /**< __struct gl_contextRec::Transform */
-#define _NEW_VIEWPORT 0x100000 /**< __struct gl_contextRec::Viewport */
-#define _NEW_PACKUNPACK 0x200000 /**< __struct gl_contextRec::Pack, __struct gl_contextRec::Unpack */
-#define _NEW_ARRAY 0x400000 /**< __struct gl_contextRec::Array */
-#define _NEW_RENDERMODE 0x800000 /**< __struct gl_contextRec::RenderMode, __struct gl_contextRec::Feedback, __struct gl_contextRec::Select */
-#define _NEW_BUFFERS 0x1000000 /**< __struct gl_contextRec::Visual, __struct gl_contextRec::DrawBuffer, */
-#define _NEW_MULTISAMPLE 0x2000000 /**< __struct gl_contextRec::Multisample */
-#define _NEW_TRACK_MATRIX 0x4000000 /**< __struct gl_contextRec::VertexProgram */
-#define _NEW_PROGRAM 0x8000000 /**< __struct gl_contextRec::VertexProgram */
-#define _NEW_CURRENT_ATTRIB 0x10000000 /**< __struct gl_contextRec::Current */
-#define _NEW_PROGRAM_CONSTANTS 0x20000000
-#define _NEW_BUFFER_OBJECT 0x40000000
-#define _NEW_ALL ~0
-/*@}*/
-
-
-/**
- * \name Bits to track array state changes
- *
- * Also used to summarize array enabled.
- */
-/*@{*/
-#define _NEW_ARRAY_VERTEX VERT_BIT_POS
-#define _NEW_ARRAY_WEIGHT VERT_BIT_WEIGHT
-#define _NEW_ARRAY_NORMAL VERT_BIT_NORMAL
-#define _NEW_ARRAY_COLOR0 VERT_BIT_COLOR0
-#define _NEW_ARRAY_COLOR1 VERT_BIT_COLOR1
-#define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG
-#define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX
-#define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG
-#define _NEW_ARRAY_POINT_SIZE VERT_BIT_COLOR_INDEX /* aliased */
-#define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0
-#define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1
-#define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2
-#define _NEW_ARRAY_TEXCOORD_3 VERT_BIT_TEX3
-#define _NEW_ARRAY_TEXCOORD_4 VERT_BIT_TEX4
-#define _NEW_ARRAY_TEXCOORD_5 VERT_BIT_TEX5
-#define _NEW_ARRAY_TEXCOORD_6 VERT_BIT_TEX6
-#define _NEW_ARRAY_TEXCOORD_7 VERT_BIT_TEX7
-#define _NEW_ARRAY_ATTRIB_0 VERT_BIT_GENERIC0 /* start at bit 16 */
-#define _NEW_ARRAY_ALL 0xffffffff
-
-
-#define _NEW_ARRAY_TEXCOORD(i) (_NEW_ARRAY_TEXCOORD_0 << (i))
-#define _NEW_ARRAY_ATTRIB(i) (_NEW_ARRAY_ATTRIB_0 << (i))
-/*@}*/
-
-
-
-/**
- * \name A bunch of flags that we think might be useful to drivers.
- *
- * Set in the __struct gl_contextRec::_TriangleCaps bitfield.
- */
-/*@{*/
-#define DD_FLATSHADE 0x1
-#define DD_SEPARATE_SPECULAR 0x2
-#define DD_TRI_CULL_FRONT_BACK 0x4 /* special case on some hw */
-#define DD_TRI_LIGHT_TWOSIDE 0x8
-#define DD_TRI_UNFILLED 0x10
-#define DD_TRI_SMOOTH 0x20
-#define DD_TRI_STIPPLE 0x40
-#define DD_TRI_OFFSET 0x80
-#define DD_LINE_SMOOTH 0x100
-#define DD_LINE_STIPPLE 0x200
-#define DD_POINT_SMOOTH 0x400
-#define DD_POINT_ATTEN 0x800
-#define DD_TRI_TWOSTENCIL 0x1000
-/*@}*/
-
-
-/**
- * \name Define the state changes under which each of these bits might change
- */
-/*@{*/
-#define _DD_NEW_FLATSHADE _NEW_LIGHT
-#define _DD_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | _NEW_FOG | _NEW_PROGRAM)
-#define _DD_NEW_TRI_CULL_FRONT_BACK _NEW_POLYGON
-#define _DD_NEW_TRI_LIGHT_TWOSIDE _NEW_LIGHT
-#define _DD_NEW_TRI_UNFILLED _NEW_POLYGON
-#define _DD_NEW_TRI_SMOOTH _NEW_POLYGON
-#define _DD_NEW_TRI_STIPPLE _NEW_POLYGON
-#define _DD_NEW_TRI_OFFSET _NEW_POLYGON
-#define _DD_NEW_LINE_SMOOTH _NEW_LINE
-#define _DD_NEW_LINE_STIPPLE _NEW_LINE
-#define _DD_NEW_LINE_WIDTH _NEW_LINE
-#define _DD_NEW_POINT_SMOOTH _NEW_POINT
-#define _DD_NEW_POINT_SIZE _NEW_POINT
-#define _DD_NEW_POINT_ATTEN _NEW_POINT
-/*@}*/
-
-
-/**
- * Composite state flags
- */
-/*@{*/
-#define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \
- _NEW_TEXTURE | \
- _NEW_POINT | \
- _NEW_PROGRAM | \
- _NEW_MODELVIEW)
-
-#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \
- _NEW_TEXTURE)
-
-#define _MESA_NEW_TRANSFER_STATE (_NEW_PIXEL)
-/*@}*/
-
-
-
-
-/* This has to be included here. */
-#include "dd.h"
-
-
-/**
- * Display list flags.
- * Strictly this is a tnl-private concept, but it doesn't seem
- * worthwhile adding a tnl private structure just to hold this one bit
- * of information:
- */
-#define DLIST_DANGLING_REFS 0x1
-
-
-/** Opaque declaration of display list payload data type */
-union gl_dlist_node;
-
-
-/**
- * Provide a location where information about a display list can be
- * collected. Could be extended with driverPrivate structures,
- * etc. in the future.
- */
-struct gl_display_list
-{
- GLuint Name;
- GLbitfield Flags; /**< DLIST_x flags */
- /** The dlist commands are in a linked list of nodes */
- union gl_dlist_node *Head;
-};
-
-
-/**
- * State used during display list compilation and execution.
- */
-struct gl_dlist_state
-{
- GLuint CallDepth; /**< Current recursion calling depth */
-
- struct gl_display_list *CurrentList; /**< List currently being compiled */
- union gl_dlist_node *CurrentBlock; /**< Pointer to current block of nodes */
- GLuint CurrentPos; /**< Index into current block of nodes */
-
- GLvertexformat ListVtxfmt;
-
- GLubyte ActiveAttribSize[VERT_ATTRIB_MAX];
- GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4];
-
- GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX];
- GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4];
-
- GLubyte ActiveIndex;
- GLfloat CurrentIndex;
-
- GLubyte ActiveEdgeFlag;
- GLboolean CurrentEdgeFlag;
-
- struct {
- /* State known to have been set by the currently-compiling display
- * list. Used to eliminate some redundant state changes.
- */
- GLenum ShadeModel;
- } Current;
-};
-
-
-/**
- * Enum for the OpenGL APIs we know about and may support.
- */
-typedef enum
-{
- API_OPENGL,
- API_OPENGLES,
- API_OPENGLES2
-} gl_api;
-
-
-/**
- * Mesa rendering context.
- *
- * This is the central context data structure for Mesa. Almost all
- * OpenGL state is contained in this structure.
- * Think of this as a base class from which device drivers will derive
- * sub classes.
- *
- * The struct gl_context typedef names this structure.
- */
-struct gl_context
-{
- /** State possibly shared with other contexts in the address space */
- struct gl_shared_state *Shared;
-
- /** \name API function pointer tables */
- /*@{*/
- gl_api API;
- struct _glapi_table *Save; /**< Display list save functions */
- struct _glapi_table *Exec; /**< Execute functions */
- struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */
- /*@}*/
-
- struct gl_config Visual;
- struct gl_framebuffer *DrawBuffer; /**< buffer for writing */
- struct gl_framebuffer *ReadBuffer; /**< buffer for reading */
- struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */
- struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */
-
- /**
- * Device driver function pointer table
- */
- struct dd_function_table Driver;
-
- void *DriverCtx; /**< Points to device driver context/state */
-
- /** Core/Driver constants */
- struct gl_constants Const;
-
- /** \name The various 4x4 matrix stacks */
- /*@{*/
- struct gl_matrix_stack ModelviewMatrixStack;
- struct gl_matrix_stack ProjectionMatrixStack;
- struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS];
- struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
- struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */
- /*@}*/
-
- /** Combined modelview and projection matrix */
- GLmatrix _ModelProjectMatrix;
-
- /** \name Display lists */
- struct gl_dlist_state ListState;
-
- GLboolean ExecuteFlag; /**< Execute GL commands? */
- GLboolean CompileFlag; /**< Compile GL commands into display list? */
-
- /** Extension information */
- struct gl_extensions Extensions;
-
- /** Version info */
- GLuint VersionMajor, VersionMinor;
- char *VersionString;
-
- /** \name State attribute stack (for glPush/PopAttrib) */
- /*@{*/
- GLuint AttribStackDepth;
- struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH];
- /*@}*/
-
- /** \name Renderer attribute groups
- *
- * We define a struct for each attribute group to make pushing and popping
- * attributes easy. Also it's a good organization.
- */
- /*@{*/
- struct gl_accum_attrib Accum; /**< Accum buffer attributes */
- struct gl_colorbuffer_attrib Color; /**< Color buffer attributes */
- struct gl_current_attrib Current; /**< Current attributes */
- struct gl_depthbuffer_attrib Depth; /**< Depth buffer attributes */
- struct gl_eval_attrib Eval; /**< Eval attributes */
- struct gl_fog_attrib Fog; /**< Fog attributes */
- struct gl_hint_attrib Hint; /**< Hint attributes */
- struct gl_light_attrib Light; /**< Light attributes */
- struct gl_line_attrib Line; /**< Line attributes */
- struct gl_list_attrib List; /**< List attributes */
- struct gl_multisample_attrib Multisample;
- struct gl_pixel_attrib Pixel; /**< Pixel attributes */
- struct gl_point_attrib Point; /**< Point attributes */
- struct gl_polygon_attrib Polygon; /**< Polygon attributes */
- GLuint PolygonStipple[32]; /**< Polygon stipple */
- struct gl_scissor_attrib Scissor; /**< Scissor attributes */
- struct gl_stencil_attrib Stencil; /**< Stencil buffer attributes */
- struct gl_texture_attrib Texture; /**< Texture attributes */
- struct gl_transform_attrib Transform; /**< Transformation attributes */
- struct gl_viewport_attrib Viewport; /**< Viewport attributes */
- /*@}*/
-
- /** \name Client attribute stack */
- /*@{*/
- GLuint ClientAttribStackDepth;
- struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH];
- /*@}*/
-
- /** \name Client attribute groups */
- /*@{*/
- struct gl_array_attrib Array; /**< Vertex arrays */
- struct gl_pixelstore_attrib Pack; /**< Pixel packing */
- struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */
- struct gl_pixelstore_attrib DefaultPacking; /**< Default params */
- /*@}*/
-
- /** \name Other assorted state (not pushed/popped on attribute stack) */
- /*@{*/
- struct gl_pixelmaps PixelMaps;
-
- struct gl_evaluators EvalMap; /**< All evaluators */
- struct gl_feedback Feedback; /**< Feedback */
- struct gl_selection Select; /**< Selection */
-
- struct gl_program_state Program; /**< general program state */
- struct gl_vertex_program_state VertexProgram;
- struct gl_fragment_program_state FragmentProgram;
- struct gl_geometry_program_state GeometryProgram;
- struct gl_ati_fragment_shader_state ATIFragmentShader;
-
- struct gl_shader_state Shader; /**< GLSL shader object state */
- struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES];
-
- struct gl_query_state Query; /**< occlusion, timer queries */
-
- struct gl_transform_feedback TransformFeedback;
-
- struct gl_buffer_object *CopyReadBuffer; /**< GL_ARB_copy_buffer */
- struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */
- /*@}*/
-
- struct gl_meta_state *Meta; /**< for "meta" operations */
-
- /* GL_EXT_framebuffer_object */
- struct gl_renderbuffer *CurrentRenderbuffer;
-
- GLenum ErrorValue; /**< Last error code */
-
- /**
- * Recognize and silence repeated error debug messages in buggy apps.
- */
- const char *ErrorDebugFmtString;
- GLuint ErrorDebugCount;
-
- GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
- GLbitfield NewState; /**< bitwise-or of _NEW_* flags */
-
- GLboolean ViewportInitialized; /**< has viewport size been initialized? */
-
- GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */
-
- /** \name Derived state */
- /*@{*/
- /** Bitwise-or of DD_* flags. Note that this bitfield may be used before
- * state validation so they need to always be current.
- */
- GLbitfield _TriangleCaps;
- GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */
- GLfloat _EyeZDir[3];
- GLfloat _ModelViewInvScale;
- GLboolean _NeedEyeCoords;
- GLboolean _ForceEyeCoords;
-
- GLuint TextureStateTimestamp; /**< detect changes to shared state */
-
- struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */
- struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */
- /**@}*/
-
- struct gl_list_extensions *ListExt; /**< driver dlist extensions */
-
- /** \name For debugging/development only */
- /*@{*/
- GLboolean FirstTimeCurrent;
- /*@}*/
-
- /** Dither disable via MESA_NO_DITHER env var */
- GLboolean NoDither;
-
- /** software compression/decompression supported or not */
- GLboolean Mesa_DXTn;
-
- GLboolean TextureFormatSupported[MESA_FORMAT_COUNT];
-
- /**
- * Use dp4 (rather than mul/mad) instructions for position
- * transformation?
- */
- GLboolean mvp_with_dp4;
-
- /**
- * \name Hooks for module contexts.
- *
- * These will eventually live in the driver or elsewhere.
- */
- /*@{*/
- void *swrast_context;
- void *swsetup_context;
- void *swtnl_context;
- void *swtnl_im;
- struct st_context *st;
- void *aelt_context;
- /*@}*/
-};
-
-
-#ifdef DEBUG
-extern int MESA_VERBOSE;
-extern int MESA_DEBUG_FLAGS;
-# define MESA_FUNCTION __FUNCTION__
-#else
-# define MESA_VERBOSE 0
-# define MESA_DEBUG_FLAGS 0
-# define MESA_FUNCTION "a function"
-# ifndef NDEBUG
-# define NDEBUG
-# endif
-#endif
-
-
-/** The MESA_VERBOSE var is a bitmask of these flags */
-enum _verbose
-{
- VERBOSE_VARRAY = 0x0001,
- VERBOSE_TEXTURE = 0x0002,
- VERBOSE_MATERIAL = 0x0004,
- VERBOSE_PIPELINE = 0x0008,
- VERBOSE_DRIVER = 0x0010,
- VERBOSE_STATE = 0x0020,
- VERBOSE_API = 0x0040,
- VERBOSE_DISPLAY_LIST = 0x0100,
- VERBOSE_LIGHTING = 0x0200,
- VERBOSE_PRIMS = 0x0400,
- VERBOSE_VERTS = 0x0800,
- VERBOSE_DISASSEM = 0x1000,
- VERBOSE_DRAW = 0x2000,
- VERBOSE_SWAPBUFFERS = 0x4000
-};
-
-
-/** The MESA_DEBUG_FLAGS var is a bitmask of these flags */
-enum _debug
-{
- DEBUG_ALWAYS_FLUSH = 0x1
-};
-
-
-
-#endif /* MTYPES_H */
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.7
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 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
+ * 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.
+ */
+
+/**
+ * \file mtypes.h
+ * Main Mesa data structures.
+ *
+ * Please try to mark derived values with a leading underscore ('_').
+ */
+
+#ifndef MTYPES_H
+#define MTYPES_H
+
+
+#include "main/glheader.h"
+#include "main/config.h"
+#include "main/mfeatures.h"
+#include "glapi/glapi.h"
+#include "math/m_matrix.h" /* GLmatrix */
+#include "main/simple_list.h" /* struct simple_node */
+#include "main/formats.h" /* MESA_FORMAT_COUNT */
+
+
+/**
+ * Color channel data type.
+ */
+#if CHAN_BITS == 8
+ typedef GLubyte GLchan;
+#define CHAN_MAX 255
+#define CHAN_MAXF 255.0F
+#define CHAN_TYPE GL_UNSIGNED_BYTE
+#elif CHAN_BITS == 16
+ typedef GLushort GLchan;
+#define CHAN_MAX 65535
+#define CHAN_MAXF 65535.0F
+#define CHAN_TYPE GL_UNSIGNED_SHORT
+#elif CHAN_BITS == 32
+ typedef GLfloat GLchan;
+#define CHAN_MAX 1.0
+#define CHAN_MAXF 1.0F
+#define CHAN_TYPE GL_FLOAT
+#else
+#error "illegal number of color channel bits"
+#endif
+
+
+/**
+ * Stencil buffer data type.
+ */
+#if STENCIL_BITS==8
+ typedef GLubyte GLstencil;
+#elif STENCIL_BITS==16
+ typedef GLushort GLstencil;
+#else
+# error "illegal number of stencil bits"
+#endif
+
+
+/**
+ * \name 64-bit extension of GLbitfield.
+ */
+/*@{*/
+typedef GLuint64 GLbitfield64;
+
+#define BITFIELD64_ONE 1ULL
+#define BITFIELD64_ALLONES ~0ULL
+
+/** Set a single bit */
+#define BITFIELD64_BIT(b) (BITFIELD64_ONE << (b))
+
+/** Set a mask of the least significant \c b bits */
+#define BITFIELD64_MASK(b) (((b) >= 64) ? BITFIELD64_ALLONES : \
+ (BITFIELD64_BIT(b) - 1))
+
+/**
+ * Set all bits from l (low bit) to h (high bit), inclusive.
+ *
+ * \note \C BITFIELD_64_RANGE(0, 63) return 64 set bits.
+ */
+#define BITFIELD64_RANGE(l, h) (BITFIELD64_MASK((h) + 1) & ~BITFIELD64_MASK(l))
+/*@}*/
+
+
+/**
+ * \name Some forward type declarations
+ */
+/*@{*/
+struct _mesa_HashTable;
+struct gl_attrib_node;
+struct gl_list_extensions;
+struct gl_meta_state;
+struct gl_pixelstore_attrib;
+struct gl_program_cache;
+struct gl_texture_format;
+struct gl_texture_image;
+struct gl_texture_object;
+struct gl_context;
+struct st_context;
+/*@}*/
+
+
+/** Extra draw modes beyond GL_POINTS, GL_TRIANGLE_FAN, etc */
+#define PRIM_OUTSIDE_BEGIN_END (GL_POLYGON+1)
+#define PRIM_INSIDE_UNKNOWN_PRIM (GL_POLYGON+2)
+#define PRIM_UNKNOWN (GL_POLYGON+3)
+
+
+/**
+ * Shader stages. Note that these will become 5 with tessellation.
+ * These MUST have the same values as gallium's PIPE_SHADER_*
+ */
+typedef enum
+{
+ MESA_SHADER_VERTEX = 0,
+ MESA_SHADER_FRAGMENT = 1,
+ MESA_SHADER_GEOMETRY = 2,
+ MESA_SHADER_TYPES = 3
+} gl_shader_type;
+
+
+
+/**
+ * Indexes for vertex program attributes.
+ * GL_NV_vertex_program aliases generic attributes over the conventional
+ * attributes. In GL_ARB_vertex_program shader the aliasing is optional.
+ * In GL_ARB_vertex_shader / OpenGL 2.0 the aliasing is disallowed (the
+ * generic attributes are distinct/separate).
+ */
+typedef enum
+{
+ VERT_ATTRIB_POS = 0,
+ VERT_ATTRIB_WEIGHT = 1,
+ VERT_ATTRIB_NORMAL = 2,
+ VERT_ATTRIB_COLOR0 = 3,
+ VERT_ATTRIB_COLOR1 = 4,
+ VERT_ATTRIB_FOG = 5,
+ VERT_ATTRIB_COLOR_INDEX = 6,
+ VERT_ATTRIB_POINT_SIZE = 6, /*alias*/
+ VERT_ATTRIB_EDGEFLAG = 7,
+ VERT_ATTRIB_TEX0 = 8,
+ VERT_ATTRIB_TEX1 = 9,
+ VERT_ATTRIB_TEX2 = 10,
+ VERT_ATTRIB_TEX3 = 11,
+ VERT_ATTRIB_TEX4 = 12,
+ VERT_ATTRIB_TEX5 = 13,
+ VERT_ATTRIB_TEX6 = 14,
+ VERT_ATTRIB_TEX7 = 15,
+ VERT_ATTRIB_GENERIC0 = 16,
+ VERT_ATTRIB_GENERIC1 = 17,
+ VERT_ATTRIB_GENERIC2 = 18,
+ VERT_ATTRIB_GENERIC3 = 19,
+ VERT_ATTRIB_GENERIC4 = 20,
+ VERT_ATTRIB_GENERIC5 = 21,
+ VERT_ATTRIB_GENERIC6 = 22,
+ VERT_ATTRIB_GENERIC7 = 23,
+ VERT_ATTRIB_GENERIC8 = 24,
+ VERT_ATTRIB_GENERIC9 = 25,
+ VERT_ATTRIB_GENERIC10 = 26,
+ VERT_ATTRIB_GENERIC11 = 27,
+ VERT_ATTRIB_GENERIC12 = 28,
+ VERT_ATTRIB_GENERIC13 = 29,
+ VERT_ATTRIB_GENERIC14 = 30,
+ VERT_ATTRIB_GENERIC15 = 31,
+ VERT_ATTRIB_MAX = 32
+} gl_vert_attrib;
+
+/**
+ * Bitflags for vertex attributes.
+ * These are used in bitfields in many places.
+ */
+/*@{*/
+#define VERT_BIT_POS (1 << VERT_ATTRIB_POS)
+#define VERT_BIT_WEIGHT (1 << VERT_ATTRIB_WEIGHT)
+#define VERT_BIT_NORMAL (1 << VERT_ATTRIB_NORMAL)
+#define VERT_BIT_COLOR0 (1 << VERT_ATTRIB_COLOR0)
+#define VERT_BIT_COLOR1 (1 << VERT_ATTRIB_COLOR1)
+#define VERT_BIT_FOG (1 << VERT_ATTRIB_FOG)
+#define VERT_BIT_COLOR_INDEX (1 << VERT_ATTRIB_COLOR_INDEX)
+#define VERT_BIT_EDGEFLAG (1 << VERT_ATTRIB_EDGEFLAG)
+#define VERT_BIT_TEX0 (1 << VERT_ATTRIB_TEX0)
+#define VERT_BIT_TEX1 (1 << VERT_ATTRIB_TEX1)
+#define VERT_BIT_TEX2 (1 << VERT_ATTRIB_TEX2)
+#define VERT_BIT_TEX3 (1 << VERT_ATTRIB_TEX3)
+#define VERT_BIT_TEX4 (1 << VERT_ATTRIB_TEX4)
+#define VERT_BIT_TEX5 (1 << VERT_ATTRIB_TEX5)
+#define VERT_BIT_TEX6 (1 << VERT_ATTRIB_TEX6)
+#define VERT_BIT_TEX7 (1 << VERT_ATTRIB_TEX7)
+#define VERT_BIT_GENERIC0 (1 << VERT_ATTRIB_GENERIC0)
+#define VERT_BIT_GENERIC1 (1 << VERT_ATTRIB_GENERIC1)
+#define VERT_BIT_GENERIC2 (1 << VERT_ATTRIB_GENERIC2)
+#define VERT_BIT_GENERIC3 (1 << VERT_ATTRIB_GENERIC3)
+#define VERT_BIT_GENERIC4 (1 << VERT_ATTRIB_GENERIC4)
+#define VERT_BIT_GENERIC5 (1 << VERT_ATTRIB_GENERIC5)
+#define VERT_BIT_GENERIC6 (1 << VERT_ATTRIB_GENERIC6)
+#define VERT_BIT_GENERIC7 (1 << VERT_ATTRIB_GENERIC7)
+#define VERT_BIT_GENERIC8 (1 << VERT_ATTRIB_GENERIC8)
+#define VERT_BIT_GENERIC9 (1 << VERT_ATTRIB_GENERIC9)
+#define VERT_BIT_GENERIC10 (1 << VERT_ATTRIB_GENERIC10)
+#define VERT_BIT_GENERIC11 (1 << VERT_ATTRIB_GENERIC11)
+#define VERT_BIT_GENERIC12 (1 << VERT_ATTRIB_GENERIC12)
+#define VERT_BIT_GENERIC13 (1 << VERT_ATTRIB_GENERIC13)
+#define VERT_BIT_GENERIC14 (1 << VERT_ATTRIB_GENERIC14)
+#define VERT_BIT_GENERIC15 (1 << VERT_ATTRIB_GENERIC15)
+
+#define VERT_BIT_TEX(u) (1 << (VERT_ATTRIB_TEX0 + (u)))
+#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g)))
+/*@}*/
+
+
+/**
+ * Indexes for vertex program result attributes
+ */
+typedef enum
+{
+ VERT_RESULT_HPOS = 0,
+ VERT_RESULT_COL0 = 1,
+ VERT_RESULT_COL1 = 2,
+ VERT_RESULT_FOGC = 3,
+ VERT_RESULT_TEX0 = 4,
+ VERT_RESULT_TEX1 = 5,
+ VERT_RESULT_TEX2 = 6,
+ VERT_RESULT_TEX3 = 7,
+ VERT_RESULT_TEX4 = 8,
+ VERT_RESULT_TEX5 = 9,
+ VERT_RESULT_TEX6 = 10,
+ VERT_RESULT_TEX7 = 11,
+ VERT_RESULT_PSIZ = 12,
+ VERT_RESULT_BFC0 = 13,
+ VERT_RESULT_BFC1 = 14,
+ VERT_RESULT_EDGE = 15,
+ VERT_RESULT_VAR0 = 16, /**< shader varying */
+ VERT_RESULT_MAX = (VERT_RESULT_VAR0 + MAX_VARYING)
+} gl_vert_result;
+
+
+/*********************************************/
+
+/**
+ * Indexes for geometry program attributes.
+ */
+typedef enum
+{
+ GEOM_ATTRIB_POSITION = 0,
+ GEOM_ATTRIB_COLOR0 = 1,
+ GEOM_ATTRIB_COLOR1 = 2,
+ GEOM_ATTRIB_SECONDARY_COLOR0 = 3,
+ GEOM_ATTRIB_SECONDARY_COLOR1 = 4,
+ GEOM_ATTRIB_FOG_FRAG_COORD = 5,
+ GEOM_ATTRIB_POINT_SIZE = 6,
+ GEOM_ATTRIB_CLIP_VERTEX = 7,
+ GEOM_ATTRIB_PRIMITIVE_ID = 8,
+ GEOM_ATTRIB_TEX_COORD = 9,
+
+ GEOM_ATTRIB_VAR0 = 16,
+ GEOM_ATTRIB_MAX = (GEOM_ATTRIB_VAR0 + MAX_VARYING)
+} gl_geom_attrib;
+
+/**
+ * Bitflags for geometry attributes.
+ * These are used in bitfields in many places.
+ */
+/*@{*/
+#define GEOM_BIT_COLOR0 (1 << GEOM_ATTRIB_COLOR0)
+#define GEOM_BIT_COLOR1 (1 << GEOM_ATTRIB_COLOR1)
+#define GEOM_BIT_SCOLOR0 (1 << GEOM_ATTRIB_SECONDARY_COLOR0)
+#define GEOM_BIT_SCOLOR1 (1 << GEOM_ATTRIB_SECONDARY_COLOR1)
+#define GEOM_BIT_TEX_COORD (1 << GEOM_ATTRIB_TEX_COORD)
+#define GEOM_BIT_FOG_COORD (1 << GEOM_ATTRIB_FOG_FRAG_COORD)
+#define GEOM_BIT_POSITION (1 << GEOM_ATTRIB_POSITION)
+#define GEOM_BIT_POINT_SIDE (1 << GEOM_ATTRIB_POINT_SIZE)
+#define GEOM_BIT_CLIP_VERTEX (1 << GEOM_ATTRIB_CLIP_VERTEX)
+#define GEOM_BIT_PRIM_ID (1 << GEOM_ATTRIB_PRIMITIVE_ID)
+#define GEOM_BIT_VAR0 (1 << GEOM_ATTRIB_VAR0)
+
+#define GEOM_BIT_VAR(g) (1 << (GEOM_BIT_VAR0 + (g)))
+/*@}*/
+
+
+/**
+ * Indexes for geometry program result attributes
+ */
+typedef enum
+{
+ GEOM_RESULT_POS = 0,
+ GEOM_RESULT_COL0 = 1,
+ GEOM_RESULT_COL1 = 2,
+ GEOM_RESULT_SCOL0 = 3,
+ GEOM_RESULT_SCOL1 = 4,
+ GEOM_RESULT_FOGC = 5,
+ GEOM_RESULT_TEX0 = 6,
+ GEOM_RESULT_TEX1 = 7,
+ GEOM_RESULT_TEX2 = 8,
+ GEOM_RESULT_TEX3 = 9,
+ GEOM_RESULT_TEX4 = 10,
+ GEOM_RESULT_TEX5 = 11,
+ GEOM_RESULT_TEX6 = 12,
+ GEOM_RESULT_TEX7 = 13,
+ GEOM_RESULT_PSIZ = 14,
+ GEOM_RESULT_CLPV = 15,
+ GEOM_RESULT_PRID = 16,
+ GEOM_RESULT_LAYR = 17,
+ GEOM_RESULT_VAR0 = 18, /**< shader varying, should really be 16 */
+ /* ### we need to -2 because var0 is 18 instead 16 like in the others */
+ GEOM_RESULT_MAX = (GEOM_RESULT_VAR0 + MAX_VARYING - 2)
+} gl_geom_result;
+
+
+/**
+ * Indexes for fragment program input attributes.
+ */
+typedef enum
+{
+ FRAG_ATTRIB_WPOS = 0,
+ FRAG_ATTRIB_COL0 = 1,
+ FRAG_ATTRIB_COL1 = 2,
+ FRAG_ATTRIB_FOGC = 3,
+ FRAG_ATTRIB_TEX0 = 4,
+ FRAG_ATTRIB_TEX1 = 5,
+ FRAG_ATTRIB_TEX2 = 6,
+ FRAG_ATTRIB_TEX3 = 7,
+ FRAG_ATTRIB_TEX4 = 8,
+ FRAG_ATTRIB_TEX5 = 9,
+ FRAG_ATTRIB_TEX6 = 10,
+ FRAG_ATTRIB_TEX7 = 11,
+ FRAG_ATTRIB_FACE = 12, /**< front/back face */
+ FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */
+ FRAG_ATTRIB_VAR0 = 14, /**< shader varying */
+ FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
+} gl_frag_attrib;
+
+/**
+ * Bitflags for fragment program input attributes.
+ */
+/*@{*/
+#define FRAG_BIT_WPOS (1 << FRAG_ATTRIB_WPOS)
+#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0)
+#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1)
+#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC)
+#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE)
+#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC)
+#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0)
+#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1)
+#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2)
+#define FRAG_BIT_TEX3 (1 << FRAG_ATTRIB_TEX3)
+#define FRAG_BIT_TEX4 (1 << FRAG_ATTRIB_TEX4)
+#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5)
+#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6)
+#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7)
+#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0)
+
+#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U))
+#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V))
+
+#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \
+ FRAG_BIT_TEX1| \
+ FRAG_BIT_TEX2| \
+ FRAG_BIT_TEX3| \
+ FRAG_BIT_TEX4| \
+ FRAG_BIT_TEX5| \
+ FRAG_BIT_TEX6| \
+ FRAG_BIT_TEX7)
+/*@}*/
+
+
+/**
+ * Fragment program results
+ */
+typedef enum
+{
+ FRAG_RESULT_DEPTH = 0,
+ FRAG_RESULT_STENCIL = 1,
+ FRAG_RESULT_COLOR = 2,
+ FRAG_RESULT_DATA0 = 3,
+ FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
+} gl_frag_result;
+
+
+/**
+ * Indexes for all renderbuffers
+ */
+typedef enum
+{
+ /* the four standard color buffers */
+ BUFFER_FRONT_LEFT,
+ BUFFER_BACK_LEFT,
+ BUFFER_FRONT_RIGHT,
+ BUFFER_BACK_RIGHT,
+ BUFFER_DEPTH,
+ BUFFER_STENCIL,
+ BUFFER_ACCUM,
+ /* optional aux buffer */
+ BUFFER_AUX0,
+ /* generic renderbuffers */
+ BUFFER_COLOR0,
+ BUFFER_COLOR1,
+ BUFFER_COLOR2,
+ BUFFER_COLOR3,
+ BUFFER_COLOR4,
+ BUFFER_COLOR5,
+ BUFFER_COLOR6,
+ BUFFER_COLOR7,
+ BUFFER_COUNT
+} gl_buffer_index;
+
+/**
+ * Bit flags for all renderbuffers
+ */
+#define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT)
+#define BUFFER_BIT_BACK_LEFT (1 << BUFFER_BACK_LEFT)
+#define BUFFER_BIT_FRONT_RIGHT (1 << BUFFER_FRONT_RIGHT)
+#define BUFFER_BIT_BACK_RIGHT (1 << BUFFER_BACK_RIGHT)
+#define BUFFER_BIT_AUX0 (1 << BUFFER_AUX0)
+#define BUFFER_BIT_AUX1 (1 << BUFFER_AUX1)
+#define BUFFER_BIT_AUX2 (1 << BUFFER_AUX2)
+#define BUFFER_BIT_AUX3 (1 << BUFFER_AUX3)
+#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH)
+#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL)
+#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM)
+#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0)
+#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1)
+#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2)
+#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3)
+#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4)
+#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5)
+#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6)
+#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7)
+
+/**
+ * Mask of all the color buffer bits (but not accum).
+ */
+#define BUFFER_BITS_COLOR (BUFFER_BIT_FRONT_LEFT | \
+ BUFFER_BIT_BACK_LEFT | \
+ BUFFER_BIT_FRONT_RIGHT | \
+ BUFFER_BIT_BACK_RIGHT | \
+ BUFFER_BIT_AUX0 | \
+ BUFFER_BIT_COLOR0 | \
+ BUFFER_BIT_COLOR1 | \
+ BUFFER_BIT_COLOR2 | \
+ BUFFER_BIT_COLOR3 | \
+ BUFFER_BIT_COLOR4 | \
+ BUFFER_BIT_COLOR5 | \
+ BUFFER_BIT_COLOR6 | \
+ BUFFER_BIT_COLOR7)
+
+
+/**
+ * Framebuffer configuration (aka visual / pixelformat)
+ * Note: some of these fields should be boolean, but it appears that
+ * code in drivers/dri/common/util.c requires int-sized fields.
+ */
+struct gl_config
+{
+ GLboolean rgbMode;
+ GLboolean floatMode;
+ GLboolean colorIndexMode; /* XXX is this used anywhere? */
+ GLuint doubleBufferMode;
+ GLuint stereoMode;
+
+ GLboolean haveAccumBuffer;
+ GLboolean haveDepthBuffer;
+ GLboolean haveStencilBuffer;
+
+ GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */
+ GLuint redMask, greenMask, blueMask, alphaMask;
+ GLint rgbBits; /* total bits for rgb */
+ GLint indexBits; /* total bits for colorindex */
+
+ GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
+ GLint depthBits;
+ GLint stencilBits;
+
+ GLint numAuxBuffers;
+
+ GLint level;
+
+ /* EXT_visual_rating / GLX 1.2 */
+ GLint visualRating;
+
+ /* EXT_visual_info / GLX 1.2 */
+ GLint transparentPixel;
+ /* colors are floats scaled to ints */
+ GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
+ GLint transparentIndex;
+
+ /* ARB_multisample / SGIS_multisample */
+ GLint sampleBuffers;
+ GLint samples;
+
+ /* SGIX_pbuffer / GLX 1.3 */
+ GLint maxPbufferWidth;
+ GLint maxPbufferHeight;
+ GLint maxPbufferPixels;
+ GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */
+ GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */
+
+ /* OML_swap_method */
+ GLint swapMethod;
+
+ /* EXT_texture_from_pixmap */
+ GLint bindToTextureRgb;
+ GLint bindToTextureRgba;
+ GLint bindToMipmapTexture;
+ GLint bindToTextureTargets;
+ GLint yInverted;
+
+ /* EXT_framebuffer_sRGB */
+ GLint sRGBCapable;
+};
+
+
+/**
+ * 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.
+ */
+/*@{*/
+#define MAT_ATTRIB_FRONT_AMBIENT 0
+#define MAT_ATTRIB_BACK_AMBIENT 1
+#define MAT_ATTRIB_FRONT_DIFFUSE 2
+#define MAT_ATTRIB_BACK_DIFFUSE 3
+#define MAT_ATTRIB_FRONT_SPECULAR 4
+#define MAT_ATTRIB_BACK_SPECULAR 5
+#define MAT_ATTRIB_FRONT_EMISSION 6
+#define MAT_ATTRIB_BACK_EMISSION 7
+#define MAT_ATTRIB_FRONT_SHININESS 8
+#define MAT_ATTRIB_BACK_SHININESS 9
+#define MAT_ATTRIB_FRONT_INDEXES 10
+#define MAT_ATTRIB_BACK_INDEXES 11
+#define MAT_ATTRIB_MAX 12
+
+#define MAT_ATTRIB_AMBIENT(f) (MAT_ATTRIB_FRONT_AMBIENT+(f))
+#define MAT_ATTRIB_DIFFUSE(f) (MAT_ATTRIB_FRONT_DIFFUSE+(f))
+#define MAT_ATTRIB_SPECULAR(f) (MAT_ATTRIB_FRONT_SPECULAR+(f))
+#define MAT_ATTRIB_EMISSION(f) (MAT_ATTRIB_FRONT_EMISSION+(f))
+#define MAT_ATTRIB_SHININESS(f)(MAT_ATTRIB_FRONT_SHININESS+(f))
+#define MAT_ATTRIB_INDEXES(f) (MAT_ATTRIB_FRONT_INDEXES+(f))
+
+#define MAT_INDEX_AMBIENT 0
+#define MAT_INDEX_DIFFUSE 1
+#define MAT_INDEX_SPECULAR 2
+
+#define MAT_BIT_FRONT_AMBIENT (1<<MAT_ATTRIB_FRONT_AMBIENT)
+#define MAT_BIT_BACK_AMBIENT (1<<MAT_ATTRIB_BACK_AMBIENT)
+#define MAT_BIT_FRONT_DIFFUSE (1<<MAT_ATTRIB_FRONT_DIFFUSE)
+#define MAT_BIT_BACK_DIFFUSE (1<<MAT_ATTRIB_BACK_DIFFUSE)
+#define MAT_BIT_FRONT_SPECULAR (1<<MAT_ATTRIB_FRONT_SPECULAR)
+#define MAT_BIT_BACK_SPECULAR (1<<MAT_ATTRIB_BACK_SPECULAR)
+#define MAT_BIT_FRONT_EMISSION (1<<MAT_ATTRIB_FRONT_EMISSION)
+#define MAT_BIT_BACK_EMISSION (1<<MAT_ATTRIB_BACK_EMISSION)
+#define MAT_BIT_FRONT_SHININESS (1<<MAT_ATTRIB_FRONT_SHININESS)
+#define MAT_BIT_BACK_SHININESS (1<<MAT_ATTRIB_BACK_SHININESS)
+#define MAT_BIT_FRONT_INDEXES (1<<MAT_ATTRIB_FRONT_INDEXES)
+#define MAT_BIT_BACK_INDEXES (1<<MAT_ATTRIB_BACK_INDEXES)
+
+
+#define FRONT_MATERIAL_BITS (MAT_BIT_FRONT_EMISSION | \
+ MAT_BIT_FRONT_AMBIENT | \
+ MAT_BIT_FRONT_DIFFUSE | \
+ MAT_BIT_FRONT_SPECULAR | \
+ MAT_BIT_FRONT_SHININESS | \
+ MAT_BIT_FRONT_INDEXES)
+
+#define BACK_MATERIAL_BITS (MAT_BIT_BACK_EMISSION | \
+ MAT_BIT_BACK_AMBIENT | \
+ MAT_BIT_BACK_DIFFUSE | \
+ MAT_BIT_BACK_SPECULAR | \
+ MAT_BIT_BACK_SHININESS | \
+ MAT_BIT_BACK_INDEXES)
+
+#define ALL_MATERIAL_BITS (FRONT_MATERIAL_BITS | BACK_MATERIAL_BITS)
+/*@}*/
+
+
+#define EXP_TABLE_SIZE 512 /**< Specular exponent lookup table sizes */
+#define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */
+
+/**
+ * Material shininess lookup table.
+ */
+struct gl_shine_tab
+{
+ struct gl_shine_tab *next, *prev;
+ GLfloat tab[SHINE_TABLE_SIZE+1];
+ GLfloat shininess;
+ GLuint refcount;
+};
+
+
+/**
+ * Light source state.
+ */
+struct gl_light
+{
+ struct gl_light *next; /**< double linked list with sentinel */
+ struct gl_light *prev;
+
+ GLfloat Ambient[4]; /**< ambient color */
+ GLfloat Diffuse[4]; /**< diffuse color */
+ GLfloat Specular[4]; /**< specular color */
+ GLfloat EyePosition[4]; /**< position in eye coordinates */
+ GLfloat SpotDirection[4]; /**< spotlight direction in eye coordinates */
+ GLfloat SpotExponent;
+ GLfloat SpotCutoff; /**< in degrees */
+ GLfloat _CosCutoffNeg; /**< = cos(SpotCutoff) */
+ GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */
+ GLfloat ConstantAttenuation;
+ GLfloat LinearAttenuation;
+ GLfloat QuadraticAttenuation;
+ GLboolean Enabled; /**< On/off flag */
+
+ /**
+ * \name Derived fields
+ */
+ /*@{*/
+ GLbitfield _Flags; /**< State */
+
+ GLfloat _Position[4]; /**< position in eye/obj coordinates */
+ GLfloat _VP_inf_norm[3]; /**< Norm direction to infinite light */
+ GLfloat _h_inf_norm[3]; /**< Norm( _VP_inf_norm + <0,0,1> ) */
+ GLfloat _NormSpotDirection[4]; /**< normalized spotlight direction */
+ GLfloat _VP_inf_spot_attenuation;
+
+ GLfloat _SpotExpTable[EXP_TABLE_SIZE][2]; /**< to replace a pow() call */
+ GLfloat _MatAmbient[2][3]; /**< material ambient * light ambient */
+ GLfloat _MatDiffuse[2][3]; /**< material diffuse * light diffuse */
+ GLfloat _MatSpecular[2][3]; /**< material spec * light specular */
+ GLfloat _dli; /**< CI diffuse light intensity */
+ GLfloat _sli; /**< CI specular light intensity */
+ /*@}*/
+};
+
+
+/**
+ * Light model state.
+ */
+struct gl_lightmodel
+{
+ GLfloat Ambient[4]; /**< ambient color */
+ GLboolean LocalViewer; /**< Local (or infinite) view point? */
+ GLboolean TwoSide; /**< Two (or one) sided lighting? */
+ GLenum ColorControl; /**< either GL_SINGLE_COLOR
+ * or GL_SEPARATE_SPECULAR_COLOR */
+};
+
+
+/**
+ * Material state.
+ */
+struct gl_material
+{
+ GLfloat Attrib[MAT_ATTRIB_MAX][4];
+};
+
+
+/**
+ * Accumulation buffer attribute group (GL_ACCUM_BUFFER_BIT)
+ */
+struct gl_accum_attrib
+{
+ GLfloat ClearColor[4]; /**< Accumulation buffer clear color */
+};
+
+
+/**
+ * Color buffer attribute group (GL_COLOR_BUFFER_BIT).
+ */
+struct gl_colorbuffer_attrib
+{
+ GLuint ClearIndex; /**< Index to use for glClear */
+ GLclampf ClearColor[4]; /**< Color to use for glClear */
+
+ GLuint IndexMask; /**< Color index write mask */
+ GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */
+
+ GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */
+
+ /**
+ * \name alpha testing
+ */
+ /*@{*/
+ GLboolean AlphaEnabled; /**< Alpha test enabled flag */
+ GLenum AlphaFunc; /**< Alpha test function */
+ GLclampf AlphaRef; /**< Alpha reference value */
+ /*@}*/
+
+ /**
+ * \name Blending
+ */
+ /*@{*/
+ GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */
+ GLfloat BlendColor[4]; /**< Blending color */
+ struct
+ {
+ GLenum SrcRGB; /**< RGB blend source term */
+ GLenum DstRGB; /**< RGB blend dest term */
+ GLenum SrcA; /**< Alpha blend source term */
+ GLenum DstA; /**< Alpha blend dest term */
+ GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
+ GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
+ } Blend[MAX_DRAW_BUFFERS];
+ /** Are the blend func terms currently different for each buffer/target? */
+ GLboolean _BlendFuncPerBuffer;
+ /** Are the blend equations currently different for each buffer/target? */
+ GLboolean _BlendEquationPerBuffer;
+ /*@}*/
+
+ /**
+ * \name Logic op
+ */
+ /*@{*/
+ GLenum LogicOp; /**< Logic operator */
+ GLboolean IndexLogicOpEnabled; /**< Color index logic op enabled flag */
+ GLboolean ColorLogicOpEnabled; /**< RGBA logic op enabled flag */
+ GLboolean _LogicOpEnabled; /**< RGBA logic op + EXT_blend_logic_op enabled flag */
+ /*@}*/
+
+ GLboolean DitherFlag; /**< Dither enable flag */
+
+ GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
+ GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
+
+ GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */
+};
+
+
+/**
+ * Current attribute group (GL_CURRENT_BIT).
+ */
+struct gl_current_attrib
+{
+ /**
+ * \name Current vertex attributes.
+ * \note Values are valid only after FLUSH_VERTICES has been called.
+ * \note Index and Edgeflag current values are stored as floats in the
+ * SIX and SEVEN attribute slots.
+ */
+ GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */
+
+ /**
+ * \name Current raster position attributes (always valid).
+ * \note This set of attributes is very similar to the SWvertex struct.
+ */
+ /*@{*/
+ GLfloat RasterPos[4];
+ GLfloat RasterDistance;
+ GLfloat RasterColor[4];
+ GLfloat RasterSecondaryColor[4];
+ GLfloat RasterTexCoords[MAX_TEXTURE_COORD_UNITS][4];
+ GLboolean RasterPosValid;
+ /*@}*/
+};
+
+
+/**
+ * Depth buffer attribute group (GL_DEPTH_BUFFER_BIT).
+ */
+struct gl_depthbuffer_attrib
+{
+ GLenum Func; /**< Function for depth buffer compare */
+ GLclampd Clear; /**< Value to clear depth buffer to */
+ GLboolean Test; /**< Depth buffering enabled flag */
+ GLboolean Mask; /**< Depth buffer writable? */
+ GLboolean BoundsTest; /**< GL_EXT_depth_bounds_test */
+ GLfloat BoundsMin, BoundsMax;/**< GL_EXT_depth_bounds_test */
+};
+
+
+/**
+ * Evaluator attribute group (GL_EVAL_BIT).
+ */
+struct gl_eval_attrib
+{
+ /**
+ * \name Enable bits
+ */
+ /*@{*/
+ GLboolean Map1Color4;
+ GLboolean Map1Index;
+ GLboolean Map1Normal;
+ GLboolean Map1TextureCoord1;
+ GLboolean Map1TextureCoord2;
+ GLboolean Map1TextureCoord3;
+ GLboolean Map1TextureCoord4;
+ GLboolean Map1Vertex3;
+ GLboolean Map1Vertex4;
+ GLboolean Map1Attrib[16]; /* GL_NV_vertex_program */
+ GLboolean Map2Color4;
+ GLboolean Map2Index;
+ GLboolean Map2Normal;
+ GLboolean Map2TextureCoord1;
+ GLboolean Map2TextureCoord2;
+ GLboolean Map2TextureCoord3;
+ GLboolean Map2TextureCoord4;
+ GLboolean Map2Vertex3;
+ GLboolean Map2Vertex4;
+ GLboolean Map2Attrib[16]; /* GL_NV_vertex_program */
+ GLboolean AutoNormal;
+ /*@}*/
+
+ /**
+ * \name Map Grid endpoints and divisions and calculated du values
+ */
+ /*@{*/
+ GLint MapGrid1un;
+ GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du;
+ GLint MapGrid2un, MapGrid2vn;
+ GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du;
+ GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv;
+ /*@}*/
+};
+
+
+/**
+ * Fog attribute group (GL_FOG_BIT).
+ */
+struct gl_fog_attrib
+{
+ GLboolean Enabled; /**< Fog enabled flag */
+ GLfloat Color[4]; /**< Fog color */
+ GLfloat Density; /**< Density >= 0.0 */
+ GLfloat Start; /**< Start distance in eye coords */
+ GLfloat End; /**< End distance in eye coords */
+ GLfloat Index; /**< Fog index */
+ GLenum Mode; /**< Fog mode */
+ GLboolean ColorSumEnabled;
+ GLenum FogCoordinateSource; /**< GL_EXT_fog_coord */
+ GLfloat _Scale; /**< (End == Start) ? 1.0 : 1.0 / (End - Start) */
+};
+
+
+/**
+ * Hint attribute group (GL_HINT_BIT).
+ *
+ * Values are always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE.
+ */
+struct gl_hint_attrib
+{
+ GLenum PerspectiveCorrection;
+ GLenum PointSmooth;
+ GLenum LineSmooth;
+ GLenum PolygonSmooth;
+ GLenum Fog;
+ GLenum ClipVolumeClipping; /**< GL_EXT_clip_volume_hint */
+ GLenum TextureCompression; /**< GL_ARB_texture_compression */
+ GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */
+ GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */
+};
+
+/**
+ * Light state flags.
+ */
+/*@{*/
+#define LIGHT_SPOT 0x1
+#define LIGHT_LOCAL_VIEWER 0x2
+#define LIGHT_POSITIONAL 0x4
+#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER)
+/*@}*/
+
+
+/**
+ * Lighting attribute group (GL_LIGHT_BIT).
+ */
+struct gl_light_attrib
+{
+ struct gl_light Light[MAX_LIGHTS]; /**< Array of light sources */
+ struct gl_lightmodel Model; /**< Lighting model */
+
+ /**
+ * Must flush FLUSH_VERTICES before referencing:
+ */
+ /*@{*/
+ struct gl_material Material; /**< Includes front & back values */
+ /*@}*/
+
+ GLboolean Enabled; /**< Lighting enabled flag */
+ GLenum ShadeModel; /**< GL_FLAT or GL_SMOOTH */
+ GLenum ProvokingVertex; /**< GL_EXT_provoking_vertex */
+ GLenum ColorMaterialFace; /**< GL_FRONT, BACK or FRONT_AND_BACK */
+ GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */
+ GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */
+ GLboolean ColorMaterialEnabled;
+ GLenum ClampVertexColor;
+
+ struct gl_light EnabledList; /**< List sentinel */
+
+ /**
+ * Derived state for optimizations:
+ */
+ /*@{*/
+ GLboolean _NeedEyeCoords;
+ GLboolean _NeedVertices; /**< Use fast shader? */
+ GLbitfield _Flags; /**< LIGHT_* flags, see above */
+ GLfloat _BaseColor[2][3];
+ /*@}*/
+};
+
+
+/**
+ * Line attribute group (GL_LINE_BIT).
+ */
+struct gl_line_attrib
+{
+ GLboolean SmoothFlag; /**< GL_LINE_SMOOTH enabled? */
+ GLboolean StippleFlag; /**< GL_LINE_STIPPLE enabled? */
+ GLushort StipplePattern; /**< Stipple pattern */
+ GLint StippleFactor; /**< Stipple repeat factor */
+ GLfloat Width; /**< Line width */
+};
+
+
+/**
+ * Display list attribute group (GL_LIST_BIT).
+ */
+struct gl_list_attrib
+{
+ GLuint ListBase;
+};
+
+
+/**
+ * Multisample attribute group (GL_MULTISAMPLE_BIT).
+ */
+struct gl_multisample_attrib
+{
+ GLboolean Enabled;
+ GLboolean _Enabled; /**< true if Enabled and multisample buffer */
+ GLboolean SampleAlphaToCoverage;
+ GLboolean SampleAlphaToOne;
+ GLboolean SampleCoverage;
+ GLfloat SampleCoverageValue;
+ GLboolean SampleCoverageInvert;
+};
+
+
+/**
+ * A pixelmap (see glPixelMap)
+ */
+struct gl_pixelmap
+{
+ GLint Size;
+ GLfloat Map[MAX_PIXEL_MAP_TABLE];
+ GLubyte Map8[MAX_PIXEL_MAP_TABLE]; /**< converted to 8-bit color */
+};
+
+
+/**
+ * Collection of all pixelmaps
+ */
+struct gl_pixelmaps
+{
+ struct gl_pixelmap RtoR; /**< i.e. GL_PIXEL_MAP_R_TO_R */
+ struct gl_pixelmap GtoG;
+ struct gl_pixelmap BtoB;
+ struct gl_pixelmap AtoA;
+ struct gl_pixelmap ItoR;
+ struct gl_pixelmap ItoG;
+ struct gl_pixelmap ItoB;
+ struct gl_pixelmap ItoA;
+ struct gl_pixelmap ItoI;
+ struct gl_pixelmap StoS;
+};
+
+
+/**
+ * Pixel attribute group (GL_PIXEL_MODE_BIT).
+ */
+struct gl_pixel_attrib
+{
+ GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */
+
+ /*--- Begin Pixel Transfer State ---*/
+ /* Fields are in the order in which they're applied... */
+
+ /** Scale & Bias (index shift, offset) */
+ /*@{*/
+ GLfloat RedBias, RedScale;
+ GLfloat GreenBias, GreenScale;
+ GLfloat BlueBias, BlueScale;
+ GLfloat AlphaBias, AlphaScale;
+ GLfloat DepthBias, DepthScale;
+ GLint IndexShift, IndexOffset;
+ /*@}*/
+
+ /* Pixel Maps */
+ /* Note: actual pixel maps are not part of this attrib group */
+ GLboolean MapColorFlag;
+ GLboolean MapStencilFlag;
+
+ /*--- End Pixel Transfer State ---*/
+
+ /** glPixelZoom */
+ GLfloat ZoomX, ZoomY;
+
+ /** GL_SGI_texture_color_table */
+ GLfloat TextureColorTableScale[4]; /**< RGBA */
+ GLfloat TextureColorTableBias[4]; /**< RGBA */
+};
+
+
+/**
+ * Point attribute group (GL_POINT_BIT).
+ */
+struct gl_point_attrib
+{
+ GLboolean SmoothFlag; /**< True if GL_POINT_SMOOTH is enabled */
+ GLfloat Size; /**< User-specified point size */
+ GLfloat Params[3]; /**< GL_EXT_point_parameters */
+ GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */
+ GLfloat Threshold; /**< GL_EXT_point_parameters */
+ GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */
+ GLboolean PointSprite; /**< GL_NV/ARB_point_sprite */
+ GLboolean CoordReplace[MAX_TEXTURE_COORD_UNITS]; /**< GL_ARB_point_sprite*/
+ GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */
+ GLenum SpriteOrigin; /**< GL_ARB_point_sprite */
+};
+
+
+/**
+ * Polygon attribute group (GL_POLYGON_BIT).
+ */
+struct gl_polygon_attrib
+{
+ GLenum FrontFace; /**< Either GL_CW or GL_CCW */
+ GLenum FrontMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
+ GLenum BackMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
+ GLboolean _FrontBit; /**< 0=GL_CCW, 1=GL_CW */
+ GLboolean CullFlag; /**< Culling on/off flag */
+ GLboolean SmoothFlag; /**< True if GL_POLYGON_SMOOTH is enabled */
+ GLboolean StippleFlag; /**< True if GL_POLYGON_STIPPLE is enabled */
+ GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */
+ GLfloat OffsetFactor; /**< Polygon offset factor, from user */
+ GLfloat OffsetUnits; /**< Polygon offset units, from user */
+ GLboolean OffsetPoint; /**< Offset in GL_POINT mode */
+ GLboolean OffsetLine; /**< Offset in GL_LINE mode */
+ GLboolean OffsetFill; /**< Offset in GL_FILL mode */
+};
+
+
+/**
+ * Scissor attributes (GL_SCISSOR_BIT).
+ */
+struct gl_scissor_attrib
+{
+ GLboolean Enabled; /**< Scissor test enabled? */
+ GLint X, Y; /**< Lower left corner of box */
+ GLsizei Width, Height; /**< Size of box */
+};
+
+
+/**
+ * Stencil attribute group (GL_STENCIL_BUFFER_BIT).
+ *
+ * Three sets of stencil data are tracked so that OpenGL 2.0,
+ * GL_EXT_stencil_two_side, and GL_ATI_separate_stencil can all be supported
+ * simultaneously. In each of the stencil state arrays, element 0 corresponds
+ * to GL_FRONT. Element 1 corresponds to the OpenGL 2.0 /
+ * GL_ATI_separate_stencil GL_BACK state. Element 2 corresponds to the
+ * GL_EXT_stencil_two_side GL_BACK state.
+ *
+ * The derived value \c _BackFace is either 1 or 2 depending on whether or
+ * not GL_STENCIL_TEST_TWO_SIDE_EXT is enabled.
+ *
+ * The derived value \c _TestTwoSide is set when the front-face and back-face
+ * stencil state are different.
+ */
+struct gl_stencil_attrib
+{
+ GLboolean Enabled; /**< Enabled flag */
+ GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */
+ GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */
+ GLboolean _Enabled; /**< Enabled and stencil buffer present */
+ GLboolean _TestTwoSide;
+ GLubyte _BackFace; /**< Current back stencil state (1 or 2) */
+ GLenum Function[3]; /**< Stencil function */
+ GLenum FailFunc[3]; /**< Fail function */
+ GLenum ZPassFunc[3]; /**< Depth buffer pass function */
+ GLenum ZFailFunc[3]; /**< Depth buffer fail function */
+ GLint Ref[3]; /**< Reference value */
+ GLuint ValueMask[3]; /**< Value mask */
+ GLuint WriteMask[3]; /**< Write mask */
+ GLuint Clear; /**< Clear value */
+};
+
+
+/**
+ * An index for each type of texture object. These correspond to the GL
+ * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc.
+ * Note: the order is from highest priority to lowest priority.
+ */
+typedef enum
+{
+ TEXTURE_2D_ARRAY_INDEX,
+ TEXTURE_1D_ARRAY_INDEX,
+ TEXTURE_CUBE_INDEX,
+ TEXTURE_3D_INDEX,
+ TEXTURE_RECT_INDEX,
+ TEXTURE_2D_INDEX,
+ TEXTURE_1D_INDEX,
+ NUM_TEXTURE_TARGETS
+} gl_texture_index;
+
+
+/**
+ * Bit flags for each type of texture object
+ * Used for Texture.Unit[]._ReallyEnabled flags.
+ */
+/*@{*/
+#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX)
+#define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX)
+#define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX)
+#define TEXTURE_3D_BIT (1 << TEXTURE_3D_INDEX)
+#define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX)
+#define TEXTURE_2D_BIT (1 << TEXTURE_2D_INDEX)
+#define TEXTURE_1D_BIT (1 << TEXTURE_1D_INDEX)
+/*@}*/
+
+
+/**
+ * TexGenEnabled flags.
+ */
+/*@{*/
+#define S_BIT 1
+#define T_BIT 2
+#define R_BIT 4
+#define Q_BIT 8
+#define STR_BITS (S_BIT | T_BIT | R_BIT)
+/*@}*/
+
+
+/**
+ * Bit flag versions of the corresponding GL_ constants.
+ */
+/*@{*/
+#define TEXGEN_SPHERE_MAP 0x1
+#define TEXGEN_OBJ_LINEAR 0x2
+#define TEXGEN_EYE_LINEAR 0x4
+#define TEXGEN_REFLECTION_MAP_NV 0x8
+#define TEXGEN_NORMAL_MAP_NV 0x10
+
+#define TEXGEN_NEED_NORMALS (TEXGEN_SPHERE_MAP | \
+ TEXGEN_REFLECTION_MAP_NV | \
+ TEXGEN_NORMAL_MAP_NV)
+#define TEXGEN_NEED_EYE_COORD (TEXGEN_SPHERE_MAP | \
+ TEXGEN_REFLECTION_MAP_NV | \
+ TEXGEN_NORMAL_MAP_NV | \
+ TEXGEN_EYE_LINEAR)
+/*@}*/
+
+
+
+/** Tex-gen enabled for texture unit? */
+#define ENABLE_TEXGEN(unit) (1 << (unit))
+
+/** Non-identity texture matrix for texture unit? */
+#define ENABLE_TEXMAT(unit) (1 << (unit))
+
+
+/**
+ * Texel fetch function prototype. We use texel fetch functions to
+ * extract RGBA, color indexes and depth components out of 1D, 2D and 3D
+ * texture images. These functions help to isolate us from the gritty
+ * details of all the various texture image encodings.
+ *
+ * \param texImage texture image.
+ * \param col texel column.
+ * \param row texel row.
+ * \param img texel image level/layer.
+ * \param texelOut output texel (up to 4 GLchans)
+ */
+typedef void (*FetchTexelFuncC)( const struct gl_texture_image *texImage,
+ GLint col, GLint row, GLint img,
+ GLchan *texelOut );
+
+/**
+ * As above, but returns floats.
+ * Used for depth component images and for upcoming signed/float
+ * texture images.
+ */
+typedef void (*FetchTexelFuncF)( const struct gl_texture_image *texImage,
+ GLint col, GLint row, GLint img,
+ GLfloat *texelOut );
+
+
+typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage,
+ GLint col, GLint row, GLint img,
+ const void *texel);
+
+
+/**
+ * Texture image state. Describes the dimensions of a texture image,
+ * the texel format and pointers to Texel Fetch functions.
+ */
+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.
+ */
+ GLuint TexFormat; /**< The actual format: MESA_FORMAT_x */
+
+ GLuint Border; /**< 0 or 1 */
+ GLuint Width; /**< = 2^WidthLog2 + 2*Border */
+ GLuint Height; /**< = 2^HeightLog2 + 2*Border */
+ GLuint Depth; /**< = 2^DepthLog2 + 2*Border */
+ GLuint Width2; /**< = Width - 2*Border */
+ GLuint Height2; /**< = Height - 2*Border */
+ GLuint Depth2; /**< = Depth - 2*Border */
+ GLuint WidthLog2; /**< = log2(Width2) */
+ GLuint HeightLog2; /**< = log2(Height2) */
+ GLuint DepthLog2; /**< = log2(Depth2) */
+ GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */
+ GLfloat WidthScale; /**< used for mipmap LOD computation */
+ GLfloat HeightScale; /**< used for mipmap LOD computation */
+ GLfloat DepthScale; /**< used for mipmap LOD computation */
+ GLboolean IsClientData; /**< Data owned by client? */
+ GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */
+
+ struct gl_texture_object *TexObject; /**< Pointer back to parent object */
+
+ FetchTexelFuncC FetchTexelc; /**< GLchan texel fetch function pointer */
+ FetchTexelFuncF FetchTexelf; /**< Float texel fetch function pointer */
+
+ GLuint RowStride; /**< Padded width in units of texels */
+ GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to
+ each 2D slice in 'Data', in texels */
+ GLvoid *Data; /**< Image data, accessed via FetchTexel() */
+
+ /**
+ * \name For device driver:
+ */
+ /*@{*/
+ void *DriverData; /**< Arbitrary device driver data */
+ /*@}*/
+};
+
+
+/**
+ * Indexes for cube map faces.
+ */
+typedef enum
+{
+ FACE_POS_X = 0,
+ FACE_NEG_X = 1,
+ FACE_POS_Y = 2,
+ FACE_NEG_Y = 3,
+ FACE_POS_Z = 4,
+ FACE_NEG_Z = 5,
+ MAX_FACES = 6
+} gl_face_index;
+
+
+/**
+ * Texture object state. Contains the array of mipmap images, border color,
+ * wrap modes, filter modes, shadow/texcompare state, and the per-texture
+ * color palette.
+ */
+struct gl_texture_object
+{
+ _glthread_Mutex Mutex; /**< for thread safety */
+ GLint RefCount; /**< reference count */
+ GLuint Name; /**< the user-visible texture object ID */
+ GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
+ GLfloat Priority; /**< in [0,1] */
+ union {
+ GLfloat f[4];
+ GLuint ui[4];
+ GLint i[4];
+ } BorderColor; /**< Interpreted according to texture format */
+ GLenum WrapS; /**< S-axis texture image wrap mode */
+ GLenum WrapT; /**< T-axis texture image wrap mode */
+ GLenum WrapR; /**< R-axis texture image wrap mode */
+ GLenum MinFilter; /**< minification filter */
+ GLenum MagFilter; /**< magnification filter */
+ GLfloat MinLod; /**< min lambda, OpenGL 1.2 */
+ GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */
+ GLfloat LodBias; /**< OpenGL 1.4 */
+ GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */
+ GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
+ GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
+ GLenum CompareMode; /**< GL_ARB_shadow */
+ GLenum CompareFunc; /**< GL_ARB_shadow */
+ GLfloat CompareFailValue; /**< GL_ARB_shadow_ambient */
+ GLenum DepthMode; /**< GL_ARB_depth_texture */
+ GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
+ GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */
+ GLint CropRect[4]; /**< GL_OES_draw_texture */
+ GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */
+ GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */
+ GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
+ GLboolean _Complete; /**< Is texture object complete? */
+ GLboolean _RenderToTexture; /**< Any rendering to this texture? */
+ GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
+ GLenum sRGBDecode; /**< GL_DECODE_EXT or GL_SKIP_DECODE_EXT */
+
+ /** Actual texture images, indexed by [cube face] and [mipmap level] */
+ struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
+
+ /** 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
+ * to instead use this struct as a base class for your own texture object
+ * class. Driver->NewTextureObject() can be used to implement the
+ * allocation.
+ */
+ void *DriverData; /**< Arbitrary device driver data */
+};
+
+
+/** Up to four combiner sources are possible with GL_NV_texture_env_combine4 */
+#define MAX_COMBINER_TERMS 4
+
+
+/**
+ * Texture combine environment state.
+ */
+struct gl_tex_env_combine_state
+{
+ GLenum ModeRGB; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
+ GLenum ModeA; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
+ /** Source terms: GL_PRIMARY_COLOR, GL_TEXTURE, etc */
+ GLenum SourceRGB[MAX_COMBINER_TERMS];
+ GLenum SourceA[MAX_COMBINER_TERMS];
+ /** Source operands: GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, etc */
+ GLenum OperandRGB[MAX_COMBINER_TERMS];
+ GLenum OperandA[MAX_COMBINER_TERMS];
+ GLuint ScaleShiftRGB; /**< 0, 1 or 2 */
+ GLuint ScaleShiftA; /**< 0, 1 or 2 */
+ GLuint _NumArgsRGB; /**< Number of inputs used for the RGB combiner */
+ GLuint _NumArgsA; /**< Number of inputs used for the A combiner */
+};
+
+
+/**
+ * Texture coord generation state.
+ */
+struct gl_texgen
+{
+ GLenum Mode; /**< GL_EYE_LINEAR, GL_SPHERE_MAP, etc */
+ GLbitfield _ModeBit; /**< TEXGEN_x bit corresponding to Mode */
+ GLfloat ObjectPlane[4];
+ GLfloat EyePlane[4];
+};
+
+
+/**
+ * Texture unit state. Contains enable flags, texture environment/function/
+ * combiners, texgen state, pointers to current texture objects and
+ * post-filter color tables.
+ */
+struct gl_texture_unit
+{
+ GLbitfield Enabled; /**< bitmask of TEXTURE_*_BIT flags */
+ GLbitfield _ReallyEnabled; /**< 0 or exactly one of TEXTURE_*_BIT flags */
+
+ GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */
+ GLfloat EnvColor[4];
+
+ struct gl_texgen GenS;
+ struct gl_texgen GenT;
+ struct gl_texgen GenR;
+ struct gl_texgen GenQ;
+ GLbitfield TexGenEnabled; /**< Bitwise-OR of [STRQ]_BIT values */
+ GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */
+
+ GLfloat LodBias; /**< for biasing mipmap levels */
+ GLenum BumpTarget;
+ GLfloat RotMatrix[4]; /* 2x2 matrix */
+
+ /**
+ * \name GL_EXT_texture_env_combine
+ */
+ struct gl_tex_env_combine_state Combine;
+
+ /**
+ * Derived state based on \c EnvMode and the \c BaseFormat of the
+ * currently enabled texture.
+ */
+ struct gl_tex_env_combine_state _EnvMode;
+
+ /**
+ * Currently enabled combiner state. This will point to either
+ * \c Combine or \c _EnvMode.
+ */
+ struct gl_tex_env_combine_state *_CurrentCombine;
+
+ /** Current texture object pointers */
+ struct gl_texture_object *CurrentTex[NUM_TEXTURE_TARGETS];
+
+ /** Points to highest priority, complete and enabled texture object */
+ struct gl_texture_object *_Current;
+
+ /** GL_SGI_texture_color_table */
+ /*@{*/
+ struct gl_color_table ColorTable;
+ struct gl_color_table ProxyColorTable;
+ GLboolean ColorTableEnabled;
+ /*@}*/
+};
+
+
+/**
+ * Texture attribute group (GL_TEXTURE_BIT).
+ */
+struct gl_texture_attrib
+{
+ GLuint CurrentUnit; /**< GL_ACTIVE_TEXTURE */
+ struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+
+ struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS];
+
+ /** 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;
+
+ /** Texture coord units/sets used for fragment texturing */
+ GLbitfield _EnabledCoordUnits;
+
+ /** Texture coord units that have texgen enabled */
+ GLbitfield _TexGenEnabled;
+
+ /** Texture coord units that have non-identity matrices */
+ GLbitfield _TexMatEnabled;
+
+ /** Bitwise-OR of all Texture.Unit[i]._GenFlags */
+ GLbitfield _GenFlags;
+};
+
+
+/**
+ * Transformation attribute group (GL_TRANSFORM_BIT).
+ */
+struct gl_transform_attrib
+{
+ GLenum MatrixMode; /**< Matrix mode */
+ GLfloat EyeUserPlane[MAX_CLIP_PLANES][4]; /**< User clip planes */
+ GLfloat _ClipUserPlane[MAX_CLIP_PLANES][4]; /**< derived */
+ GLbitfield ClipPlanesEnabled; /**< on/off bitmask */
+ GLboolean Normalize; /**< Normalize all normals? */
+ GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */
+ GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */
+ GLboolean DepthClamp; /**< GL_ARB_depth_clamp */
+
+ GLfloat CullEyePos[4];
+ GLfloat CullObjPos[4];
+};
+
+
+/**
+ * Viewport attribute group (GL_VIEWPORT_BIT).
+ */
+struct gl_viewport_attrib
+{
+ GLint X, Y; /**< position */
+ GLsizei Width, Height; /**< size */
+ GLfloat Near, Far; /**< Depth buffer range */
+ GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */
+};
+
+
+/**
+ * GL_ARB_vertex/pixel_buffer_object buffer object
+ */
+struct gl_buffer_object
+{
+ _glthread_Mutex Mutex;
+ GLint RefCount;
+ GLuint Name;
+ GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */
+ GLsizeiptrARB Size; /**< Size of buffer storage in bytes */
+ GLubyte *Data; /**< Location of storage either in RAM or VRAM. */
+ /** Fields describing a mapped buffer */
+ /*@{*/
+ GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */
+ GLvoid *Pointer; /**< User-space address of mapping */
+ GLintptr Offset; /**< Mapped offset */
+ GLsizeiptr Length; /**< Mapped length */
+ /*@}*/
+ GLboolean Written; /**< Ever written to? (for debugging) */
+ GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
+};
+
+
+/**
+ * Client pixel packing/unpacking attributes
+ */
+struct gl_pixelstore_attrib
+{
+ GLint Alignment;
+ GLint RowLength;
+ GLint SkipPixels;
+ GLint SkipRows;
+ GLint ImageHeight;
+ GLint SkipImages;
+ GLboolean SwapBytes;
+ GLboolean LsbFirst;
+ GLboolean ClientStorage; /**< GL_APPLE_client_storage */
+ GLboolean Invert; /**< GL_MESA_pack_invert */
+ struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */
+};
+
+
+/**
+ * Client vertex array attributes
+ */
+struct gl_client_array
+{
+ GLint Size; /**< components per element (1,2,3,4) */
+ GLenum Type; /**< datatype: GL_FLOAT, GL_INT, etc */
+ GLenum Format; /**< default: GL_RGBA, but may be GL_BGRA */
+ GLsizei Stride; /**< user-specified stride */
+ GLsizei StrideB; /**< actual stride in bytes */
+ const GLubyte *Ptr; /**< Points to array data */
+ GLboolean Enabled; /**< Enabled flag is a boolean */
+ GLboolean Normalized; /**< GL_ARB_vertex_program */
+ GLboolean Integer; /**< Integer-valued? */
+ GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */
+ GLuint _ElementSize; /**< size of each element in bytes */
+
+ struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */
+ GLuint _MaxElement; /**< max element index into array buffer + 1 */
+};
+
+
+/**
+ * Collection of vertex arrays. Defined by the GL_APPLE_vertex_array_object
+ * extension, but a nice encapsulation in any case.
+ */
+struct gl_array_object
+{
+ /** Name of the array object as received from glGenVertexArrayAPPLE. */
+ GLuint Name;
+
+ GLint RefCount;
+ _glthread_Mutex Mutex;
+ GLboolean VBOonly; /**< require all arrays to live in VBOs? */
+
+ /** Conventional vertex arrays */
+ /*@{*/
+ struct gl_client_array Vertex;
+ struct gl_client_array Weight;
+ struct gl_client_array Normal;
+ struct gl_client_array Color;
+ struct gl_client_array SecondaryColor;
+ struct gl_client_array FogCoord;
+ struct gl_client_array Index;
+ struct gl_client_array EdgeFlag;
+ struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS];
+ struct gl_client_array PointSize;
+ /*@}*/
+
+ /**
+ * Generic arrays for vertex programs/shaders.
+ * For NV vertex programs, these attributes alias and take priority
+ * over the conventional attribs above. For ARB vertex programs and
+ * GLSL vertex shaders, these attributes are separate.
+ */
+ struct gl_client_array VertexAttrib[MAX_VERTEX_GENERIC_ATTRIBS];
+
+ /** Mask of _NEW_ARRAY_* values indicating which arrays are enabled */
+ GLbitfield _Enabled;
+
+ /**
+ * Min of all enabled arrays' _MaxElement. When arrays reside inside VBOs
+ * we can determine the max legal (in bounds) glDrawElements array index.
+ */
+ GLuint _MaxElement;
+};
+
+
+/**
+ * Vertex array state
+ */
+struct gl_array_attrib
+{
+ /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */
+ struct gl_array_object *ArrayObj;
+
+ /** The default vertex array object */
+ struct gl_array_object *DefaultArrayObj;
+
+ /** Array objects (GL_ARB/APPLE_vertex_array_object) */
+ struct _mesa_HashTable *Objects;
+
+ GLint ActiveTexture; /**< Client Active Texture */
+ GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */
+ GLuint LockCount; /**< GL_EXT_compiled_vertex_array */
+
+ /** GL 3.1 (slightly different from GL_NV_primitive_restart) */
+ GLboolean PrimitiveRestart;
+ GLuint RestartIndex;
+
+ GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */
+
+ /* GL_ARB_vertex_buffer_object */
+ struct gl_buffer_object *ArrayBufferObj;
+ struct gl_buffer_object *ElementArrayBufferObj;
+};
+
+
+/**
+ * Feedback buffer state
+ */
+struct gl_feedback
+{
+ GLenum Type;
+ GLbitfield _Mask; /**< FB_* bits */
+ GLfloat *Buffer;
+ GLuint BufferSize;
+ GLuint Count;
+};
+
+
+/**
+ * Selection buffer state
+ */
+struct gl_selection
+{
+ GLuint *Buffer; /**< selection buffer */
+ GLuint BufferSize; /**< size of the selection buffer */
+ GLuint BufferCount; /**< number of values in the selection buffer */
+ GLuint Hits; /**< number of records in the selection buffer */
+ GLuint NameStackDepth; /**< name stack depth */
+ GLuint NameStack[MAX_NAME_STACK_DEPTH]; /**< name stack */
+ GLboolean HitFlag; /**< hit flag */
+ GLfloat HitMinZ; /**< minimum hit depth */
+ GLfloat HitMaxZ; /**< maximum hit depth */
+};
+
+
+/**
+ * 1-D Evaluator control points
+ */
+struct gl_1d_map
+{
+ GLuint Order; /**< Number of control points */
+ GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */
+ GLfloat *Points; /**< Points to contiguous control points */
+};
+
+
+/**
+ * 2-D Evaluator control points
+ */
+struct gl_2d_map
+{
+ GLuint Uorder; /**< Number of control points in U dimension */
+ GLuint Vorder; /**< Number of control points in V dimension */
+ GLfloat u1, u2, du;
+ GLfloat v1, v2, dv;
+ GLfloat *Points; /**< Points to contiguous control points */
+};
+
+
+/**
+ * All evaluator control point state
+ */
+struct gl_evaluators
+{
+ /**
+ * \name 1-D maps
+ */
+ /*@{*/
+ struct gl_1d_map Map1Vertex3;
+ struct gl_1d_map Map1Vertex4;
+ struct gl_1d_map Map1Index;
+ struct gl_1d_map Map1Color4;
+ struct gl_1d_map Map1Normal;
+ struct gl_1d_map Map1Texture1;
+ struct gl_1d_map Map1Texture2;
+ struct gl_1d_map Map1Texture3;
+ struct gl_1d_map Map1Texture4;
+ struct gl_1d_map Map1Attrib[16]; /**< GL_NV_vertex_program */
+ /*@}*/
+
+ /**
+ * \name 2-D maps
+ */
+ /*@{*/
+ struct gl_2d_map Map2Vertex3;
+ struct gl_2d_map Map2Vertex4;
+ struct gl_2d_map Map2Index;
+ struct gl_2d_map Map2Color4;
+ struct gl_2d_map Map2Normal;
+ struct gl_2d_map Map2Texture1;
+ struct gl_2d_map Map2Texture2;
+ struct gl_2d_map Map2Texture3;
+ struct gl_2d_map Map2Texture4;
+ struct gl_2d_map Map2Attrib[16]; /**< GL_NV_vertex_program */
+ /*@}*/
+};
+
+
+/**
+ * Names of the various vertex/fragment program register files, etc.
+ *
+ * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
+ * All values should fit in a 4-bit field.
+ *
+ * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM,
+ * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to
+ * be "uniform" variables since they can only be set outside glBegin/End.
+ * They're also all stored in the same Parameters array.
+ */
+typedef enum
+{
+ PROGRAM_TEMPORARY, /**< machine->Temporary[] */
+ PROGRAM_INPUT, /**< machine->Inputs[] */
+ PROGRAM_OUTPUT, /**< machine->Outputs[] */
+ PROGRAM_VARYING, /**< machine->Inputs[]/Outputs[] */
+ PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */
+ PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */
+ PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */
+ PROGRAM_NAMED_PARAM, /**< gl_program->Parameters[] */
+ PROGRAM_CONSTANT, /**< gl_program->Parameters[] */
+ PROGRAM_UNIFORM, /**< gl_program->Parameters[] */
+ PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */
+ PROGRAM_ADDRESS, /**< machine->AddressReg */
+ PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */
+ PROGRAM_SYSTEM_VALUE,/**< InstanceId, PrimitiveID, etc. */
+ PROGRAM_UNDEFINED, /**< Invalid/TBD value */
+ PROGRAM_FILE_MAX
+} gl_register_file;
+
+
+/**
+ * If the register file is PROGRAM_SYSTEM_VALUE, the register index will be
+ * one of these values.
+ */
+typedef enum
+{
+ SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */
+ SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */
+ SYSTEM_VALUE_MAX /**< Number of values */
+} gl_system_value;
+
+
+/** Vertex and fragment instructions */
+struct prog_instruction;
+struct gl_program_parameter_list;
+struct gl_uniform_list;
+
+
+/**
+ * Base class for any kind of program object
+ */
+struct gl_program
+{
+ GLuint Id;
+ GLubyte *String; /**< Null-terminated program text */
+ GLint RefCount;
+ GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */
+ GLenum Format; /**< String encoding format */
+ GLboolean Resident;
+
+ struct prog_instruction *Instructions;
+
+ GLbitfield InputsRead; /**< Bitmask of which input regs are read */
+ GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
+ GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
+ GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */
+ GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */
+ GLbitfield TexturesUsed[MAX_TEXTURE_UNITS]; /**< TEXTURE_x_BIT bitmask */
+ GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */
+ GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
+
+
+ /** Named parameters, constants, etc. from program text */
+ struct gl_program_parameter_list *Parameters;
+ /** Numbered local parameters */
+ GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
+
+ /** Vertex/fragment shader varying vars */
+ struct gl_program_parameter_list *Varying;
+ /** Vertex program user-defined attributes */
+ struct gl_program_parameter_list *Attributes;
+
+ /** Map from sampler unit to texture unit (set by glUniform1i()) */
+ GLubyte SamplerUnits[MAX_SAMPLERS];
+ /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
+ gl_texture_index SamplerTargets[MAX_SAMPLERS];
+
+ /** Bitmask of which register files are read/written with indirect
+ * addressing. Mask of (1 << PROGRAM_x) bits.
+ */
+ GLbitfield IndirectRegisterFiles;
+
+ /** Logical counts */
+ /*@{*/
+ GLuint NumInstructions;
+ GLuint NumTemporaries;
+ GLuint NumParameters;
+ GLuint NumAttributes;
+ GLuint NumAddressRegs;
+ GLuint NumAluInstructions;
+ GLuint NumTexInstructions;
+ GLuint NumTexIndirections;
+ /*@}*/
+ /** Native, actual h/w counts */
+ /*@{*/
+ GLuint NumNativeInstructions;
+ GLuint NumNativeTemporaries;
+ GLuint NumNativeParameters;
+ GLuint NumNativeAttributes;
+ GLuint NumNativeAddressRegs;
+ GLuint NumNativeAluInstructions;
+ GLuint NumNativeTexInstructions;
+ GLuint NumNativeTexIndirections;
+ /*@}*/
+};
+
+
+/** Vertex program object */
+struct gl_vertex_program
+{
+ struct gl_program Base; /**< base class */
+ GLboolean IsNVProgram; /**< is this a GL_NV_vertex_program program? */
+ GLboolean IsPositionInvariant;
+};
+
+
+/** Geometry program object */
+struct gl_geometry_program
+{
+ struct gl_program Base; /**< base class */
+
+ GLint VerticesOut;
+ GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
+ GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
+ GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
+};
+
+
+/** Fragment program object */
+struct gl_fragment_program
+{
+ struct gl_program Base; /**< base class */
+ GLenum FogOption;
+ GLboolean UsesKill; /**< shader uses KIL instruction */
+ GLboolean OriginUpperLeft;
+ GLboolean PixelCenterInteger;
+};
+
+
+/**
+ * State common to vertex and fragment programs.
+ */
+struct gl_program_state
+{
+ GLint ErrorPos; /* GL_PROGRAM_ERROR_POSITION_ARB/NV */
+ const char *ErrorString; /* GL_PROGRAM_ERROR_STRING_ARB/NV */
+};
+
+
+/**
+ * Context state for vertex programs.
+ */
+struct gl_vertex_program_state
+{
+ GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */
+ GLboolean _Enabled; /**< Enabled and _valid_ user program? */
+ GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */
+ GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */
+ struct gl_vertex_program *Current; /**< User-bound vertex program */
+
+ /** Currently enabled and valid vertex program (including internal
+ * programs, user-defined vertex programs and GLSL vertex shaders).
+ * This is the program we must use when rendering.
+ */
+ struct gl_vertex_program *_Current;
+
+ GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
+
+ /* For GL_NV_vertex_program only: */
+ GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4];
+ GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4];
+
+ /** Should fixed-function T&L be implemented with a vertex prog? */
+ GLboolean _MaintainTnlProgram;
+
+ /** Program to emulate fixed-function T&L (see above) */
+ struct gl_vertex_program *_TnlProgram;
+
+ /** Cache of fixed-function programs */
+ struct gl_program_cache *Cache;
+
+ GLboolean _Overriden;
+};
+
+
+/**
+ * Context state for geometry programs.
+ */
+struct gl_geometry_program_state
+{
+ GLboolean Enabled; /**< GL_ARB_GEOMETRY_SHADER4 */
+ GLboolean _Enabled; /**< Enabled and valid program? */
+ struct gl_geometry_program *Current; /**< user-bound geometry program */
+
+ /** Currently enabled and valid program (including internal programs
+ * and compiled shader programs).
+ */
+ struct gl_geometry_program *_Current;
+
+ GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
+
+ /** Cache of fixed-function programs */
+ struct gl_program_cache *Cache;
+};
+
+/**
+ * Context state for fragment programs.
+ */
+struct gl_fragment_program_state
+{
+ GLboolean Enabled; /**< User-set fragment program enable flag */
+ GLboolean _Enabled; /**< Enabled and _valid_ user program? */
+ struct gl_fragment_program *Current; /**< User-bound fragment program */
+
+ /** Currently enabled and valid fragment program (including internal
+ * programs, user-defined fragment programs and GLSL fragment shaders).
+ * This is the program we must use when rendering.
+ */
+ struct gl_fragment_program *_Current;
+
+ GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
+
+ /** Should fixed-function texturing be implemented with a fragment prog? */
+ GLboolean _MaintainTexEnvProgram;
+
+ /** Program to emulate fixed-function texture env/combine (see above) */
+ struct gl_fragment_program *_TexEnvProgram;
+
+ /** Cache of fixed-function programs */
+ struct gl_program_cache *Cache;
+};
+
+
+/**
+ * ATI_fragment_shader runtime state
+ */
+#define ATI_FS_INPUT_PRIMARY 0
+#define ATI_FS_INPUT_SECONDARY 1
+
+struct atifs_instruction;
+struct atifs_setupinst;
+
+/**
+ * ATI fragment shader
+ */
+struct ati_fragment_shader
+{
+ GLuint Id;
+ GLint RefCount;
+ struct atifs_instruction *Instructions[2];
+ struct atifs_setupinst *SetupInst[2];
+ GLfloat Constants[8][4];
+ GLbitfield LocalConstDef; /**< Indicates which constants have been set */
+ GLubyte numArithInstr[2];
+ GLubyte regsAssigned[2];
+ GLubyte NumPasses; /**< 1 or 2 */
+ GLubyte cur_pass;
+ GLubyte last_optype;
+ GLboolean interpinp1;
+ GLboolean isValid;
+ GLuint swizzlerq;
+};
+
+/**
+ * Context state for GL_ATI_fragment_shader
+ */
+struct gl_ati_fragment_shader_state
+{
+ GLboolean Enabled;
+ GLboolean _Enabled; /**< enabled and valid shader? */
+ GLboolean Compiling;
+ GLfloat GlobalConstants[8][4];
+ struct ati_fragment_shader *Current;
+};
+
+
+/**
+ * Occlusion/timer query object.
+ */
+struct gl_query_object
+{
+ GLenum Target; /**< The query target, when active */
+ GLuint Id; /**< hash table ID/name */
+ GLuint64EXT Result; /**< the counter */
+ GLboolean Active; /**< inside Begin/EndQuery */
+ GLboolean Ready; /**< result is ready? */
+};
+
+
+/**
+ * Context state for query objects.
+ */
+struct gl_query_state
+{
+ struct _mesa_HashTable *QueryObjects;
+ struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */
+ struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */
+
+ /** GL_NV_conditional_render */
+ struct gl_query_object *CondRenderQuery;
+
+ /** GL_EXT_transform_feedback */
+ struct gl_query_object *PrimitivesGenerated;
+ struct gl_query_object *PrimitivesWritten;
+
+ /** GL_ARB_timer_query */
+ struct gl_query_object *TimeElapsed;
+
+ GLenum CondRenderMode;
+};
+
+
+/** Sync object state */
+struct gl_sync_object {
+ struct simple_node link;
+ GLenum Type; /**< GL_SYNC_FENCE */
+ GLuint Name; /**< Fence name */
+ GLint RefCount; /**< Reference count */
+ GLboolean DeletePending; /**< Object was deleted while there were still
+ * live references (e.g., sync not yet finished)
+ */
+ GLenum SyncCondition;
+ GLbitfield Flags; /**< Flags passed to glFenceSync */
+ GLuint StatusFlag:1; /**< Has the sync object been signaled? */
+};
+
+
+/** Set by #pragma directives */
+struct gl_sl_pragmas
+{
+ GLboolean IgnoreOptimize; /**< ignore #pragma optimize(on/off) ? */
+ GLboolean IgnoreDebug; /**< ignore #pragma debug(on/off) ? */
+ GLboolean Optimize; /**< defaults on */
+ GLboolean Debug; /**< defaults off */
+};
+
+
+/**
+ * A GLSL vertex or fragment shader object.
+ */
+struct gl_shader
+{
+ GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB (first field!) */
+ GLuint Name; /**< AKA the handle */
+ GLint RefCount; /**< Reference count */
+ GLboolean DeletePending;
+ GLboolean CompileStatus;
+ GLboolean Main; /**< shader defines main() */
+ GLboolean UnresolvedRefs;
+ const GLchar *Source; /**< Source code string */
+ GLuint SourceChecksum; /**< for debug/logging purposes */
+ struct gl_program *Program; /**< Post-compile assembly code */
+ GLchar *InfoLog;
+ struct gl_sl_pragmas Pragmas;
+
+ unsigned Version; /**< GLSL version used for linking */
+
+ struct exec_list *ir;
+ struct glsl_symbol_table *symbols;
+
+ /** Shaders containing built-in functions that are used for linking. */
+ struct gl_shader *builtins_to_link[16];
+ unsigned num_builtins_to_link;
+};
+
+
+/**
+ * A GLSL program object.
+ * Basically a linked collection of vertex and fragment shaders.
+ */
+struct gl_shader_program
+{
+ GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */
+ GLuint Name; /**< aka handle or ID */
+ GLint RefCount; /**< Reference count */
+ GLboolean DeletePending;
+
+ GLuint NumShaders; /**< number of attached shaders */
+ struct gl_shader **Shaders; /**< List of attached the shaders */
+
+ /** User-defined attribute bindings (glBindAttribLocation) */
+ struct gl_program_parameter_list *Attributes;
+
+ /** Transform feedback varyings */
+ struct {
+ GLenum BufferMode;
+ GLuint NumVarying;
+ GLchar **VaryingNames; /**< Array [NumVarying] of char * */
+ } TransformFeedback;
+
+ /** Geometry shader state - copied into gl_geometry_program at link time */
+ struct {
+ GLint VerticesOut;
+ GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
+ GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
+ GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
+ } Geom;
+
+ /* post-link info: */
+ struct gl_vertex_program *VertexProgram; /**< Linked vertex program */
+ struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
+ struct gl_geometry_program *GeometryProgram; /**< Linked geometry prog */
+ struct gl_uniform_list *Uniforms;
+ struct gl_program_parameter_list *Varying;
+ GLboolean LinkStatus; /**< GL_LINK_STATUS */
+ GLboolean Validated;
+ GLboolean _Used; /**< Ever used for drawing? */
+ GLchar *InfoLog;
+
+ unsigned Version; /**< GLSL version used for linking */
+
+ /**
+ * Per-stage shaders resulting from the first stage of linking.
+ *
+ * Set of linked shaders for this program. The array is accessed using the
+ * \c MESA_SHADER_* defines. Entries for non-existent stages will be
+ * \c NULL.
+ */
+ struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES];
+};
+
+
+#define GLSL_DUMP 0x1 /**< Dump shaders to stdout */
+#define GLSL_LOG 0x2 /**< Write shaders to files */
+#define GLSL_OPT 0x4 /**< Force optimizations (override pragmas) */
+#define GLSL_NO_OPT 0x8 /**< Force no optimizations (override pragmas) */
+#define GLSL_UNIFORMS 0x10 /**< Print glUniform calls */
+#define GLSL_NOP_VERT 0x20 /**< Force no-op vertex shaders */
+#define GLSL_NOP_FRAG 0x40 /**< Force no-op fragment shaders */
+#define GLSL_USE_PROG 0x80 /**< Log glUseProgram calls */
+
+
+/**
+ * Context state for GLSL vertex/fragment shaders.
+ */
+struct gl_shader_state
+{
+ /**
+ * Programs used for rendering
+ *
+ * There is a separate program set for each shader stage. If
+ * GL_EXT_separate_shader_objects is not supported, each of these must point
+ * to \c NULL or to the same program.
+ */
+ struct gl_shader_program *CurrentVertexProgram;
+ struct gl_shader_program *CurrentGeometryProgram;
+ struct gl_shader_program *CurrentFragmentProgram;
+
+ /**
+ * Program used by glUniform calls.
+ *
+ * Explicitly set by \c glUseProgram and \c glActiveProgramEXT.
+ */
+ struct gl_shader_program *ActiveProgram;
+
+ void *MemPool;
+
+ GLbitfield Flags; /**< Mask of GLSL_x flags */
+};
+
+/**
+ * Compiler options for a single GLSL shaders type
+ */
+struct gl_shader_compiler_options
+{
+ /** Driver-selectable options: */
+ GLboolean EmitCondCodes; /**< Use condition codes? */
+ GLboolean EmitNVTempInitialization; /**< 0-fill NV temp registers */
+ /**
+ * Attempts to flatten all ir_if (OPCODE_IF) for GPUs that can't
+ * support control flow.
+ */
+ GLboolean EmitNoIfs;
+ GLboolean EmitNoLoops;
+ GLboolean EmitNoFunctions;
+ GLboolean EmitNoCont; /**< Emit CONT opcode? */
+ GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */
+ GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */
+ GLboolean EmitNoPow; /**< Emit POW opcodes? */
+
+ /**
+ * \name Forms of indirect addressing the driver cannot do.
+ */
+ /*@{*/
+ GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */
+ GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */
+ GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */
+ GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */
+ /*@}*/
+
+ GLuint MaxUnrollIterations;
+
+ struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */
+};
+
+/**
+ * Transform feedback object state
+ */
+struct gl_transform_feedback_object
+{
+ GLuint Name; /**< AKA the object ID */
+ GLint RefCount;
+ GLboolean Active; /**< Is transform feedback enabled? */
+ GLboolean Paused; /**< Is transform feedback paused? */
+
+ /** The feedback buffers */
+ GLuint BufferNames[MAX_FEEDBACK_ATTRIBS];
+ struct gl_buffer_object *Buffers[MAX_FEEDBACK_ATTRIBS];
+
+ /** Start of feedback data in dest buffer */
+ GLintptr Offset[MAX_FEEDBACK_ATTRIBS];
+ /** Max data to put into dest buffer (in bytes) */
+ GLsizeiptr Size[MAX_FEEDBACK_ATTRIBS];
+};
+
+
+/**
+ * Context state for transform feedback.
+ */
+struct gl_transform_feedback
+{
+ GLenum Mode; /**< GL_POINTS, GL_LINES or GL_TRIANGLES */
+
+ GLboolean RasterDiscard; /**< GL_RASTERIZER_DISCARD */
+
+ /** The general binding point (GL_TRANSFORM_FEEDBACK_BUFFER) */
+ struct gl_buffer_object *CurrentBuffer;
+
+ /** The table of all transform feedback objects */
+ struct _mesa_HashTable *Objects;
+
+ /** The current xform-fb object (GL_TRANSFORM_FEEDBACK_BINDING) */
+ struct gl_transform_feedback_object *CurrentObject;
+
+ /** The default xform-fb object (Name==0) */
+ struct gl_transform_feedback_object *DefaultObject;
+};
+
+
+
+/**
+ * State which can be shared by multiple contexts:
+ */
+struct gl_shared_state
+{
+ _glthread_Mutex Mutex; /**< for thread safety */
+ GLint RefCount; /**< Reference count */
+ struct _mesa_HashTable *DisplayList; /**< Display lists hash table */
+ struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */
+
+ /** Default texture objects (shared by all texture units) */
+ struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS];
+
+ /** Fallback texture used when a bound texture is incomplete */
+ struct gl_texture_object *FallbackTex;
+
+ /**
+ * \name Thread safety and statechange notification for texture
+ * objects.
+ *
+ * \todo Improve the granularity of locking.
+ */
+ /*@{*/
+ _glthread_Mutex TexMutex; /**< texobj thread safety */
+ GLuint TextureStateStamp; /**< state notification for shared tex */
+ /*@}*/
+
+ /** Default buffer object for vertex arrays that aren't in VBOs */
+ struct gl_buffer_object *NullBufferObj;
+
+ /**
+ * \name Vertex/geometry/fragment programs
+ */
+ /*@{*/
+ struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
+ struct gl_vertex_program *DefaultVertexProgram;
+ struct gl_fragment_program *DefaultFragmentProgram;
+ struct gl_geometry_program *DefaultGeometryProgram;
+ /*@}*/
+
+ /* GL_ATI_fragment_shader */
+ struct _mesa_HashTable *ATIShaders;
+ struct ati_fragment_shader *DefaultFragmentShader;
+
+ struct _mesa_HashTable *BufferObjects;
+
+ /** Table of both gl_shader and gl_shader_program objects */
+ struct _mesa_HashTable *ShaderObjects;
+
+ /* GL_EXT_framebuffer_object */
+ struct _mesa_HashTable *RenderBuffers;
+ struct _mesa_HashTable *FrameBuffers;
+
+ /* GL_ARB_sync */
+ struct simple_node SyncObjects;
+
+ void *DriverData; /**< Device driver shared state */
+};
+
+
+
+
+/**
+ * A renderbuffer stores colors or depth values or stencil values.
+ * A framebuffer object will have a collection of these.
+ * Data are read/written to the buffer with a handful of Get/Put functions.
+ *
+ * Instances of this object are allocated with the Driver's NewRenderbuffer
+ * hook. Drivers will likely wrap this class inside a driver-specific
+ * class to simulate inheritance.
+ */
+struct gl_renderbuffer
+{
+#define RB_MAGIC 0xaabbccdd
+ int Magic; /** XXX TEMPORARY DEBUG INFO */
+ _glthread_Mutex Mutex; /**< for thread safety */
+ GLuint ClassID; /**< Useful for drivers */
+ GLuint Name;
+ GLint RefCount;
+ GLuint Width, Height;
+ GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
+
+ GLenum InternalFormat; /**< The user-specified format */
+ GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or
+ GL_STENCIL_INDEX. */
+ GLuint Format; /**< The actual format: MESA_FORMAT_x */
+
+ GLubyte NumSamples;
+
+ GLenum DataType; /**< Type of values passed to the Get/Put functions */
+ GLvoid *Data; /**< This may not be used by some kinds of RBs */
+
+ /* Used to wrap one renderbuffer around another: */
+ struct gl_renderbuffer *Wrapped;
+
+ /* Delete this renderbuffer */
+ void (*Delete)(struct gl_renderbuffer *rb);
+
+ /* Allocate new storage for this renderbuffer */
+ GLboolean (*AllocStorage)(struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat,
+ GLuint width, GLuint height);
+
+ /* Lock/Unlock are called before/after calling the Get/Put functions.
+ * Not sure this is the right place for these yet.
+ void (*Lock)(struct gl_context *ctx, struct gl_renderbuffer *rb);
+ void (*Unlock)(struct gl_context *ctx, struct gl_renderbuffer *rb);
+ */
+
+ /* Return a pointer to the element/pixel at (x,y).
+ * Should return NULL if the buffer memory can't be directly addressed.
+ */
+ void *(*GetPointer)(struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLint x, GLint y);
+
+ /* Get/Read a row of values.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*GetRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values);
+
+ /* Get/Read values at arbitrary locations.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*GetValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values);
+
+ /* Put/Write a row of values.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask);
+
+ /* Put/Write a row of RGB values. This is a special-case routine that's
+ * only used for RGBA renderbuffers when the source data is GL_RGB. That's
+ * a common case for glDrawPixels and some triangle routines.
+ * The values will be of format GL_RGB and type DataType.
+ */
+ void (*PutRowRGB)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask);
+
+
+ /* Put/Write a row of identical values.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutMonoRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask);
+
+ /* Put/Write values at arbitrary locations.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *values,
+ const GLubyte *mask);
+ /* Put/Write identical values at arbitrary locations.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutMonoValues)(struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask);
+};
+
+
+/**
+ * A renderbuffer attachment points to either a texture object (and specifies
+ * a mipmap level, cube face or 3D texture slice) or points to a renderbuffer.
+ */
+struct gl_renderbuffer_attachment
+{
+ GLenum Type; /**< \c GL_NONE or \c GL_TEXTURE or \c GL_RENDERBUFFER_EXT */
+ GLboolean Complete;
+
+ /**
+ * If \c Type is \c GL_RENDERBUFFER_EXT, this stores a pointer to the
+ * application supplied renderbuffer object.
+ */
+ struct gl_renderbuffer *Renderbuffer;
+
+ /**
+ * If \c Type is \c GL_TEXTURE, this stores a pointer to the application
+ * supplied texture object.
+ */
+ struct gl_texture_object *Texture;
+ GLuint TextureLevel; /**< Attached mipmap level. */
+ GLuint CubeMapFace; /**< 0 .. 5, for cube map textures. */
+ GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D
+ * and 2D array textures */
+};
+
+
+/**
+ * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc).
+ * In C++ terms, think of this as a base class from which device drivers
+ * will make derived classes.
+ */
+struct gl_framebuffer
+{
+ _glthread_Mutex Mutex; /**< for thread safety */
+ /**
+ * If zero, this is a window system framebuffer. If non-zero, this
+ * is a FBO framebuffer; note that for some devices (i.e. those with
+ * a natural pixel coordinate system for FBOs that differs from the
+ * OpenGL/Mesa coordinate system), this means that the viewport,
+ * polygon face orientation, and polygon stipple will have to be inverted.
+ */
+ GLuint Name;
+
+ GLint RefCount;
+ GLboolean DeletePending;
+
+ /**
+ * The framebuffer's visual. Immutable if this is a window system buffer.
+ * Computed from attachments if user-made FBO.
+ */
+ struct gl_config Visual;
+
+ GLboolean Initialized;
+
+ GLuint Width, Height; /**< size of frame buffer in pixels */
+
+ /** \name Drawing bounds (Intersection of buffer size and scissor box) */
+ /*@{*/
+ GLint _Xmin, _Xmax; /**< inclusive */
+ GLint _Ymin, _Ymax; /**< exclusive */
+ /*@}*/
+
+ /** \name Derived Z buffer stuff */
+ /*@{*/
+ GLuint _DepthMax; /**< Max depth buffer value */
+ GLfloat _DepthMaxF; /**< Float max depth buffer value */
+ GLfloat _MRD; /**< minimum resolvable difference in Z values */
+ /*@}*/
+
+ /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
+ GLenum _Status;
+
+ /** Integer color values */
+ GLboolean _IntegerColor;
+
+ /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */
+ struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT];
+
+ /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER
+ * attribute group and GL_PIXEL attribute group, respectively.
+ */
+ GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS];
+ GLenum ColorReadBuffer;
+
+ /** Computed from ColorDraw/ReadBuffer above */
+ GLuint _NumColorDrawBuffers;
+ GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */
+ GLint _ColorReadBufferIndex; /* -1 = None */
+ struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
+ struct gl_renderbuffer *_ColorReadBuffer;
+
+ /** The Actual depth/stencil buffers to use. May be wrappers around the
+ * depth/stencil buffers attached above. */
+ struct gl_renderbuffer *_DepthBuffer;
+ struct gl_renderbuffer *_StencilBuffer;
+
+ /** Delete this framebuffer */
+ void (*Delete)(struct gl_framebuffer *fb);
+};
+
+
+/**
+ * Precision info for shader datatypes. See glGetShaderPrecisionFormat().
+ */
+struct gl_precision
+{
+ GLushort RangeMin; /**< min value exponent */
+ GLushort RangeMax; /**< max value exponent */
+ GLushort Precision; /**< number of mantissa bits */
+};
+
+
+/**
+ * Limits for vertex and fragment programs/shaders.
+ */
+struct gl_program_constants
+{
+ /* logical limits */
+ GLuint MaxInstructions;
+ GLuint MaxAluInstructions;
+ GLuint MaxTexInstructions;
+ GLuint MaxTexIndirections;
+ GLuint MaxAttribs;
+ GLuint MaxTemps;
+ GLuint MaxAddressRegs;
+ GLuint MaxParameters;
+ GLuint MaxLocalParams;
+ GLuint MaxEnvParams;
+ /* native/hardware limits */
+ GLuint MaxNativeInstructions;
+ GLuint MaxNativeAluInstructions;
+ GLuint MaxNativeTexInstructions;
+ GLuint MaxNativeTexIndirections;
+ GLuint MaxNativeAttribs;
+ GLuint MaxNativeTemps;
+ GLuint MaxNativeAddressRegs;
+ GLuint MaxNativeParameters;
+ /* For shaders */
+ GLuint MaxUniformComponents;
+ /* GL_ARB_geometry_shader4 */
+ GLuint MaxGeometryTextureImageUnits;
+ GLuint MaxGeometryVaryingComponents;
+ GLuint MaxVertexVaryingComponents;
+ GLuint MaxGeometryUniformComponents;
+ GLuint MaxGeometryOutputVertices;
+ GLuint MaxGeometryTotalOutputComponents;
+ /* ES 2.0 and GL_ARB_ES2_compatibility */
+ struct gl_precision LowFloat, MediumFloat, HighFloat;
+ struct gl_precision LowInt, MediumInt, HighInt;
+};
+
+
+/**
+ * Constants which may be overridden by device driver during context creation
+ * but are never changed after that.
+ */
+struct gl_constants
+{
+ GLint MaxTextureMbytes; /**< Max memory per image, in MB */
+ GLint MaxTextureLevels; /**< Max mipmap levels. */
+ GLint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */
+ GLint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */
+ GLint MaxArrayTextureLayers; /**< Max layers in array textures */
+ GLint MaxTextureRectSize; /**< Max rectangle texture size, in pixes */
+ GLuint MaxTextureCoordUnits;
+ GLuint MaxTextureImageUnits;
+ GLuint MaxVertexTextureImageUnits;
+ GLuint MaxCombinedTextureImageUnits;
+ GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */
+ GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
+ GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */
+
+ GLuint MaxArrayLockSize;
+
+ GLint SubPixelBits;
+
+ GLfloat MinPointSize, MaxPointSize; /**< aliased */
+ GLfloat MinPointSizeAA, MaxPointSizeAA; /**< antialiased */
+ GLfloat PointSizeGranularity;
+ GLfloat MinLineWidth, MaxLineWidth; /**< aliased */
+ GLfloat MinLineWidthAA, MaxLineWidthAA; /**< antialiased */
+ GLfloat LineWidthGranularity;
+
+ GLuint MaxColorTableSize;
+
+ GLuint MaxClipPlanes;
+ GLuint MaxLights;
+ GLfloat MaxShininess; /**< GL_NV_light_max_exponent */
+ GLfloat MaxSpotExponent; /**< GL_NV_light_max_exponent */
+
+ GLuint MaxViewportWidth, MaxViewportHeight;
+
+ struct gl_program_constants VertexProgram; /**< GL_ARB_vertex_program */
+ struct gl_program_constants FragmentProgram; /**< GL_ARB_fragment_program */
+ struct gl_program_constants GeometryProgram; /**< GL_ARB_geometry_shader4 */
+ GLuint MaxProgramMatrices;
+ GLuint MaxProgramMatrixStackDepth;
+
+ /** vertex array / buffer object bounds checking */
+ GLboolean CheckArrayBounds;
+
+ GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */
+
+ GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */
+ GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */
+ GLuint MaxSamples; /**< GL_ARB_framebuffer_object */
+
+ GLuint MaxVarying; /**< Number of float[4] varying parameters */
+
+ GLuint GLSLVersion; /**< GLSL version supported (ex: 120 = 1.20) */
+
+ /** Which texture units support GL_ATI_envmap_bumpmap as targets */
+ GLbitfield SupportedBumpUnits;
+
+ /**
+ * Maximum amount of time, measured in nanseconds, that the server can wait.
+ */
+ GLuint64 MaxServerWaitTimeout;
+
+ /** GL_EXT_provoking_vertex */
+ GLboolean QuadsFollowProvokingVertexConvention;
+
+ /** OpenGL version 3.0 */
+ GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */
+
+ /** OpenGL version 3.2 */
+ GLbitfield ProfileMask; /**< Mask of CONTEXT_x_PROFILE_BIT */
+
+ /** GL_EXT_transform_feedback */
+ GLuint MaxTransformFeedbackSeparateAttribs;
+ GLuint MaxTransformFeedbackSeparateComponents;
+ GLuint MaxTransformFeedbackInterleavedComponents;
+
+ /** GL_EXT_gpu_shader4 */
+ GLint MinProgramTexelOffset, MaxProgramTexelOffset;
+};
+
+
+/**
+ * Enable flag for each OpenGL extension. Different device drivers will
+ * enable different extensions at runtime.
+ */
+struct gl_extensions
+{
+ GLboolean dummy; /* don't remove this! */
+ GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */
+ GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
+ GLboolean ARB_ES2_compatibility;
+ GLboolean ARB_blend_func_extended;
+ GLboolean ARB_copy_buffer;
+ GLboolean ARB_depth_buffer_float;
+ GLboolean ARB_depth_clamp;
+ GLboolean ARB_depth_texture;
+ GLboolean ARB_draw_buffers;
+ GLboolean ARB_draw_buffers_blend;
+ GLboolean ARB_draw_elements_base_vertex;
+ GLboolean ARB_draw_instanced;
+ GLboolean ARB_fragment_coord_conventions;
+ GLboolean ARB_fragment_program;
+ GLboolean ARB_fragment_program_shadow;
+ GLboolean ARB_fragment_shader;
+ GLboolean ARB_framebuffer_object;
+ GLboolean ARB_explicit_attrib_location;
+ GLboolean ARB_geometry_shader4;
+ GLboolean ARB_half_float_pixel;
+ GLboolean ARB_half_float_vertex;
+ GLboolean ARB_instanced_arrays;
+ GLboolean ARB_map_buffer_range;
+ GLboolean ARB_multisample;
+ GLboolean ARB_multitexture;
+ GLboolean ARB_occlusion_query;
+ GLboolean ARB_occlusion_query2;
+ GLboolean ARB_point_sprite;
+ GLboolean ARB_sampler_objects;
+ GLboolean ARB_seamless_cube_map;
+ GLboolean ARB_shader_objects;
+ GLboolean ARB_shader_stencil_export;
+ GLboolean ARB_shading_language_100;
+ GLboolean ARB_shadow;
+ GLboolean ARB_shadow_ambient;
+ GLboolean ARB_sync;
+ GLboolean ARB_texture_border_clamp;
+ GLboolean ARB_texture_buffer_object;
+ GLboolean ARB_texture_compression;
+ GLboolean ARB_texture_compression_rgtc;
+ GLboolean ARB_texture_cube_map;
+ GLboolean ARB_texture_env_combine;
+ GLboolean ARB_texture_env_crossbar;
+ GLboolean ARB_texture_env_dot3;
+ GLboolean ARB_texture_float;
+ GLboolean ARB_texture_mirrored_repeat;
+ GLboolean ARB_texture_multisample;
+ GLboolean ARB_texture_non_power_of_two;
+ GLboolean ARB_texture_rg;
+ GLboolean ARB_texture_rgb10_a2ui;
+ GLboolean ARB_timer_query;
+ GLboolean ARB_transform_feedback2;
+ GLboolean ARB_transpose_matrix;
+ GLboolean ARB_uniform_buffer_object;
+ GLboolean ARB_vertex_array_object;
+ GLboolean ARB_vertex_buffer_object;
+ GLboolean ARB_vertex_program;
+ GLboolean ARB_vertex_shader;
+ GLboolean ARB_vertex_type_2_10_10_10_rev;
+ GLboolean ARB_window_pos;
+ GLboolean EXT_abgr;
+ GLboolean EXT_bgra;
+ GLboolean EXT_blend_color;
+ GLboolean EXT_blend_equation_separate;
+ GLboolean EXT_blend_func_separate;
+ GLboolean EXT_blend_logic_op;
+ GLboolean EXT_blend_minmax;
+ GLboolean EXT_blend_subtract;
+ GLboolean EXT_clip_volume_hint;
+ GLboolean EXT_compiled_vertex_array;
+ GLboolean EXT_copy_texture;
+ GLboolean EXT_depth_bounds_test;
+ GLboolean EXT_draw_buffers2;
+ GLboolean EXT_draw_range_elements;
+ GLboolean EXT_fog_coord;
+ GLboolean EXT_framebuffer_blit;
+ GLboolean EXT_framebuffer_multisample;
+ GLboolean EXT_framebuffer_object;
+ GLboolean EXT_framebuffer_sRGB;
+ 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;
+ GLboolean EXT_pixel_buffer_object;
+ GLboolean EXT_point_parameters;
+ GLboolean EXT_polygon_offset;
+ GLboolean EXT_provoking_vertex;
+ GLboolean EXT_rescale_normal;
+ GLboolean EXT_shadow_funcs;
+ 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;
+ GLboolean EXT_texture;
+ GLboolean EXT_texture_object;
+ GLboolean EXT_texture3D;
+ GLboolean EXT_texture_array;
+ GLboolean EXT_texture_compression_s3tc;
+ GLboolean EXT_texture_env_add;
+ GLboolean EXT_texture_env_combine;
+ GLboolean EXT_texture_env_dot3;
+ GLboolean EXT_texture_filter_anisotropic;
+ GLboolean EXT_texture_integer;
+ GLboolean EXT_texture_lod_bias;
+ GLboolean EXT_texture_mirror_clamp;
+ GLboolean EXT_texture_shared_exponent;
+ GLboolean EXT_texture_sRGB;
+ GLboolean EXT_texture_sRGB_decode;
+ GLboolean EXT_texture_swizzle;
+ GLboolean EXT_transform_feedback;
+ GLboolean EXT_timer_query;
+ GLboolean EXT_vertex_array;
+ GLboolean EXT_vertex_array_bgra;
+ GLboolean EXT_vertex_array_set;
+ GLboolean OES_standard_derivatives;
+ /* vendor extensions */
+ GLboolean APPLE_client_storage;
+ GLboolean APPLE_packed_pixels;
+ GLboolean APPLE_vertex_array_object;
+ GLboolean APPLE_object_purgeable;
+ GLboolean ATI_envmap_bumpmap;
+ GLboolean ATI_texture_mirror_once;
+ GLboolean ATI_texture_env_combine3;
+ GLboolean ATI_fragment_shader;
+ GLboolean ATI_separate_stencil;
+ GLboolean IBM_rasterpos_clip;
+ GLboolean IBM_multimode_draw_arrays;
+ GLboolean MESA_pack_invert;
+ GLboolean MESA_resize_buffers;
+ GLboolean MESA_ycbcr_texture;
+ GLboolean MESA_texture_array;
+ GLboolean MESA_texture_signed_rgba;
+ GLboolean NV_blend_square;
+ GLboolean NV_conditional_render;
+ GLboolean NV_fragment_program;
+ GLboolean NV_fragment_program_option;
+ GLboolean NV_light_max_exponent;
+ GLboolean NV_point_sprite;
+ GLboolean NV_primitive_restart;
+ GLboolean NV_texgen_reflection;
+ GLboolean NV_texture_env_combine4;
+ GLboolean NV_texture_rectangle;
+ GLboolean NV_vertex_program;
+ GLboolean NV_vertex_program1_1;
+ GLboolean OES_read_format;
+ GLboolean SGI_texture_color_table;
+ GLboolean SGIS_generate_mipmap;
+ GLboolean SGIS_texture_edge_clamp;
+ GLboolean SGIS_texture_lod;
+ GLboolean TDFX_texture_compression_FXT1;
+ GLboolean S3_s3tc;
+ GLboolean OES_EGL_image;
+ GLboolean OES_draw_texture;
+ GLboolean EXT_texture_format_BGRA8888;
+ GLboolean extension_sentinel;
+ /** The extension string */
+ const GLubyte *String;
+ /** Number of supported extensions */
+ GLuint Count;
+};
+
+
+/**
+ * A stack of matrices (projection, modelview, color, texture, etc).
+ */
+struct gl_matrix_stack
+{
+ GLmatrix *Top; /**< points into Stack */
+ GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */
+ GLuint Depth; /**< 0 <= Depth < MaxDepth */
+ GLuint MaxDepth; /**< size of Stack[] array */
+ GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */
+};
+
+
+/**
+ * \name Bits for image transfer operations
+ * \sa __struct gl_contextRec::ImageTransferState.
+ */
+/*@{*/
+#define IMAGE_SCALE_BIAS_BIT 0x1
+#define IMAGE_SHIFT_OFFSET_BIT 0x2
+#define IMAGE_MAP_COLOR_BIT 0x4
+#define IMAGE_CLAMP_BIT 0x800
+
+
+/** Pixel Transfer ops */
+#define IMAGE_BITS (IMAGE_SCALE_BIAS_BIT | \
+ IMAGE_SHIFT_OFFSET_BIT | \
+ IMAGE_MAP_COLOR_BIT)
+
+/**
+ * \name Bits to indicate what state has changed.
+ */
+/*@{*/
+#define _NEW_MODELVIEW (1 << 0) /**< gl_context::ModelView */
+#define _NEW_PROJECTION (1 << 1) /**< gl_context::Projection */
+#define _NEW_TEXTURE_MATRIX (1 << 2) /**< gl_context::TextureMatrix */
+#define _NEW_COLOR (1 << 3) /**< gl_context::Color */
+#define _NEW_DEPTH (1 << 4) /**< gl_context::Depth */
+#define _NEW_EVAL (1 << 5) /**< gl_context::Eval, EvalMap */
+#define _NEW_FOG (1 << 6) /**< gl_context::Fog */
+#define _NEW_HINT (1 << 7) /**< gl_context::Hint */
+#define _NEW_LIGHT (1 << 8) /**< gl_context::Light */
+#define _NEW_LINE (1 << 9) /**< gl_context::Line */
+#define _NEW_PIXEL (1 << 10) /**< gl_context::Pixel */
+#define _NEW_POINT (1 << 11) /**< gl_context::Point */
+#define _NEW_POLYGON (1 << 12) /**< gl_context::Polygon */
+#define _NEW_POLYGONSTIPPLE (1 << 13) /**< gl_context::PolygonStipple */
+#define _NEW_SCISSOR (1 << 14) /**< gl_context::Scissor */
+#define _NEW_STENCIL (1 << 15) /**< gl_context::Stencil */
+#define _NEW_TEXTURE (1 << 16) /**< gl_context::Texture */
+#define _NEW_TRANSFORM (1 << 17) /**< gl_context::Transform */
+#define _NEW_VIEWPORT (1 << 18) /**< gl_context::Viewport */
+#define _NEW_PACKUNPACK (1 << 19) /**< gl_context::Pack, Unpack */
+#define _NEW_ARRAY (1 << 20) /**< gl_context::Array */
+#define _NEW_RENDERMODE (1 << 21) /**< gl_context::RenderMode, etc */
+#define _NEW_BUFFERS (1 << 22) /**< gl_context::Visual, DrawBuffer, */
+#define _NEW_CURRENT_ATTRIB (1 << 23) /**< gl_context::Current */
+#define _NEW_MULTISAMPLE (1 << 24) /**< gl_context::Multisample */
+#define _NEW_TRACK_MATRIX (1 << 25) /**< gl_context::VertexProgram */
+#define _NEW_PROGRAM (1 << 26) /**< New program/shader state */
+#define _NEW_PROGRAM_CONSTANTS (1 << 27)
+#define _NEW_BUFFER_OBJECT (1 << 28)
+#define _NEW_ALL ~0
+/*@}*/
+
+
+/**
+ * \name Bits to track array state changes
+ *
+ * Also used to summarize array enabled.
+ */
+/*@{*/
+#define _NEW_ARRAY_VERTEX VERT_BIT_POS
+#define _NEW_ARRAY_WEIGHT VERT_BIT_WEIGHT
+#define _NEW_ARRAY_NORMAL VERT_BIT_NORMAL
+#define _NEW_ARRAY_COLOR0 VERT_BIT_COLOR0
+#define _NEW_ARRAY_COLOR1 VERT_BIT_COLOR1
+#define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG
+#define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX
+#define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG
+#define _NEW_ARRAY_POINT_SIZE VERT_BIT_COLOR_INDEX /* aliased */
+#define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0
+#define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1
+#define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2
+#define _NEW_ARRAY_TEXCOORD_3 VERT_BIT_TEX3
+#define _NEW_ARRAY_TEXCOORD_4 VERT_BIT_TEX4
+#define _NEW_ARRAY_TEXCOORD_5 VERT_BIT_TEX5
+#define _NEW_ARRAY_TEXCOORD_6 VERT_BIT_TEX6
+#define _NEW_ARRAY_TEXCOORD_7 VERT_BIT_TEX7
+#define _NEW_ARRAY_ATTRIB_0 VERT_BIT_GENERIC0 /* start at bit 16 */
+#define _NEW_ARRAY_ALL 0xffffffff
+
+
+#define _NEW_ARRAY_TEXCOORD(i) (_NEW_ARRAY_TEXCOORD_0 << (i))
+#define _NEW_ARRAY_ATTRIB(i) (_NEW_ARRAY_ATTRIB_0 << (i))
+/*@}*/
+
+
+
+/**
+ * \name A bunch of flags that we think might be useful to drivers.
+ *
+ * Set in the __struct gl_contextRec::_TriangleCaps bitfield.
+ */
+/*@{*/
+#define DD_FLATSHADE 0x1
+#define DD_SEPARATE_SPECULAR 0x2
+#define DD_TRI_CULL_FRONT_BACK 0x4 /* special case on some hw */
+#define DD_TRI_LIGHT_TWOSIDE 0x8
+#define DD_TRI_UNFILLED 0x10
+#define DD_TRI_SMOOTH 0x20
+#define DD_TRI_STIPPLE 0x40
+#define DD_TRI_OFFSET 0x80
+#define DD_LINE_SMOOTH 0x100
+#define DD_LINE_STIPPLE 0x200
+#define DD_POINT_SMOOTH 0x400
+#define DD_POINT_ATTEN 0x800
+#define DD_TRI_TWOSTENCIL 0x1000
+/*@}*/
+
+
+/**
+ * \name Define the state changes under which each of these bits might change
+ */
+/*@{*/
+#define _DD_NEW_FLATSHADE _NEW_LIGHT
+#define _DD_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | _NEW_FOG | _NEW_PROGRAM)
+#define _DD_NEW_TRI_CULL_FRONT_BACK _NEW_POLYGON
+#define _DD_NEW_TRI_LIGHT_TWOSIDE _NEW_LIGHT
+#define _DD_NEW_TRI_UNFILLED _NEW_POLYGON
+#define _DD_NEW_TRI_SMOOTH _NEW_POLYGON
+#define _DD_NEW_TRI_STIPPLE _NEW_POLYGON
+#define _DD_NEW_TRI_OFFSET _NEW_POLYGON
+#define _DD_NEW_LINE_SMOOTH _NEW_LINE
+#define _DD_NEW_LINE_STIPPLE _NEW_LINE
+#define _DD_NEW_LINE_WIDTH _NEW_LINE
+#define _DD_NEW_POINT_SMOOTH _NEW_POINT
+#define _DD_NEW_POINT_SIZE _NEW_POINT
+#define _DD_NEW_POINT_ATTEN _NEW_POINT
+/*@}*/
+
+
+/**
+ * Composite state flags
+ */
+/*@{*/
+#define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \
+ _NEW_TEXTURE | \
+ _NEW_POINT | \
+ _NEW_PROGRAM | \
+ _NEW_MODELVIEW)
+
+#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \
+ _NEW_TEXTURE)
+
+#define _MESA_NEW_TRANSFER_STATE (_NEW_PIXEL)
+/*@}*/
+
+
+
+
+/* This has to be included here. */
+#include "dd.h"
+
+
+/**
+ * Display list flags.
+ * Strictly this is a tnl-private concept, but it doesn't seem
+ * worthwhile adding a tnl private structure just to hold this one bit
+ * of information:
+ */
+#define DLIST_DANGLING_REFS 0x1
+
+
+/** Opaque declaration of display list payload data type */
+union gl_dlist_node;
+
+
+/**
+ * Provide a location where information about a display list can be
+ * collected. Could be extended with driverPrivate structures,
+ * etc. in the future.
+ */
+struct gl_display_list
+{
+ GLuint Name;
+ GLbitfield Flags; /**< DLIST_x flags */
+ /** The dlist commands are in a linked list of nodes */
+ union gl_dlist_node *Head;
+};
+
+
+/**
+ * State used during display list compilation and execution.
+ */
+struct gl_dlist_state
+{
+ GLuint CallDepth; /**< Current recursion calling depth */
+
+ struct gl_display_list *CurrentList; /**< List currently being compiled */
+ union gl_dlist_node *CurrentBlock; /**< Pointer to current block of nodes */
+ GLuint CurrentPos; /**< Index into current block of nodes */
+
+ GLvertexformat ListVtxfmt;
+
+ GLubyte ActiveAttribSize[VERT_ATTRIB_MAX];
+ GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4];
+
+ GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX];
+ GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4];
+
+ GLubyte ActiveIndex;
+ GLfloat CurrentIndex;
+
+ GLubyte ActiveEdgeFlag;
+ GLboolean CurrentEdgeFlag;
+
+ struct {
+ /* State known to have been set by the currently-compiling display
+ * list. Used to eliminate some redundant state changes.
+ */
+ GLenum ShadeModel;
+ } Current;
+};
+
+
+/**
+ * Enum for the OpenGL APIs we know about and may support.
+ */
+typedef enum
+{
+ API_OPENGL,
+ API_OPENGLES,
+ API_OPENGLES2
+} gl_api;
+
+
+/**
+ * Mesa rendering context.
+ *
+ * This is the central context data structure for Mesa. Almost all
+ * OpenGL state is contained in this structure.
+ * Think of this as a base class from which device drivers will derive
+ * sub classes.
+ *
+ * The struct gl_context typedef names this structure.
+ */
+struct gl_context
+{
+ /** State possibly shared with other contexts in the address space */
+ struct gl_shared_state *Shared;
+
+ /** \name API function pointer tables */
+ /*@{*/
+ gl_api API;
+ struct _glapi_table *Save; /**< Display list save functions */
+ struct _glapi_table *Exec; /**< Execute functions */
+ struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */
+ /*@}*/
+
+ struct gl_config Visual;
+ struct gl_framebuffer *DrawBuffer; /**< buffer for writing */
+ struct gl_framebuffer *ReadBuffer; /**< buffer for reading */
+ struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */
+ struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */
+
+ /**
+ * Device driver function pointer table
+ */
+ struct dd_function_table Driver;
+
+ void *DriverCtx; /**< Points to device driver context/state */
+
+ /** Core/Driver constants */
+ struct gl_constants Const;
+
+ /** \name The various 4x4 matrix stacks */
+ /*@{*/
+ struct gl_matrix_stack ModelviewMatrixStack;
+ struct gl_matrix_stack ProjectionMatrixStack;
+ struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS];
+ struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
+ struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */
+ /*@}*/
+
+ /** Combined modelview and projection matrix */
+ GLmatrix _ModelProjectMatrix;
+
+ /** \name Display lists */
+ struct gl_dlist_state ListState;
+
+ GLboolean ExecuteFlag; /**< Execute GL commands? */
+ GLboolean CompileFlag; /**< Compile GL commands into display list? */
+
+ /** Extension information */
+ struct gl_extensions Extensions;
+
+ /** Version info */
+ GLuint VersionMajor, VersionMinor;
+ char *VersionString;
+
+ /** \name State attribute stack (for glPush/PopAttrib) */
+ /*@{*/
+ GLuint AttribStackDepth;
+ struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH];
+ /*@}*/
+
+ /** \name Renderer attribute groups
+ *
+ * We define a struct for each attribute group to make pushing and popping
+ * attributes easy. Also it's a good organization.
+ */
+ /*@{*/
+ struct gl_accum_attrib Accum; /**< Accum buffer attributes */
+ struct gl_colorbuffer_attrib Color; /**< Color buffer attributes */
+ struct gl_current_attrib Current; /**< Current attributes */
+ struct gl_depthbuffer_attrib Depth; /**< Depth buffer attributes */
+ struct gl_eval_attrib Eval; /**< Eval attributes */
+ struct gl_fog_attrib Fog; /**< Fog attributes */
+ struct gl_hint_attrib Hint; /**< Hint attributes */
+ struct gl_light_attrib Light; /**< Light attributes */
+ struct gl_line_attrib Line; /**< Line attributes */
+ struct gl_list_attrib List; /**< List attributes */
+ struct gl_multisample_attrib Multisample;
+ struct gl_pixel_attrib Pixel; /**< Pixel attributes */
+ struct gl_point_attrib Point; /**< Point attributes */
+ struct gl_polygon_attrib Polygon; /**< Polygon attributes */
+ GLuint PolygonStipple[32]; /**< Polygon stipple */
+ struct gl_scissor_attrib Scissor; /**< Scissor attributes */
+ struct gl_stencil_attrib Stencil; /**< Stencil buffer attributes */
+ struct gl_texture_attrib Texture; /**< Texture attributes */
+ struct gl_transform_attrib Transform; /**< Transformation attributes */
+ struct gl_viewport_attrib Viewport; /**< Viewport attributes */
+ /*@}*/
+
+ /** \name Client attribute stack */
+ /*@{*/
+ GLuint ClientAttribStackDepth;
+ struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH];
+ /*@}*/
+
+ /** \name Client attribute groups */
+ /*@{*/
+ struct gl_array_attrib Array; /**< Vertex arrays */
+ struct gl_pixelstore_attrib Pack; /**< Pixel packing */
+ struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */
+ struct gl_pixelstore_attrib DefaultPacking; /**< Default params */
+ /*@}*/
+
+ /** \name Other assorted state (not pushed/popped on attribute stack) */
+ /*@{*/
+ struct gl_pixelmaps PixelMaps;
+
+ struct gl_evaluators EvalMap; /**< All evaluators */
+ struct gl_feedback Feedback; /**< Feedback */
+ struct gl_selection Select; /**< Selection */
+
+ struct gl_program_state Program; /**< general program state */
+ struct gl_vertex_program_state VertexProgram;
+ struct gl_fragment_program_state FragmentProgram;
+ struct gl_geometry_program_state GeometryProgram;
+ struct gl_ati_fragment_shader_state ATIFragmentShader;
+
+ struct gl_shader_state Shader; /**< GLSL shader object state */
+ struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES];
+
+ struct gl_query_state Query; /**< occlusion, timer queries */
+
+ struct gl_transform_feedback TransformFeedback;
+
+ struct gl_buffer_object *CopyReadBuffer; /**< GL_ARB_copy_buffer */
+ struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */
+ /*@}*/
+
+ struct gl_meta_state *Meta; /**< for "meta" operations */
+
+ /* GL_EXT_framebuffer_object */
+ struct gl_renderbuffer *CurrentRenderbuffer;
+
+ GLenum ErrorValue; /**< Last error code */
+
+ /**
+ * Recognize and silence repeated error debug messages in buggy apps.
+ */
+ const char *ErrorDebugFmtString;
+ GLuint ErrorDebugCount;
+
+ GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
+ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */
+
+ GLboolean ViewportInitialized; /**< has viewport size been initialized? */
+
+ GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */
+
+ /** \name Derived state */
+ /*@{*/
+ /** Bitwise-or of DD_* flags. Note that this bitfield may be used before
+ * state validation so they need to always be current.
+ */
+ GLbitfield _TriangleCaps;
+ GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */
+ GLfloat _EyeZDir[3];
+ GLfloat _ModelViewInvScale;
+ GLboolean _NeedEyeCoords;
+ GLboolean _ForceEyeCoords;
+
+ GLuint TextureStateTimestamp; /**< detect changes to shared state */
+
+ struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */
+ struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */
+ /**@}*/
+
+ struct gl_list_extensions *ListExt; /**< driver dlist extensions */
+
+ /** \name For debugging/development only */
+ /*@{*/
+ GLboolean FirstTimeCurrent;
+ /*@}*/
+
+ /** Dither disable via MESA_NO_DITHER env var */
+ GLboolean NoDither;
+
+ /** software compression/decompression supported or not */
+ GLboolean Mesa_DXTn;
+
+ GLboolean TextureFormatSupported[MESA_FORMAT_COUNT];
+
+ /**
+ * Use dp4 (rather than mul/mad) instructions for position
+ * transformation?
+ */
+ GLboolean mvp_with_dp4;
+
+ /**
+ * \name Hooks for module contexts.
+ *
+ * These will eventually live in the driver or elsewhere.
+ */
+ /*@{*/
+ void *swrast_context;
+ void *swsetup_context;
+ void *swtnl_context;
+ void *swtnl_im;
+ struct st_context *st;
+ void *aelt_context;
+ /*@}*/
+};
+
+
+#ifdef DEBUG
+extern int MESA_VERBOSE;
+extern int MESA_DEBUG_FLAGS;
+# define MESA_FUNCTION __FUNCTION__
+#else
+# define MESA_VERBOSE 0
+# define MESA_DEBUG_FLAGS 0
+# define MESA_FUNCTION "a function"
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+
+/** The MESA_VERBOSE var is a bitmask of these flags */
+enum _verbose
+{
+ VERBOSE_VARRAY = 0x0001,
+ VERBOSE_TEXTURE = 0x0002,
+ VERBOSE_MATERIAL = 0x0004,
+ VERBOSE_PIPELINE = 0x0008,
+ VERBOSE_DRIVER = 0x0010,
+ VERBOSE_STATE = 0x0020,
+ VERBOSE_API = 0x0040,
+ VERBOSE_DISPLAY_LIST = 0x0100,
+ VERBOSE_LIGHTING = 0x0200,
+ VERBOSE_PRIMS = 0x0400,
+ VERBOSE_VERTS = 0x0800,
+ VERBOSE_DISASSEM = 0x1000,
+ VERBOSE_DRAW = 0x2000,
+ VERBOSE_SWAPBUFFERS = 0x4000
+};
+
+
+/** The MESA_DEBUG_FLAGS var is a bitmask of these flags */
+enum _debug
+{
+ DEBUG_ALWAYS_FLUSH = 0x1
+};
+
+
+
+#endif /* MTYPES_H */
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index 66935af91..4909b76cb 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -1,1435 +1,1448 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.5
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 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
- * 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.
- */
-
-/**
- * \file texparam.c
- *
- * glTexParameter-related functions
- */
-
-
-#include "main/glheader.h"
-#include "main/colormac.h"
-#include "main/context.h"
-#include "main/formats.h"
-#include "main/macros.h"
-#include "main/mfeatures.h"
-#include "main/mtypes.h"
-#include "main/texcompress.h"
-#include "main/texparam.h"
-#include "main/teximage.h"
-#include "main/texstate.h"
-#include "main/texfetch.h"
-#include "program/prog_instruction.h"
-
-
-/**
- * Check if a coordinate wrap mode is supported for the texture target.
- * \return GL_TRUE if legal, GL_FALSE otherwise
- */
-static GLboolean
-validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
-{
- const struct gl_extensions * const e = & ctx->Extensions;
-
- if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
- (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
- /* any texture target */
- return GL_TRUE;
- }
- else if (target != GL_TEXTURE_RECTANGLE_NV &&
- (wrap == GL_REPEAT ||
- (wrap == GL_MIRRORED_REPEAT &&
- e->ARB_texture_mirrored_repeat) ||
- (wrap == GL_MIRROR_CLAMP_EXT &&
- (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
- (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
- (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
- (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
- (e->EXT_texture_mirror_clamp)))) {
- /* non-rectangle texture */
- return GL_TRUE;
- }
-
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
- return GL_FALSE;
-}
-
-
-/**
- * Get current texture object for given target.
- * Return NULL if any error (and record the error).
- * Note that this is different from _mesa_select_tex_object() in that proxy
- * targets are not accepted.
- * Only the glGetTexLevelParameter() functions accept proxy targets.
- */
-static struct gl_texture_object *
-get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
-{
- struct gl_texture_unit *texUnit;
-
- if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "gl%sTexParameter(current unit)", get ? "Get" : "");
- return NULL;
- }
-
- texUnit = _mesa_get_current_tex_unit(ctx);
-
- switch (target) {
- case GL_TEXTURE_1D:
- return texUnit->CurrentTex[TEXTURE_1D_INDEX];
- case GL_TEXTURE_2D:
- return texUnit->CurrentTex[TEXTURE_2D_INDEX];
- case GL_TEXTURE_3D:
- return texUnit->CurrentTex[TEXTURE_3D_INDEX];
- case GL_TEXTURE_CUBE_MAP:
- if (ctx->Extensions.ARB_texture_cube_map) {
- return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
- }
- break;
- case GL_TEXTURE_RECTANGLE_NV:
- if (ctx->Extensions.NV_texture_rectangle) {
- return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
- }
- break;
- case GL_TEXTURE_1D_ARRAY_EXT:
- if (ctx->Extensions.MESA_texture_array) {
- return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
- }
- break;
- case GL_TEXTURE_2D_ARRAY_EXT:
- if (ctx->Extensions.MESA_texture_array) {
- return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
- }
- break;
- default:
- ;
- }
-
- _mesa_error(ctx, GL_INVALID_ENUM,
- "gl%sTexParameter(target)", get ? "Get" : "");
- return NULL;
-}
-
-
-/**
- * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
- * \return -1 if error.
- */
-static GLint
-comp_to_swizzle(GLenum comp)
-{
- switch (comp) {
- case GL_RED:
- return SWIZZLE_X;
- case GL_GREEN:
- return SWIZZLE_Y;
- case GL_BLUE:
- return SWIZZLE_Z;
- case GL_ALPHA:
- return SWIZZLE_W;
- case GL_ZERO:
- return SWIZZLE_ZERO;
- case GL_ONE:
- return SWIZZLE_ONE;
- default:
- return -1;
- }
-}
-
-
-static void
-set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
-{
- ASSERT(comp < 4);
- ASSERT(swz <= SWIZZLE_NIL);
- {
- GLuint mask = 0x7 << (3 * comp);
- GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
- *swizzle = s;
- }
-}
-
-
-/**
- * This is called just prior to changing any texture object state.
- * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
- * state flag and then mark the texture object as 'incomplete' so that any
- * per-texture derived state gets recomputed.
- */
-static INLINE void
-flush(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- texObj->_Complete = GL_FALSE;
-}
-
-
-/**
- * Set an integer-valued texture parameter
- * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
- */
-static GLboolean
-set_tex_parameteri(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- GLenum pname, const GLint *params)
-{
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- if (texObj->MinFilter == params[0])
- return GL_FALSE;
- switch (params[0]) {
- case GL_NEAREST:
- case GL_LINEAR:
- flush(ctx, texObj);
- texObj->MinFilter = params[0];
- return GL_TRUE;
- case GL_NEAREST_MIPMAP_NEAREST:
- case GL_LINEAR_MIPMAP_NEAREST:
- case GL_NEAREST_MIPMAP_LINEAR:
- case GL_LINEAR_MIPMAP_LINEAR:
- if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
- flush(ctx, texObj);
- texObj->MinFilter = params[0];
- return GL_TRUE;
- }
- /* fall-through */
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
- params[0] );
- }
- return GL_FALSE;
-
- case GL_TEXTURE_MAG_FILTER:
- if (texObj->MagFilter == params[0])
- return GL_FALSE;
- switch (params[0]) {
- case GL_NEAREST:
- case GL_LINEAR:
- flush(ctx, texObj);
- texObj->MagFilter = params[0];
- return GL_TRUE;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
- params[0]);
- }
- return GL_FALSE;
-
- case GL_TEXTURE_WRAP_S:
- if (texObj->WrapS == params[0])
- return GL_FALSE;
- if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
- flush(ctx, texObj);
- texObj->WrapS = params[0];
- return GL_TRUE;
- }
- return GL_FALSE;
-
- case GL_TEXTURE_WRAP_T:
- if (texObj->WrapT == params[0])
- return GL_FALSE;
- if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
- flush(ctx, texObj);
- texObj->WrapT = params[0];
- return GL_TRUE;
- }
- return GL_FALSE;
-
- case GL_TEXTURE_WRAP_R:
- if (texObj->WrapR == params[0])
- return GL_FALSE;
- if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
- flush(ctx, texObj);
- texObj->WrapR = params[0];
- return GL_TRUE;
- }
- return GL_FALSE;
-
- case GL_TEXTURE_BASE_LEVEL:
- if (texObj->BaseLevel == params[0])
- return GL_FALSE;
- if (params[0] < 0 ||
- (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexParameter(param=%d)", params[0]);
- return GL_FALSE;
- }
- flush(ctx, texObj);
- texObj->BaseLevel = params[0];
- return GL_TRUE;
-
- case GL_TEXTURE_MAX_LEVEL:
- if (texObj->MaxLevel == params[0])
- return GL_FALSE;
- if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexParameter(param=%d)", params[0]);
- return GL_FALSE;
- }
- flush(ctx, texObj);
- texObj->MaxLevel = params[0];
- return GL_TRUE;
-
- case GL_GENERATE_MIPMAP_SGIS:
- if (texObj->GenerateMipmap != params[0]) {
- flush(ctx, texObj);
- texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
- return GL_TRUE;
- }
- return GL_FALSE;
-
- case GL_TEXTURE_COMPARE_MODE_ARB:
- if (ctx->Extensions.ARB_shadow &&
- (params[0] == GL_NONE ||
- params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) {
- if (texObj->CompareMode != params[0]) {
- flush(ctx, texObj);
- texObj->CompareMode = params[0];
- return GL_TRUE;
- }
- return GL_FALSE;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)");
- }
- return GL_FALSE;
-
- case GL_TEXTURE_COMPARE_FUNC_ARB:
- if (ctx->Extensions.ARB_shadow) {
- if (texObj->CompareFunc == params[0])
- return GL_FALSE;
- switch (params[0]) {
- case GL_LEQUAL:
- case GL_GEQUAL:
- flush(ctx, texObj);
- texObj->CompareFunc = params[0];
- return GL_TRUE;
- case GL_EQUAL:
- case GL_NOTEQUAL:
- case GL_LESS:
- case GL_GREATER:
- case GL_ALWAYS:
- case GL_NEVER:
- if (ctx->Extensions.EXT_shadow_funcs) {
- flush(ctx, texObj);
- texObj->CompareFunc = params[0];
- return GL_TRUE;
- }
- /* fall-through */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)");
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
- }
- return GL_FALSE;
-
- case GL_DEPTH_TEXTURE_MODE_ARB:
- if (ctx->Extensions.ARB_depth_texture &&
- (params[0] == GL_LUMINANCE ||
- params[0] == GL_INTENSITY ||
- params[0] == GL_ALPHA ||
- (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED))) {
- if (texObj->DepthMode != params[0]) {
- flush(ctx, texObj);
- texObj->DepthMode = params[0];
- return GL_TRUE;
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)");
- }
- return GL_FALSE;
-
-#if FEATURE_OES_draw_texture
- case GL_TEXTURE_CROP_RECT_OES:
- texObj->CropRect[0] = params[0];
- texObj->CropRect[1] = params[1];
- texObj->CropRect[2] = params[2];
- texObj->CropRect[3] = params[3];
- return GL_TRUE;
-#endif
-
- case GL_TEXTURE_SWIZZLE_R_EXT:
- case GL_TEXTURE_SWIZZLE_G_EXT:
- case GL_TEXTURE_SWIZZLE_B_EXT:
- case GL_TEXTURE_SWIZZLE_A_EXT:
- if (ctx->Extensions.EXT_texture_swizzle) {
- const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
- const GLint swz = comp_to_swizzle(params[0]);
- if (swz < 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexParameter(swizzle 0x%x)", params[0]);
- return GL_FALSE;
- }
- ASSERT(comp < 4);
- if (swz >= 0) {
- flush(ctx, texObj);
- texObj->Swizzle[comp] = params[0];
- set_swizzle_component(&texObj->_Swizzle, comp, swz);
- return GL_TRUE;
- }
- }
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
- return GL_FALSE;
-
- case GL_TEXTURE_SWIZZLE_RGBA_EXT:
- if (ctx->Extensions.EXT_texture_swizzle) {
- GLuint comp;
- flush(ctx, texObj);
- for (comp = 0; comp < 4; comp++) {
- const GLint swz = comp_to_swizzle(params[comp]);
- if (swz >= 0) {
- texObj->Swizzle[comp] = params[comp];
- set_swizzle_component(&texObj->_Swizzle, comp, swz);
- }
- else {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexParameter(swizzle 0x%x)", params[comp]);
- return GL_FALSE;
- }
- }
- return GL_TRUE;
- }
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
- return GL_FALSE;
- case GL_TEXTURE_SRGB_DECODE_EXT:
- if (ctx->Extensions.EXT_texture_sRGB_decode) {
- GLenum decode = params[0];
- if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
- if (texObj->sRGBDecode != decode) {
- flush(ctx, texObj);
- texObj->sRGBDecode = decode;
- _mesa_update_fetch_functions(texObj);
- }
- return GL_TRUE;
- }
- }
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
- return GL_FALSE;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
- }
- return GL_FALSE;
-}
-
-
-/**
- * Set a float-valued texture parameter
- * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
- */
-static GLboolean
-set_tex_parameterf(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- GLenum pname, const GLfloat *params)
-{
- switch (pname) {
- case GL_TEXTURE_MIN_LOD:
- if (texObj->MinLod == params[0])
- return GL_FALSE;
- flush(ctx, texObj);
- texObj->MinLod = params[0];
- return GL_TRUE;
-
- case GL_TEXTURE_MAX_LOD:
- if (texObj->MaxLod == params[0])
- return GL_FALSE;
- flush(ctx, texObj);
- texObj->MaxLod = params[0];
- return GL_TRUE;
-
- case GL_TEXTURE_PRIORITY:
- flush(ctx, texObj);
- texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
- return GL_TRUE;
-
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- if (ctx->Extensions.EXT_texture_filter_anisotropic) {
- if (texObj->MaxAnisotropy == params[0])
- return GL_FALSE;
- if (params[0] < 1.0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
- return GL_FALSE;
- }
- flush(ctx, texObj);
- /* clamp to max, that's what NVIDIA does */
- texObj->MaxAnisotropy = MIN2(params[0],
- ctx->Const.MaxTextureMaxAnisotropy);
- return GL_TRUE;
- }
- else {
- static GLuint count = 0;
- if (count++ < 10)
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
- }
- return GL_FALSE;
-
- case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
- if (ctx->Extensions.ARB_shadow_ambient) {
- if (texObj->CompareFailValue != params[0]) {
- flush(ctx, texObj);
- texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F);
- return GL_TRUE;
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)");
- }
- return GL_FALSE;
-
- case GL_TEXTURE_LOD_BIAS:
- /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
- if (ctx->Extensions.EXT_texture_lod_bias) {
- if (texObj->LodBias != params[0]) {
- flush(ctx, texObj);
- texObj->LodBias = params[0];
- return GL_TRUE;
- }
- return GL_FALSE;
- }
- break;
-
- case GL_TEXTURE_BORDER_COLOR:
- flush(ctx, texObj);
- texObj->BorderColor.f[RCOMP] = params[0];
- texObj->BorderColor.f[GCOMP] = params[1];
- texObj->BorderColor.f[BCOMP] = params[2];
- texObj->BorderColor.f[ACOMP] = params[3];
- return GL_TRUE;
-
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
- }
- return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
-{
- GLboolean need_update;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- texObj = get_texobj(ctx, target, GL_FALSE);
- if (!texObj)
- return;
-
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_MAG_FILTER:
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_BASE_LEVEL:
- case GL_TEXTURE_MAX_LEVEL:
- case GL_GENERATE_MIPMAP_SGIS:
- case GL_TEXTURE_COMPARE_MODE_ARB:
- case GL_TEXTURE_COMPARE_FUNC_ARB:
- case GL_DEPTH_TEXTURE_MODE_ARB:
- case GL_TEXTURE_SRGB_DECODE_EXT:
- {
- /* convert float param to int */
- GLint p[4];
- p[0] = (GLint) param;
- p[1] = p[2] = p[3] = 0;
- need_update = set_tex_parameteri(ctx, texObj, pname, p);
- }
- break;
- default:
- {
- /* this will generate an error if pname is illegal */
- GLfloat p[4];
- p[0] = param;
- p[1] = p[2] = p[3] = 0.0F;
- need_update = set_tex_parameterf(ctx, texObj, pname, p);
- }
- }
-
- if (ctx->Driver.TexParameter && need_update) {
- ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
- }
-}
-
-
-void GLAPIENTRY
-_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
-{
- GLboolean need_update;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- texObj = get_texobj(ctx, target, GL_FALSE);
- if (!texObj)
- return;
-
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_MAG_FILTER:
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_BASE_LEVEL:
- case GL_TEXTURE_MAX_LEVEL:
- case GL_GENERATE_MIPMAP_SGIS:
- case GL_TEXTURE_COMPARE_MODE_ARB:
- case GL_TEXTURE_COMPARE_FUNC_ARB:
- case GL_DEPTH_TEXTURE_MODE_ARB:
- case GL_TEXTURE_SRGB_DECODE_EXT:
- {
- /* convert float param to int */
- GLint p[4];
- p[0] = (GLint) params[0];
- p[1] = p[2] = p[3] = 0;
- need_update = set_tex_parameteri(ctx, texObj, pname, p);
- }
- break;
-
-#if FEATURE_OES_draw_texture
- case GL_TEXTURE_CROP_RECT_OES:
- {
- /* convert float params to int */
- GLint iparams[4];
- iparams[0] = (GLint) params[0];
- iparams[1] = (GLint) params[1];
- iparams[2] = (GLint) params[2];
- iparams[3] = (GLint) params[3];
- need_update = set_tex_parameteri(ctx, texObj, pname, iparams);
- }
- break;
-#endif
-
- default:
- /* this will generate an error if pname is illegal */
- need_update = set_tex_parameterf(ctx, texObj, pname, params);
- }
-
- if (ctx->Driver.TexParameter && need_update) {
- ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
- }
-}
-
-
-void GLAPIENTRY
-_mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
-{
- GLboolean need_update;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- texObj = get_texobj(ctx, target, GL_FALSE);
- if (!texObj)
- return;
-
- switch (pname) {
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- case GL_TEXTURE_PRIORITY:
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- case GL_TEXTURE_LOD_BIAS:
- case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
- {
- GLfloat fparam[4];
- fparam[0] = (GLfloat) param;
- fparam[1] = fparam[2] = fparam[3] = 0.0F;
- /* convert int param to float */
- need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
- }
- break;
- default:
- /* this will generate an error if pname is illegal */
- {
- GLint iparam[4];
- iparam[0] = param;
- iparam[1] = iparam[2] = iparam[3] = 0;
- need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
- }
- }
-
- if (ctx->Driver.TexParameter && need_update) {
- GLfloat fparam = (GLfloat) param;
- ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
- }
-}
-
-
-void GLAPIENTRY
-_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
-{
- GLboolean need_update;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- texObj = get_texobj(ctx, target, GL_FALSE);
- if (!texObj)
- return;
-
- switch (pname) {
- case GL_TEXTURE_BORDER_COLOR:
- {
- /* convert int params to float */
- GLfloat fparams[4];
- fparams[0] = INT_TO_FLOAT(params[0]);
- fparams[1] = INT_TO_FLOAT(params[1]);
- fparams[2] = INT_TO_FLOAT(params[2]);
- fparams[3] = INT_TO_FLOAT(params[3]);
- need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
- }
- break;
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- case GL_TEXTURE_PRIORITY:
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- case GL_TEXTURE_LOD_BIAS:
- case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
- {
- /* convert int param to float */
- GLfloat fparams[4];
- fparams[0] = (GLfloat) params[0];
- fparams[1] = fparams[2] = fparams[3] = 0.0F;
- need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
- }
- break;
- default:
- /* this will generate an error if pname is illegal */
- need_update = set_tex_parameteri(ctx, texObj, pname, params);
- }
-
- if (ctx->Driver.TexParameter && need_update) {
- GLfloat fparams[4];
- fparams[0] = INT_TO_FLOAT(params[0]);
- if (pname == GL_TEXTURE_BORDER_COLOR ||
- pname == GL_TEXTURE_CROP_RECT_OES) {
- fparams[1] = INT_TO_FLOAT(params[1]);
- fparams[2] = INT_TO_FLOAT(params[2]);
- fparams[3] = INT_TO_FLOAT(params[3]);
- }
- ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
- }
-}
-
-
-/**
- * Set tex parameter to integer value(s). Primarily intended to set
- * integer-valued texture border color (for integer-valued textures).
- * New in GL 3.0.
- */
-void GLAPIENTRY
-_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
-{
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- texObj = get_texobj(ctx, target, GL_FALSE);
- if (!texObj)
- return;
-
- switch (pname) {
- case GL_TEXTURE_BORDER_COLOR:
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- /* set the integer-valued border color */
- COPY_4V(texObj->BorderColor.i, params);
- break;
- default:
- _mesa_TexParameteriv(target, pname, params);
- break;
- }
- /* XXX no driver hook for TexParameterIiv() yet */
-}
-
-
-/**
- * Set tex parameter to unsigned integer value(s). Primarily intended to set
- * uint-valued texture border color (for integer-valued textures).
- * New in GL 3.0
- */
-void GLAPIENTRY
-_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
-{
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- texObj = get_texobj(ctx, target, GL_FALSE);
- if (!texObj)
- return;
-
- switch (pname) {
- case GL_TEXTURE_BORDER_COLOR:
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- /* set the unsigned integer-valued border color */
- COPY_4V(texObj->BorderColor.ui, params);
- break;
- default:
- _mesa_TexParameteriv(target, pname, (const GLint *) params);
- break;
- }
- /* XXX no driver hook for TexParameterIuiv() yet */
-}
-
-
-
-
-void GLAPIENTRY
-_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
- GLenum pname, GLfloat *params )
-{
- GLint iparam;
- _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
- *params = (GLfloat) iparam;
-}
-
-
-void GLAPIENTRY
-_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
- GLenum pname, GLint *params )
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- const struct gl_texture_image *img = NULL;
- GLboolean isProxy;
- GLint maxLevels;
- gl_format texFormat;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTexLevelParameteriv(current unit)");
- return;
- }
-
- texUnit = _mesa_get_current_tex_unit(ctx);
-
- /* this will catch bad target values */
- maxLevels = _mesa_max_texture_levels(ctx, target);
- if (maxLevels == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(target=0x%x)", target);
- return;
- }
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
- return;
- }
-
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- _mesa_lock_texture(ctx, texObj);
-
- img = _mesa_select_tex_image(ctx, texObj, target, level);
- if (!img || !img->TexFormat) {
- /* undefined texture image */
- if (pname == GL_TEXTURE_COMPONENTS)
- *params = 1;
- else
- *params = 0;
- goto out;
- }
-
- texFormat = img->TexFormat;
-
- isProxy = _mesa_is_proxy_texture(target);
-
- switch (pname) {
- case GL_TEXTURE_WIDTH:
- *params = img->Width;
- break;
- case GL_TEXTURE_HEIGHT:
- *params = img->Height;
- break;
- case GL_TEXTURE_DEPTH:
- *params = img->Depth;
- break;
- case GL_TEXTURE_INTERNAL_FORMAT:
- if (_mesa_is_format_compressed(img->TexFormat)) {
- /* need to return the actual compressed format */
- *params = _mesa_compressed_format_to_glenum(ctx, img->TexFormat);
- }
- else {
- /* return the user's requested internal format */
- *params = img->InternalFormat;
- }
- break;
- case GL_TEXTURE_BORDER:
- *params = img->Border;
- break;
- case GL_TEXTURE_RED_SIZE:
- if (img->_BaseFormat == GL_RED) {
- *params = _mesa_get_format_bits(texFormat, pname);
- break;
- }
- /* FALLTHROUGH */
- case GL_TEXTURE_GREEN_SIZE:
- if (img->_BaseFormat == GL_RG) {
- *params = _mesa_get_format_bits(texFormat, pname);
- break;
- }
- /* FALLTHROUGH */
- case GL_TEXTURE_BLUE_SIZE:
- if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
- *params = _mesa_get_format_bits(texFormat, pname);
- else
- *params = 0;
- break;
- case GL_TEXTURE_ALPHA_SIZE:
- if (img->_BaseFormat == GL_ALPHA ||
- img->_BaseFormat == GL_LUMINANCE_ALPHA ||
- img->_BaseFormat == GL_RGBA)
- *params = _mesa_get_format_bits(texFormat, pname);
- else
- *params = 0;
- break;
- case GL_TEXTURE_INTENSITY_SIZE:
- if (img->_BaseFormat != GL_INTENSITY)
- *params = 0;
- else {
- *params = _mesa_get_format_bits(texFormat, pname);
- if (*params == 0) {
- /* intensity probably stored as rgb texture */
- *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
- _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
- }
- }
- break;
- case GL_TEXTURE_LUMINANCE_SIZE:
- if (img->_BaseFormat != GL_LUMINANCE &&
- img->_BaseFormat != GL_LUMINANCE_ALPHA)
- *params = 0;
- else {
- *params = _mesa_get_format_bits(texFormat, pname);
- if (*params == 0) {
- /* luminance probably stored as rgb texture */
- *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
- _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
- }
- }
- 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)
- *params = _mesa_get_format_bits(texFormat, pname);
- else
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- break;
- case GL_TEXTURE_STENCIL_SIZE_EXT:
- if (ctx->Extensions.EXT_packed_depth_stencil ||
- ctx->Extensions.ARB_framebuffer_object) {
- *params = _mesa_get_format_bits(texFormat, pname);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
- case GL_TEXTURE_SHARED_SIZE:
- if (ctx->VersionMajor >= 3) {
- /* XXX return number of exponent bits for shared exponent texture
- * formats, like GL_RGB9_E5.
- */
- *params = 0;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
-
- /* GL_ARB_texture_compression */
- case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
- if (_mesa_is_format_compressed(img->TexFormat) && !isProxy) {
- *params = _mesa_format_image_size(texFormat, img->Width,
- img->Height, img->Depth);
- }
- else {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
- case GL_TEXTURE_COMPRESSED:
- *params = (GLint) _mesa_is_format_compressed(img->TexFormat);
- break;
-
- /* GL_ARB_texture_float */
- case GL_TEXTURE_RED_TYPE_ARB:
- if (ctx->Extensions.ARB_texture_float) {
- *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE) ?
- _mesa_get_format_datatype(texFormat) : GL_NONE;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
- case GL_TEXTURE_GREEN_TYPE_ARB:
- if (ctx->Extensions.ARB_texture_float) {
- *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE) ?
- _mesa_get_format_datatype(texFormat) : GL_NONE;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
- case GL_TEXTURE_BLUE_TYPE_ARB:
- if (ctx->Extensions.ARB_texture_float) {
- *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_BLUE_SIZE) ?
- _mesa_get_format_datatype(texFormat) : GL_NONE;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
- case GL_TEXTURE_ALPHA_TYPE_ARB:
- if (ctx->Extensions.ARB_texture_float) {
- *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_ALPHA_SIZE) ?
- _mesa_get_format_datatype(texFormat) : GL_NONE;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
- case GL_TEXTURE_LUMINANCE_TYPE_ARB:
- if (ctx->Extensions.ARB_texture_float) {
- *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_LUMINANCE_SIZE) ?
- _mesa_get_format_datatype(texFormat) : GL_NONE;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
- case GL_TEXTURE_INTENSITY_TYPE_ARB:
- if (ctx->Extensions.ARB_texture_float) {
- *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_INTENSITY_SIZE) ?
- _mesa_get_format_datatype(texFormat) : GL_NONE;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
- case GL_TEXTURE_DEPTH_TYPE_ARB:
- if (ctx->Extensions.ARB_texture_float) {
- *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_DEPTH_SIZE) ?
- _mesa_get_format_datatype(texFormat) : GL_NONE;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
- break;
-
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTexLevelParameter[if]v(pname)");
- }
-
- out:
- _mesa_unlock_texture(ctx, texObj);
-}
-
-
-
-void GLAPIENTRY
-_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
-{
- struct gl_texture_object *obj;
- GLboolean error = GL_FALSE;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- obj = get_texobj(ctx, target, GL_TRUE);
- if (!obj)
- return;
-
- _mesa_lock_texture(ctx, obj);
- switch (pname) {
- case GL_TEXTURE_MAG_FILTER:
- *params = ENUM_TO_FLOAT(obj->MagFilter);
- break;
- case GL_TEXTURE_MIN_FILTER:
- *params = ENUM_TO_FLOAT(obj->MinFilter);
- break;
- case GL_TEXTURE_WRAP_S:
- *params = ENUM_TO_FLOAT(obj->WrapS);
- break;
- case GL_TEXTURE_WRAP_T:
- *params = ENUM_TO_FLOAT(obj->WrapT);
- break;
- case GL_TEXTURE_WRAP_R:
- *params = ENUM_TO_FLOAT(obj->WrapR);
- break;
- case GL_TEXTURE_BORDER_COLOR:
- params[0] = CLAMP(obj->BorderColor.f[0], 0.0F, 1.0F);
- params[1] = CLAMP(obj->BorderColor.f[1], 0.0F, 1.0F);
- params[2] = CLAMP(obj->BorderColor.f[2], 0.0F, 1.0F);
- params[3] = CLAMP(obj->BorderColor.f[3], 0.0F, 1.0F);
- break;
- case GL_TEXTURE_RESIDENT:
- {
- GLboolean resident;
- if (ctx->Driver.IsTextureResident)
- resident = ctx->Driver.IsTextureResident(ctx, obj);
- else
- resident = GL_TRUE;
- *params = ENUM_TO_FLOAT(resident);
- }
- break;
- case GL_TEXTURE_PRIORITY:
- *params = obj->Priority;
- break;
- case GL_TEXTURE_MIN_LOD:
- *params = obj->MinLod;
- break;
- case GL_TEXTURE_MAX_LOD:
- *params = obj->MaxLod;
- break;
- case GL_TEXTURE_BASE_LEVEL:
- *params = (GLfloat) obj->BaseLevel;
- break;
- case GL_TEXTURE_MAX_LEVEL:
- *params = (GLfloat) obj->MaxLevel;
- break;
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- if (ctx->Extensions.EXT_texture_filter_anisotropic) {
- *params = obj->MaxAnisotropy;
- }
- else
- error = GL_TRUE;
- break;
- case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
- if (ctx->Extensions.ARB_shadow_ambient) {
- *params = obj->CompareFailValue;
- }
- else
- error = GL_TRUE;
- break;
- case GL_GENERATE_MIPMAP_SGIS:
- *params = (GLfloat) obj->GenerateMipmap;
- break;
- case GL_TEXTURE_COMPARE_MODE_ARB:
- if (ctx->Extensions.ARB_shadow) {
- *params = (GLfloat) obj->CompareMode;
- }
- else
- error = GL_TRUE;
- break;
- case GL_TEXTURE_COMPARE_FUNC_ARB:
- if (ctx->Extensions.ARB_shadow) {
- *params = (GLfloat) obj->CompareFunc;
- }
- else
- error = GL_TRUE;
- break;
- case GL_DEPTH_TEXTURE_MODE_ARB:
- if (ctx->Extensions.ARB_depth_texture) {
- *params = (GLfloat) obj->DepthMode;
- }
- else
- error = GL_TRUE;
- break;
- case GL_TEXTURE_LOD_BIAS:
- if (ctx->Extensions.EXT_texture_lod_bias) {
- *params = obj->LodBias;
- }
- else
- error = GL_TRUE;
- break;
-#if FEATURE_OES_draw_texture
- case GL_TEXTURE_CROP_RECT_OES:
- params[0] = obj->CropRect[0];
- params[1] = obj->CropRect[1];
- params[2] = obj->CropRect[2];
- params[3] = obj->CropRect[3];
- break;
-#endif
-
- case GL_TEXTURE_SWIZZLE_R_EXT:
- case GL_TEXTURE_SWIZZLE_G_EXT:
- case GL_TEXTURE_SWIZZLE_B_EXT:
- case GL_TEXTURE_SWIZZLE_A_EXT:
- if (ctx->Extensions.EXT_texture_swizzle) {
- GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
- *params = (GLfloat) obj->Swizzle[comp];
- }
- else {
- error = GL_TRUE;
- }
- break;
-
- case GL_TEXTURE_SWIZZLE_RGBA_EXT:
- if (ctx->Extensions.EXT_texture_swizzle) {
- GLuint comp;
- for (comp = 0; comp < 4; comp++) {
- params[comp] = (GLfloat) obj->Swizzle[comp];
- }
- }
- else {
- error = GL_TRUE;
- }
- break;
-
- default:
- error = GL_TRUE;
- break;
- }
-
- if (error)
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
- pname);
-
- _mesa_unlock_texture(ctx, obj);
-}
-
-
-void GLAPIENTRY
-_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
-{
- struct gl_texture_object *obj;
- GLboolean error = GL_FALSE;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- obj = get_texobj(ctx, target, GL_TRUE);
- if (!obj)
- return;
-
- _mesa_lock_texture(ctx, obj);
- switch (pname) {
- case GL_TEXTURE_MAG_FILTER:
- *params = (GLint) obj->MagFilter;
- break;;
- case GL_TEXTURE_MIN_FILTER:
- *params = (GLint) obj->MinFilter;
- break;;
- case GL_TEXTURE_WRAP_S:
- *params = (GLint) obj->WrapS;
- break;;
- case GL_TEXTURE_WRAP_T:
- *params = (GLint) obj->WrapT;
- break;;
- case GL_TEXTURE_WRAP_R:
- *params = (GLint) obj->WrapR;
- break;;
- case GL_TEXTURE_BORDER_COLOR:
- {
- GLfloat b[4];
- b[0] = CLAMP(obj->BorderColor.f[0], 0.0F, 1.0F);
- b[1] = CLAMP(obj->BorderColor.f[1], 0.0F, 1.0F);
- b[2] = CLAMP(obj->BorderColor.f[2], 0.0F, 1.0F);
- b[3] = CLAMP(obj->BorderColor.f[3], 0.0F, 1.0F);
- params[0] = FLOAT_TO_INT(b[0]);
- params[1] = FLOAT_TO_INT(b[1]);
- params[2] = FLOAT_TO_INT(b[2]);
- params[3] = FLOAT_TO_INT(b[3]);
- }
- break;;
- case GL_TEXTURE_RESIDENT:
- {
- GLboolean resident;
- if (ctx->Driver.IsTextureResident)
- resident = ctx->Driver.IsTextureResident(ctx, obj);
- else
- resident = GL_TRUE;
- *params = (GLint) resident;
- }
- break;;
- case GL_TEXTURE_PRIORITY:
- *params = FLOAT_TO_INT(obj->Priority);
- break;;
- case GL_TEXTURE_MIN_LOD:
- *params = (GLint) obj->MinLod;
- break;;
- case GL_TEXTURE_MAX_LOD:
- *params = (GLint) obj->MaxLod;
- break;;
- case GL_TEXTURE_BASE_LEVEL:
- *params = obj->BaseLevel;
- break;;
- case GL_TEXTURE_MAX_LEVEL:
- *params = obj->MaxLevel;
- break;;
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- if (ctx->Extensions.EXT_texture_filter_anisotropic) {
- *params = (GLint) obj->MaxAnisotropy;
- }
- else {
- error = GL_TRUE;
- }
- break;
- case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
- if (ctx->Extensions.ARB_shadow_ambient) {
- *params = (GLint) FLOAT_TO_INT(obj->CompareFailValue);
- }
- else {
- error = GL_TRUE;
- }
- break;
- case GL_GENERATE_MIPMAP_SGIS:
- *params = (GLint) obj->GenerateMipmap;
- break;
- case GL_TEXTURE_COMPARE_MODE_ARB:
- if (ctx->Extensions.ARB_shadow) {
- *params = (GLint) obj->CompareMode;
- }
- else {
- error = GL_TRUE;
- }
- break;
- case GL_TEXTURE_COMPARE_FUNC_ARB:
- if (ctx->Extensions.ARB_shadow) {
- *params = (GLint) obj->CompareFunc;
- }
- else {
- error = GL_TRUE;
- }
- break;
- case GL_DEPTH_TEXTURE_MODE_ARB:
- if (ctx->Extensions.ARB_depth_texture) {
- *params = (GLint) obj->DepthMode;
- }
- else {
- error = GL_TRUE;
- }
- break;
- case GL_TEXTURE_LOD_BIAS:
- if (ctx->Extensions.EXT_texture_lod_bias) {
- *params = (GLint) obj->LodBias;
- }
- else {
- error = GL_TRUE;
- }
- break;
-#if FEATURE_OES_draw_texture
- case GL_TEXTURE_CROP_RECT_OES:
- params[0] = obj->CropRect[0];
- params[1] = obj->CropRect[1];
- params[2] = obj->CropRect[2];
- params[3] = obj->CropRect[3];
- break;
-#endif
- case GL_TEXTURE_SWIZZLE_R_EXT:
- case GL_TEXTURE_SWIZZLE_G_EXT:
- case GL_TEXTURE_SWIZZLE_B_EXT:
- case GL_TEXTURE_SWIZZLE_A_EXT:
- if (ctx->Extensions.EXT_texture_swizzle) {
- GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
- *params = obj->Swizzle[comp];
- }
- else {
- error = GL_TRUE;
- }
- break;
-
- case GL_TEXTURE_SWIZZLE_RGBA_EXT:
- if (ctx->Extensions.EXT_texture_swizzle) {
- COPY_4V(params, obj->Swizzle);
- }
- else {
- error = GL_TRUE;
- }
- break;
-
- default:
- ; /* silence warnings */
- }
-
- if (error)
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)",
- pname);
-
- _mesa_unlock_texture(ctx, obj);
-}
-
-
-/** New in GL 3.0 */
-void GLAPIENTRY
-_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
-{
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- texObj = get_texobj(ctx, target, GL_TRUE);
-
- switch (pname) {
- case GL_TEXTURE_BORDER_COLOR:
- COPY_4V(params, texObj->BorderColor.i);
- break;
- default:
- _mesa_GetTexParameteriv(target, pname, params);
- }
-}
-
-
-/** New in GL 3.0 */
-void GLAPIENTRY
-_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
-{
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- texObj = get_texobj(ctx, target, GL_TRUE);
-
- switch (pname) {
- case GL_TEXTURE_BORDER_COLOR:
- COPY_4V(params, texObj->BorderColor.i);
- break;
- default:
- {
- GLint ip[4];
- _mesa_GetTexParameteriv(target, pname, ip);
- params[0] = ip[0];
- if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
- pname == GL_TEXTURE_CROP_RECT_OES) {
- params[1] = ip[1];
- params[2] = ip[2];
- params[3] = ip[3];
- }
- }
- }
-}
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.5
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 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
+ * 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.
+ */
+
+/**
+ * \file texparam.c
+ *
+ * glTexParameter-related functions
+ */
+
+
+#include "main/glheader.h"
+#include "main/colormac.h"
+#include "main/context.h"
+#include "main/formats.h"
+#include "main/macros.h"
+#include "main/mfeatures.h"
+#include "main/mtypes.h"
+#include "main/texcompress.h"
+#include "main/texparam.h"
+#include "main/teximage.h"
+#include "main/texstate.h"
+#include "main/texfetch.h"
+#include "program/prog_instruction.h"
+
+
+/**
+ * Check if a coordinate wrap mode is supported for the texture target.
+ * \return GL_TRUE if legal, GL_FALSE otherwise
+ */
+static GLboolean
+validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
+{
+ const struct gl_extensions * const e = & ctx->Extensions;
+
+ if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
+ (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
+ /* any texture target */
+ return GL_TRUE;
+ }
+ else if (target != GL_TEXTURE_RECTANGLE_NV &&
+ (wrap == GL_REPEAT ||
+ (wrap == GL_MIRRORED_REPEAT &&
+ e->ARB_texture_mirrored_repeat) ||
+ (wrap == GL_MIRROR_CLAMP_EXT &&
+ (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
+ (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
+ (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
+ (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
+ (e->EXT_texture_mirror_clamp)))) {
+ /* non-rectangle texture */
+ return GL_TRUE;
+ }
+
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
+ return GL_FALSE;
+}
+
+
+/**
+ * Get current texture object for given target.
+ * Return NULL if any error (and record the error).
+ * Note that this is different from _mesa_select_tex_object() in that proxy
+ * targets are not accepted.
+ * Only the glGetTexLevelParameter() functions accept proxy targets.
+ */
+static struct gl_texture_object *
+get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
+{
+ struct gl_texture_unit *texUnit;
+
+ if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "gl%sTexParameter(current unit)", get ? "Get" : "");
+ return NULL;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ return texUnit->CurrentTex[TEXTURE_1D_INDEX];
+ case GL_TEXTURE_2D:
+ return texUnit->CurrentTex[TEXTURE_2D_INDEX];
+ case GL_TEXTURE_3D:
+ return texUnit->CurrentTex[TEXTURE_3D_INDEX];
+ case GL_TEXTURE_CUBE_MAP:
+ if (ctx->Extensions.ARB_texture_cube_map) {
+ return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
+ }
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ if (ctx->Extensions.NV_texture_rectangle) {
+ return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
+ }
+ break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ if (ctx->Extensions.MESA_texture_array) {
+ return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
+ }
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ if (ctx->Extensions.MESA_texture_array) {
+ return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
+ }
+ break;
+ default:
+ ;
+ }
+
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "gl%sTexParameter(target)", get ? "Get" : "");
+ return NULL;
+}
+
+
+/**
+ * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
+ * \return -1 if error.
+ */
+static GLint
+comp_to_swizzle(GLenum comp)
+{
+ switch (comp) {
+ case GL_RED:
+ return SWIZZLE_X;
+ case GL_GREEN:
+ return SWIZZLE_Y;
+ case GL_BLUE:
+ return SWIZZLE_Z;
+ case GL_ALPHA:
+ return SWIZZLE_W;
+ case GL_ZERO:
+ return SWIZZLE_ZERO;
+ case GL_ONE:
+ return SWIZZLE_ONE;
+ default:
+ return -1;
+ }
+}
+
+
+static void
+set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
+{
+ ASSERT(comp < 4);
+ ASSERT(swz <= SWIZZLE_NIL);
+ {
+ GLuint mask = 0x7 << (3 * comp);
+ GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
+ *swizzle = s;
+ }
+}
+
+
+/**
+ * This is called just prior to changing any texture object state which
+ * will not effect texture completeness.
+ */
+static INLINE void
+flush(struct gl_context *ctx)
+{
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+}
+
+
+/**
+ * This is called just prior to changing any texture object state which
+ * can effect texture completeness (texture base level, max level,
+ * minification filter).
+ * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
+ * state flag and then mark the texture object as 'incomplete' so that any
+ * per-texture derived state gets recomputed.
+ */
+static INLINE void
+incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->_Complete = GL_FALSE;
+}
+
+
+/**
+ * Set an integer-valued texture parameter
+ * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
+ */
+static GLboolean
+set_tex_parameteri(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLint *params)
+{
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ if (texObj->MinFilter == params[0])
+ return GL_FALSE;
+ switch (params[0]) {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ incomplete(ctx, texObj);
+ texObj->MinFilter = params[0];
+ return GL_TRUE;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ case GL_LINEAR_MIPMAP_NEAREST:
+ case GL_NEAREST_MIPMAP_LINEAR:
+ case GL_LINEAR_MIPMAP_LINEAR:
+ if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
+ incomplete(ctx, texObj);
+ texObj->MinFilter = params[0];
+ return GL_TRUE;
+ }
+ /* fall-through */
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
+ params[0] );
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_MAG_FILTER:
+ if (texObj->MagFilter == params[0])
+ return GL_FALSE;
+ switch (params[0]) {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ flush(ctx); /* does not effect completeness */
+ texObj->MagFilter = params[0];
+ return GL_TRUE;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
+ params[0]);
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_WRAP_S:
+ if (texObj->WrapS == params[0])
+ return GL_FALSE;
+ if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
+ flush(ctx);
+ texObj->WrapS = params[0];
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_WRAP_T:
+ if (texObj->WrapT == params[0])
+ return GL_FALSE;
+ if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
+ flush(ctx);
+ texObj->WrapT = params[0];
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_WRAP_R:
+ if (texObj->WrapR == params[0])
+ return GL_FALSE;
+ if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
+ flush(ctx);
+ texObj->WrapR = params[0];
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ if (texObj->BaseLevel == params[0])
+ return GL_FALSE;
+ if (params[0] < 0 ||
+ (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexParameter(param=%d)", params[0]);
+ return GL_FALSE;
+ }
+ incomplete(ctx, texObj);
+ texObj->BaseLevel = params[0];
+ return GL_TRUE;
+
+ case GL_TEXTURE_MAX_LEVEL:
+ if (texObj->MaxLevel == params[0])
+ return GL_FALSE;
+ if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexParameter(param=%d)", params[0]);
+ return GL_FALSE;
+ }
+ incomplete(ctx, texObj);
+ texObj->MaxLevel = params[0];
+ return GL_TRUE;
+
+ case GL_GENERATE_MIPMAP_SGIS:
+ if (texObj->GenerateMipmap != params[0]) {
+ /* no flush() */
+ texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (ctx->Extensions.ARB_shadow &&
+ (params[0] == GL_NONE ||
+ params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) {
+ if (texObj->CompareMode != params[0]) {
+ flush(ctx);
+ texObj->CompareMode = params[0];
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)");
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ if (texObj->CompareFunc == params[0])
+ return GL_FALSE;
+ switch (params[0]) {
+ case GL_LEQUAL:
+ case GL_GEQUAL:
+ flush(ctx);
+ texObj->CompareFunc = params[0];
+ return GL_TRUE;
+ case GL_EQUAL:
+ case GL_NOTEQUAL:
+ case GL_LESS:
+ case GL_GREATER:
+ case GL_ALWAYS:
+ case GL_NEVER:
+ if (ctx->Extensions.EXT_shadow_funcs) {
+ flush(ctx);
+ texObj->CompareFunc = params[0];
+ return GL_TRUE;
+ }
+ /* fall-through */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)");
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+ }
+ return GL_FALSE;
+
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture &&
+ (params[0] == GL_LUMINANCE ||
+ params[0] == GL_INTENSITY ||
+ params[0] == GL_ALPHA ||
+ (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED))) {
+ if (texObj->DepthMode != params[0]) {
+ flush(ctx);
+ texObj->DepthMode = params[0];
+ return GL_TRUE;
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)");
+ }
+ return GL_FALSE;
+
+#if FEATURE_OES_draw_texture
+ case GL_TEXTURE_CROP_RECT_OES:
+ texObj->CropRect[0] = params[0];
+ texObj->CropRect[1] = params[1];
+ texObj->CropRect[2] = params[2];
+ texObj->CropRect[3] = params[3];
+ return GL_TRUE;
+#endif
+
+ case GL_TEXTURE_SWIZZLE_R_EXT:
+ case GL_TEXTURE_SWIZZLE_G_EXT:
+ case GL_TEXTURE_SWIZZLE_B_EXT:
+ case GL_TEXTURE_SWIZZLE_A_EXT:
+ if (ctx->Extensions.EXT_texture_swizzle) {
+ const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+ const GLint swz = comp_to_swizzle(params[0]);
+ if (swz < 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexParameter(swizzle 0x%x)", params[0]);
+ return GL_FALSE;
+ }
+ ASSERT(comp < 4);
+ if (swz >= 0) {
+ flush(ctx);
+ texObj->Swizzle[comp] = params[0];
+ set_swizzle_component(&texObj->_Swizzle, comp, swz);
+ return GL_TRUE;
+ }
+ }
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+ return GL_FALSE;
+
+ case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+ if (ctx->Extensions.EXT_texture_swizzle) {
+ GLuint comp;
+ flush(ctx);
+ for (comp = 0; comp < 4; comp++) {
+ const GLint swz = comp_to_swizzle(params[comp]);
+ if (swz >= 0) {
+ texObj->Swizzle[comp] = params[comp];
+ set_swizzle_component(&texObj->_Swizzle, comp, swz);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexParameter(swizzle 0x%x)", params[comp]);
+ return GL_FALSE;
+ }
+ }
+ return GL_TRUE;
+ }
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+ return GL_FALSE;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (ctx->Extensions.EXT_texture_sRGB_decode) {
+ GLenum decode = params[0];
+ if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
+ if (texObj->sRGBDecode != decode) {
+ flush(ctx);
+ texObj->sRGBDecode = decode;
+ _mesa_update_fetch_functions(texObj);
+ }
+ return GL_TRUE;
+ }
+ }
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+ return GL_FALSE;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+ }
+ return GL_FALSE;
+}
+
+
+/**
+ * Set a float-valued texture parameter
+ * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
+ */
+static GLboolean
+set_tex_parameterf(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params)
+{
+ switch (pname) {
+ case GL_TEXTURE_MIN_LOD:
+ if (texObj->MinLod == params[0])
+ return GL_FALSE;
+ flush(ctx);
+ texObj->MinLod = params[0];
+ return GL_TRUE;
+
+ case GL_TEXTURE_MAX_LOD:
+ if (texObj->MaxLod == params[0])
+ return GL_FALSE;
+ flush(ctx);
+ texObj->MaxLod = params[0];
+ return GL_TRUE;
+
+ case GL_TEXTURE_PRIORITY:
+ flush(ctx);
+ texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
+ return GL_TRUE;
+
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ if (texObj->MaxAnisotropy == params[0])
+ return GL_FALSE;
+ if (params[0] < 1.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+ return GL_FALSE;
+ }
+ flush(ctx);
+ /* clamp to max, that's what NVIDIA does */
+ texObj->MaxAnisotropy = MIN2(params[0],
+ ctx->Const.MaxTextureMaxAnisotropy);
+ return GL_TRUE;
+ }
+ else {
+ static GLuint count = 0;
+ if (count++ < 10)
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+ if (ctx->Extensions.ARB_shadow_ambient) {
+ if (texObj->CompareFailValue != params[0]) {
+ flush(ctx);
+ texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F);
+ return GL_TRUE;
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)");
+ }
+ return GL_FALSE;
+
+ case GL_TEXTURE_LOD_BIAS:
+ /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ if (texObj->LodBias != params[0]) {
+ flush(ctx);
+ texObj->LodBias = params[0];
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+ }
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ flush(ctx);
+ texObj->BorderColor.f[RCOMP] = params[0];
+ texObj->BorderColor.f[GCOMP] = params[1];
+ texObj->BorderColor.f[BCOMP] = params[2];
+ texObj->BorderColor.f[ACOMP] = params[3];
+ return GL_TRUE;
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+ }
+ return GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ GLboolean need_update;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ texObj = get_texobj(ctx, target, GL_FALSE);
+ if (!texObj)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_GENERATE_MIPMAP_SGIS:
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ {
+ /* convert float param to int */
+ GLint p[4];
+ p[0] = (GLint) param;
+ p[1] = p[2] = p[3] = 0;
+ need_update = set_tex_parameteri(ctx, texObj, pname, p);
+ }
+ break;
+ default:
+ {
+ /* this will generate an error if pname is illegal */
+ GLfloat p[4];
+ p[0] = param;
+ p[1] = p[2] = p[3] = 0.0F;
+ need_update = set_tex_parameterf(ctx, texObj, pname, p);
+ }
+ }
+
+ if (ctx->Driver.TexParameter && need_update) {
+ ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GLboolean need_update;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ texObj = get_texobj(ctx, target, GL_FALSE);
+ if (!texObj)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_GENERATE_MIPMAP_SGIS:
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ {
+ /* convert float param to int */
+ GLint p[4];
+ p[0] = (GLint) params[0];
+ p[1] = p[2] = p[3] = 0;
+ need_update = set_tex_parameteri(ctx, texObj, pname, p);
+ }
+ break;
+
+#if FEATURE_OES_draw_texture
+ case GL_TEXTURE_CROP_RECT_OES:
+ {
+ /* convert float params to int */
+ GLint iparams[4];
+ iparams[0] = (GLint) params[0];
+ iparams[1] = (GLint) params[1];
+ iparams[2] = (GLint) params[2];
+ iparams[3] = (GLint) params[3];
+ need_update = set_tex_parameteri(ctx, texObj, pname, iparams);
+ }
+ break;
+#endif
+
+ default:
+ /* this will generate an error if pname is illegal */
+ need_update = set_tex_parameterf(ctx, texObj, pname, params);
+ }
+
+ if (ctx->Driver.TexParameter && need_update) {
+ ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ GLboolean need_update;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ texObj = get_texobj(ctx, target, GL_FALSE);
+ if (!texObj)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ case GL_TEXTURE_PRIORITY:
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ case GL_TEXTURE_LOD_BIAS:
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+ {
+ GLfloat fparam[4];
+ fparam[0] = (GLfloat) param;
+ fparam[1] = fparam[2] = fparam[3] = 0.0F;
+ /* convert int param to float */
+ need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
+ }
+ break;
+ default:
+ /* this will generate an error if pname is illegal */
+ {
+ GLint iparam[4];
+ iparam[0] = param;
+ iparam[1] = iparam[2] = iparam[3] = 0;
+ need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
+ }
+ }
+
+ if (ctx->Driver.TexParameter && need_update) {
+ GLfloat fparam = (GLfloat) param;
+ ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ GLboolean need_update;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ texObj = get_texobj(ctx, target, GL_FALSE);
+ if (!texObj)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_BORDER_COLOR:
+ {
+ /* convert int params to float */
+ GLfloat fparams[4];
+ fparams[0] = INT_TO_FLOAT(params[0]);
+ fparams[1] = INT_TO_FLOAT(params[1]);
+ fparams[2] = INT_TO_FLOAT(params[2]);
+ fparams[3] = INT_TO_FLOAT(params[3]);
+ need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
+ }
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ case GL_TEXTURE_PRIORITY:
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ case GL_TEXTURE_LOD_BIAS:
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+ {
+ /* convert int param to float */
+ GLfloat fparams[4];
+ fparams[0] = (GLfloat) params[0];
+ fparams[1] = fparams[2] = fparams[3] = 0.0F;
+ need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
+ }
+ break;
+ default:
+ /* this will generate an error if pname is illegal */
+ need_update = set_tex_parameteri(ctx, texObj, pname, params);
+ }
+
+ if (ctx->Driver.TexParameter && need_update) {
+ GLfloat fparams[4];
+ fparams[0] = INT_TO_FLOAT(params[0]);
+ if (pname == GL_TEXTURE_BORDER_COLOR ||
+ pname == GL_TEXTURE_CROP_RECT_OES) {
+ fparams[1] = INT_TO_FLOAT(params[1]);
+ fparams[2] = INT_TO_FLOAT(params[2]);
+ fparams[3] = INT_TO_FLOAT(params[3]);
+ }
+ ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
+ }
+}
+
+
+/**
+ * Set tex parameter to integer value(s). Primarily intended to set
+ * integer-valued texture border color (for integer-valued textures).
+ * New in GL 3.0.
+ */
+void GLAPIENTRY
+_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
+{
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ texObj = get_texobj(ctx, target, GL_FALSE);
+ if (!texObj)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_BORDER_COLOR:
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ /* set the integer-valued border color */
+ COPY_4V(texObj->BorderColor.i, params);
+ break;
+ default:
+ _mesa_TexParameteriv(target, pname, params);
+ break;
+ }
+ /* XXX no driver hook for TexParameterIiv() yet */
+}
+
+
+/**
+ * Set tex parameter to unsigned integer value(s). Primarily intended to set
+ * uint-valued texture border color (for integer-valued textures).
+ * New in GL 3.0
+ */
+void GLAPIENTRY
+_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
+{
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ texObj = get_texobj(ctx, target, GL_FALSE);
+ if (!texObj)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_BORDER_COLOR:
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ /* set the unsigned integer-valued border color */
+ COPY_4V(texObj->BorderColor.ui, params);
+ break;
+ default:
+ _mesa_TexParameteriv(target, pname, (const GLint *) params);
+ break;
+ }
+ /* XXX no driver hook for TexParameterIuiv() yet */
+}
+
+
+
+
+void GLAPIENTRY
+_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
+ GLenum pname, GLfloat *params )
+{
+ GLint iparam;
+ _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
+ *params = (GLfloat) iparam;
+}
+
+
+void GLAPIENTRY
+_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
+ GLenum pname, GLint *params )
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ const struct gl_texture_image *img = NULL;
+ GLboolean isProxy;
+ GLint maxLevels;
+ gl_format texFormat;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetTexLevelParameteriv(current unit)");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+
+ /* this will catch bad target values */
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ if (maxLevels == 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(target=0x%x)", target);
+ return;
+ }
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
+ return;
+ }
+
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ _mesa_lock_texture(ctx, texObj);
+
+ img = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (!img || !img->TexFormat) {
+ /* undefined texture image */
+ if (pname == GL_TEXTURE_COMPONENTS)
+ *params = 1;
+ else
+ *params = 0;
+ goto out;
+ }
+
+ texFormat = img->TexFormat;
+
+ isProxy = _mesa_is_proxy_texture(target);
+
+ switch (pname) {
+ case GL_TEXTURE_WIDTH:
+ *params = img->Width;
+ break;
+ case GL_TEXTURE_HEIGHT:
+ *params = img->Height;
+ break;
+ case GL_TEXTURE_DEPTH:
+ *params = img->Depth;
+ break;
+ case GL_TEXTURE_INTERNAL_FORMAT:
+ if (_mesa_is_format_compressed(img->TexFormat)) {
+ /* need to return the actual compressed format */
+ *params = _mesa_compressed_format_to_glenum(ctx, img->TexFormat);
+ }
+ else {
+ /* return the user's requested internal format */
+ *params = img->InternalFormat;
+ }
+ break;
+ case GL_TEXTURE_BORDER:
+ *params = img->Border;
+ break;
+ case GL_TEXTURE_RED_SIZE:
+ if (img->_BaseFormat == GL_RED) {
+ *params = _mesa_get_format_bits(texFormat, pname);
+ break;
+ }
+ /* FALLTHROUGH */
+ case GL_TEXTURE_GREEN_SIZE:
+ if (img->_BaseFormat == GL_RG) {
+ *params = _mesa_get_format_bits(texFormat, pname);
+ break;
+ }
+ /* FALLTHROUGH */
+ case GL_TEXTURE_BLUE_SIZE:
+ if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
+ *params = _mesa_get_format_bits(texFormat, pname);
+ else
+ *params = 0;
+ break;
+ case GL_TEXTURE_ALPHA_SIZE:
+ if (img->_BaseFormat == GL_ALPHA ||
+ img->_BaseFormat == GL_LUMINANCE_ALPHA ||
+ img->_BaseFormat == GL_RGBA)
+ *params = _mesa_get_format_bits(texFormat, pname);
+ else
+ *params = 0;
+ break;
+ case GL_TEXTURE_INTENSITY_SIZE:
+ if (img->_BaseFormat != GL_INTENSITY)
+ *params = 0;
+ else {
+ *params = _mesa_get_format_bits(texFormat, pname);
+ if (*params == 0) {
+ /* intensity probably stored as rgb texture */
+ *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
+ _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
+ }
+ }
+ break;
+ case GL_TEXTURE_LUMINANCE_SIZE:
+ if (img->_BaseFormat != GL_LUMINANCE &&
+ img->_BaseFormat != GL_LUMINANCE_ALPHA)
+ *params = 0;
+ else {
+ *params = _mesa_get_format_bits(texFormat, pname);
+ if (*params == 0) {
+ /* luminance probably stored as rgb texture */
+ *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
+ _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
+ }
+ }
+ 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)
+ *params = _mesa_get_format_bits(texFormat, pname);
+ else
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ break;
+ case GL_TEXTURE_STENCIL_SIZE_EXT:
+ if (ctx->Extensions.EXT_packed_depth_stencil ||
+ ctx->Extensions.ARB_framebuffer_object) {
+ *params = _mesa_get_format_bits(texFormat, pname);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+ case GL_TEXTURE_SHARED_SIZE:
+ if (ctx->VersionMajor >= 3) {
+ /* XXX return number of exponent bits for shared exponent texture
+ * formats, like GL_RGB9_E5.
+ */
+ *params = 0;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+
+ /* GL_ARB_texture_compression */
+ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
+ if (_mesa_is_format_compressed(img->TexFormat) && !isProxy) {
+ *params = _mesa_format_image_size(texFormat, img->Width,
+ img->Height, img->Depth);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+ case GL_TEXTURE_COMPRESSED:
+ *params = (GLint) _mesa_is_format_compressed(img->TexFormat);
+ break;
+
+ /* GL_ARB_texture_float */
+ case GL_TEXTURE_RED_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE) ?
+ _mesa_get_format_datatype(texFormat) : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+ case GL_TEXTURE_GREEN_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE) ?
+ _mesa_get_format_datatype(texFormat) : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+ case GL_TEXTURE_BLUE_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_BLUE_SIZE) ?
+ _mesa_get_format_datatype(texFormat) : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+ case GL_TEXTURE_ALPHA_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_ALPHA_SIZE) ?
+ _mesa_get_format_datatype(texFormat) : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+ case GL_TEXTURE_LUMINANCE_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_LUMINANCE_SIZE) ?
+ _mesa_get_format_datatype(texFormat) : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+ case GL_TEXTURE_INTENSITY_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_INTENSITY_SIZE) ?
+ _mesa_get_format_datatype(texFormat) : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+ case GL_TEXTURE_DEPTH_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_DEPTH_SIZE) ?
+ _mesa_get_format_datatype(texFormat) : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ break;
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+
+ out:
+ _mesa_unlock_texture(ctx, texObj);
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
+{
+ struct gl_texture_object *obj;
+ GLboolean error = GL_FALSE;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ obj = get_texobj(ctx, target, GL_TRUE);
+ if (!obj)
+ return;
+
+ _mesa_lock_texture(ctx, obj);
+ switch (pname) {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = ENUM_TO_FLOAT(obj->MagFilter);
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = ENUM_TO_FLOAT(obj->MinFilter);
+ break;
+ case GL_TEXTURE_WRAP_S:
+ *params = ENUM_TO_FLOAT(obj->WrapS);
+ break;
+ case GL_TEXTURE_WRAP_T:
+ *params = ENUM_TO_FLOAT(obj->WrapT);
+ break;
+ case GL_TEXTURE_WRAP_R:
+ *params = ENUM_TO_FLOAT(obj->WrapR);
+ break;
+ case GL_TEXTURE_BORDER_COLOR:
+ params[0] = CLAMP(obj->BorderColor.f[0], 0.0F, 1.0F);
+ params[1] = CLAMP(obj->BorderColor.f[1], 0.0F, 1.0F);
+ params[2] = CLAMP(obj->BorderColor.f[2], 0.0F, 1.0F);
+ params[3] = CLAMP(obj->BorderColor.f[3], 0.0F, 1.0F);
+ break;
+ case GL_TEXTURE_RESIDENT:
+ {
+ GLboolean resident;
+ if (ctx->Driver.IsTextureResident)
+ resident = ctx->Driver.IsTextureResident(ctx, obj);
+ else
+ resident = GL_TRUE;
+ *params = ENUM_TO_FLOAT(resident);
+ }
+ break;
+ case GL_TEXTURE_PRIORITY:
+ *params = obj->Priority;
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ *params = obj->MinLod;
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ *params = obj->MaxLod;
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ *params = (GLfloat) obj->BaseLevel;
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ *params = (GLfloat) obj->MaxLevel;
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ *params = obj->MaxAnisotropy;
+ }
+ else
+ error = GL_TRUE;
+ break;
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+ if (ctx->Extensions.ARB_shadow_ambient) {
+ *params = obj->CompareFailValue;
+ }
+ else
+ error = GL_TRUE;
+ break;
+ case GL_GENERATE_MIPMAP_SGIS:
+ *params = (GLfloat) obj->GenerateMipmap;
+ break;
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ *params = (GLfloat) obj->CompareMode;
+ }
+ else
+ error = GL_TRUE;
+ break;
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ *params = (GLfloat) obj->CompareFunc;
+ }
+ else
+ error = GL_TRUE;
+ break;
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture) {
+ *params = (GLfloat) obj->DepthMode;
+ }
+ else
+ error = GL_TRUE;
+ break;
+ case GL_TEXTURE_LOD_BIAS:
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ *params = obj->LodBias;
+ }
+ else
+ error = GL_TRUE;
+ break;
+#if FEATURE_OES_draw_texture
+ case GL_TEXTURE_CROP_RECT_OES:
+ params[0] = obj->CropRect[0];
+ params[1] = obj->CropRect[1];
+ params[2] = obj->CropRect[2];
+ params[3] = obj->CropRect[3];
+ break;
+#endif
+
+ case GL_TEXTURE_SWIZZLE_R_EXT:
+ case GL_TEXTURE_SWIZZLE_G_EXT:
+ case GL_TEXTURE_SWIZZLE_B_EXT:
+ case GL_TEXTURE_SWIZZLE_A_EXT:
+ if (ctx->Extensions.EXT_texture_swizzle) {
+ GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+ *params = (GLfloat) obj->Swizzle[comp];
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+
+ case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+ if (ctx->Extensions.EXT_texture_swizzle) {
+ GLuint comp;
+ for (comp = 0; comp < 4; comp++) {
+ params[comp] = (GLfloat) obj->Swizzle[comp];
+ }
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+
+ default:
+ error = GL_TRUE;
+ break;
+ }
+
+ if (error)
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
+ pname);
+
+ _mesa_unlock_texture(ctx, obj);
+}
+
+
+void GLAPIENTRY
+_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
+{
+ struct gl_texture_object *obj;
+ GLboolean error = GL_FALSE;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ obj = get_texobj(ctx, target, GL_TRUE);
+ if (!obj)
+ return;
+
+ _mesa_lock_texture(ctx, obj);
+ switch (pname) {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = (GLint) obj->MagFilter;
+ break;;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = (GLint) obj->MinFilter;
+ break;;
+ case GL_TEXTURE_WRAP_S:
+ *params = (GLint) obj->WrapS;
+ break;;
+ case GL_TEXTURE_WRAP_T:
+ *params = (GLint) obj->WrapT;
+ break;;
+ case GL_TEXTURE_WRAP_R:
+ *params = (GLint) obj->WrapR;
+ break;;
+ case GL_TEXTURE_BORDER_COLOR:
+ {
+ GLfloat b[4];
+ b[0] = CLAMP(obj->BorderColor.f[0], 0.0F, 1.0F);
+ b[1] = CLAMP(obj->BorderColor.f[1], 0.0F, 1.0F);
+ b[2] = CLAMP(obj->BorderColor.f[2], 0.0F, 1.0F);
+ b[3] = CLAMP(obj->BorderColor.f[3], 0.0F, 1.0F);
+ params[0] = FLOAT_TO_INT(b[0]);
+ params[1] = FLOAT_TO_INT(b[1]);
+ params[2] = FLOAT_TO_INT(b[2]);
+ params[3] = FLOAT_TO_INT(b[3]);
+ }
+ break;;
+ case GL_TEXTURE_RESIDENT:
+ {
+ GLboolean resident;
+ if (ctx->Driver.IsTextureResident)
+ resident = ctx->Driver.IsTextureResident(ctx, obj);
+ else
+ resident = GL_TRUE;
+ *params = (GLint) resident;
+ }
+ break;;
+ case GL_TEXTURE_PRIORITY:
+ *params = FLOAT_TO_INT(obj->Priority);
+ break;;
+ case GL_TEXTURE_MIN_LOD:
+ *params = (GLint) obj->MinLod;
+ break;;
+ case GL_TEXTURE_MAX_LOD:
+ *params = (GLint) obj->MaxLod;
+ break;;
+ case GL_TEXTURE_BASE_LEVEL:
+ *params = obj->BaseLevel;
+ break;;
+ case GL_TEXTURE_MAX_LEVEL:
+ *params = obj->MaxLevel;
+ break;;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ *params = (GLint) obj->MaxAnisotropy;
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+ if (ctx->Extensions.ARB_shadow_ambient) {
+ *params = (GLint) FLOAT_TO_INT(obj->CompareFailValue);
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+ case GL_GENERATE_MIPMAP_SGIS:
+ *params = (GLint) obj->GenerateMipmap;
+ break;
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ *params = (GLint) obj->CompareMode;
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ *params = (GLint) obj->CompareFunc;
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture) {
+ *params = (GLint) obj->DepthMode;
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+ case GL_TEXTURE_LOD_BIAS:
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ *params = (GLint) obj->LodBias;
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+#if FEATURE_OES_draw_texture
+ case GL_TEXTURE_CROP_RECT_OES:
+ params[0] = obj->CropRect[0];
+ params[1] = obj->CropRect[1];
+ params[2] = obj->CropRect[2];
+ params[3] = obj->CropRect[3];
+ break;
+#endif
+ case GL_TEXTURE_SWIZZLE_R_EXT:
+ case GL_TEXTURE_SWIZZLE_G_EXT:
+ case GL_TEXTURE_SWIZZLE_B_EXT:
+ case GL_TEXTURE_SWIZZLE_A_EXT:
+ if (ctx->Extensions.EXT_texture_swizzle) {
+ GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+ *params = obj->Swizzle[comp];
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+
+ case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+ if (ctx->Extensions.EXT_texture_swizzle) {
+ COPY_4V(params, obj->Swizzle);
+ }
+ else {
+ error = GL_TRUE;
+ }
+ break;
+
+ default:
+ ; /* silence warnings */
+ }
+
+ if (error)
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)",
+ pname);
+
+ _mesa_unlock_texture(ctx, obj);
+}
+
+
+/** New in GL 3.0 */
+void GLAPIENTRY
+_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
+{
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ texObj = get_texobj(ctx, target, GL_TRUE);
+
+ switch (pname) {
+ case GL_TEXTURE_BORDER_COLOR:
+ COPY_4V(params, texObj->BorderColor.i);
+ break;
+ default:
+ _mesa_GetTexParameteriv(target, pname, params);
+ }
+}
+
+
+/** New in GL 3.0 */
+void GLAPIENTRY
+_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
+{
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ texObj = get_texobj(ctx, target, GL_TRUE);
+
+ switch (pname) {
+ case GL_TEXTURE_BORDER_COLOR:
+ COPY_4V(params, texObj->BorderColor.i);
+ break;
+ default:
+ {
+ GLint ip[4];
+ _mesa_GetTexParameteriv(target, pname, ip);
+ params[0] = ip[0];
+ if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
+ pname == GL_TEXTURE_CROP_RECT_OES) {
+ params[1] = ip[1];
+ params[2] = ip[2];
+ params[3] = ip[3];
+ }
+ }
+ }
+}