mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
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.
This commit is contained in:
parent
ca710a0a7f
commit
ad360a81bd
5 changed files with 375 additions and 173 deletions
|
|
@ -24,6 +24,7 @@ DRIVER_SOURCES = \
|
|||
savagestate.c \
|
||||
savagetex.c \
|
||||
savagetris.c \
|
||||
savagerender.c \
|
||||
savageioctl.c \
|
||||
savagespan.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;
|
||||
|
||||
|
|
|
|||
356
src/mesa/drivers/dri/savage/savagerender.c
Normal file
356
src/mesa/drivers/dri/savage/savagerender.c
Normal file
|
|
@ -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 */
|
||||
};
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue