A new module to provide RasterSetup and advanced triangle/line/point

functionality layered on top of the software rasterizer.

An example entrypoint:
	void _swsetup_Triangle( GLcontext, GLuint, GLuint, GLuint, GLuint )

will coerce the software rasterizer to draw flat, twoside-lit,
unfilled and offset triangles (including decomposition to points or lines).
This commit is contained in:
Keith Whitwell
2000-11-05 18:20:18 +00:00
parent c6f348cbc9
commit 7c20642b10
10 changed files with 1260 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
INTRODUCTION
A helper module which provides glue to bind the software rasterizer to
the software t&l module. The main task of this module is to build
swrast vertices from the t&l vertex_buffer structs, and to use them to
perform triangle setup functions not implemented in the software
rasterizer.
The module provides a RasterSetup function to plug into the t&l driver
interface. This hook had previously been used for hardware
rasterizers, with the software rasterizer taking its data directly
from the vertex buffer.
There are strong advantages to decoupling the software rasterizer from
the t&l module, primarily allowing hardware drivers better control
over fallbacks, the removal of implicit knowledge about the software
rasterizer in the t&l module, allowing the two modules to evolve
independently and allowing either to be substituted with equivalent
functionality from another codebase.
This module provides helpers for triangle/quad setup for offset,
unfilled and twoside-lit triangles. The software rasterizer doesn't
handle these primitives directly.
Hardware rasterization drivers probably have little use for this
module. Rather, they might provide a layer that translates their
native (hardware) vertices to swrast vertices before calling into the
swrast module for fallbacks.
STATE
This module associates an array of SWvertex structs with each VB.
Thus there are:
GLboolean _swsetup_RegisterVB( struct vertex_buffer *VB );
void _swsetup_UnregisterVB( struct vertex_buffer *VB );
Which must be called to create and destroy internal vertex storage for
this module.
To create and destroy the module itself:
GLboolean _swsetup_CreateContext( GLcontext *ctx );
void _swsetup_DestroyContext( GLcontext *ctx );
Like the software rasterizer, this module tracks state changes
internally and maintains a set of entry points which will always
reflect the current state. For this to work, the driver must call:
void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state );
SERVICES
The module provides the following entrypoints:
void _swrast_RasterSetup( struct vertex_buffer *VB,
GLuint start, GLuint end );
Build SWvertices for <VB> between indices start and end.
void _swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint v3, GLuint pv );
void _swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint pv );
void _swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv );
void _swsetup_Points( GLcontext *ctx, GLuint first, GLuint last );
Draw quad, triangle, line, points. Note that these are in the format
expected by core mesa. The Quad and Triangle functions handle
unfilled, offset, twoside-lit and flat-shaded primitives correctly.
These functions can thus be plugged into the ctx->Driver struct and
left permanently in place, providing the InvalidateState() routine is
correctly called on state changes.

View File

