Rename some of the tnl->Driver.* functions to tnl->Driver.Render.*, to make it

clear that these are owned by t_vb_render.c.

Make swrast_setup opaque - it now hooks itself directly into
tnl->Driver.Render.*.  Add a _swsetup_Wakeup() call that does this.

Update X11 (tested), osmesa and FX drivers for this change.

FX compiles but is probably broken as the changes there are large.  It was the
only remaining driver that used the internal _swsetup_ functions for
interp and copy_pv.  This usage has been replaced with code from the DRI
tdfx driver.
This commit is contained in:
Keith Whitwell 2001-07-12 22:09:21 +00:00
parent fae7b778b8
commit 1182ffeec3
24 changed files with 1871 additions and 1812 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile.X11,v 1.55 2001/06/27 12:52:12 keithw Exp $
# $Id: Makefile.X11,v 1.56 2001/07/12 22:09:21 keithw Exp $
# Mesa 3-D graphics library
# Version: 3.5
@ -21,6 +21,9 @@ LIBDIR = ../lib
CORE_SOURCES = \
swrast_setup/ss_context.c \
swrast_setup/ss_triangle.c \
swrast_setup/ss_vb.c \
api_arrayelt.c \
api_loopback.c \
api_noop.c \
@ -118,10 +121,6 @@ CORE_SOURCES = \
swrast/s_texstore.c \
swrast/s_triangle.c \
swrast/s_zoom.c \
swrast_setup/ss_context.c \
swrast_setup/ss_triangle.c \
swrast_setup/ss_vb.c \
swrast_setup/ss_interp.c \
tnl/t_array_api.c \
tnl/t_array_import.c \
tnl/t_context.c \

View file

@ -674,11 +674,6 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
if (getenv("FX_EMULATE_SINGLE_TMU"))
fxMesa->haveTwoTMUs = GL_FALSE;
fxMesa->emulateTwoTMUs = fxMesa->haveTwoTMUs;
if (!getenv("FX_DONT_FAKE_MULTITEX"))
fxMesa->emulateTwoTMUs = GL_TRUE;
if (getenv("FX_GLIDE_SWAPINTERVAL"))
fxMesa->swapInterval = atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
else
@ -754,7 +749,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
fxMesa->textureAlign = FX_grGetInteger(FX_TEXTURE_ALIGN);
fxMesa->glCtx->Const.MaxTextureLevels = 9;
fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->emulateTwoTMUs ? 2 : 1;
fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->haveTwoTMUs ? 2 : 1;
fxMesa->new_state = _NEW_ALL;
/* Initialize the software rasterizer and helper modules.
@ -783,10 +778,6 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
fxDDInitExtensions(fxMesa->glCtx);
#ifdef FXVTXFMT
fxDDInitVtxfmt(fxMesa->glCtx);
#endif
FX_grGlideGetState((GrState *) fxMesa->state);
/* Run the config file */
@ -830,7 +821,7 @@ fxDDInitExtensions(GLcontext * ctx)
if (fxMesa->haveTwoTMUs)
_mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
if (fxMesa->emulateTwoTMUs)
if (fxMesa->haveTwoTMUs)
_mesa_enable_extension(ctx, "GL_ARB_multitexture");
}
@ -843,8 +834,8 @@ fxDDInitExtensions(GLcontext * ctx)
*
* Performs similar work to fxDDChooseRenderState() - should be merged.
*/
static GLboolean
fxIsInHardware(GLcontext * ctx)
GLboolean
fx_check_IsInHardware(GLcontext * ctx)
{
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
@ -868,7 +859,7 @@ fxIsInHardware(GLcontext * ctx)
}
/* Unsupported texture/multitexture cases */
if (fxMesa->emulateTwoTMUs) {
if (fxMesa->haveTwoTMUs) {
if (ctx->Texture._ReallyEnabled & (TEXTURE0_3D | TEXTURE1_3D))
return GL_FALSE; /* can't do 3D textures */
if (ctx->Texture._ReallyEnabled & (TEXTURE0_1D | TEXTURE1_1D))
@ -939,6 +930,9 @@ fxIsInHardware(GLcontext * ctx)
return GL_TRUE;
}
static void
update_texture_scales(GLcontext * ctx)
{
@ -980,79 +974,34 @@ fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state)
if (new_state & (_FX_NEW_IS_IN_HARDWARE |
_FX_NEW_RENDERSTATE |
_FX_NEW_SETUP_FUNCTION | _NEW_TEXTURE)) {
_FX_NEW_SETUP_FUNCTION |
_NEW_TEXTURE)) {
if (new_state & _FX_NEW_IS_IN_HARDWARE)
fxMesa->is_in_hardware = fxIsInHardware(ctx);
fxCheckIsInHardware(ctx);
if (fxMesa->new_state)
fxSetupFXUnits(ctx);
if (new_state & _FX_NEW_RENDERSTATE)
fxDDChooseRenderState(ctx);
if (fxMesa->is_in_hardware) {
if (new_state & _FX_NEW_RENDERSTATE)
fxDDChooseRenderState(ctx);
if (new_state & _FX_NEW_SETUP_FUNCTION)
tnl->Driver.BuildProjectedVertices = fx_validate_BuildProjVerts;
if (new_state & _FX_NEW_SETUP_FUNCTION)
fxDDChooseSetupState(ctx);
}
if (new_state & _NEW_TEXTURE)
update_texture_scales(ctx);
}
#ifdef FXVTXFMT
if (fxMesa->allow_vfmt) {
if (new_state & _NEW_LIGHT)
fx_update_lighting(ctx);
if (new_state & _FX_NEW_VTXFMT)
fxDDCheckVtxfmt(ctx);
}
#endif
}
static void
fxDDRenderPrimitive(GLcontext * ctx, GLenum mode)
{
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
if (!fxMesa->is_in_hardware) {
_swsetup_RenderPrimitive(ctx, mode);
}
else {
fxMesa->render_prim = mode;
}
}
static void
fxDDRenderStart(GLcontext * ctx)
{
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
_swsetup_RenderStart(ctx);
if (fxMesa->new_state) {
fxSetupFXUnits(ctx);
}
}
static void
fxDDRenderFinish(GLcontext * ctx)
{
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
if (!fxMesa->is_in_hardware) {
_swsetup_RenderFinish(ctx);
}
}
void
fxSetupDDPointers(GLcontext * ctx)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_DRIVER) {
fprintf(stderr, "fxmesa: fxSetupDDPointers()\n");
}
@ -1106,16 +1055,6 @@ fxSetupDDPointers(GLcontext * ctx)
ctx->Driver.ShadeModel = fxDDShadeModel;
ctx->Driver.Enable = fxDDEnable;
tnl->Driver.RunPipeline = _tnl_run_pipeline;
tnl->Driver.RenderStart = fxDDRenderStart;
tnl->Driver.RenderFinish = fxDDRenderFinish;
tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.RenderPrimitive = fxDDRenderPrimitive;
tnl->Driver.RenderInterp = _swsetup_RenderInterp;
tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
fxSetupDDSpanPointers(ctx);
fxDDUpdateDDPointers(ctx, ~0);
}

View file

@ -94,37 +94,6 @@ extern float gl_ubyte_to_float_255_color_tab[256];
/* Should have size == 16 * sizeof(float).
*/
typedef union
{
GrVertex v;
GLfloat f[16];
GLuint ui[16];
}
fxVertex;
/* Used in the fxvtxfmt t&l engine.
*/
typedef struct
{
GrVertex v;
GLfloat clip[4];
GLfloat texcoord[2][2];
GLubyte mask;
GLfloat normal[3]; /* for replay & fallback */
}
fxClipVertex;
typedef void (*vfmt_project_func) (GLcontext * ctx, fxClipVertex * v);
typedef void (*vfmt_interpolate_func) (GLfloat t,
fxClipVertex * O,
const fxClipVertex * I,
const fxClipVertex * J);
#if defined(FXMESA_USE_ARGB)
#define FXCOLOR4( c ) ( \
@ -147,14 +116,15 @@ typedef void (*vfmt_interpolate_func) (GLfloat t,
/* fastpath/vtxfmt flags first
/* fastpath flags first
*/
#define SETUP_TMU0 0x1
#define SETUP_TMU1 0x2
#define SETUP_RGBA 0x4
#define SETUP_SNAP 0x8
#define SETUP_XYZW 0x10
#define MAX_SETUP 0x20
#define SETUP_PTEX 0x20
#define MAX_SETUP 0x40
#define FX_NUM_TMU 2
@ -356,6 +326,7 @@ tfxUnitsState;
_DD_NEW_POINT_SIZE | \
_NEW_LINE)
/* Covers the state referenced by fxDDChooseSetupFunction.
*/
#define _FX_NEW_SETUP_FUNCTION (_NEW_LIGHT| \
@ -364,18 +335,6 @@ tfxUnitsState;
_NEW_COLOR) \
/* Covers the state referenced in fxDDCheckVtxfmt.
*/
#define _FX_NEW_VTXFMT (_NEW_TEXTURE | \
_NEW_TEXTURE_MATRIX | \
_NEW_TRANSFORM | \
_NEW_LIGHT | \
_NEW_PROJECTION | \
_NEW_MODELVIEW | \
_TNL_NEW_NEED_EYE_COORDS | \
_FX_NEW_RENDERSTATE)
/* These lookup table are used to extract RGB values in [0,255] from
* 16-bit pixel values.
*/
@ -384,11 +343,9 @@ extern GLubyte FX_PixelToG[0x10000];
extern GLubyte FX_PixelToB[0x10000];
typedef void (*fx_tri_func) (GLcontext *, const fxVertex *,
const fxVertex *, const fxVertex *);
typedef void (*fx_line_func) (GLcontext *, const fxVertex *,
const fxVertex *);
typedef void (*fx_point_func) (GLcontext *, const fxVertex *);
typedef void (*fx_tri_func) (fxMesaContext, GrVertex *, GrVertex *, GrVertex *);
typedef void (*fx_line_func) (fxMesaContext, GrVertex *, GrVertex *);
typedef void (*fx_point_func) (fxMesaContext, GrVertex *);
struct tfxMesaContext
{
@ -434,19 +391,18 @@ struct tfxMesaContext
/* Vertex building and storage:
*/
GLuint tmu_source[FX_NUM_TMU];
GLuint tex_dest[MAX_TEXTURE_UNITS];
GLuint setupindex;
GLuint setup_gone; /* for multipass */
GLuint SetupIndex;
GLuint stw_hint_state; /* for grHints */
fxVertex *verts;
GrVertex *verts;
GLboolean snapVertices; /* needed for older Voodoo hardware */
struct gl_client_array UbyteColor;
/* Rasterization:
*/
GLuint render_index;
GLuint passes, multipass;
GLuint is_in_hardware;
GLenum render_prim;
GLenum render_primitive;
GLenum raster_primitive;
/* Current rasterization functions
*/
@ -454,15 +410,6 @@ struct tfxMesaContext
fx_line_func draw_line;
fx_tri_func draw_tri;
/* System to turn culling on/off for tris/lines/points.
*/
fx_point_func initial_point;
fx_line_func initial_line;
fx_tri_func initial_tri;
fx_point_func subsequent_point;
fx_line_func subsequent_line;
fx_tri_func subsequent_tri;
/* Keep texture scales somewhere handy:
*/
@ -485,7 +432,6 @@ struct tfxMesaContext
GLboolean verbose;
GLboolean haveTwoTMUs; /* True if we really have 2 tmu's */
GLboolean emulateTwoTMUs; /* True if we present 2 tmu's to mesa. */
GLboolean haveAlphaBuffer;
GLboolean haveZBuffer;
GLboolean haveDoubleBuffer;
@ -502,37 +448,8 @@ struct tfxMesaContext
int clipMaxX;
int clipMinY;
int clipMaxY;
/* fxvtxfmt
*/
GLboolean allow_vfmt;
GLvertexformat vtxfmt;
fxClipVertex current;
fxClipVertex *vert; /* points into verts[] */
void (*fire_on_vertex) (GLcontext *);
void (*fire_on_end) (GLcontext *);
void (*fire_on_fallback) (GLcontext *);
vfmt_project_func project_vertex;
vfmt_interpolate_func interpolate_vertices;
int vtxfmt_fallback_count;
int vtxfmt_installed;
void (*old_begin) (GLenum);
GLenum prim;
GLuint accel_light;
GLfloat basecolor[4];
/* Projected vertices, fastpath data:
*/
GLvector1ui clipped_elements;
fxVertex *last_vert;
GLuint size;
};
typedef void (*tfxSetupFunc) (GLcontext * ctx, GLuint, GLuint);
extern GrHwConfiguration glbHWConfig;
extern int glbCurrentBoard;
@ -540,17 +457,20 @@ extern int glbCurrentBoard;
extern void fxSetupFXUnits(GLcontext *);
extern void fxSetupDDPointers(GLcontext *);
/* fxvsetup:
/* fxvb.c:
*/
extern void fxDDSetupInit(void);
extern void fxAllocVB(GLcontext * ctx);
extern void fxFreeVB(GLcontext * ctx);
extern void fxPrintSetupFlags(const char *msg, GLuint flags);
extern void fx_BuildProjVerts(GLcontext * ctx,
GLuint start, GLuint count, GLuint newinputs);
extern void fx_validate_BuildProjVerts(GLcontext * ctx,
GLuint start, GLuint count,
GLuint newinputs);
extern void fxPrintSetupFlags(char *msg, GLuint flags );
extern void fxCheckTexSizes( GLcontext *ctx );
extern void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint count,
GLuint newinputs );
extern void fxChooseVertexState( GLcontext *ctx );
/* fxtrifuncs:
*/
@ -655,14 +575,4 @@ extern void fxTMMoveInTM_NoLock(fxMesaContext fxMesa,
extern void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder);
/* fxvtxfmt:
*/
extern void fxDDCheckVtxfmt(GLcontext * ctx);
extern void fx_update_lighting(GLcontext * ctx);
extern void fxDDInitVtxfmt(GLcontext * ctx);
/* fxsimplerender
*/
extern const struct gl_pipeline_stage fx_render_stage;
#endif

