diff options
Diffstat (limited to 'src/mesa/tnl/t_vertex.c')
-rw-r--r-- | src/mesa/tnl/t_vertex.c | 605 |
1 files changed, 411 insertions, 194 deletions
diff --git a/src/mesa/tnl/t_vertex.c b/src/mesa/tnl/t_vertex.c index 61ac08efc4d..6ac9f8a90c5 100644 --- a/src/mesa/tnl/t_vertex.c +++ b/src/mesa/tnl/t_vertex.c @@ -25,24 +25,26 @@ * Keith Whitwell <[email protected]> */ +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "t_context.h" +#include "t_vertex.h" +/* Build and manage clipspace/ndc/window vertices. + * + * Another new mechanism designed and crying out for codegen. Before + * that, it would be very interesting to investigate the merger of + * these vertices and those built in t_vtx_*. + */ -struct attr { - int attrib; - int vertoffset; - int vertattrsize; - int *inputptr; - int inputstride; - void (*insert)( const struct attr *a, char *v, const GLfloat *input ); - void (*extract)( const struct attr *a, GLfloat *output, const char *v ); - const GLfloat *vp; -}; +#define GET_VERTEX_STATE(ctx) &(TNL_CONTEXT(ctx)->clipspace) -static void insert_4f_viewport( const struct attr *a, char *v, +static void insert_4f_viewport( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { GLfloat *out = (GLfloat *)v; @@ -54,7 +56,7 @@ static void insert_4f_viewport( const struct attr *a, char *v, out[3] = in[3]; } -static void insert_3f_viewport( const struct attr *a, char *v, +static void insert_3f_viewport( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { GLfloat *out = (GLfloat *)v; @@ -65,7 +67,7 @@ static void insert_3f_viewport( const struct attr *a, char *v, out[2] = vp[10] * in[2] + vp[14]; } -static void insert_2f_viewport( const struct attr *a, char *v, +static void insert_2f_viewport( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { GLfloat *out = (GLfloat *)v; @@ -76,7 +78,7 @@ static void insert_2f_viewport( const struct attr *a, char *v, } -static void insert_4f( const struct attr *a, char *v, const GLfloat *in ) +static void insert_4f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { GLfloat *out = (GLfloat *)(v); @@ -86,7 +88,7 @@ static void insert_4f( const struct attr *a, char *v, const GLfloat *in ) out[3] = in[3]; } -static void insert_3f_xyw( const struct attr *a, char *v, const GLfloat *in ) +static void insert_3f_xyw( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { GLfloat *out = (GLfloat *)(v); @@ -96,7 +98,7 @@ static void insert_3f_xyw( const struct attr *a, char *v, const GLfloat *in ) } -static void insert_3f( const struct attr *a, char *v, const GLfloat *in ) +static void insert_3f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { GLfloat *out = (GLfloat *)(v); @@ -106,22 +108,63 @@ static void insert_3f( const struct attr *a, char *v, const GLfloat *in ) } -static void insert_2f( const struct attr *a, char *v, const GLfloat *in ) +static void insert_2f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) +{ + GLfloat *out = (GLfloat *)(v); + + out[0] = in[0]; + out[1] = in[1]; +} + +static void insert_1f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) +{ + GLfloat *out = (GLfloat *)(v); + + out[0] = in[0]; +} + +static void insert_3f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { GLfloat *out = (GLfloat *)(v); out[0] = in[0]; out[1] = in[1]; + out[2] = in[2]; + out[3] = 1; } -static void insert_1f( const struct attr *a, char *v, const GLfloat *in ) + +static void insert_2f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { GLfloat *out = (GLfloat *)(v); out[0] = in[0]; + out[1] = in[1]; + out[2] = 0; + out[3] = 1; } -static void insert_4ub_4f_rgba( const struct attr *a, char *v, +static void insert_1f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) +{ + GLfloat *out = (GLfloat *)(v); + + out[0] = in[0]; + out[1] = 0; + out[2] = 0; + out[3] = 1; +} + +static void insert_4chan_4f_rgba( const struct tnl_clipspace_attr *a, char *v, + const GLfloat *in ) +{ + GLchan *c = (GLchan *)v; + UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); + UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); + UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); + UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]); +} + +static void insert_4ub_4f_rgba( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); @@ -130,7 +173,7 @@ static void insert_4ub_4f_rgba( const struct attr *a, char *v, UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); } -static void insert_4ub_4f_bgra( const struct attr *a, char *v, +static void insert_4ub_4f_bgra( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); @@ -139,7 +182,7 @@ static void insert_4ub_4f_bgra( const struct attr *a, char *v, UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); } -static void insert_3ub_3f_rgb( const struct attr *a, char *v, +static void insert_3ub_3f_rgb( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); @@ -147,7 +190,7 @@ static void insert_3ub_3f_rgb( const struct attr *a, char *v, UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); } -static void insert_3ub_3f_bgr( const struct attr *a, char *v, +static void insert_3ub_3f_bgr( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); @@ -155,7 +198,7 @@ static void insert_3ub_3f_bgr( const struct attr *a, char *v, UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); } -static void insert_1ub_1f( const struct attr *a, char *v, +static void insert_1ub_1f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ) { UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); @@ -169,7 +212,7 @@ static void insert_1ub_1f( const struct attr *a, char *v, * Currently always extracts a full 4 floats. */ -static void extract_4f_viewport( const struct attr *a, GLfloat *out, +static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { const GLfloat *in = (const GLfloat *)v; @@ -181,7 +224,7 @@ static void extract_4f_viewport( const struct attr *a, GLfloat *out, out[3] = in[3]; } -static void extract_3f_viewport( const struct attr *a, GLfloat *out, +static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { const GLfloat *in = (const GLfloat *)v; @@ -194,7 +237,7 @@ static void extract_3f_viewport( const struct attr *a, GLfloat *out, } -static void extract_2f_viewport( const struct attr *a, GLfloat *out, +static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { const GLfloat *in = (const GLfloat *)v; @@ -207,7 +250,7 @@ static void extract_2f_viewport( const struct attr *a, GLfloat *out, } -static void extract_4f( const struct attr *a, GLfloat *out, const char *v ) +static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { const GLfloat *in = (const GLfloat *)v; @@ -217,7 +260,7 @@ static void extract_4f( const struct attr *a, GLfloat *out, const char *v ) out[3] = in[3]; } -static void extract_3f_xyw( const struct attr *a, GLfloat *out, const char *v ) +static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { const GLfloat *in = (const GLfloat *)v; @@ -228,7 +271,7 @@ static void extract_3f_xyw( const struct attr *a, GLfloat *out, const char *v ) } -static void extract_3f( const struct attr *a, GLfloat *out, const char *v ) +static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { const GLfloat *in = (const GLfloat *)v; @@ -239,7 +282,7 @@ static void extract_3f( const struct attr *a, GLfloat *out, const char *v ) } -static void extract_2f( const struct attr *a, GLfloat *out, const char *v ) +static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { const GLfloat *in = (const GLfloat *)v; @@ -249,7 +292,7 @@ static void extract_2f( const struct attr *a, GLfloat *out, const char *v ) out[3] = 1; } -static void extract_1f( const struct attr *a, GLfloat *out, const char *v ) +static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { const GLfloat *in = (const GLfloat *)v; @@ -259,50 +302,146 @@ static void extract_1f( const struct attr *a, GLfloat *out, const char *v ) out[3] = 1; } -static void extract_4ub_4f_rgba( const struct attr *a, GLfloat *out, +static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); + GLchan *c = (GLchan *)v; + + out[0] = CHAN_TO_FLOAT(c[0]); + out[1] = CHAN_TO_FLOAT(c[1]); + out[2] = CHAN_TO_FLOAT(c[2]); + out[3] = CHAN_TO_FLOAT(c[3]); } -static void extract_4ub_4f_bgra( const struct attr *a, GLfloat *out, +static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); + out[0] = UBYTE_TO_FLOAT(v[0]); + out[1] = UBYTE_TO_FLOAT(v[1]); + out[2] = UBYTE_TO_FLOAT(v[2]); + out[3] = UBYTE_TO_FLOAT(v[3]); +} + +static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out, + const char *v ) +{ + out[2] = UBYTE_TO_FLOAT(v[0]); + out[1] = UBYTE_TO_FLOAT(v[1]); + out[0] = UBYTE_TO_FLOAT(v[2]); + out[3] = UBYTE_TO_FLOAT(v[3]); } -static void extract_3ub_3f_rgb( const struct attr *a, GLfloat *out, +static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); + out[0] = UBYTE_TO_FLOAT(v[0]); + out[1] = UBYTE_TO_FLOAT(v[1]); + out[2] = UBYTE_TO_FLOAT(v[2]); out[3] = 1; } -static void extract_3ub_3f_bgr( const struct attr *a, GLfloat *out, +static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); + out[2] = UBYTE_TO_FLOAT(v[0]); + out[1] = UBYTE_TO_FLOAT(v[1]); + out[0] = UBYTE_TO_FLOAT(v[2]); out[3] = 1; } -static void extract_1ub_1f( const struct attr *a, GLfloat *out, const char *v ) +static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v ) { - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + out[0] = UBYTE_TO_FLOAT(v[0]); out[1] = 0; out[2] = 0; out[3] = 1; } + +typedef void (*extract_func)( const struct tnl_clipspace_attr *a, GLfloat *out, + const char *v ); + +typedef void (*insert_func)( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in ); + + +struct { + extract_func extract; + insert_func insert; + GLuint attrsize; +} format_info[EMIT_MAX] = { + + { extract_1f, + insert_1f, + sizeof(GLfloat) }, + + { extract_2f, + insert_2f, + 2 * sizeof(GLfloat) }, + + { extract_3f, + insert_3f, + 3 * sizeof(GLfloat) }, + + { extract_4f, + insert_4f, + 4 * sizeof(GLfloat) }, + + { extract_2f_viewport, + insert_2f_viewport, + 2 * sizeof(GLfloat) }, + + { extract_3f_viewport, + insert_3f_viewport, + 3 * sizeof(GLfloat) }, + + { extract_4f_viewport, + insert_4f_viewport, + 4 * sizeof(GLfloat) }, + + { extract_3f_xyw, + insert_3f_xyw, + 3 * sizeof(GLfloat) }, + + { extract_1ub_1f, + insert_1ub_1f, + sizeof(GLubyte) }, + + { extract_3ub_3f_rgb, + insert_3ub_3f_rgb, + 3 * sizeof(GLubyte) }, + + { extract_3ub_3f_bgr, + insert_3ub_3f_bgr, + 3 * sizeof(GLubyte) }, + + { extract_4ub_4f_rgba, + insert_4ub_4f_rgba, + 4 * sizeof(GLubyte) }, + + { extract_4ub_4f_bgra, + insert_4ub_4f_bgra, + 4 * sizeof(GLubyte) }, + + { extract_4chan_4f_rgba, + insert_4chan_4f_rgba, + 4 * sizeof(GLchan) }, + + { extract_1f, + insert_1f_pad, + 4 * sizeof(GLfloat) }, + + { extract_2f, + insert_2f_pad, + 4 * sizeof(GLfloat) }, + + { extract_3f, + insert_3f_pad, + 4 * sizeof(GLfloat) }, + + +}; + + /*********************************************************************** * Generic (non-codegen) functions for whole vertices or groups of * vertices @@ -310,27 +449,30 @@ static void extract_1ub_1f( const struct attr *a, GLfloat *out, const char *v ) static void generic_emit( GLcontext *ctx, GLuint start, GLuint end, - void *dest, - GLuint stride ) + void *dest ) { - int i, j; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + struct tnl_clipspace_attr *a = vtx->attr; char *v = (char *)dest; + int i, j; + GLuint count = vtx->attr_count; + GLuint stride; - vtx->vertex_buf = v - start * stride; - vtx->vertex_stride = stride; + for (j = 0; j < count; j++) { + GLvector4f *vptr = VB->AttribPtr[a[j].attrib]; + a[j].inputstride = vptr->stride; + a[j].inputptr = (GLfloat *)STRIDE_4F(vptr->data, start * vptr->stride); + } end -= start; - - for (j = 0; j < vtx->attr_count; j++) { - GLvector4f *vptr = VB->AttrPtr[a[j].attrib]; - a[j].inputptr = STRIDE_4F(vptr->data, start * vptr->stride); - } + stride = vtx->vertex_size; for (i = 0 ; i < end ; i++, v += stride) { - for (j = 0; j < vtx->attr_count; j++) { - int *in = a[j].inputptr; + for (j = 0; j < count; j++) { + GLfloat *in = a[j].inputptr; (char *)a[j].inputptr += a[j].inputstride; - a[j].out( &a[j], v + a[j].vertoffset, in ); + a[j].insert( &a[j], v + a[j].vertoffset, in ); } } } @@ -341,26 +483,45 @@ static void generic_interp( GLcontext *ctx, GLuint edst, GLuint eout, GLuint ein, GLboolean force_boundary ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - char *vin = vtx->vertex_buf + ein * vtx->vertex_stride; - char *vout = vtx->vertex_buf + eout * vtx->vertex_stride; - char *vdst = vtx->vertex_buf + edst * vtx->vertex_stride; - const struct attr *a = vtx->attr; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + char *vin = vtx->vertex_buf + ein * vtx->vertex_size; + char *vout = vtx->vertex_buf + eout * vtx->vertex_size; + char *vdst = vtx->vertex_buf + edst * vtx->vertex_size; + const struct tnl_clipspace_attr *a = vtx->attr; int attr_count = vtx->attr_count; int j; - - for (j = 0; j < attr_count; j++) { + + if (tnl->NeedNdcCoords) { + const GLfloat *dstclip = VB->ClipPtr->data[edst]; + const GLfloat w = 1.0 / dstclip[3]; + GLfloat pos[4]; + + pos[0] = dstclip[0] * w; + pos[1] = dstclip[1] * w; + pos[2] = dstclip[2] * w; + pos[3] = w; + + a[0].insert( &a[0], vdst, pos ); + } + else { + a[0].insert( &a[0], vdst, VB->ClipPtr->data[edst] ); + } + + + for (j = 1; j < attr_count; j++) { GLfloat fin[4], fout[4], fdst[4]; - - a[j].extract( &a[j], vin, fin ); - a[j].extract( &a[j], vout, fout ); + + a[j].extract( &a[j], fin, vin + a[j].vertoffset ); + a[j].extract( &a[j], fout, vout + a[j].vertoffset ); INTERP_F( t, fdst[3], fout[3], fin[3] ); INTERP_F( t, fdst[2], fout[2], fin[2] ); INTERP_F( t, fdst[1], fout[1], fin[1] ); INTERP_F( t, fdst[0], fout[0], fin[0] ); - a[j].insert( &a[j], vdst, fdst ); + a[j].insert( &a[j], vdst + a[j].vertoffset, fdst ); } } @@ -368,45 +529,77 @@ static void generic_interp( GLcontext *ctx, /* Extract color attributes from one vertex and insert them into * another. (Shortcircuit extract/insert with memcpy). */ -static void generic_copy_colors( GLcontext *ctx, GLuint edst, GLuint esrc ) +static void generic_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - char *vsrc = vert_start + esrc * vert_stride; - char *vdst = vert_start + edst * vert_stride; - const struct attr *a = vtx->attr; + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + char *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size; + char *vdst = vtx->vertex_buf + edst * vtx->vertex_size; + const struct tnl_clipspace_attr *a = vtx->attr; int attr_count = vtx->attr_count; int j; for (j = 0; j < attr_count; j++) { - if (a[j].attribute == VERT_ATTRIB_COLOR0 || - a[j].attribute == VERT_ATTRIB_COLOR1) { + if (a[j].attrib == VERT_ATTRIB_COLOR0 || + a[j].attrib == VERT_ATTRIB_COLOR1) { memcpy( vdst + a[j].vertoffset, vsrc + a[j].vertoffset, a[j].vertattrsize ); + } } } -static void generic_get_attr( GLcontext *ctx, const char *vertex, - GLenum attr, GLfloat *dest ) + +/* Helper functions for hardware which doesn't put back colors and/or + * edgeflags into vertices. + */ +static void generic_interp_extras( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - const struct attr *a = vtx->attr; - int attr_count = vtx->attr_count; - int j; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - for (j = 0; j < attr_count; j++) { - if (a[j].attribute == attr) { - a[j].extract( &a[j], vin, dest ); - return; + if (VB->ColorPtr[1]) { + assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat)); + + INTERP_4F( t, + VB->ColorPtr[1]->data[dst], + VB->ColorPtr[1]->data[out], + VB->ColorPtr[1]->data[in] ); + + if (VB->SecondaryColorPtr[1]) { + INTERP_3F( t, + VB->SecondaryColorPtr[1]->data[dst], + VB->SecondaryColorPtr[1]->data[out], + VB->SecondaryColorPtr[1]->data[in] ); } } - /* Else return the value from ctx->Current - */ - memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); + if (VB->EdgeFlag) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; + } + + generic_interp(ctx, t, dst, out, in, force_boundary); } +static void generic_copy_pv_extras( GLcontext *ctx, + GLuint dst, GLuint src ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + COPY_4FV( VB->ColorPtr[1]->data[dst], + VB->ColorPtr[1]->data[src] ); + + if (VB->SecondaryColorPtr[1]) { + COPY_4FV( VB->SecondaryColorPtr[1]->data[dst], + VB->SecondaryColorPtr[1]->data[src] ); + } + } + + _tnl_copy_pv(ctx, dst, src); +} @@ -420,12 +613,11 @@ static void generic_get_attr( GLcontext *ctx, const char *vertex, static void choose_emit_func( GLcontext *ctx, GLuint start, GLuint end, - void *dest, - GLuint stride ) + void *dest ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - vtx->emit_func = generic_emit_func; - vtx->emit_func( ctx, start, end, dest, stride ); + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + vtx->emit = generic_emit; + vtx->emit( ctx, start, end, dest ); } @@ -434,17 +626,31 @@ static void choose_interp_func( GLcontext *ctx, GLuint edst, GLuint eout, GLuint ein, GLboolean force_boundary ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - vtx->interp_func = generic_interp_func; - vtx->interp_func( ctx, t, edst, eout, ein, force_boundary ); + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + + if (vtx->need_extras && + (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + vtx->interp = generic_interp_extras; + } else { + vtx->interp = generic_interp; + } + + vtx->interp( ctx, t, edst, eout, ein, force_boundary ); } -static void choose_copy_color_func( GLcontext *ctx, GLuint edst, GLuint esrc ) +static void choose_copy_pv_func( GLcontext *ctx, GLuint edst, GLuint esrc ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - vtx->copy_color_func = generic_copy_color_func; - vtx->copy_color_func( ctx, edst, esrc ); + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + + if (vtx->need_extras && + (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + vtx->copy_pv = generic_copy_pv_extras; + } else { + vtx->copy_pv = generic_copy_pv; + } + + vtx->copy_pv( ctx, edst, esrc ); } @@ -452,14 +658,6 @@ static void choose_copy_color_func( GLcontext *ctx, GLuint edst, GLuint esrc ) * Public entrypoints, mostly dispatch to the above: */ -void _tnl_emit( GLcontext *ctx, - GLuint start, GLuint end, - void *dest, - GLuint stride ) -{ - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - vtx->emit_func( ctx, start, end, dest, stride ); -} /* Interpolate between two vertices to produce a third: */ @@ -468,16 +666,16 @@ void _tnl_interp( GLcontext *ctx, GLuint edst, GLuint eout, GLuint ein, GLboolean force_boundary ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - vtx->interp_func( ctx, t, edst, eout, ein, force_boundary ); + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + vtx->interp( ctx, t, edst, eout, ein, force_boundary ); } /* Copy colors from one vertex to another: */ -void _tnl_copy_colors( GLcontext *ctx, GLuint edst, GLuint esrc ) +void _tnl_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - vtx->copy_color_func( ctx, edst, esrc ); + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + vtx->copy_pv( ctx, edst, esrc ); } @@ -485,117 +683,136 @@ void _tnl_copy_colors( GLcontext *ctx, GLuint edst, GLuint esrc ) * reverse any viewport transformation, swizzling or other conversions * which may have been applied: */ -void _tnl_get_attr( GLcontext *ctx, void *vertex, GLenum attrib, - GLfloat *dest ) +void _tnl_get_attr( GLcontext *ctx, const void *vin, + GLenum attr, GLfloat *dest ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); - vtx->get_attr_func( ctx, vertex, attrib, dest ); + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + const struct tnl_clipspace_attr *a = vtx->attr; + int attr_count = vtx->attr_count; + int j; + + for (j = 0; j < attr_count; j++) { + if (a[j].attrib == attr) { + a[j].extract( &a[j], dest, vin ); + return; + } + } + + /* Else return the value from ctx->Current + */ + memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); } +void *_tnl_get_vertex( GLcontext *ctx, GLuint nr ) +{ + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + return vtx->vertex_buf + nr * vtx->vertex_size; +} -void _tnl_install_attrs( GLcontext *ctx, const struct dri_attr_map *map, +void _tnl_invalidate_vertex_state( GLcontext *ctx, GLuint new_state ) +{ + if (new_state & (_DD_NEW_TRI_LIGHT_TWOSIDE|_DD_NEW_TRI_UNFILLED) ) { + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + vtx->new_inputs = ~0; + vtx->interp = choose_interp_func; + vtx->copy_pv = choose_copy_pv_func; + } +} + + +GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map, GLuint nr, const GLfloat *vp ) { - struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx); + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + int offset = 0; int i; - assert(nr < _TNL_ATTR_MAX); + assert(nr < _TNL_ATTRIB_MAX); + assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS); vtx->attr_count = nr; - vtx->emit_func = choose_emit_func; - vtx->interp_func = choose_interp_func; - vtx->copy_color_func = choose_copy_color_func; - vtx->get_attr_func = choose_get_attr_func; + vtx->emit = choose_emit_func; + vtx->interp = choose_interp_func; + vtx->copy_pv = choose_copy_pv_func; + vtx->new_inputs = ~0; for (i = 0; i < nr; i++) { - GLuint attrib = map[i].attrib; + GLuint format = map[i].format; vtx->attr[i].attrib = map[i].attrib; - vtx->attr[i].hw_format = map[i].hw_format; +/* vtx->attr[i].format = map[i].format; */ vtx->attr[i].vp = vp; - vtx->attr[i].insert = attrib_info[attrib].insert; - vtx->attr[i].extract = attrib_info[attrib].extract; - vtx->attr[i].vertattrsize = attrib_info[attrib].attrsize; + vtx->attr[i].insert = format_info[format].insert; + vtx->attr[i].extract = format_info[format].extract; + vtx->attr[i].vertattrsize = format_info[format].attrsize; vtx->attr[i].vertoffset = offset; - offset += attrib_info[attrib].attrsize; + offset += format_info[format].attrsize; } -} + assert(offset <= vtx->max_vertex_size); + + vtx->vertex_size = offset; + return vtx->vertex_size; +} -/* Populate a swrast SWvertex from an attrib-style vertex. - */ -void _tnl_translate( GLcontext *ctx, const void *vertex, SWvertex *dest ) + +void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs ) { - _tnl_get_attr( ctx, vertex, VERT_ATTRIB_POS, dest.win ); + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + vtx->new_inputs |= newinputs; +} - for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) - _tnl_get_attr( ctx, vertex, VERT_ATTRIB_TEX(i), dest.texcoord[i] ); - - _tnl_get_attr( ctx, vertex, VERT_ATTRIB_COLOR0, tmp ); - UNCLAMPED_FLOAT_TO_CHAN_RGBA( dest.color, tmp ); - _tnl_get_attr( ctx, vertex, VERT_ATTRIB_COLOR1, tmp ); - UNCLAMPED_FLOAT_TO_CHAN_RGB( dest.specular, tmp ); - _tnl_get_attr( ctx, vertex, VERT_ATTRIB_FOG, tmp ); - dest.fog = tmp[0]; +void _tnl_build_vertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ) +{ + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + GLuint stride = vtx->vertex_size; + GLubyte *v = ((GLubyte *)vtx->vertex_buf + (start*stride)); - _tnl_get_attr( ctx, vertex, VERT_ATTRIB_INDEX, tmp ); - dest.index = (GLuint) tmp[0]; + newinputs |= vtx->new_inputs; + vtx->new_inputs = 0; - _tnl_get_attr( ctx, vertex, VERT_ATTRIB_POINTSIZE, tmp ); - dest.pointSize = tmp[0]; + if (newinputs) + vtx->emit( ctx, start, count, v ); } -static void interp_extras( GLcontext *ctx, - GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ) +void *_tnl_emit_vertices_to_buffer( GLcontext *ctx, + GLuint start, + GLuint count, + void *dest ) { - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + vtx->emit( ctx, start, count, dest ); + return (void *)((char *)dest + vtx->vertex_size * (count - start)); +} - if (VB->ColorPtr[1]) { - assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat)); - INTERP_4F( t, - GET_COLOR(VB->ColorPtr[1], dst), - GET_COLOR(VB->ColorPtr[1], out), - GET_COLOR(VB->ColorPtr[1], in) ); +void _tnl_init_vertices( GLcontext *ctx, + GLuint vb_size, + GLuint max_vertex_size ) +{ + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - 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) ); - } - } + _tnl_install_attrs( ctx, 0, 0, 0 ); - if (VB->EdgeFlag) { - VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; - } - - generic_interp(ctx, t, dst, out, in, force_boundary); + vtx->need_extras = GL_TRUE; + vtx->max_vertex_size = max_vertex_size; + vtx->vertex_buf = (char *)ALIGN_MALLOC(vb_size * 4 * 18, max_vertex_size); } -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) ); - } +void _tnl_free_vertices( GLcontext *ctx ) +{ + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + if (vtx->vertex_buf) { + ALIGN_FREE(vtx->vertex_buf); + vtx->vertex_buf = 0; } - - generic_copy_colors(ctx, dst, src); } - -#endif |