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