Large update

- Remove via duplicates of shared template files
	- Update driver to work with current versions of the above
	- Rework dma accounting
	- Rework emitting to dma to use a consistent set of macros

The handling of cliprects in the driver is still pretty questionable.
This commit is contained in:
Keith Whitwell 2004-12-29 12:39:50 +00:00
parent 7b05b70c2a
commit 13ae06cf36
20 changed files with 1131 additions and 4331 deletions

View file

@ -303,9 +303,8 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
/* REMOVE: point attenuation stage */
#if 1
#if 0
&_via_fastrender_stage, /* ADD: unclipped rastersetup-to-dma */
&_via_render_stage, /* ADD: modification from _tnl_render_stage */
#endif
&_tnl_render_stage,
0,
@ -315,6 +314,8 @@ static const struct tnl_pipeline_stage *via_pipeline[] = {
static GLboolean
AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa)
{
GLuint *addr;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (vmesa->dma)
via_free_dma_buffer(vmesa);
@ -329,24 +330,24 @@ AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa)
return GL_FALSE;
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
return GL_TRUE;
}
static void
InitVertexBuffer(viaContextPtr vmesa)
{
GLuint *addr;
/* Insert placeholder for a cliprect:
*/
addr = (GLuint *)vmesa->dma;
*addr = 0xF210F110;
*addr = (HC_ParaType_NotTex << 16);
*addr = 0xcccccccc;
*addr = 0xdddddddd;
addr[0] = HC_HEADER2;
addr[1] = (HC_ParaType_NotTex << 16);
addr[2] = HC_DUMMY;
addr[3] = HC_DUMMY;
addr[4] = HC_DUMMY;
addr[5] = HC_DUMMY;
addr[6] = HC_DUMMY;
addr[7] = HC_DUMMY;
vmesa->dmaLow = DMA_OFFSET;
vmesa->dmaHigh = VIA_DMA_BUFSIZ;
vmesa->dmaAddr = (unsigned char *)vmesa->dma;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
return GL_TRUE;
}
static void
@ -404,6 +405,7 @@ viaCreateContext(const __GLcontextModes *mesaVis,
case 0:
vmesa->hasDepth = GL_FALSE;
vmesa->depthBits = 0;
vmesa->depth_max = 1.0;
break;
case 16:
vmesa->hasDepth = GL_TRUE;
@ -522,7 +524,6 @@ viaCreateContext(const __GLcontextModes *mesaVis,
vmesa->texHeap = mmInit(0, viaScreen->textureSize);
vmesa->stippleInHw = 1;
vmesa->renderIndex = ~0;
vmesa->needUploadAllState = 1;
make_empty_list(&vmesa->TexObjList);
make_empty_list(&vmesa->SwappedOut);
@ -532,7 +533,15 @@ viaCreateContext(const __GLcontextModes *mesaVis,
_math_matrix_ctr(&vmesa->ViewportMatrix);
driInitExtensions( ctx, card_extensions, GL_TRUE );
/* Do this early, before VIA_FLUSH_DMA can be called:
*/
if (!AllocateDmaBuffer(mesaVis, vmesa)) {
fprintf(stderr ,"AllocateDmaBuffer fail\n");
FREE(vmesa);
return GL_FALSE;
}
driInitExtensions( ctx, card_extensions, GL_TRUE );
viaInitStateFuncs(ctx);
viaInitTextures(ctx);
viaInitTriFuncs(ctx);
@ -571,14 +580,6 @@ viaCreateContext(const __GLcontextModes *mesaVis,
(*vmesa->get_ust)( & vmesa->swap_ust );
if (!AllocateDmaBuffer(mesaVis, vmesa)) {
fprintf(stderr ,"AllocateDmaBuffer fail\n");
FREE(vmesa);
return GL_FALSE;
}
InitVertexBuffer(vmesa);
vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg);
vmesa->pnGEMode = (GLuint *)((GLuint)viaScreen->reg + 0x4);
vmesa->regEngineStatus = (GLuint *)((GLuint)viaScreen->reg + 0x400);
@ -599,7 +600,6 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv)
viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
assert(vmesa); /* should never be null */
/* viaFlushPrimsLocked(vmesa); */
if (vmesa) {
/*=* John Sheng [2003.5.31] agp tex *=*/
@ -756,7 +756,7 @@ void viaGetLock(viaContextPtr vmesa, GLuint flags)
if (sarea->ctxOwner != me) {
sarea->ctxOwner = me;
vmesa->needUploadAllState = 1;
vmesa->newState = ~0;
}
viaXMesaWindowMoved(vmesa);
@ -785,7 +785,7 @@ viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
}
}
else
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
}
else {
_mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");

View file

@ -53,6 +53,7 @@ typedef struct via_texture_object_t *viaTextureObjectPtr;
#define VIA_FALLBACK_USER_DISABLE 0x800
#define VIA_DMA_BUFSIZ 500000
#define VIA_DMA_HIGHWATER (VIA_DMA_BUFSIZ - 256)
/* Use the templated vertex formats:
*/
@ -60,14 +61,6 @@ typedef struct via_texture_object_t *viaTextureObjectPtr;
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
#define RightOf 1
#define LeftOf 2
#define Down 4
#define Up 8
#define S0 16
#define S1 32
#define P_MASK 0x0f;
#define S_MASK 0x30;
typedef void (*via_tri_func)(viaContextPtr, viaVertex *, viaVertex *,
viaVertex *);
typedef void (*via_line_func)(viaContextPtr, viaVertex *, viaVertex *);
@ -121,11 +114,6 @@ struct via_context_t {
*/
GLuint Fallback;
/* Temporaries for translating away float colors:
*/
struct gl_client_array UbyteColor;
struct gl_client_array UbyteSecondaryColor;
/* State for via_vb.c and via_tris.c.
*/
GLuint newState; /* _NEW_* flags */
@ -134,21 +122,16 @@ struct via_context_t {
GLuint renderIndex;
GLmatrix ViewportMatrix;
GLenum renderPrimitive;
GLenum reducedPrimitive;
GLuint hwPrimitive;
GLenum hwPrimitive;
unsigned char *verts;
/* drmBufPtr dma_buffer;
*/
unsigned char* dmaAddr;
GLuint dmaLow;
GLuint dmaHigh;
GLuint dmaLastPrim;
GLboolean useAgp;
GLuint needUploadAllState;
GLuint primitiveRendered;
/* Fallback rasterization functions
*/
@ -217,7 +200,7 @@ struct via_context_t {
*/
GLuint dirty;
int vertexSize;
int vertexStrideShift;
int vertexFormat;
GLint lastStamp;
GLboolean stippleInHw;
@ -289,8 +272,7 @@ struct via_context_t {
PFNGLXGETUSTPROC get_ust;
};
/*#define DMA_OFFSET 16*/
#define DMA_OFFSET 32
#define VIA_CONTEXT(ctx) ((viaContextPtr)(ctx->DriverCtx))

View file

@ -1,705 +0,0 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, 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, 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
*/
#if HAVE_RGBA
#define VERT_SET_IND(v, c) (void)c
#define VERT_COPY_IND(v0, v1)
#define VERT_SAVE_IND(idx)
#define VERT_RESTORE_IND(idx)
#if HAVE_BACK_COLORS
#define VERT_SET_RGBA(v, c)
#endif
#else
#define VERT_SET_RGBA(v, c) (void)c
#define VERT_COPY_RGBA(v0, v1)
#define VERT_SAVE_RGBA(idx)
#define VERT_RESTORE_RGBA(idx)
#if HAVE_BACK_COLORS
#define VERT_SET_IND(v, c)
#endif
#endif
#if !HAVE_SPEC
#define VERT_SET_SPEC(v, c) (void)c
#define VERT_COPY_SPEC(v0, v1)
#define VERT_SAVE_SPEC(idx)
#define VERT_RESTORE_SPEC(idx)
#if HAVE_BACK_COLORS
#define VERT_COPY_SPEC1(v)
#endif
#else
#if HAVE_BACK_COLORS
#define VERT_SET_SPEC(v, c)
#endif
#endif
#if !HAVE_BACK_COLORS
#define VERT_COPY_SPEC1(v)
#define VERT_COPY_IND1(v)
#define VERT_COPY_RGBA1(v)
#endif
#ifndef INSANE_VERTICES
#define VERT_SET_Z(v, val) VERT_Z(v) = val
#define VERT_Z_ADD(v, val) VERT_Z(v) += val
#endif
#if DO_TRI
static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2)
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
VERTEX *v[3];
GLfloat offset;
GLfloat z[3];
GLenum mode = GL_FILL;
GLuint facing;
LOCAL_VARS(3);
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
v[0] = (VERTEX *)GET_VERTEX(e0);
v[1] = (VERTEX *)GET_VERTEX(e1);
v[2] = (VERTEX *)GET_VERTEX(e2);
if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) {
GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
GLfloat cc = ex * fy - ey * fx;
if (DO_TWOSIDE || DO_UNFILLED) {
facing = AREA_IS_CCW(cc) ^ ctx->Polygon._FrontBit;
if (DO_UNFILLED) {
if (facing) {
mode = ctx->Polygon.BackMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode != GL_FRONT) {
return;
}
}
else {
mode = ctx->Polygon.FrontMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode != GL_BACK) {
return;
}
}
}
if (DO_TWOSIDE && facing == 1) {
if (HAVE_RGBA) {
if (HAVE_BACK_COLORS) {
if (!DO_FLAT) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_COPY_RGBA1(v[0]);
VERT_COPY_RGBA1(v[1]);
}
VERT_SAVE_RGBA(2);
VERT_COPY_RGBA1(v[2]);
if (HAVE_SPEC) {
if (!DO_FLAT) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_COPY_SPEC1(v[0]);
VERT_COPY_SPEC1(v[1]);
}
VERT_SAVE_SPEC(2);
VERT_COPY_SPEC1(v[2]);
}
}
else {
GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
(void)vbcolor;
if (!DO_FLAT) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_SET_RGBA(v[0], vbcolor[e0]);
VERT_SET_RGBA(v[1], vbcolor[e1]);
}
VERT_SAVE_RGBA(2);
VERT_SET_RGBA(v[2], vbcolor[e2]);
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
if (!DO_FLAT) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_SET_SPEC(v[0], vbspec[e0]);
VERT_SET_SPEC(v[1], vbspec[e1]);
}
VERT_SAVE_SPEC(2);
VERT_SET_SPEC(v[2], vbspec[e2]);
}
}
}
else {
GLfloat *vbindex = (GLfloat*) VB->IndexPtr[1]->data;
if (!DO_FLAT) {
VERT_SAVE_IND( 0 );
VERT_SAVE_IND( 1 );
VERT_SET_IND(v[0], vbindex[e0]);
VERT_SET_IND(v[1], vbindex[e1]);
}
VERT_SAVE_IND( 2 );
VERT_SET_IND(v[2], vbindex[e2]);
}
}
}
if (DO_OFFSET) {
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
z[0] = VERT_Z(v[0]);
z[1] = VERT_Z(v[1]);
z[2] = VERT_Z(v[2]);
if (cc * cc > 1e-16) {
GLfloat ic = 1.0 / cc;
GLfloat ez = z[0] - z[2];
GLfloat fz = z[1] - z[2];
GLfloat a = ey * fz - ez * fy;
GLfloat b = ez * fx - ex * fz;
GLfloat ac = a * ic;
GLfloat bc = b * ic;
if (ac < 0.0f) ac = -ac;
if (bc < 0.0f) bc = -bc;
offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
}
offset *= ctx->MRD;
}
}
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_COPY_RGBA(v[0], v[2]);
VERT_COPY_RGBA(v[1], v[2]);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_COPY_SPEC(v[0], v[2]);
VERT_COPY_SPEC(v[1], v[2]);
}
}
else {
VERT_SAVE_IND(0);
VERT_SAVE_IND(1);
VERT_COPY_IND(v[0], v[2]);
VERT_COPY_IND(v[1], v[2]);
}
}
if (mode == GL_POINT) {
if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
}
UNFILLED_TRI(ctx, GL_POINT, e0, e1, e2);
}
else if (mode == GL_LINE) {
if (DO_OFFSET && ctx->Polygon.OffsetLine) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
}
UNFILLED_TRI(ctx, GL_LINE, e0, e1, e2);
}
else {
if (DO_OFFSET && ctx->Polygon.OffsetFill) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
}
if (DO_UNFILLED)
RASTERIZE(GL_TRIANGLES);
TRI(v[0], v[1], v[2]);
}
if (DO_OFFSET) {
VERT_SET_Z(v[0], z[0]);
VERT_SET_Z(v[1], z[1]);
VERT_SET_Z(v[2], z[2]);
}
if (DO_TWOSIDE && facing == 1) {
if (HAVE_RGBA) {
if (!DO_FLAT) {
VERT_RESTORE_RGBA(0);
VERT_RESTORE_RGBA(1);
}
VERT_RESTORE_RGBA(2);
if (HAVE_SPEC) {
if (!DO_FLAT) {
VERT_RESTORE_SPEC(0);
VERT_RESTORE_SPEC(1);
}
VERT_RESTORE_SPEC(2);
}
}
else {
if (!DO_FLAT) {
VERT_RESTORE_IND( 0 );
VERT_RESTORE_IND( 1 );
}
VERT_RESTORE_IND( 2 );
}
}
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_RESTORE_RGBA(0);
VERT_RESTORE_RGBA(1);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_RESTORE_SPEC(0);
VERT_RESTORE_SPEC(1);
}
}
else {
VERT_RESTORE_IND(0);
VERT_RESTORE_IND(1);
}
}
SET_PRIMITIVE_RENDERED
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#endif
#if DO_QUAD
#if DO_FULL_QUAD
static void TAG(quad)(GLcontext *ctx,
GLuint e0, GLuint e1, GLuint e2, GLuint e3)
{
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
VERTEX *v[4];
GLfloat offset;
GLfloat z[4];
GLenum mode = GL_FILL;
GLuint facing;
LOCAL_VARS(4);
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
v[0] = (VERTEX *)GET_VERTEX(e0);
v[1] = (VERTEX *)GET_VERTEX(e1);
v[2] = (VERTEX *)GET_VERTEX(e2);
v[3] = (VERTEX *)GET_VERTEX(e3);
if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) {
GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
GLfloat cc = ex * fy - ey * fx;
if (DO_TWOSIDE || DO_UNFILLED) {
facing = AREA_IS_CCW(cc) ^ ctx->Polygon._FrontBit;
if (DO_UNFILLED) {
if (facing) {
mode = ctx->Polygon.BackMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode != GL_FRONT) {
return;
}
}
else {
mode = ctx->Polygon.FrontMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode != GL_BACK) {
return;
}
}
}
if (DO_TWOSIDE && facing == 1) {
if (HAVE_RGBA) {
GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
(void)vbcolor;
if (HAVE_BACK_COLORS) {
if (!DO_FLAT) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_SAVE_RGBA(2);
VERT_COPY_RGBA1(v[0]);
VERT_COPY_RGBA1(v[1]);
VERT_COPY_RGBA1(v[2]);
}
VERT_SAVE_RGBA(3);
VERT_COPY_RGBA1(v[3]);
if (HAVE_SPEC) {
if (!DO_FLAT) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_SAVE_SPEC(2);
VERT_COPY_SPEC1(v[0]);
VERT_COPY_SPEC1(v[1]);
VERT_COPY_SPEC1(v[2]);
}
VERT_SAVE_SPEC(3);
VERT_COPY_SPEC1(v[3]);
}
}
else {
if (!DO_FLAT) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_SAVE_RGBA(2);
VERT_SET_RGBA(v[0], vbcolor[e0]);
VERT_SET_RGBA(v[1], vbcolor[e1]);
VERT_SET_RGBA(v[2], vbcolor[e2]);
}
VERT_SAVE_RGBA(3);
VERT_SET_RGBA(v[3], vbcolor[e3]);
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
if (!DO_FLAT) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_SAVE_SPEC(2);
VERT_SET_SPEC(v[0], vbspec[e0]);
VERT_SET_SPEC(v[1], vbspec[e1]);
VERT_SET_SPEC(v[2], vbspec[e2]);
}
VERT_SAVE_SPEC(3);
VERT_SET_SPEC(v[3], vbspec[e3]);
}
}
}
else {
GLfloat *vbindex = (GLfloat*) VB->IndexPtr[1]->data;
if (!DO_FLAT) {
VERT_SAVE_IND( 0 );
VERT_SAVE_IND( 1 );
VERT_SAVE_IND( 2 );
VERT_SET_IND(v[0], vbindex[e0]);
VERT_SET_IND(v[1], vbindex[e1]);
VERT_SET_IND(v[2], vbindex[e2]);
}
VERT_SAVE_IND( 3 );
VERT_SET_IND(v[3], vbindex[e3]);
}
}
}
if (DO_OFFSET) {
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
z[0] = VERT_Z(v[0]);
z[1] = VERT_Z(v[1]);
z[2] = VERT_Z(v[2]);
z[3] = VERT_Z(v[3]);
if (cc * cc > 1e-16) {
GLfloat ez = z[2] - z[0];
GLfloat fz = z[3] - z[1];
GLfloat a = ey * fz - ez * fy;
GLfloat b = ez * fx - ex * fz;
GLfloat ic = 1.0 / cc;
GLfloat ac = a * ic;
GLfloat bc = b * ic;
if ( ac < 0.0f ) ac = -ac;
if ( bc < 0.0f ) bc = -bc;
offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
}
offset *= ctx->MRD;
}
}
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_SAVE_RGBA(2);
VERT_COPY_RGBA(v[0], v[3]);
VERT_COPY_RGBA(v[1], v[3]);
VERT_COPY_RGBA(v[2], v[3]);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_SAVE_SPEC(2);
VERT_COPY_SPEC(v[0], v[3]);
VERT_COPY_SPEC(v[1], v[3]);
VERT_COPY_SPEC(v[2], v[3]);
}
}
else {
VERT_SAVE_IND(0);
VERT_SAVE_IND(1);
VERT_SAVE_IND(2);
VERT_COPY_IND(v[0], v[3]);
VERT_COPY_IND(v[1], v[3]);
VERT_COPY_IND(v[2], v[3]);
}
}
if (mode == GL_POINT) {
if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
VERT_Z_ADD(v[3], offset);
}
UNFILLED_QUAD(ctx, GL_POINT, e0, e1, e2, e3);
}
else if (mode == GL_LINE) {
if (DO_OFFSET && ctx->Polygon.OffsetLine) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
VERT_Z_ADD(v[3], offset);
}
UNFILLED_QUAD(ctx, GL_LINE, e0, e1, e2, e3);
}
else {
if (DO_OFFSET && ctx->Polygon.OffsetFill) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
VERT_Z_ADD(v[3], offset);
}
RASTERIZE(GL_TRIANGLES);
QUAD((v[0]), (v[1]), (v[2]), (v[3]));
}
if (DO_OFFSET) {
VERT_SET_Z(v[0], z[0]);
VERT_SET_Z(v[1], z[1]);
VERT_SET_Z(v[2], z[2]);
VERT_SET_Z(v[3], z[3]);
}
if (DO_TWOSIDE && facing == 1) {
if (HAVE_RGBA) {
if (!DO_FLAT) {
VERT_RESTORE_RGBA(0);
VERT_RESTORE_RGBA(1);
VERT_RESTORE_RGBA(2);
}
VERT_RESTORE_RGBA(3);
if (HAVE_SPEC) {
if (!DO_FLAT) {
VERT_RESTORE_SPEC(0);
VERT_RESTORE_SPEC(1);
VERT_RESTORE_SPEC(2);
}
VERT_RESTORE_SPEC(3);
}
}
else {
if (!DO_FLAT) {
VERT_RESTORE_IND( 0 );
VERT_RESTORE_IND( 1 );
VERT_RESTORE_IND( 2 );
}
VERT_RESTORE_IND( 3 );
}
}
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_RESTORE_RGBA(0);
VERT_RESTORE_RGBA(1);
VERT_RESTORE_RGBA(2);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_RESTORE_SPEC(0);
VERT_RESTORE_SPEC(1);
VERT_RESTORE_SPEC(2);
}
}
else {
VERT_RESTORE_IND(0);
VERT_RESTORE_IND(1);
VERT_RESTORE_IND(2);
}
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#else
static void TAG(quad)(GLcontext *ctx, GLuint e0,
GLuint e1, GLuint e2, GLuint e3)
{
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (DO_UNFILLED) {
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte ef1 = VB->EdgeFlag[e1];
GLubyte ef3 = VB->EdgeFlag[e3];
VB->EdgeFlag[e1] = 0;
TAG(triangle)(ctx, e0, e1, e3);
VB->EdgeFlag[e1] = ef1;
VB->EdgeFlag[e3] = 0;
TAG(triangle)(ctx, e1, e2, e3);
VB->EdgeFlag[e3] = ef3;
}
else {
TAG(triangle)(ctx, e0, e1, e3);
TAG(triangle)(ctx, e1, e2, e3);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#endif
#endif
#if DO_LINE
static void TAG(line)(GLcontext *ctx, GLuint e0, GLuint e1)
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
VERTEX *v[2];
LOCAL_VARS(2);
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
v[0] = (VERTEX *)GET_VERTEX(e0);
v[1] = (VERTEX *)GET_VERTEX(e1);
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_SAVE_RGBA( 0 );
VERT_COPY_RGBA( v[0], v[1] );
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_SAVE_SPEC(0);
VERT_COPY_SPEC(v[0], v[1]);
}
}
else {
VERT_SAVE_IND(0);
VERT_COPY_IND(v[0], v[1]);
}
}
LINE(v[0], v[1]);
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_RESTORE_RGBA(0);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_RESTORE_SPEC(0);
}
}
else {
VERT_RESTORE_IND(0);
}
}
SET_PRIMITIVE_RENDERED
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#endif
#if DO_POINTS
static void TAG(points)(GLcontext *ctx, GLuint first, GLuint last)
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
int i;
LOCAL_VARS(1);
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (VB->Elts == 0) {
for (i = first; i < last; i++) {
if (VB->ClipMask[i] == 0) {
VERTEX *v = (VERTEX *)GET_VERTEX(i);
POINT(v);
SET_PRIMITIVE_RENDERED
}
}
}
else {
for (i = first; i < last; i++) {
GLuint e = VB->Elts[i];
if (VB->ClipMask[e] == 0) {
VERTEX *v = (VERTEX *)GET_VERTEX(e);
POINT(v);
SET_PRIMITIVE_RENDERED
}
}
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#endif
static void TAG(init)(void)
{
#if DO_QUAD
TAB[IND].quad = TAG(quad);
#endif
#if DO_TRI
TAB[IND].triangle = TAG(triangle);
#endif
#if DO_LINE
TAB[IND].line = TAG(line);
#endif
#if DO_POINTS
TAB[IND].points = TAG(points);
#endif
}
#undef IND
#undef TAG
#if HAVE_RGBA
#undef VERT_SET_IND
#undef VERT_COPY_IND
#undef VERT_SAVE_IND
#undef VERT_RESTORE_IND
#if HAVE_BACK_COLORS
#undef VERT_SET_RGBA
#endif
#else
#undef VERT_SET_RGBA
#undef VERT_COPY_RGBA
#undef VERT_SAVE_RGBA
#undef VERT_RESTORE_RGBA
#if HAVE_BACK_COLORS
#undef VERT_SET_IND
#endif
#endif
#if !HAVE_SPEC
#undef VERT_SET_SPEC
#undef VERT_COPY_SPEC
#undef VERT_SAVE_SPEC
#undef VERT_RESTORE_SPEC
#if HAVE_BACK_COLORS
#undef VERT_COPY_SPEC1
#endif
#else
#if HAVE_BACK_COLORS
#undef VERT_SET_SPEC
#endif
#endif
#if !HAVE_BACK_COLORS
#undef VERT_COPY_SPEC1
#undef VERT_COPY_IND1
#undef VERT_COPY_RGBA1
#endif
#ifndef INSANE_VERTICES
#undef VERT_SET_Z
#undef VERT_Z_ADD
#endif

View file

@ -1,716 +0,0 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, 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, 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
*/
/* Unlike the other templates here, this assumes quite a bit about the
* underlying hardware. Specifically it assumes a d3d-like vertex
* format, with a layout more or less constrained to look like the
* following:
*
* union {
* struct {
* float x, y, z, w;
* struct { char r, g, b, a; } color;
* struct { char r, g, b, fog; } spec;
* float u0, v0;
* float u1, v1;
* float u2, v2;
* float u3, v3;
* } v;
* struct {
* float x, y, z, w;
* struct { char r, g, b, a; } color;
* struct { char r, g, b, fog; } spec;
* float u0, v0, q0;
* float u1, v1, q1;
* float u2, v2, q2;
* float u3, v3, q3;
* } pv;
* struct {
* float x, y, z;
* struct { char r, g, b, a; } color;
* } tv;
* float f[16];
* unsigned int ui[16];
* unsigned char ub4[4][16];
* }
*
* DO_XYZW: Emit xyz and maybe w coordinates.
* DO_RGBA: Emit color.
* DO_SPEC: Emit specular color.
* DO_FOG: Emit fog coordinate in specular alpha.
* DO_TEX0: Emit tex0 u,v coordinates.
* DO_TEX1: Emit tex1 u,v coordinates.
* DO_TEX2: Emit tex2 u,v coordinates.
* DO_TEX3: Emit tex3 u,v coordinates.
* DO_PTEX: Emit tex0,1,2,3 q coordinates where possible.
*
* HAVE_RGBA_COLOR: Hardware takes color in rgba order (else bgra).
*
* HAVE_HW_VIEWPORT: Hardware performs viewport transform.
* HAVE_HW_DIVIDE: Hardware performs perspective divide.
*
* HAVE_TINY_VERTICES: Hardware understands v.tv format.
* HAVE_PTEX_VERTICES: Hardware understands v.pv format.
* HAVE_NOTEX_VERTICES: Hardware understands v.v format with texcount 0.
*
* Additionally, this template assumes it is emitting *transformed*
* vertices; the modifications to emit untransformed vertices (ie. to
* t&l hardware) are probably too great to cooexist with the code
* already in this file.
*
* NOTE: The PTEX vertex format always includes TEX0 and TEX1, even if
* only TEX0 is enabled, in order to maintain a vertex size which is
* an exact number of quadwords.
*/
#if (HAVE_HW_VIEWPORT)
#define VIEWPORT_X(dst, x) dst = x
#define VIEWPORT_Y(dst, y) dst = y
#define VIEWPORT_Z(dst, z) dst = z
#else
#define VIEWPORT_X(dst, x) dst = s[0] * x + s[12]
#define VIEWPORT_Y(dst, y) dst = s[5] * y + s[13]
#define VIEWPORT_Z(dst, z) dst = s[10] * z + s[14]
#endif
#if (HAVE_HW_DIVIDE && !HAVE_PTEX_VERTICES)
#error "can't cope with this combination"
#endif
#ifndef LOCALVARS
#define LOCALVARS
#endif
#ifndef CHECK_HW_DIVIDE
#define CHECK_HW_DIVIDE 1
#endif
#if (HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICES)
static void TAG(emit)(GLcontext *ctx,
GLuint start, GLuint end,
void *dest,
GLuint stride)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4];
GLfloat (*tc2)[4], (*tc3)[4];
GLfloat (*col)[4], (*spec)[4];
GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
GLuint tc2_stride, tc3_stride;
GLuint tc0_size, tc1_size;
GLuint tc2_size, tc3_size;
GLfloat (*coord)[4];
GLuint coord_stride;
VERTEX *v = (VERTEX *)dest;
const GLfloat *s = GET_VIEWPORT_MAT();
const GLubyte *mask = VB->ClipMask;
int i;
if (VIA_DEBUG) fprintf(stderr, "TAG-emit for HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICE\n");
if (HAVE_HW_VIEWPORT && HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
(void) s;
coord = VB->ClipPtr->data;
coord_stride = VB->ClipPtr->stride;
}
else {
coord = VB->NdcPtr->data;
coord_stride = VB->NdcPtr->stride;
}
if (DO_TEX3) {
const GLuint t3 = GET_TEXSOURCE(3);
tc3 = VB->TexCoordPtr[t3]->data;
tc3_stride = VB->TexCoordPtr[t3]->stride;
if (DO_PTEX)
tc3_size = VB->TexCoordPtr[t3]->size;
}
if (DO_TEX2) {
const GLuint t2 = GET_TEXSOURCE(2);
tc2 = VB->TexCoordPtr[t2]->data;
tc2_stride = VB->TexCoordPtr[t2]->stride;
if (DO_PTEX)
tc2_size = VB->TexCoordPtr[t2]->size;
}
if (DO_TEX1) {
const GLuint t1 = GET_TEXSOURCE(1);
tc1 = VB->TexCoordPtr[t1]->data;
tc1_stride = VB->TexCoordPtr[t1]->stride;
if (DO_PTEX)
tc1_size = VB->TexCoordPtr[t1]->size;
}
if (DO_TEX0) {
const GLuint t0 = GET_TEXSOURCE(0);
/* test */
tc0_stride = VB->TexCoordPtr[t0]->stride;
tc0 = VB->TexCoordPtr[t0]->data;
if (DO_PTEX)
tc0_size = VB->TexCoordPtr[t0]->size;
}
if (DO_RGBA) {
col = VB->ColorPtr[0]->data;
col_stride = VB->ColorPtr[0]->stride;
}
if (DO_SPEC) {
spec = VB->SecondaryColorPtr[0]->data;
spec_stride = VB->SecondaryColorPtr[0]->stride;
}
if (DO_FOG) {
if (VB->FogCoordPtr) {
fog = VB->FogCoordPtr->data;
fog_stride = VB->FogCoordPtr->stride;
}
else {
static GLfloat tmp[4] = { 0, 0, 0, 0 };
fog = &tmp;
fog_stride = 0;
}
}
/* May have nonstandard strides:
*/
if (start) {
STRIDE_4F(coord, start * coord_stride);
if (DO_TEX0)
STRIDE_4F(tc0, start * tc0_stride);
if (DO_TEX1)
STRIDE_4F(tc1, start * tc1_stride);
if (DO_TEX2)
STRIDE_4F(tc2, start * tc2_stride);
if (DO_TEX3)
STRIDE_4F(tc3, start * tc3_stride);
if (DO_RGBA)
STRIDE_4F(col, start * col_stride);
if (DO_SPEC)
STRIDE_4F(spec, start * spec_stride);
if (DO_FOG)
STRIDE_4F(fog, start * fog_stride);
}
for (i = start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
if (DO_XYZW) {
if (HAVE_HW_VIEWPORT || mask[i] == 0) {
VIEWPORT_X(v->v.x, coord[0][0]);
VIEWPORT_Y(v->v.y, coord[0][1]);
VIEWPORT_Z(v->v.z, coord[0][2]);
}
v->v.w = coord[0][3];
STRIDE_4F(coord, coord_stride);
}
if (DO_RGBA) {
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.red, col[0][0]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.green, col[0][1]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.blue, col[0][2]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.alpha, col[0][3]);
STRIDE_4F(col, col_stride);
}
if (DO_SPEC) {
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.red, spec[0][0]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.green, spec[0][1]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.blue, spec[0][2]);
STRIDE_4F(spec, spec_stride);
}
else {
v->v.specular.red = 0;
v->v.specular.green = 0;
v->v.specular.blue = 0;
}
if (DO_FOG) {
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.alpha, fog[0][0]);
/*=* [DBG] exy : fix lighting on + fog off error *=*/
STRIDE_4F(fog, fog_stride);
}
else {
v->v.specular.alpha = 0;
}
if (DO_TEX0) {
v->v.u0 = tc0[0][0];
v->v.v0 = tc0[0][1];
if (DO_PTEX) {
if (HAVE_PTEX_VERTICES) {
if (tc0_size == 4)
v->pv.q0 = tc0[0][3];
else
v->pv.q0 = 1.0;
}
else if (tc0_size == 4) {
float rhw = 1.0 / tc0[0][3];
v->v.w *= tc0[0][3];
v->v.u0 *= rhw;
v->v.v0 *= rhw;
}
}
STRIDE_4F(tc0, tc0_stride);
}
if (DO_TEX1) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
v->pv.u1 = tc1[0][0];
v->pv.v1 = tc1[0][1];
if (tc1_size == 4)
v->pv.q1 = tc1[0][3];
else
v->pv.q1 = 1.0;
}
else {
v->v.u1 = tc1[0][0];
v->v.v1 = tc1[0][1];
}
STRIDE_4F(tc1, tc1_stride);
}
else if (DO_PTEX) {
*(GLuint *)&v->pv.q1 = 0;
}
if (DO_TEX2) {
if (DO_PTEX) {
v->pv.u2 = tc2[0][0];
v->pv.v2 = tc2[0][1];
if (tc2_size == 4)
v->pv.q2 = tc2[0][3];
else
v->pv.q2 = 1.0;
}
else {
v->v.u2 = tc2[0][0];
v->v.v2 = tc2[0][1];
}
STRIDE_4F(tc2, tc2_stride);
}
if (DO_TEX3) {
if (DO_PTEX) {
v->pv.u3 = tc3[0][0];
v->pv.v3 = tc3[0][1];
if (tc3_size == 4)
v->pv.q3 = tc3[0][3];
else
v->pv.q3 = 1.0;
}
else {
v->v.u3 = tc3[0][0];
v->v.v3 = tc3[0][1];
}
STRIDE_4F(tc3, tc3_stride);
}
}
}
#else
#if DO_XYZW
#if HAVE_HW_DIVIDE
#error "cannot use tiny vertices with hw perspective divide"
#endif
static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
void *dest, GLuint stride)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLfloat (*col)[4];
GLuint col_stride;
GLfloat (*coord)[4] = VB->NdcPtr->data;
GLuint coord_stride = VB->NdcPtr->stride;
GLfloat *v = (GLfloat *)dest;
const GLubyte *mask = VB->ClipMask;
const GLfloat *s = GET_VIEWPORT_MAT();
int i;
(void) s;
/*ASSERT(stride == 4);*/
if (VIA_DEBUG) {
fprintf(stderr, "TAG-emit for DO_XYZW\n");
fprintf(stderr, "%s\n", __FUNCTION__);
}
col = VB->ColorPtr[0]->data;
col_stride = VB->ColorPtr[0]->stride;
if (start) {
STRIDE_4F(coord, start * coord_stride);
STRIDE_4F(col, start * col_stride);
}
for (i = start; i < end; i++, v += 4) {
if (DO_XYZW) {
if (HAVE_HW_VIEWPORT || mask[i] == 0) {
VIEWPORT_X(v[0], coord[0][0]);
VIEWPORT_Y(v[1], coord[0][1]);
VIEWPORT_Z(v[2], coord[0][2]);
}
STRIDE_4F(coord, coord_stride);
}
if (DO_RGBA) {
VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3];
UNCLAMPED_FLOAT_TO_UBYTE(c->red, col[0][0]);
UNCLAMPED_FLOAT_TO_UBYTE(c->green, col[0][1]);
UNCLAMPED_FLOAT_TO_UBYTE(c->blue, col[0][2]);
UNCLAMPED_FLOAT_TO_UBYTE(c->alpha, col[0][3]);
STRIDE_4F( col, col_stride );
}
}
}
#else
static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
void *dest, GLuint stride)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte (*col)[4];
GLuint col_stride;
GLfloat *v = (GLfloat *)dest;
int i;
if (VIA_DEBUG) {
fprintf(stderr, "TAG-emit for No DO_XYZW\n");
fprintf(stderr, "%s\n", __FUNCTION__);
}
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
IMPORT_FLOAT_COLORS( ctx );
col = VB->ColorPtr[0]->Ptr;
col_stride = VB->ColorPtr[0]->StrideB;
if (start)
STRIDE_4UB(col, col_stride * start);
/* Need to figure out where color is:
*/
if (GET_VERTEX_FORMAT() == TINY_VERTEX_FORMAT)
v += 3;
else
v += 4;
for (i = start; i < end; i++, STRIDE_F(v, stride)) {
if (HAVE_RGBA_COLOR) {
*(GLuint *)v = *(GLuint *)col[0];
}
else {
GLubyte *b = (GLubyte *)v;
b[0] = col[0][2];
b[1] = col[0][1];
b[2] = col[0][0];
b[3] = col[0][3];
}
STRIDE_4UB(col, col_stride);
}
}
#endif /* emit */
#endif /* emit */
#if (DO_XYZW) && (DO_RGBA)
#if (HAVE_PTEX_VERTICES)
static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
/* Force 'missing' texcoords to something valid.
*/
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
if (DO_PTEX)
return GL_TRUE;
if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
(DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
(DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) ||
(DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4))
return GL_FALSE;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
return GL_TRUE;
}
#else
static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
/* Force 'missing' texcoords to something valid.
*/
if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
if (DO_TEX1 && VB->TexCoordPtr[0] == 0) {
VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
}
if (DO_PTEX)
return GL_TRUE;
if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
(DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
(DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) {
/*PTEX_FALLBACK();*/
return GL_FALSE;
}
if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) {
if (DO_TEX1 || DO_TEX2 || DO_TEX3) {
/*PTEX_FALLBACK();*/
}
return GL_FALSE;
}
return GL_TRUE;
}
#endif /* ptex */
static void TAG(interp)(GLcontext *ctx,
GLfloat t,
GLuint edst, GLuint eout, GLuint ein,
GLboolean force_boundary)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte *ddverts = GET_VERTEX_STORE();
GLuint shift = GET_VERTEX_STRIDE_SHIFT();
const GLfloat *dstclip = VB->ClipPtr->data[edst];
GLfloat w;
const GLfloat *s = GET_VIEWPORT_MAT();
VERTEX *dst = (VERTEX *)(ddverts + (edst << shift));
VERTEX *in = (VERTEX *)(ddverts + (ein << shift));
VERTEX *out = (VERTEX *)(ddverts + (eout << shift));
(void)s;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
VIEWPORT_X(dst->v.x, dstclip[0]);
VIEWPORT_Y(dst->v.y, dstclip[1]);
VIEWPORT_Z(dst->v.z, dstclip[2]);
w = dstclip[3];
}
else {
w = 1.0 / dstclip[3];
VIEWPORT_X(dst->v.x, dstclip[0] * w);
VIEWPORT_Y(dst->v.y, dstclip[1] * w);
VIEWPORT_Z(dst->v.z, dstclip[2] * w);
}
if ((HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) ||
DO_FOG || DO_SPEC || DO_TEX0 || DO_TEX1 ||
DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) {
dst->v.w = w;
INTERP_UB(t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0]);
INTERP_UB(t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1]);
INTERP_UB(t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2]);
INTERP_UB(t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3]);
if (DO_SPEC) {
INTERP_UB(t, dst->ub4[5][0], out->ub4[5][0], in->ub4[5][0]);
INTERP_UB(t, dst->ub4[5][1], out->ub4[5][1], in->ub4[5][1]);
INTERP_UB(t, dst->ub4[5][2], out->ub4[5][2], in->ub4[5][2]);
}
if (DO_FOG) {
INTERP_UB(t, dst->ub4[5][3], out->ub4[5][3], in->ub4[5][3]);
}
if (DO_TEX0) {
if (DO_PTEX) {
if (HAVE_PTEX_VERTICES) {
INTERP_F(t, dst->pv.u0, out->pv.u0, in->pv.u0);
INTERP_F(t, dst->pv.v0, out->pv.v0, in->pv.v0);
INTERP_F(t, dst->pv.q0, out->pv.q0, in->pv.q0);
}
else {
INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
}
}
else {
INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
}
}
if (DO_TEX1) {
if (DO_PTEX) {
if (HAVE_PTEX_VERTICES) {
INTERP_F(t, dst->pv.u1, out->pv.u1, in->pv.u1);
INTERP_F(t, dst->pv.v1, out->pv.v1, in->pv.v1);
INTERP_F(t, dst->pv.q1, out->pv.q1, in->pv.q1);
}
else {
INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
}
}
else {
INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
}
}
else if (DO_PTEX) {
dst->pv.q0 = 0.0; /* must be a valid float on radeon */
}
if (DO_TEX2) {
if (DO_PTEX) {
INTERP_F(t, dst->pv.u2, out->pv.u2, in->pv.u2);
INTERP_F(t, dst->pv.v2, out->pv.v2, in->pv.v2);
INTERP_F(t, dst->pv.q2, out->pv.q2, in->pv.q2);
}
else {
INTERP_F(t, dst->v.u2, out->v.u2, in->v.u2);
INTERP_F(t, dst->v.v2, out->v.v2, in->v.v2);
}
}
if (DO_TEX3) {
if (DO_PTEX) {
INTERP_F(t, dst->pv.u3, out->pv.u3, in->pv.u3);
INTERP_F(t, dst->pv.v3, out->pv.v3, in->pv.v3);
INTERP_F(t, dst->pv.q3, out->pv.q3, in->pv.q3);
}
else {
INTERP_F(t, dst->v.u3, out->v.u3, in->v.u3);
INTERP_F(t, dst->v.v3, out->v.v3, in->v.v3);
}
}
}
else {
/* 4-dword vertex. Color is in v[3] and there is no oow coordinate.
*/
INTERP_UB(t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0]);
INTERP_UB(t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1]);
INTERP_UB(t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2]);
INTERP_UB(t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3]);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#endif /* rgba && xyzw */
static void TAG(init)(void)
{
setup_tab[IND].emit = TAG(emit);
#if (DO_XYZW && DO_RGBA)
setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
setup_tab[IND].interp = TAG(interp);
#endif
if (DO_SPEC)
setup_tab[IND].copyPv = copy_pv_rgba4_spec5;
else if (HAVE_HW_DIVIDE || DO_SPEC || DO_FOG || DO_TEX0 || DO_TEX1 ||
DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES)
setup_tab[IND].copyPv = copy_pv_rgba4;
else
setup_tab[IND].copyPv = copy_pv_rgba3;
if (DO_TEX3) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
ASSERT(HAVE_PTEX_VERTICES);
setup_tab[IND].vertexFormat = PROJ_TEX3_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 18;
setup_tab[IND].vertexStrideShift = 7;
}
else {
setup_tab[IND].vertexFormat = TEX3_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 14;
setup_tab[IND].vertexStrideShift = 6;
}
}
else if (DO_TEX2) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
ASSERT(HAVE_PTEX_VERTICES);
setup_tab[IND].vertexFormat = PROJ_TEX3_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 18;
setup_tab[IND].vertexStrideShift = 7;
}
else {
setup_tab[IND].vertexFormat = TEX2_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 12;
setup_tab[IND].vertexStrideShift = 6;
}
}
else if (DO_TEX1) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
ASSERT(HAVE_PTEX_VERTICES);
setup_tab[IND].vertexFormat = PROJ_TEX1_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 12;
setup_tab[IND].vertexStrideShift = 6;
}
else {
setup_tab[IND].vertexFormat = TEX1_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 10;
setup_tab[IND].vertexStrideShift = 6;
}
}
else if (DO_TEX0) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
setup_tab[IND].vertexFormat = PROJ_TEX1_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 12;
setup_tab[IND].vertexStrideShift = 6;
}
else {
setup_tab[IND].vertexFormat = TEX0_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 8;
setup_tab[IND].vertexStrideShift = 5;
}
}
else if (!HAVE_HW_DIVIDE && !DO_SPEC && !DO_FOG && HAVE_TINY_VERTICES) {
setup_tab[IND].vertexFormat = TINY_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 4;
setup_tab[IND].vertexStrideShift = 4;
}
else if (HAVE_NOTEX_VERTICES) {
setup_tab[IND].vertexFormat = NOTEX_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 6;
setup_tab[IND].vertexStrideShift = 5;
}
else {
setup_tab[IND].vertexFormat = TEX0_VERTEX_FORMAT;
setup_tab[IND].vertexSize = 8;
setup_tab[IND].vertexStrideShift = 5;
}
assert(setup_tab[IND].vertexSize * 4 <=
1 << setup_tab[IND].vertexStrideShift);
}
#undef IND
#undef TAG

