1/* 2 * Mesa 3-D graphics library 3 * Version: 3.5 4 * 5 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/* 26 * New (3.1) transformation code written by Keith Whitwell. 27 */ 28 29 30#include "main/glheader.h" 31#include "main/imports.h" 32#include "main/macros.h" 33 34#include "m_vector.h" 35 36 37 38/** 39 * Given a vector [count][4] of floats, set all the [][elt] values 40 * to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3). 41 */ 42void 43_mesa_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) 44{ 45 static const GLubyte elem_bits[4] = { 46 VEC_DIRTY_0, 47 VEC_DIRTY_1, 48 VEC_DIRTY_2, 49 VEC_DIRTY_3 50 }; 51 static const GLfloat clean[4] = { 0, 0, 0, 1 }; 52 const GLfloat v = clean[elt]; 53 GLfloat (*data)[4] = (GLfloat (*)[4])vec->start; 54 GLuint i; 55 56 for (i = 0; i < count; i++) 57 data[i][elt] = v; 58 59 vec->flags &= ~elem_bits[elt]; 60} 61 62 63static const GLubyte size_bits[5] = { 64 0, 65 VEC_SIZE_1, 66 VEC_SIZE_2, 67 VEC_SIZE_3, 68 VEC_SIZE_4, 69}; 70 71 72/** 73 * Initialize GLvector objects. 74 * \param v the vector object to initialize. 75 * \param flags bitwise-OR of VEC_* flags 76 * \param storage pointer to storage for the vector's data 77 */ 78void 79_mesa_vector4f_init( GLvector4f *v, GLbitfield flags, GLfloat (*storage)[4] ) 80{ 81 v->stride = 4 * sizeof(GLfloat); 82 v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */ 83 v->data = storage; 84 v->start = (GLfloat *) storage; 85 v->count = 0; 86 v->flags = size_bits[4] | flags; 87} 88 89 90/** 91 * Initialize GLvector objects and allocate storage. 92 * \param v the vector object 93 * \param flags bitwise-OR of VEC_* flags 94 * \param count number of elements to allocate in vector 95 * \param alignment desired memory alignment for the data (in bytes) 96 */ 97void 98_mesa_vector4f_alloc( GLvector4f *v, GLbitfield flags, GLuint count, 99 GLuint alignment ) 100{ 101 v->stride = 4 * sizeof(GLfloat); 102 v->size = 2; 103 v->storage = _mesa_align_malloc( count * 4 * sizeof(GLfloat), alignment ); 104 v->storage_count = count; 105 v->start = (GLfloat *) v->storage; 106 v->data = (GLfloat (*)[4]) v->storage; 107 v->count = 0; 108 v->flags = size_bits[4] | flags | VEC_MALLOC; 109} 110 111 112/** 113 * Vector deallocation. Free whatever memory is pointed to by the 114 * vector's storage field if the VEC_MALLOC flag is set. 115 * DO NOT free the GLvector object itself, though. 116 */ 117void 118_mesa_vector4f_free( GLvector4f *v ) 119{ 120 if (v->flags & VEC_MALLOC) { 121 _mesa_align_free( v->storage ); 122 v->data = NULL; 123 v->start = NULL; 124 v->storage = NULL; 125 v->flags &= ~VEC_MALLOC; 126 } 127} 128 129 130/** 131 * For debugging 132 */ 133void 134_mesa_vector4f_print( const GLvector4f *v, const GLubyte *cullmask, 135 GLboolean culling ) 136{ 137 static const GLfloat c[4] = { 0, 0, 0, 1 }; 138 static const char *templates[5] = { 139 "%d:\t0, 0, 0, 1\n", 140 "%d:\t%f, 0, 0, 1\n", 141 "%d:\t%f, %f, 0, 1\n", 142 "%d:\t%f, %f, %f, 1\n", 143 "%d:\t%f, %f, %f, %f\n" 144 }; 145 146 const char *t = templates[v->size]; 147 GLfloat *d = (GLfloat *)v->data; 148 GLuint j, i = 0, count; 149 150 printf("data-start\n"); 151 for (; d != v->start; STRIDE_F(d, v->stride), i++) 152 printf(t, i, d[0], d[1], d[2], d[3]); 153 154 printf("start-count(%u)\n", v->count); 155 count = i + v->count; 156 157 if (culling) { 158 for (; i < count; STRIDE_F(d, v->stride), i++) 159 if (cullmask[i]) 160 printf(t, i, d[0], d[1], d[2], d[3]); 161 } 162 else { 163 for (; i < count; STRIDE_F(d, v->stride), i++) 164 printf(t, i, d[0], d[1], d[2], d[3]); 165 } 166 167 for (j = v->size; j < 4; j++) { 168 if ((v->flags & (1<<j)) == 0) { 169 170 printf("checking col %u is clean as advertised ", j); 171 172 for (i = 0, d = (GLfloat *) v->data; 173 i < count && d[j] == c[j]; 174 i++, STRIDE_F(d, v->stride)) { 175 /* no-op */ 176 } 177 178 if (i == count) 179 printf(" --> ok\n"); 180 else 181 printf(" --> Failed at %u ******\n", i); 182 } 183 } 184} 185