17117f1b4Smrg/************************************************************************** 201e04c3fSmrg * 3af69d88dSmrg * Copyright 2005 VMware, Inc. 47117f1b4Smrg * All Rights Reserved. 501e04c3fSmrg * 67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77117f1b4Smrg * copy of this software and associated documentation files (the 87117f1b4Smrg * "Software"), to deal in the Software without restriction, including 97117f1b4Smrg * without limitation the rights to use, copy, modify, merge, publish, 107117f1b4Smrg * distribute, sub license, and/or sell copies of the Software, and to 117117f1b4Smrg * permit persons to whom the Software is furnished to do so, subject to 127117f1b4Smrg * the following conditions: 1301e04c3fSmrg * 147117f1b4Smrg * The above copyright notice and this permission notice (including the 157117f1b4Smrg * next paragraph) shall be included in all copies or substantial portions 167117f1b4Smrg * of the Software. 1701e04c3fSmrg * 187117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 197117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 207117f1b4Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 227117f1b4Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 237117f1b4Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 247117f1b4Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2501e04c3fSmrg * 267117f1b4Smrg **************************************************************************/ 277117f1b4Smrg 2801e04c3fSmrg#include <stdio.h> 29c1f859d4Smrg#include "main/context.h" 30c1f859d4Smrg#include "main/glheader.h" 31c1f859d4Smrg#include "main/enums.h" 327ec681f3Smrg#include "main/mesa_private.h" 33cdc920a0Smrg#include "main/dispatch.h" 34c1f859d4Smrg#include "glapi/glapi.h" 357117f1b4Smrg 3601e04c3fSmrg#include "vbo_private.h" 377117f1b4Smrg 387117f1b4Smrg 3901e04c3fSmrgtypedef void (*attr_func)(struct gl_context *ctx, GLint index, const GLfloat *); 407117f1b4Smrg 417117f1b4Smrg 427117f1b4Smrg/* This file makes heavy use of the aliasing of NV vertex attributes 437117f1b4Smrg * with the legacy attributes, and also with ARB and Material 447117f1b4Smrg * attributes as currently implemented. 457117f1b4Smrg */ 4601e04c3fSmrgstatic void 4701e04c3fSmrgVertexAttrib1fvNV(struct gl_context *ctx, GLint index, const GLfloat *v) 487117f1b4Smrg{ 4901e04c3fSmrg CALL_VertexAttrib1fvNV(ctx->Exec, (index, v)); 507117f1b4Smrg} 517117f1b4Smrg 5201e04c3fSmrg 5301e04c3fSmrgstatic void 5401e04c3fSmrgVertexAttrib2fvNV(struct gl_context *ctx, GLint index, const GLfloat *v) 557117f1b4Smrg{ 5601e04c3fSmrg CALL_VertexAttrib2fvNV(ctx->Exec, (index, v)); 577117f1b4Smrg} 587117f1b4Smrg 5901e04c3fSmrg 6001e04c3fSmrgstatic void 6101e04c3fSmrgVertexAttrib3fvNV(struct gl_context *ctx, GLint index, const GLfloat *v) 627117f1b4Smrg{ 6301e04c3fSmrg CALL_VertexAttrib3fvNV(ctx->Exec, (index, v)); 647117f1b4Smrg} 657117f1b4Smrg 6601e04c3fSmrg 6701e04c3fSmrgstatic void 6801e04c3fSmrgVertexAttrib4fvNV(struct gl_context *ctx, GLint index, const GLfloat *v) 697117f1b4Smrg{ 7001e04c3fSmrg CALL_VertexAttrib4fvNV(ctx->Exec, (index, v)); 717117f1b4Smrg} 727117f1b4Smrg 7301e04c3fSmrg 747117f1b4Smrgstatic attr_func vert_attrfunc[4] = { 757117f1b4Smrg VertexAttrib1fvNV, 767117f1b4Smrg VertexAttrib2fvNV, 777117f1b4Smrg VertexAttrib3fvNV, 787117f1b4Smrg VertexAttrib4fvNV 797117f1b4Smrg}; 807117f1b4Smrg 8101e04c3fSmrg 827117f1b4Smrgstruct loopback_attr { 8301e04c3fSmrg enum vbo_attrib index; 8401e04c3fSmrg GLuint offset; 857117f1b4Smrg attr_func func; 867117f1b4Smrg}; 877117f1b4Smrg 8801e04c3fSmrg 8901e04c3fSmrg/** 9001e04c3fSmrg * Don't emit ends and begins on wrapped primitives. Don't replay 91cdc920a0Smrg * wrapped vertices. If we get here, it's probably because the 927117f1b4Smrg * precalculated wrapping is wrong. 937117f1b4Smrg */ 9401e04c3fSmrgstatic void 9501e04c3fSmrgloopback_prim(struct gl_context *ctx, 9601e04c3fSmrg const GLubyte *buffer, 9701e04c3fSmrg const struct _mesa_prim *prim, 9801e04c3fSmrg GLuint wrap_count, 9901e04c3fSmrg GLuint stride, 10001e04c3fSmrg const struct loopback_attr *la, GLuint nr) 1017117f1b4Smrg{ 10201e04c3fSmrg GLuint start = prim->start; 10301e04c3fSmrg const GLuint end = start + prim->count; 10401e04c3fSmrg const GLubyte *data; 1057117f1b4Smrg 1067117f1b4Smrg if (0) 10701e04c3fSmrg printf("loopback prim %s(%s,%s) verts %d..%d vsize %d\n", 10801e04c3fSmrg _mesa_lookup_prim_by_nr(prim->mode), 10901e04c3fSmrg prim->begin ? "begin" : "..", 11001e04c3fSmrg prim->end ? "end" : "..", 11101e04c3fSmrg start, end, 11201e04c3fSmrg stride); 1137117f1b4Smrg 1147117f1b4Smrg if (prim->begin) { 1157ec681f3Smrg CALL_Begin(ctx->Exec, (prim->mode)); 1167117f1b4Smrg } 1177117f1b4Smrg else { 1187117f1b4Smrg start += wrap_count; 1197117f1b4Smrg } 1207117f1b4Smrg 12101e04c3fSmrg data = buffer + start * stride; 1227117f1b4Smrg 12301e04c3fSmrg for (GLuint j = start; j < end; j++) { 12401e04c3fSmrg for (GLuint k = 0; k < nr; k++) 12501e04c3fSmrg la[k].func(ctx, la[k].index, (const GLfloat *)(data + la[k].offset)); 1267117f1b4Smrg 12701e04c3fSmrg data += stride; 1287117f1b4Smrg } 1297117f1b4Smrg 1307117f1b4Smrg if (prim->end) { 1317ec681f3Smrg CALL_End(ctx->Exec, ()); 1327117f1b4Smrg } 1337117f1b4Smrg} 1347117f1b4Smrg 13501e04c3fSmrg 13601e04c3fSmrgstatic inline void 13701e04c3fSmrgappend_attr(GLuint *nr, struct loopback_attr la[], int i, int shift, 13801e04c3fSmrg const struct gl_vertex_array_object *vao) 1397117f1b4Smrg{ 14001e04c3fSmrg la[*nr].index = shift + i; 14101e04c3fSmrg la[*nr].offset = vao->VertexAttrib[i].RelativeOffset; 1428a1362adSmaya la[*nr].func = vert_attrfunc[vao->VertexAttrib[i].Format.Size - 1]; 14301e04c3fSmrg (*nr)++; 1447117f1b4Smrg} 1457117f1b4Smrg 1467117f1b4Smrg 14701e04c3fSmrgvoid 14801e04c3fSmrg_vbo_loopback_vertex_list(struct gl_context *ctx, 1497ec681f3Smrg const struct vbo_save_vertex_list* node, 1507ec681f3Smrg fi_type *buffer) 1517117f1b4Smrg{ 1527117f1b4Smrg struct loopback_attr la[VBO_ATTRIB_MAX]; 15301e04c3fSmrg GLuint nr = 0; 1547117f1b4Smrg 1557117f1b4Smrg /* All Legacy, NV, ARB and Material attributes are routed through 1567117f1b4Smrg * the NV attributes entrypoints: 1577117f1b4Smrg */ 15801e04c3fSmrg const struct gl_vertex_array_object *vao = node->VAO[VP_MODE_FF]; 1598a1362adSmaya GLbitfield mask = vao->Enabled & VERT_BIT_MAT_ALL; 16001e04c3fSmrg while (mask) { 16101e04c3fSmrg const int i = u_bit_scan(&mask); 16201e04c3fSmrg append_attr(&nr, la, i, VBO_MATERIAL_SHIFT, vao); 16301e04c3fSmrg } 16401e04c3fSmrg 16501e04c3fSmrg vao = node->VAO[VP_MODE_SHADER]; 1668a1362adSmaya mask = vao->Enabled & ~(VERT_BIT_POS | VERT_BIT_GENERIC0); 16701e04c3fSmrg while (mask) { 16801e04c3fSmrg const int i = u_bit_scan(&mask); 16901e04c3fSmrg append_attr(&nr, la, i, 0, vao); 17001e04c3fSmrg } 17101e04c3fSmrg 17201e04c3fSmrg /* The last in the list should be the vertex provoking attribute */ 1738a1362adSmaya if (vao->Enabled & VERT_BIT_GENERIC0) { 17401e04c3fSmrg append_attr(&nr, la, VERT_ATTRIB_GENERIC0, 0, vao); 1758a1362adSmaya } else if (vao->Enabled & VERT_BIT_POS) { 17601e04c3fSmrg append_attr(&nr, la, VERT_ATTRIB_POS, 0, vao); 17701e04c3fSmrg } 17801e04c3fSmrg 1797ec681f3Smrg const GLuint wrap_count = node->cold->wrap_count; 18001e04c3fSmrg const GLuint stride = _vbo_save_get_stride(node); 1817117f1b4Smrg 18201e04c3fSmrg /* Replay the primitives */ 1837ec681f3Smrg const struct _mesa_prim *prims = node->cold->prims; 1847ec681f3Smrg const GLuint prim_count = node->cold->prim_count; 1857ec681f3Smrg 18601e04c3fSmrg for (GLuint i = 0; i < prim_count; i++) { 1877ec681f3Smrg loopback_prim(ctx, (GLubyte*)buffer + vao->BufferBinding[0].Offset, 1887ec681f3Smrg &prims[i], wrap_count, stride, la, nr); 1897117f1b4Smrg } 1907117f1b4Smrg} 191