vbo_context.c revision 8a1362ad
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/vtxfmt.h" 32#include "main/api_arrayelt.h" 33#include "main/arrayobj.h" 34#include "main/varray.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 GLuint i; 76 77 /* Set up a constant (Stride == 0) array for each current 78 * attribute: 79 */ 80 for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { 81 const unsigned attr = VERT_ATTRIB_FF(i); 82 struct gl_array_attributes *attrib = &vbo->current[attr]; 83 84 init_array(ctx, attrib, check_size(ctx->Current.Attrib[attr]), 85 ctx->Current.Attrib[attr]); 86 } 87} 88 89 90static void 91init_generic_currval(struct gl_context *ctx) 92{ 93 struct vbo_context *vbo = vbo_context(ctx); 94 GLuint i; 95 96 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { 97 const unsigned attr = VBO_ATTRIB_GENERIC0 + i; 98 struct gl_array_attributes *attrib = &vbo->current[attr]; 99 100 init_array(ctx, attrib, 1, ctx->Current.Attrib[attr]); 101 } 102} 103 104 105static void 106init_mat_currval(struct gl_context *ctx) 107{ 108 struct vbo_context *vbo = vbo_context(ctx); 109 GLuint i; 110 111 /* Set up a constant (StrideB == 0) array for each current 112 * attribute: 113 */ 114 for (i = 0; i < MAT_ATTRIB_MAX; i++) { 115 const unsigned attr = VBO_ATTRIB_MAT_FRONT_AMBIENT + i; 116 struct gl_array_attributes *attrib = &vbo->current[attr]; 117 unsigned size; 118 119 /* Size is fixed for the material attributes, for others will 120 * be determined at runtime: 121 */ 122 switch (i) { 123 case MAT_ATTRIB_FRONT_SHININESS: 124 case MAT_ATTRIB_BACK_SHININESS: 125 size = 1; 126 break; 127 case MAT_ATTRIB_FRONT_INDEXES: 128 case MAT_ATTRIB_BACK_INDEXES: 129 size = 3; 130 break; 131 default: 132 size = 4; 133 break; 134 } 135 136 init_array(ctx, attrib, size, ctx->Light.Material.Attrib[i]); 137 } 138} 139 140 141void 142_vbo_install_exec_vtxfmt(struct gl_context *ctx) 143{ 144 struct vbo_context *vbo = vbo_context(ctx); 145 146 _mesa_install_exec_vtxfmt(ctx, &vbo->exec.vtxfmt); 147} 148 149 150void 151vbo_exec_invalidate_state(struct gl_context *ctx) 152{ 153 struct vbo_context *vbo = vbo_context(ctx); 154 struct vbo_exec_context *exec = &vbo->exec; 155 156 if (ctx->NewState & _NEW_EVAL) 157 exec->eval.recalculate_maps = GL_TRUE; 158} 159 160 161GLboolean 162_vbo_CreateContext(struct gl_context *ctx) 163{ 164 struct vbo_context *vbo = CALLOC_STRUCT(vbo_context); 165 166 ctx->vbo_context = vbo; 167 168 vbo->binding.Offset = 0; 169 vbo->binding.Stride = 0; 170 vbo->binding.InstanceDivisor = 0; 171 _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, 172 ctx->Shared->NullBufferObj); 173 init_legacy_currval(ctx); 174 init_generic_currval(ctx); 175 init_mat_currval(ctx); 176 177 /* make sure all VBO_ATTRIB_ values can fit in an unsigned byte */ 178 STATIC_ASSERT(VBO_ATTRIB_MAX <= 255); 179 180 /* Hook our functions into exec and compile dispatch tables. These 181 * will pretty much be permanently installed, which means that the 182 * vtxfmt mechanism can be removed now. 183 */ 184 vbo_exec_init(ctx); 185 if (ctx->API == API_OPENGL_COMPAT) 186 vbo_save_init(ctx); 187 188 vbo->VAO = _mesa_new_vao(ctx, ~((GLuint)0)); 189 /* The exec VAO assumes to have all arributes bound to binding 0 */ 190 for (unsigned i = 0; i < VERT_ATTRIB_MAX; ++i) 191 _mesa_vertex_attrib_binding(ctx, vbo->VAO, i, 0); 192 193 _math_init_eval(); 194 195 return GL_TRUE; 196} 197 198 199void 200_vbo_DestroyContext(struct gl_context *ctx) 201{ 202 struct vbo_context *vbo = vbo_context(ctx); 203 204 if (vbo) { 205 206 _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, NULL); 207 208 vbo_exec_destroy(ctx); 209 if (ctx->API == API_OPENGL_COMPAT) 210 vbo_save_destroy(ctx); 211 _mesa_reference_vao(ctx, &vbo->VAO, NULL); 212 free(vbo); 213 ctx->vbo_context = NULL; 214 } 215} 216 217 218const struct gl_array_attributes * 219_vbo_current_attrib(const struct gl_context *ctx, gl_vert_attrib attr) 220{ 221 const struct vbo_context *vbo = vbo_context_const(ctx); 222 const gl_vertex_processing_mode vmp = ctx->VertexProgram._VPMode; 223 return &vbo->current[_vbo_attribute_alias_map[vmp][attr]]; 224} 225 226 227const struct gl_vertex_buffer_binding * 228_vbo_current_binding(const struct gl_context *ctx) 229{ 230 const struct vbo_context *vbo = vbo_context_const(ctx); 231 return &vbo->binding; 232} 233