* 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 "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
#include "tnl/t_context.h"
#define HAVE_QUADS 0
#define HAVE_QUAD_STRIPS 0
-#define HAVE_ELTS 0 /* for now */
+#define HAVE_ELTS 1
#define LOCAL_VARS savageContextPtr imesa = SAVAGE_CONTEXT(ctx)
#define INIT( prim ) do { \
case GL_TRIANGLE_FAN: imesa->HwPrim = SAVAGE_PRIM_TRIFAN; break; \
} \
} while (0)
-#define FLUSH() savageFlushVertices(imesa)
+#define FLUSH() savageFlushElts(imesa), savageFlushVertices(imesa)
+
#define GET_CURRENT_VB_MAX_VERTS() \
((imesa->bufferSize/4 - imesa->vtxBuf->used) / imesa->HwVertexSize)
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
#define EMIT_VERTS( ctx, j, nr, buf ) \
_tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf )
+#define ELTS_VARS( buf ) GLushort *dest = buf, firstElt = imesa->firstElt
+#define ELT_INIT( prim ) INIT(prim)
+
+/* (size - used - 1 qword for drawing command) * 4 elts per qword */
+#define GET_CURRENT_VB_MAX_ELTS() \
+ ((imesa->cmdBuf.size - (imesa->cmdBuf.write - imesa->cmdBuf.base) - 1)*4)
+/* (size - space for initial state - 1 qword for drawing command) * 4 elts
+ * imesa is not defined in validate_render :( */
+#define GET_SUBSEQUENT_VB_MAX_ELTS() \
+ ((SAVAGE_CONTEXT(ctx)->cmdBuf.size - \
+ (SAVAGE_CONTEXT(ctx)->cmdBuf.start - \
+ SAVAGE_CONTEXT(ctx)->cmdBuf.base) - 1)*4)
+
+#define ALLOC_ELTS(nr) savageAllocElts(imesa, nr)
+#define EMIT_ELT(offset, x) do { \
+ (dest)[offset] = (GLushort) ((x)+firstElt); \
+} while (0)
+#define EMIT_TWO_ELTS(offset, x, y) do { \
+ *(GLuint *)(dest + offset) = (((y)+firstElt) << 16) | \
+ ((x)+firstElt); \
+} while (0)
+
+#define INCR_ELTS( nr ) dest += nr
+#define ELTPTR dest
+#define RELEASE_ELT_VERTS() \
+ savageReleaseIndexedVerts(imesa)
+
+#define EMIT_INDEXED_VERTS( ctx, start, count ) do { \
+ GLuint *buf = savageAllocIndexedVerts(imesa, count-start); \
+ EMIT_VERTS(ctx, start, count-start, buf); \
+} while (0)
+
#define TAG(x) savage_##x
#include "tnl_dd/t_dd_dmatmp.h"
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- tnl_render_func *tab;
+ tnl_render_func *tab, *tab_elts;
GLboolean valid;
GLuint i;
+ if (savageHaveIndexedVerts(imesa))
+ savageReleaseIndexedVerts(imesa);
+
if (imesa->savageScreen->chipset < S3_SAVAGE4 &&
(ctx->_TriangleCaps & DD_FLATSHADE)) {
tab = savage_flat_render_tab_verts_s3d;
+ tab_elts = savage_flat_render_tab_elts_s3d;
valid = savage_flat_validate_render_s3d( ctx, VB );
} else {
tab = savage_render_tab_verts;
+ tab_elts = savage_render_tab_elts;
valid = savage_validate_render( ctx, VB );
}
- /* Don't handle clipping or indexed vertices or vertex manipulations.
+ /* Don't handle clipping 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.
+ * Also check for ptex 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;
+
+ /* update and emit state */
savageDDUpdateHwState(ctx);
+ savageEmitChangedState(imesa);
+
+ if (VB->Elts) {
+ tab = tab_elts;
+ if (!savageHaveIndexedVerts(imesa)) {
+ if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS())
+ return GL_TRUE;
+ EMIT_INDEXED_VERTS(ctx, 0, VB->Count);
+ }
+ }
for (i = 0 ; i < VB->PrimitiveCount ; i++)
{
- GLuint prim = VB->Primitive[i].mode;
+ GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;
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 =
+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 */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
savage_run_render /* run */
};
/* Pipeline stage for texture coordinate normalization */
/**********************************************************************/
struct texnorm_stage_data {
+ GLboolean active;
GLvector4f texcoord[MAX_TEXTURE_UNITS];
};
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
- if (imesa->Fallback)
+ if (imesa->Fallback || !store->active)
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);
- }
+ const GLbitfield reallyEnabled = ctx->Texture.Unit[i]._ReallyEnabled;
+ if (reallyEnabled) {
+ const struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
+ const GLboolean normalizeS = (texObj->WrapS == GL_REPEAT);
+ const GLboolean normalizeT = (reallyEnabled & TEXTURE_2D_BIT) &&
+ (texObj->WrapT == GL_REPEAT);
+ const GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;
+ const GLint instride = VB->TexCoordPtr[i]->stride;
+ GLfloat (*out)[4] = store->texcoord[i].data;
+ GLint j;
+
+ if (!ctx->Texture.Unit[i]._ReallyEnabled ||
+ VB->TexCoordPtr[i]->size == 4)
+ /* Never try to normalize homogenous tex coords! */
+ continue;
+
+ 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];
}
-
- if (normalizeS || normalizeT)
- VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i];
}
return GL_TRUE;
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 );
+
+ return GL_TRUE;
}
-static void check_texnorm( GLcontext *ctx,
- struct tnl_pipeline_stage *stage )
+static void validate_texnorm( GLcontext *ctx,
+ struct tnl_pipeline_stage *stage )
{
+ struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage);
GLuint flags = 0;
if (((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|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);
+ store->active = (flags != 0);
}
static void free_texnorm_data( struct tnl_pipeline_stage *stage )
}
}
-const struct tnl_pipeline_stage _savage_texnorm_stage =
+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 */
+ free_texnorm_data, /* destructor */
+ validate_texnorm,
+ run_texnorm_stage
};