17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * 47117f1b4Smrg * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 57117f1b4Smrg * 67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 87117f1b4Smrg * to deal in the Software without restriction, including without limitation 97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 117117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 127117f1b4Smrg * 137117f1b4Smrg * The above copyright notice and this permission notice shall be included 147117f1b4Smrg * in all copies or substantial portions of the Software. 157117f1b4Smrg * 167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 237117f1b4Smrg * 247117f1b4Smrg * Authors: 25af69d88dSmrg * Keith Whitwell <keithw@vmware.com> 267117f1b4Smrg */ 277117f1b4Smrg 2801e04c3fSmrg#include "main/errors.h" 294a49301eSmrg#include "main/bufferobj.h" 304a49301eSmrg#include "math/m_eval.h" 3101e04c3fSmrg#include "main/vtxfmt.h" 3201e04c3fSmrg#include "main/api_arrayelt.h" 3301e04c3fSmrg#include "main/arrayobj.h" 3401e04c3fSmrg#include "main/varray.h" 357ec681f3Smrg#include "util/u_memory.h" 367117f1b4Smrg#include "vbo.h" 3701e04c3fSmrg#include "vbo_private.h" 387117f1b4Smrg 397117f1b4Smrg 4001e04c3fSmrgstatic GLuint 4101e04c3fSmrgcheck_size(const GLfloat *attr) 427117f1b4Smrg{ 4301e04c3fSmrg if (attr[3] != 1.0F) 4401e04c3fSmrg return 4; 4501e04c3fSmrg if (attr[2] != 0.0F) 4601e04c3fSmrg return 3; 4701e04c3fSmrg if (attr[1] != 0.0F) 4801e04c3fSmrg return 2; 4901e04c3fSmrg return 1; 507117f1b4Smrg} 517117f1b4Smrg 52cdc920a0Smrg 5301e04c3fSmrg/** 5401e04c3fSmrg * Helper for initializing a vertex array. 5501e04c3fSmrg */ 5601e04c3fSmrgstatic void 5701e04c3fSmrginit_array(struct gl_context *ctx, struct gl_array_attributes *attrib, 5801e04c3fSmrg unsigned size, const void *pointer) 5901e04c3fSmrg{ 6001e04c3fSmrg memset(attrib, 0, sizeof(*attrib)); 6101e04c3fSmrg 628a1362adSmaya vbo_set_vertex_format(&attrib->Format, size, GL_FLOAT); 6301e04c3fSmrg attrib->Stride = 0; 6401e04c3fSmrg attrib->Ptr = pointer; 6501e04c3fSmrg} 6601e04c3fSmrg 6701e04c3fSmrg 6801e04c3fSmrg/** 6901e04c3fSmrg * Set up the vbo->currval arrays to point at the context's current 7001e04c3fSmrg * vertex attributes (with strides = 0). 7101e04c3fSmrg */ 7201e04c3fSmrgstatic void 7301e04c3fSmrginit_legacy_currval(struct gl_context *ctx) 747117f1b4Smrg{ 757117f1b4Smrg struct vbo_context *vbo = vbo_context(ctx); 767117f1b4Smrg 7701e04c3fSmrg /* Set up a constant (Stride == 0) array for each current 787117f1b4Smrg * attribute: 797117f1b4Smrg */ 807ec681f3Smrg for (int attr = 0; attr < VERT_ATTRIB_MAX; attr++) { 817ec681f3Smrg if (VERT_BIT(attr) & VERT_BIT_GENERIC_ALL) 827ec681f3Smrg continue; 837ec681f3Smrg 8401e04c3fSmrg struct gl_array_attributes *attrib = &vbo->current[attr]; 857117f1b4Smrg 8601e04c3fSmrg init_array(ctx, attrib, check_size(ctx->Current.Attrib[attr]), 8701e04c3fSmrg ctx->Current.Attrib[attr]); 887117f1b4Smrg } 897117f1b4Smrg} 907117f1b4Smrg 917117f1b4Smrg 9201e04c3fSmrgstatic void 9301e04c3fSmrginit_generic_currval(struct gl_context *ctx) 947117f1b4Smrg{ 957117f1b4Smrg struct vbo_context *vbo = vbo_context(ctx); 967117f1b4Smrg GLuint i; 977117f1b4Smrg 98af69d88dSmrg for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { 9901e04c3fSmrg const unsigned attr = VBO_ATTRIB_GENERIC0 + i; 10001e04c3fSmrg struct gl_array_attributes *attrib = &vbo->current[attr]; 1017117f1b4Smrg 10201e04c3fSmrg init_array(ctx, attrib, 1, ctx->Current.Attrib[attr]); 1037117f1b4Smrg } 1047117f1b4Smrg} 1057117f1b4Smrg 1067117f1b4Smrg 10701e04c3fSmrgstatic void 10801e04c3fSmrginit_mat_currval(struct gl_context *ctx) 1097117f1b4Smrg{ 1107117f1b4Smrg struct vbo_context *vbo = vbo_context(ctx); 1117117f1b4Smrg GLuint i; 1127117f1b4Smrg 1137117f1b4Smrg /* Set up a constant (StrideB == 0) array for each current 1147117f1b4Smrg * attribute: 1157117f1b4Smrg */ 11601e04c3fSmrg for (i = 0; i < MAT_ATTRIB_MAX; i++) { 11701e04c3fSmrg const unsigned attr = VBO_ATTRIB_MAT_FRONT_AMBIENT + i; 11801e04c3fSmrg struct gl_array_attributes *attrib = &vbo->current[attr]; 11901e04c3fSmrg unsigned size; 1207117f1b4Smrg 1217117f1b4Smrg /* Size is fixed for the material attributes, for others will 1227117f1b4Smrg * be determined at runtime: 1237117f1b4Smrg */ 12401e04c3fSmrg switch (i) { 1257117f1b4Smrg case MAT_ATTRIB_FRONT_SHININESS: 1267117f1b4Smrg case MAT_ATTRIB_BACK_SHININESS: 12701e04c3fSmrg size = 1; 12801e04c3fSmrg break; 1297117f1b4Smrg case MAT_ATTRIB_FRONT_INDEXES: 1307117f1b4Smrg case MAT_ATTRIB_BACK_INDEXES: 13101e04c3fSmrg size = 3; 13201e04c3fSmrg break; 1337117f1b4Smrg default: 13401e04c3fSmrg size = 4; 13501e04c3fSmrg break; 1367117f1b4Smrg } 1377117f1b4Smrg 13801e04c3fSmrg init_array(ctx, attrib, size, ctx->Light.Material.Attrib[i]); 1397117f1b4Smrg } 1407117f1b4Smrg} 1417117f1b4Smrg 1427117f1b4Smrg 14301e04c3fSmrgvoid 14401e04c3fSmrg_vbo_install_exec_vtxfmt(struct gl_context *ctx) 14501e04c3fSmrg{ 14601e04c3fSmrg struct vbo_context *vbo = vbo_context(ctx); 14701e04c3fSmrg 14801e04c3fSmrg _mesa_install_exec_vtxfmt(ctx, &vbo->exec.vtxfmt); 14901e04c3fSmrg} 15001e04c3fSmrg 15101e04c3fSmrg 15201e04c3fSmrgvoid 1537ec681f3Smrgvbo_exec_update_eval_maps(struct gl_context *ctx) 15401e04c3fSmrg{ 15501e04c3fSmrg struct vbo_context *vbo = vbo_context(ctx); 15601e04c3fSmrg 1577ec681f3Smrg vbo->exec.eval.recalculate_maps = GL_TRUE; 15801e04c3fSmrg} 15901e04c3fSmrg 16001e04c3fSmrg 16101e04c3fSmrgGLboolean 1627ec681f3Smrg_vbo_CreateContext(struct gl_context *ctx, bool use_buffer_objects) 1637117f1b4Smrg{ 1647ec681f3Smrg struct vbo_context *vbo = &ctx->vbo_context; 1657117f1b4Smrg 1667ec681f3Smrg memset(vbo, 0, sizeof(*vbo)); 1677117f1b4Smrg 16801e04c3fSmrg vbo->binding.Offset = 0; 16901e04c3fSmrg vbo->binding.Stride = 0; 17001e04c3fSmrg vbo->binding.InstanceDivisor = 0; 1717ec681f3Smrg 17201e04c3fSmrg init_legacy_currval(ctx); 17301e04c3fSmrg init_generic_currval(ctx); 17401e04c3fSmrg init_mat_currval(ctx); 1757117f1b4Smrg 17601e04c3fSmrg /* make sure all VBO_ATTRIB_ values can fit in an unsigned byte */ 17701e04c3fSmrg STATIC_ASSERT(VBO_ATTRIB_MAX <= 255); 1787117f1b4Smrg 1797117f1b4Smrg /* Hook our functions into exec and compile dispatch tables. These 1807117f1b4Smrg * will pretty much be permanently installed, which means that the 1817117f1b4Smrg * vtxfmt mechanism can be removed now. 1827117f1b4Smrg */ 1837ec681f3Smrg vbo_exec_init(ctx, use_buffer_objects); 184af69d88dSmrg if (ctx->API == API_OPENGL_COMPAT) 18501e04c3fSmrg vbo_save_init(ctx); 18601e04c3fSmrg 18701e04c3fSmrg vbo->VAO = _mesa_new_vao(ctx, ~((GLuint)0)); 18801e04c3fSmrg /* The exec VAO assumes to have all arributes bound to binding 0 */ 18901e04c3fSmrg for (unsigned i = 0; i < VERT_ATTRIB_MAX; ++i) 19001e04c3fSmrg _mesa_vertex_attrib_binding(ctx, vbo->VAO, i, 0); 1917117f1b4Smrg 1924a49301eSmrg _math_init_eval(); 1934a49301eSmrg 1947117f1b4Smrg return GL_TRUE; 1957117f1b4Smrg} 1967117f1b4Smrg 197cdc920a0Smrg 19801e04c3fSmrgvoid 19901e04c3fSmrg_vbo_DestroyContext(struct gl_context *ctx) 2007117f1b4Smrg{ 2014a49301eSmrg struct vbo_context *vbo = vbo_context(ctx); 2024a49301eSmrg 2034a49301eSmrg if (vbo) { 20401e04c3fSmrg _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, NULL); 2054a49301eSmrg 2064a49301eSmrg vbo_exec_destroy(ctx); 207af69d88dSmrg if (ctx->API == API_OPENGL_COMPAT) 2083464ebd5Sriastradh vbo_save_destroy(ctx); 20901e04c3fSmrg _mesa_reference_vao(ctx, &vbo->VAO, NULL); 2104a49301eSmrg } 2114a49301eSmrg} 2124a49301eSmrg 2134a49301eSmrg 21401e04c3fSmrgconst struct gl_array_attributes * 21501e04c3fSmrg_vbo_current_attrib(const struct gl_context *ctx, gl_vert_attrib attr) 2164a49301eSmrg{ 21701e04c3fSmrg const struct vbo_context *vbo = vbo_context_const(ctx); 21801e04c3fSmrg const gl_vertex_processing_mode vmp = ctx->VertexProgram._VPMode; 21901e04c3fSmrg return &vbo->current[_vbo_attribute_alias_map[vmp][attr]]; 2207117f1b4Smrg} 2214a49301eSmrg 22201e04c3fSmrg 22301e04c3fSmrgconst struct gl_vertex_buffer_binding * 22401e04c3fSmrg_vbo_current_binding(const struct gl_context *ctx) 22501e04c3fSmrg{ 22601e04c3fSmrg const struct vbo_context *vbo = vbo_context_const(ctx); 22701e04c3fSmrg return &vbo->binding; 22801e04c3fSmrg} 229