X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fvbo%2Fvbo_save_loopback.c;h=26a9f94facbe27fd0b611a1fe1c097202a076efd;hb=b62379ac6f699933da52d032e2b3c06ab73f9549;hp=430333b84dd002bfe88558df486882627bfd0f43;hpb=82152a2a8e1afeb61710318e769b1379be6c02c6;p=mesa.git diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c index 430333b84dd..26a9f94facb 100644 --- a/src/mesa/vbo/vbo_save_loopback.c +++ b/src/mesa/vbo/vbo_save_loopback.c @@ -1,8 +1,8 @@ /************************************************************************** - * - * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. + * + * Copyright 2005 VMware, Inc. * 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 @@ -10,64 +10,67 @@ * distribute, sub license, 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 (including the * next paragraph) 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS 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. - * + * **************************************************************************/ -#include "swrast_setup/swrast_setup.h" -#include "swrast/swrast.h" -#include "tnl/tnl.h" -#include "context.h" +#include +#include "main/context.h" +#include "main/glheader.h" +#include "main/enums.h" +#include "main/imports.h" +#include "main/dispatch.h" +#include "glapi/glapi.h" -#include "vbo_context.h" +#include "vbo_private.h" -#include "glheader.h" -#include "enums.h" -#include "glapi.h" -#include "imports.h" -#include "macros.h" -#include "mtypes.h" -#include "dispatch.h" - -typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * ); +typedef void (*attr_func)(struct gl_context *ctx, GLint index, const GLfloat *); /* This file makes heavy use of the aliasing of NV vertex attributes * with the legacy attributes, and also with ARB and Material * attributes as currently implemented. */ -static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v) +static void +VertexAttrib1fvNV(struct gl_context *ctx, GLint index, const GLfloat *v) { - CALL_VertexAttrib1fvNV(ctx->Exec, (target, v)); + CALL_VertexAttrib1fvNV(ctx->Exec, (index, v)); } -static void VertexAttrib2fvNV(GLcontext *ctx, GLint target, const GLfloat *v) + +static void +VertexAttrib2fvNV(struct gl_context *ctx, GLint index, const GLfloat *v) { - CALL_VertexAttrib2fvNV(ctx->Exec, (target, v)); + CALL_VertexAttrib2fvNV(ctx->Exec, (index, v)); } -static void VertexAttrib3fvNV(GLcontext *ctx, GLint target, const GLfloat *v) + +static void +VertexAttrib3fvNV(struct gl_context *ctx, GLint index, const GLfloat *v) { - CALL_VertexAttrib3fvNV(ctx->Exec, (target, v)); + CALL_VertexAttrib3fvNV(ctx->Exec, (index, v)); } -static void VertexAttrib4fvNV(GLcontext *ctx, GLint target, const GLfloat *v) + +static void +VertexAttrib4fvNV(struct gl_context *ctx, GLint index, const GLfloat *v) { - CALL_VertexAttrib4fvNV(ctx->Exec, (target, v)); + CALL_VertexAttrib4fvNV(ctx->Exec, (index, v)); } + static attr_func vert_attrfunc[4] = { VertexAttrib1fvNV, VertexAttrib2fvNV, @@ -75,59 +78,53 @@ static attr_func vert_attrfunc[4] = { VertexAttrib4fvNV }; + struct loopback_attr { - GLint target; - GLint sz; + enum vbo_attrib index; + GLuint offset; attr_func func; }; -/* Don't emit ends and begins on wrapped primitives. Don't replay - * wrapped vertices. If we get here, it's probably because the the + +/** + * Don't emit ends and begins on wrapped primitives. Don't replay + * wrapped vertices. If we get here, it's probably because the * precalculated wrapping is wrong. */ -static void loopback_prim( GLcontext *ctx, - const GLfloat *buffer, - const struct _mesa_prim *prim, - GLuint wrap_count, - GLuint vertex_size, - const struct loopback_attr *la, GLuint nr ) +static void +loopback_prim(struct gl_context *ctx, + const GLubyte *buffer, + const struct _mesa_prim *prim, + GLuint wrap_count, + GLuint stride, + const struct loopback_attr *la, GLuint nr) { - GLint start = prim->start; - GLint end = start + prim->count; - const GLfloat *data; - GLint j; - GLuint k; + GLuint start = prim->start; + const GLuint end = start + prim->count; + const GLubyte *data; if (0) - _mesa_printf("loopback prim %s(%s,%s) verts %d..%d\n", - _mesa_lookup_enum_by_nr(prim->mode), - prim->begin ? "begin" : "..", - prim->end ? "end" : "..", - start, - end); + printf("loopback prim %s(%s,%s) verts %d..%d vsize %d\n", + _mesa_lookup_prim_by_nr(prim->mode), + prim->begin ? "begin" : "..", + prim->end ? "end" : "..", + start, end, + stride); if (prim->begin) { - CALL_Begin(GET_DISPATCH(), ( prim->mode )); + CALL_Begin(GET_DISPATCH(), (prim->mode)); } else { - assert(start == 0); start += wrap_count; } - data = buffer + start * vertex_size; + data = buffer + start * stride; - for (j = start ; j < end ; j++) { - const GLfloat *tmp = data + la[0].sz; + for (GLuint j = start; j < end; j++) { + for (GLuint k = 0; k < nr; k++) + la[k].func(ctx, la[k].index, (const GLfloat *)(data + la[k].offset)); - for (k = 1 ; k < nr ; k++) { - la[k].func( ctx, la[k].target, tmp ); - tmp += la[k].sz; - } - - /* Fire the vertex - */ - la[0].func( ctx, VBO_ATTRIB_POS, data ); - data = tmp; + data += stride; } if (prim->end) { @@ -135,60 +132,77 @@ static void loopback_prim( GLcontext *ctx, } } -/* Primitives generated by DrawArrays/DrawElements/Rectf may be - * caught here. If there is no primitive in progress, execute them - * normally, otherwise need to track and discard the generated - * primitives. - */ -static void loopback_weak_prim( GLcontext *ctx, - const struct _mesa_prim *prim ) + +static inline void +append_attr(GLuint *nr, struct loopback_attr la[], int i, int shift, + const struct gl_vertex_array_object *vao) { - /* Use the prim_weak flag to ensure that if this primitive - * wraps, we don't mistake future vertex_lists for part of the - * surrounding primitive. - * - * While this flag is set, we are simply disposing of data - * generated by an operation now known to be a noop. - */ - if (prim->begin) - ctx->Driver.CurrentExecPrimitive |= VBO_SAVE_PRIM_WEAK; - if (prim->end) - ctx->Driver.CurrentExecPrimitive &= ~VBO_SAVE_PRIM_WEAK; + la[*nr].index = shift + i; + la[*nr].offset = vao->VertexAttrib[i].RelativeOffset; + la[*nr].func = vert_attrfunc[vao->VertexAttrib[i].Format.Size - 1]; + (*nr)++; } -void vbo_loopback_vertex_list( GLcontext *ctx, - const GLfloat *buffer, - const GLubyte *attrsz, - const struct _mesa_prim *prim, - GLuint prim_count, - GLuint wrap_count, - GLuint vertex_size) +void +_vbo_loopback_vertex_list(struct gl_context *ctx, + const struct vbo_save_vertex_list* node) { struct loopback_attr la[VBO_ATTRIB_MAX]; - GLuint i, nr = 0; + GLuint nr = 0; /* All Legacy, NV, ARB and Material attributes are routed through * the NV attributes entrypoints: */ - for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { - if (attrsz[i]) { - la[nr].target = i; - la[nr].sz = attrsz[i]; - la[nr].func = vert_attrfunc[attrsz[i]-1]; - nr++; - } + const struct gl_vertex_array_object *vao = node->VAO[VP_MODE_FF]; + GLbitfield mask = vao->Enabled & VERT_BIT_MAT_ALL; + while (mask) { + const int i = u_bit_scan(&mask); + append_attr(&nr, la, i, VBO_MATERIAL_SHIFT, vao); + } + + vao = node->VAO[VP_MODE_SHADER]; + mask = vao->Enabled & ~(VERT_BIT_POS | VERT_BIT_GENERIC0); + while (mask) { + const int i = u_bit_scan(&mask); + append_attr(&nr, la, i, 0, vao); + } + + /* The last in the list should be the vertex provoking attribute */ + if (vao->Enabled & VERT_BIT_GENERIC0) { + append_attr(&nr, la, VERT_ATTRIB_GENERIC0, 0, vao); + } else if (vao->Enabled & VERT_BIT_POS) { + append_attr(&nr, la, VERT_ATTRIB_POS, 0, vao); + } + + const GLuint wrap_count = node->wrap_count; + const GLuint stride = _vbo_save_get_stride(node); + const GLubyte *buffer = NULL; + if (0 < nr) { + /* Compute the minimal offset into the vertex buffer object */ + GLuint offset = ~0u; + for (GLuint i = 0; i < nr; ++i) + offset = MIN2(offset, la[i].offset); + for (GLuint i = 0; i < nr; ++i) + la[i].offset -= offset; + + /* Get the mapped base pointer, assert sufficient mapping */ + struct gl_buffer_object *bufferobj = vao->BufferBinding[0].BufferObj; + assert(bufferobj && bufferobj->Mappings[MAP_INTERNAL].Pointer); + buffer = bufferobj->Mappings[MAP_INTERNAL].Pointer; + assert(bufferobj->Mappings[MAP_INTERNAL].Offset + <= vao->BufferBinding[0].Offset + offset + + stride*(_vbo_save_get_min_index(node) + wrap_count)); + buffer += vao->BufferBinding[0].Offset + offset + - bufferobj->Mappings[MAP_INTERNAL].Offset; + assert(stride*(_vbo_save_get_vertex_count(node) - wrap_count) + <= bufferobj->Mappings[MAP_INTERNAL].Length); } - for (i = 0 ; i < prim_count ; i++) { - if ((prim[i].mode & VBO_SAVE_PRIM_WEAK) && - (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)) - { - loopback_weak_prim( ctx, &prim[i] ); - } - else - { - loopback_prim( ctx, buffer, &prim[i], wrap_count, vertex_size, la, nr ); - } + /* Replay the primitives */ + const struct _mesa_prim *prims = node->prims; + const GLuint prim_count = node->prim_count; + for (GLuint i = 0; i < prim_count; i++) { + loopback_prim(ctx, buffer, &prims[i], wrap_count, stride, la, nr); } }