View file

@ -55,8 +55,6 @@
#include "enums.h"
#include "tnl/t_context.h"
/*static GLboolean fxMultipassTexture(GLcontext *, GLuint);*/
static void
fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
{
@ -531,23 +529,8 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
break;
case GL_BLEND:
#if 0
FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_LOCAL,
locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
if (ifmt == GL_ALPHA)
FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
GR_COMBINE_FACTOR_NONE,
localc, GR_COMBINE_OTHER_NONE, FXFALSE);
else
FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
GR_COMBINE_FACTOR_LOCAL,
localc, GR_COMBINE_OTHER_TEXTURE, FXTRUE);
ctx->Driver.MultipassFunc = fxMultipassBlend;
#else
if (MESA_VERBOSE & VERBOSE_DRIVER)
fprintf(stderr, "fx Driver: GL_BLEND not yet supported\n");
#endif
break;
case GL_REPLACE:
if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE))
@ -1037,7 +1020,7 @@ fxSetupTexture_NoLock(GLcontext * ctx)
*/
tex2Denabled = (ctx->Texture._ReallyEnabled & TEXTURE0_2D);
if (fxMesa->emulateTwoTMUs)
if (fxMesa->haveTwoTMUs)
tex2Denabled |= (ctx->Texture._ReallyEnabled & TEXTURE1_2D);
switch (tex2Denabled) {
@ -1055,7 +1038,6 @@ fxSetupTexture_NoLock(GLcontext * ctx)
fprintf(stderr, "fxmesa: enabling fake multitexture\n");
fxSetupTextureSingleTMU_NoLock(ctx, 0);
/*ctx->Driver.MultipassFunc = fxMultipassTexture;*/
}
break;
default:
@ -1547,7 +1529,8 @@ fxSetupCull(GLcontext * ctx)
else
FX_CONTEXT(ctx)->cullMode = GR_CULL_DISABLE;
FX_grCullMode(FX_CONTEXT(ctx)->cullMode);
if (FX_CONTEXT(ctx)->raster_primitive == GL_TRIANGLES)
FX_grCullMode(FX_CONTEXT(ctx)->cullMode);
}
@ -1616,129 +1599,7 @@ fxDDEnable(GLcontext * ctx, GLenum cap, GLboolean state)
}
}
#if 0
/*
Multipass to do GL_BLEND texture functions
Cf*(1-Ct) has already been written to the buffer during the first pass
Cc*Ct gets written during the second pass (in this function)
Everything gets reset in the third call (in this function)
*/
static GLboolean
fxMultipassBlend(struct vertex_buffer *VB, GLuint pass)
{
GLcontext *ctx = VB->ctx;
fxMesaContext fxMesa = FX_CONTEXT(ctx);
switch (pass) {
case 1:
/* Add Cc*Ct */
fxMesa->restoreUnitsState = fxMesa->unitsState;
if (ctx->Depth.Mask) {
/* We don't want to check or change the depth buffers */
switch (ctx->Depth.Func) {
case GL_NEVER:
case GL_ALWAYS:
break;
default:
fxDDDepthFunc(ctx, GL_EQUAL);
break;
}
fxDDDepthMask(ctx, FALSE);
}
/* Enable Cc*Ct mode */
/* XXX Set the Constant Color ? */
fxDDEnable(ctx, GL_BLEND, GL_TRUE);
fxDDBlendFunc(ctx, XXX, XXX);
fxSetupTextureSingleTMU(ctx, XXX);
fxSetupBlend(ctx);
fxSetupDepthTest(ctx);
break;
case 2:
/* Reset everything back to normal */
fxMesa->unitsState = fxMesa->restoreUnitsState;
fxMesa->setup_gone |= XXX;
fxSetupTextureSingleTMU(ctx, XXX);
fxSetupBlend(ctx);
fxSetupDepthTest(ctx);
break;
}
return pass == 1;
}
#endif
/************************************************************************/
/******************** Fake Multitexture Support *************************/
/************************************************************************/
/* Its considered cheeky to try to fake ARB multitexture by doing
* multipass rendering, because it is not possible to emulate the full
* spec in this way. The fact is that the voodoo 2 supports only a
* subset of the possible multitexturing modes, and it is possible to
* support almost the same subset using multipass blending on the
* voodoo 1. In all other cases for both voodoo 1 and 2, we fall back
* to software rendering, satisfying the spec if not the user.
*/
static GLboolean
fxMultipassTexture(GLcontext * ctx, GLuint pass)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
fxVertex *v = fxMesa->verts;
fxVertex *last = fxMesa->verts + tnl->vb.Count;
switch (pass) {
case 1:
if (MESA_VERBOSE &
(VERBOSE_DRIVER | VERBOSE_PIPELINE | VERBOSE_TEXTURE))
fprintf(stderr, "fxmesa: Second texture pass\n");
for (; v != last; v++) {
v->f[S0COORD] = v->f[S1COORD];
v->f[T0COORD] = v->f[T1COORD];
}
fxMesa->restoreUnitsState = fxMesa->unitsState;
fxMesa->tmu_source[0] = 1;
if (ctx->Depth.Mask) {
switch (ctx->Depth.Func) {
case GL_NEVER:
case GL_ALWAYS:
break;
default:
fxDDDepthFunc(ctx, GL_EQUAL);
break;
}
fxDDDepthMask(ctx, GL_FALSE);
}
if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) {
fxDDEnable(ctx, GL_BLEND, GL_TRUE);
fxDDBlendFunc(ctx, GL_DST_COLOR, GL_ZERO);
}
fxSetupTextureSingleTMU(ctx, 1);
fxSetupBlend(ctx);
fxSetupDepthTest(ctx);
break;
case 2:
/* Restore original state.
*/
fxMesa->tmu_source[0] = 0;
fxMesa->unitsState = fxMesa->restoreUnitsState;
fxMesa->setup_gone |= SETUP_TMU0;
fxSetupTextureSingleTMU(ctx, 0);
fxSetupBlend(ctx);
fxSetupDepthTest(ctx);
break;
}
return pass == 1;
}
/************************************************************************/
@ -1809,9 +1670,6 @@ fxSetupFXUnits(GLcontext * ctx)
if (newstate & FX_NEW_CULL)
fxSetupCull(ctx);
fxMesa->draw_point = fxMesa->initial_point;
fxMesa->draw_line = fxMesa->initial_line;
fxMesa->draw_tri = fxMesa->initial_tri;
fxMesa->new_state = 0;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,6 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
*
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
* GLX Hardware Device Driver for Intel i810
* Copyright (C) 1999 Keith Whitwell
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -18,400 +15,379 @@
* 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.
* KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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.
*
*
* Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
* terms stated above.
*
* Author:
* Keith Whitwell <keith@precisioninsight.com>
*/
/* fxvsetup.c - 3Dfx VooDoo vertices setup functions */
#ifdef HAVE_CONFIG_H
#include "conf.h"
#endif
#if defined(FX)
#include "fxdrv.h"
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfxvb.c,v 1.7 2000/11/08 05:02:43 dawes Exp $ */
#include "glheader.h"
#include "mtypes.h"
#include "mem.h"
#include "macros.h"
#include "colormac.h"
#include "mmath.h"
#include "math/m_translate.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "fxdrv.h"
void
fxPrintSetupFlags(const char *msg, GLuint flags)
static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
{
fprintf(stderr, "%s: %d %s%s%s%s%s\n",
msg,
flags,
(flags & SETUP_XYZW) ? " xyzw," : "",
(flags & SETUP_SNAP) ? " snap," : "",
(flags & SETUP_RGBA) ? " rgba," : "",
(flags & SETUP_TMU0) ? " tmu0," : "",
(flags & SETUP_TMU1) ? " tmu1," : "");
fxMesaContext fxMesa = FX_CONTEXT( ctx );
GrVertex *dst = fxMesa->verts + edst;
GrVertex *src = fxMesa->verts + esrc;
dst->r = src->r;
dst->g = src->g;
dst->b = src->b;
dst->a = src->a;
}
static void
project_texcoords(fxVertex * v,
struct vertex_buffer *VB,
GLuint tmu_nr, GLuint tc_nr, GLuint start, GLuint count)
typedef void (*emit_func)( GLcontext *, GLuint, GLuint, void * );
static struct {
emit_func emit;
interp_func interp;
GLboolean (*check_tex_sizes)( GLcontext *ctx );
GLuint vertex_format;
} setup_tab[MAX_SETUP];
static void import_float_colors( GLcontext *ctx )
{
GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]);
GLvector4f *vec = VB->TexCoordPtr[tc_nr];
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct gl_client_array *from = VB->ColorPtr[0];
struct gl_client_array *to = &FX_CONTEXT(ctx)->UbyteColor;
GLuint count = VB->Count;
GLuint i;
GLuint stride = vec->stride;
GLfloat *data = VEC_ELT(vec, GLfloat, start);
for (i = start; i < count; i++, STRIDE_F(data, stride), v++) {
tmu->oow = v->v.oow * data[3];
tmu = (GrTmuVertex *) ((char *) tmu + sizeof(fxVertex));
if (!to->Ptr) {
to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLubyte), 32 );
to->Type = GL_UNSIGNED_BYTE;
}
}
static void
copy_w(fxVertex * v,
struct vertex_buffer *VB, GLuint tmu_nr, GLuint start, GLuint count)
{
GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]);
GLuint i;
for (i = start; i < count; i++, v++) {
tmu->oow = v->v.oow;
tmu = (GrTmuVertex *) ((char *) tmu + sizeof(fxVertex));
/* No need to transform the same value 3000 times.
*/
if (!from->StrideB) {
to->StrideB = 0;
count = 1;
}
else
to->StrideB = 4 * sizeof(GLubyte);
_math_trans_4ub( (GLubyte (*)[4]) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
from->Size,
0,
count);
VB->ColorPtr[0] = to;
}
/* need to compute W values for fogging purposes
*/
static void
fx_fake_fog_w(GLcontext * ctx,
fxVertex * verts,
struct vertex_buffer *VB, GLuint start, GLuint end)
{
const GLfloat m10 = ctx->ProjectionMatrix.m[10];
const GLfloat m14 = ctx->ProjectionMatrix.m[14];
GLfloat(*clip)[4] = VB->ClipPtr->data;
GLubyte *clipmask = VB->ClipMask;
GLuint i;
for (i = start; i < end; i++) {
if (clipmask[i] == 0) {
verts[i].v.oow = -m10 / (clip[i][2] - m14); /* -1/zEye */
#define GET_COLOR(ptr, idx) (((GLfloat (*)[4])((ptr)->Ptr))[idx])
static void interp_extras( GLcontext *ctx,
GLfloat t,
GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
/*fprintf(stderr, "%s\n", __FUNCTION__);*/
if (VB->ColorPtr[1]) {
INTERP_4F( t,
GET_COLOR(VB->ColorPtr[1], dst),
GET_COLOR(VB->ColorPtr[1], out),
GET_COLOR(VB->ColorPtr[1], in) );
if (VB->SecondaryColorPtr[1]) {
INTERP_3F( t,
GET_COLOR(VB->SecondaryColorPtr[1], dst),
GET_COLOR(VB->SecondaryColorPtr[1], out),
GET_COLOR(VB->SecondaryColorPtr[1], in) );
}
}
if (VB->EdgeFlag) {
VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
}
setup_tab[FX_CONTEXT(ctx)->SetupIndex].interp(ctx, t, dst, out, in,
force_boundary);
}
static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
if (VB->ColorPtr[1]) {
COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
GET_COLOR(VB->ColorPtr[1], src) );
if (VB->SecondaryColorPtr[1]) {
COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst),
GET_COLOR(VB->SecondaryColorPtr[1], src) );
}
}
copy_pv(ctx, dst, src);
}
static tfxSetupFunc setupfuncs[MAX_SETUP];
#define IND (SETUP_XYZW)
#define INPUTS (VERT_CLIP)
#define NAME fxsetupXYZW
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_RGBA)
#define INPUTS (VERT_CLIP|VERT_RGBA)
#define NAME fxsetupXYZWRGBA
#define TAG(x) x##_wg
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_TMU0)
#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
#define NAME fxsetupXYZWT0
#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0)
#define TAG(x) x##_wgt0
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_TMU1)
#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
#define NAME fxsetupXYZWT1
#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
#define TAG(x) x##_wgt0t1
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0)
#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
#define NAME fxsetupXYZWT0T1
#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX)
#define TAG(x) x##_wgpt0
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_TMU0|SETUP_RGBA)
#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupXYZWRGBAT0
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_RGBA)
#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupXYZWRGBAT1
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupXYZWRGBAT0T1
#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\
SETUP_PTEX)
#define TAG(x) x##_wgpt0t1
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_SNAP)
#define INPUTS (VERT_CLIP)
#define NAME fxsetupXYZW_SNAP
#include "fxvbtmp.h"
/* Snapping for voodoo-1
*/
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA)
#define INPUTS (VERT_CLIP|VERT_RGBA)
#define NAME fxsetupXYZW_SNAP_RGBA
#define TAG(x) x##_wsg
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0)
#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
#define NAME fxsetupXYZW_SNAP_T0
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0)
#define TAG(x) x##_wsgt0
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1)
#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
#define NAME fxsetupXYZW_SNAP_T1
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
SETUP_TMU1)
#define TAG(x) x##_wsgt0t1
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0)
#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
#define NAME fxsetupXYZW_SNAP_T0T1
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
SETUP_PTEX)
#define TAG(x) x##_wsgpt0
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0|SETUP_RGBA)
#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupXYZW_SNAP_RGBAT0
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_RGBA)
#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupXYZW_SNAP_RGBAT1
#include "fxvbtmp.h"
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupXYZW_SNAP_RGBAT0T1
#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
SETUP_TMU1|SETUP_PTEX)
#define TAG(x) x##_wsgpt0t1
#include "fxvbtmp.h"
/* Vertex repair (multipass rendering)
*/
#define IND (SETUP_RGBA)
#define INPUTS (VERT_RGBA)
#define NAME fxsetupRGBA
#define TAG(x) x##_g
#include "fxvbtmp.h"
#define IND (SETUP_TMU0)
#define INPUTS (VERT_TEX_ANY)
#define NAME fxsetupT0
#define TAG(x) x##_t0
#include "fxvbtmp.h"
#define IND (SETUP_TMU1)
#define INPUTS (VERT_TEX_ANY)
#define NAME fxsetupT1
#define IND (SETUP_TMU0|SETUP_TMU1)
#define TAG(x) x##_t0t1
#include "fxvbtmp.h"
#define IND (SETUP_TMU1|SETUP_TMU0)
#define INPUTS (VERT_TEX_ANY)
#define NAME fxsetupT0T1
#define IND (SETUP_RGBA|SETUP_TMU0)
#define TAG(x) x##_gt0
#include "fxvbtmp.h"
#define IND (SETUP_TMU0|SETUP_RGBA)
#define INPUTS (VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupRGBAT0
#include "fxvbtmp.h"
#define IND (SETUP_TMU1|SETUP_RGBA)
#define INPUTS (VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupRGBAT1
#include "fxvbtmp.h"
#define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
#define INPUTS (VERT_RGBA|VERT_TEX_ANY)
#define NAME fxsetupRGBAT0T1
#define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
#define TAG(x) x##_gt0t1
#include "fxvbtmp.h"
static void
fxsetup_invalid(GLcontext * ctx, GLuint start, GLuint end)
static void init_setup_tab( void )
{
fprintf(stderr, "fxMesa: invalid setup function\n");
(void) (ctx && start && end);
init_wg();
init_wgt0();
init_wgt0t1();
init_wgpt0();
init_wgpt0t1();
init_wsg();
init_wsgt0();
init_wsgt0t1();
init_wsgpt0();
init_wsgpt0t1();
init_g();
init_t0();
init_t0t1();
init_gt0();
init_gt0t1();
}
void
fxDDSetupInit(void)
void fxPrintSetupFlags(char *msg, GLuint flags )
{
GLuint i;
for (i = 0; i < Elements(setupfuncs); i++)
setupfuncs[i] = fxsetup_invalid;
setupfuncs[SETUP_XYZW] = fxsetupXYZW;
setupfuncs[SETUP_XYZW | SETUP_RGBA] = fxsetupXYZWRGBA;
setupfuncs[SETUP_XYZW | SETUP_TMU0] = fxsetupXYZWT0;
setupfuncs[SETUP_XYZW | SETUP_TMU1] = fxsetupXYZWT1;
setupfuncs[SETUP_XYZW | SETUP_TMU0 | SETUP_RGBA] = fxsetupXYZWRGBAT0;
setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_RGBA] = fxsetupXYZWRGBAT1;
setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_TMU0] = fxsetupXYZWT0T1;
setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] =
fxsetupXYZWRGBAT0T1;
setupfuncs[SETUP_XYZW | SETUP_SNAP] = fxsetupXYZW_SNAP;
setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_RGBA] = fxsetupXYZW_SNAP_RGBA;
setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU0] = fxsetupXYZW_SNAP_T0;
setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1] = fxsetupXYZW_SNAP_T1;
setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU0 | SETUP_RGBA] =
fxsetupXYZW_SNAP_RGBAT0;
setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_RGBA] =
fxsetupXYZW_SNAP_RGBAT1;
setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_TMU0] =
fxsetupXYZW_SNAP_T0T1;
setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA]
= fxsetupXYZW_SNAP_RGBAT0T1;
setupfuncs[SETUP_RGBA] = fxsetupRGBA;
setupfuncs[SETUP_TMU0] = fxsetupT0;
setupfuncs[SETUP_TMU1] = fxsetupT1;
setupfuncs[SETUP_TMU1 | SETUP_TMU0] = fxsetupT0T1;
setupfuncs[SETUP_TMU0 | SETUP_RGBA] = fxsetupRGBAT0;
setupfuncs[SETUP_TMU1 | SETUP_RGBA] = fxsetupRGBAT1;
setupfuncs[SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] = fxsetupRGBAT0T1;
fprintf(stderr, "%s(%x): %s%s%s%s\n",
msg,
(int)flags,
(flags & SETUP_XYZW) ? " xyzw," : "",
(flags & SETUP_SNAP) ? " snap," : "",
(flags & SETUP_RGBA) ? " rgba," : "",
(flags & SETUP_TMU0) ? " tex-0," : "",
(flags & SETUP_TMU1) ? " tex-1," : "");
}
void
fx_validate_BuildProjVerts(GLcontext * ctx, GLuint start, GLuint count,
GLuint newinputs)
void fxCheckTexSizes( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
fxMesaContext fxMesa = FX_CONTEXT( ctx );
if (!fxMesa->is_in_hardware)
tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
else {
GLuint setupindex = SETUP_XYZW;
if (!setup_tab[fxMesa->SetupIndex].check_tex_sizes(ctx)) {
GLuint ind = fxMesa->SetupIndex |= (SETUP_PTEX|SETUP_RGBA);
if (fxMesa->snapVertices)
setupindex |= SETUP_SNAP;
fxMesa->tmu_source[0] = 0;
fxMesa->tmu_source[1] = 1;
fxMesa->tex_dest[0] = SETUP_TMU0;
fxMesa->tex_dest[1] = SETUP_TMU1;
/* For flat and two-side-lit triangles, colors will always be added
* to vertices in the triangle functions. Vertices will *always*
* have rbga values, but only sometimes will they come from here.
/* Tdfx handles projective textures nicely; just have to change
* up to the new vertex format.
*/
if ((ctx->_TriangleCaps & (DD_FLATSHADE | DD_TRI_LIGHT_TWOSIDE)) == 0)
setupindex |= SETUP_RGBA;
if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) {
if (ctx->Texture._ReallyEnabled & TEXTURE0_2D)
setupindex |= SETUP_TMU0;
fxMesa->stw_hint_state = setup_tab[ind].vertex_format;
FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state);
if (ctx->Texture._ReallyEnabled & TEXTURE1_2D) {
if ((ctx->Texture._ReallyEnabled & TEXTURE0_2D) == 0) {
fxMesa->tmu_source[0] = 1;
fxMesa->tex_dest[0] = SETUP_TMU1;
fxMesa->tmu_source[1] = 0;
fxMesa->tex_dest[1] = SETUP_TMU0;
setupindex |= SETUP_TMU0;
}
else {
setupindex |= SETUP_TMU1;
/* This is required as we have just changed the vertex
* format, so the interp routines must also change.
* In the unfilled and twosided cases we are using the
* Extras ones anyway, so leave them in place.
*/
if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
tnl->Driver.Render.Interp = setup_tab[fxMesa->SetupIndex].interp;
}
}
if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_PIPELINE | VERBOSE_STATE))
fxPrintSetupFlags("fxmesa: vertex setup function", setupindex);
fxMesa->setupindex = setupindex;
tnl->Driver.BuildProjectedVertices = fx_BuildProjVerts;
}
tnl->Driver.BuildProjectedVertices(ctx, start, count, newinputs);
}
void
fx_BuildProjVerts(GLcontext * ctx, GLuint start, GLuint count,
GLuint newinputs)
void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint count,
GLuint newinputs )
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
fxMesaContext fxMesa = FX_CONTEXT( ctx );
GrVertex *v = (fxMesa->verts + start);
if (newinputs == ~0) {
/* build interpolated vertices */
setupfuncs[fxMesa->setupindex] (ctx, start, count);
}
else {
GLuint ind = fxMesa->setup_gone;
fxMesa->setup_gone = 0;
if (!newinputs)
return;
if (newinputs & VERT_CLIP)
ind = fxMesa->setupindex; /* clipmask has potentially changed */
else {
if (newinputs & VERT_TEX0)
ind |= fxMesa->tex_dest[0];
if (newinputs & VERT_CLIP) {
setup_tab[fxMesa->SetupIndex].emit( ctx, start, count, v );
} else {
GLuint ind = 0;
if (newinputs & VERT_TEX1)
ind |= fxMesa->tex_dest[1];
if (newinputs & VERT_RGBA)
ind |= SETUP_RGBA;
if (newinputs & VERT_TEX0)
ind |= SETUP_TMU0;
if (newinputs & VERT_RGBA)
ind |= SETUP_RGBA;
if (newinputs & VERT_TEX1)
ind |= SETUP_TMU0|SETUP_TMU1;
ind &= fxMesa->setupindex;
}
if (fxMesa->SetupIndex & SETUP_PTEX)
ind = ~0;
ind &= fxMesa->SetupIndex;
if (ind) {
if (fxMesa->new_state)
fxSetupFXUnits(ctx); /* why? */
if (VB->importable_data & newinputs)
VB->import_data(ctx, VB->importable_data & newinputs,
VEC_BAD_STRIDE);
setupfuncs[ind] (ctx, start, count);
setup_tab[ind].emit( ctx, start, count, v );
}
}
}
void
fxAllocVB(GLcontext * ctx)
void fxChooseVertexState( GLcontext *ctx )
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
fxMesa->verts = ALIGN_MALLOC(tnl->vb.Size * sizeof(fxMesa->verts[0]), 32);
fxMesaContext fxMesa = FX_CONTEXT( ctx );
GLuint ind = SETUP_XYZW|SETUP_RGBA;
if (fxMesa->snapVertices)
ind |= SETUP_SNAP;
fxMesa->tmu_source[0] = 0;
fxMesa->tmu_source[1] = 1;
if (ctx->Texture._ReallyEnabled & 0xf0) {
if (ctx->Texture._ReallyEnabled & 0xf) {
ind |= SETUP_TMU1|SETUP_TMU0;
}
else {
fxMesa->tmu_source[0] = 1;
fxMesa->tmu_source[1] = 0;
ind |= SETUP_TMU0;
}
}
else if (ctx->Texture._ReallyEnabled & 0xf) {
ind |= SETUP_TMU0;
}
fxMesa->SetupIndex = ind;
if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
tnl->Driver.Render.Interp = interp_extras;
tnl->Driver.Render.CopyPV = copy_pv_extras;
} else {
tnl->Driver.Render.Interp = setup_tab[ind].interp;
tnl->Driver.Render.CopyPV = copy_pv;
}
if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) {
fxMesa->stw_hint_state = setup_tab[ind].vertex_format;
FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state);
}
}
void
fxFreeVB(GLcontext * ctx)
void fxAllocVB( GLcontext *ctx )
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
if (fxMesa->verts)
ALIGN_FREE(fxMesa->verts);
fxMesa->verts = 0;
GLuint size = TNL_CONTEXT(ctx)->vb.Size;
static int firsttime = 1;
if (firsttime) {
init_setup_tab();
firsttime = 0;
}
fxMesa->verts = (GrVertex *)ALIGN_MALLOC(size * sizeof(GrVertex), 32);
fxMesa->SetupIndex = SETUP_XYZW|SETUP_RGBA;
}
#else
/*
* Need this to provide at least one external definition.
*/
extern int gl_fx_dummy_function_vsetup(void);
int
gl_fx_dummy_function_vsetup(void)
void fxFreeVB( GLcontext *ctx )
{
return 0;
}
fxMesaContext fxMesa = FX_CONTEXT(ctx);
if (fxMesa->verts) {
ALIGN_FREE(fxMesa->verts);
fxMesa->verts = 0;
}
#endif /* FX */
if (fxMesa->UbyteColor.Ptr) {
ALIGN_FREE(fxMesa->UbyteColor.Ptr);
fxMesa->UbyteColor.Ptr = 0;
}
}