@@ -0,0 +1,230 @@
/* $Id: ss_context.c,v 1.1 2000/11/05 18:20:18 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
#include "glheader.h"
#include "mem.h"
#include "ss_context.h"
#include "ss_triangle.h"
#include "ss_vb.h"
#include "swrast_setup.h"
/* Stub for swsetup->Triangle to select a true triangle function
* after a state change.
*/
static void
_swsetup_validate_quad( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint v3, GLuint pv )
{
_swsetup_choose_trifuncs( ctx );
SWSETUP_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3, pv );
}
static void
_swsetup_validate_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint pv )
{
_swsetup_choose_trifuncs( ctx );
SWSETUP_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2, pv );
}
static void
_swsetup_validate_line( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
{
_swsetup_choose_trifuncs( ctx );
SWSETUP_CONTEXT(ctx)->Line( ctx, v0, v1, pv );
}
static void
_swsetup_validate_points( GLcontext *ctx, GLuint first, GLuint last )
{
_swsetup_choose_trifuncs( ctx );
SWSETUP_CONTEXT(ctx)->Points( ctx, first, last );
}
static void
_swsetup_validate_rastersetup( struct vertex_buffer *VB,
GLuint start, GLuint end )
{
GLcontext *ctx = VB->ctx;
_swsetup_choose_rastersetup_func( ctx );
SWSETUP_CONTEXT(ctx)->RasterSetup( VB, start, end );
}
#define _SWSETUP_NEW_RASTERSETUP (_NEW_RENDERMODE| \
_NEW_TEXTURE| \
_NEW_COLOR| \
_NEW_FOG| \
_NEW_POINT)
#define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT)
#if 0
/* TODO: sleep/wakeup mechanism
*/
static void
_swsetup_sleep( GLcontext *ctx, GLuint new_state )
{
}
#endif
static void
_swsetup_invalidate_state( GLcontext *ctx, GLuint new_state )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
swsetup->NewState |= new_state;
if (new_state & _SWSETUP_NEW_RENDERINDEX) {
swsetup->Triangle = _swsetup_validate_triangle;
swsetup->Line = _swsetup_validate_line;
swsetup->Points = _swsetup_validate_points;
swsetup->Quad = _swsetup_validate_quad;
}
if (new_state & _SWSETUP_NEW_RASTERSETUP) {
swsetup->RasterSetup = _swsetup_validate_rastersetup;
}
}
/* Dispatch from these fixed entrypoints to the state-dependent
* functions:
*/
void
_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint v3, GLuint pv )
{
SWSETUP_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3, pv );
}
void
_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint pv )
{
SWSETUP_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2, pv );
}
void
_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
{
SWSETUP_CONTEXT(ctx)->Line( ctx, v0, v1, pv );
}
void
_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last )
{
SWSETUP_CONTEXT(ctx)->Points( ctx, first, last );
}
void
_swsetup_RasterSetup( struct vertex_buffer *VB, GLuint start, GLuint end )
{
SWSETUP_CONTEXT(VB->ctx)->RasterSetup( VB, start, end );
}
void
_swsetup_InvalidateState( GLcontext *ctx, GLuint new_state )
{
SWSETUP_CONTEXT(ctx)->InvalidateState( ctx, new_state );
}
GLboolean
_swsetup_CreateContext( GLcontext *ctx )
{
SScontext *swsetup = (SScontext *)CALLOC(sizeof(SScontext));
if (!swsetup)
return GL_FALSE;
ctx->swsetup_context = swsetup;
swsetup->NewState = ~0;
swsetup->InvalidateState = _swsetup_invalidate_state;
swsetup->Quad = _swsetup_validate_quad;
swsetup->Triangle = _swsetup_validate_triangle;
swsetup->Line = _swsetup_validate_line;
swsetup->Points = _swsetup_validate_points;
swsetup->RasterSetup = _swsetup_validate_rastersetup;
_swsetup_vb_init( ctx );
_swsetup_trifuncs_init( ctx );
return GL_TRUE;
}
void
_swsetup_DestroyContext( GLcontext *ctx )
{
if (SWSETUP_CONTEXT(ctx)) {
FREE(SWSETUP_CONTEXT(ctx));
ctx->swsetup_context = 0;
}
}
GLboolean
_swsetup_RegisterVB( struct vertex_buffer *VB )
{
SSvertexbuffer *ssvb = (SSvertexbuffer *)CALLOC(sizeof(SSvertexbuffer) );
ssvb->verts = ALIGN_MALLOC( sizeof(SWvertex) * VB->Size, 32);
if (!ssvb->verts) {
FREE(ssvb);
return GL_FALSE;
}
VB->swsetup_vb = ssvb;
return GL_TRUE;
}
void
_swsetup_UnregisterVB( struct vertex_buffer *VB )
{
SSvertexbuffer *ssvb = SWSETUP_VB(VB);
if (ssvb) {
if (ssvb->verts) ALIGN_FREE(ssvb->verts);
FREE(ssvb);
VB->swsetup_vb = 0;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
#ifndef SS_CONTEXT_H
#define SS_CONTEXT_H
#include "types.h"
#include "swrast/swrast.h"
#include "swrast_setup.h"
typedef struct {
GLuint NewState;
GLuint StateChanges;
/* Function hooks, trigger lazy state updates.
*/
void (*InvalidateState)( GLcontext *ctx, GLuint new_state );
void (*RasterSetup)( struct vertex_buffer *VB, GLuint start, GLuint end );
void (*Quad)( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint v3, GLuint pv );
void (*Triangle)( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint pv );
void (*Line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv );
void (*Points)( GLcontext *ctx, GLuint first, GLuint last );
} SScontext;
typedef struct {
SWvertex *verts;
} SSvertexbuffer;
#define SWSETUP_CONTEXT(ctx) ((SScontext *)ctx->swsetup_context)
#define SWSETUP_VB(VB) ((SSvertexbuffer *)VB->swsetup_vb)
#endif

View File

@@ -0,0 +1,161 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
#include "glheader.h"
#include "macros.h"
#include "types.h"
#include "ss_triangle.h"
#include "ss_context.h"
#define SS_FLAT_BIT 0x1
#define SS_OFFSET_BIT 0x2
#define SS_TWOSIDE_BIT 0x4
#define SS_UNFILLED_BIT 0x10
#define SS_MAX_TRIFUNC 0x20
static triangle_func tri_tab[SS_MAX_TRIFUNC];
static line_func line_tab[SS_MAX_TRIFUNC];
static points_func points_tab[SS_MAX_TRIFUNC];
static quad_func quad_tab[SS_MAX_TRIFUNC];
#define SS_COLOR(a,b) COPY_4UBV(a,b)
#define SS_SPEC(a,b) COPY_4UBV(a,b)
#define SS_IND(a,b) (a = b)
#define IND (0)
#define TAG(x) x
#include "ss_tritmp.h"
#define IND (SS_FLAT_BIT)
#define TAG(x) x##_flat
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT)
#define TAG(x) x##_offset
#include "ss_tritmp.h"
#define IND (SS_FLAT_BIT|SS_OFFSET_BIT)
#define TAG(x) x##_flat_offset
#include "ss_tritmp.h"
#define IND (SS_TWOSIDE_BIT)
#define TAG(x) x##_twoside
#include "ss_tritmp.h"
#define IND (SS_FLAT_BIT|SS_TWOSIDE_BIT)
#define TAG(x) x##_flat_twoside
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT)
#define TAG(x) x##_offset_twoside
#include "ss_tritmp.h"
#define IND (SS_FLAT_BIT|SS_OFFSET_BIT|SS_TWOSIDE_BIT)
#define TAG(x) x##_flat_offset_twoside
#include "ss_tritmp.h"
#define IND (SS_UNFILLED_BIT)
#define TAG(x) x##_unfilled
#include "ss_tritmp.h"
#define IND (SS_FLAT_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_flat_unfilled
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_offset_unfilled
#include "ss_tritmp.h"
#define IND (SS_FLAT_BIT|SS_OFFSET_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_flat_offset_unfilled
#include "ss_tritmp.h"
#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_twoside_unfilled
#include "ss_tritmp.h"
#define IND (SS_FLAT_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_flat_twoside_unfilled
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_offset_twoside_unfilled
#include "ss_tritmp.h"
#define IND (SS_FLAT_BIT|SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_flat_offset_twoside_unfilled
#include "ss_tritmp.h"
void _swsetup_trifuncs_init( GLcontext *ctx )
{
(void) ctx;
init();
init_flat();
init_offset();
init_flat_offset();
init_twoside();
init_flat_twoside();
init_offset_twoside();
init_flat_offset_twoside();
init_unfilled();
init_flat_unfilled();
init_offset_unfilled();
init_flat_offset_unfilled();
init_twoside_unfilled();
init_flat_twoside_unfilled();
init_offset_twoside_unfilled();
init_flat_offset_twoside_unfilled();
}
void _swsetup_choose_trifuncs( GLcontext *ctx )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
GLuint ind = 0;
if (ctx->Light.ShadeModel == GL_FLAT)
ind |= SS_FLAT_BIT;
if (ctx->Polygon._OffsetAny)
ind |= SS_OFFSET_BIT;
if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
ind |= SS_TWOSIDE_BIT;
if (ctx->Polygon._Unfilled)
ind |= SS_UNFILLED_BIT;
swsetup->Triangle = tri_tab[ind];
swsetup->Line = line_tab[ind];
swsetup->Points = points_tab[ind];
swsetup->Quad = quad_tab[ind];
}