View file

@ -1,526 +0,0 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, 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, 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
*/
/* Template for render stages which build and emit vertices directly
* to fixed-size dma buffers. Useful for rendering strips and other
* native primitives where clipping and per-vertex tweaks such as
* those in t_dd_tritmp.h are not required.
*
* Produces code for both inline triangles and indexed triangles.
* Where various primitive types are unaccelerated by hardware, the
* code attempts to fallback to other primitive types (quadstrips to
* tristrips, lineloops to linestrips), or to indexed vertices.
* Ultimately, a FALLBACK() macro is invoked if there is no way to
* render the primitive natively.
*/
#if !defined(HAVE_TRIANGLES)
#error "must have at least triangles to use render template"
#endif
#if !HAVE_ELTS
#define ELTS_VARS
#define ALLOC_ELTS(nr)
#define EMIT_ELT(offset, elt)
#define EMIT_TWO_ELTS(offset, elt0, elt1)
#define INCR_ELTS(nr)
#define ELT_INIT(prim)
#define GET_CURRENT_VB_MAX_ELTS() 0
#define GET_SUBSEQUENT_VB_MAX_ELTS() 0
#define ALLOC_ELTS_NEW_PRIMITIVE(nr)
#define RELEASE_ELT_VERTS()
#define EMIT_INDEXED_VERTS(ctx, start, count)
#endif
#ifndef EMIT_TWO_ELTS
#define EMIT_TWO_ELTS(offset, elt0, elt1) \
do { \
EMIT_ELT(offset, elt0); \
EMIT_ELT(offset + 1, elt1); \
} while (0)
#endif
#ifndef FINISH
#define FINISH
#endif
/***********************************************************************
* Render non-indexed primitives.
***********************************************************************/
static void TAG(render_points_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (HAVE_POINTS) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
GLuint j, nr;
INIT(GL_POINTS);
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += nr) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
static void TAG(render_lines_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (HAVE_LINES) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
GLuint j, nr;
INIT(GL_LINES);
/* Emit whole number of lines in total and in each buffer:
*/
count -= (count - start) & 1;
currentsz -= currentsz & 1;
dmasz -= dmasz & 1;
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += nr) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
static void TAG(render_line_strip_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (HAVE_LINE_STRIPS) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
GLuint j, nr;
INIT(GL_LINE_STRIP);
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j + 1 < count; j += nr - 1) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
static void TAG(render_line_loop_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (HAVE_LINE_STRIPS) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
GLuint j, nr;
INIT(GL_LINE_STRIP);
if (flags & PRIM_BEGIN)
j = start;
else
j = start + 1;
/* Ensure last vertex won't wrap buffers:
*/
currentsz--;
dmasz--;
if (currentsz < 8)
currentsz = dmasz;
for (; j + 1 < count; j += nr - 1) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
if (start < count - 1 && (flags & PRIM_END))
EMIT_VERTS(ctx, start, 1);
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
static void TAG(render_triangles_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
LOCAL_VARS;
int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 3) * 3;
int currentsz = (GET_CURRENT_VB_MAX_VERTS() / 3) * 3;
GLuint j, nr;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
INIT(GL_TRIANGLES);
/* Emit whole number of tris in total. dmasz is already a multiple
* of 3.
*/
count -= (count - start) % 3;
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += nr) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_tri_strip_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (HAVE_TRI_STRIPS) {
LOCAL_VARS;
GLuint j, nr;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
INIT(GL_TRIANGLE_STRIP);
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
/* From here on emit even numbers of tris when wrapping over buffers:
*/
dmasz -= (dmasz & 1);
currentsz -= (currentsz & 1);
for (j = start; j + 2 < count; j += nr - 2) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
static void TAG(render_tri_fan_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (HAVE_TRI_FANS) {
LOCAL_VARS;
GLuint j, nr;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
INIT(GL_TRIANGLE_FAN);
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
for (j = start + 1; j + 1 < count; j += nr - 1) {
nr = MIN2(currentsz, count - j + 1);
EMIT_VERTS(ctx, start, 1);
EMIT_VERTS(ctx, j, nr - 1);
currentsz = dmasz;
}
FINISH;
}
else {
/* Could write code to emit these as indexed vertices (for the
* g400, for instance).
*/
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_poly_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (HAVE_POLYGONS) {
LOCAL_VARS;
GLuint j, nr;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
INIT(GL_POLYGON);
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
for (j = start + 1; j + 1 < count; j += nr - 1) {
nr = MIN2(currentsz, count - j + 1);
EMIT_VERTS(ctx, start, 1);
EMIT_VERTS(ctx, j, nr - 1);
currentsz = dmasz;
}
FINISH;
}
else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) {
TAG(render_tri_fan_verts)(ctx, start, count, flags);
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
static void TAG(render_quad_strip_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j, nr;
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (HAVE_QUAD_STRIPS) {
LOCAL_VARS;
GLuint j, nr;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz;
INIT(GL_QUAD_STRIP);
currentsz = GET_CURRENT_VB_MAX_VERTS();
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
dmasz -= (dmasz & 2);
currentsz -= (currentsz & 2);
for (j = start; j + 3 < count; j += nr - 2) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else if (HAVE_TRI_STRIPS) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
/* Emit smooth-shaded quadstrips as tristrips:
*/
INIT(GL_TRIANGLE_STRIP);
/* Emit whole number of quads in total, and in each buffer.
*/
dmasz -= dmasz & 1;
currentsz -= currentsz & 1;
count -= (count - start) & 1;
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
for (j = start; j + 3 < count; j += nr - 2) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
static void TAG(render_quads_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (HAVE_QUADS) {
LOCAL_VARS;
int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 4) * 4;
int currentsz = (GET_CURRENT_VB_MAX_VERTS() / 4) * 4;
GLuint j, nr;
INIT(GL_QUADS);
/* Emit whole number of quads in total. dmasz is already a multiple
* of 4.
*/
count -= (count - start) % 4;
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += nr) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else if (HAVE_TRIANGLES) {
/* Hardware doesn't have a quad primitive type -- try to
* simulate it using triangle primitive.
*/
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz;
GLuint j;
INIT(GL_TRIANGLES);
currentsz = GET_CURRENT_VB_MAX_VERTS();
/* Emit whole number of quads in total, and in each buffer.
*/
dmasz -= dmasz & 3;
count -= (count - start) & 3;
currentsz -= currentsz & 3;
/* Adjust for rendering as triangles:
*/
currentsz = currentsz / 6 * 4;
dmasz = dmasz / 6 * 4;
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += 4) {
/* Send v0, v1, v3
*/
EMIT_VERTS(ctx, j, 2);
EMIT_VERTS(ctx, j + 3, 1);
/* Send v1, v2, v3
*/
EMIT_VERTS(ctx, j + 1, 3);
}
FINISH;
}
else {
/* Vertices won't fit in a single buffer, fallback.
*/
VERT_FALLBACK(ctx, start, count, flags);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_noop)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
}
static tnl_render_func TAG(render_tab_verts)[GL_POLYGON + 2] =
{
TAG(render_points_verts),
TAG(render_lines_verts),
TAG(render_line_loop_verts),
TAG(render_line_strip_verts),
TAG(render_triangles_verts),
TAG(render_tri_strip_verts),
TAG(render_tri_fan_verts),
TAG(render_quads_verts),
TAG(render_quad_strip_verts),
TAG(render_poly_verts),
TAG(render_noop),
};

View file

@ -155,26 +155,25 @@ via_free_depth_buffer(viaContextPtr vmesa)
GLboolean
via_alloc_dma_buffer(viaContextPtr vmesa)
{
drmVIADMAInit init;
drmVIADMAInit init;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
vmesa->dma = (GLuint *) malloc(VIA_DMA_BUFSIZ);
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
vmesa->dma = (GLuint *) malloc(VIA_DMA_BUFSIZ);
/*
* Check whether AGP DMA has been initialized.
*/
init.func = VIA_DMA_INITIALIZED;
vmesa->useAgp =
/*
* Check whether AGP DMA has been initialized.
*/
init.func = VIA_DMA_INITIALIZED;
vmesa->useAgp =
( 0 == drmCommandWrite(vmesa->driFd, DRM_VIA_DMA_INIT,
&init, sizeof(init)));
if (vmesa->useAgp)
printf("unichrome_dri.so: Using AGP.\n");
else
printf("unichrome_dri.so: Using PCI.\n");
if (vmesa->useAgp)
printf("unichrome_dri.so: Using AGP.\n");
else
printf("unichrome_dri.so: Using PCI.\n");
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
return ((vmesa->dma) ? GL_TRUE : GL_FALSE);
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
return ((vmesa->dma) ? GL_TRUE : GL_FALSE);
}
void

View file

@ -71,21 +71,19 @@ v * copy of this software and associated documentation files (the "Software"),
#define VIA_BLIT_COPY 0xCC
#define VIA_BLIT_FILL 0xF0
#define VIA_BLIT_SET 0xFF
#define VIA_BLITSIZE 96
#define DEPTH_SCALE ((1 << 16) - 1)
typedef enum {VIABLIT_TRANSCOPY, VIABLIT_COPY, VIABLIT_FILL} ViaBlitOps;
/*=* John Sheng [2003.5.31] flip *=*/
#define SetReg2DAGP(nReg, nData) { \
*((GLuint *)(vb)) = ((nReg) >> 2) | 0xF0000000; \
*((GLuint *)(vb) + 1) = (nData); \
vb = ((GLuint *)vb) + 2; \
vmesa->dmaLow +=8; \
void viaCheckDma(viaContextPtr vmesa, GLuint bytes)
{
VIA_FINISH_PRIM( vmesa );
if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
viaFlushPrims(vmesa);
}
}
#define DEPTH_SCALE ((1 << 16) - 1)
static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch)
@ -98,7 +96,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLuint clear_depth_mask = 0xf << 28;
GLuint clear_depth = 0;
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
flag |= VIA_FRONT;
@ -220,7 +218,7 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
driWaitForVBlank( dPriv, & vmesa->vbl_seq, vmesa->vblank_flags, & missed_target );
LOCK_HARDWARE(vmesa);
@ -270,10 +268,9 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
{
/*=* John Sheng [2003.5.31] flip *=*/
viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
GLcontext *ctx = vmesa->glCtx;
GLuint nBackBase;
viaBuffer buffer_tmp;
GLcontext *ctx;
GLboolean missed_target;
int retcode;
@ -282,9 +279,8 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
ctx = vmesa->glCtx;
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
/* Now wait for the vblank:
*/
@ -297,52 +293,28 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
LOCK_HARDWARE(vmesa);
/* Page Flip*/
if(GL_FALSE) {
viaFlushPrimsLocked(vmesa);
while ((*(volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x200) & 0x2) != 0x2);
while (*(volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x200) & 0x2);
nBackBase = vmesa->back.offset >> 1;
/*if (nFirstFlip) {
*vb++ = HALCYON_HEADER2;
*vb++ = 0x00fe0000;
*vb++ = 0x00001004;
*vb++ = 0x00001004;
vmesa->dmaLow += 16;
{
RING_VARS;
nFirstFlip = GL_FALSE;
}
SetReg2DAGP(0x214, nBackBase);
viaFlushPrimsLocked(vmesa);*/
if (!vmesa->nDoneFirstFlip) {
*((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x43c)) = 0x00fe0000;
*((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x440)) = 0x00001004;
vmesa->nDoneFirstFlip = GL_TRUE;
}
*((GLuint *)((GLuint)vmesa->regMMIOBase + 0x214)) = nBackBase;
}
/* Auto Swap */
else {
viaFlushPrimsLocked(vmesa);
vb = viaCheckDma(vmesa, 8 * 4);
if (!vmesa->nDoneFirstFlip) {
*vb++ = HALCYON_HEADER2;
*vb++ = 0x00fe0000;
*vb++ = 0x0000000e;
*vb++ = 0x0000000e;
vmesa->dmaLow += 16;
vmesa->nDoneFirstFlip = GL_FALSE;
vmesa->nDoneFirstFlip = GL_FALSE; /* XXX: FIXME LATER!!! */
BEGIN_RING(4);
OUT_RING(HALCYON_HEADER2);
OUT_RING(0x00fe0000);
OUT_RING(0x0000000e);
OUT_RING(0x0000000e);
ADVANCE_RING();
}
nBackBase = (vmesa->back.offset );
*vb++ = HALCYON_HEADER2;
*vb++ = 0x00fe0000;
*vb++ = (HC_SubA_HFBBasL << 24) | (nBackBase & 0xFFFFF8) | 0x2;
*vb++ = (HC_SubA_HFBDrawFirst << 24) |
((nBackBase & 0xFF000000) >> 24) | 0x0100;
vmesa->dmaLow += 16;
BEGIN_RING(4);
OUT_RING( HALCYON_HEADER2 );
OUT_RING( 0x00fe0000 );
OUT_RING((HC_SubA_HFBBasL << 24) | (nBackBase & 0xFFFFF8) | 0x2);
OUT_RING((HC_SubA_HFBDrawFirst << 24) |
((nBackBase & 0xFF000000) >> 24) | 0x0100);
ADVANCE_RING();
viaFlushPrimsLocked(vmesa);
}
@ -355,6 +327,9 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
memcpy(&vmesa->back, &vmesa->front, sizeof(viaBuffer));
memcpy(&vmesa->front, &buffer_tmp, sizeof(viaBuffer));
/* KW: BOGUS BOGUS BOGUS: The first time an app calls glDrawBuffer
* while pageflipping, this will blow up: FIXME
*/
if(vmesa->currentPage) {
vmesa->currentPage = 0;
if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
@ -374,9 +349,145 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
}
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#define VIA_CMDBUF_MAX_LAG 50000
static int fire_buffer(viaContextPtr vmesa, drm_via_flush_sys_t *buf)
{
drmVIACommandBuffer bufI;
int ret;
bufI.buf = (char *) (buf->index + buf->offset);
bufI.size = buf->size;
if (vmesa->useAgp) {
drmVIACmdBufSize bSiz;
/* Do the CMDBUF_SIZE ioctl:
*/
bSiz.func = VIA_CMDBUF_LAG;
bSiz.wait = 1;
bSiz.size = VIA_CMDBUF_MAX_LAG;
do {
ret = drmCommandWriteRead(vmesa->driFd, DRM_VIA_CMDBUF_SIZE,
&bSiz, sizeof(bSiz));
} while (ret == -EAGAIN);
if (ret) {
fprintf(stderr, "%s: DRM_VIA_CMDBUF_SIZE returned %d\n", __FUNCTION__, ret);
abort();
return ret;
}
/* Acutally fire the buffer:
*/
do {
ret = drmCommandWrite(vmesa->driFd, DRM_VIA_CMDBUFFER,
&bufI, sizeof(bufI));
} while (ret == -EAGAIN);
if (ret) {
fprintf(stderr, "%s: DRM_VIA_CMDBUFFER returned %d\n", __FUNCTION__, ret);
abort();
/* If this fails, the original code fell back to the PCI path.
*/
}
else
return 0;
/* Fall through to PCI handling?!?
*/
WAIT_IDLE(vmesa);
}
ret = drmCommandWrite(vmesa->driFd, DRM_VIA_PCICMD, &bufI, sizeof(bufI));
if (ret) {
fprintf(stderr, "%s: DRM_VIA_PCICMD returned %d\n", __FUNCTION__, ret);
abort();
}
return ret;
}
/* Inserts the surface addresss and active cliprects one at a time
* into the head of the DMA buffer being flushed. Fires the buffer
* for each cliprect.
*/
static int via_flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf)
{
GLuint *vb = (GLuint *)vmesa->dmaAddr;
GLuint format = (vmesa->viaScreen->bitsPerPixel == 0x20
? HC_HDBFM_ARGB8888
: HC_HDBFM_RGB565);
if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
GLuint offset = vmesa->back.offset;
GLuint pitch = vmesa->back.pitch;
vb[0] = HC_HEADER2;
vb[1] = HC_ParaType_NotTex << 16;
if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
vb[2] = (HC_SubA_HClipTB << 24) | 0x0;
vb[3] = (HC_SubA_HClipLR << 24) | 0x0;
}
else {
vb[2] = (HC_SubA_HClipTB << 24) | vmesa->driDrawable->h;
vb[3] = (HC_SubA_HClipLR << 24) | vmesa->driDrawable->w;
}
vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
vb[5] = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
vb[6] = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
vb[7] = 0xcccccccc;
return fire_buffer( vmesa, buf );
}
else {
GLuint i, ret;
drm_clip_rect_t *b = vmesa->sarea->boxes;
for (i = 0; i < vmesa->sarea->nbox; i++, b++) {
GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
GLuint pitch = vmesa->front.pitch;
GLuint offset = (vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel)) & ~0x1f;
GLuint clipL = b->x1 + vmesa->drawXoff;
GLuint clipR = b->x2 + vmesa->drawXoff;
GLuint clipT = b->y1;
GLuint clipB = b->y2;
vb[0] = HC_HEADER2;
vb[1] = (HC_ParaType_NotTex << 16);
if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
vb[2] = (HC_SubA_HClipTB << 24) | 0x0;
vb[3] = (HC_SubA_HClipLR << 24) | 0x0;
}
else {
vb[2] = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
vb[3] = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
}
vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
vb[5] = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
vb[6] = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
vb[7] = 0xcccccccc;
ret = fire_buffer( vmesa, buf );
if (ret)
return ret;
}
}
return 0;
}
static int intersect_rect(drm_clip_rect_t *out,
drm_clip_rect_t *a,
drm_clip_rect_t *b)
@ -400,73 +511,83 @@ void viaFlushPrimsLocked(viaContextPtr vmesa)
int nbox = vmesa->numClipRects;
drm_via_sarea_t *sarea = vmesa->sarea;
drm_via_flush_sys_t sysCmd;
GLuint *vb = viaCheckDma(vmesa, 0);
int i;
RING_VARS;
if (*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|vmesa->hHWContext) &&
*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|DRM_LOCK_CONT|vmesa->hHWContext))
*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|DRM_LOCK_CONT|vmesa->hHWContext)) {
fprintf(stderr, "%s called without lock held\n", __FUNCTION__);
abort();
}
if (vmesa->dmaLow == DMA_OFFSET) {
return;
}
if (vmesa->dmaLow > (VIA_DMA_BUFSIZ - 256))
assert(vmesa->dmaLastPrim == 0);
/* viaFinishPrimitive can add up to 8 bytes beyond VIA_DMA_HIGHWATER:
*/
if (vmesa->dmaLow > VIA_DMA_HIGHWATER + 8) {
fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow);
abort();
}
switch (vmesa->dmaLow & 0x1F) {
case 8:
*vb++ = HC_HEADER2;
*vb++ = (HC_ParaType_NotTex << 16);
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
vmesa->dmaLow += 24;
BEGIN_RING_NOCHECK( 6 );
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_NotTex << 16) );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
ADVANCE_RING();
break;
case 16:
*vb++ = HC_HEADER2;
*vb++ = (HC_ParaType_NotTex << 16);
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
vmesa->dmaLow += 16;
BEGIN_RING_NOCHECK( 4 );
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_NotTex << 16) );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
ADVANCE_RING();
break;
case 24:
*vb++ = HC_HEADER2;
*vb++ = (HC_ParaType_NotTex << 16);
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
*vb++ = HC_DUMMY;
vmesa->dmaLow += 40;
BEGIN_RING_NOCHECK( 10 );
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_NotTex << 16) );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
OUT_RING( HC_DUMMY );
ADVANCE_RING();
break;
case 0:
break;
default:
break;
if (VIA_DEBUG)
fprintf(stderr, "%s: unaligned value for vmesa->dmaLow: %x\n",
__FUNCTION__, vmesa->dmaLow);
/* abort(); */
/* goto done; */
}
/* assert((vmesa->dmaLow & 0x1f) == 0); */
sysCmd.offset = 0x0;
sysCmd.size = vmesa->dmaLow;
sysCmd.index = (GLuint)vmesa->dma;
sysCmd.discard = 0;
sarea->vertexPrim = vmesa->hwPrimitive;
if (!nbox) {
sysCmd.size = 0;
}
else if (nbox > VIA_NR_SAREA_CLIPRECTS) {
/* XXX: not handled ? */
}
if (!nbox) {
sysCmd.size = 0; /* KW: FIXME bogus if we ever start emitting partial state */
sarea->nbox = 0;
sysCmd.discard = 1;
flush_sys(vmesa, &sysCmd);
via_flush_sys(vmesa, &sysCmd);
}
else {
for (i = 0; i < nbox; ) {
@ -503,14 +624,17 @@ void viaFlushPrimsLocked(viaContextPtr vmesa)
if (nr == nbox) {
sysCmd.discard = 1;
flush_sys(vmesa, &sysCmd);
}
via_flush_sys(vmesa, &sysCmd);
}
}
if (VIA_DEBUG) {
GLuint i;
GLuint *data = (GLuint *)vmesa->dmaAddr;
for (i = 0; i < vmesa->dmaLow; i += 16) {
fprintf(stderr, "%04x: ", i);
fprintf(stderr, "%08x ", *data++);
fprintf(stderr, "%08x ", *data++);
fprintf(stderr, "%08x ", *data++);
@ -518,18 +642,19 @@ void viaFlushPrimsLocked(viaContextPtr vmesa)
}
fprintf(stderr, "******************************************\n");
}
done:
/* Reset vmesa vars:
*/
vmesa->dmaLow = DMA_OFFSET;
vmesa->dmaAddr = (unsigned char *)vmesa->dma;
vmesa->dmaHigh = VIA_DMA_BUFSIZ;
}
void viaFlushPrims(viaContextPtr vmesa)
{
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (vmesa->dmaLow) {
if (vmesa->dmaLow != DMA_OFFSET) {
LOCK_HARDWARE(vmesa);
viaFlushPrimsLocked(vmesa);
UNLOCK_HARDWARE(vmesa);
@ -540,13 +665,13 @@ void viaFlushPrims(viaContextPtr vmesa)
static void viaFlush(GLcontext *ctx)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
}
static void viaFinish(GLcontext *ctx)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
WAIT_IDLE(vmesa);
}
@ -564,15 +689,21 @@ void viaInitIoctlFuncs(GLcontext *ctx)
}
#define SetReg2DAGP(nReg, nData) do { \
OUT_RING( ((nReg) >> 2) | 0xF0000000 ); \
OUT_RING( nData ); \
} while (0)
GLuint *viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
GLuint srcPitch,GLuint dstBase,GLuint dstPitch,
GLuint w,GLuint h,int xdir,int ydir, GLuint blitMode,
GLuint color, GLuint nMask, GLuint *vb)
static void viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
GLuint srcPitch,GLuint dstBase,GLuint dstPitch,
GLuint w,GLuint h,int xdir,int ydir, GLuint blitMode,
GLuint color, GLuint nMask )
{
GLuint dwGEMode = 0, srcY=0, srcX, dstY=0, dstX;
GLuint cmd;
RING_VARS;
if (VIA_DEBUG)
fprintf(stderr, "%s bpp %d src %x/%x dst %x/%x w %d h %d dir %d,%d mode: %x color: 0x%08x mask 0x%08x\n",
@ -580,7 +711,7 @@ GLuint *viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
if (!w || !h)
return vb;
return;
srcX = srcBase & 31;
dstX = dstBase & 31;
@ -599,7 +730,7 @@ GLuint *viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
dwGEMode |= VIA_GEM_8bpp;
break;
}
SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
cmd = 0;
@ -615,16 +746,15 @@ GLuint *viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
}
switch(blitMode) {
case VIABLIT_TRANSCOPY:
SetReg2DAGP( VIA_REG_SRCCOLORKEY, color);
SetReg2DAGP( VIA_REG_KEYCONTROL, 0x4000);
cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24);
break;
case VIABLIT_FILL:
case VIA_BLIT_FILL:
BEGIN_RING((2 + 9) * 2);
SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
SetReg2DAGP( VIA_REG_FGCOLOR, color);
cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24);
break;
default:
case VIA_BLIT_COPY:
BEGIN_RING((2 + 9) * 2);
SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
SetReg2DAGP( VIA_REG_KEYCONTROL, 0x0);
cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24);
}
@ -639,14 +769,13 @@ GLuint *viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
SetReg2DAGP( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
SetReg2DAGP( VIA_REG_GECMD, cmd);
SetReg2DAGP( 0x2C, 0x00000000);
return vb;
ADVANCE_RING();
}
void viaFillFrontBuffer(viaContextPtr vmesa)
{
GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight,i;
drm_clip_rect_t *b = vmesa->sarea->boxes;
GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*VIA_BLITSIZE);
GLuint pixel = (GLuint)vmesa->ClearColor;
GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
nDestPitch = vmesa->front.pitch;
@ -656,9 +785,9 @@ void viaFillFrontBuffer(viaContextPtr vmesa)
nDestHeight = b->y2 - b->y1;
nDestBase = vmesa->viaScreen->fbOffset +
(b->y1* nDestPitch + b->x1 * bytePerPixel);
vb = viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
nDestBase , nDestPitch, nDestWidth, nDestHeight,
0,0,VIABLIT_FILL, pixel, 0x0, vb);
viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
nDestBase , nDestPitch, nDestWidth, nDestHeight,
0,0,VIA_BLIT_FILL, pixel, 0x0);
b++;
}
@ -668,7 +797,6 @@ void viaFillFrontBuffer(viaContextPtr vmesa)
void viaFillFrontPBuffer(viaContextPtr vmesa)
{
GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offset;
GLuint *vb = viaCheckDma(vmesa, VIA_BLITSIZE);
GLuint pixel = (GLuint)vmesa->ClearColor;
offset = vmesa->front.offset;
@ -681,7 +809,7 @@ void viaFillFrontPBuffer(viaContextPtr vmesa)
viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
nDestBase , nDestPitch, nDestWidth, nDestHeight,
0,0,VIABLIT_FILL, pixel, 0x0, vb);
0,0,VIA_BLIT_FILL, pixel, 0x0);
viaFlushPrimsLocked(vmesa);
}
@ -690,7 +818,6 @@ void viaFillBackBuffer(viaContextPtr vmesa)
{
GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offset;
GLcontext *ctx = vmesa->glCtx;
GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*VIA_BLITSIZE);
GLuint pixel = (GLuint)vmesa->ClearColor;
GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
@ -704,7 +831,7 @@ void viaFillBackBuffer(viaContextPtr vmesa)
nDestHeight = vmesa->driDrawable->h;
viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
nDestBase , nDestPitch, nDestWidth, nDestHeight,
0,0,VIABLIT_FILL, pixel, 0x0, vb);
0,0,VIA_BLIT_FILL, pixel, 0x0);
}
/*=* John Sheng [2003.7.18] texenv *=*/
@ -716,9 +843,9 @@ void viaFillBackBuffer(viaContextPtr vmesa)
nDestHeight = b->y2 - b->y1;
nDestBase = offset + ((b->y1 - vmesa->drawY) * nDestPitch) +
(b->x1 - vmesa->drawX + vmesa->drawXoff) * bytePerPixel;
vb = viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
nDestBase , nDestPitch, nDestWidth, nDestHeight,
0,0,VIABLIT_FILL, pixel, 0x0, vb);
viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch,
nDestBase , nDestPitch, nDestWidth, nDestHeight,
0,0,VIA_BLIT_FILL, pixel, 0x0);
b++;
}
}
@ -732,7 +859,6 @@ void viaFillBackBuffer(viaContextPtr vmesa)
void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask)
{
GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset;
GLuint *vb = viaCheckDma(vmesa, VIA_BLITSIZE);
offset = vmesa->depth.offset;
if (VIA_DEBUG)
@ -740,16 +866,13 @@ void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask)
nDestBase = offset;
nDestPitch = vmesa->depth.pitch;
/* KW: bogus offset? */
/* offsetX = vmesa->drawXoff; */
offsetX = 0;
offsetX = vmesa->drawXoff;
nDestWidth = (vmesa->depth.pitch / vmesa->depth.bpp * 8) - offsetX;
nDestHeight = vmesa->driDrawable->h;
viaBlit(vmesa, vmesa->depth.bpp , nDestBase, nDestPitch,
nDestBase , nDestPitch, nDestWidth, nDestHeight,
0,0,VIABLIT_FILL, pixel, mask, vb);
0,0,VIA_BLIT_FILL, pixel, mask);
if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
@ -759,7 +882,6 @@ void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask)
void viaDoSwapBuffers(viaContextPtr vmesa)
{
GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*VIA_BLITSIZE );
GLuint nFrontPitch;
GLuint nBackPitch;
GLuint nFrontWidth, nFrontHeight;
@ -782,9 +904,9 @@ void viaDoSwapBuffers(viaContextPtr vmesa)
nBackBase = vmesa->back.offset + ((b->y1 - vmesa->drawY) * nBackPitch) +
(b->x1 - vmesa->drawX + vmesa->drawXoff) * bytePerPixel;
vb = viaBlit(vmesa, bytePerPixel << 3 , nBackBase, nBackPitch,
nFrontBase , nFrontPitch, nFrontWidth, nFrontHeight,
0,0,VIABLIT_COPY, 0, 0, vb);
viaBlit(vmesa, bytePerPixel << 3 , nBackBase, nBackPitch,
nFrontBase , nFrontPitch, nFrontWidth, nFrontHeight,
0,0,VIA_BLIT_COPY, 0, 0);
b++;
}
@ -795,7 +917,6 @@ void viaDoSwapBuffers(viaContextPtr vmesa)
void viaDoSwapPBuffers(viaContextPtr vmesa)
{
GLuint *vb = viaCheckDma(vmesa, 64 );
GLuint nFrontPitch;
GLuint nBackPitch;
GLuint nFrontWidth, nFrontHeight;
@ -804,6 +925,7 @@ void viaDoSwapPBuffers(viaContextPtr vmesa)
GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
GLuint EngStatus = *(vmesa->pnGEMode);
GLuint blitMode;
RING_VARS;
switch(bytePerPixel) {
case 4:
@ -817,10 +939,6 @@ void viaDoSwapPBuffers(viaContextPtr vmesa)
break;
}
/* Restore mode */
SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | blitMode);
nFrontPitch = vmesa->front.pitch;
nBackPitch = vmesa->back.pitch;
@ -837,6 +955,10 @@ void viaDoSwapPBuffers(viaContextPtr vmesa)
nFrontOffsetY = 0;
nBackOffsetX = nFrontOffsetX;
nBackOffsetY = nFrontOffsetY;
BEGIN_RING(8 * 2);
/* Restore mode */
SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | blitMode);
/* GEWD */
SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16));
/* GEDST */
@ -852,203 +974,30 @@ void viaDoSwapPBuffers(viaContextPtr vmesa)
((nBackPitch >> 3) & 0x7FF));
/* BITBLT */
SetReg2DAGP(0x0, 0x1 | 0xCC000000);
ADVANCE_RING();
viaFlushPrimsLocked(vmesa);
if (VIA_DEBUG) fprintf(stderr, "Do Swap PBuffer\n");
}
#define VIA_CMDBUF_MAX_LAG 50000
int flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf)
GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int line)
{
GLuint *pnBuf;
GLuint *pnEnd;
volatile GLuint *pnMMIOBase;
GLuint *vb = (GLuint *)vmesa->dmaAddr;
GLuint i = 0;
drmVIACommandBuffer bufI;
drmVIACmdBufSize bSiz;
int ret;
pnMMIOBase = vmesa->regMMIOBase;
pnBuf = (GLuint *)(buf->index + buf->offset);
pnEnd = (GLuint *)((GLuint)pnBuf + buf->size);
if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
*vb++ = HC_HEADER2;
*vb++ = (HC_ParaType_NotTex << 16);
if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
*vb++ = (HC_SubA_HClipTB << 24) | 0x0;
*vb++ = (HC_SubA_HClipLR << 24) | 0x0;
}
else {
*vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h);
/* KW: drawXoff known zero */
/* *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff)); */
*vb++ = ((HC_SubA_HClipLR << 24) | vmesa->driDrawable->w);
}
/*=* John Sheng [2003.6.16] fix pci path *=*/
{
GLuint pitch, format, offset;
if (vmesa->viaScreen->bitsPerPixel == 0x20) {
format = HC_HDBFM_ARGB8888;
}
else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
format = HC_HDBFM_RGB565;
}
else
return -1;
offset = vmesa->back.offset;
pitch = vmesa->back.pitch;
*vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
*vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
*vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
*vb++ = 0xcccccccc;
}
bufI.buf = (char *) pnBuf;
bufI.size = buf->size;
/*
* If AGP is enabled, try it. Otherwise or if it fails, use PCI MMIO.
*/
ret = 1;
if (vmesa->useAgp) {
/*
* Prevent command regulator from lagging to far behind by waiting.
* Otherwise some applications become unresponsive and jumpy.
* The VIA_CMDBUF_MAX_LAG size may be tuned. We could also wait for idle
* but that would severely lower performance of some very important
* applications. (for example glxgears :).
*/
bSiz.func = VIA_CMDBUF_LAG;
bSiz.wait = 1;
bSiz.size = VIA_CMDBUF_MAX_LAG;
while ( -EAGAIN == (ret = drmCommandWriteRead(vmesa->driFd, DRM_VIA_CMDBUF_SIZE,
&bSiz, sizeof(bSiz))));
if (ret) {
_mesa_error(vmesa->glCtx, GL_INVALID_OPERATION, __FUNCTION__);
abort();
}
while ( -EAGAIN == (ret = drmCommandWrite(vmesa->driFd, DRM_VIA_CMDBUFFER,
&bufI, sizeof(bufI))));
if (ret) {
abort();
}
}
if (ret) {
if (vmesa->useAgp) WAIT_IDLE(vmesa);
/* for (i = 0; */
if (drmCommandWrite(vmesa->driFd, DRM_VIA_PCICMD, &bufI, sizeof(bufI))) {
_mesa_error(vmesa->glCtx, GL_INVALID_OPERATION, __FUNCTION__);
abort();
}
}
}
else {
GLuint *head;
GLuint clipL, clipR, clipT, clipB;
drm_clip_rect_t *b = vmesa->sarea->boxes;
GLuint *pnTmp;
*vb++ = HC_HEADER2;
*vb++ = (HC_ParaType_NotTex << 16);
head = vb;
pnTmp = pnBuf;
for (i = 0; i < vmesa->sarea->nbox; i++) {
clipL = b->x1 + vmesa->drawXoff;
clipR = b->x2 + vmesa->drawXoff; /* FIXME: is this correct? */
clipT = b->y1;
clipB = b->y2;
if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
*vb = (HC_SubA_HClipTB << 24) | 0x0;
vb++;
*vb = (HC_SubA_HClipLR << 24) | 0x0;
vb++;
}
else {
*vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
vb++;
*vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
vb++;
}
/*=* John Sheng [2003.6.16] fix pci path *=*/
{
GLuint pitch, format, offset;
GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
if (vmesa->viaScreen->bitsPerPixel == 0x20) {
format = HC_HDBFM_ARGB8888;
}
else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
format = HC_HDBFM_RGB565;
}
else
return -1;
pitch = vmesa->front.pitch;
offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
offset = offset & 0xffffffe0;
*vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
*vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
*vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
*vb++ = 0xcccccccc;
}
pnBuf = pnTmp;
bufI.buf = (char *) pnBuf;
bufI.size = buf->size;
ret = 1;
if (vmesa->useAgp) {
bSiz.func = VIA_CMDBUF_LAG;
bSiz.wait = 1;
bSiz.size = VIA_CMDBUF_MAX_LAG;
while ( -EAGAIN == (ret = drmCommandWriteRead(vmesa->driFd, DRM_VIA_CMDBUF_SIZE,
&bSiz, sizeof(bSiz))));
if (ret) {
_mesa_error(vmesa->glCtx, GL_INVALID_OPERATION, __FUNCTION__);
abort();
}
while ( -EAGAIN == (ret = drmCommandWrite(vmesa->driFd, DRM_VIA_CMDBUFFER,
&bufI, sizeof(bufI))));
if (ret) {
abort();
}
}
if (ret) {
if (vmesa->useAgp)
WAIT_IDLE(vmesa);
if (drmCommandWrite(vmesa->driFd, DRM_VIA_PCICMD, &bufI, sizeof(bufI))) {
_mesa_error(vmesa->glCtx, GL_INVALID_OPERATION, __FUNCTION__);
abort();
}
}
b++;
vb = head;
}
if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n",
vmesa->dmaLow, bytes, vmesa->dmaLow + bytes);
viaFlushPrims(vmesa);
}
return 0;
{
GLuint *start = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow);
vmesa->dmaLow += bytes;
if (VIA_DEBUG && (vmesa->dmaLow & 0x4))
fprintf(stderr, "%s/%d: alloc 0x%x --> dmaLow 0x%x\n", func, line, bytes, vmesa->dmaLow);
return start;
}
}

