1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Mesa 3-D graphics library
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
12bf215546Sopenharmony_ci *
13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
23bf215546Sopenharmony_ci *
24bf215546Sopenharmony_ci * Authors:
25bf215546Sopenharmony_ci *    Keith Whitwell <keithw@vmware.com>
26bf215546Sopenharmony_ci */
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "main/errors.h"
29bf215546Sopenharmony_ci#include "main/bufferobj.h"
30bf215546Sopenharmony_ci#include "math/m_eval.h"
31bf215546Sopenharmony_ci#include "main/api_arrayelt.h"
32bf215546Sopenharmony_ci#include "main/arrayobj.h"
33bf215546Sopenharmony_ci#include "main/varray.h"
34bf215546Sopenharmony_ci#include "util/u_memory.h"
35bf215546Sopenharmony_ci#include "vbo.h"
36bf215546Sopenharmony_ci#include "vbo_private.h"
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_cistatic GLuint
40bf215546Sopenharmony_cicheck_size(const GLfloat *attr)
41bf215546Sopenharmony_ci{
42bf215546Sopenharmony_ci   if (attr[3] != 1.0F)
43bf215546Sopenharmony_ci      return 4;
44bf215546Sopenharmony_ci   if (attr[2] != 0.0F)
45bf215546Sopenharmony_ci      return 3;
46bf215546Sopenharmony_ci   if (attr[1] != 0.0F)
47bf215546Sopenharmony_ci      return 2;
48bf215546Sopenharmony_ci   return 1;
49bf215546Sopenharmony_ci}
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci/**
53bf215546Sopenharmony_ci * Helper for initializing a vertex array.
54bf215546Sopenharmony_ci */
55bf215546Sopenharmony_cistatic void
56bf215546Sopenharmony_ciinit_array(struct gl_context *ctx, struct gl_array_attributes *attrib,
57bf215546Sopenharmony_ci           unsigned size, const void *pointer)
58bf215546Sopenharmony_ci{
59bf215546Sopenharmony_ci   memset(attrib, 0, sizeof(*attrib));
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci   vbo_set_vertex_format(&attrib->Format, size, GL_FLOAT);
62bf215546Sopenharmony_ci   attrib->Stride = 0;
63bf215546Sopenharmony_ci   attrib->Ptr = pointer;
64bf215546Sopenharmony_ci}
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_ci/**
68bf215546Sopenharmony_ci * Set up the vbo->currval arrays to point at the context's current
69bf215546Sopenharmony_ci * vertex attributes (with strides = 0).
70bf215546Sopenharmony_ci */
71bf215546Sopenharmony_cistatic void
72bf215546Sopenharmony_ciinit_legacy_currval(struct gl_context *ctx)
73bf215546Sopenharmony_ci{
74bf215546Sopenharmony_ci   struct vbo_context *vbo = vbo_context(ctx);
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   /* Set up a constant (Stride == 0) array for each current
77bf215546Sopenharmony_ci    * attribute:
78bf215546Sopenharmony_ci    */
79bf215546Sopenharmony_ci   for (int attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
80bf215546Sopenharmony_ci      if (VERT_BIT(attr) & VERT_BIT_GENERIC_ALL)
81bf215546Sopenharmony_ci         continue;
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci      struct gl_array_attributes *attrib = &vbo->current[attr];
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci      init_array(ctx, attrib, check_size(ctx->Current.Attrib[attr]),
86bf215546Sopenharmony_ci                 ctx->Current.Attrib[attr]);
87bf215546Sopenharmony_ci   }
88bf215546Sopenharmony_ci}
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_cistatic void
92bf215546Sopenharmony_ciinit_generic_currval(struct gl_context *ctx)
93bf215546Sopenharmony_ci{
94bf215546Sopenharmony_ci   struct vbo_context *vbo = vbo_context(ctx);
95bf215546Sopenharmony_ci   GLuint i;
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
98bf215546Sopenharmony_ci      const unsigned attr = VBO_ATTRIB_GENERIC0 + i;
99bf215546Sopenharmony_ci      struct gl_array_attributes *attrib = &vbo->current[attr];
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci      init_array(ctx, attrib, 1, ctx->Current.Attrib[attr]);
102bf215546Sopenharmony_ci   }
103bf215546Sopenharmony_ci}
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_cistatic void
107bf215546Sopenharmony_ciinit_mat_currval(struct gl_context *ctx)
108bf215546Sopenharmony_ci{
109bf215546Sopenharmony_ci   struct vbo_context *vbo = vbo_context(ctx);
110bf215546Sopenharmony_ci   GLuint i;
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   /* Set up a constant (StrideB == 0) array for each current
113bf215546Sopenharmony_ci    * attribute:
114bf215546Sopenharmony_ci    */
115bf215546Sopenharmony_ci   for (i = 0; i < MAT_ATTRIB_MAX; i++) {
116bf215546Sopenharmony_ci      const unsigned attr = VBO_ATTRIB_MAT_FRONT_AMBIENT + i;
117bf215546Sopenharmony_ci      struct gl_array_attributes *attrib = &vbo->current[attr];
118bf215546Sopenharmony_ci      unsigned size;
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci      /* Size is fixed for the material attributes, for others will
121bf215546Sopenharmony_ci       * be determined at runtime:
122bf215546Sopenharmony_ci       */
123bf215546Sopenharmony_ci      switch (i) {
124bf215546Sopenharmony_ci      case MAT_ATTRIB_FRONT_SHININESS:
125bf215546Sopenharmony_ci      case MAT_ATTRIB_BACK_SHININESS:
126bf215546Sopenharmony_ci         size = 1;
127bf215546Sopenharmony_ci         break;
128bf215546Sopenharmony_ci      case MAT_ATTRIB_FRONT_INDEXES:
129bf215546Sopenharmony_ci      case MAT_ATTRIB_BACK_INDEXES:
130bf215546Sopenharmony_ci         size = 3;
131bf215546Sopenharmony_ci         break;
132bf215546Sopenharmony_ci      default:
133bf215546Sopenharmony_ci         size = 4;
134bf215546Sopenharmony_ci         break;
135bf215546Sopenharmony_ci      }
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci      init_array(ctx, attrib, size, ctx->Light.Material.Attrib[i]);
138bf215546Sopenharmony_ci   }
139bf215546Sopenharmony_ci}
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_civoid
143bf215546Sopenharmony_civbo_exec_update_eval_maps(struct gl_context *ctx)
144bf215546Sopenharmony_ci{
145bf215546Sopenharmony_ci   struct vbo_context *vbo = vbo_context(ctx);
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci   vbo->exec.eval.recalculate_maps = GL_TRUE;
148bf215546Sopenharmony_ci}
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ciGLboolean
152bf215546Sopenharmony_ci_vbo_CreateContext(struct gl_context *ctx)
153bf215546Sopenharmony_ci{
154bf215546Sopenharmony_ci   struct vbo_context *vbo = &ctx->vbo_context;
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci   memset(vbo, 0, sizeof(*vbo));
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ci   init_legacy_currval(ctx);
159bf215546Sopenharmony_ci   init_generic_currval(ctx);
160bf215546Sopenharmony_ci   init_mat_currval(ctx);
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci   /* make sure all VBO_ATTRIB_ values can fit in an unsigned byte */
163bf215546Sopenharmony_ci   STATIC_ASSERT(VBO_ATTRIB_MAX <= 255);
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   /* Hook our functions into exec and compile dispatch tables.  These
166bf215546Sopenharmony_ci    * will pretty much be permanently installed, which means that the
167bf215546Sopenharmony_ci    * vtxfmt mechanism can be removed now.
168bf215546Sopenharmony_ci    */
169bf215546Sopenharmony_ci   vbo_exec_init(ctx);
170bf215546Sopenharmony_ci   if (ctx->API == API_OPENGL_COMPAT)
171bf215546Sopenharmony_ci      vbo_save_init(ctx);
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci   vbo->VAO = _mesa_new_vao(ctx, ~((GLuint)0));
174bf215546Sopenharmony_ci   /* The exec VAO assumes to have all arributes bound to binding 0 */
175bf215546Sopenharmony_ci   for (unsigned i = 0; i < VERT_ATTRIB_MAX; ++i)
176bf215546Sopenharmony_ci      _mesa_vertex_attrib_binding(ctx, vbo->VAO, i, 0);
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   _math_init_eval();
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci   return GL_TRUE;
181bf215546Sopenharmony_ci}
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_civoid
185bf215546Sopenharmony_ci_vbo_DestroyContext(struct gl_context *ctx)
186bf215546Sopenharmony_ci{
187bf215546Sopenharmony_ci   struct vbo_context *vbo = vbo_context(ctx);
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_ci   if (vbo) {
190bf215546Sopenharmony_ci      vbo_exec_destroy(ctx);
191bf215546Sopenharmony_ci      if (ctx->API == API_OPENGL_COMPAT)
192bf215546Sopenharmony_ci         vbo_save_destroy(ctx);
193bf215546Sopenharmony_ci      _mesa_reference_vao(ctx, &vbo->VAO, NULL);
194bf215546Sopenharmony_ci   }
195bf215546Sopenharmony_ci}
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_ciconst struct gl_array_attributes *
199bf215546Sopenharmony_ci_vbo_current_attrib(const struct gl_context *ctx, gl_vert_attrib attr)
200bf215546Sopenharmony_ci{
201bf215546Sopenharmony_ci   const struct vbo_context *vbo = vbo_context_const(ctx);
202bf215546Sopenharmony_ci   const gl_vertex_processing_mode vmp = ctx->VertexProgram._VPMode;
203bf215546Sopenharmony_ci   return &vbo->current[_vbo_attribute_alias_map[vmp][attr]];
204bf215546Sopenharmony_ci}
205