View File

@@ -0,0 +1,38 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
#ifndef SS_TRIANGLE_H
#define SS_TRIANGLE_H
#include "types.h"
#include "ss_context.h"
void _swsetup_trifuncs_init( GLcontext *ctx );
void _swsetup_choose_trifuncs( GLcontext *ctx );
#endif

View File

@@ -0,0 +1,286 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
static void TAG(triangle)(GLcontext *ctx,
GLuint e0, GLuint e1, GLuint e2,
GLuint pv)
{
struct vertex_buffer *VB = ctx->VB;
SWvertex *verts = SWSETUP_VB(VB)->verts;
SWvertex *v[3];
GLfloat offset;
GLfloat z[3];
GLubyte c[3][4], s[3][4];
GLuint i[3];
GLenum mode = GL_FILL;
v[0] = &verts[e0];
v[1] = &verts[e1];
v[2] = &verts[e2];
if (IND & (SS_TWOSIDE_BIT | SS_FLAT_BIT)) {
SS_COLOR(c[0], v[0]->color);
SS_COLOR(c[1], v[1]->color);
SS_COLOR(c[2], v[2]->color);
SS_SPEC(s[0], v[0]->specular);
SS_SPEC(s[1], v[1]->specular);
SS_SPEC(s[2], v[2]->specular);
SS_IND(i[0], v[0]->index);
SS_IND(i[1], v[1]->index);
SS_IND(i[2], v[2]->index);
}
if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT))
{
GLfloat ex = v[0]->win[0] - v[2]->win[0];
GLfloat ey = v[0]->win[1] - v[2]->win[1];
GLfloat fx = v[1]->win[0] - v[2]->win[0];
GLfloat fy = v[1]->win[1] - v[2]->win[1];
GLfloat cc = ex*fy - ey*fx;
if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT))
{
GLuint facing = (cc < 0.0) ^ ctx->Polygon.FrontBit;
if (IND & SS_UNFILLED_BIT)
mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;
if (IND & SS_TWOSIDE_BIT) {
GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
GLubyte (*vbspec)[4] = VB->SecondaryColor[facing]->data;
GLuint *vbindex = VB->Index[facing]->data;
if (IND & SS_FLAT_BIT) {
SS_COLOR(v[0]->color, vbcolor[pv]);
SS_COLOR(v[1]->color, vbcolor[pv]);
SS_COLOR(v[2]->color, vbcolor[pv]);
SS_SPEC(v[0]->specular, vbspec[pv]);
SS_SPEC(v[1]->specular, vbspec[pv]);
SS_SPEC(v[2]->specular, vbspec[pv]);
SS_IND(v[0]->index, vbindex[pv]);
SS_IND(v[1]->index, vbindex[pv]);
SS_IND(v[2]->index, vbindex[pv]);
} else {
SS_COLOR(v[0]->color, vbcolor[e0]);
SS_COLOR(v[1]->color, vbcolor[e1]);
SS_COLOR(v[2]->color, vbcolor[e2]);
SS_SPEC(v[0]->specular, vbspec[e0]);
SS_SPEC(v[1]->specular, vbspec[e1]);
SS_SPEC(v[2]->specular, vbspec[e2]);
SS_IND(v[0]->index, vbindex[e0]);
SS_IND(v[1]->index, vbindex[e1]);
SS_IND(v[2]->index, vbindex[e2]);
}
}
}
if (IND & SS_OFFSET_BIT)
{
offset = ctx->Polygon.OffsetUnits;
z[0] = v[0]->win[2];
z[1] = v[1]->win[2];
z[2] = v[2]->win[2];
if (cc * cc > 1e-16) {
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 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;
}
}
}
else if(IND & SS_FLAT_BIT)
{
GLubyte *color = VB->Color[0]->data[pv];
GLubyte *spec = VB->SecondaryColor[0]->data[pv];
GLuint index = VB->Index[0]->data[pv];
SS_COLOR(v[0]->color, color);
SS_COLOR(v[1]->color, color);
SS_COLOR(v[2]->color, color);
SS_SPEC(v[0]->specular, spec);
SS_SPEC(v[1]->specular, spec);
SS_SPEC(v[2]->specular, spec);
SS_IND(v[0]->index, index);
SS_IND(v[1]->index, index);
SS_IND(v[2]->index, index);
}
if (mode == GL_POINT) {
GLubyte *ef = VB->EdgeFlagPtr->data;
if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) {
v[0]->win[2] += offset;
v[1]->win[2] += offset;
v[2]->win[2] += offset;
}
if (ef[e0]&0x1) { ef[e0] &= ~0x1; _swrast_Point( ctx, v[0] ); }
if (ef[e1]&0x1) { ef[e1] &= ~0x1; _swrast_Point( ctx, v[1] ); }
if (ef[e2]&0x2) { ef[e2] &= ~0x2; _swrast_Point( ctx, v[2] ); }
} else if (mode == GL_LINE) {
GLubyte *ef = VB->EdgeFlagPtr->data;
if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) {
v[0]->win[2] += offset;
v[1]->win[2] += offset;
v[2]->win[2] += offset;
}
if (ef[e0]&0x1) { ef[e0] &= ~0x1; _swrast_Line( ctx, v[0], v[1] ); }
if (ef[e1]&0x1) { ef[e1] &= ~0x1; _swrast_Line( ctx, v[1], v[2] ); }
if (ef[e2]&0x2) { ef[e2] &= ~0x2; _swrast_Line( ctx, v[2], v[0] ); }
} else {
if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) {
v[0]->win[2] += offset;
v[1]->win[2] += offset;
v[2]->win[2] += offset;
}
_swrast_Triangle( ctx, v[0], v[1], v[2] );
}
if (IND & SS_OFFSET_BIT) {
v[0]->win[2] = z[0];
v[1]->win[2] = z[1];
v[2]->win[2] = z[2];
}
if (IND & (SS_FLAT_BIT | SS_TWOSIDE_BIT)) {
SS_COLOR(v[0]->color, c[0]);
SS_COLOR(v[1]->color, c[1]);
SS_COLOR(v[2]->color, c[2]);
SS_SPEC(v[0]->specular, s[0]);
SS_SPEC(v[1]->specular, s[1]);
SS_SPEC(v[2]->specular, s[2]);
SS_IND(v[0]->index, i[0]);
SS_IND(v[1]->index, i[1]);
SS_IND(v[2]->index, i[2]);
}
}
/* Need to do something with edgeflags:
*/
static void TAG(quad)( GLcontext *ctx, GLuint v0,
GLuint v1, GLuint v2, GLuint v3,
GLuint pv )
{
TAG(triangle)( ctx, v0, v1, v3, pv );
TAG(triangle)( ctx, v1, v2, v3, pv );
}
static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
{
struct vertex_buffer *VB = ctx->VB;
SWvertex *verts = SWSETUP_VB(VB)->verts;
GLubyte c[2][4], s[2][4];
GLuint i[2];
SWvertex *vert0 = &verts[v0];
SWvertex *vert1 = &verts[v1];
if (IND & SS_FLAT_BIT) {
GLubyte *color = VB->Color[0]->data[pv];
GLubyte *spec = VB->SecondaryColor[0]->data[pv];
GLuint index = VB->Index[0]->data[pv];
SS_COLOR(c[0], vert0->color);
SS_COLOR(c[1], vert1->color);
SS_SPEC(s[0], vert0->specular);
SS_SPEC(s[1], vert1->specular);
SS_IND(i[0], vert0->index);
SS_IND(i[1], vert1->index);
SS_COLOR(vert0->color, color);
SS_COLOR(vert1->color, color);
SS_SPEC(vert0->specular, spec);
SS_SPEC(vert1->specular, spec);
SS_IND(vert0->index, index);
SS_IND(vert1->index, index);
}
_swrast_Line( ctx, vert0, vert1 );
if (IND & SS_FLAT_BIT) {
SS_COLOR(vert0->color, c[0]);
SS_COLOR(vert1->color, c[1]);
SS_SPEC(vert0->specular, s[0]);
SS_SPEC(vert1->specular, s[1]);
SS_IND(vert0->index, i[0]);
SS_IND(vert1->index, i[1]);
}
}
static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
SWvertex *verts = SWSETUP_VB(VB)->verts;
int i;
for(i=first;i<=last;i++)
if(VB->ClipMask[i]==0)
_swrast_Point( ctx, &verts[i] );
}
static void TAG(init)( void )
{
tri_tab[IND] = TAG(triangle);
quad_tab[IND] = TAG(quad);
line_tab[IND] = TAG(line);
points_tab[IND] = TAG(points);
}
#undef IND
#undef TAG