View file

@ -1,181 +1,277 @@
/*
* Mesa 3-D graphics library
* Version: 3.3
*
* Copyright (C) 1999-2000 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.
*
* Author:
* Keith Whitwell <keith@precisioninsight.com>
*/
static void
NAME(GLcontext * ctx, GLuint start, GLuint end)
static void TAG(emit)( GLcontext *ctx,
GLuint start, GLuint end,
void *dest )
{
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
fxVertex *verts = fxMesa->verts;
fxMesaContext fxMesa = FX_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLuint tmu0_source = fxMesa->tmu_source[0];
GLuint tmu1_source = fxMesa->tmu_source[1];
GLfloat (*tmu0_data)[4];
GLfloat (*tmu1_data)[4];
GLfloat (*color)[4];
GLfloat (*proj)[4] = VB->ProjectedClipPtr->data;
fxVertex *v = &verts[start];
GLfloat sscale0 = fxMesa->s0scale;
GLfloat tscale0 = fxMesa->t0scale;
GLfloat sscale1 = fxMesa->s1scale;
GLfloat tscale1 = fxMesa->t1scale;
GLubyte *clipmask = VB->ClipMask;
GLuint i;
GLfloat (*tc0)[4], (*tc1)[4];
GLubyte (*col)[4];
GLuint tc0_stride, tc1_stride, col_stride;
GLuint tc0_size, tc1_size;
GLfloat (*proj)[4] = VB->ProjectedClipPtr->data;
GLuint proj_stride = VB->ProjectedClipPtr->stride;
GrVertex *v = (GrVertex *)dest;
GLfloat u0scale,v0scale,u1scale,v1scale;
const GLfloat *const s = ctx->Viewport._WindowMap.m;
int i;
if (IND & SETUP_TMU0)
tmu0_data = VB->TexCoordPtr[tmu0_source]->data;
if (IND & SETUP_TMU1)
tmu1_data = VB->TexCoordPtr[tmu1_source]->data;
if (IND & SETUP_TMU0) {
tc0_stride = VB->TexCoordPtr[tmu0_source]->stride;
tc0 = VB->TexCoordPtr[tmu0_source]->data;
u0scale = fxMesa->s0scale;
v0scale = fxMesa->t0scale;
if (IND & SETUP_PTEX)
tc0_size = VB->TexCoordPtr[tmu0_source]->size;
}
if (IND & SETUP_RGBA)
color = VB->ColorPtr[0]->Ptr;
if (IND & SETUP_TMU1) {
tc1 = VB->TexCoordPtr[tmu1_source]->data;
tc1_stride = VB->TexCoordPtr[tmu1_source]->stride;
u1scale = fxMesa->s1scale; /* wrong if tmu1_source == 0, possible? */
v1scale = fxMesa->t1scale;
if (IND & SETUP_PTEX)
tc1_size = VB->TexCoordPtr[tmu1_source]->size;
}
if (IND & SETUP_RGBA) {
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
import_float_colors( ctx );
col = VB->ColorPtr[0]->Ptr;
col_stride = VB->ColorPtr[0]->StrideB;
}
if (VB->ClipOrMask) {
for (i = start; i < end; i++, v++) {
if (!clipmask[i]) {
if (IND & SETUP_XYZW) {
v->v.x = s[0] * proj[i][0] + s[12];
v->v.y = s[5] * proj[i][1] + s[13];
v->v.ooz = s[10] * proj[i][2] + s[14];
v->v.oow = proj[i][3];
if (start) {
proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride);
if (IND & SETUP_TMU0)
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride);
if (IND & SETUP_TMU1)
tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride);
if (IND & SETUP_RGBA)
STRIDE_4UB(col, start * col_stride);
}
if (IND & SETUP_SNAP) {
for (i=start; i < end; i++, v++) {
if (IND & SETUP_XYZW) {
/* unclipped */
v->x = s[0] * proj[0][0] + s[12];
v->y = s[5] * proj[0][1] + s[13];
v->ooz = s[10] * proj[0][2] + s[14];
v->oow = proj[0][3];
if (IND & SETUP_SNAP) {
#if defined(USE_IEEE)
const float snapper = (3L << 18);
v->v.x += snapper;
v->v.x -= snapper;
v->v.y += snapper;
v->v.y -= snapper;
const float snapper = (3L << 18);
v->x += snapper;
v->x -= snapper;
v->y += snapper;
v->y -= snapper;
#else
v->v.x = ((int) (v->v.x * 16.0f)) * (1.0f / 16.0f);
v->v.y = ((int) (v->v.y * 16.0f)) * (1.0f / 16.0f);
v->x = ((int) (v->x * 16.0f)) * (1.0f / 16.0f);
v->y = ((int) (v->y * 16.0f)) * (1.0f / 16.0f);
#endif
}
}
if (IND & SETUP_RGBA) {
UNCLAMPED_FLOAT_TO_UBYTE(v->v.r, color[i][0]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.g, color[i][1]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.b, color[i][2]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.a, color[i][3]);
}
if (IND & SETUP_TMU0) {
v->v.tmuvtx[0].sow = sscale0 * tmu0_data[i][0] * v->v.oow;
v->v.tmuvtx[0].tow = tscale0 * tmu0_data[i][1] * v->v.oow;
}
if (IND & SETUP_TMU1) {
v->v.tmuvtx[1].sow = sscale1 * tmu1_data[i][0] * v->v.oow;
v->v.tmuvtx[1].tow = tscale1 * tmu1_data[i][1] * v->v.oow;
}
}
}
}
else {
for (i = start; i < end; i++, v++) {
if (IND & SETUP_XYZW) {
v->v.x = s[0] * proj[i][0] + s[12];
v->v.y = s[5] * proj[i][1] + s[13];
v->v.ooz = s[10] * proj[i][2] + s[14];
v->v.oow = proj[i][3];
if (IND & SETUP_SNAP) {
#if defined(USE_IEEE)
const float snapper = (3L << 18);
v->v.x += snapper;
v->v.x -= snapper;
v->v.y += snapper;
v->v.y -= snapper;
#else
v->v.x = ((int) (v->v.x * 16.0f)) * (1.0f / 16.0f);
v->v.y = ((int) (v->v.y * 16.0f)) * (1.0f / 16.0f);
#endif
}
proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride);
}
if (IND & SETUP_RGBA) {
v->r = (GLfloat) col[0][0];
v->g = (GLfloat) col[0][1];
v->b = (GLfloat) col[0][2];
v->a = (GLfloat) col[0][3];
STRIDE_4UB(col, col_stride);
}
if (IND & SETUP_TMU0) {
GLfloat w = v->oow;
if (IND & SETUP_PTEX) {
v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
v->tmuvtx[0].oow = w;
if (tc0_size == 4)
v->tmuvtx[0].oow = tc0[0][3] * w;
}
else {
v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
}
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
}
if (IND & SETUP_TMU1) {
GLfloat w = v->oow;
if (IND & SETUP_PTEX) {
v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
v->tmuvtx[1].oow = w;
if (tc1_size == 4)
v->tmuvtx[1].oow = tc1[0][3] * w;
}
else {
v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
}
if (IND & SETUP_RGBA) {
UNCLAMPED_FLOAT_TO_UBYTE(v->v.r, color[i][0]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.g, color[i][1]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.b, color[i][2]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.a, color[i][3]);
}
if (IND & SETUP_TMU0) {
v->v.tmuvtx[0].sow = sscale0 * tmu0_data[i][0] * v->v.oow;
v->v.tmuvtx[0].tow = tscale0 * tmu0_data[i][1] * v->v.oow;
}
if (IND & SETUP_TMU1) {
v->v.tmuvtx[1].sow = sscale1 * tmu1_data[i][0] * v->v.oow;
v->v.tmuvtx[1].tow = tscale1 * tmu1_data[i][1] * v->v.oow;
}
}
}
if ((IND & SETUP_XYZW) &&
ctx->ProjectionMatrix.m[15] != 0.0F && ctx->Fog.Enabled) {
fx_fake_fog_w(ctx, v, VB, start, end);
}
/* Check for and enable projective texturing in each texture unit.
*/
if (IND & (SETUP_TMU0 | SETUP_TMU1)) {
GLuint tmu0_sz = 2;
GLuint tmu1_sz = 2;
GLuint hs = fxMesa->stw_hint_state & ~(GR_STWHINT_W_DIFF_TMU0 |
GR_STWHINT_W_DIFF_TMU1);
if (VB->TexCoordPtr[tmu0_source])
tmu0_sz = VB->TexCoordPtr[tmu0_source]->size;
if (VB->TexCoordPtr[tmu1_source])
tmu1_sz = VB->TexCoordPtr[tmu1_source]->size;
if (tmu0_sz == 4) {
project_texcoords(v, VB, 0, tmu0_source, start, end);
if (tmu1_sz == 4)
project_texcoords(v, VB, 1, tmu1_source, start, end);
else
copy_w(v, VB, 1, start, end);
hs |= (GR_STWHINT_W_DIFF_TMU0 | GR_STWHINT_W_DIFF_TMU1);
}
else if (tmu1_sz == 4) {
project_texcoords(v, VB, 1, tmu1_source, start, end);
hs |= GR_STWHINT_W_DIFF_TMU1;
}
if (hs != fxMesa->stw_hint_state) {
fxMesa->stw_hint_state = hs;
FX_grHints(GR_HINT_STWHINT, hs);
}
tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride);
}
}
}
#if (IND & SETUP_XYZW) && (IND & SETUP_RGBA)
static GLboolean TAG(check_tex_sizes)( GLcontext *ctx )
{
/* fprintf(stderr, "%s\n", __FUNCTION__); */
if (IND & SETUP_PTEX)
return GL_TRUE;
if (IND & SETUP_TMU0) {
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
if (IND & SETUP_TMU1) {
if (VB->TexCoordPtr[0] == 0)
VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
if (VB->TexCoordPtr[1]->size == 4)
return GL_FALSE;
}
if (VB->TexCoordPtr[0]->size == 4)
return GL_FALSE;
}
return GL_TRUE;
}
static void TAG(interp)( GLcontext *ctx,
GLfloat t,
GLuint edst, GLuint eout, GLuint ein,
GLboolean force_boundary )
{
fxMesaContext fxMesa = FX_CONTEXT( ctx );
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
const GLfloat *dstclip = VB->ClipPtr->data[edst];
const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]);
const GLfloat *const s = ctx->Viewport._WindowMap.m;
GrVertex *fxverts = fxMesa->verts;
GrVertex *dst = (GrVertex *) (fxverts + edst);
const GrVertex *out = (const GrVertex *) (fxverts + eout);
const GrVertex *in = (const GrVertex *) (fxverts + ein);
const GLfloat wout = 1.0F / out->oow;
const GLfloat win = 1.0F / in->oow;
dst->x = s[0] * dstclip[0] * oow + s[12];
dst->y = s[5] * dstclip[1] * oow + s[13];
dst->z = s[10] * dstclip[2] * oow + s[14];
dst->oow = oow;
if (IND & SETUP_SNAP) {
#if defined(USE_IEEE)
const float snapper = (3L << 18);
dst->x += snapper;
dst->x -= snapper;
dst->y += snapper;
dst->y -= snapper;
#else
dst->x = ((int) (dst->x * 16.0f)) * (1.0f / 16.0f);
dst->y = ((int) (dst->y * 16.0f)) * (1.0f / 16.0f);
#endif
}
INTERP_F( t, dst->r, out->r, in->r );
INTERP_F( t, dst->g, out->g, in->g );
INTERP_F( t, dst->b, out->b, in->b );
INTERP_F( t, dst->a, out->a, in->a );
if (IND & SETUP_TMU0) {
if (IND & SETUP_PTEX) {
INTERP_F( t,
dst->tmuvtx[0].sow,
out->tmuvtx[0].sow * wout,
in->tmuvtx[0].sow * win );
INTERP_F( t,
dst->tmuvtx[0].tow,
out->tmuvtx[0].tow * wout,
in->tmuvtx[0].tow * win );
INTERP_F( t,
dst->tmuvtx[0].oow,
out->tmuvtx[0].oow * wout,
in->tmuvtx[0].oow * win );
dst->tmuvtx[0].sow *= oow;
dst->tmuvtx[0].tow *= oow;
dst->tmuvtx[0].oow *= oow;
} else {
INTERP_F( t,
dst->tmuvtx[0].sow,
out->tmuvtx[0].sow * wout,
in->tmuvtx[0].sow * win );
INTERP_F( t,
dst->tmuvtx[0].tow,
out->tmuvtx[0].tow * wout,
in->tmuvtx[0].tow * win );
dst->tmuvtx[0].sow *= oow;
dst->tmuvtx[0].tow *= oow;
}
}
if (IND & SETUP_TMU1) {
if (IND & SETUP_PTEX) {
INTERP_F( t,
dst->tmuvtx[1].sow,
out->tmuvtx[1].sow * wout,
in->tmuvtx[1].sow * win );
INTERP_F( t,
dst->tmuvtx[1].tow,
out->tmuvtx[1].tow * wout,
in->tmuvtx[1].tow * win );
INTERP_F( t,
dst->tmuvtx[1].oow,
out->tmuvtx[1].oow * wout,
in->tmuvtx[1].oow * win );
dst->tmuvtx[1].sow *= oow;
dst->tmuvtx[1].tow *= oow;
dst->tmuvtx[1].oow *= oow;
} else {
INTERP_F( t,
dst->tmuvtx[1].sow,
out->tmuvtx[1].sow * wout,
in->tmuvtx[1].sow * win );
INTERP_F( t,
dst->tmuvtx[1].tow,
out->tmuvtx[1].tow * wout,
in->tmuvtx[1].tow * win );
dst->tmuvtx[1].sow *= oow;
dst->tmuvtx[1].tow *= oow;
}
}
}
#endif
static void TAG(init)( void )
{
setup_tab[IND].emit = TAG(emit);
#if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
setup_tab[IND].interp = TAG(interp);
if (IND & SETUP_PTEX) {
setup_tab[IND].vertex_format = (GR_STWHINT_W_DIFF_TMU0 |
GR_STWHINT_W_DIFF_TMU1);
}
else {
setup_tab[IND].vertex_format = 0;
}
#endif
}
#undef IND
#undef NAME
#undef INPUTS
#undef TAG

