source: trunk/src/opengl/mesa/cva.c

Last change on this file was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 22.2 KB
RevLine 
[3598]1/* $Id: cva.c,v 1.2 2000-05-23 20:40:27 jeroen Exp $ */
[2938]2
3/*
4 * Mesa 3-D graphics library
[3598]5 * Version: 3.3
[2938]6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27/* Mesa CVA implementation.
28 * Copyright (C) 1999 Keith Whitwell
29 */
30
[3598]31#include "glheader.h"
[2938]32#include "types.h"
33#include "cva.h"
[3598]34#include "mem.h"
[2938]35#include "context.h"
36#include "macros.h"
37#include "pipeline.h"
38#include "varray.h"
39#include "vbcull.h"
40#include "vbrender.h"
41#include "vbxform.h"
42#include "vector.h"
43
44/* Mesa CVA implementation.
45 * Copyright (C) 1999 Keith Whitwell
46 */
47
48static void copy_clipmask( GLubyte *dest, GLubyte *ormask, GLubyte *andmask,
49 const GLubyte *src,
50 const GLuint *elt, GLuint nr )
51{
52 GLuint i;
53 GLubyte o = *ormask;
54 GLubyte a = *andmask;
55
56 for (i = 0 ; i < nr ; i++) {
57 GLubyte t = src[elt[i]];
58 dest[i] = t;
59 o |= t;
60 a &= t;
61 }
62
63 *ormask = o;
64 *andmask = a;
65}
66
67static void translate_4f( GLvector4f *dest,
[3598]68 CONST GLvector4f *src,
69 CONST GLuint elt[],
70 GLuint nr )
[2938]71{
72 GLuint i;
73 GLfloat (*from)[4] = (GLfloat (*)[4])src->start;
74 GLfloat (*to)[4] = (GLfloat (*)[4])dest->start;
75 GLuint stride = src->stride;
76
77 if (stride == 4 * sizeof(GLfloat)) {
78 for (i = 0 ; i < nr ; i++)
[3598]79 COPY_4FV( to[i], from[elt[i]] );
[2938]80 } else {
81 for (i = 0 ; i < nr ; i++) {
[3598]82 CONST GLubyte *f = (GLubyte *)from + elt[i] * stride;
83 COPY_4FV( to[i], (GLfloat *)f );
[2938]84 }
85 }
86
87 dest->size = src->size;
88 dest->flags |= (src->flags & VEC_SIZE_4);
89 dest->count = nr;
90}
91
92static void translate_3f( GLvector3f *dest,
[3598]93 CONST GLvector3f *src,
94 CONST GLuint elt[],
95 GLuint nr )
[2938]96{
97 GLuint i;
98 GLfloat (*from)[3] = (GLfloat (*)[3])src->start;
99 GLfloat (*to)[3] = (GLfloat (*)[3])dest->start;
100 GLuint stride = src->stride;
101
102 if (stride == 3 * sizeof(GLfloat)) {
103 for (i = 0 ; i < nr ; i++)
[3598]104 COPY_3FV( to[i], from[elt[i]] );
[2938]105 } else {
106 for (i = 0 ; i < nr ; i++) {
[3598]107 CONST GLubyte *f = (GLubyte *)from + elt[i] * stride;
108 COPY_3FV( to[i], (GLfloat *)f );
[2938]109 }
110 }
111
112 dest->count = nr;
113}
114
115static void translate_4ub( GLvector4ub *dest,
[3598]116 CONST GLvector4ub *src,
117 GLuint elt[],
118 GLuint nr )
[2938]119{
120 GLuint i;
121 GLubyte (*from)[4] = (GLubyte (*)[4])src->start;
122 GLubyte (*to)[4] = (GLubyte (*)[4])dest->start;
123 GLuint stride = src->stride;
124
125 if (stride == 4 * sizeof(GLubyte)) {
126 for (i = 0 ; i < nr ; i++)
[3598]127 COPY_4UBV( to[i], from[elt[i]]);
[2938]128 } else {
129 for (i = 0 ; i < nr ; i++) {
[3598]130 CONST GLubyte *f = (GLubyte *)from + elt[i] * stride;
131 COPY_4UBV( to[i], f );
[2938]132 }
133 }
134
135 dest->count = nr;
136}
137
138static void translate_1ui( GLvector1ui *dest,
[3598]139 GLvector1ui *src,
140 GLuint elt[],
141 GLuint nr )
[2938]142{
143 GLuint i;
144 GLuint *from = src->start;
145 GLuint *to = dest->start;
146 GLuint stride = src->stride;
147
148 if (stride == sizeof(GLuint)) {
149 for (i = 0 ; i < nr ; i++)
[3598]150 to[i] = from[elt[i]];
[2938]151 } else {
152 for (i = 0 ; i < nr ; i++) {
[3598]153 CONST GLubyte *f = (GLubyte *)from + elt[i] * stride;
154 to[i] = *(GLuint *)f;
[2938]155 }
156 }
157
158 dest->count = nr;
159}
160
161static void translate_1ub( GLvector1ub *dest,
[3598]162 GLvector1ub *src,
163 GLuint elt[],
164 GLuint nr )
[2938]165{
166 GLuint i;
167 GLubyte *from = src->start;
168 GLubyte *to = dest->start;
169 GLuint stride = src->stride;
170
171 if (stride == sizeof(GLubyte)) {
172 for (i = 0 ; i < nr ; i++)
[3598]173 to[i] = from[elt[i]];
[2938]174 } else {
175 for (i = 0 ; i < nr ; i++) {
[3598]176 CONST GLubyte *f = from + elt[i] * stride;
177 to[i] = *f;
[2938]178 }
179 }
180
181 dest->count = nr;
182}
183
184
185/* The fallback case for handling the merge of cva and immediate
186 * data. This code back-copies data from cva->immediate to build a
187 * normal looking immediate struct, which is then sent off to the
188 * old raster setup and render routines.
189 *
190 * The FX driver implements a replacement for this step which merges
191 * the new data into the already prepared GrVertex structs.
192 *
193 * When there is no data to merge, gl_render_vb_indirect is called
194 * instead.
195 */
196void gl_merge_cva( struct vertex_buffer *VB,
[3598]197 struct vertex_buffer *cvaVB )
[2938]198{
199 GLcontext *ctx = VB->ctx;
200 GLuint *elt = VB->EltPtr->start;
201 GLuint count = VB->Count - VB->Start;
202 GLuint available = ctx->CVA.pre.outputs | ctx->Array.Summary;
203 GLuint required = ctx->CVA.elt.inputs;
204 GLuint flags;
205
206 /* Should attempt to build an or-flag of reduced (ie rasterization)
207 * prims in the VB, so a software points function doesn't screw us
208 * when we're doing hardware triangles.
209 */
210 if ((required & VERT_SETUP_FULL) &&
211 (ctx->IndirectTriangles & DD_SW_SETUP))
212 {
213 if (MESA_VERBOSE & VERBOSE_PIPELINE)
[3598]214 gl_print_vert_flags("extra flags for setup",
215 ctx->RenderFlags & available & ~required);
[2938]216 required |= ctx->RenderFlags;
217 }
218
219 flags = required & available;
220
221 if ((flags & VERT_DATA) == 0)
222 return;
223
224 if (MESA_VERBOSE&VERBOSE_PIPELINE)
225 gl_print_vert_flags("cva merge", flags);
226
227 if (flags & VERT_WIN) {
228 VB->ClipPtr = &VB->Clip;
229 VB->Projected = &VB->Win;
230 VB->CullMode = 0;
231
232 if (cvaVB->ClipOrMask) {
233
[3598]234 /* Copy clipmask back into VB, build a new clipOrMask */
235 copy_clipmask( VB->ClipMask + VB->Start,
236 &VB->ClipOrMask, &VB->ClipAndMask,
237 cvaVB->ClipMask,
238 elt,
239 VB->Count - VB->Start );
[2938]240
[3598]241 /* overkill if !VB->ClipOrMask - should just copy 'copied' verts */
242 translate_4f( VB->ClipPtr, cvaVB->ClipPtr, elt, count);
[2938]243
[3598]244 if (VB->ClipOrMask & CLIP_USER_BIT) {
245 GLubyte or = 0, and = ~0;
[2938]246
[3598]247 copy_clipmask( VB->UserClipMask + VB->Start,
248 &or, &and,
249 cvaVB->UserClipMask,
250 elt,
251 VB->Count - VB->Start);
[2938]252
[3598]253 if (and) VB->ClipAndMask |= CLIP_USER_BIT;
254 }
255
256 if (VB->ClipOrMask)
257 VB->CullMode |= CLIP_MASK_ACTIVE;
258
259 if (VB->ClipAndMask) {
260 VB->Culled = 1;
261 gl_dont_cull_vb( VB );
262 return;
263 }
[2938]264 }
265
266 translate_4f( &VB->Win, &cvaVB->Win, elt, count );
267
268 /* Can't be precomputed - but may be wasteful to do this now.
269 */
270 if (ctx->IndirectTriangles & DD_ANY_CULL)
271 {
[3598]272 GLuint cullcount = gl_cull_vb( VB );
273 if (cullcount) VB->CullMode |= CULL_MASK_ACTIVE;
274 if (cullcount == VB->Count) { VB->Culled = 2 ; return; }
[2938]275 }
276 else
[3598]277 gl_dont_cull_vb( VB );
[2938]278 } else {
279 VB->ClipPtr = &VB->Clip;
280 VB->Projected = &VB->Win;
281 }
282
283 if (flags & VERT_EYE)
284 {
285 VB->Unprojected = VB->EyePtr = &VB->Eye;
286 translate_4f( VB->EyePtr, cvaVB->EyePtr, elt, count);
287 }
288
289 if (flags & VERT_OBJ_ANY)
290 {
291 VB->ObjPtr = &VB->IM->v.Obj;
292 if (!ctx->NeedEyeCoords) VB->Unprojected = VB->ObjPtr;
293 translate_4f( VB->ObjPtr, cvaVB->ObjPtr, elt, count);
294 }
295
296 if (flags & VERT_NORM)
297 {
298 VB->NormalPtr = &VB->IM->v.Normal;
299 translate_3f( VB->NormalPtr, cvaVB->NormalPtr, elt, count );
300 VB->CullMode &= ~COMPACTED_NORMALS;
301 }
302
303 if (flags & VERT_RGBA)
304 {
305 VB->ColorPtr = VB->Color[0] = VB->LitColor[0];
306 translate_4ub( VB->Color[0], cvaVB->Color[0], elt, count );
307
308 if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
[3598]309 VB->Color[1] = VB->LitColor[1];
310 translate_4ub( VB->Color[1], cvaVB->Color[1], elt, count );
[2938]311 }
312 }
313
314 if (flags & VERT_INDEX)
315 {
316 VB->IndexPtr = VB->Index[0] = VB->LitIndex[0];
317 translate_1ui( VB->Index[0], cvaVB->Index[0], elt, count );
318
319 if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
[3598]320 VB->Index[1] = VB->LitIndex[1];
321 translate_1ui( VB->Index[1], cvaVB->Index[1], elt, count );
[2938]322 }
323 }
324
325 if (flags & VERT_EDGE)
326 {
327 VB->EdgeFlagPtr = &VB->IM->v.EdgeFlag;
328 translate_1ub( VB->EdgeFlagPtr, cvaVB->EdgeFlagPtr, elt, count );
329 }
330
331 if (flags & VERT_TEX0_ANY)
332 {
333 VB->TexCoordPtr[0] = &VB->IM->v.TexCoord[0];
334 translate_4f( VB->TexCoordPtr[0], cvaVB->TexCoordPtr[0], elt, count);
335 }
336
337 if (flags & VERT_TEX1_ANY)
338 {
339 VB->TexCoordPtr[1] = &VB->IM->v.TexCoord[1];
340 translate_4f( VB->TexCoordPtr[1], cvaVB->TexCoordPtr[1], elt, count);
341 }
342}
343
344
345
346
347/* We don't have a good mechanism for dealing with the situation where
348 * cva is 'abandoned' midway through a vertex buffer, or indeed any mixing
349 * of cva & standard data in a single immediate struct.
350 *
351 * Basically just abandon CVA even though the precalced data
352 * is already there.
353 */
354void gl_rescue_cva( GLcontext *ctx, struct immediate *IM )
355{
356 struct vertex_buffer *VB = ctx->VB;
357
358 IM->Start = VB->CopyStart;
359
360 ctx->CompileCVAFlag = 0;
361 gl_build_immediate_pipeline( ctx );
362 gl_exec_array_elements( ctx, IM, IM->Start, IM->Count );
363}
364
365
366
367
368
369/* Transform the array components now, upto the setup call. When
370 * actual draw commands arrive, the data will be merged prior to
371 * calling render_vb.
372 */
[3598]373void
374_mesa_LockArraysEXT(GLint first, GLsizei count)
[2938]375{
[3598]376 GET_CURRENT_CONTEXT(ctx);
[2938]377 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "unlock arrays" );
378
379 if (MESA_VERBOSE & VERBOSE_API)
380 fprintf(stderr, "glLockArrays %d %d\n", first, count);
381
382 /* Can't mix locked & unlocked - if count is too large, just
383 * unlock.
384 */
385 if (first == 0 &&
386 count > 0 &&
387 count <= ctx->Const.MaxArrayLockSize)
388 {
389 struct gl_cva *cva = &ctx->CVA;
390
391 if (!ctx->Array.LockCount) {
[3598]392 ctx->Array.NewArrayState = ~0;
393 ctx->CVA.lock_changed ^= 1;
394 ctx->NewState |= NEW_CLIENT_STATE;
[2938]395 }
396
397 ctx->Array.LockFirst = first;
398 ctx->Array.LockCount = count;
399 ctx->CompileCVAFlag = !ctx->CompileFlag;
400
401 if (!cva->VB) {
[3598]402 cva->VB = gl_vb_create_for_cva( ctx, ctx->Const.MaxArrayLockSize );
403 gl_alloc_cva_store( cva, cva->VB->Size );
404 gl_reset_cva_vb( cva->VB, ~0 );
[2938]405 }
406 }
407 else
408 {
409 if (ctx->Array.LockCount) {
[3598]410 ctx->CVA.lock_changed ^= 1;
411 ctx->NewState |= NEW_CLIENT_STATE;
[2938]412 }
413
414
415 ctx->Array.LockFirst = 0;
416 ctx->Array.LockCount = 0;
417 ctx->CompileCVAFlag = 0;
418 }
419}
420
421
422
423
[3598]424void
425_mesa_UnlockArraysEXT( void )
[2938]426{
[3598]427 GET_CURRENT_CONTEXT(ctx);
[2938]428 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "unlock arrays" );
429
430 if (MESA_VERBOSE & VERBOSE_API)
431 fprintf(stderr, "glUnlockArrays\n");
432
433 if (ctx->Array.LockCount) {
434 ctx->CVA.lock_changed ^= 1;
435 ctx->NewState |= NEW_CLIENT_STATE;
436 }
437
438 ctx->Array.LockFirst = 0;
439 ctx->Array.LockCount = 0;
440 ctx->CompileCVAFlag = 0;
441}
442
443
444/* This storage used to hold translated client data if type or stride
445 * need to be fixed.
446 */
447void gl_alloc_cva_store( struct gl_cva *cva, GLuint size )
448{
449 cva->store.Obj = (GLfloat (*)[4])MALLOC( sizeof(GLfloat) * 4 * size );
450 cva->store.Normal = (GLfloat (*)[3])MALLOC( sizeof(GLfloat) * 3 * size );
451 cva->store.Color = (GLubyte (*)[4])MALLOC( sizeof(GLubyte) * 4 * size );
452 cva->store.EdgeFlag = (GLubyte *)MALLOC( sizeof(GLubyte) * size );
453 cva->store.Index = (GLuint *)MALLOC( sizeof(GLuint) * size );
454 cva->store.TexCoord[0] = (GLfloat (*)[4])MALLOC( sizeof(GLfloat) * 4 * size);
455 cva->store.TexCoord[1] = (GLfloat (*)[4])MALLOC( sizeof(GLfloat) * 4 * size);
456 cva->store.Elt = (GLuint *)MALLOC( sizeof(GLuint) * size );
457 cva->elt_size = size;
458}
459
460void gl_free_cva_store( struct gl_cva *cva )
461{
462 FREE( cva->store.Obj );
463 FREE( cva->store.Normal );
464 FREE( cva->store.Color );
465 FREE( cva->store.EdgeFlag );
466 FREE( cva->store.Index );
467 FREE( cva->store.TexCoord[0] );
468 FREE( cva->store.TexCoord[1] );
469 FREE( cva->store.Elt );
470}
471
472
473void gl_prepare_arrays_cva( struct vertex_buffer *VB )
474{
475 GLcontext *ctx = VB->ctx;
476 struct gl_cva *cva = &ctx->CVA;
477 GLuint start = ctx->Array.LockFirst;
478 GLuint n = ctx->Array.LockCount;
479 GLuint enable = ((ctx->Array.NewArrayState & ctx->Array.Summary) |
[3598]480 VB->pipeline->fallback);
[2938]481 GLuint disable = ctx->Array.NewArrayState & ~enable;
482 GLuint i;
483
484 if (MESA_VERBOSE&VERBOSE_PIPELINE) {
485 gl_print_vert_flags("*** ENABLE", enable);
486 gl_print_vert_flags("*** DISABLE", disable);
487 }
488
489 if (enable)
490 {
491 struct gl_client_array *client_data;
492 GLuint fallback = VB->pipeline->fallback;
493
494 if (enable & VERT_ELT)
495 {
[3598]496 GLvector1ui *elt = VB->EltPtr = &cva->v.Elt;
[2938]497
[3598]498 if (cva->Elt.Type == GL_UNSIGNED_INT)
499 {
500 elt->data = (GLuint *) cva->Elt.Ptr;
501 elt->stride = sizeof(GLuint);
502 elt->flags = 0;
503 } else {
504 elt->data = cva->store.Elt;
505 elt->stride = sizeof(GLuint);
[2938]506
[3598]507 if (cva->elt_count > cva->elt_size)
508 {
509 while (cva->elt_count > (cva->elt_size *= 2)) {};
510 FREE(cva->store.Elt);
511 cva->store.Elt = (GLuint *) MALLOC(cva->elt_size *
512 sizeof(GLuint));
513 }
514 cva->EltFunc( elt->data, &cva->Elt, 0, cva->elt_count );
515 }
516 elt->start = VEC_ELT(elt, GLuint, 0);
517 elt->count = cva->elt_count;
[2938]518
[3598]519 fallback |= (cva->pre.new_inputs & ~ctx->Array.Summary);
520 enable |= fallback;
521 disable &= ~fallback;
522 if (MESA_VERBOSE&VERBOSE_PIPELINE) {
523 gl_print_vert_flags("*** NEW INPUTS", cva->pre.new_inputs);
524 gl_print_vert_flags("*** FALLBACK", fallback);
525 }
[2938]526 }
527
528 if (enable & VERT_RGBA)
529 {
[3598]530 GLvector4ub *col = &cva->v.Color;
[2938]531
[3598]532 client_data = &ctx->Array.Color;
533 if (fallback & VERT_RGBA) client_data = &ctx->Fallback.Color;
[2938]534
[3598]535 VB->Color[0] = VB->Color[1] = VB->ColorPtr = &cva->v.Color;
[2938]536
[3598]537 if (client_data->Type != GL_UNSIGNED_BYTE ||
538 client_data->Size != 4)
539 {
540 col->data = cva->store.Color;
541 col->stride = 4 * sizeof(GLubyte);
542 ctx->Array.ColorFunc( col->data, client_data, start, n );
543 col->flags = VEC_WRITABLE|VEC_GOOD_STRIDE;
544 } else {
545 col->data = (GLubyte (*)[4]) client_data->Ptr;
546 col->stride = client_data->StrideB;
547 col->flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
548 if (client_data->StrideB != 4 * sizeof(GLubyte))
549 col->flags ^= VEC_STRIDE_FLAGS;
550 }
551 col->start = VEC_ELT(col, GLubyte, start);
552 col->count = n;
[2938]553 }
554
555 if (enable & VERT_INDEX)
556 {
[3598]557 GLvector1ui *index = VB->IndexPtr = &cva->v.Index;
558 VB->Index[0] = VB->Index[1] = VB->IndexPtr;
[2938]559
[3598]560 client_data = &ctx->Array.Index;
561 if (fallback & VERT_INDEX) client_data = &ctx->Fallback.Index;
[2938]562
[3598]563 if (client_data->Type != GL_UNSIGNED_INT)
564 {
565 index->data = cva->store.Index;
566 index->stride = sizeof(GLuint);
567 ctx->Array.IndexFunc( index->data, client_data, start, n );
568 index->flags = VEC_WRITABLE|VEC_GOOD_STRIDE;
569 } else {
570 index->data = (GLuint *) client_data->Ptr;
571 index->stride = client_data->StrideB;
572 index->flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
573 if (index->stride != sizeof(GLuint))
574 index->flags ^= VEC_STRIDE_FLAGS;
575 }
576 index->count = n;
577 index->start = VEC_ELT(index, GLuint, start);
[2938]578 }
579
580 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
[3598]581 if (enable & PIPE_TEX(i)) {
582 GLvector4f *tc = VB->TexCoordPtr[i] = &cva->v.TexCoord[i];
[2938]583
[3598]584 client_data = &ctx->Array.TexCoord[i];
[2938]585
[3598]586 if (fallback & PIPE_TEX(i)) {
587 client_data = &ctx->Fallback.TexCoord[i];
588 client_data->Size = gl_texcoord_size( ctx->Current.Flag, i );
589 }
[2938]590
[3598]591 /* Writeability and stride handled lazily by
592 * gl_import_client_data().
593 */
594 if (client_data->Type == GL_FLOAT)
595 {
596 tc->data = (GLfloat (*)[4]) client_data->Ptr;
597 tc->stride = client_data->StrideB;
598 tc->flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
599 if (tc->stride != 4 * sizeof(GLfloat))
600 tc->flags ^= VEC_STRIDE_FLAGS;
601 } else {
602 tc->data = cva->store.TexCoord[i];
603 tc->stride = 4 * sizeof(GLfloat);
604 ctx->Array.TexCoordFunc[i]( tc->data, client_data, start, n );
605 tc->flags = VEC_WRITABLE|VEC_GOOD_STRIDE;
606 }
607 tc->count = n;
608 tc->start = VEC_ELT(tc, GLfloat, start);
609 tc->size = client_data->Size;
610 }
[2938]611
612 if (enable & VERT_OBJ_ANY)
613 {
[3598]614 GLvector4f *obj = VB->ObjPtr = &cva->v.Obj;
[2938]615
[3598]616 if (ctx->Array.Vertex.Type == GL_FLOAT)
617 {
618 obj->data = (GLfloat (*)[4]) ctx->Array.Vertex.Ptr;
619 obj->stride = ctx->Array.Vertex.StrideB;
620 obj->flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
621 if (obj->stride != 4 * sizeof(GLfloat))
622 obj->flags ^= VEC_STRIDE_FLAGS;
623 } else {
624 obj->data = cva->store.Obj;
625 obj->stride = 4 * sizeof(GLfloat);
626 ctx->Array.VertexFunc( obj->data, &ctx->Array.Vertex, start, n );
627 obj->flags = VEC_WRITABLE|VEC_GOOD_STRIDE;
628 }
629 obj->count = n;
630 obj->start = VEC_ELT(obj, GLfloat, start);
631 obj->size = ctx->Array.Vertex.Size;
[2938]632 }
633
634 if (enable & VERT_NORM)
635 {
[3598]636 GLvector3f *norm = VB->NormalPtr = &cva->v.Normal;
[2938]637
[3598]638 client_data = &ctx->Array.Normal;
[2938]639
[3598]640 if (fallback & VERT_NORM)
641 client_data = &ctx->Fallback.Normal;
[2938]642
[3598]643 /* Never need to write to normals, and we can always cope with stride.
644 */
645 if (client_data->Type == GL_FLOAT) {
646 norm->data = (GLfloat (*)[3]) client_data->Ptr;
647 norm->stride = client_data->StrideB;
648 } else {
649 norm->data = cva->store.Normal;
650 norm->stride = 3 * sizeof(GLfloat);
651 ctx->Array.NormalFunc( norm->data, client_data, start, n );
652 }
653 norm->flags = 0;
654 norm->count = n;
655 norm->start = VEC_ELT(norm, GLfloat, start);
[2938]656 }
657
658 if (enable & VERT_EDGE)
659 {
[3598]660 GLvector1ub *edge = VB->EdgeFlagPtr = &cva->v.EdgeFlag;
[2938]661
[3598]662 client_data = &ctx->Array.EdgeFlag;
[2938]663
[3598]664 if (fallback & VERT_EDGE)
665 client_data = &ctx->Fallback.EdgeFlag;
[2938]666
[3598]667 edge->data = (GLboolean *) client_data->Ptr;
668 edge->stride = client_data->StrideB;
669 edge->flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
670 if (edge->stride != sizeof(GLubyte))
671 edge->flags ^= VEC_STRIDE_FLAGS;
[2938]672
[3598]673 edge->count = n;
674 edge->start = VEC_ELT(edge, GLubyte, start);
[2938]675 }
676 }
677
678 if (disable) {
679 if (disable & VERT_RGBA) cva->v.Color = *VB->LitColor[0];
680 if (disable & VERT_INDEX) cva->v.Index = *VB->LitIndex[0];
681 if (disable & VERT_NORM) cva->v.Normal = *VB->store.Normal;
682 if (disable & VERT_OBJ_ANY) cva->v.Obj = *VB->store.Obj;
683 if (disable & VERT_TEX0_ANY) cva->v.TexCoord[0]= *(VB->store.TexCoord[0]);
684 if (disable & VERT_TEX0_ANY) cva->v.TexCoord[1]= *(VB->store.TexCoord[1]);
685 if (disable & VERT_EDGE) cva->v.EdgeFlag = *VB->store.EdgeFlag;
686 }
687
688 VB->Flag[VB->Count] &= ~VERT_END_VB;
689 VB->Count = n;
[3598]690
[2938]691 if (ctx->Enabled & ENABLE_LIGHT)
692 {
693 if (ctx->Array.Flags != VB->Flag[0])
[3598]694 VB->FlagMax = 0;
[2938]695
696 if (VB->FlagMax < n) {
[3598]697 for (i = VB->FlagMax ; i < n ; i++)
698 VB->Flag[i] = ctx->Array.Flags;
699 VB->Flag[i] = 0;
700 VB->FlagMax = n;
[2938]701 }
702
703 VB->Flag[n] |= VERT_END_VB;
704 }
705}
706
707void gl_cva_force_precalc( GLcontext *ctx )
708{
709 struct gl_cva *cva = &ctx->CVA;
710
711 if (cva->pre.changed_ops)
712 gl_reset_cva_vb( cva->VB, cva->pre.changed_ops );
713
714 gl_run_pipeline( cva->VB );
715
716 ctx->Array.NewArrayState = 0;
717}
718
719
720/* Simplified: just make sure the pipelines are valid.
721 */
722void gl_cva_compile_cassette( GLcontext *ctx, struct immediate *IM )
723{
724 struct gl_cva *cva = &ctx->CVA;
725 cva->orflag |= IM->OrFlag;
726
727 /* Allow pipeline recalculation based on inputs received from client.
728 */
729 if (IM->OrFlag & (cva->pre.forbidden_inputs|cva->elt.forbidden_inputs))
730 {
731 if (IM->OrFlag & cva->pre.forbidden_inputs)
732 {
[3598]733 cva->pre.pipeline_valid = 0;
734 cva->pre.data_valid = 0;
735 cva->pre.forbidden_inputs = 0;
[2938]736 }
737
738 if ((IM->OrFlag & cva->elt.forbidden_inputs))
739 {
[3598]740 cva->elt.forbidden_inputs = 0;
[2938]741 }
742
743 cva->elt.pipeline_valid = 0;
744 }
745
746 /* Recalculate CVA data if necessary.
747 */
748 if (ctx->CompileCVAFlag && !cva->pre.data_valid)
749 {
750 if (!cva->pre.pipeline_valid)
[3598]751 gl_build_precalc_pipeline( ctx );
[2938]752
753 gl_cva_force_precalc( ctx );
754 }
755
756 /* Build immediate pipeline if necessary.
757 */
758 if (!cva->elt.pipeline_valid)
759 gl_build_immediate_pipeline( ctx );
760
761 gl_fixup_input( ctx, IM );
762 gl_execute_cassette( ctx, IM );
763}
764
765
766void gl_cva_init( GLcontext *ctx )
767{
768 (void) ctx;
769}
Note: See TracBrowser for help on using the repository browser.