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

Last change on this file since 2938 was 2938, checked in by sandervl, 25 years ago

created

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