View file

@ -1,4 +1,4 @@
/* $Id: osmesa.c,v 1.60 2001/07/05 15:12:13 brianp Exp $ */
/* $Id: osmesa.c,v 1.61 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -346,6 +346,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
_swsetup_Wakeup( ctx );
osmesa_register_swrast_functions( ctx );
}
}
@ -2072,20 +2073,6 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
swdd->SetReadBuffer = set_read_buffer;
tnl->Driver.RunPipeline = _tnl_run_pipeline;
tnl->Driver.RenderStart = _swsetup_RenderStart;
tnl->Driver.RenderFinish = _swsetup_RenderFinish;
tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
tnl->Driver.PointsFunc = _swsetup_Points;
tnl->Driver.LineFunc = _swsetup_Line;
tnl->Driver.TriangleFunc = _swsetup_Triangle;
tnl->Driver.QuadFunc = _swsetup_Quad;
tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.RenderInterp = _swsetup_RenderInterp;
tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );

View file

@ -1,4 +1,4 @@
/* $Id: xm_dd.c,v 1.24 2001/05/10 12:22:32 keithw Exp $ */
/* $Id: xm_dd.c,v 1.25 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -992,19 +992,10 @@ void xmesa_init_pointers( GLcontext *ctx )
*/
tnl = TNL_CONTEXT(ctx);
tnl->Driver.RunPipeline = _tnl_run_pipeline;
tnl->Driver.RenderStart = _swsetup_RenderStart;
tnl->Driver.RenderFinish = _swsetup_RenderFinish;
tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
tnl->Driver.PointsFunc = _swsetup_Points;
tnl->Driver.LineFunc = _swsetup_Line;
tnl->Driver.TriangleFunc = _swsetup_Triangle;
tnl->Driver.QuadFunc = _swsetup_Quad;
tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.RenderInterp = _swsetup_RenderInterp;
tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
/* Install swsetup for tnl->Driver.Render.*:
*/
_swsetup_Wakeup(ctx);
(void) DitherValues; /* silenced unused var warning */
}

