17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * 47117f1b4Smrg * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 57117f1b4Smrg * 67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 87117f1b4Smrg * to deal in the Software without restriction, including without limitation 97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 117117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 127117f1b4Smrg * 137117f1b4Smrg * The above copyright notice and this permission notice shall be included 147117f1b4Smrg * in all copies or substantial portions of the Software. 157117f1b4Smrg * 167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 237117f1b4Smrg */ 247117f1b4Smrg 257117f1b4Smrg/* 267117f1b4Smrg * New (3.1) transformation code written by Keith Whitwell. 277117f1b4Smrg */ 287117f1b4Smrg 2901e04c3fSmrg#include <stdio.h> 307ec681f3Smrg#include <stddef.h> 317117f1b4Smrg 32c1f859d4Smrg#include "main/glheader.h" 33c1f859d4Smrg#include "main/macros.h" 347117f1b4Smrg 357117f1b4Smrg#include "m_vector.h" 367117f1b4Smrg 377ec681f3Smrg#include "util/u_memory.h" 387ec681f3Smrg 397117f1b4Smrg 407117f1b4Smrg 414a49301eSmrg/** 427117f1b4Smrg * Given a vector [count][4] of floats, set all the [][elt] values 437117f1b4Smrg * to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3). 447117f1b4Smrg */ 454a49301eSmrgvoid 464a49301eSmrg_mesa_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) 477117f1b4Smrg{ 487117f1b4Smrg static const GLubyte elem_bits[4] = { 497117f1b4Smrg VEC_DIRTY_0, 507117f1b4Smrg VEC_DIRTY_1, 517117f1b4Smrg VEC_DIRTY_2, 527117f1b4Smrg VEC_DIRTY_3 537117f1b4Smrg }; 547117f1b4Smrg static const GLfloat clean[4] = { 0, 0, 0, 1 }; 557117f1b4Smrg const GLfloat v = clean[elt]; 567117f1b4Smrg GLfloat (*data)[4] = (GLfloat (*)[4])vec->start; 577117f1b4Smrg GLuint i; 587117f1b4Smrg 594a49301eSmrg for (i = 0; i < count; i++) 607117f1b4Smrg data[i][elt] = v; 617117f1b4Smrg 627117f1b4Smrg vec->flags &= ~elem_bits[elt]; 637117f1b4Smrg} 647117f1b4Smrg 654a49301eSmrg 667117f1b4Smrgstatic const GLubyte size_bits[5] = { 677117f1b4Smrg 0, 687117f1b4Smrg VEC_SIZE_1, 697117f1b4Smrg VEC_SIZE_2, 707117f1b4Smrg VEC_SIZE_3, 717117f1b4Smrg VEC_SIZE_4, 727117f1b4Smrg}; 737117f1b4Smrg 747117f1b4Smrg 754a49301eSmrg/** 767117f1b4Smrg * Initialize GLvector objects. 774a49301eSmrg * \param v the vector object to initialize. 784a49301eSmrg * \param flags bitwise-OR of VEC_* flags 794a49301eSmrg * \param storage pointer to storage for the vector's data 807117f1b4Smrg */ 814a49301eSmrgvoid 824a49301eSmrg_mesa_vector4f_init( GLvector4f *v, GLbitfield flags, GLfloat (*storage)[4] ) 837117f1b4Smrg{ 847ec681f3Smrg STATIC_ASSERT(V4F_DATA == offsetof(GLvector4f, data)); 857ec681f3Smrg STATIC_ASSERT(V4F_START == offsetof(GLvector4f, start)); 867ec681f3Smrg STATIC_ASSERT(V4F_COUNT == offsetof(GLvector4f, count)); 877ec681f3Smrg STATIC_ASSERT(V4F_STRIDE == offsetof(GLvector4f, stride)); 887ec681f3Smrg STATIC_ASSERT(V4F_SIZE == offsetof(GLvector4f, size)); 897ec681f3Smrg STATIC_ASSERT(V4F_FLAGS == offsetof(GLvector4f, flags)); 907ec681f3Smrg 917117f1b4Smrg v->stride = 4 * sizeof(GLfloat); 927117f1b4Smrg v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */ 937117f1b4Smrg v->data = storage; 947117f1b4Smrg v->start = (GLfloat *) storage; 957117f1b4Smrg v->count = 0; 964a49301eSmrg v->flags = size_bits[4] | flags; 977117f1b4Smrg} 987117f1b4Smrg 997117f1b4Smrg 1004a49301eSmrg/** 1017117f1b4Smrg * Initialize GLvector objects and allocate storage. 1024a49301eSmrg * \param v the vector object 1034a49301eSmrg * \param flags bitwise-OR of VEC_* flags 1044a49301eSmrg * \param count number of elements to allocate in vector 1054a49301eSmrg * \param alignment desired memory alignment for the data (in bytes) 1067117f1b4Smrg */ 1074a49301eSmrgvoid 1084a49301eSmrg_mesa_vector4f_alloc( GLvector4f *v, GLbitfield flags, GLuint count, 1094a49301eSmrg GLuint alignment ) 1107117f1b4Smrg{ 1117117f1b4Smrg v->stride = 4 * sizeof(GLfloat); 1127117f1b4Smrg v->size = 2; 1137ec681f3Smrg v->storage = align_malloc( count * 4 * sizeof(GLfloat), alignment ); 1144a49301eSmrg v->storage_count = count; 1157117f1b4Smrg v->start = (GLfloat *) v->storage; 1167117f1b4Smrg v->data = (GLfloat (*)[4]) v->storage; 1177117f1b4Smrg v->count = 0; 1184a49301eSmrg v->flags = size_bits[4] | flags | VEC_MALLOC; 1197117f1b4Smrg} 1207117f1b4Smrg 1217117f1b4Smrg 1224a49301eSmrg/** 1237117f1b4Smrg * Vector deallocation. Free whatever memory is pointed to by the 1247117f1b4Smrg * vector's storage field if the VEC_MALLOC flag is set. 1257117f1b4Smrg * DO NOT free the GLvector object itself, though. 1267117f1b4Smrg */ 1274a49301eSmrgvoid 1284a49301eSmrg_mesa_vector4f_free( GLvector4f *v ) 1297117f1b4Smrg{ 1307117f1b4Smrg if (v->flags & VEC_MALLOC) { 1317ec681f3Smrg align_free( v->storage ); 1327117f1b4Smrg v->data = NULL; 1337117f1b4Smrg v->start = NULL; 1347117f1b4Smrg v->storage = NULL; 1357117f1b4Smrg v->flags &= ~VEC_MALLOC; 1367117f1b4Smrg } 1377117f1b4Smrg} 1387117f1b4Smrg 1397117f1b4Smrg 1404a49301eSmrg/** 1417117f1b4Smrg * For debugging 1427117f1b4Smrg */ 1434a49301eSmrgvoid 1444a49301eSmrg_mesa_vector4f_print( const GLvector4f *v, const GLubyte *cullmask, 1454a49301eSmrg GLboolean culling ) 1467117f1b4Smrg{ 1474a49301eSmrg static const GLfloat c[4] = { 0, 0, 0, 1 }; 1484a49301eSmrg static const char *templates[5] = { 1497117f1b4Smrg "%d:\t0, 0, 0, 1\n", 1507117f1b4Smrg "%d:\t%f, 0, 0, 1\n", 1517117f1b4Smrg "%d:\t%f, %f, 0, 1\n", 1527117f1b4Smrg "%d:\t%f, %f, %f, 1\n", 1537117f1b4Smrg "%d:\t%f, %f, %f, %f\n" 1547117f1b4Smrg }; 1557117f1b4Smrg 1567117f1b4Smrg const char *t = templates[v->size]; 1577117f1b4Smrg GLfloat *d = (GLfloat *)v->data; 1587117f1b4Smrg GLuint j, i = 0, count; 1597117f1b4Smrg 160cdc920a0Smrg printf("data-start\n"); 1614a49301eSmrg for (; d != v->start; STRIDE_F(d, v->stride), i++) 162cdc920a0Smrg printf(t, i, d[0], d[1], d[2], d[3]); 1637117f1b4Smrg 164cdc920a0Smrg printf("start-count(%u)\n", v->count); 1657117f1b4Smrg count = i + v->count; 1667117f1b4Smrg 1677117f1b4Smrg if (culling) { 1684a49301eSmrg for (; i < count; STRIDE_F(d, v->stride), i++) 1697117f1b4Smrg if (cullmask[i]) 170cdc920a0Smrg printf(t, i, d[0], d[1], d[2], d[3]); 1717117f1b4Smrg } 1727117f1b4Smrg else { 1734a49301eSmrg for (; i < count; STRIDE_F(d, v->stride), i++) 174cdc920a0Smrg printf(t, i, d[0], d[1], d[2], d[3]); 1757117f1b4Smrg } 1767117f1b4Smrg 1774a49301eSmrg for (j = v->size; j < 4; j++) { 1787117f1b4Smrg if ((v->flags & (1<<j)) == 0) { 1797117f1b4Smrg 180cdc920a0Smrg printf("checking col %u is clean as advertised ", j); 1817117f1b4Smrg 1824a49301eSmrg for (i = 0, d = (GLfloat *) v->data; 1834a49301eSmrg i < count && d[j] == c[j]; 1844a49301eSmrg i++, STRIDE_F(d, v->stride)) { 1854a49301eSmrg /* no-op */ 1864a49301eSmrg } 1877117f1b4Smrg 1887117f1b4Smrg if (i == count) 189cdc920a0Smrg printf(" --> ok\n"); 1907117f1b4Smrg else 191cdc920a0Smrg printf(" --> Failed at %u ******\n", i); 1927117f1b4Smrg } 1937117f1b4Smrg } 1947117f1b4Smrg} 195