1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2005 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 * Authors: 25 * Keith Whitwell <keithw@vmware.com> 26 */ 27 28#include "main/errors.h" 29#include "main/bufferobj.h" 30#include "math/m_eval.h" 31#include "main/api_arrayelt.h" 32#include "main/arrayobj.h" 33#include "main/varray.h" 34#include "util/u_memory.h" 35#include "vbo.h" 36#include "vbo_private.h" 37 38 39static GLuint 40check_size(const GLfloat *attr) 41{ 42 if (attr[3] != 1.0F) 43 return 4; 44 if (attr[2] != 0.0F) 45 return 3; 46 if (attr[1] != 0.0F) 47 return 2; 48 return 1; 49} 50 51 52/** 53 * Helper for initializing a vertex array. 54 */ 55static void 56init_array(struct gl_context *ctx, struct gl_array_attributes *attrib, 57 unsigned size, const void *pointer) 58{ 59 memset(attrib, 0, sizeof(*attrib)); 60 61 vbo_set_vertex_format(&attrib->Format, size, GL_FLOAT); 62 attrib->Stride = 0; 63 attrib->Ptr = pointer; 64} 65 66 67/** 68 * Set up the vbo->currval arrays to point at the context's current 69 * vertex attributes (with strides = 0). 70 */ 71static void 72init_legacy_currval(struct gl_context *ctx) 73{ 74 struct vbo_context *vbo = vbo_context(ctx); 75 76 /* Set up a constant (Stride == 0) array for each current 77 * attribute: 78 */ 79 for (int attr = 0; attr < VERT_ATTRIB_MAX; attr++) { 80 if (VERT_BIT(attr) & VERT_BIT_GENERIC_ALL) 81 continue; 82 83 struct gl_array_attributes *attrib = &vbo->current[attr]; 84 85 init_array(ctx, attrib, check_size(ctx->Current.Attrib[attr]), 86 ctx->Current.Attrib[attr]); 87 } 88} 89 90 91static void 92init_generic_currval(struct gl_context *ctx) 93{ 94 struct vbo_context *vbo = vbo_context(ctx); 95 GLuint i; 96 97 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { 98 const unsigned attr = VBO_ATTRIB_GENERIC0 + i; 99 struct gl_array_attributes *attrib = &vbo->current[attr]; 100 101 init_array(ctx, attrib, 1, ctx->Current.Attrib[attr]); 102 } 103} 104 105 106static void 107init_mat_currval(struct gl_context *ctx) 108{ 109 struct vbo_context *vbo = vbo_context(ctx); 110 GLuint i; 111 112 /* Set up a constant (StrideB == 0) array for each current 113 * attribute: 114 */ 115 for (i = 0; i < MAT_ATTRIB_MAX; i++) { 116 const unsigned attr = VBO_ATTRIB_MAT_FRONT_AMBIENT + i; 117 struct gl_array_attributes *attrib = &vbo->current[attr]; 118 unsigned size; 119 120 /* Size is fixed for the material attributes, for others will 121 * be determined at runtime: 122 */ 123 switch (i) { 124 case MAT_ATTRIB_FRONT_SHININESS: 125 case MAT_ATTRIB_BACK_SHININESS: 126 size = 1; 127 break; 128 case MAT_ATTRIB_FRONT_INDEXES: 129 case MAT_ATTRIB_BACK_INDEXES: 130 size = 3; 131 break; 132 default: 133 size = 4; 134 break; 135 } 136 137 init_array(ctx, attrib, size, ctx->Light.Material.Attrib[i]); 138 } 139} 140 141 142void 143vbo_exec_update_eval_maps(struct gl_context *ctx) 144{ 145 struct vbo_context *vbo = vbo_context(ctx); 146 147 vbo->exec.eval.recalculate_maps = GL_TRUE; 148} 149 150 151GLboolean 152_vbo_CreateContext(struct gl_context *ctx) 153{ 154 struct vbo_context *vbo = &ctx->vbo_context; 155 156 memset(vbo, 0, sizeof(*vbo)); 157 158 init_legacy_currval(ctx); 159 init_generic_currval(ctx); 160 init_mat_currval(ctx); 161 162 /* make sure all VBO_ATTRIB_ values can fit in an unsigned byte */ 163 STATIC_ASSERT(VBO_ATTRIB_MAX <= 255); 164 165 /* Hook our functions into exec and compile dispatch tables. These 166 * will pretty much be permanently installed, which means that the 167 * vtxfmt mechanism can be removed now. 168 */ 169 vbo_exec_init(ctx); 170 if (ctx->API == API_OPENGL_COMPAT) 171 vbo_save_init(ctx); 172 173 vbo->VAO = _mesa_new_vao(ctx, ~((GLuint)0)); 174 /* The exec VAO assumes to have all arributes bound to binding 0 */ 175 for (unsigned i = 0; i < VERT_ATTRIB_MAX; ++i) 176 _mesa_vertex_attrib_binding(ctx, vbo->VAO, i, 0); 177 178 _math_init_eval(); 179 180 return GL_TRUE; 181} 182 183 184void 185_vbo_DestroyContext(struct gl_context *ctx) 186{ 187 struct vbo_context *vbo = vbo_context(ctx); 188 189 if (vbo) { 190 vbo_exec_destroy(ctx); 191 if (ctx->API == API_OPENGL_COMPAT) 192 vbo_save_destroy(ctx); 193 _mesa_reference_vao(ctx, &vbo->VAO, NULL); 194 } 195} 196 197 198const struct gl_array_attributes * 199_vbo_current_attrib(const struct gl_context *ctx, gl_vert_attrib attr) 200{ 201 const struct vbo_context *vbo = vbo_context_const(ctx); 202 const gl_vertex_processing_mode vmp = ctx->VertexProgram._VPMode; 203 return &vbo->current[_vbo_attribute_alias_map[vmp][attr]]; 204} 205