View file

@ -1,4 +1,4 @@
# $Id: Makefile.X11,v 1.55 2001/06/27 12:52:12 keithw Exp $
# $Id: Makefile.X11,v 1.56 2001/07/12 22:09:21 keithw Exp $
# Mesa 3-D graphics library
# Version: 3.5
@ -21,6 +21,9 @@ LIBDIR = ../lib
CORE_SOURCES = \
swrast_setup/ss_context.c \
swrast_setup/ss_triangle.c \
swrast_setup/ss_vb.c \
api_arrayelt.c \
api_loopback.c \
api_noop.c \
@ -118,10 +121,6 @@ CORE_SOURCES = \
swrast/s_texstore.c \
swrast/s_triangle.c \
swrast/s_zoom.c \
swrast_setup/ss_context.c \
swrast_setup/ss_triangle.c \
swrast_setup/ss_vb.c \
swrast_setup/ss_interp.c \
tnl/t_array_api.c \
tnl/t_array_import.c \
tnl/t_context.c \

View file

@ -1,4 +1,4 @@
/* $Id: s_context.c,v 1.21 2001/05/17 09:32:17 keithw Exp $ */
/* $Id: s_context.c,v 1.22 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -529,7 +529,7 @@ _swrast_GetDeviceDriverReference( GLcontext *ctx )
return &swrast->Driver;
}
#define SWRAST_DEBUG_VERTICES 0
#define SWRAST_DEBUG_VERTICES 1
void
_swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
@ -540,6 +540,8 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
fprintf(stderr, "win %f %f %f %f\n",
v->win[0], v->win[1], v->win[2], v->win[3]);
return;
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
fprintf(stderr, "texcoord[%d] %f %f %f %f\n", i,
v->texcoord[i][0], v->texcoord[i][1],

View file

@ -6,10 +6,8 @@ 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.
The module implements a full set of functions to plug into the
t_vb_render.c driver interface (tnl->Driver.Render.*).
There are strong advantages to decoupling the software rasterizer from
the t&l module, primarily allowing hardware drivers better control
@ -18,63 +16,50 @@ 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.
This module implements 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.
Hardware rasterization drivers typically use this module in situations
where no hardware rasterization is possible, ie during total
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:
To create and destroy the module:
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:
The module is not active by default, and must be installed by calling
_swrast_Wakeup(). This function installs internal swrast_setup
functions into all the tnl->Driver.Render driver hooks, thus taking
over the task of rasterization entirely:
void _swrast_Wakeup( GLcontext *ctx );
This module tracks state changes internally and maintains derived
values based on the current state. For this to work, the driver
ensure the following funciton is called whenever the state changes and
the swsetup module is 'awake':
void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state );
SERVICES
There is no explicit call to put the swsetup module to sleep. Simply
install other function pointers into all the tnl->Driver.Render.*
hooks, and (optionally) cease calling _swsetup_InvalidateState().
The module provides the following entrypoints:
DRIVER INTERFACE
void _swrast_RasterSetup( struct vertex_buffer *VB,
GLuint start, GLuint end );
The module offers a minimal driver interface:
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 (*Start)( GLcontext *ctx );
void (*Finish)( GLcontext *ctx );
These are called before and after the completion of all swrast drawing
activity. As swrast doesn't call callbacks during triangle, line or
point rasterization, these are necessary to provide locking hooks for
some drivers. They may otherwise be left null.
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

@ -1,4 +1,4 @@
/* $Id: ss_context.c,v 1.13 2001/03/12 00:48:43 gareth Exp $ */
/* $Id: ss_context.c,v 1.14 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -32,12 +32,14 @@
#include "ss_context.h"
#include "ss_triangle.h"
#include "ss_vb.h"
#include "ss_interp.h"
#include "swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#define _SWSETUP_NEW_VERTS (_NEW_RENDERMODE| \
_NEW_POLYGON| \
_NEW_LIGHT| \
_NEW_TEXTURE| \
_NEW_COLOR| \
@ -47,47 +49,6 @@
#define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT)
/* Dispatch from these fixed entrypoints to the state-dependent
* functions.
*
* The design of swsetup suggests that we could really program
* ctx->Driver.TriangleFunc directly from _swsetup_RenderStart, and
* avoid this second level of indirection. However, this is more
* convient for fallback cases in hardware rasterization drivers.
*/
void
_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint v3 )
{
SWSETUP_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3 );
}
void
_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2 )
{
SWSETUP_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 );
}
void
_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1 )
{
SWSETUP_CONTEXT(ctx)->Line( ctx, v0, v1 );
}
void
_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last )
{
SWSETUP_CONTEXT(ctx)->Points( ctx, first, last );
}
void
_swsetup_BuildProjectedVertices( GLcontext *ctx, GLuint start, GLuint end,
GLuint new_inputs )
{
SWSETUP_CONTEXT(ctx)->BuildProjVerts( ctx, start, end, new_inputs );
}
GLboolean
_swsetup_CreateContext( GLcontext *ctx )
@ -98,7 +59,8 @@ _swsetup_CreateContext( GLcontext *ctx )
if (!swsetup)
return GL_FALSE;
swsetup->verts = (SWvertex *) ALIGN_MALLOC( sizeof(SWvertex) * tnl->vb.Size, 32);
swsetup->verts = (SWvertex *) ALIGN_MALLOC( sizeof(SWvertex) * tnl->vb.Size,
32);
if (!swsetup->verts) {
FREE(swsetup);
return GL_FALSE;
@ -108,7 +70,6 @@ _swsetup_CreateContext( GLcontext *ctx )
swsetup->NewState = ~0;
_swsetup_vb_init( ctx );
_swsetup_interp_init( ctx );
_swsetup_trifuncs_init( ctx );
return GL_TRUE;
@ -126,17 +87,16 @@ _swsetup_DestroyContext( GLcontext *ctx )
}
}
void
static void
_swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode )
{
SWSETUP_CONTEXT(ctx)->render_prim = mode;
}
void
static void
_swsetup_RenderStart( GLcontext *ctx )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLuint new_state = swsetup->NewState;
if (new_state & _SWSETUP_NEW_RENDERINDEX) {
@ -149,16 +109,19 @@ _swsetup_RenderStart( GLcontext *ctx )
swsetup->NewState = 0;
if (VB->ClipMask && VB->importable_data)
VB->import_data( ctx,
VB->importable_data,
VEC_NOT_WRITEABLE|VEC_BAD_STRIDE);
if (swsetup->Driver.Start)
swsetup->Driver.Start( ctx );
}
void
static void
_swsetup_RenderFinish( GLcontext *ctx )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
_swrast_flush( ctx );
if (swsetup->Driver.Finish)
swsetup->Driver.Finish( ctx );
}
void
@ -166,23 +129,29 @@ _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
swsetup->NewState |= new_state;
if (new_state & _SWSETUP_NEW_INTERP) {
swsetup->RenderInterp = _swsetup_validate_interp;
swsetup->RenderCopyPV = _swsetup_validate_copypv;
}
}
void
_swsetup_RenderInterp( GLcontext *ctx, GLfloat t,
GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary )
_swsetup_Wakeup( GLcontext *ctx )
{
SWSETUP_CONTEXT(ctx)->RenderInterp( ctx, t, dst, out, in, force_boundary );
}
void
_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src )
{
SWSETUP_CONTEXT(ctx)->RenderCopyPV( ctx, dst, src );
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.Start = _swsetup_RenderStart;
tnl->Driver.Render.Finish = _swsetup_RenderFinish;
tnl->Driver.Render.PrimitiveNotify = _swsetup_RenderPrimitive;
/* interp */
/* copypv */
tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; /* new */
tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; /* new */
/* points */
/* line */
/* triangle */
/* quad */
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
/* buildvertices */
tnl->Driver.Render.Multipass = 0;
_tnl_need_projected_coords( ctx, GL_TRUE );
_swsetup_InvalidateState( ctx, ~0 );
}

View file

@ -1,4 +1,4 @@
/* $Id: ss_context.h,v 1.7 2001/03/12 00:48:43 gareth Exp $ */
/* $Id: ss_context.h,v 1.8 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -36,35 +36,14 @@
typedef struct {
GLuint NewState;
GLuint StateChanges;
/* Function hooks, trigger lazy state updates.
*/
void (*InvalidateState)( GLcontext *ctx, GLuint new_state );
void (*BuildProjVerts)( GLcontext *ctx,
GLuint start, GLuint end, GLuint new_inputs );
void (*Quad)( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint v3 );
void (*Triangle)( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2 );
void (*Line)( GLcontext *ctx, GLuint v0, GLuint v1 );
void (*Points)( GLcontext *ctx, GLuint first, GLuint last );
void (*RenderCopyPV)( GLcontext *ctx, GLuint dst, GLuint src );
void (*RenderInterp)( GLcontext *ctx, GLfloat t,
GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary );
SWvertex *verts;
GLenum render_prim;
GLuint SetupIndex;
struct {
void (*Start)( GLcontext * );
void (*Finish)( GLcontext * );
} Driver;
} SScontext;
#define SWSETUP_CONTEXT(ctx) ((SScontext *)ctx->swsetup_context)

View file

