1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.3
4  *
5  * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Keith Whitwell <keith@tungstengraphics.com>
26  */
27 
28 #include "main/imports.h"
29 #include "main/mtypes.h"
30 #include "main/api_arrayelt.h"
31 #include "main/bufferobj.h"
32 #include "math/m_eval.h"
33 #include "vbo.h"
34 #include "vbo_context.h"
35 
36 #define NR_MAT_ATTRIBS 12
37 
check_size(const GLfloat * attr)38 static GLuint check_size( const GLfloat *attr )
39 {
40    if (attr[3] != 1.0) return 4;
41    if (attr[2] != 0.0) return 3;
42    if (attr[1] != 0.0) return 2;
43    return 1;
44 }
45 
46 
init_legacy_currval(struct gl_context * ctx)47 static void init_legacy_currval(struct gl_context *ctx)
48 {
49    struct vbo_context *vbo = vbo_context(ctx);
50    struct gl_client_array *arrays = &vbo->currval[VBO_ATTRIB_POS];
51    GLuint i;
52 
53    memset(arrays, 0, sizeof(*arrays) * VERT_ATTRIB_FF_MAX);
54 
55    /* Set up a constant (StrideB == 0) array for each current
56     * attribute:
57     */
58    for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
59       struct gl_client_array *cl = &arrays[i];
60 
61       /* Size will have to be determined at runtime:
62        */
63       cl->Size = check_size(ctx->Current.Attrib[i]);
64       cl->Stride = 0;
65       cl->StrideB = 0;
66       cl->Enabled = 1;
67       cl->Type = GL_FLOAT;
68       cl->Format = GL_RGBA;
69       cl->Ptr = (const void *)ctx->Current.Attrib[i];
70       cl->_ElementSize = cl->Size * sizeof(GLfloat);
71       _mesa_reference_buffer_object(ctx, &cl->BufferObj,
72                                     ctx->Shared->NullBufferObj);
73    }
74 }
75 
76 
init_generic_currval(struct gl_context * ctx)77 static void init_generic_currval(struct gl_context *ctx)
78 {
79    struct vbo_context *vbo = vbo_context(ctx);
80    struct gl_client_array *arrays = &vbo->currval[VBO_ATTRIB_GENERIC0];
81    GLuint i;
82 
83    memset(arrays, 0, sizeof(*arrays) * VERT_ATTRIB_GENERIC_MAX);
84 
85    for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
86       struct gl_client_array *cl = &arrays[i];
87 
88       /* This will have to be determined at runtime:
89        */
90       cl->Size = 1;
91       cl->Type = GL_FLOAT;
92       cl->Format = GL_RGBA;
93       cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i];
94       cl->Stride = 0;
95       cl->StrideB = 0;
96       cl->Enabled = 1;
97       cl->_ElementSize = cl->Size * sizeof(GLfloat);
98       _mesa_reference_buffer_object(ctx, &cl->BufferObj,
99                                     ctx->Shared->NullBufferObj);
100    }
101 }
102 
103 
init_mat_currval(struct gl_context * ctx)104 static void init_mat_currval(struct gl_context *ctx)
105 {
106    struct vbo_context *vbo = vbo_context(ctx);
107    struct gl_client_array *arrays =
108       &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT];
109    GLuint i;
110 
111    ASSERT(NR_MAT_ATTRIBS == MAT_ATTRIB_MAX);
112 
113    memset(arrays, 0, sizeof(*arrays) * NR_MAT_ATTRIBS);
114 
115    /* Set up a constant (StrideB == 0) array for each current
116     * attribute:
117     */
118    for (i = 0; i < NR_MAT_ATTRIBS; i++) {
119       struct gl_client_array *cl = &arrays[i];
120 
121       /* Size is fixed for the material attributes, for others will
122        * be determined at runtime:
123        */
124       switch (i - VERT_ATTRIB_GENERIC0) {
125       case MAT_ATTRIB_FRONT_SHININESS:
126       case MAT_ATTRIB_BACK_SHININESS:
127 	 cl->Size = 1;
128 	 break;
129       case MAT_ATTRIB_FRONT_INDEXES:
130       case MAT_ATTRIB_BACK_INDEXES:
131 	 cl->Size = 3;
132 	 break;
133       default:
134 	 cl->Size = 4;
135 	 break;
136       }
137 
138       cl->Ptr = (const void *)ctx->Light.Material.Attrib[i];
139       cl->Type = GL_FLOAT;
140       cl->Format = GL_RGBA;
141       cl->Stride = 0;
142       cl->StrideB = 0;
143       cl->Enabled = 1;
144       cl->_ElementSize = cl->Size * sizeof(GLfloat);
145       _mesa_reference_buffer_object(ctx, &cl->BufferObj,
146                                     ctx->Shared->NullBufferObj);
147    }
148 }
149 
150 
_vbo_CreateContext(struct gl_context * ctx)151 GLboolean _vbo_CreateContext( struct gl_context *ctx )
152 {
153    struct vbo_context *vbo = CALLOC_STRUCT(vbo_context);
154 
155    ctx->swtnl_im = (void *)vbo;
156 
157    /* Initialize the arrayelt helper
158     */
159    if (!ctx->aelt_context &&
160        !_ae_create_context( ctx )) {
161       return GL_FALSE;
162    }
163 
164    init_legacy_currval( ctx );
165    init_generic_currval( ctx );
166    init_mat_currval( ctx );
167 
168    /* Build mappings from VERT_ATTRIB -> VBO_ATTRIB depending on type
169     * of vertex program active.
170     */
171    {
172       GLuint i;
173 
174       /* identity mapping */
175       for (i = 0; i < Elements(vbo->map_vp_none); i++)
176 	 vbo->map_vp_none[i] = i;
177       /* map material attribs to generic slots */
178       for (i = 0; i < NR_MAT_ATTRIBS; i++)
179 	 vbo->map_vp_none[VERT_ATTRIB_GENERIC(i)]
180             = VBO_ATTRIB_MAT_FRONT_AMBIENT + i;
181 
182       for (i = 0; i < Elements(vbo->map_vp_arb); i++)
183 	 vbo->map_vp_arb[i] = i;
184    }
185 
186 
187    /* Hook our functions into exec and compile dispatch tables.  These
188     * will pretty much be permanently installed, which means that the
189     * vtxfmt mechanism can be removed now.
190     */
191    vbo_exec_init( ctx );
192    if (ctx->API == API_OPENGL)
193       vbo_save_init( ctx );
194 
195    _math_init_eval();
196 
197    return GL_TRUE;
198 }
199 
200 
_vbo_InvalidateState(struct gl_context * ctx,GLuint new_state)201 void _vbo_InvalidateState( struct gl_context *ctx, GLuint new_state )
202 {
203    vbo_exec_invalidate_state(ctx, new_state);
204 }
205 
206 
_vbo_DestroyContext(struct gl_context * ctx)207 void _vbo_DestroyContext( struct gl_context *ctx )
208 {
209    struct vbo_context *vbo = vbo_context(ctx);
210 
211    if (ctx->aelt_context) {
212       _ae_destroy_context( ctx );
213       ctx->aelt_context = NULL;
214    }
215 
216    if (vbo) {
217       GLuint i;
218 
219       for (i = 0; i < VBO_ATTRIB_MAX; i++) {
220          _mesa_reference_buffer_object(ctx, &vbo->currval[i].BufferObj, NULL);
221       }
222 
223       vbo_exec_destroy(ctx);
224       if (ctx->API == API_OPENGL)
225          vbo_save_destroy(ctx);
226       FREE(vbo);
227       ctx->swtnl_im = NULL;
228    }
229 }
230 
231 
vbo_set_draw_func(struct gl_context * ctx,vbo_draw_func func)232 void vbo_set_draw_func(struct gl_context *ctx, vbo_draw_func func)
233 {
234    struct vbo_context *vbo = vbo_context(ctx);
235    vbo->draw_prims = func;
236 }
237 
238