View file

@ -28,43 +28,83 @@
#include "via_context.h"
void viaEmitPrim(viaContextPtr vmesa);
void viaFinishPrimitive(viaContextPtr vmesa);
void viaFlushPrims(viaContextPtr vmesa);
void viaFlushPrimsLocked(viaContextPtr vmesa);
void viaInitIoctlFuncs(GLcontext *ctx);
void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
void viaPageFlip(const __DRIdrawablePrivate *dpriv);
int via_check_copy(int fd);
void viaFillFrontBuffer(viaContextPtr vmesa);
void viaFillFrontPBuffer(viaContextPtr vmesa);
void viaFillBackBuffer(viaContextPtr vmesa);
void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask);
void viaDoSwapBuffers(viaContextPtr vmesa);
void viaDoSwapPBuffers(viaContextPtr vmesa);
void viaCheckDma(viaContextPtr vmesa, GLuint bytes);
int flush_agp(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd);
int flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf);
#define VIA_FINISH_PRIM(vmesa) do { \
if (vmesa->dmaLastPrim) \
viaFinishPrimitive( vmesa ); \
} while (0)
#define VIA_FIREVERTICES(vmesa) \
do { \
if (vmesa->dmaLow != DMA_OFFSET) { \
viaFlushPrims(vmesa); \
} \
} while (0)
#define VIA_FLUSH_DMA(vmesa) do { \
VIA_FINISH_PRIM(vmesa); \
if (vmesa->dmaLow != DMA_OFFSET) \
viaFlushPrims(vmesa); \
} while (0)
static __inline GLuint *viaCheckDma(viaContextPtr vmesa, int bytes)
{
if (vmesa->dmaLow + bytes > vmesa->dmaHigh) {
if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n",
vmesa->dmaLow, bytes, vmesa->dmaLow + bytes);
viaFlushPrims(vmesa);
}
GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int line);
#define viaAllocDma( v, b ) viaAllocDmaFunc(v, b, __FUNCTION__, __LINE__)
/* Room for the cliprect and other preamble at the head of each dma
* buffer: (What about buffers which only contain blits?)
*/
#define DMA_OFFSET 32
#define RING_VARS GLuint *_vb = 0, _nr, _x;
#define BEGIN_RING(n) do { \
if (_vb != 0) abort(); \
_vb = viaAllocDma(vmesa, (n) * sizeof(GLuint)); \
_nr = (n); \
_x = 0; \
} while (0)
#define BEGIN_RING_NOCHECK(n) do { \
if (_vb != 0) abort(); \
_vb = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow); \
vmesa->dmaLow += (n) * sizeof(GLuint); \
_nr = (n); \
_x = 0; \
} while (0)
#define OUT_RING(n) _vb[_x++] = (n)
#define ADVANCE_RING() do { \
if (_x != _nr) abort(); \
_vb = 0; \
} while (0)
#define ADVANCE_RING_VARIABLE() do { \
if (_x > _nr) abort(); \
vmesa->dmaLow -= (_nr - _x) * sizeof(GLuint); \
_vb = 0; \
} while (0)
#define QWORD_PAD_RING() do { \
if (vmesa->dmaLow & 0x4) { \
BEGIN_RING(1); \
OUT_RING(HC_DUMMY); \
ADVANCE_RING(); \
} \
} while (0)
{
GLuint *start = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow);
return start;
}
}
#endif