@ -1,4 +1,4 @@
/* $Id: ss_triangle.c,v 1.13 2001/04/28 08:39:18 keithw Exp $ */
/* $Id: ss_triangle.c,v 1.14 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -262,7 +262,7 @@ static void swsetup_line( GLcontext *ctx, GLuint v0, GLuint v1 )
void _swsetup_choose_trifuncs( GLcontext *ctx )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint ind = 0;
if (ctx->Polygon._OffsetAny)
@ -277,8 +277,8 @@ void _swsetup_choose_trifuncs( GLcontext *ctx )
if (ctx->Visual.rgbMode)
ind |= SS_RGBA_BIT;
swsetup->Triangle = tri_tab[ind];
swsetup->Quad = quad_tab[ind];
swsetup->Line = swsetup_line;
swsetup->Points = swsetup_points;
tnl->Driver.Render.Triangle = tri_tab[ind];
tnl->Driver.Render.Quad = quad_tab[ind];
tnl->Driver.Render.Line = swsetup_line;
tnl->Driver.Render.Points = swsetup_points;
}

View file

@ -1,4 +1,4 @@
/* $Id: ss_tritmp.h,v 1.12 2001/04/28 08:39:18 keithw Exp $ */
/* $Id: ss_tritmp.h,v 1.13 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -62,13 +62,15 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
if (IND & SS_TWOSIDE_BIT) {
if (IND & SS_RGBA_BIT) {
GLfloat (*vbcolor)[4] = (GLfloat (*)[4])VB->ColorPtr[1]->Ptr;
GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[1]->Ptr;
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]);
if (VB->SecondaryColorPtr[1]) {
GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[1]->Ptr;
SS_SPEC(v[0]->specular, vbspec[e0]);
SS_SPEC(v[1]->specular, vbspec[e1]);
SS_SPEC(v[2]->specular, vbspec[e2]);
}
} else {
GLuint *vbindex = VB->IndexPtr[1]->data;
SS_IND(v[0]->index, vbindex[e0]);
@ -135,13 +137,15 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
if (facing == 1) {
if (IND & SS_RGBA_BIT) {
GLfloat (*vbcolor)[4] = (GLfloat (*)[4])VB->ColorPtr[0]->Ptr;
GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr;
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]);
if (VB->SecondaryColorPtr[0]) {
GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr;
SS_SPEC(v[0]->specular, vbspec[e0]);
SS_SPEC(v[1]->specular, vbspec[e1]);
SS_SPEC(v[2]->specular, vbspec[e2]);
}
} else {
GLuint *vbindex = VB->IndexPtr[0]->data;
SS_IND(v[0]->index, vbindex[e0]);

View file

@ -1,4 +1,4 @@
/* $Id: ss_vb.c,v 1.12 2001/03/29 21:16:26 keithw Exp $ */
/* $Id: ss_vb.c,v 1.13 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -46,8 +46,6 @@
* in this module, but not the rest of the swrast module.
*/
typedef void (*SetupFunc)( GLcontext *ctx,
GLuint start, GLuint end, GLuint newinputs );
#define COLOR 0x1
#define INDEX 0x2
@ -58,7 +56,9 @@ typedef void (*SetupFunc)( GLcontext *ctx,
#define POINT 0x40
#define MAX_SETUPFUNC 0x80
static SetupFunc setup_func[MAX_SETUPFUNC];
static setup_func setup_tab[MAX_SETUPFUNC];
static interp_func interp_tab[MAX_SETUPFUNC];
static copy_pv_func copy_pv_tab[MAX_SETUPFUNC];
#define IND (0)
@ -165,84 +165,150 @@ static SetupFunc setup_func[MAX_SETUPFUNC];
#define TAG(x) x##_index
#include "ss_vbtmp.h"
#define IND (INDEX|TEX0)
#define TAG(x) x##_index_tex0
#include "ss_vbtmp.h"
#define IND (INDEX|FOG)
#define TAG(x) x##_index_fog
#include "ss_vbtmp.h"
#define IND (INDEX|TEX0|FOG)
#define TAG(x) x##_index_tex0_fog
#include "ss_vbtmp.h"
#define IND (INDEX|POINT)
#define TAG(x) x##_index_point
#include "ss_vbtmp.h"
#define IND (INDEX|TEX0|POINT)
#define TAG(x) x##_index_tex0_point
#include "ss_vbtmp.h"
#define IND (INDEX|FOG|POINT)
#define TAG(x) x##_index_fog_point
#include "ss_vbtmp.h"
#define IND (INDEX|TEX0|FOG|POINT)
#define TAG(x) x##_index_tex0_fog_point
#include "ss_vbtmp.h"
/***********************************************************************
* Additional setup and interp for back color and edgeflag.
***********************************************************************/
#define GET_COLOR(ptr, idx) (((GLfloat (*)[4])((ptr)->Ptr))[idx])
static void interp_extras( GLcontext *ctx,
GLfloat t,
GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
if (VB->ColorPtr[1]) {
INTERP_4F( t,
GET_COLOR(VB->ColorPtr[1], dst),
GET_COLOR(VB->ColorPtr[1], out),
GET_COLOR(VB->ColorPtr[1], in) );
if (VB->SecondaryColorPtr[1]) {
INTERP_3F( t,
GET_COLOR(VB->SecondaryColorPtr[1], dst),
GET_COLOR(VB->SecondaryColorPtr[1], out),
GET_COLOR(VB->SecondaryColorPtr[1], in) );
}
}
else if (VB->IndexPtr[1]) {
VB->IndexPtr[1]->data[dst] = (GLuint) (GLint)
LINTERP( t,
(GLfloat) VB->IndexPtr[1]->data[out],
(GLfloat) VB->IndexPtr[1]->data[in] );
}
if (VB->EdgeFlag) {
VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
}
interp_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, t, dst, out, in,
force_boundary);
}
static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
if (VB->ColorPtr[1]) {
COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
GET_COLOR(VB->ColorPtr[1], src) );
if (VB->SecondaryColorPtr[1]) {
COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst),
GET_COLOR(VB->SecondaryColorPtr[1], src) );
}
}
else if (VB->IndexPtr[1]) {
VB->IndexPtr[1]->data[dst] = VB->IndexPtr[1]->data[src];
}
copy_pv_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, dst, src);
}
/***********************************************************************
* Initialization
***********************************************************************/
static void
rs_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs )
emit_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs )
{
fprintf(stderr, "swrast_setup: invalid setup function\n");
(void) (ctx && start && end && newinputs);
}
void
_swsetup_vb_init( GLcontext *ctx )
static void
interp_invalid( GLcontext *ctx, GLfloat t,
GLuint edst, GLuint eout, GLuint ein,
GLboolean force_boundary )
{
fprintf(stderr, "swrast_setup: invalid interp function\n");
(void) (ctx && t && edst && eout && ein && force_boundary);
}
static void
copy_pv_invalid( GLcontext *ctx, GLuint edst, GLuint esrc )
{
fprintf(stderr, "swrast_setup: invalid copy_pv function\n");
(void) (ctx && edst && esrc );
}
static void init_standard( void )
{
GLuint i;
(void) ctx;
for (i = 0 ; i < Elements(setup_func) ; i++)
setup_func[i] = rs_invalid;
for (i = 0 ; i < Elements(setup_tab) ; i++) {
setup_tab[i] = emit_invalid;
interp_tab[i] = interp_invalid;
copy_pv_tab[i] = copy_pv_invalid;
}
setup_func[0] = rs_none;
setup_func[COLOR] = rs_color;
setup_func[COLOR|SPEC] = rs_color_spec;
setup_func[COLOR|FOG] = rs_color_fog;
setup_func[COLOR|SPEC|FOG] = rs_color_spec_fog;
setup_func[COLOR|TEX0] = rs_color_tex0;
setup_func[COLOR|TEX0|SPEC] = rs_color_tex0_spec;
setup_func[COLOR|TEX0|FOG] = rs_color_tex0_fog;
setup_func[COLOR|TEX0|SPEC|FOG] = rs_color_tex0_spec_fog;
setup_func[COLOR|MULTITEX] = rs_color_multitex;
setup_func[COLOR|MULTITEX|SPEC] = rs_color_multitex_spec;
setup_func[COLOR|MULTITEX|FOG] = rs_color_multitex_fog;
setup_func[COLOR|MULTITEX|SPEC|FOG] = rs_color_multitex_spec_fog;
setup_func[COLOR|POINT] = rs_color_point;
setup_func[COLOR|SPEC|POINT] = rs_color_spec_point;
setup_func[COLOR|FOG|POINT] = rs_color_fog_point;
setup_func[COLOR|SPEC|FOG|POINT] = rs_color_spec_fog_point;
setup_func[COLOR|TEX0|POINT] = rs_color_tex0_point;
setup_func[COLOR|TEX0|SPEC|POINT] = rs_color_tex0_spec_point;
setup_func[COLOR|TEX0|FOG|POINT] = rs_color_tex0_fog_point;
setup_func[COLOR|TEX0|SPEC|FOG|POINT] = rs_color_tex0_spec_fog_point;
setup_func[COLOR|MULTITEX|POINT] = rs_color_multitex_point;
setup_func[COLOR|MULTITEX|SPEC|POINT] = rs_color_multitex_spec_point;
setup_func[COLOR|MULTITEX|FOG|POINT] = rs_color_multitex_fog_point;
setup_func[COLOR|MULTITEX|SPEC|FOG|POINT] = rs_color_multitex_spec_fog_point;
setup_func[INDEX] = rs_index;
setup_func[INDEX|TEX0] = rs_index_tex0;
setup_func[INDEX|FOG] = rs_index_fog;
setup_func[INDEX|TEX0|FOG] = rs_index_tex0_fog;
setup_func[INDEX|POINT] = rs_index_point;
setup_func[INDEX|TEX0|POINT] = rs_index_tex0_point;
setup_func[INDEX|FOG|POINT] = rs_index_fog_point;
setup_func[INDEX|TEX0|FOG|POINT] = rs_index_tex0_fog_point;
init_none();
init_color();
init_color_spec();
init_color_fog();
init_color_spec_fog();
init_color_tex0();
init_color_tex0_spec();
init_color_tex0_fog();
init_color_tex0_spec_fog();
init_color_multitex();
init_color_multitex_spec();
init_color_multitex_fog();
init_color_multitex_spec_fog();
init_color_point();
init_color_spec_point();
init_color_fog_point();
init_color_spec_fog_point();
init_color_tex0_point();
init_color_tex0_spec_point();
init_color_tex0_fog_point();
init_color_tex0_spec_fog_point();
init_color_multitex_point();
init_color_multitex_spec_point();
init_color_multitex_fog_point();
init_color_multitex_spec_fog_point();
init_index();
init_index_fog();
init_index_point();
init_index_fog_point();
}
static void printSetupFlags(char *msg, GLuint flags )
@ -260,10 +326,12 @@ static void printSetupFlags(char *msg, GLuint flags )
}
void
_swsetup_choose_rastersetup_func(GLcontext *ctx)
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
int funcindex = 0;
if (ctx->RenderMode == GL_RENDER) {
@ -275,8 +343,7 @@ _swsetup_choose_rastersetup_func(GLcontext *ctx)
else if (ctx->Texture._ReallyEnabled & 0xf)
funcindex |= TEX0;
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
ctx->Fog.ColorSumEnabled)
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
funcindex |= SPEC;
}
else {
@ -293,12 +360,33 @@ _swsetup_choose_rastersetup_func(GLcontext *ctx)
if (ctx->Visual.rgbMode)
funcindex = (COLOR | TEX0); /* is feedback color subject to fogging? */
else
funcindex = (INDEX | TEX0);
funcindex = INDEX;
}
else
funcindex = 0;
swsetup->SetupIndex = funcindex;
tnl->Driver.Render.BuildVertices = setup_tab[funcindex];
if (0) printSetupFlags("software setup func", funcindex);
swsetup->BuildProjVerts = setup_func[funcindex];
ASSERT(setup_func[funcindex] != rs_invalid);
if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
tnl->Driver.Render.Interp = interp_extras;
tnl->Driver.Render.CopyPV = copy_pv_extras;
}
else {
tnl->Driver.Render.Interp = interp_tab[funcindex];
tnl->Driver.Render.CopyPV = copy_pv_tab[funcindex];
}
ASSERT(tnl->Driver.Render.BuildVertices);
ASSERT(tnl->Driver.Render.BuildVertices != emit_invalid);
}
void
_swsetup_vb_init( GLcontext *ctx )
{
(void) ctx;
init_standard();
(void) printSetupFlags;
}

View file