View File

@@ -0,0 +1,173 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
#include "glheader.h"
#include "macros.h"
#include "stages.h"
#include "swrast/swrast.h"
#include "ss_context.h"
#include "ss_vb.h"
/* Provides a RasterSetup function which prebuilds vertices for the
* software rasterizer. This is required for the triangle functions
* in this module, but not the rest of the swrast module.
*/
typedef void (*SetupFunc)( struct vertex_buffer *VB,
GLuint start, GLuint end );
#define COLOR 0x1
#define INDEX 0x2
#define TEX0 0x4
#define MULTITEX 0x8
#define SPEC 0x10
#define FOG 0x20
#define EYE 0x40
#define MAX_SETUPFUNC 0x80
static SetupFunc setup_func[MAX_SETUPFUNC];
#define IND (COLOR)
#define TAG(x) x##_color
#include "ss_vbtmp.h"
#define IND (INDEX)
#define TAG(x) x##_index
#include "ss_vbtmp.h"
#define IND (TEX0|COLOR)
#define TAG(x) x##_tex0_color
#include "ss_vbtmp.h"
#define IND (TEX0|COLOR|SPEC)
#define TAG(x) x##_tex0_color_spec
#include "ss_vbtmp.h"
#define IND (TEX0|COLOR|SPEC|FOG)
#define TAG(x) x##_tex0_color_spec_fog
#include "ss_vbtmp.h"
#define IND (MULTITEX|COLOR)
#define TAG(x) x##_multitex_color
#include "ss_vbtmp.h"
#define IND (MULTITEX|COLOR|SPEC|FOG)
#define TAG(x) x##_multitex_color_spec_fog
#include "ss_vbtmp.h"
#define IND (TEX0|COLOR|EYE)
#define TAG(x) x##_tex0_color_eye
#include "ss_vbtmp.h"
#define IND (MULTITEX|COLOR|SPEC|INDEX|EYE|FOG)
#define TAG(x) x##_multitex_color_spec_index_eye_fog
#include "ss_vbtmp.h"
void
_swsetup_vb_init( GLcontext *ctx )
{
int i;
(void) ctx;
for (i = 0 ; i < Elements(setup_func) ; i++)
setup_func[i] = rs_multitex_color_spec_index_eye_fog;
/* Some specialized cases:
*/
setup_func[0] = rs_color;
setup_func[COLOR] = rs_color;
setup_func[INDEX] = rs_index;
setup_func[TEX0] = rs_tex0_color;
setup_func[TEX0|COLOR] = rs_tex0_color;
setup_func[SPEC] = rs_tex0_color_spec;
setup_func[COLOR|SPEC] = rs_tex0_color_spec;
setup_func[TEX0|SPEC] = rs_tex0_color_spec;
setup_func[TEX0|COLOR|SPEC] = rs_tex0_color_spec;
setup_func[MULTITEX] = rs_multitex_color;
setup_func[MULTITEX|COLOR] = rs_multitex_color;
setup_func[FOG] = rs_tex0_color_spec_fog;
setup_func[COLOR|FOG] = rs_tex0_color_spec_fog;
setup_func[SPEC|FOG] = rs_tex0_color_spec_fog;
setup_func[COLOR|SPEC|FOG] = rs_tex0_color_spec_fog;
setup_func[TEX0|FOG] = rs_tex0_color_spec_fog;
setup_func[TEX0|COLOR|FOG] = rs_tex0_color_spec_fog;
setup_func[TEX0|SPEC|FOG] = rs_tex0_color_spec_fog;
setup_func[TEX0|COLOR|SPEC|FOG] = rs_tex0_color_spec_fog;
setup_func[MULTITEX|SPEC] = rs_multitex_color_spec_fog;
setup_func[MULTITEX|COLOR|SPEC] = rs_multitex_color_spec_fog;
setup_func[MULTITEX|FOG] = rs_multitex_color_spec_fog;
setup_func[MULTITEX|SPEC|FOG] = rs_multitex_color_spec_fog;
setup_func[MULTITEX|COLOR|SPEC|FOG] = rs_multitex_color_spec_fog;
setup_func[TEX0|EYE] = rs_tex0_color_eye;
setup_func[TEX0|COLOR|EYE] = rs_tex0_color_eye;
}
void
_swsetup_choose_rastersetup_func(GLcontext *ctx)
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
int funcindex;
if (ctx->Visual.RGBAflag) {
funcindex = COLOR;
if (ctx->Texture._ReallyEnabled & ~0xf)
funcindex |= MULTITEX;
else if (ctx->Texture._ReallyEnabled & 0xf)
funcindex |= TEX0;
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
ctx->Fog.ColorSumEnabled)
funcindex |= SPEC;
if (ctx->Point._Attenuated)
funcindex |= EYE;
}
else
funcindex = INDEX;
if (ctx->RenderMode != GL_RENDER)
funcindex = (INDEX|COLOR|MULTITEX);
swsetup->RasterSetup = setup_func[funcindex];
}

