/* * * GLX Hardware Device Driver for Sun Creator/Creator3D * Copyright (C) 2000, 2001 David S. Miller * * 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 * DAVID MILLER, 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. * * * David S. Miller */ #include "ffb_xmesa.h" #include "ffb_context.h" #include "ffb_vb.h" #include "imports.h" #include "tnl/t_context.h" #include "swrast_setup/swrast_setup.h" #include "math/m_translate.h" #undef VB_DEBUG static void ffb_copy_pv_oneside(GLcontext *ctx, GLuint edst, GLuint esrc) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); ffb_vertex *dst = &fmesa->verts[edst]; ffb_vertex *src = &fmesa->verts[esrc]; #ifdef VB_DEBUG fprintf(stderr, "ffb_copy_pv_oneside: edst(%d) esrc(%d)\n", edst, esrc); #endif dst->color[0].alpha = src->color[0].alpha; dst->color[0].red = src->color[0].red; dst->color[0].green = src->color[0].green; dst->color[0].blue = src->color[0].blue; } static void ffb_copy_pv_twoside(GLcontext *ctx, GLuint edst, GLuint esrc) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); ffb_vertex *dst = &fmesa->verts[edst]; ffb_vertex *src = &fmesa->verts[esrc]; #ifdef VB_DEBUG fprintf(stderr, "ffb_copy_pv_twoside: edst(%d) esrc(%d)\n", edst, esrc); #endif dst->color[0].alpha = src->color[0].alpha; dst->color[0].red = src->color[0].red; dst->color[0].green = src->color[0].green; dst->color[0].blue = src->color[0].blue; dst->color[1].alpha = src->color[1].alpha; dst->color[1].red = src->color[1].red; dst->color[1].green = src->color[1].green; dst->color[1].blue = src->color[1].blue; } #define FFB_VB_RGBA_BIT 0x01 #define FFB_VB_XYZ_BIT 0x02 #define FFB_VB_TWOSIDE_BIT 0x04 #define FFB_VB_MAX 0x08 typedef void (*ffb_emit_func)(GLcontext *, GLuint, GLuint); static struct { ffb_emit_func emit; tnl_interp_func interp; } setup_tab[FFB_VB_MAX]; #define IND (FFB_VB_XYZ_BIT) #define TAG(x) x##_w #include "ffb_vbtmp.h" #define IND (FFB_VB_RGBA_BIT) #define TAG(x) x##_g #include "ffb_vbtmp.h" #define IND (FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT) #define TAG(x) x##_wg #include "ffb_vbtmp.h" #define IND (FFB_VB_TWOSIDE_BIT) #define TAG(x) x##_t #include "ffb_vbtmp.h" #define IND (FFB_VB_XYZ_BIT | FFB_VB_TWOSIDE_BIT) #define TAG(x) x##_wt #include "ffb_vbtmp.h" #define IND (FFB_VB_RGBA_BIT | FFB_VB_TWOSIDE_BIT) #define TAG(x) x##_gt #include "ffb_vbtmp.h" #define IND (FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT | FFB_VB_TWOSIDE_BIT) #define TAG(x) x##_wgt #include "ffb_vbtmp.h" static void init_setup_tab( void ) { init_w(); init_g(); init_wg(); init_t(); init_wt(); init_gt(); init_wgt(); } #ifdef VB_DEBUG static void ffbPrintSetupFlags(char *msg, GLuint flags) { fprintf(stderr, "%s(%x): %s%s%s\n", msg, (int)flags, (flags & FFB_VB_XYZ_BIT) ? " xyz," : "", (flags & FFB_VB_RGBA_BIT) ? " rgba," : "", (flags & FFB_VB_TWOSIDE_BIT) ? " twoside," : ""); } #endif static void ffbDDBuildVertices(GLcontext *ctx, GLuint start, GLuint count, GLuint newinputs) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); newinputs |= fmesa->setupnewinputs; fmesa->setupnewinputs = 0; if (!newinputs) return; if (newinputs & VERT_BIT_POS) { setup_tab[fmesa->setupindex].emit(ctx, start, count); } else { GLuint ind = 0; if (newinputs & VERT_BIT_COLOR0) ind |= (FFB_VB_RGBA_BIT | FFB_VB_TWOSIDE_BIT); ind &= fmesa->setupindex; if (ind) setup_tab[ind].emit(ctx, start, count); } } void ffbChooseVertexState( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); ffbContextPtr fmesa = FFB_CONTEXT(ctx); int ind = FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT; if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ind |= FFB_VB_TWOSIDE_BIT; #ifdef VB_DEBUG ffbPrintSetupFlags("ffb: full setup function", ind); #endif fmesa->setupindex = ind; tnl->Driver.Render.BuildVertices = ffbDDBuildVertices; tnl->Driver.Render.Interp = setup_tab[ind].interp; if (ind & FFB_VB_TWOSIDE_BIT) tnl->Driver.Render.CopyPV = ffb_copy_pv_twoside; else tnl->Driver.Render.CopyPV = ffb_copy_pv_oneside; } void ffbInitVB( GLcontext *ctx ) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLuint size = TNL_CONTEXT(ctx)->vb.Size; fmesa->verts = (ffb_vertex *)ALIGN_MALLOC(size * sizeof(ffb_vertex), 32); { static int firsttime = 1; if (firsttime) { init_setup_tab(); firsttime = 0; } } } void ffbFreeVB( GLcontext *ctx ) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); if (fmesa->verts) { ALIGN_FREE(fmesa->verts); fmesa->verts = 0; } }