-/* $Id: state.c,v 1.62 2001/03/19 02:25:35 keithw Exp $ */
+/* $Id: state.c,v 1.96 2002/10/24 23:57:21 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
*/
-#ifdef PC_HEADER
-#include "all.h"
-#else
#include "glheader.h"
#include "accum.h"
-#include "alpha.h"
#include "api_loopback.h"
#include "attrib.h"
-#include "bitmap.h"
#include "blend.h"
#include "buffers.h"
#include "clip.h"
#include "colortab.h"
#include "context.h"
#include "convolve.h"
-#include "copypix.h"
#include "depth.h"
#include "dlist.h"
#include "drawpix.h"
#include "histogram.h"
#include "light.h"
#include "lines.h"
-#include "logic.h"
-#include "masking.h"
#include "matrix.h"
#include "mmath.h"
#include "pixel.h"
-#include "pixeltex.h"
#include "points.h"
#include "polygon.h"
#include "rastpos.h"
-#include "readpix.h"
-#include "scissor.h"
#include "state.h"
#include "stencil.h"
#include "teximage.h"
#include "texstate.h"
#include "mtypes.h"
#include "varray.h"
-#include "winpos.h"
+#if FEATURE_NV_vertex_program
+#include "vpstate.h"
+#endif
#include "math/m_matrix.h"
#include "math/m_xform.h"
-#endif
static int
generic_noop(void)
{
#ifdef DEBUG
- _mesa_problem(NULL, "undefined function dispatch");
+ _mesa_problem(NULL, "User called no-op dispatch function");
#endif
return 0;
}
/* first initialize all dispatch slots to no-op */
_mesa_init_no_op_table(exec, tableSize);
- _mesa_loopback_init_api_table( exec, GL_FALSE );
+ _mesa_loopback_init_api_table( exec, GL_TRUE );
/* load the dispatch slots we understand */
exec->Accum = _mesa_Accum;
exec->LockArraysEXT = _mesa_LockArraysEXT;
exec->UnlockArraysEXT = _mesa_UnlockArraysEXT;
+ /* 148. GL_EXT_multi_draw_arrays */
+ exec->MultiDrawArraysEXT = _mesa_MultiDrawArraysEXT;
+ exec->MultiDrawElementsEXT = _mesa_MultiDrawElementsEXT;
+
/* 173. GL_INGR_blend_func_separate */
exec->BlendFuncSeparateEXT = _mesa_BlendFuncSeparateEXT;
exec->WindowPos4sMESA = _mesa_WindowPos4sMESA;
exec->WindowPos4svMESA = _mesa_WindowPos4svMESA;
+ /* 233. GL_NV_vertex_program */
+#if FEATURE_NV_vertex_program
+ exec->BindProgramNV = _mesa_BindProgramNV;
+ exec->DeleteProgramsNV = _mesa_DeleteProgramsNV;
+ exec->ExecuteProgramNV = _mesa_ExecuteProgramNV;
+ exec->GenProgramsNV = _mesa_GenProgramsNV;
+ exec->AreProgramsResidentNV = _mesa_AreProgramsResidentNV;
+ exec->RequestResidentProgramsNV = _mesa_RequestResidentProgramsNV;
+ exec->GetProgramParameterfvNV = _mesa_GetProgramParameterfvNV;
+ exec->GetProgramParameterdvNV = _mesa_GetProgramParameterdvNV;
+ exec->GetProgramivNV = _mesa_GetProgramivNV;
+ exec->GetProgramStringNV = _mesa_GetProgramStringNV;
+ exec->GetTrackMatrixivNV = _mesa_GetTrackMatrixivNV;
+ exec->GetVertexAttribdvNV = _mesa_GetVertexAttribdvNV;
+ exec->GetVertexAttribfvNV = _mesa_GetVertexAttribfvNV;
+ exec->GetVertexAttribivNV = _mesa_GetVertexAttribivNV;
+ exec->GetVertexAttribPointervNV = _mesa_GetVertexAttribPointervNV;
+ exec->IsProgramNV = _mesa_IsProgramNV;
+ exec->LoadProgramNV = _mesa_LoadProgramNV;
+ exec->ProgramParameter4dNV = _mesa_ProgramParameter4dNV;
+ exec->ProgramParameter4dvNV = _mesa_ProgramParameter4dvNV;
+ exec->ProgramParameter4fNV = _mesa_ProgramParameter4fNV;
+ exec->ProgramParameter4fvNV = _mesa_ProgramParameter4fvNV;
+ exec->ProgramParameters4dvNV = _mesa_ProgramParameters4dvNV;
+ exec->ProgramParameters4fvNV = _mesa_ProgramParameters4fvNV;
+ exec->TrackMatrixNV = _mesa_TrackMatrixNV;
+ exec->VertexAttribPointerNV = _mesa_VertexAttribPointerNV;
+#endif
+
+ /* 262. GL_NV_point_sprite */
+ exec->PointParameteriNV = _mesa_PointParameteriNV;
+ exec->PointParameterivNV = _mesa_PointParameterivNV;
+
+ /* 268. GL_EXT_stencil_two_side */
+ exec->ActiveStencilFaceEXT = _mesa_ActiveStencilFaceEXT;
+
/* ARB 1. GL_ARB_multitexture */
exec->ActiveTextureARB = _mesa_ActiveTextureARB;
exec->ClientActiveTextureARB = _mesa_ClientActiveTextureARB;
exec->MultTransposeMatrixdARB = _mesa_MultTransposeMatrixdARB;
exec->MultTransposeMatrixfARB = _mesa_MultTransposeMatrixfARB;
+ /* ARB 5. GL_ARB_multisample */
+ exec->SampleCoverageARB = _mesa_SampleCoverageARB;
+
/* ARB 12. GL_ARB_texture_compression */
exec->CompressedTexImage3DARB = _mesa_CompressedTexImage3DARB;
exec->CompressedTexImage2DARB = _mesa_CompressedTexImage2DARB;
exec->CompressedTexSubImage1DARB = _mesa_CompressedTexSubImage1DARB;
exec->GetCompressedTexImageARB = _mesa_GetCompressedTexImageARB;
+ /* ARB 14. GL_ARB_point_parameters */
+ /* reuse EXT_point_parameters functions */
+
}
/**********************************************************************/
+/*
+ * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET
+ * in ctx->_TriangleCaps if needed.
+ */
static void
update_polygon( GLcontext *ctx )
{
ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
/* Any Polygon offsets enabled? */
- ctx->Polygon._OffsetAny = GL_FALSE;
- ctx->_TriangleCaps &= ~DD_TRI_OFFSET;
-
if (ctx->Polygon.OffsetPoint ||
ctx->Polygon.OffsetLine ||
ctx->Polygon.OffsetFill) {
ctx->_TriangleCaps |= DD_TRI_OFFSET;
- ctx->Polygon._OffsetAny = GL_TRUE;
}
}
static void
calculate_model_project_matrix( GLcontext *ctx )
{
- if (!ctx->_NeedEyeCoords) {
- _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix,
- &ctx->ProjectionMatrix,
- &ctx->ModelView );
+ _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix,
+ ctx->ProjectionMatrixStack.Top,
+ ctx->ModelviewMatrixStack.Top );
- _math_matrix_analyse( &ctx->_ModelProjectMatrix );
- }
+ _math_matrix_analyse( &ctx->_ModelProjectMatrix );
}
static void
update_modelview_scale( GLcontext *ctx )
{
ctx->_ModelViewInvScale = 1.0F;
- if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
+ if (ctx->ModelviewMatrixStack.Top->flags & (MAT_FLAG_UNIFORM_SCALE |
MAT_FLAG_GENERAL_SCALE |
MAT_FLAG_GENERAL_3D |
MAT_FLAG_GENERAL) ) {
- const GLfloat *m = ctx->ModelView.inv;
+ const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv;
GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
if (f < 1e-12) f = 1.0;
if (ctx->_NeedEyeCoords)
- ctx->_ModelViewInvScale = 1.0/GL_SQRT(f);
+ ctx->_ModelViewInvScale = (GLfloat) (1.0/GL_SQRT(f));
else
- ctx->_ModelViewInvScale = GL_SQRT(f);
+ ctx->_ModelViewInvScale = (GLfloat) GL_SQRT(f);
}
}
/* Recalculate all state that depends on _NeedEyeCoords.
*/
update_modelview_scale(ctx);
- calculate_model_project_matrix(ctx);
_mesa_compute_light_positions( ctx );
if (ctx->Driver.LightingSpaceChange)
if (new_state & _NEW_MODELVIEW)
update_modelview_scale(ctx);
- if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
- calculate_model_project_matrix(ctx);
-
if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
_mesa_compute_light_positions( ctx );
}
/* NOTE: This routine references Tranform attribute values to compute
* userclip positions in clip space, but is only called on
* _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values
- * uptodate across changes to the Transform attributes.
+ * up to date across changes to the Transform attributes.
*/
static void
update_projection( GLcontext *ctx )
{
- _math_matrix_analyse( &ctx->ProjectionMatrix );
+ _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
/* Recompute clip plane positions in clipspace. This is also done
* in _mesa_ClipPlane().
*/
- if (ctx->Transform._AnyClip) {
+ if (ctx->Transform.ClipPlanesEnabled) {
GLuint p;
for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
- if (ctx->Transform.ClipEnabled[p]) {
+ if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
_mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
ctx->Transform.EyeUserPlane[p],
- ctx->ProjectionMatrix.inv );
+ ctx->ProjectionMatrixStack.Top->inv );
}
}
}
if (ctx->Pixel.PostConvolutionColorTableEnabled)
mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
- if (ctx->ColorMatrix.type != MATRIX_IDENTITY ||
+ if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
ctx->Pixel.PostColorMatrixBias[0] != 0.0F ||
ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
{
GLuint i;
- ctx->_Enabled &= ~ENABLE_TEXMAT_ANY;
+ ctx->Texture._TexMatEnabled = 0;
for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
- if (ctx->TextureMatrix[i].flags & MAT_DIRTY) {
- _math_matrix_analyse( &ctx->TextureMatrix[i] );
-
- if (ctx->Driver.TextureMatrix)
- ctx->Driver.TextureMatrix( ctx, i, &ctx->TextureMatrix[i] );
+ if (ctx->TextureMatrixStack[i].Top->flags & MAT_DIRTY) {
+ _math_matrix_analyse( ctx->TextureMatrixStack[i].Top );
if (ctx->Texture.Unit[i]._ReallyEnabled &&
- ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
- ctx->_Enabled |= ENABLE_TEXMAT0 << i;
+ ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY)
+ ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i);
+
+ if (ctx->Driver.TextureMatrix)
+ ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top);
}
}
}
static void
update_texture_state( GLcontext *ctx )
{
- GLuint i;
+ GLuint unit;
- ctx->Texture._ReallyEnabled = 0;
+ ctx->Texture._EnabledUnits = 0;
ctx->Texture._GenFlags = 0;
ctx->_NeedNormals &= ~NEED_NORMALS_TEXGEN;
ctx->_NeedEyeCoords &= ~NEED_EYE_TEXGEN;
- ctx->_Enabled &= ~(ENABLE_TEXGEN_ANY |
- ENABLE_TEXMAT_ANY);
+ ctx->Texture._TexMatEnabled = 0;
+ ctx->Texture._TexGenEnabled = 0;
/* Update texture unit state.
*/
- for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
texUnit->_ReallyEnabled = 0;
texUnit->_GenFlags = 0;
if (!texUnit->Enabled)
continue;
- /* Find the texture of highest dimensionality that is enabled
- * and complete. We'll use it for texturing.
+ /* Look for the highest-priority texture target that's enabled and
+ * complete. That's the one we'll use for texturing.
*/
- if (texUnit->Enabled & TEXTURE0_CUBE) {
+ if (texUnit->Enabled & TEXTURE_CUBE_BIT) {
struct gl_texture_object *texObj = texUnit->CurrentCubeMap;
if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj);
}
if (texObj->Complete) {
- texUnit->_ReallyEnabled = TEXTURE0_CUBE;
+ texUnit->_ReallyEnabled = TEXTURE_CUBE_BIT;
texUnit->_Current = texObj;
}
}
- if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_3D)) {
+ if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_3D_BIT)) {
struct gl_texture_object *texObj = texUnit->Current3D;
if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj);
}
if (texObj->Complete) {
- texUnit->_ReallyEnabled = TEXTURE0_3D;
+ texUnit->_ReallyEnabled = TEXTURE_3D_BIT;
+ texUnit->_Current = texObj;
+ }
+ }
+
+ if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_RECT_BIT)) {
+ struct gl_texture_object *texObj = texUnit->CurrentRect;
+ if (!texObj->Complete) {
+ _mesa_test_texobj_completeness(ctx, texObj);
+ }
+ if (texObj->Complete) {
+ texUnit->_ReallyEnabled = TEXTURE_RECT_BIT;
texUnit->_Current = texObj;
}
}
- if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_2D)) {
+ if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_2D_BIT)) {
struct gl_texture_object *texObj = texUnit->Current2D;
if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj);
}
if (texObj->Complete) {
- texUnit->_ReallyEnabled = TEXTURE0_2D;
+ texUnit->_ReallyEnabled = TEXTURE_2D_BIT;
texUnit->_Current = texObj;
}
}
- if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_1D)) {
+ if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_1D_BIT)) {
struct gl_texture_object *texObj = texUnit->Current1D;
if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj);
}
if (texObj->Complete) {
- texUnit->_ReallyEnabled = TEXTURE0_1D;
+ texUnit->_ReallyEnabled = TEXTURE_1D_BIT;
texUnit->_Current = texObj;
}
}
continue;
}
- {
- GLuint flag = texUnit->_ReallyEnabled << (i * 4);
- ctx->Texture._ReallyEnabled |= flag;
- }
+ if (texUnit->_ReallyEnabled)
+ ctx->Texture._EnabledUnits |= (1 << unit);
if (texUnit->TexGenEnabled) {
if (texUnit->TexGenEnabled & S_BIT) {
texUnit->_GenFlags |= texUnit->_GenBitR;
}
- ctx->_Enabled |= ENABLE_TEXGEN0 << i;
+ ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
ctx->Texture._GenFlags |= texUnit->_GenFlags;
}
- if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
- ctx->_Enabled |= ENABLE_TEXMAT0 << i;
+ if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
+ ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
}
if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) {
}
+
/*
* If ctx->NewState is non-zero then this function MUST be called before
* rendering any primitive. Basically, function pointers and miscellaneous
const GLuint oldneedeyecoords = ctx->_NeedEyeCoords;
if (MESA_VERBOSE & VERBOSE_STATE)
- _mesa_print_state("", new_state);
+ _mesa_print_state("_mesa_update_state", new_state);
if (new_state & _NEW_MODELVIEW)
- _math_matrix_analyse( &ctx->ModelView );
+ _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
if (new_state & _NEW_PROJECTION)
update_projection( ctx );
update_texture_matrices( ctx );
if (new_state & _NEW_COLOR_MATRIX)
- _math_matrix_analyse( &ctx->ColorMatrix );
+ _math_matrix_analyse( ctx->ColorMatrixStack.Top );
/* References ColorMatrix.type (derived above).
*/
if (new_state & (_NEW_MODELVIEW|_NEW_LIGHT)) {
ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT_MODELVIEW;
if (ctx->Light.Enabled &&
- !TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
+ !TEST_MAT_FLAGS( ctx->ModelviewMatrixStack.Top, MAT_FLAGS_LENGTH_PRESERVING))
ctx->_NeedEyeCoords |= NEED_EYE_LIGHT_MODELVIEW;
}
+#if 0
+ /* XXX this is a bit of a hack. We should be checking elsewhere if
+ * vertex program mode is enabled. We set _NeedEyeCoords to zero to
+ * ensure that the combined modelview/projection matrix is computed
+ * in calculate_model_project_matrix().
+ */
+ if (ctx->VertexProgram.Enabled)
+ ctx->_NeedEyeCoords = 0;
+ /* KW: it's now always computed.
+ */
+#endif
+
+ /* Keep ModelviewProject uptodate always to allow tnl
+ * implementations that go model->clip even when eye is required.
+ */
+ if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
+ calculate_model_project_matrix(ctx);
+
/* ctx->_NeedEyeCoords is now uptodate.
*
* If the truth value of this variable has changed, update for the
* light positions & normal transforms for other reasons.
*/
if (new_state & (_NEW_MODELVIEW |
- _NEW_PROJECTION |
_NEW_LIGHT |
_MESA_NEW_NEED_EYE_COORDS))
update_tnl_spaces( ctx, oldneedeyecoords );
/* At this point we can do some assertions to be sure the required
* device driver function pointers are all initialized.
- *
- * KW: Moved the some of these asserts to t_vb_render.c, as they
- * are strictly only required for that stage. The Driver struct
- * should probably be split; the read/write span/pixels functions
- * should be referenced only from swrast, for instance.
*/
ASSERT(ctx->Driver.GetString);
ASSERT(ctx->Driver.UpdateState);
ASSERT(ctx->Driver.Clear);
- ASSERT(ctx->Driver.SetDrawBuffer);
ASSERT(ctx->Driver.GetBufferSize);
if (ctx->Visual.accumRedBits > 0) {
ASSERT(ctx->Driver.Accum);
ASSERT(ctx->Driver.ReadPixels);
ASSERT(ctx->Driver.CopyPixels);
ASSERT(ctx->Driver.Bitmap);
- ASSERT(ctx->Driver.ResizeBuffersMESA);
+ ASSERT(ctx->Driver.ResizeBuffers);
ASSERT(ctx->Driver.TexImage1D);
ASSERT(ctx->Driver.TexImage2D);
ASSERT(ctx->Driver.TexImage3D);
ASSERT(ctx->Driver.CopyTexSubImage2D);
ASSERT(ctx->Driver.CopyTexSubImage3D);
if (ctx->Extensions.ARB_texture_compression) {
+#if 0 /* HW drivers need these, but not SW rasterizers */
ASSERT(ctx->Driver.CompressedTexImage1D);
ASSERT(ctx->Driver.CompressedTexImage2D);
ASSERT(ctx->Driver.CompressedTexImage3D);
ASSERT(ctx->Driver.CompressedTexSubImage1D);
ASSERT(ctx->Driver.CompressedTexSubImage2D);
ASSERT(ctx->Driver.CompressedTexSubImage3D);
- ASSERT(ctx->Driver.IsCompressedFormat);
- ASSERT(ctx->Driver.GetCompressedTexImage);
- ASSERT(ctx->Driver.BaseCompressedTexFormat);
+#endif
}
}
+
+/* Is this helpful?
+ */
+void
+_mesa_allow_light_in_model( GLcontext *ctx, GLboolean flag )
+{
+ if (flag)
+ ctx->_NeedEyeCoords &= ~NEED_EYE_DRIVER;
+ else
+ ctx->_NeedEyeCoords |= NEED_EYE_DRIVER;
+
+ ctx->NewState |= _NEW_POINT; /* one of the bits from
+ * _MESA_NEW_NEED_EYE_COORDS.
+ */
+}