From ad360a81bdc9076cc09f9241176116efdbba43e4 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Sun, 16 Jan 2005 01:28:26 +0000 Subject: [PATCH] Added a fast path for emitting unclipped primitives directly to a vertex buffer. ELTS are not supported yet (missing functionality in the DRM). You need at least Savage DRM version 2.1.3, which fixes a bug that screwed up triangle fans and strips. Moved the texture normalization stage to savagerender.c. --- src/mesa/drivers/dri/savage/Makefile | 1 + src/mesa/drivers/dri/savage/savage_xmesa.c | 6 +- src/mesa/drivers/dri/savage/savagerender.c | 356 +++++++++++++++++++++ src/mesa/drivers/dri/savage/savagestate.c | 2 +- src/mesa/drivers/dri/savage/savagetris.c | 183 +---------- 5 files changed, 375 insertions(+), 173 deletions(-) create mode 100644 src/mesa/drivers/dri/savage/savagerender.c diff --git a/src/mesa/drivers/dri/savage/Makefile b/src/mesa/drivers/dri/savage/Makefile index 181556318fb..204c3b03cba 100644 --- a/src/mesa/drivers/dri/savage/Makefile +++ b/src/mesa/drivers/dri/savage/Makefile @@ -24,6 +24,7 @@ DRIVER_SOURCES = \ savagestate.c \ savagetex.c \ savagetris.c \ + savagerender.c \ savageioctl.c \ savagespan.c diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index a1c5142d4ff..9a8e090ab51 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -110,6 +110,7 @@ static const char *const card_extensions[] = }; extern const struct tnl_pipeline_stage _savage_texnorm_stage; +extern const struct tnl_pipeline_stage _savage_render_stage; static const struct tnl_pipeline_stage *savage_pipeline[] = { @@ -120,6 +121,7 @@ static const struct tnl_pipeline_stage *savage_pipeline[] = { &_tnl_texgen_stage, &_tnl_texture_transform_stage, &_savage_texnorm_stage, + &_savage_render_stage, &_tnl_render_stage, 0, }; @@ -426,10 +428,10 @@ savageCreateContext( const __GLcontextModes *mesaVis, imesa->dmaVtxBuf.used = 0; imesa->dmaVtxBuf.flushed = 0; - imesa->clientVtxBuf.total = 16384; + imesa->clientVtxBuf.total = imesa->bufferSize / 4; imesa->clientVtxBuf.used = 0; imesa->clientVtxBuf.flushed = 0; - imesa->clientVtxBuf.buf = (u_int32_t *)malloc(16384*4); + imesa->clientVtxBuf.buf = (u_int32_t *)malloc(imesa->bufferSize); imesa->vtxBuf = &imesa->clientVtxBuf; diff --git a/src/mesa/drivers/dri/savage/savagerender.c b/src/mesa/drivers/dri/savage/savagerender.c new file mode 100644 index 00000000000..50ec9eac685 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagerender.c @@ -0,0 +1,356 @@ +/* + * Copyright 2005 Felix Kuehling + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING 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. + */ + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Simulate missing primitives with indexed vertices. + */ +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" + +#include "tnl/t_context.h" + +#include "savagecontext.h" +#include "savagetris.h" +#include "savagestate.h" +#include "savageioctl.h" + +/* + * Standard render tab for Savage4 and smooth shading on Savage3D + */ +#define HAVE_POINTS 0 +#define HAVE_LINES 0 +#define HAVE_LINE_STRIPS 0 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 +#define HAVE_TRI_FANS 1 +#define HAVE_POLYGONS 0 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 + +#define HAVE_ELTS 0 /* for now */ + +#define LOCAL_VARS savageContextPtr imesa = SAVAGE_CONTEXT(ctx) +#define INIT( prim ) do { \ + if (0) fprintf(stderr, "%s\n", __FUNCTION__); \ + savageFlushVertices(imesa); \ + switch (prim) { \ + case GL_TRIANGLES: imesa->HwPrim = SAVAGE_PRIM_TRILIST; break; \ + case GL_TRIANGLE_STRIP: imesa->HwPrim = SAVAGE_PRIM_TRISTRIP; break; \ + case GL_TRIANGLE_FAN: imesa->HwPrim = SAVAGE_PRIM_TRIFAN; break; \ + } \ +} while (0) +#define FLUSH() savageFlushVertices(imesa) +#define GET_CURRENT_VB_MAX_VERTS() \ + ((imesa->bufferSize/4 - imesa->vtxBuf->used) / imesa->HwVertexSize) +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ + (imesa->bufferSize/4 / imesa->HwVertexSize) + +#define ALLOC_VERTS( nr ) \ + savageAllocVtxBuf( imesa, (nr) * imesa->HwVertexSize ) +#define EMIT_VERTS( ctx, j, nr, buf ) \ + _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf ) + +#define TAG(x) savage_##x +#include "tnl_dd/t_dd_dmatmp.h" + +/* + * On Savage3D triangle fans and strips are broken with flat + * shading. With triangles it wants the color for flat shading in the + * first vertex! So we make another template instance which uses + * triangles only (with reordered vertices: SAVAGE_PRIM_TRILIST_201). + * The reordering is done by the DRM. + */ +#undef HAVE_TRI_STRIPS +#undef HAVE_TRI_FANS +#define HAVE_TRI_STRIPS 0 +#define HAVE_TRI_FANS 0 + +#undef INIT +#define INIT( prim ) do { \ + if (0) fprintf(stderr, "%s\n", __FUNCTION__); \ + savageFlushVertices(imesa); \ + imesa->HwPrim = SAVAGE_PRIM_TRILIST_201; \ +} while(0) + +#undef TAG +#define TAG(x) savage_flat_##x##_s3d +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + +static GLboolean savage_run_render( GLcontext *ctx, + struct tnl_pipeline_stage *stage ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + tnl_render_func *tab; + GLboolean valid; + GLuint i; + + if (imesa->savageScreen->chipset < S3_SAVAGE4 && + (ctx->_TriangleCaps & DD_FLATSHADE)) { + tab = savage_flat_render_tab_verts_s3d; + valid = savage_flat_validate_render_s3d( ctx, VB ); + } else { + tab = savage_render_tab_verts; + valid = savage_validate_render( ctx, VB ); + } + + /* Don't handle clipping or indexed vertices or vertex manipulations. + */ + if (imesa->RenderIndex != 0 || !valid) { + return GL_TRUE; + } + + tnl->Driver.Render.Start( ctx ); + /* Check RenderIndex again. The ptexHack is detected late in RenderStart. + * Also check for fallbacks detected late. + */ + if (imesa->RenderIndex != 0 || imesa->Fallback != 0) { + return GL_TRUE; + } + + /* setup for hardware culling */ + imesa->raster_primitive = GL_TRIANGLES; + imesa->new_state |= SAVAGE_NEW_CULL; + savageDDUpdateHwState(ctx); + + for (i = 0 ; i < VB->PrimitiveCount ; i++) + { + GLuint prim = VB->Primitive[i].mode; + GLuint start = VB->Primitive[i].start; + GLuint length = VB->Primitive[i].count; + + if (length) + tab[prim & PRIM_MODE_MASK]( ctx, start, start+length, prim); + } + + tnl->Driver.Render.Finish( ctx ); + + return GL_FALSE; /* finished the pipe */ +} + +static void savage_check_render( GLcontext *ctx, + struct tnl_pipeline_stage *stage ) +{ + __DRIscreenPrivate *driScrnPriv = + SAVAGE_CONTEXT(ctx)->savageScreen->driScrnPriv; + stage->inputs = TNL_CONTEXT(ctx)->render_inputs; + /* This hack will go away when we depend on 2.2.x for ELTS. */ + if (driScrnPriv->drmMinor <= 1 && driScrnPriv->drmPatch < 3) { + static GLboolean firstTime = GL_TRUE; + stage->active = GL_FALSE; + if (firstTime) { + fprintf (stderr, + "*** Disabling fast path because your DRM version is buggy.\n" + "*** You need at least Savage DRM version 2.1.3.\n"); + firstTime = GL_FALSE; + } + } +} + +static void dtr( struct tnl_pipeline_stage *stage ) +{ + (void)stage; +} + +const struct tnl_pipeline_stage _savage_render_stage = +{ + "savage render", + (_DD_NEW_SEPARATE_SPECULAR | + _NEW_TEXTURE| + _NEW_FOG| + _NEW_RENDERMODE), /* re-check (new inputs) */ + 0, /* re-run (always runs) */ + GL_TRUE, /* active */ + 0, 0, /* inputs (set in check_render), outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + savage_check_render, /* check - initially set to alloc data */ + savage_run_render /* run */ +}; + + +/**********************************************************************/ +/* Pipeline stage for texture coordinate normalization */ +/**********************************************************************/ +struct texnorm_stage_data { + GLvector4f texcoord[MAX_TEXTURE_UNITS]; +}; + +#define TEXNORM_STAGE_DATA(stage) ((struct texnorm_stage_data *)stage->privatePtr) + + +static GLboolean run_texnorm_stage( GLcontext *ctx, + struct tnl_pipeline_stage *stage ) +{ + struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage); + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + + if (imesa->Fallback) + return GL_TRUE; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (!(stage->inputs & stage->changed_inputs & VERT_BIT_TEX(i)) || + VB->TexCoordPtr[i]->size == 4) + /* Never try to normalize homogenous tex coords! */ + continue; + + GLuint reallyEnabled = ctx->Texture.Unit[i]._ReallyEnabled; + struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; + GLboolean normalizeS = (texObj->WrapS == GL_REPEAT); + GLboolean normalizeT = (reallyEnabled & TEXTURE_2D_BIT) && + (texObj->WrapT == GL_REPEAT); + GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data; + GLint instride = VB->TexCoordPtr[i]->stride; + GLfloat (*out)[4] = store->texcoord[i].data; + GLint j; + + if (normalizeS && normalizeT) { + /* take first texcoords as rough estimate of mean value */ + GLfloat correctionS = -floor(in[0]+0.5); + GLfloat correctionT = -floor(in[1]+0.5); + for (j = 0; j < VB->Count; ++j) { + out[j][0] = in[0] + correctionS; + out[j][1] = in[1] + correctionT; + in = (GLfloat *)((GLubyte *)in + instride); + } + } else if (normalizeS) { + /* take first texcoords as rough estimate of mean value */ + GLfloat correctionS = -floor(in[0]+0.5); + if (reallyEnabled & TEXTURE_2D_BIT) { + for (j = 0; j < VB->Count; ++j) { + out[j][0] = in[0] + correctionS; + out[j][1] = in[1]; + in = (GLfloat *)((GLubyte *)in + instride); + } + } else { + for (j = 0; j < VB->Count; ++j) { + out[j][0] = in[0] + correctionS; + in = (GLfloat *)((GLubyte *)in + instride); + } + } + } else if (normalizeT) { + /* take first texcoords as rough estimate of mean value */ + GLfloat correctionT = -floor(in[1]+0.5); + for (j = 0; j < VB->Count; ++j) { + out[j][0] = in[0]; + out[j][1] = in[1] + correctionT; + in = (GLfloat *)((GLubyte *)in + instride); + } + } + + if (normalizeS || normalizeT) + VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i]; + } + + return GL_TRUE; +} + +/* Called the first time stage->run() is invoked. + */ +static GLboolean alloc_texnorm_data( GLcontext *ctx, + struct tnl_pipeline_stage *stage ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct texnorm_stage_data *store; + GLuint i; + + stage->privatePtr = CALLOC(sizeof(*store)); + store = TEXNORM_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 ); + + /* Now run the stage. + */ + stage->run = run_texnorm_stage; + return stage->run( ctx, stage ); +} + +static void check_texnorm( GLcontext *ctx, + struct tnl_pipeline_stage *stage ) +{ + GLuint flags = 0; + + if (((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) && + (ctx->Texture.Unit[0]._Current->WrapS == GL_REPEAT)) || + ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) && + (ctx->Texture.Unit[0]._Current->WrapT == GL_REPEAT))) + flags |= VERT_BIT_TEX0; + + if (((ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) && + (ctx->Texture.Unit[1]._Current->WrapS == GL_REPEAT)) || + ((ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) && + (ctx->Texture.Unit[1]._Current->WrapT == GL_REPEAT))) + flags |= VERT_BIT_TEX1; + + stage->inputs = flags; + stage->outputs = flags; + stage->active = (flags != 0); +} + +static void free_texnorm_data( struct tnl_pipeline_stage *stage ) +{ + struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage); + GLuint i; + + if (store) { + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) + if (store->texcoord[i].data) + _mesa_vector4f_free( &store->texcoord[i] ); + FREE( store ); + stage->privatePtr = 0; + } +} + +const struct tnl_pipeline_stage _savage_texnorm_stage = +{ + "savage texture coordinate normalization stage", /* name */ + _NEW_TEXTURE, /* check_state */ + _NEW_TEXTURE, /* run_state */ + GL_TRUE, /* active? */ + 0, /* inputs */ + 0, /* outputs */ + 0, /* changed_inputs */ + NULL, /* private data */ + free_texnorm_data, /* destructor */ + check_texnorm, /* check */ + alloc_texnorm_data, /* run -- initially set to init */ +}; diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index b57fa39dd8d..2b512c11410 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -825,7 +825,7 @@ static void savageUpdateCull( GLcontext *ctx ) savageContextPtr imesa = SAVAGE_CONTEXT(ctx); GLuint cullMode; if (ctx->Polygon.CullFlag && - imesa->raster_primitive == GL_TRIANGLES && + imesa->raster_primitive >= GL_TRIANGLES && ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) cullMode = imesa->LcsCullMode; else diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c index 382eccc82c8..0092f3ea770 100644 --- a/src/mesa/drivers/dri/savage/savagetris.c +++ b/src/mesa/drivers/dri/savage/savagetris.c @@ -762,16 +762,6 @@ static void savageChooseRenderState(GLcontext *ctx) imesa->RenderIndex = index; } - - if (imesa->savageScreen->chipset < S3_SAVAGE4 && (flags & DD_FLATSHADE)) { - if (imesa->HwPrim != SAVAGE_PRIM_TRILIST_201) - savageFlushVertices(imesa); - imesa->HwPrim = SAVAGE_PRIM_TRILIST_201; - } else { - if (imesa->HwPrim != SAVAGE_PRIM_TRILIST) - savageFlushVertices(imesa); - imesa->HwPrim = SAVAGE_PRIM_TRILIST; - } } /**********************************************************************/ @@ -788,10 +778,22 @@ static void savageRunPipeline( GLcontext *ctx ) if (imesa->new_state) savageDDUpdateHwState( ctx ); - if (!imesa->Fallback && imesa->new_gl_state) { + if (!imesa->Fallback) { if (imesa->new_gl_state & _SAVAGE_NEW_RENDER_STATE) savageChooseRenderState( ctx ); + /* choose the correct primitive type for tnl rendering */ + if (imesa->savageScreen->chipset < S3_SAVAGE4 && + (ctx->_TriangleCaps & DD_FLATSHADE)) { + if (imesa->HwPrim != SAVAGE_PRIM_TRILIST_201) + savageFlushVertices(imesa); + imesa->HwPrim = SAVAGE_PRIM_TRILIST_201; + } else { + if (imesa->HwPrim != SAVAGE_PRIM_TRILIST) + savageFlushVertices(imesa); + imesa->HwPrim = SAVAGE_PRIM_TRILIST; + } + imesa->new_gl_state = 0; } @@ -1288,162 +1290,3 @@ void savageInitTriFuncs( GLcontext *ctx ) SAVAGE_CONTEXT(ctx)->verts = (char *)tnl->clipspace.vertex_buf; } - - -/*** - * Pipeline stage for texture coordinate normalization - * This should probably go somewhere else. - ***/ -struct texnorm_stage_data { - GLvector4f texcoord[MAX_TEXTURE_UNITS]; -}; - -#define TEXNORM_STAGE_DATA(stage) ((struct texnorm_stage_data *)stage->privatePtr) - - -static GLboolean run_texnorm_stage( GLcontext *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage); - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint i; - - if (imesa->Fallback) - return GL_TRUE; - - for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { - if (!(stage->inputs & stage->changed_inputs & VERT_BIT_TEX(i)) || - VB->TexCoordPtr[i]->size == 4) - /* Never try to normalize homogenous tex coords! */ - continue; - - GLuint reallyEnabled = ctx->Texture.Unit[i]._ReallyEnabled; - struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; - GLboolean normalizeS = (texObj->WrapS == GL_REPEAT); - GLboolean normalizeT = (reallyEnabled & TEXTURE_2D_BIT) && - (texObj->WrapT == GL_REPEAT); - GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data; - GLint instride = VB->TexCoordPtr[i]->stride; - GLfloat (*out)[4] = store->texcoord[i].data; - GLint j; - - if (normalizeS && normalizeT) { - /* take first texcoords as rough estimate of mean value */ - GLfloat correctionS = -floor(in[0]+0.5); - GLfloat correctionT = -floor(in[1]+0.5); - for (j = 0; j < VB->Count; ++j) { - out[j][0] = in[0] + correctionS; - out[j][1] = in[1] + correctionT; - in = (GLfloat *)((GLubyte *)in + instride); - } - } else if (normalizeS) { - /* take first texcoords as rough estimate of mean value */ - GLfloat correctionS = -floor(in[0]+0.5); - if (reallyEnabled & TEXTURE_2D_BIT) { - for (j = 0; j < VB->Count; ++j) { - out[j][0] = in[0] + correctionS; - out[j][1] = in[1]; - in = (GLfloat *)((GLubyte *)in + instride); - } - } else { - for (j = 0; j < VB->Count; ++j) { - out[j][0] = in[0] + correctionS; - in = (GLfloat *)((GLubyte *)in + instride); - } - } - } else if (normalizeT) { - /* take first texcoords as rough estimate of mean value */ - GLfloat correctionT = -floor(in[1]+0.5); - for (j = 0; j < VB->Count; ++j) { - out[j][0] = in[0]; - out[j][1] = in[1] + correctionT; - in = (GLfloat *)((GLubyte *)in + instride); - } - } - - if (normalizeS || normalizeT) - VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i]; - } - - return GL_TRUE; -} - - -/* Called the first time stage->run() is invoked. - */ -static GLboolean alloc_texnorm_data( GLcontext *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct texnorm_stage_data *store; - GLuint i; - - stage->privatePtr = CALLOC(sizeof(*store)); - store = TEXNORM_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) - _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 ); - - /* Now run the stage. - */ - stage->run = run_texnorm_stage; - return stage->run( ctx, stage ); -} - - -static void check_texnorm( GLcontext *ctx, - struct tnl_pipeline_stage *stage ) -{ - GLuint flags = 0; - - if (((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) && - (ctx->Texture.Unit[0]._Current->WrapS == GL_REPEAT)) || - ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) && - (ctx->Texture.Unit[0]._Current->WrapT == GL_REPEAT))) - flags |= VERT_BIT_TEX0; - - if (((ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) && - (ctx->Texture.Unit[1]._Current->WrapS == GL_REPEAT)) || - ((ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) && - (ctx->Texture.Unit[1]._Current->WrapT == GL_REPEAT))) - flags |= VERT_BIT_TEX1; - - stage->inputs = flags; - stage->outputs = flags; - stage->active = (flags != 0); -} - - -static void free_texnorm_data( struct tnl_pipeline_stage *stage ) -{ - struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage); - GLuint i; - - if (store) { - for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) - if (store->texcoord[i].data) - _mesa_vector4f_free( &store->texcoord[i] ); - FREE( store ); - stage->privatePtr = 0; - } -} - - -const struct tnl_pipeline_stage _savage_texnorm_stage = -{ - "savage texture coordinate normalization stage", /* name */ - _NEW_TEXTURE, /* check_state */ - _NEW_TEXTURE, /* run_state */ - GL_TRUE, /* active? */ - 0, /* inputs */ - 0, /* outputs */ - 0, /* changed_inputs */ - NULL, /* private data */ - free_texnorm_data, /* destructor */ - check_texnorm, /* check */ - alloc_texnorm_data, /* run -- initially set to init */ -}; -- 2.30.2