xref: /third_party/mesa3d/src/mesa/vbo/vbo_context.c (revision bf215546)
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