@ -1,4 +1,4 @@
/* $Id: ss_vbtmp.h,v 1.15 2001/04/30 09:04:00 keithw Exp $ */
/* $Id: ss_vbtmp.h,v 1.16 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -28,19 +28,23 @@
*/
static void TAG(rs)(GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs )
static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
GLuint newinputs )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
SWvertex *v;
GLfloat (*proj)[4]; /* projected clip coordinates */
GLfloat (*tc[MAX_TEXTURE_UNITS])[4];
GLfloat (*color)[4];
GLfloat (*spec)[4];
GLfloat *proj; /* projected clip coordinates */
GLfloat *tc[MAX_TEXTURE_UNITS];
GLfloat *color;
GLfloat *spec;
GLuint *index;
GLfloat *fog;
GLfloat *pointSize;
GLuint tsz[MAX_TEXTURE_UNITS];
GLuint tstride[MAX_TEXTURE_UNITS];
GLuint proj_stride, color_stride, spec_stride, index_stride;
GLuint fog_stride, pointSize_stride;
GLuint i;
GLfloat *m = ctx->Viewport._WindowMap.m;
const GLfloat sx = m[0];
@ -51,96 +55,202 @@ static void TAG(rs)(GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs )
const GLfloat tz = m[14];
GLuint maxtex = 0;
/* Only the most basic optimization for cva:
*/
if (!newinputs)
return;
/* TODO: Get import_client_data to pad vectors out to 4 cleanly.
*
* NOTE: This has the effect of converting any remaining ubyte
* colors to floats... As they're already there 90% of the
* time, this isn't a bad thing.
*/
if (VB->importable_data)
VB->import_data( ctx, VB->importable_data & newinputs,
(VB->ClipOrMask
? VEC_NOT_WRITEABLE|VEC_BAD_STRIDE
: VEC_BAD_STRIDE));
if (IND & TEX0) {
tc[0] = VB->TexCoordPtr[0]->data;
tc[0] = (GLfloat *)VB->TexCoordPtr[0]->data;
tsz[0] = VB->TexCoordPtr[0]->size;
tstride[0] = VB->TexCoordPtr[0]->stride;
}
if (IND & MULTITEX) {
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
if (VB->TexCoordPtr[i]) {
maxtex = i+1;
tc[i] = VB->TexCoordPtr[i]->data;
tc[i] = (GLfloat *)VB->TexCoordPtr[i]->data;
tsz[i] = VB->TexCoordPtr[i]->size;
tstride[i] = VB->TexCoordPtr[i]->stride;
}
else tc[i] = 0;
}
}
/* Tie up some dangling pointers for flat/twoside code in ss_tritmp.h
*/
if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) == 0) {
VB->SecondaryColorPtr[0] = VB->ColorPtr[0];
VB->SecondaryColorPtr[1] = VB->ColorPtr[1];
}
proj = VB->ProjectedClipPtr->data[0];
proj_stride = VB->ProjectedClipPtr->stride;
proj = VB->ProjectedClipPtr->data;
if (IND & FOG)
if (IND & FOG) {
fog = VB->FogCoordPtr->data;
if (IND & COLOR)
color = (GLfloat (*)[4])VB->ColorPtr[0]->Ptr;
if (IND & SPEC)
spec = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr;
if (IND & INDEX)
fog_stride = VB->FogCoordPtr->stride;
}
if (IND & COLOR) {
color = VB->ColorPtr[0]->Ptr;
color_stride = VB->ColorPtr[0]->StrideB;
}
if (IND & SPEC) {
spec = VB->SecondaryColorPtr[0]->Ptr;
spec_stride = VB->SecondaryColorPtr[0]->StrideB;
}
if (IND & INDEX) {
index = VB->IndexPtr[0]->data;
if (IND & POINT)
index_stride = VB->IndexPtr[0]->stride;
}
if (IND & POINT) {
pointSize = VB->PointSizePtr->data;
pointSize_stride = VB->PointSizePtr->stride;
}
v = &(SWSETUP_CONTEXT(ctx)->verts[start]);
for (i=start; i < end; i++, v++) {
if (VB->ClipMask[i] == 0) {
v->win[0] = sx * proj[i][0] + tx;
v->win[1] = sy * proj[i][1] + ty;
v->win[2] = sz * proj[i][2] + tz;
v->win[3] = proj[i][3];
if (IND & TEX0)
COPY_CLEAN_4V( v->texcoord[0], tsz[0], tc[0][i] );
if (IND & MULTITEX) {
GLuint u;
for (u = 0 ; u < maxtex ; u++)
if (tc[u])
COPY_CLEAN_4V( v->texcoord[u], tsz[u], tc[u][i] );
}
if (IND & COLOR)
UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->color, color[i]);
if (IND & SPEC)
UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->specular, spec[i]);
if (IND & FOG)
v->fog = fog[i];
if (IND & INDEX)
v->index = index[i];
if (IND & POINT)
v->pointSize = pointSize[i];
v->win[0] = sx * proj[0] + tx;
v->win[1] = sy * proj[1] + ty;
v->win[2] = sz * proj[2] + tz;
v->win[3] = proj[3];
}
STRIDE_F(proj, proj_stride);
if (IND & TEX0) {
COPY_CLEAN_4V( v->texcoord[0], tsz[0], tc[0] );
STRIDE_F(tc[0], tstride[0]);
}
if (IND & MULTITEX) {
GLuint u;
for (u = 0 ; u < maxtex ; u++)
if (tc[u]) {
COPY_CLEAN_4V( v->texcoord[u], tsz[u], tc[u] );
STRIDE_F(tc[u], tstride[u]);
}
}
if (IND & COLOR) {
UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->color, color);
STRIDE_F(color, color_stride);
/* COPY_CHAN4(v->color, color); */
/* STRIDE_CHAN(color, color_stride); */
}
if (IND & SPEC) {
UNCLAMPED_FLOAT_TO_RGB_CHAN(v->specular, spec);
STRIDE_F(spec, spec_stride);
/* COPY_CHAN4(v->specular, spec); */
/* STRIDE_CHAN(spec, spec_stride); */
}
if (IND & FOG) {
v->fog = fog[0];
STRIDE_F(fog, fog_stride);
}
if (IND & INDEX) {
v->index = index[0];
STRIDE_UI(index, index_stride);
}
if (IND & POINT) {
v->pointSize = pointSize[0];
STRIDE_F(pointSize, pointSize_stride);
}
}
}
static void TAG(interp)( GLcontext *ctx,
GLfloat t,
GLuint edst, GLuint eout, GLuint ein,
GLboolean force_boundary )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLfloat *m = ctx->Viewport._WindowMap.m;
GLfloat *clip = VB->ClipPtr->data[edst];
SWvertex *dst = &swsetup->verts[edst];
SWvertex *in = &swsetup->verts[ein];
SWvertex *out = &swsetup->verts[eout];
/* Avoid division by zero by rearranging order of clip planes?
*/
if (clip[3] != 0.0) {
GLfloat oow = 1.0F / clip[3];
dst->win[0] = m[0] * clip[0] * oow + m[12];
dst->win[1] = m[5] * clip[1] * oow + m[13];
dst->win[2] = m[10] * clip[2] * oow + m[14];
dst->win[3] = oow;
}
/* fprintf(stderr, "%s edst %d win %f %f %f %f\n", */
/* __FUNCTION__, edst, */
/* dst->win[0], dst->win[1], dst->win[2], dst->win[3]); */
if (IND & TEX0) {
INTERP_4F( t, dst->texcoord[0], out->texcoord[0], in->texcoord[0] );
}
if (IND & MULTITEX) {
GLuint u;
GLuint maxtex = ctx->Const.MaxTextureUnits;
for (u = 0 ; u < maxtex ; u++)
if (VB->TexCoordPtr[u]) {
INTERP_4F( t, dst->texcoord[u], out->texcoord[u], in->texcoord[u] );
}
}
if (IND & COLOR) {
INTERP_CHAN( t, dst->color[0], out->color[0], in->color[0] );
INTERP_CHAN( t, dst->color[1], out->color[1], in->color[1] );
INTERP_CHAN( t, dst->color[2], out->color[2], in->color[2] );
INTERP_CHAN( t, dst->color[3], out->color[3], in->color[3] );
}
if (IND & SPEC) {
INTERP_CHAN( t, dst->specular[0], out->specular[0], in->specular[0] );
INTERP_CHAN( t, dst->specular[1], out->specular[1], in->specular[1] );
INTERP_CHAN( t, dst->specular[2], out->specular[2], in->specular[2] );
}
if (IND & FOG) {
INTERP_F( t, dst->fog, out->fog, in->fog );
}
if (IND & INDEX) {
INTERP_UI( t, dst->index, out->index, in->index );
}
if (IND & POINT) {
INTERP_F( t, dst->pointSize, out->pointSize, in->pointSize );
}
}
static void TAG(copy_pv)( GLcontext *ctx, GLuint edst, GLuint esrc )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
SWvertex *dst = &swsetup->verts[edst];
SWvertex *src = &swsetup->verts[esrc];
if (IND & COLOR) {
COPY_CHAN4( dst->color, src->color );
}
if (IND & SPEC) {
COPY_3V( dst->specular, src->specular );
}
if (IND & INDEX) {
dst->index = src->index;
}
}
static void TAG(init)( void )
{
setup_tab[IND] = TAG(emit);
interp_tab[IND] = TAG(interp);
copy_pv_tab[IND] = TAG(copy_pv);
}
#undef TAG
#undef IND
#undef SETUP_FLAGS

View file

@ -1,4 +1,4 @@
/* $Id: swrast_setup.h,v 1.8 2001/03/12 00:48:43 gareth Exp $ */
/* $Id: swrast_setup.h,v 1.9 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -30,6 +30,10 @@
/* Public interface to the swrast_setup module. This module provides
* an implementation of the driver interface to t_vb_render.c, and uses
* the software rasterizer (swrast) to perform actual rasterization.
*
* The internals of the implementation are private, but can be hooked
* into tnl at any time (except between RenderStart/RenderEnd) by
* calling _swsetup_Wakeup().
*/
#ifndef SWRAST_SETUP_H
@ -45,48 +49,6 @@ extern void
_swsetup_InvalidateState( GLcontext *ctx, GLuint new_state );
extern void
_swsetup_BuildProjectedVertices( GLcontext *ctx,
GLuint start,
GLuint end,
GLuint new_inputs );
extern void
_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3 );
extern void
_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2 );
extern void
_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1 );
extern void
_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last );
extern void
_swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode );
extern void
_swsetup_RenderStart( GLcontext *ctx );
extern void
_swsetup_RenderFinish( GLcontext *ctx );
extern void
_swsetup_RenderProjectInterpVerts( GLcontext *ctx );
extern void
_swsetup_RenderInterp( GLcontext *ctx, GLfloat t,
GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary );
extern void
_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src );
extern void
_swsetup_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n );
extern void
_swsetup_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj );
_swsetup_Wakeup( GLcontext *ctx );
#endif

View file