View File

@@ -0,0 +1,37 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
#ifndef SS_VB_H
#define SS_VB_H
#include "types.h"
#include "swrast_setup.h"
void _swsetup_vb_init( GLcontext *ctx );
void _swsetup_choose_rastersetup_func( GLcontext *ctx );
#endif

View File

@@ -0,0 +1,117 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
static void TAG(rs)(struct vertex_buffer *VB, GLuint start, GLuint end)
{
GLcontext *ctx = VB->ctx;
SWvertex *v;
GLfloat (*eye)[4];
GLfloat (*win)[4];
GLfloat (*tc[MAX_TEXTURE_UNITS])[4];
GLubyte (*color)[4];
GLubyte (*spec)[4];
GLuint *index;
GLfloat *fog;
GLuint sz[MAX_TEXTURE_UNITS];
GLuint szeye;
int i;
/* TODO: Do window map here.
*/
/* GLfloat *m = VB->ctx->Viewport.WindowMap.m; */
/* const GLfloat sx = m[0]; */
/* const GLfloat sy = m[5]; */
/* const GLfloat sz = m[10] * ctx->Visual->DepthMaxF; */
/* const GLfloat tx = m[12]; */
/* const GLfloat ty = m[13]; */
/* const GLfloat tz = m[14] * ctx->Visual->DepthMaxF; */
/* TODO: Get import_client_data to pad vectors out to 4 cleanly.
*/
gl_import_client_data( VB, ctx->_RenderFlags,
(VB->ClipOrMask
? /* VEC_CLEAN| */VEC_WRITABLE|VEC_GOOD_STRIDE
: /* VEC_CLEAN| */VEC_GOOD_STRIDE));
if (IND & TEX0) {
tc[0] = VB->TexCoordPtr[0]->data;
sz[0] = VB->TexCoordPtr[0]->size;
}
if (IND & MULTITEX) {
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
tc[i] = VB->TexCoordPtr[i]->data;
sz[i] = VB->TexCoordPtr[i]->size;
}
}
fog = VB->FogCoordPtr->data;
eye = VB->EyePtr->data;
szeye = VB->EyePtr->size;
win = VB->Win.data;
color = VB->Color[0]->data;
spec = VB->SecondaryColor[0]->data;
index = VB->Index[0]->data;
v = &(SWSETUP_VB(VB)->verts[start]);
for (i=start; i < end; i++, v++) {
if (VB->ClipMask[i] == 0) {
COPY_4FV( v->win, win[i] );
if (IND & EYE)
COPY_4FV( v->eye, eye[i] );
if (IND & TEX0)
COPY_CLEAN_4V( v->texcoord[0], sz[0], tc[0][i] );
if (IND & MULTITEX) {
GLuint u;
for (u = 0 ; u < MAX_TEXTURE_UNITS ; u++)
if (ctx->Texture.Unit[u]._ReallyEnabled)
COPY_CLEAN_4V( v->texcoord[u], sz[u], tc[u][i] );
}
if (IND & COLOR)
COPY_4UBV(v->color, color[i]);
if (IND & SPEC)
COPY_4UBV(v->specular, spec[i]);
if (IND & FOG)
v->fog = fog[i];
if (IND & INDEX)
v->index = index[i];
}
}
}
#undef TAG
#undef IND

View File

@@ -0,0 +1,70 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keithw@valinux.com>
*/
/* Public interface to the swrast_setup module.
*/
#ifndef SWRAST_SETUP_H
#define SWRAST_SETUP_H
GLboolean
_swsetup_CreateContext( GLcontext *ctx );
void
_swsetup_DestroyContext( GLcontext *ctx );
GLboolean
_swsetup_RegisterVB( struct vertex_buffer *VB );
void
_swsetup_UnregisterVB( struct vertex_buffer *VB );
void
_swsetup_InvalidateState( GLcontext *ctx, GLuint new_state );
void
_swsetup_RasterSetup( struct vertex_buffer *VB,
GLuint start, GLuint end );
void
_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint v3, GLuint pv );
void
_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint pv );
void
_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv );
void
_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last );
#endif