X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Ftnl%2Ft_vertex.c;h=c3294b007b09522893b2fc1cc945dabb741d085a;hb=6bb4255f8ebb8cc048afe498e11738985d134f8a;hp=f4847f757814c1810b0c2c6cea7751789a78adb2;hpb=9557401a98b9585289fe8f65be33b6c5fda79095;p=mesa.git diff --git a/src/mesa/tnl/t_vertex.c b/src/mesa/tnl/t_vertex.c index f4847f75781..c3294b007b0 100644 --- a/src/mesa/tnl/t_vertex.c +++ b/src/mesa/tnl/t_vertex.c @@ -1,5 +1,5 @@ /* - * Copyright 2003 Tungsten Graphics, inc. + * Copyright 2003 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -16,19 +16,19 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell + * Keith Whitwell */ -#include "glheader.h" -#include "context.h" -#include "colormac.h" - +#include +#include "main/glheader.h" +#include "main/context.h" +#include "swrast/s_chan.h" #include "t_context.h" #include "t_vertex.h" @@ -46,7 +46,9 @@ static GLboolean match_fastpath( struct tnl_clipspace *vtx, return GL_FALSE; for (j = 0; j < vtx->attr_count; j++) - if (vtx->attr[j].format != fp->attr[j].format) + if (vtx->attr[j].format != fp->attr[j].format || + vtx->attr[j].inputsize != fp->attr[j].size || + vtx->attr[j].vertoffset != fp->attr[j].offset) return GL_FALSE; if (fp->match_strides) { @@ -81,15 +83,28 @@ void _tnl_register_fastpath( struct tnl_clipspace *vtx, struct tnl_clipspace_fastpath *fastpath = CALLOC_STRUCT(tnl_clipspace_fastpath); GLuint i; + if (fastpath == NULL) { + _mesa_error_no_memory(__func__); + return; + } + fastpath->vertex_size = vtx->vertex_size; fastpath->attr_count = vtx->attr_count; fastpath->match_strides = match_strides; fastpath->func = vtx->emit; - fastpath->attr = MALLOC(vtx->attr_count * sizeof(fastpath->attr[0])); + fastpath->attr = malloc(vtx->attr_count * sizeof(fastpath->attr[0])); + + if (fastpath->attr == NULL) { + free(fastpath); + _mesa_error_no_memory(__func__); + return; + } for (i = 0; i < vtx->attr_count; i++) { fastpath->attr[i].format = vtx->attr[i].format; fastpath->attr[i].stride = vtx->attr[i].inputstride; + fastpath->attr[i].size = vtx->attr[i].inputsize; + fastpath->attr[i].offset = vtx->attr[i].vertoffset; } fastpath->next = vtx->fastpath; @@ -101,7 +116,7 @@ void _tnl_register_fastpath( struct tnl_clipspace *vtx, /*********************************************************************** * Build codegen functions or return generic ones: */ -static void choose_emit_func( GLcontext *ctx, GLuint count, GLubyte *dest) +static void choose_emit_func( struct gl_context *ctx, GLuint count, GLubyte *dest) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); @@ -145,15 +160,17 @@ static void choose_emit_func( GLcontext *ctx, GLuint count, GLubyte *dest) -static void choose_interp_func( GLcontext *ctx, +static void choose_interp_func( struct gl_context *ctx, GLfloat t, GLuint edst, GLuint eout, GLuint ein, GLboolean force_boundary ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL || + ctx->Polygon.BackMode != GL_FILL); + GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide; - if (vtx->need_extras && - (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + if (vtx->need_extras && (twosided || unfilled)) { vtx->interp = _tnl_generic_interp_extras; } else { vtx->interp = _tnl_generic_interp; @@ -163,12 +180,15 @@ static void choose_interp_func( GLcontext *ctx, } -static void choose_copy_pv_func( GLcontext *ctx, GLuint edst, GLuint esrc ) +static void choose_copy_pv_func( struct gl_context *ctx, GLuint edst, GLuint esrc ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL || + ctx->Polygon.BackMode != GL_FILL); - if (vtx->need_extras && - (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide; + + if (vtx->need_extras && (twosided || unfilled)) { vtx->copy_pv = _tnl_generic_copy_pv_extras; } else { vtx->copy_pv = _tnl_generic_copy_pv; @@ -185,7 +205,7 @@ static void choose_copy_pv_func( GLcontext *ctx, GLuint edst, GLuint esrc ) /* Interpolate between two vertices to produce a third: */ -void _tnl_interp( GLcontext *ctx, +void _tnl_interp( struct gl_context *ctx, GLfloat t, GLuint edst, GLuint eout, GLuint ein, GLboolean force_boundary ) @@ -196,7 +216,7 @@ void _tnl_interp( GLcontext *ctx, /* Copy colors from one vertex to another: */ -void _tnl_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) +void _tnl_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); vtx->copy_pv( ctx, edst, esrc ); @@ -207,7 +227,7 @@ void _tnl_copy_pv( 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, const void *vin, +void _tnl_get_attr( struct gl_context *ctx, const void *vin, GLenum attr, GLfloat *dest ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); @@ -224,13 +244,21 @@ void _tnl_get_attr( GLcontext *ctx, const void *vin, /* Else return the value from ctx->Current. */ - _mesa_memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); + if (attr == _TNL_ATTRIB_POINTSIZE) { + /* If the hardware vertex doesn't have point size then use size from + * struct gl_context. XXX this will be wrong if drawing attenuated points! + */ + dest[0] = ctx->Point.Size; + } + else { + memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); + } } /* Complementary operation to the above. */ -void _tnl_set_attr( GLcontext *ctx, void *vout, +void _tnl_set_attr( struct gl_context *ctx, void *vout, GLenum attr, const GLfloat *src ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); @@ -247,16 +275,17 @@ void _tnl_set_attr( GLcontext *ctx, void *vout, } -void *_tnl_get_vertex( GLcontext *ctx, GLuint nr ) +void *_tnl_get_vertex( struct gl_context *ctx, GLuint nr ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); return vtx->vertex_buf + nr * vtx->vertex_size; } -void _tnl_invalidate_vertex_state( GLcontext *ctx, GLuint new_state ) +void _tnl_invalidate_vertex_state( struct gl_context *ctx, GLuint new_state ) { - if (new_state & (_DD_NEW_TRI_LIGHT_TWOSIDE|_DD_NEW_TRI_UNFILLED) ) { + /* if two-sided lighting changes or filled/unfilled polygon state changes */ + if (new_state & (_NEW_LIGHT | _NEW_POLYGON) ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); vtx->new_inputs = ~0; vtx->interp = choose_interp_func; @@ -272,7 +301,7 @@ static void invalidate_funcs( struct tnl_clipspace *vtx ) vtx->new_inputs = ~0; } -GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map, +GLuint _tnl_install_attrs( struct gl_context *ctx, const struct tnl_attr_map *map, GLuint nr, const GLfloat *vp, GLuint unpacked_size ) { @@ -294,8 +323,8 @@ GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map, const GLuint format = map[i].format; if (format == EMIT_PAD) { if (DBG) - _mesa_printf("%d: pad %d, offset %d\n", i, - map[i].offset, offset); + printf("%d: pad %d, offset %d\n", i, + map[i].offset, offset); offset += map[i].offset; @@ -325,9 +354,9 @@ GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map, if (DBG) - _mesa_printf("%d: %s, vp %p, offset %d\n", i, - _tnl_format_info[format].name, (void *)vp, - vtx->attr[j].vertoffset); + printf("%d: %s, vp %p, offset %d\n", i, + _tnl_format_info[format].name, (void *)vp, + vtx->attr[j].vertoffset); offset += _tnl_format_info[format].attrsize; j++; @@ -347,7 +376,7 @@ GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map, -void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs ) +void _tnl_invalidate_vertices( struct gl_context *ctx, GLuint newinputs ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); vtx->new_inputs |= newinputs; @@ -357,13 +386,29 @@ void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs ) /* This event has broader use beyond this file - will move elsewhere * and probably invoke a driver callback. */ -void _tnl_notify_pipeline_output_change( GLcontext *ctx ) +void _tnl_notify_pipeline_output_change( struct gl_context *ctx ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); invalidate_funcs(vtx); } -static void update_input_ptrs( GLcontext *ctx, GLuint start ) + +static void adjust_input_ptrs( struct gl_context *ctx, GLint diff) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + struct tnl_clipspace_attr *a = vtx->attr; + const GLuint count = vtx->attr_count; + GLuint j; + + diff -= 1; + for (j=0; jAttribPtr[a->attrib]; + (a++)->inputptr += diff*vptr->stride; + } +} + +static void update_input_ptrs( struct gl_context *ctx, GLuint start ) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); @@ -395,7 +440,7 @@ static void update_input_ptrs( GLcontext *ctx, GLuint start ) } -void _tnl_build_vertices( GLcontext *ctx, +void _tnl_build_vertices( struct gl_context *ctx, GLuint start, GLuint end, GLuint newinputs ) @@ -410,7 +455,7 @@ void _tnl_build_vertices( GLcontext *ctx, /* Emit VB vertices start..end to dest. Note that VB vertex at * postion start will be emitted to dest at position zero. */ -void *_tnl_emit_vertices_to_buffer( GLcontext *ctx, +void *_tnl_emit_vertices_to_buffer( struct gl_context *ctx, GLuint start, GLuint end, void *dest ) @@ -418,15 +463,42 @@ void *_tnl_emit_vertices_to_buffer( GLcontext *ctx, struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); update_input_ptrs(ctx, start); - /* Note: dest should not be adjusted for non-zero 'start' values: */ - vtx->emit( ctx, end - start, dest ); + vtx->emit( ctx, end - start, (GLubyte*) dest ); return (void *)((GLubyte *)dest + vtx->vertex_size * (end - start)); } +/* Emit indexed VB vertices start..end to dest. Note that VB vertex at + * postion start will be emitted to dest at position zero. + */ + +void *_tnl_emit_indexed_vertices_to_buffer( struct gl_context *ctx, + const GLuint *elts, + GLuint start, + GLuint end, + void *dest ) +{ + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + GLuint oldIndex; + GLubyte *cdest = dest; + + update_input_ptrs(ctx, oldIndex = elts[start++]); + vtx->emit( ctx, 1, cdest ); + cdest += vtx->vertex_size; + + for (; start < end; ++start) { + adjust_input_ptrs(ctx, elts[start] - oldIndex); + oldIndex = elts[start]; + vtx->emit( ctx, 1, cdest); + cdest += vtx->vertex_size; + } + + return (void *) cdest; +} -void _tnl_init_vertices( GLcontext *ctx, + +void _tnl_init_vertices( struct gl_context *ctx, GLuint vb_size, GLuint max_vertex_size ) { @@ -438,7 +510,7 @@ void _tnl_init_vertices( GLcontext *ctx, if (max_vertex_size > vtx->max_vertex_size) { _tnl_free_vertices( ctx ); vtx->max_vertex_size = max_vertex_size; - vtx->vertex_buf = (GLubyte *)ALIGN_CALLOC(vb_size * max_vertex_size, 32 ); + vtx->vertex_buf = _mesa_align_calloc(vb_size * max_vertex_size, 32 ); invalidate_funcs(vtx); } @@ -470,29 +542,37 @@ void _tnl_init_vertices( GLcontext *ctx, vtx->codegen_emit = NULL; -#ifdef __i386__ - if (getenv("MESA_EXPERIMENTAL")) +#ifdef USE_SSE_ASM + if (!getenv("MESA_NO_CODEGEN")) vtx->codegen_emit = _tnl_generate_sse_emit; #endif } -void _tnl_free_vertices( GLcontext *ctx ) +void _tnl_free_vertices( struct gl_context *ctx ) { - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - struct tnl_clipspace_fastpath *fp, *tmp; + TNLcontext *tnl = TNL_CONTEXT(ctx); + if (tnl) { + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); + struct tnl_clipspace_fastpath *fp, *tmp; - if (vtx->vertex_buf) { - ALIGN_FREE(vtx->vertex_buf); + _mesa_align_free(vtx->vertex_buf); vtx->vertex_buf = NULL; + + for (fp = vtx->fastpath ; fp ; fp = tmp) { + tmp = fp->next; + free(fp->attr); + + /* KW: At the moment, fp->func is constrained to be allocated by + * _mesa_exec_alloc(), as the hardwired fastpaths in + * t_vertex_generic.c are handled specially. It would be nice + * to unify them, but this probably won't change until this + * module gets another overhaul. + */ + _mesa_exec_free((void *) fp->func); + free(fp); + } + + vtx->fastpath = NULL; } - - for (fp = vtx->fastpath ; fp ; fp = tmp) { - tmp = fp->next; - FREE(fp->attr); - FREE((void *)fp->func); - FREE(fp); - } - - vtx->fastpath = NULL; }