1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg * 24848b8605Smrg * Authors: 25848b8605Smrg * Keith Whitwell <keithw@vmware.com> 26848b8605Smrg */ 27848b8605Smrg 28b8e80941Smrg#include "main/errors.h" 29848b8605Smrg#include "main/bufferobj.h" 30848b8605Smrg#include "math/m_eval.h" 31b8e80941Smrg#include "main/vtxfmt.h" 32b8e80941Smrg#include "main/api_arrayelt.h" 33b8e80941Smrg#include "main/arrayobj.h" 34b8e80941Smrg#include "main/varray.h" 35848b8605Smrg#include "vbo.h" 36b8e80941Smrg#include "vbo_private.h" 37b8e80941Smrg 38b8e80941Smrg 39b8e80941Smrgstatic GLuint 40b8e80941Smrgcheck_size(const GLfloat *attr) 41b8e80941Smrg{ 42b8e80941Smrg if (attr[3] != 1.0F) 43b8e80941Smrg return 4; 44b8e80941Smrg if (attr[2] != 0.0F) 45b8e80941Smrg return 3; 46b8e80941Smrg if (attr[1] != 0.0F) 47b8e80941Smrg return 2; 48b8e80941Smrg return 1; 49b8e80941Smrg} 50848b8605Smrg 51848b8605Smrg 52b8e80941Smrg/** 53b8e80941Smrg * Helper for initializing a vertex array. 54b8e80941Smrg */ 55b8e80941Smrgstatic void 56b8e80941Smrginit_array(struct gl_context *ctx, struct gl_array_attributes *attrib, 57b8e80941Smrg unsigned size, const void *pointer) 58848b8605Smrg{ 59b8e80941Smrg memset(attrib, 0, sizeof(*attrib)); 60b8e80941Smrg 61b8e80941Smrg vbo_set_vertex_format(&attrib->Format, size, GL_FLOAT); 62b8e80941Smrg attrib->Stride = 0; 63b8e80941Smrg attrib->Ptr = pointer; 64848b8605Smrg} 65848b8605Smrg 66848b8605Smrg 67b8e80941Smrg/** 68b8e80941Smrg * Set up the vbo->currval arrays to point at the context's current 69b8e80941Smrg * vertex attributes (with strides = 0). 70b8e80941Smrg */ 71b8e80941Smrgstatic void 72b8e80941Smrginit_legacy_currval(struct gl_context *ctx) 73848b8605Smrg{ 74848b8605Smrg struct vbo_context *vbo = vbo_context(ctx); 75848b8605Smrg GLuint i; 76848b8605Smrg 77b8e80941Smrg /* Set up a constant (Stride == 0) array for each current 78848b8605Smrg * attribute: 79848b8605Smrg */ 80848b8605Smrg for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { 81b8e80941Smrg const unsigned attr = VERT_ATTRIB_FF(i); 82b8e80941Smrg struct gl_array_attributes *attrib = &vbo->current[attr]; 83848b8605Smrg 84b8e80941Smrg init_array(ctx, attrib, check_size(ctx->Current.Attrib[attr]), 85b8e80941Smrg ctx->Current.Attrib[attr]); 86848b8605Smrg } 87848b8605Smrg} 88848b8605Smrg 89848b8605Smrg 90b8e80941Smrgstatic void 91b8e80941Smrginit_generic_currval(struct gl_context *ctx) 92848b8605Smrg{ 93848b8605Smrg struct vbo_context *vbo = vbo_context(ctx); 94848b8605Smrg GLuint i; 95848b8605Smrg 96848b8605Smrg for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { 97b8e80941Smrg const unsigned attr = VBO_ATTRIB_GENERIC0 + i; 98b8e80941Smrg struct gl_array_attributes *attrib = &vbo->current[attr]; 99848b8605Smrg 100b8e80941Smrg init_array(ctx, attrib, 1, ctx->Current.Attrib[attr]); 101848b8605Smrg } 102848b8605Smrg} 103848b8605Smrg 104848b8605Smrg 105b8e80941Smrgstatic void 106b8e80941Smrginit_mat_currval(struct gl_context *ctx) 107848b8605Smrg{ 108848b8605Smrg struct vbo_context *vbo = vbo_context(ctx); 109848b8605Smrg GLuint i; 110848b8605Smrg 111848b8605Smrg /* Set up a constant (StrideB == 0) array for each current 112848b8605Smrg * attribute: 113848b8605Smrg */ 114b8e80941Smrg for (i = 0; i < MAT_ATTRIB_MAX; i++) { 115b8e80941Smrg const unsigned attr = VBO_ATTRIB_MAT_FRONT_AMBIENT + i; 116b8e80941Smrg struct gl_array_attributes *attrib = &vbo->current[attr]; 117b8e80941Smrg unsigned size; 118848b8605Smrg 119848b8605Smrg /* Size is fixed for the material attributes, for others will 120848b8605Smrg * be determined at runtime: 121848b8605Smrg */ 122b8e80941Smrg switch (i) { 123848b8605Smrg case MAT_ATTRIB_FRONT_SHININESS: 124848b8605Smrg case MAT_ATTRIB_BACK_SHININESS: 125b8e80941Smrg size = 1; 126b8e80941Smrg break; 127848b8605Smrg case MAT_ATTRIB_FRONT_INDEXES: 128848b8605Smrg case MAT_ATTRIB_BACK_INDEXES: 129b8e80941Smrg size = 3; 130b8e80941Smrg break; 131848b8605Smrg default: 132b8e80941Smrg size = 4; 133b8e80941Smrg break; 134848b8605Smrg } 135848b8605Smrg 136b8e80941Smrg init_array(ctx, attrib, size, ctx->Light.Material.Attrib[i]); 137848b8605Smrg } 138848b8605Smrg} 139848b8605Smrg 140848b8605Smrg 141b8e80941Smrgvoid 142b8e80941Smrg_vbo_install_exec_vtxfmt(struct gl_context *ctx) 143848b8605Smrg{ 144b8e80941Smrg struct vbo_context *vbo = vbo_context(ctx); 145848b8605Smrg 146b8e80941Smrg _mesa_install_exec_vtxfmt(ctx, &vbo->exec.vtxfmt); 147b8e80941Smrg} 148848b8605Smrg 149848b8605Smrg 150b8e80941Smrgvoid 151b8e80941Smrgvbo_exec_invalidate_state(struct gl_context *ctx) 152b8e80941Smrg{ 153b8e80941Smrg struct vbo_context *vbo = vbo_context(ctx); 154b8e80941Smrg struct vbo_exec_context *exec = &vbo->exec; 155b8e80941Smrg 156b8e80941Smrg if (ctx->NewState & _NEW_EVAL) 157b8e80941Smrg exec->eval.recalculate_maps = GL_TRUE; 158b8e80941Smrg} 159b8e80941Smrg 160848b8605Smrg 161b8e80941SmrgGLboolean 162b8e80941Smrg_vbo_CreateContext(struct gl_context *ctx) 163b8e80941Smrg{ 164b8e80941Smrg struct vbo_context *vbo = CALLOC_STRUCT(vbo_context); 165b8e80941Smrg 166b8e80941Smrg ctx->vbo_context = vbo; 167b8e80941Smrg 168b8e80941Smrg vbo->binding.Offset = 0; 169b8e80941Smrg vbo->binding.Stride = 0; 170b8e80941Smrg vbo->binding.InstanceDivisor = 0; 171b8e80941Smrg _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, 172b8e80941Smrg ctx->Shared->NullBufferObj); 173b8e80941Smrg init_legacy_currval(ctx); 174b8e80941Smrg init_generic_currval(ctx); 175b8e80941Smrg init_mat_currval(ctx); 176848b8605Smrg 177b8e80941Smrg /* make sure all VBO_ATTRIB_ values can fit in an unsigned byte */ 178b8e80941Smrg STATIC_ASSERT(VBO_ATTRIB_MAX <= 255); 179848b8605Smrg 180848b8605Smrg /* Hook our functions into exec and compile dispatch tables. These 181848b8605Smrg * will pretty much be permanently installed, which means that the 182848b8605Smrg * vtxfmt mechanism can be removed now. 183848b8605Smrg */ 184b8e80941Smrg vbo_exec_init(ctx); 185848b8605Smrg if (ctx->API == API_OPENGL_COMPAT) 186b8e80941Smrg vbo_save_init(ctx); 187b8e80941Smrg 188b8e80941Smrg vbo->VAO = _mesa_new_vao(ctx, ~((GLuint)0)); 189b8e80941Smrg /* The exec VAO assumes to have all arributes bound to binding 0 */ 190b8e80941Smrg for (unsigned i = 0; i < VERT_ATTRIB_MAX; ++i) 191b8e80941Smrg _mesa_vertex_attrib_binding(ctx, vbo->VAO, i, 0); 192848b8605Smrg 193848b8605Smrg _math_init_eval(); 194848b8605Smrg 195848b8605Smrg return GL_TRUE; 196848b8605Smrg} 197848b8605Smrg 198848b8605Smrg 199b8e80941Smrgvoid 200b8e80941Smrg_vbo_DestroyContext(struct gl_context *ctx) 201848b8605Smrg{ 202848b8605Smrg struct vbo_context *vbo = vbo_context(ctx); 203848b8605Smrg 204848b8605Smrg if (vbo) { 205848b8605Smrg 206b8e80941Smrg _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, NULL); 207848b8605Smrg 208848b8605Smrg vbo_exec_destroy(ctx); 209848b8605Smrg if (ctx->API == API_OPENGL_COMPAT) 210848b8605Smrg vbo_save_destroy(ctx); 211b8e80941Smrg _mesa_reference_vao(ctx, &vbo->VAO, NULL); 212848b8605Smrg free(vbo); 213848b8605Smrg ctx->vbo_context = NULL; 214848b8605Smrg } 215848b8605Smrg} 216848b8605Smrg 217848b8605Smrg 218b8e80941Smrgconst struct gl_array_attributes * 219b8e80941Smrg_vbo_current_attrib(const struct gl_context *ctx, gl_vert_attrib attr) 220848b8605Smrg{ 221b8e80941Smrg const struct vbo_context *vbo = vbo_context_const(ctx); 222b8e80941Smrg const gl_vertex_processing_mode vmp = ctx->VertexProgram._VPMode; 223b8e80941Smrg return &vbo->current[_vbo_attribute_alias_map[vmp][attr]]; 224848b8605Smrg} 225848b8605Smrg 226b8e80941Smrg 227b8e80941Smrgconst struct gl_vertex_buffer_binding * 228b8e80941Smrg_vbo_current_binding(const struct gl_context *ctx) 229b8e80941Smrg{ 230b8e80941Smrg const struct vbo_context *vbo = vbo_context_const(ctx); 231b8e80941Smrg return &vbo->binding; 232b8e80941Smrg} 233