View file

@ -60,70 +60,25 @@
#define HAVE_ELTS 0
static const GLenum reducedPrim[GL_POLYGON + 1] = {
GL_POINTS,
GL_LINES,
GL_LINES,
GL_LINES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES
};
/* Fallback to normal rendering.
*/
static void VERT_FALLBACK(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
fprintf(stderr, "VERT_FALLBACK\n");
tnl->Driver.Render.PrimitiveNotify(ctx, flags & PRIM_MODE_MASK);
tnl->Driver.Render.BuildVertices(ctx, start, count, ~0);
tnl->Driver.Render.PrimTabVerts[flags & PRIM_MODE_MASK](ctx, start,
count, flags);
VIA_CONTEXT(ctx)->setupNewInputs = VERT_BIT_CLIP;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#define LOCAL_VARS viaContextPtr vmesa = VIA_CONTEXT(ctx)
/*
#define INIT(prim) \
do { \
VIA_FIREVERTICES(vmesa); \
viaRasterPrimitive(ctx, reducedPrim[prim], prim); \
} while (0)
*/
#define INIT(prim) \
do { \
viaRasterPrimitive(ctx, reducedPrim[prim], prim); \
} while (0)
#define NEW_PRIMITIVE() VIA_FIREVERTICES(vmesa)
#define NEW_BUFFER() VIA_FIREVERTICES(vmesa)
#define INIT(prim) do { \
viaRasterPrimitive(ctx, prim, prim); \
} while (0)
#define GET_CURRENT_VB_MAX_VERTS() \
(((int)vmesa->dmaHigh - (int)vmesa->dmaLow) / (vmesa->vertexSize * 4))
((VIA_DMA_BUF_SZ - (512 + (int)vmesa->dmaLow)) / (vmesa->vertexSize * 4))
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
(VIA_DMA_BUF_SZ - 4) / (vmesa->vertexSize * 4)
(VIA_DMA_BUF_SZ - 512) / (vmesa->vertexSize * 4)
#define ALLOC_VERTS( nr ) \
viaAllocDma( vmesa, (nr) * vmesa->vertexSize * 4)
#define EMIT_VERTS(ctx, j, nr) \
via_emit_contiguous_verts(ctx, j, (j) + (nr))
#define EMIT_VERTS(ctx, j, nr, buf) \
via_emit_contiguous_verts(ctx, j, (j) + (nr), buf)
#define FINISH \
do { \
vmesa->primitiveRendered = GL_TRUE; \
viaRasterPrimitiveFinish(ctx); \
} while (0)
#define FLUSH() VIA_FINISH_PRIM( vmesa )
#define TAG(x) via_fast##x
#include "via_dmatmp.h"
#include "tnl_dd/t_dd_dmatmp.h"
#undef TAG
#undef LOCAL_VARS
#undef INIT
@ -141,7 +96,9 @@ static GLboolean via_run_fastrender(GLcontext *ctx,
/* Don't handle clipping or indexed vertices.
*/
if (VB->ClipOrMask || vmesa->renderIndex != 0 || VB->Elts) {
if (VB->ClipOrMask ||
vmesa->renderIndex != 0 ||
!via_fastvalidate_render( ctx, VB )) {
if (VIA_DEBUG) {
fprintf(stderr, "slow path\n");
fprintf(stderr, "ClipOrMask = %08x\n", VB->ClipOrMask);
@ -152,7 +109,6 @@ static GLboolean via_run_fastrender(GLcontext *ctx,
}
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
vmesa->setupNewInputs = VERT_BIT_CLIP;
vmesa->primitiveRendered = GL_TRUE;
tnl->Driver.Render.Start(ctx);
@ -166,9 +122,6 @@ static GLboolean via_run_fastrender(GLcontext *ctx,
tnl->Driver.Render.Finish(ctx);
/*=* DBG - viewperf7.0 : fix command buffer overflow *=*/
if (vmesa->dmaLow > (VIA_DMA_BUFSIZ / 2))
viaFlushPrims(vmesa);
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
return GL_FALSE; /* finished the pipe */
}
@ -219,295 +172,3 @@ const struct tnl_pipeline_stage _via_fastrender_stage =
};
/*
* Render whole vertex buffers, including projection of vertices from
* clip space and clipping of primitives.
*
* This file makes calls to project vertices and to the point, line
* and triangle rasterizers via the function pointers:
*
* context->Driver.Render.*
*
*/
/**********************************************************************/
/* Clip single primitives */
/**********************************************************************/
#undef DIFFERENT_SIGNS
#if defined(USE_IEEE)
#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1 << 31))
#define DIFFERENT_SIGNS(x, y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1 << 31))
#else
#define NEGATIVE(x) (x < 0)
#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0)
/* Could just use (x*y<0) except for the flatshading requirements.
* Maybe there's a better way?
*/
#endif
#define W(i) coord[i][3]
#define Z(i) coord[i][2]
#define Y(i) coord[i][1]
#define X(i) coord[i][0]
#define SIZE 4
#define TAG(x) x##_4
#include "via_vb_cliptmp.h"
/**********************************************************************/
/* Clip and render whole begin/end objects */
/**********************************************************************/
#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
/* Vertices, with the possibility of clipping.
*/
#define RENDER_POINTS(start, count) \
tnl->Driver.Render.Points(ctx, start, count)
#define RENDER_LINE(v1, v2) \
do { \
GLubyte c1 = mask[v1], c2 = mask[v2]; \
GLubyte ormask = c1 | c2; \
if (!ormask) \
LineFunc(ctx, v1, v2); \
else if (!(c1 & c2 & 0x3f)) \
clip_line_4(ctx, v1, v2, ormask); \
} while (0)
#define RENDER_TRI(v1, v2, v3) \
if (VIA_DEBUG) fprintf(stderr, "RENDER_TRI - clip\n"); \
do { \
GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \
GLubyte ormask = c1 | c2 | c3; \
if (!ormask) \
TriangleFunc(ctx, v1, v2, v3); \
else if (!(c1 & c2 & c3 & 0x3f)) \
clip_tri_4(ctx, v1, v2, v3, ormask); \
} while (0)
#define RENDER_QUAD(v1, v2, v3, v4) \
do { \
GLubyte c1 = mask[v1], c2 = mask[v2]; \
GLubyte c3 = mask[v3], c4 = mask[v4]; \
GLubyte ormask = c1 | c2 | c3 | c4; \
if (!ormask) \
QuadFunc(ctx, v1, v2, v3, v4); \
else if (!(c1 & c2 & c3 & c4 & 0x3f)) \
clip_quad_4(ctx, v1, v2, v3, v4, ormask); \
} while (0)
#define LOCAL_VARS \
TNLcontext *tnl = TNL_CONTEXT(ctx); \
struct vertex_buffer *VB = &tnl->vb; \
const GLuint * const elt = VB->Elts; \
const GLubyte *mask = VB->ClipMask; \
const GLuint sz = VB->ClipPtr->size; \
const tnl_line_func LineFunc = tnl->Driver.Render.Line; \
const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \
const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \
const GLboolean stipple = ctx->Line.StippleFlag; \
(void) (LineFunc && TriangleFunc && QuadFunc); \
(void) elt; (void) mask; (void) sz; (void) stipple;
#define POSTFIX \
viaRasterPrimitiveFinish(ctx)
#define TAG(x) clip_##x##_verts
#define INIT(x) tnl->Driver.Render.PrimitiveNotify(ctx, x)
#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple(ctx)
#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
#define PRESERVE_VB_DEFS
#include "via_vb_rendertmp.h"
/* Elts, with the possibility of clipping.
*/
#undef ELT
#undef TAG
#define ELT(x) elt[x]
#define TAG(x) clip_##x##_elts
#include "via_vb_rendertmp.h"
/* TODO: do this for all primitives, verts and elts:
*/
static void clip_elt_triangles(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl_render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES];
struct vertex_buffer *VB = &tnl->vb;
const GLuint * const elt = VB->Elts;
GLubyte *mask = VB->ClipMask;
GLuint last = count-2;
GLuint j;
(void)flags;
tnl->Driver.Render.PrimitiveNotify(ctx, GL_TRIANGLES);
for (j = start; j < last; j += 3) {
GLubyte c1 = mask[elt[j]];
GLubyte c2 = mask[elt[j + 1]];
GLubyte c3 = mask[elt[j + 2]];
GLubyte ormask = c1 | c2 | c3;
if (ormask) {
if (start < j)
render_tris(ctx, start, j, 0);
if (!(c1 & c2 & c3 & 0x3f))
clip_tri_4(ctx, elt[j], elt[j + 1], elt[j + 2], ormask);
start = j+3;
}
}
if (start < j)
render_tris(ctx, start, j, 0);
viaRasterPrimitiveFinish(ctx);
}
/**********************************************************************/
/* Helper functions for drivers */
/**********************************************************************/
/*
void _tnl_RenderClippedPolygon(GLcontext *ctx, const GLuint *elts, GLuint n)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint *tmp = VB->Elts;
VB->Elts = (GLuint *)elts;
tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n, PRIM_BEGIN|PRIM_END);
VB->Elts = tmp;
}
void _tnl_RenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.Line(ctx, ii, jj);
}
*/
/**********************************************************************/
/* Render pipeline stage */
/**********************************************************************/
static GLboolean via_run_render(GLcontext *ctx,
struct tnl_pipeline_stage *stage)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
viaContextPtr vmesa = VIA_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
/* DBG */
GLuint newInputs = stage->changed_inputs;
/*GLuint newInputs = stage->inputs;*/
tnl_render_func *tab;
GLuint pass = 0;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
tnl->Driver.Render.Start(ctx);
tnl->Driver.Render.BuildVertices(ctx, 0, VB->Count, newInputs);
if (VB->ClipOrMask) {
tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles;
}
else {
tab = VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts;
}
do {
GLuint i;
for (i = 0; i < VB->PrimitiveCount; i++) {
GLuint flags = VB->Primitive[i].mode;
GLuint start = VB->Primitive[i].start;
GLuint length= VB->Primitive[i].count;
ASSERT(length || (flags & PRIM_END));
ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON + 1);
if (length)
tab[flags & PRIM_MODE_MASK](ctx, start, start + length,flags);
}
}
while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass(ctx, ++pass));
tnl->Driver.Render.Finish(ctx);
/*=* DBG viewperf7.0 : fix command buffer overflow *=*/
if (vmesa->dmaLow > (VIA_DMA_BUFSIZ / 2))
viaFlushPrims(vmesa);
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
return GL_FALSE; /* finished the pipe */
}
/* Quite a bit of work involved in finding out the inputs for the
* render stage.
*/
static void via_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
{
GLuint inputs = VERT_BIT_CLIP;
if (ctx->Visual.rgbMode) {
inputs |= VERT_BIT_COLOR0;
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
inputs |= VERT_BIT_COLOR1;
if (ctx->Texture.Unit[0]._ReallyEnabled) {
inputs |= VERT_BIT_TEX0;
}
if (ctx->Texture.Unit[1]._ReallyEnabled) {
inputs |= VERT_BIT_TEX1;
}
}
else {
/*inputs |= VERT_BIT_INDEX;*/
}
/*if (ctx->Point._Attenuated)
inputs |= VERT_POINT_SIZE;*/
if (ctx->Fog.Enabled)
inputs |= VERT_BIT_FOG;
/*if (ctx->_TriangleCaps & DD_TRI_UNFILLED)
inputs |= VERT_EDGE;
if (ctx->RenderMode == GL_FEEDBACK)
inputs |= VERT_TEX_ANY;*/
stage->inputs = inputs;
}
static void dtr(struct tnl_pipeline_stage *stage)
{
(void)stage;
}
const struct tnl_pipeline_stage _via_render_stage =
{
"via render",
(_NEW_BUFFERS |
_DD_NEW_SEPARATE_SPECULAR |
_DD_NEW_FLATSHADE |
_NEW_TEXTURE |
_NEW_LIGHT |
_NEW_POINT |
_NEW_FOG |
_DD_NEW_TRI_UNFILLED |
_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 */
via_check_render, /* check - initially set to alloc data */
via_run_render /* run */
};

View file

@ -254,6 +254,7 @@ static void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
static void viaSpanRenderStart( GLcontext *ctx )
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
VIA_FINISH_PRIM(vmesa);
LOCK_HARDWARE(vmesa);
viaFlushPrimsLocked(vmesa);
WAIT_IDLE(vmesa);

View file

@ -67,6 +67,458 @@ static GLuint ROP[16] = {
HC_HROP_WHITE /* GL_SET 1 */
};
static void via_emit_state(viaContextPtr vmesa)
{
GLcontext *ctx = vmesa->glCtx;
GLuint i = 0;
GLuint j = 0;
RING_VARS;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
viaCheckDma(vmesa, 0x110);
BEGIN_RING(5);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_NotTex << 16) );
OUT_RING( ((HC_SubA_HEnable << 24) | vmesa->regEnable) );
OUT_RING( ((HC_SubA_HFBBMSKL << 24) | vmesa->regHFBBMSKL) );
OUT_RING( ((HC_SubA_HROP << 24) | vmesa->regHROP) );
ADVANCE_RING();
if (vmesa->have_hw_stencil) {
GLuint pitch, format, offset;
format = HC_HZWBFM_24;
offset = vmesa->depth.offset;
pitch = vmesa->depth.pitch;
BEGIN_RING(6);
OUT_RING( ((HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF)) );
OUT_RING( ((HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24)) );
OUT_RING( ((HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK |
format | pitch) );
OUT_RING( ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD) );
OUT_RING( ((HC_SubA_HSTREF << 24) | vmesa->regHSTREF) );
OUT_RING( ((HC_SubA_HSTMD << 24) | vmesa->regHSTMD) );
ADVANCE_RING();
}
else if (vmesa->hasDepth) {
GLuint pitch, format, offset;
if (vmesa->depthBits == 16) {
/* We haven't support 16bit depth yet */
format = HC_HZWBFM_16;
/*format = HC_HZWBFM_32;*/
if (VIA_DEBUG) fprintf(stderr, "z format = 16\n");
}
else {
format = HC_HZWBFM_32;
if (VIA_DEBUG) fprintf(stderr, "z format = 32\n");
}
offset = vmesa->depth.offset;
pitch = vmesa->depth.pitch;
BEGIN_RING(4);
OUT_RING( ((HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF)) );
OUT_RING( ((HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24)) );
OUT_RING( ((HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK |
format | pitch) );
OUT_RING( ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD) );
ADVANCE_RING();
}
if (ctx->Color.AlphaEnabled) {
BEGIN_RING(1);
OUT_RING( ((HC_SubA_HATMD << 24) | vmesa->regHATMD) );
ADVANCE_RING();
i++;
}
if (ctx->Color.BlendEnabled) {
BEGIN_RING(11);
OUT_RING( ((HC_SubA_HABLCsat << 24) | vmesa->regHABLCsat) );
OUT_RING( ((HC_SubA_HABLCop << 24) | vmesa->regHABLCop) );
OUT_RING( ((HC_SubA_HABLAsat << 24) | vmesa->regHABLAsat) );
OUT_RING( ((HC_SubA_HABLAop << 24) | vmesa->regHABLAop) );
OUT_RING( ((HC_SubA_HABLRCa << 24) | vmesa->regHABLRCa) );
OUT_RING( ((HC_SubA_HABLRFCa << 24) | vmesa->regHABLRFCa) );
OUT_RING( ((HC_SubA_HABLRCbias << 24) | vmesa->regHABLRCbias) );
OUT_RING( ((HC_SubA_HABLRCb << 24) | vmesa->regHABLRCb) );
OUT_RING( ((HC_SubA_HABLRFCb << 24) | vmesa->regHABLRFCb) );
OUT_RING( ((HC_SubA_HABLRAa << 24) | vmesa->regHABLRAa) );
OUT_RING( ((HC_SubA_HABLRAb << 24) | vmesa->regHABLRAb) );
ADVANCE_RING();
}
if (ctx->Fog.Enabled) {
BEGIN_RING(3);
OUT_RING( ((HC_SubA_HFogLF << 24) | vmesa->regHFogLF) );
OUT_RING( ((HC_SubA_HFogCL << 24) | vmesa->regHFogCL) );
OUT_RING( ((HC_SubA_HFogCH << 24) | vmesa->regHFogCH) );
ADVANCE_RING();
}
if (ctx->Line.StippleFlag) {
BEGIN_RING(2);
OUT_RING( ((HC_SubA_HLP << 24) | ctx->Line.StipplePattern) );
OUT_RING( ((HC_SubA_HLPRF << 24) | ctx->Line.StippleFactor) );
ADVANCE_RING();
}
else {
BEGIN_RING(2);
OUT_RING( ((HC_SubA_HLP << 24) | 0xFFFF) );
OUT_RING( ((HC_SubA_HLPRF << 24) | 0x1) );
ADVANCE_RING();
}
BEGIN_RING(1);
OUT_RING( ((HC_SubA_HPixGC << 24) | 0x0) );
ADVANCE_RING();
QWORD_PAD_RING();
if (ctx->Texture._EnabledUnits) {
struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
{
viaTextureObjectPtr t = (viaTextureObjectPtr)texUnit0->_Current->DriverData;
GLuint nDummyValue = 0;
BEGIN_RING( 8 );
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Tex << 16) | (HC_SubType_TexGeneral << 24) );
if (ctx->Texture._EnabledUnits > 1) {
if (VIA_DEBUG) fprintf(stderr, "multi texture\n");
nDummyValue = (HC_SubA_HTXSMD << 24) | (1 << 3);
if (t && t->needClearCache) {
OUT_RING( nDummyValue | HC_HTXCHCLR_MASK );
OUT_RING( nDummyValue );
}
else {
OUT_RING( nDummyValue );
OUT_RING( nDummyValue );
}
}
else {
if (VIA_DEBUG) fprintf(stderr, "single texture\n");
nDummyValue = (HC_SubA_HTXSMD << 24) | 0;
if (t && t->needClearCache) {
OUT_RING( nDummyValue | HC_HTXCHCLR_MASK );
OUT_RING( nDummyValue );
}
else {
OUT_RING( nDummyValue );
OUT_RING( nDummyValue );
}
}
OUT_RING( HC_HEADER2 );
OUT_RING( HC_ParaType_NotTex << 16 );
OUT_RING( (HC_SubA_HEnable << 24) | vmesa->regEnable );
OUT_RING( (HC_SubA_HEnable << 24) | vmesa->regEnable );
ADVANCE_RING();
}
if (texUnit0->Enabled) {
struct gl_texture_object *texObj = texUnit0->_Current;
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
GLuint numLevels = t->lastLevel - t->firstLevel + 1;
if (VIA_DEBUG) {
fprintf(stderr, "texture0 enabled\n");
fprintf(stderr, "texture level %d\n", t->actualLevel);
}
if (numLevels == 8) {
BEGIN_RING(27);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Tex << 16) | (0 << 24) );
OUT_RING( t->regTexFM );
OUT_RING( (HC_SubA_HTXnL0OS << 24) |
((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
OUT_RING( t->regTexWidthLog2[0] );
OUT_RING( t->regTexWidthLog2[1] );
OUT_RING( t->regTexHeightLog2[0] );
OUT_RING( t->regTexHeightLog2[1] );
OUT_RING( t->regTexBaseH[0] );
OUT_RING( t->regTexBaseH[1] );
OUT_RING( t->regTexBaseH[2] );
OUT_RING( t->regTexBaseAndPitch[0].baseL );
OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[1].baseL );
OUT_RING( t->regTexBaseAndPitch[1].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[2].baseL );
OUT_RING( t->regTexBaseAndPitch[2].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[3].baseL );
OUT_RING( t->regTexBaseAndPitch[3].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[4].baseL );
OUT_RING( t->regTexBaseAndPitch[4].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[5].baseL );
OUT_RING( t->regTexBaseAndPitch[5].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[6].baseL );
OUT_RING( t->regTexBaseAndPitch[6].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[7].baseL );
OUT_RING( t->regTexBaseAndPitch[7].pitchLog2 );
ADVANCE_RING();
}
else if (numLevels > 1) {
BEGIN_RING(12 + numLevels * 2);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Tex << 16) | (0 << 24) );
OUT_RING( t->regTexFM );
OUT_RING( (HC_SubA_HTXnL0OS << 24) |
((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
OUT_RING( t->regTexWidthLog2[0] );
OUT_RING( t->regTexHeightLog2[0] );
if (numLevels > 6) {
OUT_RING( t->regTexWidthLog2[1] );
OUT_RING( t->regTexHeightLog2[1] );
}
OUT_RING( t->regTexBaseH[0] );
if (numLevels > 3) {
OUT_RING( t->regTexBaseH[1] );
}
if (numLevels > 6) {
OUT_RING( t->regTexBaseH[2] );
}
if (numLevels > 9) {
OUT_RING( t->regTexBaseH[3] );
}
for (j = 0; j < numLevels; j++) {
OUT_RING( t->regTexBaseAndPitch[j].baseL );
OUT_RING( t->regTexBaseAndPitch[j].pitchLog2 );
}
ADVANCE_RING_VARIABLE();
}
else {
BEGIN_RING(9);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Tex << 16) | (0 << 24) );
OUT_RING( t->regTexFM );
OUT_RING( (HC_SubA_HTXnL0OS << 24) |
((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
OUT_RING( t->regTexWidthLog2[0] );
OUT_RING( t->regTexHeightLog2[0] );
OUT_RING( t->regTexBaseH[0] );
OUT_RING( t->regTexBaseAndPitch[0].baseL );
OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
ADVANCE_RING();
}
BEGIN_RING(12);
OUT_RING( (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB_0 );
OUT_RING( (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD_0 );
OUT_RING( (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat_0 );
OUT_RING( (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop_0 );
OUT_RING( (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog_0 );
OUT_RING( (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat_0 );
OUT_RING( (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb_0 );
OUT_RING( (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa_0 );
OUT_RING( (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog_0 );
OUT_RING( (HC_SubA_HTXnTBLRCa << 24) | vmesa->regHTXnTBLRCa_0 );
OUT_RING( (HC_SubA_HTXnTBLRCc << 24) | vmesa->regHTXnTBLRCc_0 );
OUT_RING( (HC_SubA_HTXnTBLRCbias << 24) | vmesa->regHTXnTBLRCbias_0 );
ADVANCE_RING();
if (t->regTexFM == HC_HTXnFM_Index8) {
struct gl_color_table *table = &texObj->Palette;
GLfloat *tableF = (GLfloat *)table->Table;
BEGIN_RING(2 + table->Size);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Palette << 16) | (0 << 24) );
for (j = 0; j < table->Size; j++)
OUT_RING( tableF[j] );
ADVANCE_RING();
}
QWORD_PAD_RING();
}
if (texUnit1->Enabled) {
struct gl_texture_object *texObj = texUnit1->_Current;
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
GLuint numLevels = t->lastLevel - t->firstLevel + 1;
if (VIA_DEBUG) {
fprintf(stderr, "texture1 enabled\n");
fprintf(stderr, "texture level %d\n", t->actualLevel);
}
if (numLevels == 8) {
BEGIN_RING(27);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Tex << 16) | (1 << 24) );
OUT_RING( t->regTexFM );
OUT_RING( (HC_SubA_HTXnL0OS << 24) |
((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
OUT_RING( t->regTexWidthLog2[0] );
OUT_RING( t->regTexWidthLog2[1] );
OUT_RING( t->regTexHeightLog2[0] );
OUT_RING( t->regTexHeightLog2[1] );
OUT_RING( t->regTexBaseH[0] );
OUT_RING( t->regTexBaseH[1] );
OUT_RING( t->regTexBaseH[2] );
OUT_RING( t->regTexBaseAndPitch[0].baseL );
OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[1].baseL );
OUT_RING( t->regTexBaseAndPitch[1].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[2].baseL );
OUT_RING( t->regTexBaseAndPitch[2].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[3].baseL );
OUT_RING( t->regTexBaseAndPitch[3].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[4].baseL );
OUT_RING( t->regTexBaseAndPitch[4].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[5].baseL );
OUT_RING( t->regTexBaseAndPitch[5].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[6].baseL );
OUT_RING( t->regTexBaseAndPitch[6].pitchLog2 );
OUT_RING( t->regTexBaseAndPitch[7].baseL );
OUT_RING( t->regTexBaseAndPitch[7].pitchLog2 );
ADVANCE_RING();
}
else if (numLevels > 1) {
BEGIN_RING(12 + numLevels * 2);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Tex << 16) | (1 << 24) );
OUT_RING( t->regTexFM );
OUT_RING( (HC_SubA_HTXnL0OS << 24) |
((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
OUT_RING( t->regTexWidthLog2[0] );
OUT_RING( t->regTexHeightLog2[0] );
if (numLevels > 6) {
OUT_RING( t->regTexWidthLog2[1] );
OUT_RING( t->regTexHeightLog2[1] );
i += 2;
}
OUT_RING( t->regTexBaseH[0] );
if (numLevels > 3) {
OUT_RING( t->regTexBaseH[1] );
}
if (numLevels > 6) {
OUT_RING( t->regTexBaseH[2] );
}
if (numLevels > 9) {
OUT_RING( t->regTexBaseH[3] );
}
for (j = 0; j < numLevels; j++) {
OUT_RING( t->regTexBaseAndPitch[j].baseL );
OUT_RING( t->regTexBaseAndPitch[j].pitchLog2 );
}
ADVANCE_RING_VARIABLE();
}
else {
BEGIN_RING(9);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Tex << 16) | (1 << 24) );
OUT_RING( t->regTexFM );
OUT_RING( (HC_SubA_HTXnL0OS << 24) |
((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
OUT_RING( t->regTexWidthLog2[0] );
OUT_RING( t->regTexHeightLog2[0] );
OUT_RING( t->regTexBaseH[0] );
OUT_RING( t->regTexBaseAndPitch[0].baseL );
OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
ADVANCE_RING();
}
BEGIN_RING(9);
OUT_RING( (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB_1 );
OUT_RING( (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD_1 );
OUT_RING( (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat_1 );
OUT_RING( (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop_1 );
OUT_RING( (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog_1 );
OUT_RING( (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat_1 );
OUT_RING( (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb_1 );
OUT_RING( (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa_1 );
OUT_RING( (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog_1 );
ADVANCE_RING();
if (t->regTexFM == HC_HTXnFM_Index8) {
struct gl_color_table *table = &texObj->Palette;
GLfloat *tableF = (GLfloat *)table->Table;
BEGIN_RING(2 + table->Size);
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_Palette << 16) | (1 << 24) );
for (j = 0; j < table->Size; j++) {
OUT_RING( tableF[j] );
}
ADVANCE_RING();
}
QWORD_PAD_RING();
}
}
if (ctx->Polygon.StippleFlag) {
GLuint *stipple = &ctx->PolygonStipple[0];
BEGIN_RING(38);
OUT_RING( HC_HEADER2 );
OUT_RING( ((HC_ParaType_Palette << 16) | (HC_SubType_Stipple << 24)) );
OUT_RING( stipple[31] );
OUT_RING( stipple[30] );
OUT_RING( stipple[29] );
OUT_RING( stipple[28] );
OUT_RING( stipple[27] );
OUT_RING( stipple[26] );
OUT_RING( stipple[25] );
OUT_RING( stipple[24] );
OUT_RING( stipple[23] );
OUT_RING( stipple[22] );
OUT_RING( stipple[21] );
OUT_RING( stipple[20] );
OUT_RING( stipple[19] );
OUT_RING( stipple[18] );
OUT_RING( stipple[17] );
OUT_RING( stipple[16] );
OUT_RING( stipple[15] );
OUT_RING( stipple[14] );
OUT_RING( stipple[13] );
OUT_RING( stipple[12] );
OUT_RING( stipple[11] );
OUT_RING( stipple[10] );
OUT_RING( stipple[9] );
OUT_RING( stipple[8] );
OUT_RING( stipple[7] );
OUT_RING( stipple[6] );
OUT_RING( stipple[5] );
OUT_RING( stipple[4] );
OUT_RING( stipple[3] );
OUT_RING( stipple[2] );
OUT_RING( stipple[1] );
OUT_RING( stipple[0] );
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_NotTex << 16) );
OUT_RING( ((HC_SubA_HSPXYOS << 24) | (0x20 - (vmesa->driDrawable->h & 0x1F))) );
OUT_RING( ((HC_SubA_HSPXYOS << 24) | (0x20 - (vmesa->driDrawable->h & 0x1F))) );
ADVANCE_RING();
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static __inline__ GLuint viaPackColor(GLuint format,
GLubyte r, GLubyte g,
GLubyte b, GLubyte a)
@ -164,7 +616,7 @@ static void viaScissor(GLcontext *ctx, GLint x, GLint y,
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (ctx->Scissor.Enabled) {
VIA_FIREVERTICES(vmesa); /* don't pipeline cliprect changes */
VIA_FLUSH_DMA(vmesa); /* don't pipeline cliprect changes */
}
vmesa->scissorRect.x1 = x;
@ -189,7 +641,7 @@ static void viaDrawBuffer(GLcontext *ctx, GLenum mode)
viaContextPtr vmesa = VIA_CONTEXT(ctx);
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (mode == GL_FRONT) {
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
vmesa->drawMap = (char *)vmesa->driScreen->pFB;
vmesa->readMap = (char *)vmesa->driScreen->pFB;
vmesa->drawPitch = vmesa->front.pitch;
@ -199,7 +651,7 @@ static void viaDrawBuffer(GLcontext *ctx, GLenum mode)
return;
}
else if (mode == GL_BACK) {
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
vmesa->drawMap = vmesa->back.map;
vmesa->readMap = vmesa->back.map;
vmesa->drawPitch = vmesa->back.pitch;
@ -907,6 +1359,8 @@ static void viaChoosePolygonState(GLcontext *ctx)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
/* KW: FIXME: this should be in viaRasterPrimitive (somehow)
*/
if (ctx->Polygon.SmoothFlag) {
vmesa->regEnable |= HC_HenAA_MASK;
}
@ -1052,26 +1506,25 @@ static void viaChooseTriangle(GLcontext *ctx)
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void viaChooseState(GLcontext *ctx, GLuint newState)
void viaValidateState( GLcontext *ctx )
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (VIA_DEBUG) fprintf(stderr, "newState = %x\n", newState);
if (!(newState & (_NEW_COLOR |
_NEW_TEXTURE |
_NEW_DEPTH |
_NEW_FOG |
_NEW_LIGHT |
_NEW_LINE |
_NEW_POLYGON |
_NEW_POLYGONSTIPPLE |
_NEW_STENCIL)))
#if 0
if (!(vmesa->newState & (_NEW_COLOR |
_NEW_TEXTURE |
_NEW_DEPTH |
_NEW_FOG |
_NEW_LIGHT |
_NEW_LINE |
_NEW_POLYGON |
_NEW_POLYGONSTIPPLE |
_NEW_STENCIL)))
return;
vmesa->newState |= newState;
#endif
if (texUnit0->_ReallyEnabled || texUnit1->_ReallyEnabled || ctx->Fog.Enabled) {
vmesa->regCmdB |= HC_HVPMSK_Cs;
@ -1080,42 +1533,53 @@ static void viaChooseState(GLcontext *ctx, GLuint newState)
vmesa->regCmdB &= ~ HC_HVPMSK_Cs;
}
if (newState & _NEW_TEXTURE)
if (vmesa->newState & _NEW_TEXTURE) {
viaChooseTextureState(ctx);
viaUpdateTextureState(ctx); /* May modify vmesa->Fallback */
}
if (newState & _NEW_COLOR)
if (vmesa->newState & _NEW_COLOR)
viaChooseColorState(ctx);
if (newState & _NEW_DEPTH)
if (vmesa->newState & _NEW_DEPTH)
viaChooseDepthState(ctx);
if (newState & _NEW_FOG)
if (vmesa->newState & _NEW_FOG)
viaChooseFogState(ctx);
if (newState & _NEW_LIGHT)
if (vmesa->newState & _NEW_LIGHT)
viaChooseLightState(ctx);
if (newState & _NEW_LINE)
if (vmesa->newState & _NEW_LINE)
viaChooseLineState(ctx);
if (newState & (_NEW_POLYGON | _NEW_POLYGONSTIPPLE))
if (vmesa->newState & (_NEW_POLYGON | _NEW_POLYGONSTIPPLE)) {
viaChoosePolygonState(ctx);
viaChooseTriangle(ctx);
}
if (newState & _NEW_STENCIL)
if (vmesa->newState & _NEW_STENCIL)
viaChooseStencilState(ctx);
viaChooseTriangle(ctx);
if (!vmesa->Fallback) {
via_emit_state(vmesa);
vmesa->newState = 0;
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void viaInvalidateState(GLcontext *ctx, GLuint newState)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
VIA_FINISH_PRIM( vmesa );
vmesa->newState |= newState;
_swrast_InvalidateState(ctx, newState);
_swsetup_InvalidateState(ctx, newState);
_ac_InvalidateState(ctx, newState);
_tnl_InvalidateState(ctx, newState);
viaChooseState(ctx, newState);
}
void viaInitStateFuncs(GLcontext *ctx)

View file

@ -30,6 +30,7 @@
extern void viaInitState(GLcontext *ctx);
extern void viaInitStateFuncs(GLcontext *ctx);
extern void viaCalcViewport(GLcontext *ctx);
extern void viaValidateState(GLcontext *ctx);
extern void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode);
#define FALLBACK(vmesa, bit, mode) viaFallback(vmesa, bit, mode)

View file

@ -237,10 +237,8 @@ static void viaDeleteTexture(GLcontext *ctx, struct gl_texture_object *texObj)
if (t) {
viaContextPtr vmesa = VIA_CONTEXT(ctx);
if (vmesa) {
/*=* John Sheng [2003.7.18] viewperf frames/sec *=*/
/*VIA_FIREVERTICES(vmesa);*/
if (vmesa->dma) { /* imply vmesa is not under destroying */
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
}
viaDestroyTexObj(vmesa, t);
}

View file

@ -429,10 +429,10 @@ void viaUploadTexImages(viaContextPtr vmesa, viaTextureObjectPtr t)
/*t->bufAddr = (char *)((GLuint)vmesa->driScreen->pFB + t->texMem.offset);*/
if (t == vmesa->CurrentTexObj[0])
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
if (t == vmesa->CurrentTexObj[1])
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
viaUpdateTexLRU(vmesa, t);

View file

@ -650,7 +650,7 @@ static void viaUpdateTexUnit(GLcontext *ctx, GLuint unit)
/* Upload teximages (not pipelined)
*/
if (t->dirtyImages) {
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
viaSetTexImages(vmesa, tObj);
if (!t->bufAddr) {
FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_TRUE);
@ -667,7 +667,7 @@ static void viaUpdateTexUnit(GLcontext *ctx, GLuint unit)
* time.
*/
if (vmesa->CurrentTexObj[unit] != t) {
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
vmesa->CurrentTexObj[unit] = t;
viaUpdateTexLRU(vmesa, t); /* done too often */
}
@ -683,7 +683,7 @@ static void viaUpdateTexUnit(GLcontext *ctx, GLuint unit)
else {
vmesa->CurrentTexObj[unit] = 0;
vmesa->TexEnvImageFmt[unit] = 0;
VIA_FIREVERTICES(vmesa);
VIA_FLUSH_DMA(vmesa);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}

File diff suppressed because it is too large Load diff

View file

@ -39,12 +39,11 @@
static struct {
void (*emit)(GLcontext *, GLuint, GLuint, void *, GLuint);
tnl_interp_func interp;
tnl_copy_pv_func copyPv;
tnl_interp_func interp;
tnl_copy_pv_func copy_pv;
GLboolean (*check_tex_sizes)(GLcontext *ctx);
GLuint vertexSize;
GLuint vertexStrideShift;
GLuint vertexFormat;
GLuint vertex_size;
GLuint vertex_format;
} setup_tab[VIA_MAX_SETUP];
#define TINY_VERTEX_FORMAT 1
@ -71,12 +70,9 @@ static struct {
#define VERTEX_COLOR via_color_t
#define GET_VIEWPORT_MAT() VIA_CONTEXT(ctx)->ViewportMatrix.m
#define GET_TEXSOURCE(n) n
#define GET_VERTEX_FORMAT() VIA_CONTEXT(ctx)->vertexSize
#define GET_VERTEX_SIZE() (1<<GET_VERTEX_STRIDE_SHIFT())
#define GET_VERTEX_FORMAT() VIA_CONTEXT(ctx)->vertexFormat
#define GET_VERTEX_SIZE() VIA_CONTEXT(ctx)->vertexSize * sizeof(GLuint)
#define GET_VERTEX_STORE() VIA_CONTEXT(ctx)->verts
#define GET_VERTEX_STRIDE_SHIFT() VIA_CONTEXT(ctx)->vertexStrideShift
#define GET_UBYTE_COLOR_STORE() &VIA_CONTEXT(ctx)->UbyteColor
#define GET_UBYTE_SPEC_COLOR_STORE() &VIA_CONTEXT(ctx)->UbyteSecondaryColor
#define INVALIDATE_STORED_VERTICES()
#define HAVE_HW_VIEWPORT 0
@ -98,11 +94,8 @@ static struct {
#define PTEX_FALLBACK() FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_TEXTURE, 1)
#define IMPORT_FLOAT_COLORS via_import_float_colors
#define IMPORT_FLOAT_SPEC_COLORS via_import_float_spec_colors
#define INTERP_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].interp
#define COPY_PV_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].copyPv
#define COPY_PV_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].copy_pv
/***********************************************************************
@ -117,94 +110,94 @@ static struct {
***********************************************************************/
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT)
#define TAG(x) x##_wg
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT)
#define TAG(x) x##_wgs
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT)
#define TAG(x) x##_wgt0
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_TEX1_BIT)
#define TAG(x) x##_wgt0t1
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgpt0
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_TEX1_BIT |\
VIA_PTEX_BIT)
#define TAG(x) x##_wgpt0t1
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT)
#define TAG(x) x##_wgst0
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
VIA_TEX1_BIT)
#define TAG(x) x##_wgst0t1
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
VIA_PTEX_BIT)
#define TAG(x) x##_wgspt0
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
VIA_TEX1_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgspt0t1
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT)
#define TAG(x) x##_wgf
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT)
#define TAG(x) x##_wgfs
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT)
#define TAG(x) x##_wgft0
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
VIA_TEX1_BIT)
#define TAG(x) x##_wgft0t1
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
VIA_PTEX_BIT)
#define TAG(x) x##_wgfpt0
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
VIA_TEX1_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgfpt0t1
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
VIA_TEX0_BIT)
#define TAG(x) x##_wgfst0
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
VIA_TEX0_BIT | VIA_TEX1_BIT)
#define TAG(x) x##_wgfst0t1
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
VIA_TEX0_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgfspt0
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
VIA_TEX0_BIT | VIA_TEX1_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgfspt0t1
#include "via_dd_vbtmp.h"
#include "tnl_dd/t_dd_vbtmp.h"
static void init_setup_tab(void) {
@ -242,13 +235,11 @@ void viaPrintSetupFlags(char *msg, GLuint flags) {
(flags & VIA_TEX1_BIT) ? " tex-1," : "");
}
void viaCheckTexSizes(GLcontext *ctx) {
void viaCheckTexSizes(GLcontext *ctx)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
viaContextPtr vmesa = VIA_CONTEXT(ctx);
if (VIA_DEBUG) {
fprintf(stderr, "%s - in\n", __FUNCTION__);
fprintf(stderr, "setupIndex = %x\n", vmesa->setupIndex);
}
if (!setup_tab[vmesa->setupIndex].check_tex_sizes(ctx)) {
/* Invalidate stored verts
*/
@ -258,8 +249,11 @@ void viaCheckTexSizes(GLcontext *ctx) {
if (!vmesa->Fallback &&
!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
tnl->Driver.Render.Interp = setup_tab[vmesa->setupIndex].interp;
tnl->Driver.Render.CopyPV = setup_tab[vmesa->setupIndex].copyPv;
tnl->Driver.Render.CopyPV = setup_tab[vmesa->setupIndex].copy_pv;
}
if (vmesa->Fallback)
tnl->Driver.Render.Start(ctx);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
@ -270,14 +264,16 @@ void viaBuildVertices(GLcontext *ctx,
GLuint newinputs)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
GLubyte *v = ((GLubyte *)vmesa->verts + (start << vmesa->vertexStrideShift));
GLuint stride = 1 << vmesa->vertexStrideShift;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
GLuint stride = vmesa->vertexSize * sizeof(GLuint);
GLubyte *v = (GLubyte *)vmesa->verts + start * stride;
newinputs |= vmesa->setupNewInputs;
vmesa->setupNewInputs = 0;
if (!newinputs)
return;
if (newinputs & VERT_BIT_CLIP) {
if (newinputs & VERT_BIT_POS) {
setup_tab[vmesa->setupIndex].emit(ctx, start, count, v, stride);
}
else {
@ -308,14 +304,13 @@ void viaBuildVertices(GLcontext *ctx,
setup_tab[ind].emit(ctx, start, count, v, stride);
}
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
void viaChooseVertexState(GLcontext *ctx) {
TNLcontext *tnl = TNL_CONTEXT(ctx);
viaContextPtr vmesa = VIA_CONTEXT(ctx);
GLuint ind = VIA_XYZW_BIT | VIA_RGBA_BIT;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
ind |= VIA_SPEC_BIT;
@ -328,7 +323,7 @@ void viaChooseVertexState(GLcontext *ctx) {
ind |= VIA_TEX0_BIT;
vmesa->setupIndex = ind;
if (VIA_DEBUG) fprintf(stderr, "setupIndex = %x\n", vmesa->setupIndex);
viaPrintSetupFlags(__FUNCTION__, ind);
if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
tnl->Driver.Render.Interp = via_interp_extras;
@ -336,30 +331,29 @@ void viaChooseVertexState(GLcontext *ctx) {
}
else {
tnl->Driver.Render.Interp = setup_tab[ind].interp;
tnl->Driver.Render.CopyPV = setup_tab[ind].copyPv;
tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
}
vmesa->vertexSize = setup_tab[ind].vertexSize;
vmesa->vertexStrideShift = setup_tab[ind].vertexStrideShift;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
vmesa->vertexSize = setup_tab[ind].vertex_size;
vmesa->vertexFormat = setup_tab[ind].vertex_format;
if (VIA_DEBUG) fprintf(stderr, "%s, size %d\n", __FUNCTION__, vmesa->vertexSize);
}
void via_emit_contiguous_verts(GLcontext *ctx,
GLuint start,
GLuint count) {
void *via_emit_contiguous_verts(GLcontext *ctx,
GLuint start,
GLuint count,
void *dest)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
GLuint vertexSize = vmesa->vertexSize * 4;
GLuint *dest = viaCheckDma(vmesa, (count - start) * vertexSize);
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (VIA_DEBUG) fprintf(stderr, "choose setup_tab[0x%x]\n", vmesa->setupIndex);
setup_tab[vmesa->setupIndex].emit(ctx, start, count, dest, vertexSize);
vmesa->dmaLow += (count - start) * vertexSize;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
GLuint stride = vmesa->vertexSize * 4;
setup_tab[vmesa->setupIndex].emit(ctx, start, count, dest, stride);
return (void *)((char *)dest + (count - start) * stride);
}
void viaInitVB(GLcontext *ctx) {
void viaInitVB(GLcontext *ctx)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
GLuint size = TNL_CONTEXT(ctx)->vb.Size;
@ -381,14 +375,4 @@ void viaFreeVB(GLcontext *ctx) {
ALIGN_FREE(vmesa->verts);
vmesa->verts = 0;
}
if (vmesa->UbyteSecondaryColor.Ptr) {
ALIGN_FREE((void*)vmesa->UbyteSecondaryColor.Ptr);
vmesa->UbyteSecondaryColor.Ptr = 0;
}
if (vmesa->UbyteColor.Ptr) {
ALIGN_FREE((void*)vmesa->UbyteColor.Ptr);
vmesa->UbyteColor.Ptr = 0;
}
}

View file

@ -52,9 +52,10 @@ extern void viaBuildVertices(GLcontext *ctx,
GLuint newinputs);
extern void via_emit_contiguous_verts(GLcontext *ctx,
GLuint start,
GLuint count);
extern void *via_emit_contiguous_verts(GLcontext *ctx,
GLuint start,
GLuint count,
void *dest);
extern void via_translate_vertex(GLcontext *ctx,
const viaVertex *src,

View file

@ -1,269 +0,0 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, 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, 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
*/
#define CLIP_DOTPROD(K, A, B, C, D) X(K) * A + Y(K) * B + Z(K) * C + W(K) * D
#define POLY_CLIP(PLANE, A, B, C, D) \
do { \
if (mask & PLANE) { \
GLuint idxPrev = inlist[0]; \
GLfloat dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D); \
GLuint outcount = 0; \
GLuint i; \
\
inlist[n] = inlist[0]; /* prevent rotation of vertices */ \
for (i = 1; i <= n; i++) { \
GLuint idx = inlist[i]; \
GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D); \
\
clipmask[idxPrev] |= PLANE; \
if (!NEGATIVE(dpPrev)) { \
outlist[outcount++] = idxPrev; \
clipmask[idxPrev] &= ~PLANE; \
} \
\
if (DIFFERENT_SIGNS(dp, dpPrev)) { \
GLuint newvert = VB->LastClipped++; \
VB->ClipMask[newvert] = 0; \
outlist[outcount++] = newvert; \
if (NEGATIVE(dp)) { \
/* Going out of bounds. Avoid division by zero as we \
* know dp != dpPrev from DIFFERENT_SIGNS, above. \
*/ \
GLfloat t = dp / (dp - dpPrev); \
INTERP_4F(t, coord[newvert], coord[idx], coord[idxPrev]); \
interp(ctx, t, newvert, idx, idxPrev, GL_TRUE); \
} \
else { \
/* Coming back in. \
*/ \
GLfloat t = dpPrev / (dpPrev - dp); \
INTERP_4F(t, coord[newvert], coord[idxPrev], coord[idx]); \
interp(ctx, t, newvert, idxPrev, idx, GL_FALSE); \
} \
} \
\
idxPrev = idx; \
dpPrev = dp; \
} \
\
if (outcount < 3) \
return; \
\
{ \
GLuint *tmp = inlist; \
inlist = outlist; \
outlist = tmp; \
n = outcount; \
} \
} \
} while (0)
#define LINE_CLIP(PLANE, A, B, C, D) \
do { \
if (mask & PLANE) { \
GLfloat dpI = CLIP_DOTPROD(ii, A, B, C, D); \
GLfloat dpJ = CLIP_DOTPROD(jj, A, B, C, D); \
\
if (DIFFERENT_SIGNS(dpI, dpJ)) { \
GLuint newvert = VB->LastClipped++; \
VB->ClipMask[newvert] = 0; \
if (NEGATIVE(dpJ)) { \
GLfloat t = dpI / (dpI - dpJ); \
VB->ClipMask[jj] |= PLANE; \
INTERP_4F(t, coord[newvert], coord[ii], coord[jj]); \
interp(ctx, t, newvert, ii, jj, GL_FALSE); \
jj = newvert; \
} \
else { \
GLfloat t = dpJ / (dpJ - dpI); \
VB->ClipMask[ii] |= PLANE; \
INTERP_4F(t, coord[newvert], coord[jj], coord[ii]); \
interp(ctx, t, newvert, jj, ii, GL_FALSE); \
ii = newvert; \
} \
} \
else if (NEGATIVE(dpI)) \
return; \
} \
} while (0)
/* Clip a line against the viewport and user clip planes.
*/
static INLINE void
TAG(clip_line)(GLcontext *ctx, GLuint i, GLuint j, GLubyte mask)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
tnl_interp_func interp = tnl->Driver.Render.Interp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint ii = i, jj = j, p;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
VB->LastClipped = VB->Count;
if (mask & 0x3f) {
LINE_CLIP(CLIP_RIGHT_BIT, -1, 0, 0, 1);
LINE_CLIP(CLIP_LEFT_BIT, 1, 0, 0, 1);
LINE_CLIP(CLIP_TOP_BIT, 0, -1, 0, 1);
LINE_CLIP(CLIP_BOTTOM_BIT, 0, 1, 0, 1);
LINE_CLIP(CLIP_FAR_BIT, 0, 0, -1, 1);
LINE_CLIP(CLIP_NEAR_BIT, 0, 0, 1, 1);
}
if (mask & CLIP_USER_BIT) {
for (p = 0; p < MAX_CLIP_PLANES; p++) {
if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
GLfloat a = ctx->Transform._ClipUserPlane[p][0];
GLfloat b = ctx->Transform._ClipUserPlane[p][1];
GLfloat c = ctx->Transform._ClipUserPlane[p][2];
GLfloat d = ctx->Transform._ClipUserPlane[p][3];
LINE_CLIP(CLIP_USER_BIT, a, b, c, d);
}
}
}
if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj)
tnl->Driver.Render.CopyPV(ctx, jj, j);
tnl->Driver.Render.ClippedLine(ctx, ii, jj);
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
/* Clip a triangle against the viewport and user clip planes.
*/
static INLINE void
TAG(clip_tri)(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
tnl_interp_func interp = tnl->Driver.Render.Interp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint pv = v2;
GLuint vlist[2][MAX_CLIPPED_VERTICES];
GLuint *inlist = vlist[0], *outlist = vlist[1];
GLuint p;
GLubyte *clipmask = VB->ClipMask;
GLuint n = 3;
ASSIGN_3V(inlist, v2, v0, v1); /* pv rotated to slot zero */
VB->LastClipped = VB->Count;
if (mask & 0x3f) {
POLY_CLIP(CLIP_RIGHT_BIT, -1, 0, 0, 1);
POLY_CLIP(CLIP_LEFT_BIT, 1, 0, 0, 1);
POLY_CLIP(CLIP_TOP_BIT, 0, -1, 0, 1);
POLY_CLIP(CLIP_BOTTOM_BIT, 0, 1, 0, 1);
POLY_CLIP(CLIP_FAR_BIT, 0, 0, -1, 1);
POLY_CLIP(CLIP_NEAR_BIT, 0, 0, 1, 1);
}
if (mask & CLIP_USER_BIT) {
for (p = 0; p < MAX_CLIP_PLANES; p++) {
if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
GLfloat a = ctx->Transform._ClipUserPlane[p][0];
GLfloat b = ctx->Transform._ClipUserPlane[p][1];
GLfloat c = ctx->Transform._ClipUserPlane[p][2];
GLfloat d = ctx->Transform._ClipUserPlane[p][3];
POLY_CLIP(CLIP_USER_BIT, a, b, c, d);
}
}
}
if (ctx->_TriangleCaps & DD_FLATSHADE) {
if (pv != inlist[0]) {
ASSERT(inlist[0] >= VB->Count);
tnl->Driver.Render.CopyPV(ctx, inlist[0], pv);
}
}
tnl->Driver.Render.ClippedPolygon(ctx, inlist, n);
}
/* Clip a quad against the viewport and user clip planes.
*/
static INLINE void
TAG(clip_quad)(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3,
GLubyte mask)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
tnl_interp_func interp = tnl->Driver.Render.Interp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint pv = v3;
GLuint vlist[2][MAX_CLIPPED_VERTICES];
GLuint *inlist = vlist[0], *outlist = vlist[1];
GLuint p;
GLubyte *clipmask = VB->ClipMask;
GLuint n = 4;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
ASSIGN_4V(inlist, v3, v0, v1, v2); /* pv rotated to slot zero */
VB->LastClipped = VB->Count;
if (mask & 0x3f) {
POLY_CLIP(CLIP_RIGHT_BIT, -1, 0, 0, 1);
POLY_CLIP(CLIP_LEFT_BIT, 1, 0, 0, 1);
POLY_CLIP(CLIP_TOP_BIT, 0, -1, 0, 1);
POLY_CLIP(CLIP_BOTTOM_BIT, 0, 1, 0, 1);
POLY_CLIP(CLIP_FAR_BIT, 0, 0, -1, 1);
POLY_CLIP(CLIP_NEAR_BIT, 0, 0, 1, 1);
}
if (mask & CLIP_USER_BIT) {
for (p = 0; p < MAX_CLIP_PLANES; p++) {
if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
GLfloat a = ctx->Transform._ClipUserPlane[p][0];
GLfloat b = ctx->Transform._ClipUserPlane[p][1];
GLfloat c = ctx->Transform._ClipUserPlane[p][2];
GLfloat d = ctx->Transform._ClipUserPlane[p][3];
POLY_CLIP(CLIP_USER_BIT, a, b, c, d);
}
}
}
if (ctx->_TriangleCaps & DD_FLATSHADE) {
if (pv != inlist[0]) {
ASSERT(inlist[0] >= VB->Count);
tnl->Driver.Render.CopyPV(ctx, inlist[0], pv);
}
}
tnl->Driver.Render.ClippedPolygon(ctx, inlist, n);
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#undef W
#undef Z
#undef Y
#undef X
#undef SIZE
#undef TAG
#undef POLY_CLIP
#undef LINE_CLIP

View file

@ -1,444 +0,0 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, 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, 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
*/
#ifndef POSTFIX
#define POSTFIX
#endif
#ifndef INIT
#define INIT(x)
#endif
#ifndef NEED_EDGEFLAG_SETUP
#define NEED_EDGEFLAG_SETUP 0
#define EDGEFLAG_GET(a) 0
#define EDGEFLAG_SET(a,b) (void)b
#endif
#ifndef RESET_STIPPLE
#define RESET_STIPPLE
#endif
#ifndef RESET_OCCLUSION
#define RESET_OCCLUSION
#endif
#ifndef TEST_PRIM_END
#define TEST_PRIM_END(flags) (flags & PRIM_END)
#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
#endif
#ifndef ELT
#define ELT(x) x
#endif
#ifndef RENDER_TAB_QUALIFIER
#define RENDER_TAB_QUALIFIER static
#endif
static void TAG(render_points)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
LOCAL_VARS;
(void)flags;
RESET_OCCLUSION;
INIT(GL_POINTS);
RENDER_POINTS(start, count);
POSTFIX;
}
static void TAG(render_lines)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
RESET_OCCLUSION;
INIT(GL_LINES);
for (j = start + 1; j < count; j += 2) {
RESET_STIPPLE;
RENDER_LINE(ELT(j - 1), ELT(j));
}
POSTFIX;
}
static void TAG(render_line_strip)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
RESET_OCCLUSION;
INIT(GL_LINES);
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
for (j = start + 1; j < count; j++)
RENDER_LINE(ELT(j - 1), ELT(j));
POSTFIX;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_line_loop)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint i;
LOCAL_VARS;
(void)flags;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
RESET_OCCLUSION;
INIT(GL_LINES);
if (start + 1 < count) {
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
RENDER_LINE(ELT(start), ELT(start + 1));
}
for (i = start + 2 ; i < count ; i++) {
RENDER_LINE(ELT(i - 1), ELT(i));
}
if (TEST_PRIM_END(flags)) {
RENDER_LINE(ELT(count - 1), ELT(start));
}
}
POSTFIX;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_triangles)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 2; j < count; j += 3) {
/* Leave the edgeflags as supplied by the user.
*/
RESET_STIPPLE;
RENDER_TRI(ELT(j - 2), ELT(j - 1), ELT(j));
}
}
else {
for (j = start + 2; j < count; j += 3) {
RENDER_TRI(ELT(j - 2), ELT(j - 1), ELT(j));
}
}
POSTFIX;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_tri_strip)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
GLuint parity = 0;
LOCAL_VARS;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 2; j < count; j++, parity ^= 1) {
GLuint ej2 = ELT(j - 2 + parity);
GLuint ej1 = ELT(j - 1 - parity);
GLuint ej = ELT(j);
GLboolean ef2 = EDGEFLAG_GET(ej2);
GLboolean ef1 = EDGEFLAG_GET(ej1);
GLboolean ef = EDGEFLAG_GET(ej);
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
EDGEFLAG_SET(ej2, GL_TRUE);
EDGEFLAG_SET(ej1, GL_TRUE);
EDGEFLAG_SET(ej, GL_TRUE);
RENDER_TRI(ej2, ej1, ej);
EDGEFLAG_SET(ej2, ef2);
EDGEFLAG_SET(ej1, ef1);
EDGEFLAG_SET(ej, ef);
}
}
else {
for (j = start + 2; j < count; j++, parity ^= 1) {
RENDER_TRI(ELT(j - 2 + parity), ELT(j - 1 - parity), ELT(j));
}
}
POSTFIX;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_tri_fan)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 2; j < count; j++) {
/* For trifans, all edges are boundary.
*/
GLuint ejs = ELT(start);
GLuint ej1 = ELT(j - 1);
GLuint ej = ELT(j);
GLboolean efs = EDGEFLAG_GET(ejs);
GLboolean ef1 = EDGEFLAG_GET(ej1);
GLboolean ef = EDGEFLAG_GET(ej);
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
EDGEFLAG_SET(ejs, GL_TRUE);
EDGEFLAG_SET(ej1, GL_TRUE);
EDGEFLAG_SET(ej, GL_TRUE);
RENDER_TRI(ejs, ej1, ej);
EDGEFLAG_SET(ejs, efs);
EDGEFLAG_SET(ej1, ef1);
EDGEFLAG_SET(ej, ef);
}
}
else {
for (j = start + 2; j < count; j++) {
RENDER_TRI(ELT(start), ELT(j - 1), ELT(j));
}
}
POSTFIX;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_poly)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j = start + 2;
LOCAL_VARS;
(void)flags;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
GLboolean efstart = EDGEFLAG_GET(ELT(start));
GLboolean efcount = EDGEFLAG_GET(ELT(count - 1));
/* If the primitive does not begin here, the first edge
* is non-boundary.
*/
if (!TEST_PRIM_BEGIN(flags)) {
EDGEFLAG_SET(ELT(start), GL_FALSE);
}
else {
RESET_STIPPLE;
}
/* If the primitive does not end here, the final edge is
* non-boundary.
*/
if (!TEST_PRIM_END(flags)) {
EDGEFLAG_SET(ELT(count - 1), GL_FALSE);
}
/* Draw the first triangles (possibly zero)
*/
if (j+1<count) {
GLboolean ef = EDGEFLAG_GET(ELT(j));
EDGEFLAG_SET(ELT(j), GL_FALSE);
RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
EDGEFLAG_SET(ELT(j), ef);
j++;
/* Don't render the first edge again:
*/
EDGEFLAG_SET(ELT(start), GL_FALSE);
for (;j+1<count;j++) {
GLboolean efj = EDGEFLAG_GET(ELT(j));
EDGEFLAG_SET(ELT(j), GL_FALSE);
RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
EDGEFLAG_SET(ELT(j), efj);
}
}
/* Draw the last or only triangle
*/
if (j < count) {
RENDER_TRI(ELT(j-1), ELT(j), ELT(start));
}
/* Restore the first and last edgeflags:
*/
EDGEFLAG_SET(ELT(count - 1), efcount);
EDGEFLAG_SET(ELT(start), efstart);
}
else {
for (j = start + 2; j < count; j++) {
RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
}
}
POSTFIX;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_quads)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 3; j < count; j += 4) {
/* Use user-specified edgeflags for quads.
*/
RESET_STIPPLE;
RENDER_QUAD(ELT(j - 3), ELT(j - 2), ELT(j - 1), ELT(j));
}
}
else {
for (j = start + 3; j < count; j += 4) {
RENDER_QUAD(ELT(j - 3), ELT(j - 2), ELT(j - 1), ELT(j));
}
}
POSTFIX;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_quad_strip)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 3; j < count; j += 2) {
/* All edges are boundary. Set edgeflags to 1, draw the
* quad, and restore them to the original values.
*/
GLboolean ef3 = EDGEFLAG_GET(ELT(j - 3));
GLboolean ef2 = EDGEFLAG_GET(ELT(j - 2));
GLboolean ef1 = EDGEFLAG_GET(ELT(j - 1));
GLboolean ef = EDGEFLAG_GET(ELT(j));
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
EDGEFLAG_SET(ELT(j - 3), GL_TRUE);
EDGEFLAG_SET(ELT(j - 2), GL_TRUE);
EDGEFLAG_SET(ELT(j - 1), GL_TRUE);
EDGEFLAG_SET(ELT(j), GL_TRUE);
RENDER_QUAD(ELT(j - 1), ELT(j - 3), ELT(j - 2), ELT(j));
EDGEFLAG_SET(ELT(j - 3), ef3);
EDGEFLAG_SET(ELT(j - 2), ef2);
EDGEFLAG_SET(ELT(j - 1), ef1);
EDGEFLAG_SET(ELT(j), ef);
}
}
else {
for (j = start + 3; j < count; j += 2) {
RENDER_QUAD(ELT(j - 1), ELT(j - 3), ELT(j - 2), ELT(j));
}
}
POSTFIX;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
static void TAG(render_noop)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
(void)(ctx && start && count && flags);
}
RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON + 2])(GLcontext *,
GLuint,
GLuint,
GLuint) =
{
TAG(render_points),
TAG(render_lines),
TAG(render_line_loop),
TAG(render_line_strip),
TAG(render_triangles),
TAG(render_tri_strip),
TAG(render_tri_fan),
TAG(render_quads),
TAG(render_quad_strip),
TAG(render_poly),
TAG(render_noop),
};
#ifndef PRESERVE_VB_DEFS
#undef RENDER_TRI
#undef RENDER_QUAD
#undef RENDER_LINE
#undef RENDER_POINTS
#undef LOCAL_VARS
#undef INIT
#undef POSTFIX
#undef RESET_STIPPLE
#undef DBG
#undef ELT
#undef RENDER_TAB_QUALIFIER
#endif
#ifndef PRESERVE_TAG
#undef TAG
#endif
#undef PRESERVE_VB_DEFS
#undef PRESERVE_TAG