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