@ -1,4 +1,4 @@
/* $Id: t_context.c,v 1.20 2001/06/28 17:34:14 keithw Exp $ */
/* $Id: t_context.c,v 1.21 2001/07/12 22:09:21 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -123,8 +123,8 @@ _tnl_CreateContext( GLcontext *ctx )
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
tnl->Driver.RenderTabElts = _tnl_render_tab_elts;
tnl->Driver.RenderTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
return GL_TRUE;

View file

@ -1,4 +1,4 @@
/* $Id: t_context.h,v 1.29 2001/06/28 17:34:14 keithw Exp $ */
/* $Id: t_context.h,v 1.30 2001/07/12 22:09:22 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -376,6 +376,9 @@ typedef void (*interp_func)( GLcontext *ctx,
GLfloat t, GLuint dst, GLuint out, GLuint in,
GLboolean force_boundary );
typedef void (*copy_pv_func)( GLcontext *ctx, GLuint dst, GLuint src );
typedef void (*setup_func)( GLcontext *ctx,
GLuint start, GLuint end,
GLuint new_inputs);
struct tnl_device_driver {
@ -390,87 +393,86 @@ struct tnl_device_driver {
*/
/***
*** Rendering
*** Rendering -- These functions called only from t_vb_render.c
***/
struct {
void (*Start)(GLcontext *ctx);
void (*Finish)(GLcontext *ctx);
/* Called before and after all rendering operations, including DrawPixels,
* ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands.
* These are a suitable place for grabbing/releasing hardware locks.
*/
void (*RenderStart)(GLcontext *ctx);
void (*RenderFinish)(GLcontext *ctx);
/* Called before and after all rendering operations, including DrawPixels,
* ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands.
* These are a suitable place for grabbing/releasing hardware locks.
*/
void (*PrimitiveNotify)(GLcontext *ctx, GLenum mode);
/* Called between RenderStart() and RenderFinish() to indicate the
* type of primitive we're about to draw. Mode will be one of the
* modes accepted by glBegin().
*/
void (*RenderPrimitive)(GLcontext *ctx, GLenum mode);
/* Called between RednerStart() and RenderFinish() to indicate the
* type of primitive we're about to draw. Mode will be one of the
* modes accepted by glBegin().
*/
interp_func Interp;
/* The interp function is called by the clipping routines when we need
* to generate an interpolated vertex. All pertinant vertex ancilliary
* data should be computed by interpolating between the 'in' and 'out'
* vertices.
*/
interp_func RenderInterp;
/* The interp function is called by the clipping routines when we need
* to generate an interpolated vertex. All pertinant vertex ancilliary
* data should be computed by interpolating between the 'in' and 'out'
* vertices.
*/
copy_pv_func CopyPV;
/* The copy function is used to make a copy of a vertex. All pertinant
* vertex attributes should be copied.
*/
copy_pv_func RenderCopyPV;
/* The copy function is used to make a copy of a vertex. All pertinant
* vertex attributes should be copied.
*/
void (*ClippedPolygon)( GLcontext *ctx, const GLuint *elts, GLuint n );
/* Render a polygon with <n> vertices whose indexes are in the <elts>
* array.
*/
void (*RenderClippedPolygon)( GLcontext *ctx, const GLuint *elts, GLuint n );
/* Render a polygon with <n> vertices whose indexes are in the <elts>
* array.
*/
void (*ClippedLine)( GLcontext *ctx, GLuint v0, GLuint v1 );
/* Render a line between the two vertices given by indexes v0 and v1. */
void (*RenderClippedLine)( GLcontext *ctx, GLuint v0, GLuint v1 );
/* Render a line between the two vertices given by indexes v0 and v1. */
points_func Points; /* must now respect vb->elts */
line_func Line;
triangle_func Triangle;
quad_func Quad;
/* These functions are called in order to render points, lines,
* triangles and quads. These are only called via the T&L module.
*/
points_func PointsFunc; /* must now respect vb->elts */
line_func LineFunc;
triangle_func TriangleFunc;
quad_func QuadFunc;
/* These functions are called in order to render points, lines,
* triangles and quads. These are only called via the T&L module.
*/
render_func *PrimTabVerts;
render_func *PrimTabElts;
/* Render whole unclipped primitives (points, lines, linestrips,
* lineloops, etc). The tables are indexed by the GL enum of the
* primitive to be rendered. RenderTabVerts is used for non-indexed
* arrays of vertices. RenderTabElts is used for indexed arrays of
* vertices.
*/
render_func *RenderTabVerts;
render_func *RenderTabElts;
/* Render whole unclipped primitives (points, lines, linestrips,
* lineloops, etc). The tables are indexed by the GL enum of the
* primitive to be rendered. RenderTabVerts is used for non-indexed
* arrays of vertices. RenderTabElts is used for indexed arrays of
* vertices.
*/
void (*ResetLineStipple)( GLcontext *ctx );
/* Reset the hardware's line stipple counter.
*/
void (*ResetLineStipple)( GLcontext *ctx );
/* Reset the hardware's line stipple counter.
*/
setup_func BuildVertices;
/* This function is called whenever new vertices are required for
* rendering. The vertices in question are those n such that start
* <= n < end. The new_inputs parameter indicates those fields of
* the vertex which need to be updated, if only a partial repair of
* the vertex is required.
*
* This function is called only from _tnl_render_stage in tnl/t_render.c.
*/
void (*BuildProjectedVertices)( GLcontext *ctx,
GLuint start, GLuint end,
GLuint new_inputs);
/* This function is called whenever new vertices are required for
* rendering. The vertices in question are those n such that start
* <= n < end. The new_inputs parameter indicates those fields of
* the vertex which need to be updated, if only a partial repair of
* the vertex is required.
*
* This function is called only from _tnl_render_stage in tnl/t_render.c.
*/
GLboolean (*MultipassFunc)( GLcontext *ctx, GLuint passno );
/* Driver may request additional render passes by returning GL_TRUE
* when this function is called. This function will be called
* after the first pass, and passes will be made until the function
* returns GL_FALSE. If no function is registered, only one pass
* is made.
*
* This function will be first invoked with passno == 1.
*/
GLboolean (*Multipass)( GLcontext *ctx, GLuint passno );
/* Driver may request additional render passes by returning GL_TRUE
* when this function is called. This function will be called
* after the first pass, and passes will be made until the function
* returns GL_FALSE. If no function is registered, only one pass
* is made.
*
* This function will be first invoked with passno == 1.
*/
} Render;
};
typedef struct {

View file

@ -1,4 +1,4 @@
/* $Id: t_pipeline.h,v 1.7 2001/03/12 00:48:43 gareth Exp $ */
/* $Id: t_pipeline.h,v 1.8 2001/07/12 22:09:22 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -66,4 +66,10 @@ extern const struct gl_pipeline_stage *_tnl_default_pipeline[];
extern render_func _tnl_render_tab_elts[];
extern render_func _tnl_render_tab_verts[];
extern void _tnl_RenderClippedPolygon( GLcontext *ctx,
const GLuint *elts, GLuint n );
extern void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj );
#endif

View file

@ -1,4 +1,4 @@
/* $Id: t_vb_cliptmp.h,v 1.12 2001/05/09 12:25:40 keithw Exp $ */
/* $Id: t_vb_cliptmp.h,v 1.13 2001/07/12 22:09:22 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -124,7 +124,7 @@ static __inline void TAG(clip_line)( GLcontext *ctx,
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
interp_func interp = tnl->Driver.RenderInterp;
interp_func interp = tnl->Driver.Render.Interp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint ii = i, jj = j, p;
@ -152,9 +152,9 @@ static __inline void TAG(clip_line)( GLcontext *ctx,
}
if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj)
tnl->Driver.RenderCopyPV( ctx, jj, j );
tnl->Driver.Render.CopyPV( ctx, jj, j );
tnl->Driver.RenderClippedLine( ctx, ii, jj );
tnl->Driver.Render.ClippedLine( ctx, ii, jj );
}
@ -166,7 +166,7 @@ static __inline void TAG(clip_tri)( GLcontext *ctx,
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
interp_func interp = tnl->Driver.RenderInterp;
interp_func interp = tnl->Driver.Render.Interp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint pv = v2;
GLuint vlist[2][MAX_CLIPPED_VERTICES];
@ -203,11 +203,11 @@ static __inline void TAG(clip_tri)( GLcontext *ctx,
if (ctx->_TriangleCaps & DD_FLATSHADE) {
if (pv != inlist[0]) {
ASSERT( inlist[0] >= VB->FirstClipped );
tnl->Driver.RenderCopyPV( ctx, inlist[0], pv );
tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
}
}
tnl->Driver.RenderClippedPolygon( ctx, inlist, n );
tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
}
@ -219,7 +219,7 @@ static __inline void TAG(clip_quad)( GLcontext *ctx,
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
interp_func interp = tnl->Driver.RenderInterp;
interp_func interp = tnl->Driver.Render.Interp;
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint pv = v3;
GLuint vlist[2][MAX_CLIPPED_VERTICES];
@ -256,11 +256,11 @@ static __inline void TAG(clip_quad)( GLcontext *ctx,
if (ctx->_TriangleCaps & DD_FLATSHADE) {
if (pv != inlist[0]) {
ASSERT( inlist[0] >= VB->FirstClipped );
tnl->Driver.RenderCopyPV( ctx, inlist[0], pv );
tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
}
}
tnl->Driver.RenderClippedPolygon( ctx, inlist, n );
tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
}
#undef W

View file

@ -1,4 +1,4 @@
/* $Id: t_vb_render.c,v 1.21 2001/06/15 15:22:08 brianp Exp $ */
/* $Id: t_vb_render.c,v 1.22 2001/07/12 22:09:22 keithw Exp $ */
/*
* Mesa 3-D graphics library
@ -35,17 +35,8 @@
* This file makes calls to project vertices and to the point, line
* and triangle rasterizers via the function pointers:
*
* context->Driver.BuildProjectedVertices()
* context->Driver.Render.*
*
* context->Driver.PointsFunc()
* context->Driver.LineFunc()
* context->Driver.TriangleFunc()
* context->Driver.QuadFunc()
*
* context->Driver.RenderTabVerts[]
* context->Driver.RenderTabElts[]
*
* None of these may be null.
*/
@ -102,7 +93,7 @@
/* Vertices, with the possibility of clipping.
*/
#define RENDER_POINTS( start, count ) \
tnl->Driver.PointsFunc( ctx, start, count )
tnl->Driver.Render.Points( ctx, start, count )
#define RENDER_LINE( v1, v2 ) \
do { \
@ -142,16 +133,16 @@ do { \
const GLuint * const elt = VB->Elts; \
const GLubyte *mask = VB->ClipMask; \
const GLuint sz = VB->ClipPtr->size; \
const line_func LineFunc = tnl->Driver.LineFunc; \
const triangle_func TriangleFunc = tnl->Driver.TriangleFunc; \
const quad_func QuadFunc = tnl->Driver.QuadFunc; \
const line_func LineFunc = tnl->Driver.Render.Line; \
const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \
const 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 TAG(x) clip_##x##_verts
#define INIT(x) tnl->Driver.RenderPrimitive( ctx, x )
#define RESET_STIPPLE if (stipple) tnl->Driver.ResetLineStipple( ctx )
#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 "t_vb_rendertmp.h"
@ -174,7 +165,7 @@ static void clip_elt_triangles( GLcontext *ctx,
GLuint flags )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
render_func render_tris = tnl->Driver.RenderTabElts[GL_TRIANGLES];
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;
@ -182,7 +173,7 @@ static void clip_elt_triangles( GLcontext *ctx,
GLuint j;
(void) flags;
tnl->Driver.RenderPrimitive( ctx, GL_TRIANGLES );
tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES );
for (j=start; j < last; j+=3 ) {
GLubyte c1 = mask[elt[j]];
@ -214,7 +205,7 @@ static void clip_elt_triangles( GLcontext *ctx,
/* Vertices, no clipping.
*/
#define RENDER_POINTS( start, count ) \
tnl->Driver.PointsFunc( ctx, start, count )
tnl->Driver.Render.Points( ctx, start, count )
#define RENDER_LINE( v1, v2 ) \
LineFunc( ctx, v1, v2 )
@ -231,15 +222,15 @@ static void clip_elt_triangles( GLcontext *ctx,
TNLcontext *tnl = TNL_CONTEXT(ctx); \
struct vertex_buffer *VB = &tnl->vb; \
const GLuint * const elt = VB->Elts; \
const line_func LineFunc = tnl->Driver.LineFunc; \
const triangle_func TriangleFunc = tnl->Driver.TriangleFunc; \
const quad_func QuadFunc = tnl->Driver.QuadFunc; \
const line_func LineFunc = tnl->Driver.Render.Line; \
const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \
const quad_func QuadFunc = tnl->Driver.Render.Quad; \
(void) (LineFunc && TriangleFunc && QuadFunc); \
(void) elt;
#define RESET_STIPPLE tnl->Driver.ResetLineStipple( ctx )
#define RESET_STIPPLE tnl->Driver.Render.ResetLineStipple( ctx )
#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
#define INIT(x) tnl->Driver.RenderPrimitive( ctx, x )
#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x )
#define RENDER_TAB_QUALIFIER
#define PRESERVE_VB_DEFS
#include "t_vb_rendertmp.h"
@ -253,6 +244,27 @@ static void clip_elt_triangles( GLcontext *ctx,
#include "t_vb_rendertmp.h"
/**********************************************************************/
/* 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 );
}
/**********************************************************************/
@ -274,31 +286,33 @@ static GLboolean run_render( GLcontext *ctx,
* that window coordinates are guarenteed not to change before
* rendering.
*/
ASSERT(tnl->Driver.RenderStart);
ASSERT(tnl->Driver.Render.Start);
tnl->Driver.RenderStart( ctx );
tnl->Driver.Render.Start( ctx );
ASSERT(tnl->Driver.BuildProjectedVertices);
ASSERT(tnl->Driver.RenderPrimitive);
ASSERT(tnl->Driver.PointsFunc);
ASSERT(tnl->Driver.LineFunc);
ASSERT(tnl->Driver.TriangleFunc);
ASSERT(tnl->Driver.QuadFunc);
ASSERT(tnl->Driver.ResetLineStipple);
ASSERT(tnl->Driver.RenderInterp);
ASSERT(tnl->Driver.RenderCopyPV);
ASSERT(tnl->Driver.RenderClippedLine);
ASSERT(tnl->Driver.RenderClippedPolygon);
ASSERT(tnl->Driver.RenderFinish);
ASSERT(tnl->Driver.Render.BuildVertices);
ASSERT(tnl->Driver.Render.PrimitiveNotify);
ASSERT(tnl->Driver.Render.Points);
ASSERT(tnl->Driver.Render.Line);
ASSERT(tnl->Driver.Render.Triangle);
ASSERT(tnl->Driver.Render.Quad);
ASSERT(tnl->Driver.Render.ResetLineStipple);
ASSERT(tnl->Driver.Render.Interp);
ASSERT(tnl->Driver.Render.CopyPV);
ASSERT(tnl->Driver.Render.ClippedLine);
ASSERT(tnl->Driver.Render.ClippedPolygon);
ASSERT(tnl->Driver.Render.Finish);
tnl->Driver.BuildProjectedVertices( ctx, 0, VB->Count, new_inputs );
tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, new_inputs );
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.RenderTabElts : tnl->Driver.RenderTabVerts;
tab = (VB->Elts ?
tnl->Driver.Render.PrimTabElts :
tnl->Driver.Render.PrimTabVerts);
}
do
@ -313,11 +327,11 @@ static GLboolean run_render( GLcontext *ctx,
if (length)
tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags );
}
} while (tnl->Driver.MultipassFunc &&
tnl->Driver.MultipassFunc( ctx, ++pass ));
} while (tnl->Driver.Render.Multipass &&
tnl->Driver.Render.Multipass( ctx, ++pass ));
tnl->Driver.RenderFinish( ctx );
tnl->Driver.Render.Finish( ctx );
/* _swrast_flush(ctx); */
/* usleep(1000000); */
return GL_FALSE; /* finished the pipe */