| 1 | /* $Id: vbxform.c,v 1.3 2000-05-23 20:41:03 jeroen 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 |
|
|---|
| 28 |
|
|---|
| 29 | #ifdef PC_HEADER
|
|---|
| 30 | #include "all.h"
|
|---|
| 31 | #else
|
|---|
| 32 | #include "glheader.h"
|
|---|
| 33 | #include "types.h"
|
|---|
| 34 | #include "context.h"
|
|---|
| 35 | #include "cva.h"
|
|---|
| 36 | #include "clip.h"
|
|---|
| 37 | #include "eval.h"
|
|---|
| 38 | #include "enums.h"
|
|---|
| 39 | #include "dlist.h"
|
|---|
| 40 | #include "fog.h"
|
|---|
| 41 | #include "light.h"
|
|---|
| 42 | #include "macros.h"
|
|---|
| 43 | #include "matrix.h"
|
|---|
| 44 | #include "mmath.h"
|
|---|
| 45 | #include "pipeline.h"
|
|---|
| 46 | #include "shade.h"
|
|---|
| 47 | #include "texture.h"
|
|---|
| 48 | #include "varray.h"
|
|---|
| 49 | #include "vb.h"
|
|---|
| 50 | #include "vbcull.h"
|
|---|
| 51 | #include "vbfill.h"
|
|---|
| 52 | #include "vbrender.h"
|
|---|
| 53 | #include "vbxform.h"
|
|---|
| 54 | #include "xform.h"
|
|---|
| 55 | #include "mem.h"
|
|---|
| 56 | #include "state.h"
|
|---|
| 57 | #endif
|
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 | void gl_maybe_transform_vb( struct immediate *IM )
|
|---|
| 61 | {
|
|---|
| 62 | GLcontext *ctx = IM->backref;
|
|---|
| 63 |
|
|---|
| 64 | if (ctx->NewState)
|
|---|
| 65 | gl_update_state(ctx);
|
|---|
| 66 |
|
|---|
| 67 | if (IM->FlushElt) {
|
|---|
| 68 | gl_exec_array_elements( ctx, IM, IM->LastPrimitive, IM->Count );
|
|---|
| 69 | IM->FlushElt = 0;
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | gl_compute_orflag( IM );
|
|---|
| 73 |
|
|---|
| 74 | if (ctx->ExecuteFlag)
|
|---|
| 75 | gl_cva_compile_cassette( ctx, IM );
|
|---|
| 76 | else
|
|---|
| 77 | gl_fixup_input( ctx, IM );
|
|---|
| 78 |
|
|---|
| 79 | if (ctx->CompileFlag)
|
|---|
| 80 | gl_compile_cassette( ctx );
|
|---|
| 81 | else
|
|---|
| 82 | gl_reset_input( ctx );
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 |
|
|---|
| 86 | void gl_flush_vb( GLcontext *ctx, const char *where )
|
|---|
| 87 | {
|
|---|
| 88 | struct immediate *IM = ctx->input;
|
|---|
| 89 |
|
|---|
| 90 | if (MESA_VERBOSE&VERBOSE_PIPELINE)
|
|---|
| 91 | fprintf(stderr, "gl_flush_vb: %s\n", where);
|
|---|
| 92 |
|
|---|
| 93 | gl_maybe_transform_vb( IM );
|
|---|
| 94 | }
|
|---|
| 95 |
|
|---|
| 96 | /* Drivers can call this inside their swapbuffers routines:
|
|---|
| 97 | */
|
|---|
| 98 | void gl_internal_flush( GLcontext *ctx )
|
|---|
| 99 | {
|
|---|
| 100 | FLUSH_VB( ctx, "internal flush" );
|
|---|
| 101 | }
|
|---|
| 102 |
|
|---|
| 103 |
|
|---|
| 104 | #define RESET_VEC(v, t, s, c) (v.start = t v.data[s], v.count = c)
|
|---|
| 105 |
|
|---|
| 106 | /*
|
|---|
| 107 | *
|
|---|
| 108 | */
|
|---|
| 109 | void gl_reset_vb( struct vertex_buffer *VB )
|
|---|
| 110 | {
|
|---|
| 111 | GLuint copy;
|
|---|
| 112 | GLuint dst;
|
|---|
| 113 | GLuint start;
|
|---|
| 114 | struct immediate *IM = VB->IM;
|
|---|
| 115 | GLubyte clipor = VB->ClipOrMask;
|
|---|
| 116 |
|
|---|
| 117 | if (!VB->CullDone)
|
|---|
| 118 | gl_fast_copy_vb( VB );
|
|---|
| 119 |
|
|---|
| 120 | copy = VB->CopyCount;
|
|---|
| 121 | start = 3-copy;
|
|---|
| 122 |
|
|---|
| 123 | VB->CopyStart = start;
|
|---|
| 124 | VB->ClipOrMask = 0;
|
|---|
| 125 | VB->ClipAndMask = CLIP_ALL_BITS;
|
|---|
| 126 |
|
|---|
| 127 | if (IM)
|
|---|
| 128 | {
|
|---|
| 129 | if (VB->Count != IM->Count && 0) {
|
|---|
| 130 | fprintf(stderr, "Trying to copy vertices in the middle of an IM (%d/%d)!!\n",
|
|---|
| 131 | VB->Count, IM->Count);
|
|---|
| 132 | }
|
|---|
| 133 | else if (VB->pipeline->copy_transformed_data) {
|
|---|
| 134 |
|
|---|
| 135 | for (dst = start ; dst < VB_START ; dst++)
|
|---|
| 136 | {
|
|---|
| 137 | GLuint src = VB->Copy[dst];
|
|---|
| 138 |
|
|---|
| 139 | if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
|
|---|
| 140 | fprintf(stderr, "copying vertex %u to %u\n", src, dst);
|
|---|
| 141 |
|
|---|
| 142 | COPY_4FV( VB->Clip.data[dst], VEC_ELT(VB->ClipPtr, GLfloat, src) );
|
|---|
| 143 | COPY_4FV( VB->Win.data[dst], VB->Win.data[src] );
|
|---|
| 144 |
|
|---|
| 145 | VB->UserClipMask[dst] = VB->UserClipMask[src];
|
|---|
| 146 | VB->ClipMask[dst] = (GLubyte) (VB->ClipMask[src] & ~CLIP_CULLED_BIT);
|
|---|
| 147 | VB->ClipAndMask &= VB->ClipMask[dst];
|
|---|
| 148 | VB->ClipOrMask |= VB->ClipMask[dst];
|
|---|
| 149 | VB->ClipMask[src] = 0; /* hack for bounds_cull_vb */
|
|---|
| 150 |
|
|---|
| 151 | COPY_4UBV( IM->Color[dst], IM->Color[src] );
|
|---|
| 152 | COPY_4UBV( VB->Spec[0][dst], VB->Spec[0][src] );
|
|---|
| 153 | COPY_4UBV( VB->Spec[1][dst], VB->Spec[1][src] );
|
|---|
| 154 | COPY_4UBV( VB->BColor.data[dst], VB->BColor.data[src] );
|
|---|
| 155 | IM->Index[dst] = IM->Index[src];
|
|---|
| 156 | VB->BIndex.data[dst] = VB->BIndex.data[src];
|
|---|
| 157 |
|
|---|
| 158 | if (VB->TexCoordPtr[0] == &IM->v.TexCoord[0])
|
|---|
| 159 | COPY_4FV( IM->TexCoord[0][dst], IM->TexCoord[0][src] );
|
|---|
| 160 |
|
|---|
| 161 | if (VB->TexCoordPtr[1] == &IM->v.TexCoord[1])
|
|---|
| 162 | COPY_4FV( IM->TexCoord[1][dst], IM->TexCoord[1][src] );
|
|---|
| 163 |
|
|---|
| 164 | IM->Elt[dst] = IM->Elt[src];
|
|---|
| 165 | VB->SavedOrFlag |= IM->Flag[src];
|
|---|
| 166 | }
|
|---|
| 167 | }
|
|---|
| 168 |
|
|---|
| 169 | VB->CullDone = 0;
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | if (clipor & CLIP_USER_BIT)
|
|---|
| 173 | MEMSET(VB->UserClipMask + VB->Start, 0, VB->Count);
|
|---|
| 174 |
|
|---|
| 175 | VB->NormCullStart = 0;
|
|---|
| 176 | VB->Parity = (VB->LastPrimitive^VB->Count)&1;
|
|---|
| 177 | VB->PurgeFlags = 0;
|
|---|
| 178 | VB->EarlyCull = 1;
|
|---|
| 179 | VB->Culled = 0;
|
|---|
| 180 | VB->BoundsPtr = 0;
|
|---|
| 181 | VB->NormalLengthPtr = 0;
|
|---|
| 182 | VB->Indirect = 0;
|
|---|
| 183 | VB->Culled = 0;
|
|---|
| 184 | }
|
|---|
| 185 |
|
|---|
| 186 |
|
|---|
| 187 |
|
|---|
| 188 |
|
|---|
| 189 | /* Copy the untransformed parts of the overlapping vertices from one
|
|---|
| 190 | * immediate struct to another (or possibly the same one).
|
|---|
| 191 | *
|
|---|
| 192 | * Only copy those elements which are genuinely untransformed. Others
|
|---|
| 193 | * are done in gl_reset_vb.
|
|---|
| 194 | */
|
|---|
| 195 | void gl_copy_prev_vertices( struct vertex_buffer *VB,
|
|---|
| 196 | struct immediate *prev,
|
|---|
| 197 | struct immediate *next )
|
|---|
| 198 | {
|
|---|
| 199 | GLuint dst;
|
|---|
| 200 | GLuint flags = VB->pipeline->inputs;
|
|---|
| 201 |
|
|---|
| 202 | if (MESA_VERBOSE&VERBOSE_CULL)
|
|---|
| 203 | fprintf(stderr, "copy prev vertices im: prev %d next %d copystart %d\n",
|
|---|
| 204 | prev->id, next->id, VB->CopyStart);
|
|---|
| 205 |
|
|---|
| 206 | /* VB_START is correct as vertex copying is only required when an
|
|---|
| 207 | * IM wraps, which means that the next VB must start at VB_START.
|
|---|
| 208 | */
|
|---|
| 209 | for (dst = VB->CopyStart ; dst < VB_START ; dst++)
|
|---|
| 210 | {
|
|---|
| 211 | GLuint src = VB->Copy[dst];
|
|---|
| 212 |
|
|---|
| 213 | if (MESA_VERBOSE&VERBOSE_CULL)
|
|---|
| 214 | fprintf(stderr, "copy_prev: copy %d to %d\n", src, dst );
|
|---|
| 215 |
|
|---|
| 216 | COPY_4FV( next->Obj[dst], prev->Obj[src] );
|
|---|
| 217 |
|
|---|
| 218 | if ((flags&VERT_TEX0_ANY) && VB->TexCoordPtr[0] == &prev->v.TexCoord[0])
|
|---|
| 219 | COPY_4FV( next->TexCoord[0][dst], prev->TexCoord[0][src] );
|
|---|
| 220 |
|
|---|
| 221 | if ((flags&VERT_TEX1_ANY) && VB->TexCoordPtr[1] == &prev->v.TexCoord[1])
|
|---|
| 222 | COPY_4FV( next->TexCoord[1][dst], prev->TexCoord[1][src] );
|
|---|
| 223 |
|
|---|
| 224 | COPY_4UBV( next->Color[dst], prev->Color[src] );
|
|---|
| 225 | next->Index[dst] = prev->Index[src];
|
|---|
| 226 | next->EdgeFlag[dst] = prev->EdgeFlag[src];
|
|---|
| 227 |
|
|---|
| 228 | next->Elt[dst] = prev->Elt[src];
|
|---|
| 229 | VB->SavedOrFlag |= prev->Flag[src];
|
|---|
| 230 | }
|
|---|
| 231 | }
|
|---|
| 232 |
|
|---|
| 233 |
|
|---|
| 234 |
|
|---|
| 235 | void RESET_IMMEDIATE( GLcontext *ctx )
|
|---|
| 236 | {
|
|---|
| 237 | if (ctx->VB->prev_buffer != ctx->VB->IM) {
|
|---|
| 238 | /* Should only get here if we are trying to use the internal
|
|---|
| 239 | * interfaces, eg gl_Vertex3f(), gl_Begin() from inside a
|
|---|
| 240 | * display list. In this case, it is necessary to pull the
|
|---|
| 241 | * current values into the ctx->VB.store buffer, because this
|
|---|
| 242 | * may not have been done.
|
|---|
| 243 | */
|
|---|
| 244 | FLUSH_VB( ctx, "RESET_IMMEDIATE" );
|
|---|
| 245 | gl_reset_input( ctx );
|
|---|
| 246 | }
|
|---|
| 247 | }
|
|---|
| 248 |
|
|---|
| 249 |
|
|---|
| 250 | /* Called to initialize new buffers, and to recycle old ones.
|
|---|
| 251 | */
|
|---|
| 252 | void gl_reset_input( GLcontext *ctx )
|
|---|
| 253 | {
|
|---|
| 254 | struct immediate *IM = ctx->input;
|
|---|
| 255 |
|
|---|
| 256 | MEMSET(IM->Flag, 0, sizeof(GLuint) * (IM->Count+2));
|
|---|
| 257 | IM->Start = VB_START;
|
|---|
| 258 | IM->Count = VB_START;
|
|---|
| 259 |
|
|---|
| 260 | IM->Primitive[IM->Start] = ctx->Current.Primitive;
|
|---|
| 261 | IM->LastPrimitive = IM->Start;
|
|---|
| 262 | IM->BeginState = VERT_BEGIN_0;
|
|---|
| 263 | IM->OrFlag = 0;
|
|---|
| 264 | IM->AndFlag = ~0U;
|
|---|
| 265 |
|
|---|
| 266 | if (0)
|
|---|
| 267 | fprintf(stderr,
|
|---|
| 268 | "in reset_input(IM %d), BeginState is %x, setting prim[%d] to %s\n",
|
|---|
| 269 | IM->id,
|
|---|
| 270 | VERT_BEGIN_0,
|
|---|
| 271 | IM->Start, gl_lookup_enum_by_nr(ctx->Current.Primitive));
|
|---|
| 272 |
|
|---|
| 273 | IM->ArrayAndFlags = ~ctx->Array.Flags;
|
|---|
| 274 | IM->ArrayIncr = ctx->Array.Vertex.Enabled;
|
|---|
| 275 | IM->ArrayEltFlush = !(ctx->CompileCVAFlag);
|
|---|
| 276 | }
|
|---|
| 277 |
|
|---|
| 278 |
|
|---|
| 279 | /* Preserves size information as well.
|
|---|
| 280 | */
|
|---|
| 281 | static void
|
|---|
| 282 | fixup_4f( GLfloat data[][4], GLuint flag[], GLuint start, GLuint match )
|
|---|
| 283 | {
|
|---|
| 284 | GLuint i = start;
|
|---|
| 285 |
|
|---|
| 286 | for (;;) {
|
|---|
| 287 | if ((flag[++i] & match) == 0) {
|
|---|
| 288 | COPY_4FV(data[i], data[i-1]);
|
|---|
| 289 | flag[i] |= (flag[i-1] & match);
|
|---|
| 290 | if (flag[i] & VERT_END_VB) break;
|
|---|
| 291 | }
|
|---|
| 292 | }
|
|---|
| 293 | }
|
|---|
| 294 |
|
|---|
| 295 |
|
|---|
| 296 |
|
|---|
| 297 | /* Only needed for buffers with eval coords.
|
|---|
| 298 | */
|
|---|
| 299 | static void
|
|---|
| 300 | fixup_3f( float data[][3], GLuint flag[], GLuint start, GLuint match )
|
|---|
| 301 | {
|
|---|
| 302 | GLuint i = start;
|
|---|
| 303 |
|
|---|
| 304 | for (;;) {
|
|---|
| 305 | if ((flag[++i] & match) == 0) {
|
|---|
| 306 | COPY_3V(data[i], data[i-1]);
|
|---|
| 307 | flag[i] |= match;
|
|---|
| 308 | if (flag[i] & VERT_END_VB) break;
|
|---|
| 309 | }
|
|---|
| 310 | }
|
|---|
| 311 | }
|
|---|
| 312 |
|
|---|
| 313 |
|
|---|
| 314 | static void
|
|---|
| 315 | fixup_1ui( GLuint *data, GLuint flag[], GLuint start, GLuint match )
|
|---|
| 316 | {
|
|---|
| 317 | GLuint i = start;
|
|---|
| 318 |
|
|---|
| 319 | for (;;) {
|
|---|
| 320 | if ((flag[++i] & match) == 0) {
|
|---|
| 321 | data[i] = data[i-1];
|
|---|
| 322 | if (flag[i] & VERT_END_VB) break;
|
|---|
| 323 | }
|
|---|
| 324 | }
|
|---|
| 325 | flag[i] |= match;
|
|---|
| 326 | }
|
|---|
| 327 |
|
|---|
| 328 | static void
|
|---|
| 329 | fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match )
|
|---|
| 330 | {
|
|---|
| 331 | GLuint i = start;
|
|---|
| 332 |
|
|---|
| 333 | for (;;) {
|
|---|
| 334 | if ((flag[++i] & match) == 0) {
|
|---|
| 335 | data[i] = data[i-1];
|
|---|
| 336 | if (flag[i] & VERT_END_VB) break;
|
|---|
| 337 | }
|
|---|
| 338 | }
|
|---|
| 339 | flag[i] |= match;
|
|---|
| 340 | }
|
|---|
| 341 |
|
|---|
| 342 |
|
|---|
| 343 | static void
|
|---|
| 344 | fixup_4ub( GLubyte data[][4], GLuint flag[], GLuint start, GLuint match )
|
|---|
| 345 | {
|
|---|
| 346 | GLuint i = start;
|
|---|
| 347 |
|
|---|
| 348 | for (;;) {
|
|---|
| 349 | if ((flag[++i] & match) == 0) {
|
|---|
| 350 | COPY_4UBV(data[i], data[i-1]);
|
|---|
| 351 | if (flag[i] & VERT_END_VB) break;
|
|---|
| 352 | }
|
|---|
| 353 | }
|
|---|
| 354 | flag[i] |= match;
|
|---|
| 355 | }
|
|---|
| 356 |
|
|---|
| 357 |
|
|---|
| 358 | /* Do this instead of fixup for shared normals.
|
|---|
| 359 | */
|
|---|
| 360 | static void
|
|---|
| 361 | find_last_3f( float data[][3], GLuint flag[], GLuint match, GLuint count )
|
|---|
| 362 | {
|
|---|
| 363 | int i = count;
|
|---|
| 364 |
|
|---|
| 365 | do {
|
|---|
| 366 | if ((flag[--i] & match) != 0) {
|
|---|
| 367 | COPY_3V(data[count], data[i]);
|
|---|
| 368 | return;
|
|---|
| 369 | }
|
|---|
| 370 | } while (i >= 0);
|
|---|
| 371 |
|
|---|
| 372 | /* To reach this point excercises a bug that seems only to exist on
|
|---|
| 373 | * dec alpha installations. I want to leave this print statement
|
|---|
| 374 | * enabled on the 3.3 branch so that we are reminded to track down
|
|---|
| 375 | * the problem.
|
|---|
| 376 | */
|
|---|
| 377 | fprintf(stderr,
|
|---|
| 378 | "didn't find VERT_NORM in find_last_3f"
|
|---|
| 379 | "(Dec alpha problem?)\n");
|
|---|
| 380 | }
|
|---|
| 381 |
|
|---|
| 382 | static void
|
|---|
| 383 | fixup_first_4v( GLfloat data[][4], GLuint flag[], GLuint match,
|
|---|
| 384 | GLuint start, GLfloat *dflt )
|
|---|
| 385 | {
|
|---|
| 386 | GLuint i = start-1;
|
|---|
| 387 | match |= VERT_END_VB;
|
|---|
| 388 |
|
|---|
| 389 | while ((flag[++i]&match) == 0)
|
|---|
| 390 | COPY_4FV(data[i], dflt);
|
|---|
| 391 | }
|
|---|
| 392 |
|
|---|
| 393 |
|
|---|
| 394 | static void
|
|---|
| 395 | fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match,
|
|---|
| 396 | GLuint start, GLuint dflt )
|
|---|
| 397 | {
|
|---|
| 398 | GLuint i = start-1;
|
|---|
| 399 | match |= VERT_END_VB;
|
|---|
| 400 |
|
|---|
| 401 | while ((flag[++i]&match) == 0)
|
|---|
| 402 | data[i] = dflt;
|
|---|
| 403 | }
|
|---|
| 404 |
|
|---|
| 405 |
|
|---|
| 406 | static void
|
|---|
| 407 | fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match,
|
|---|
| 408 | GLuint start, GLubyte dflt )
|
|---|
| 409 | {
|
|---|
| 410 | GLuint i = start-1;
|
|---|
| 411 | match |= VERT_END_VB;
|
|---|
| 412 |
|
|---|
| 413 | while ((flag[++i]&match) == 0)
|
|---|
| 414 | data[i] = dflt;
|
|---|
| 415 | }
|
|---|
| 416 |
|
|---|
| 417 |
|
|---|
| 418 | static void
|
|---|
| 419 | fixup_first_4ub( GLubyte data[][4], GLuint flag[], GLuint match,
|
|---|
| 420 | GLuint start, GLubyte dflt[4] )
|
|---|
| 421 | {
|
|---|
| 422 | GLuint i = start-1;
|
|---|
| 423 | match |= VERT_END_VB;
|
|---|
| 424 |
|
|---|
| 425 | while ((flag[++i]&match) == 0)
|
|---|
| 426 | COPY_4UBV(data[i], dflt);
|
|---|
| 427 | }
|
|---|
| 428 |
|
|---|
| 429 |
|
|---|
| 430 |
|
|---|
| 431 |
|
|---|
| 432 | static GLuint vertex_sizes[16] = { 0,
|
|---|
| 433 | 1,
|
|---|
| 434 | 2, 2,
|
|---|
| 435 | 3, 3, 3, 3,
|
|---|
| 436 | 4, 4, 4, 4, 4, 4, 4, 4 };
|
|---|
| 437 |
|
|---|
| 438 |
|
|---|
| 439 |
|
|---|
| 440 | GLuint gl_texcoord_size( GLuint flag, GLuint unit )
|
|---|
| 441 | {
|
|---|
| 442 | flag >>= VERT_TEX0_SHIFT + unit * NR_TEXSIZE_BITS;
|
|---|
| 443 | return vertex_sizes[flag & 0xf];
|
|---|
| 444 | }
|
|---|
| 445 |
|
|---|
| 446 |
|
|---|
| 447 | static void set_vec_sizes( struct immediate *IM, GLuint orflag )
|
|---|
| 448 | {
|
|---|
| 449 | GLuint i;
|
|---|
| 450 |
|
|---|
| 451 | if (orflag & VERT_OBJ_ANY) {
|
|---|
| 452 | GLuint szflag = orflag & VERT_OBJ_234;
|
|---|
| 453 | IM->v.Obj.size = vertex_sizes[szflag<<1];
|
|---|
| 454 | }
|
|---|
| 455 |
|
|---|
| 456 | for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
|
|---|
| 457 | if (orflag & VERT_TEX_ANY(i)) {
|
|---|
| 458 | GLuint szflag = ((orflag>>(VERT_TEX0_SHIFT+i*NR_TEXSIZE_BITS))
|
|---|
| 459 | & 0xf);
|
|---|
| 460 | IM->v.TexCoord[i].size = vertex_sizes[szflag];
|
|---|
| 461 | }
|
|---|
| 462 | }
|
|---|
| 463 | }
|
|---|
| 464 |
|
|---|
| 465 |
|
|---|
| 466 | void gl_compute_orflag( struct immediate *IM )
|
|---|
| 467 | {
|
|---|
| 468 | GLuint count = IM->Count;
|
|---|
| 469 | GLuint orflag = 0;
|
|---|
| 470 | GLuint andflag = ~0U;
|
|---|
| 471 | GLuint i;
|
|---|
| 472 |
|
|---|
| 473 | IM->LastData = count-1;
|
|---|
| 474 |
|
|---|
| 475 | /* fprintf(stderr, "In gl_compute_orflag, start %d count %d\n", IM->Start, IM->Count); */
|
|---|
| 476 | /* gl_print_vert_flags("initial andflag", andflag); */
|
|---|
| 477 |
|
|---|
| 478 | /* Compute the flags for the whole buffer, even if
|
|---|
| 479 | */
|
|---|
| 480 | for (i = IM->Start ; i < count ; i++) {
|
|---|
| 481 | andflag &= IM->Flag[i];
|
|---|
| 482 | orflag |= IM->Flag[i];
|
|---|
| 483 | }
|
|---|
| 484 |
|
|---|
| 485 | if (IM->Flag[i] & VERT_DATA) {
|
|---|
| 486 | IM->LastData++;
|
|---|
| 487 | /* andflag &= IM->Flag[i]; */
|
|---|
| 488 | orflag |= IM->Flag[i];
|
|---|
| 489 | }
|
|---|
| 490 |
|
|---|
| 491 | /* gl_print_vert_flags("final andflag", andflag); */
|
|---|
| 492 |
|
|---|
| 493 | IM->Flag[IM->LastData+1] |= VERT_END_VB;
|
|---|
| 494 | IM->AndFlag = andflag;
|
|---|
| 495 | IM->OrFlag = orflag;
|
|---|
| 496 | }
|
|---|
| 497 |
|
|---|
| 498 | void gl_fixup_input( GLcontext *ctx, struct immediate *IM )
|
|---|
| 499 | {
|
|---|
| 500 | GLuint count = IM->Count;
|
|---|
| 501 | GLuint start = IM->Start;
|
|---|
| 502 | GLuint fixup, diff;
|
|---|
| 503 | GLuint andflag = IM->AndFlag;
|
|---|
| 504 | GLuint orflag = IM->OrFlag;
|
|---|
| 505 |
|
|---|
| 506 | IM->Primitive[count] = IM->Primitive[IM->LastPrimitive];
|
|---|
| 507 | IM->NextPrimitive[IM->LastPrimitive] = count;
|
|---|
| 508 | IM->NextPrimitive[count] = count+1;
|
|---|
| 509 |
|
|---|
| 510 | if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
|
|---|
| 511 | {
|
|---|
| 512 | fprintf(stderr, "Start: %u Count: %u LastData: %u\n",
|
|---|
| 513 | IM->Start, IM->Count, IM->LastData);
|
|---|
| 514 | gl_print_vert_flags("Orflag", orflag);
|
|---|
| 515 | gl_print_vert_flags("Andflag", andflag);
|
|---|
| 516 | }
|
|---|
| 517 |
|
|---|
| 518 | /* Array elements modify the current state - must do this before
|
|---|
| 519 | * fixup.
|
|---|
| 520 | */
|
|---|
| 521 | if (ctx->CompileCVAFlag && !(andflag & VERT_ELT))
|
|---|
| 522 | gl_rescue_cva( ctx, IM );
|
|---|
| 523 |
|
|---|
| 524 | if (orflag & VERT_ELT)
|
|---|
| 525 | {
|
|---|
| 526 | orflag = IM->OrFlag;
|
|---|
| 527 | andflag = IM->AndFlag;
|
|---|
| 528 | start = IM->Start;
|
|---|
| 529 | }
|
|---|
| 530 |
|
|---|
| 531 | fixup = ~andflag & VERT_FIXUP;
|
|---|
| 532 |
|
|---|
| 533 | if (!ctx->CompileFlag)
|
|---|
| 534 | fixup &= ctx->CVA.elt.inputs;
|
|---|
| 535 |
|
|---|
| 536 | if (!ctx->ExecuteFlag)
|
|---|
| 537 | fixup &= orflag;
|
|---|
| 538 |
|
|---|
| 539 | if (ctx->CompileCVAFlag)
|
|---|
| 540 | fixup &= ~ctx->CVA.pre.outputs;
|
|---|
| 541 |
|
|---|
| 542 | if ((orflag & (VERT_OBJ_ANY|VERT_EVAL_ANY)) == 0)
|
|---|
| 543 | fixup = 0;
|
|---|
| 544 |
|
|---|
| 545 | if (fixup)
|
|---|
| 546 | {
|
|---|
| 547 |
|
|---|
| 548 | if (ctx->ExecuteFlag && (fixup & ~IM->Flag[start])) {
|
|---|
| 549 | GLuint copy = fixup & ~IM->Flag[start];
|
|---|
| 550 |
|
|---|
| 551 | if (copy & VERT_NORM)
|
|---|
| 552 | COPY_3V( IM->Normal[start], ctx->Current.Normal );
|
|---|
| 553 |
|
|---|
| 554 | if (copy & VERT_RGBA)
|
|---|
| 555 | COPY_4UBV( IM->Color[start], ctx->Current.ByteColor);
|
|---|
| 556 |
|
|---|
| 557 | if (copy & VERT_INDEX)
|
|---|
| 558 | IM->Index[start] = ctx->Current.Index;
|
|---|
| 559 |
|
|---|
| 560 | if (copy & VERT_EDGE)
|
|---|
| 561 | IM->EdgeFlag[start] = ctx->Current.EdgeFlag;
|
|---|
| 562 |
|
|---|
| 563 | if (copy & VERT_TEX0_ANY)
|
|---|
| 564 | COPY_4FV( IM->TexCoord[0][start], ctx->Current.Texcoord[0] );
|
|---|
| 565 |
|
|---|
| 566 | if (copy & VERT_TEX1_ANY)
|
|---|
| 567 | COPY_4FV( IM->TexCoord[1][start], ctx->Current.Texcoord[1] );
|
|---|
| 568 | }
|
|---|
| 569 |
|
|---|
| 570 |
|
|---|
| 571 | if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
|
|---|
| 572 | gl_print_vert_flags("fixup", fixup);
|
|---|
| 573 |
|
|---|
| 574 | if (fixup & VERT_TEX0_ANY) {
|
|---|
| 575 | if (orflag & VERT_TEX0_ANY)
|
|---|
| 576 | fixup_4f( IM->TexCoord[0], IM->Flag, start, VERT_TEX0_1234 );
|
|---|
| 577 | else
|
|---|
| 578 | fixup_first_4v( IM->TexCoord[0], IM->Flag, 0, start,
|
|---|
| 579 | IM->TexCoord[0][start]);
|
|---|
| 580 | }
|
|---|
| 581 |
|
|---|
| 582 | if (fixup & VERT_TEX1_ANY) {
|
|---|
| 583 | if (orflag & VERT_TEX1_ANY)
|
|---|
| 584 | fixup_4f( IM->TexCoord[1], IM->Flag, start, VERT_TEX1_1234 );
|
|---|
| 585 | else
|
|---|
| 586 | fixup_first_4v( IM->TexCoord[1], IM->Flag, 0, start,
|
|---|
| 587 | IM->TexCoord[1][start] );
|
|---|
| 588 | }
|
|---|
| 589 |
|
|---|
| 590 | if (fixup & VERT_EDGE) {
|
|---|
| 591 | if (orflag & VERT_EDGE)
|
|---|
| 592 | fixup_1ub( IM->EdgeFlag, IM->Flag, start, VERT_EDGE );
|
|---|
| 593 | else
|
|---|
| 594 | fixup_first_1ub( IM->EdgeFlag, IM->Flag, 0, start,
|
|---|
| 595 | IM->EdgeFlag[start] );
|
|---|
| 596 | }
|
|---|
| 597 |
|
|---|
| 598 | if (fixup & VERT_INDEX) {
|
|---|
| 599 | if (orflag & VERT_INDEX)
|
|---|
| 600 | fixup_1ui( IM->Index, IM->Flag, start, VERT_INDEX );
|
|---|
| 601 | else
|
|---|
| 602 | fixup_first_1ui( IM->Index, IM->Flag, 0, start, IM->Index[start] );
|
|---|
| 603 | }
|
|---|
| 604 |
|
|---|
| 605 | if (fixup & VERT_RGBA) {
|
|---|
| 606 | if (orflag & VERT_RGBA)
|
|---|
| 607 | fixup_4ub( IM->Color, IM->Flag, start, VERT_RGBA );
|
|---|
| 608 | else
|
|---|
| 609 | fixup_first_4ub( IM->Color, IM->Flag, 0, start, IM->Color[start] );
|
|---|
| 610 | }
|
|---|
| 611 |
|
|---|
| 612 | if (fixup & VERT_NORM) {
|
|---|
| 613 | /* Only eval cannot use the Flag member to find valid normals:
|
|---|
| 614 | */
|
|---|
| 615 | if (IM->OrFlag & VERT_EVAL_ANY)
|
|---|
| 616 | fixup_3f( IM->Normal, IM->Flag, start, VERT_NORM );
|
|---|
| 617 | else {
|
|---|
| 618 | /* Copy-to-current requires a valid normal in the last slot:
|
|---|
| 619 | */
|
|---|
| 620 | if ((IM->OrFlag & VERT_NORM) &&
|
|---|
| 621 | !(IM->Flag[IM->LastData] & VERT_NORM))
|
|---|
| 622 | find_last_3f( IM->Normal, IM->Flag, VERT_NORM, IM->LastData );
|
|---|
| 623 | }
|
|---|
| 624 | }
|
|---|
| 625 | }
|
|---|
| 626 |
|
|---|
| 627 | diff = count - start;
|
|---|
| 628 | IM->v.Obj.count = diff;
|
|---|
| 629 | IM->v.Normal.count = diff;
|
|---|
| 630 | IM->v.TexCoord[0].count = diff;
|
|---|
| 631 | IM->v.TexCoord[1].count = diff;
|
|---|
| 632 | IM->v.EdgeFlag.count = diff;
|
|---|
| 633 | IM->v.Color.count = diff;
|
|---|
| 634 | IM->v.Index.count = diff;
|
|---|
| 635 |
|
|---|
| 636 | /* Prune possible half-filled slot.
|
|---|
| 637 | */
|
|---|
| 638 | IM->Flag[IM->LastData+1] &= ~VERT_END_VB;
|
|---|
| 639 | IM->Flag[IM->Count] |= VERT_END_VB;
|
|---|
| 640 | }
|
|---|
| 641 |
|
|---|
| 642 |
|
|---|
| 643 | static void calc_normal_lengths( GLfloat *dest,
|
|---|
| 644 | CONST GLfloat (*data)[3],
|
|---|
| 645 | const GLuint *flags,
|
|---|
| 646 | GLuint count )
|
|---|
| 647 | {
|
|---|
| 648 | GLuint i;
|
|---|
| 649 |
|
|---|
| 650 | for (i = 0 ; i < count ; i++ )
|
|---|
| 651 | if (flags[i] & VERT_NORM) {
|
|---|
| 652 | GLfloat tmp = (GLfloat) LEN_3FV( data[i] );
|
|---|
| 653 | dest[i] = 0;
|
|---|
| 654 | if (tmp > 0)
|
|---|
| 655 | dest[i] = 1.0F / tmp;
|
|---|
| 656 | }
|
|---|
| 657 | }
|
|---|
| 658 |
|
|---|
| 659 |
|
|---|
| 660 | /* Revive a compiled immediate struct - propogate new 'Current'
|
|---|
| 661 | * values. Often this is redundant because the current values were
|
|---|
| 662 | * known and fixed up at compile time.
|
|---|
| 663 | */
|
|---|
| 664 | void gl_fixup_cassette( GLcontext *ctx, struct immediate *IM )
|
|---|
| 665 | {
|
|---|
| 666 | GLuint fixup;
|
|---|
| 667 | GLuint count = IM->Count;
|
|---|
| 668 | GLuint start = IM->Start;
|
|---|
| 669 |
|
|---|
| 670 | if (count == start)
|
|---|
| 671 | return;
|
|---|
| 672 |
|
|---|
| 673 | if (ctx->NewState)
|
|---|
| 674 | gl_update_state( ctx );
|
|---|
| 675 |
|
|---|
| 676 |
|
|---|
| 677 | if (ctx->Transform.Normalize && IM->LastCalcedLength < IM->Count) {
|
|---|
| 678 | GLuint start = IM->LastCalcedLength;
|
|---|
| 679 |
|
|---|
| 680 | if (!IM->NormalLengths)
|
|---|
| 681 | IM->NormalLengths = (GLfloat *)MALLOC(sizeof(GLfloat) * VB_SIZE);
|
|---|
| 682 |
|
|---|
| 683 | calc_normal_lengths( IM->NormalLengths + start,
|
|---|
| 684 | (const GLfloat (*)[3])(IM->Normal + start),
|
|---|
| 685 | IM->Flag + start,
|
|---|
| 686 | IM->Count - start);
|
|---|
| 687 |
|
|---|
| 688 | IM->LastCalcedLength = IM->Count;
|
|---|
| 689 | }
|
|---|
| 690 |
|
|---|
| 691 | fixup = ctx->CVA.elt.inputs & ~IM->AndFlag & VERT_FIXUP;
|
|---|
| 692 |
|
|---|
| 693 | if (fixup) {
|
|---|
| 694 |
|
|---|
| 695 | if (MESA_VERBOSE & VERBOSE_IMMEDIATE) {
|
|---|
| 696 | fprintf(stderr, "start: %d count: %d\n", start, count);
|
|---|
| 697 | gl_print_vert_flags("fixup_cassette", fixup);
|
|---|
| 698 | }
|
|---|
| 699 |
|
|---|
| 700 | if (fixup & VERT_TEX0_ANY)
|
|---|
| 701 | fixup_first_4v( IM->TexCoord[0], IM->Flag, VERT_TEX0_ANY, start,
|
|---|
| 702 | ctx->Current.Texcoord[0] );
|
|---|
| 703 |
|
|---|
| 704 | if (fixup & VERT_TEX1_ANY)
|
|---|
| 705 | fixup_first_4v( IM->TexCoord[1], IM->Flag, VERT_TEX1_ANY, start,
|
|---|
| 706 | ctx->Current.Texcoord[1] );
|
|---|
| 707 |
|
|---|
| 708 | if (fixup & VERT_EDGE)
|
|---|
| 709 | fixup_first_1ub(IM->EdgeFlag, IM->Flag, VERT_EDGE, start,
|
|---|
| 710 | ctx->Current.EdgeFlag );
|
|---|
| 711 |
|
|---|
| 712 | if (fixup & VERT_INDEX)
|
|---|
| 713 | fixup_first_1ui(IM->Index, IM->Flag, VERT_INDEX, start,
|
|---|
| 714 | ctx->Current.Index );
|
|---|
| 715 |
|
|---|
| 716 | if (fixup & VERT_RGBA)
|
|---|
| 717 | fixup_first_4ub(IM->Color, IM->Flag, VERT_RGBA, start,
|
|---|
| 718 | ctx->Current.ByteColor );
|
|---|
| 719 |
|
|---|
| 720 | if ((fixup & VERT_NORM) && !(IM->Flag[start] & VERT_NORM)) {
|
|---|
| 721 | COPY_3V(IM->Normal[start], ctx->Current.Normal);
|
|---|
| 722 | if (ctx->Transform.Normalize)
|
|---|
| 723 | IM->NormalLengths[start] = 1.0F / (GLfloat) LEN_3FV(ctx->Current.Normal);
|
|---|
| 724 | }
|
|---|
| 725 | }
|
|---|
| 726 | }
|
|---|
| 727 |
|
|---|
| 728 |
|
|---|
| 729 |
|
|---|
| 730 | static void fixup_primitives( struct vertex_buffer *VB, struct immediate *IM )
|
|---|
| 731 | {
|
|---|
| 732 | static GLuint increment[GL_POLYGON+2] = { 1,2,1,1,3,1,1,4,2,1,1 };
|
|---|
| 733 | static GLuint intro[GL_POLYGON+2] = { 0,0,2,2,0,2,2,0,2,2,0 };
|
|---|
| 734 | GLcontext *ctx = VB->ctx;
|
|---|
| 735 | const GLuint *flags = IM->Flag;
|
|---|
| 736 | const GLuint *in_prim = IM->Primitive;
|
|---|
| 737 | const GLuint *in_nextprim = IM->NextPrimitive;
|
|---|
| 738 | GLuint *out_prim = VB->IM->Primitive;
|
|---|
| 739 | GLuint *out_nextprim = VB->IM->NextPrimitive;
|
|---|
| 740 | GLuint count = VB->Count;
|
|---|
| 741 | GLuint start = VB->Start;
|
|---|
| 742 | GLuint in, out, last;
|
|---|
| 743 | GLuint incr, prim;
|
|---|
| 744 | GLuint transition;
|
|---|
| 745 | GLuint interesting;
|
|---|
| 746 | GLuint err;
|
|---|
| 747 |
|
|---|
| 748 | /* printf("IM: %d VB->Count %d VB->Start %d current prim: %d\n", IM->id, VB->Count, VB->Start, ctx->Current.Primitive); */
|
|---|
| 749 |
|
|---|
| 750 | if (ctx->Current.Primitive == GL_POLYGON+1) {
|
|---|
| 751 | transition = VERT_BEGIN;
|
|---|
| 752 | err = IM->BeginState & VERT_ERROR_1;
|
|---|
| 753 | } else {
|
|---|
| 754 | transition = VERT_END;
|
|---|
| 755 | err = IM->BeginState & VERT_ERROR_0;
|
|---|
| 756 | }
|
|---|
| 757 |
|
|---|
| 758 | if (err) {
|
|---|
| 759 | /* Occurred somewhere inside the vb. Don't know/care where/why.
|
|---|
| 760 | */
|
|---|
| 761 | gl_error( ctx, GL_INVALID_OPERATION, "begin/end");
|
|---|
| 762 | }
|
|---|
| 763 |
|
|---|
| 764 | interesting = transition | VERT_END_VB;
|
|---|
| 765 |
|
|---|
| 766 |
|
|---|
| 767 | for (in = start ; in <= count ; in = in_nextprim[in])
|
|---|
| 768 | if (flags[in] & interesting)
|
|---|
| 769 | break;
|
|---|
| 770 |
|
|---|
| 771 | out = VB->CopyStart;
|
|---|
| 772 |
|
|---|
| 773 | if (in == out) {
|
|---|
| 774 | out_nextprim[out] = in_nextprim[in];
|
|---|
| 775 | out_prim[out] = in_prim[in];
|
|---|
| 776 | last = IM->LastPrimitive;
|
|---|
| 777 | } else if (flags[in] & transition) {
|
|---|
| 778 | out_nextprim[out] = in;
|
|---|
| 779 | out_prim[out] = ctx->Current.Primitive;
|
|---|
| 780 | out = in;
|
|---|
| 781 | last = IM->LastPrimitive;
|
|---|
| 782 | } else {
|
|---|
| 783 | out_nextprim[out] = in;
|
|---|
| 784 | out_prim[out] = ctx->Current.Primitive;
|
|---|
| 785 | in++;
|
|---|
| 786 | last = out;
|
|---|
| 787 | }
|
|---|
| 788 |
|
|---|
| 789 | for ( ; in <= count ; in = in_nextprim[in] ) {
|
|---|
| 790 | out_prim[in] = in_prim[in];
|
|---|
| 791 | out_nextprim[in] = in_nextprim[in];
|
|---|
| 792 | }
|
|---|
| 793 |
|
|---|
| 794 |
|
|---|
| 795 | VB->Primitive = out_prim;
|
|---|
| 796 | VB->NextPrimitive = out_nextprim;
|
|---|
| 797 | VB->LastPrimitive = last;
|
|---|
| 798 | prim = ctx->Current.Primitive = (GLenum) out_prim[last];
|
|---|
| 799 |
|
|---|
| 800 |
|
|---|
| 801 | /* Calculate whether the primitive finished on a 'good number' of
|
|---|
| 802 | * vertices, or whether there are overflowing vertices we have to
|
|---|
| 803 | * copy to the next buffer (in addition to the normal ones required
|
|---|
| 804 | * by a continuing primitive).
|
|---|
| 805 | *
|
|---|
| 806 | * Note that GL_POLYGON+1, ie outside begin/end, has increment 1.
|
|---|
| 807 | */
|
|---|
| 808 |
|
|---|
| 809 | incr = increment[prim];
|
|---|
| 810 |
|
|---|
| 811 | if (incr != 1 && (count - last - intro[prim]))
|
|---|
| 812 | VB->Ovf = (count - last - intro[prim]) % incr;
|
|---|
| 813 | else
|
|---|
| 814 | VB->Ovf = 0;
|
|---|
| 815 |
|
|---|
| 816 | if (0)
|
|---|
| 817 | fprintf(stderr, "prim: %s count %u last %u incr %u ovf: %u\n",
|
|---|
| 818 | gl_prim_name[prim], count, last, incr, VB->Ovf);
|
|---|
| 819 | }
|
|---|
| 820 |
|
|---|
| 821 |
|
|---|
| 822 | void gl_copy_to_current( GLcontext *ctx, struct immediate *IM )
|
|---|
| 823 | {
|
|---|
| 824 | GLuint count = IM->LastData;
|
|---|
| 825 | GLuint flag = IM->OrFlag;
|
|---|
| 826 | GLuint mask = 0;
|
|---|
| 827 |
|
|---|
| 828 | if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
|
|---|
| 829 | gl_print_vert_flags("copy to current", flag);
|
|---|
| 830 |
|
|---|
| 831 | if (flag & VERT_NORM)
|
|---|
| 832 | COPY_3FV( ctx->Current.Normal, IM->Normal[count]);
|
|---|
| 833 |
|
|---|
| 834 | if (flag & VERT_INDEX)
|
|---|
| 835 | ctx->Current.Index = IM->Index[count];
|
|---|
| 836 |
|
|---|
| 837 | if (flag & VERT_EDGE)
|
|---|
| 838 | ctx->Current.EdgeFlag = IM->EdgeFlag[count];
|
|---|
| 839 |
|
|---|
| 840 | if (flag & VERT_RGBA)
|
|---|
| 841 | COPY_4UBV(ctx->Current.ByteColor, IM->Color[count]);
|
|---|
| 842 |
|
|---|
| 843 | if (flag & VERT_TEX0_ANY) {
|
|---|
| 844 | mask |= VERT_TEX0_1234;
|
|---|
| 845 | COPY_4FV( ctx->Current.Texcoord[0], IM->TexCoord[0][count]);
|
|---|
| 846 | }
|
|---|
| 847 |
|
|---|
| 848 | if (flag & VERT_TEX1_ANY) {
|
|---|
| 849 | mask |= VERT_TEX1_1234;
|
|---|
| 850 | COPY_4FV( ctx->Current.Texcoord[1], IM->TexCoord[1][count]);
|
|---|
| 851 | }
|
|---|
| 852 |
|
|---|
| 853 | /* Save the texcoord size information as well.
|
|---|
| 854 | */
|
|---|
| 855 | ctx->Current.Flag &= ~mask;
|
|---|
| 856 | ctx->Current.Flag |= IM->Flag[count] & mask;
|
|---|
| 857 | }
|
|---|
| 858 |
|
|---|
| 859 |
|
|---|
| 860 | void gl_execute_cassette( GLcontext *ctx, struct immediate *IM )
|
|---|
| 861 | {
|
|---|
| 862 | struct vertex_buffer *VB = ctx->VB;
|
|---|
| 863 | struct immediate *prev = VB->prev_buffer;
|
|---|
| 864 | GLuint vec_start, diff;
|
|---|
| 865 |
|
|---|
| 866 | IM->ref_count++;
|
|---|
| 867 |
|
|---|
| 868 | if (prev != IM || IM != VB->IM) {
|
|---|
| 869 | gl_copy_prev_vertices( VB, VB->prev_buffer, IM );
|
|---|
| 870 | }
|
|---|
| 871 |
|
|---|
| 872 | if (! --prev->ref_count )
|
|---|
| 873 | gl_immediate_free( prev );
|
|---|
| 874 |
|
|---|
| 875 | VB->prev_buffer = IM;
|
|---|
| 876 | VB->Start = IM->Start;
|
|---|
| 877 | VB->Count = IM->Count;
|
|---|
| 878 | VB->Flag = IM->Flag;
|
|---|
| 879 | VB->OrFlag = IM->OrFlag | VB->SavedOrFlag;
|
|---|
| 880 | VB->EltPtr = &IM->v.Elt;
|
|---|
| 881 | VB->MaterialMask = IM->MaterialMask;
|
|---|
| 882 | VB->Material = IM->Material;
|
|---|
| 883 | VB->CullMode = (GLubyte) ((IM->AndFlag & VERT_NORM) ? 0 : COMPACTED_NORMALS);
|
|---|
| 884 | VB->ObjPtr = &IM->v.Obj;
|
|---|
| 885 | VB->NormalPtr = &IM->v.Normal;
|
|---|
| 886 | VB->ColorPtr = &IM->v.Color;
|
|---|
| 887 | VB->Color[0] = VB->Color[1] = VB->ColorPtr;
|
|---|
| 888 | VB->IndexPtr = &IM->v.Index;
|
|---|
| 889 | VB->EdgeFlagPtr = &IM->v.EdgeFlag;
|
|---|
| 890 | VB->TexCoordPtr[0] = &IM->v.TexCoord[0];
|
|---|
| 891 | VB->TexCoordPtr[1] = &IM->v.TexCoord[1];
|
|---|
| 892 | /* VB->BoundsPtr = IM->Bounds; */
|
|---|
| 893 | VB->NormalLengthPtr = IM->NormalLengths;
|
|---|
| 894 | VB->IndirectCount = VB->Count;
|
|---|
| 895 | VB->SavedOrFlag = 0;
|
|---|
| 896 |
|
|---|
| 897 | if (IM->Start != VB_START)
|
|---|
| 898 | VB->CopyStart = IM->Start;
|
|---|
| 899 |
|
|---|
| 900 | vec_start = IM->Start;
|
|---|
| 901 | if (vec_start == VB_START && VB->pipeline->replay_copied_vertices)
|
|---|
| 902 | vec_start = VB->CopyStart;
|
|---|
| 903 |
|
|---|
| 904 | if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
|
|---|
| 905 | fprintf(stderr, "reseting vectors to %d/%d .. %d\n", vec_start, IM->Start, IM->Count);
|
|---|
| 906 |
|
|---|
| 907 | VB->LastPrimitive = IM->Start;
|
|---|
| 908 |
|
|---|
| 909 | diff = IM->Count - vec_start;
|
|---|
| 910 |
|
|---|
| 911 | RESET_VEC(IM->v.Obj, (GLfloat *), vec_start, diff);
|
|---|
| 912 | RESET_VEC(IM->v.Normal, (GLfloat *), vec_start, diff);
|
|---|
| 913 | RESET_VEC(IM->v.TexCoord[0], (GLfloat *), vec_start, diff);
|
|---|
| 914 | RESET_VEC(IM->v.TexCoord[1], (GLfloat *), vec_start, diff);
|
|---|
| 915 | RESET_VEC(IM->v.Index, &, vec_start, diff);
|
|---|
| 916 | RESET_VEC(IM->v.Elt, &, vec_start, diff);
|
|---|
| 917 | RESET_VEC(IM->v.EdgeFlag, &, vec_start, diff);
|
|---|
| 918 | RESET_VEC(IM->v.Color, (GLubyte *), vec_start, diff);
|
|---|
| 919 | RESET_VEC(VB->Clip, (GLfloat *), vec_start, diff);
|
|---|
| 920 | RESET_VEC(VB->Eye, (GLfloat *), vec_start, diff);
|
|---|
| 921 | RESET_VEC(VB->Win, (GLfloat *), vec_start, diff);
|
|---|
| 922 | RESET_VEC(VB->BColor, (GLubyte *), vec_start, diff);
|
|---|
| 923 | RESET_VEC(VB->BIndex, &, vec_start, diff);
|
|---|
| 924 |
|
|---|
| 925 | if (IM != VB->IM) {
|
|---|
| 926 | RESET_VEC(VB->IM->v.Obj, (GLfloat *), vec_start, diff);
|
|---|
| 927 | RESET_VEC(VB->IM->v.Normal, (GLfloat *), vec_start, diff);
|
|---|
| 928 | RESET_VEC(VB->IM->v.TexCoord[0], (GLfloat *), vec_start, diff);
|
|---|
| 929 | RESET_VEC(VB->IM->v.TexCoord[1], (GLfloat *), vec_start, diff);
|
|---|
| 930 | RESET_VEC(VB->IM->v.Index, &, vec_start, diff);
|
|---|
| 931 | RESET_VEC(VB->IM->v.Elt, &, vec_start, diff);
|
|---|
| 932 | RESET_VEC(VB->IM->v.EdgeFlag, &, vec_start, diff);
|
|---|
| 933 | RESET_VEC(VB->IM->v.Color, (GLubyte *), vec_start, diff);
|
|---|
| 934 | }
|
|---|
| 935 |
|
|---|
| 936 | gl_copy_to_current( ctx, IM );
|
|---|
| 937 |
|
|---|
| 938 | set_vec_sizes( IM, VB->OrFlag );
|
|---|
| 939 |
|
|---|
| 940 | if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
|
|---|
| 941 | fprintf(stderr,
|
|---|
| 942 | "executing cassette, rows %u tc0->size == %u tc1->size == %u\n",
|
|---|
| 943 | VB->Count,
|
|---|
| 944 | VB->TexCoordPtr[0]->size,
|
|---|
| 945 | VB->TexCoordPtr[1]->size);
|
|---|
| 946 |
|
|---|
| 947 | if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
|
|---|
| 948 | gl_print_cassette( IM );
|
|---|
| 949 |
|
|---|
| 950 |
|
|---|
| 951 | if (IM->OrFlag & VERT_EVAL_ANY)
|
|---|
| 952 | gl_eval_vb( VB );
|
|---|
| 953 |
|
|---|
| 954 | if (IM->Count > IM->Start || (IM->Flag[IM->Start] & (VERT_END|VERT_BEGIN)))
|
|---|
| 955 | fixup_primitives( VB, IM );
|
|---|
| 956 |
|
|---|
| 957 | if (VB->IndirectCount > IM->Start)
|
|---|
| 958 | gl_run_pipeline( VB );
|
|---|
| 959 | else
|
|---|
| 960 | gl_update_materials( VB );
|
|---|
| 961 |
|
|---|
| 962 | /* This is unfortunate:
|
|---|
| 963 | */
|
|---|
| 964 | if (VB->pipeline->replay_copied_vertices) {
|
|---|
| 965 | if (!VB->CullDone)
|
|---|
| 966 | gl_fast_copy_vb( VB );
|
|---|
| 967 |
|
|---|
| 968 | gl_copy_prev_vertices( VB, VB->prev_buffer, IM );
|
|---|
| 969 | }
|
|---|
| 970 |
|
|---|
| 971 | gl_reset_vb( VB );
|
|---|
| 972 | }
|
|---|
| 973 |
|
|---|
| 974 | void gl_print_cassette( struct immediate *IM )
|
|---|
| 975 | {
|
|---|
| 976 | gl_print_cassette_flags( IM, IM->Flag );
|
|---|
| 977 | }
|
|---|
| 978 |
|
|---|
| 979 | void gl_print_cassette_flags( struct immediate *IM, GLuint *flags )
|
|---|
| 980 | {
|
|---|
| 981 | GLuint i;
|
|---|
| 982 | GLuint andflag = IM->AndFlag;
|
|---|
| 983 | GLuint orflag = IM->OrFlag;
|
|---|
| 984 | GLuint state = IM->BeginState;
|
|---|
| 985 | GLuint req = ~0;
|
|---|
| 986 | static const char *tplate[5] = { "%s ",
|
|---|
| 987 | "%s: %f ",
|
|---|
| 988 | "%s: %f %f ",
|
|---|
| 989 | "%s: %f %f %f ",
|
|---|
| 990 | "%s: %f %f %f %f " };
|
|---|
| 991 |
|
|---|
| 992 | fprintf(stderr, "Cassette id %d, %u rows.\n", IM->id, IM->Count - IM->Start);
|
|---|
| 993 |
|
|---|
| 994 | gl_print_vert_flags("Contains at least one", orflag);
|
|---|
| 995 |
|
|---|
| 996 | if (IM->Count != IM->Start)
|
|---|
| 997 | {
|
|---|
| 998 | gl_print_vert_flags("Contains a full complement of", andflag);
|
|---|
| 999 |
|
|---|
| 1000 | fprintf(stderr, "Final begin/end state %s/%s, errors %s/%s\n",
|
|---|
| 1001 | (state & VERT_BEGIN_0) ? "in" : "out",
|
|---|
| 1002 | (state & VERT_BEGIN_1) ? "in" : "out",
|
|---|
| 1003 | (state & VERT_ERROR_0) ? "y" : "n",
|
|---|
| 1004 | (state & VERT_ERROR_1) ? "y" : "n");
|
|---|
| 1005 |
|
|---|
| 1006 | fprintf(stderr, "Obj size: %u, TexCoord0 size: %u, TexCoord1 size: %u\n",
|
|---|
| 1007 | IM->v.Obj.size,
|
|---|
| 1008 | IM->v.TexCoord[0].size,
|
|---|
| 1009 | IM->v.TexCoord[1].size);
|
|---|
| 1010 | }
|
|---|
| 1011 |
|
|---|
| 1012 | for (i = IM->Start ; i <= IM->Count ; i++) {
|
|---|
| 1013 | fprintf(stderr, "%u: ", i);
|
|---|
| 1014 | if (req & VERT_OBJ_ANY) {
|
|---|
| 1015 | if (flags[i] & VERT_EVAL_C1)
|
|---|
| 1016 | fprintf(stderr, "EvalCoord %f ", IM->Obj[i][0]);
|
|---|
| 1017 | else if (flags[i] & VERT_EVAL_P1)
|
|---|
| 1018 | fprintf(stderr, "EvalPoint %.0f ", IM->Obj[i][0]);
|
|---|
| 1019 | else if (flags[i] & VERT_EVAL_C2)
|
|---|
| 1020 | fprintf(stderr, "EvalCoord %f %f ", IM->Obj[i][0], IM->Obj[i][1]);
|
|---|
| 1021 | else if (flags[i] & VERT_EVAL_P2)
|
|---|
| 1022 | fprintf(stderr, "EvalPoint %.0f %.0f ", IM->Obj[i][0], IM->Obj[i][1]);
|
|---|
| 1023 | else if (i < IM->Count && (flags[i]&VERT_OBJ_234)) {
|
|---|
| 1024 | fprintf(stderr, "(%x) ", flags[i] & VERT_OBJ_234);
|
|---|
| 1025 | fprintf(stderr, tplate[vertex_sizes[(flags[i]&VERT_OBJ_234)<<1]],
|
|---|
| 1026 | "Obj",
|
|---|
| 1027 | IM->Obj[i][0], IM->Obj[i][1], IM->Obj[i][2], IM->Obj[i][3]);
|
|---|
| 1028 | }
|
|---|
| 1029 | }
|
|---|
| 1030 |
|
|---|
| 1031 | if (req & flags[i] & VERT_ELT)
|
|---|
| 1032 | fprintf(stderr, " Elt %u\t", IM->Elt[i]);
|
|---|
| 1033 |
|
|---|
| 1034 | if (req & flags[i] & VERT_NORM)
|
|---|
| 1035 | fprintf(stderr, " Norm %f %f %f ",
|
|---|
| 1036 | IM->Normal[i][0], IM->Normal[i][1], IM->Normal[i][2]);
|
|---|
| 1037 |
|
|---|
| 1038 | if (req & flags[i] & VERT_TEX0_ANY)
|
|---|
| 1039 | fprintf(stderr, tplate[vertex_sizes[(flags[i]>>VERT_TEX0_SHIFT)&7]],
|
|---|
| 1040 | "TC0",
|
|---|
| 1041 | IM->TexCoord[0][i][0], IM->TexCoord[0][i][1],
|
|---|
| 1042 | IM->TexCoord[0][i][2], IM->TexCoord[0][i][2]);
|
|---|
| 1043 |
|
|---|
| 1044 |
|
|---|
| 1045 | if (req & flags[i] & VERT_TEX1_ANY)
|
|---|
| 1046 | fprintf(stderr, tplate[vertex_sizes[(flags[i]>>(VERT_TEX0_SHIFT+4))&7]],
|
|---|
| 1047 | "TC1",
|
|---|
| 1048 | IM->TexCoord[1][i][0], IM->TexCoord[1][i][1],
|
|---|
| 1049 | IM->TexCoord[1][i][2], IM->TexCoord[1][i][2]);
|
|---|
| 1050 |
|
|---|
| 1051 | if (req & flags[i] & VERT_RGBA)
|
|---|
| 1052 | fprintf(stderr, " Rgba %d %d %d %d ",
|
|---|
| 1053 | IM->Color[i][0], IM->Color[i][1],
|
|---|
| 1054 | IM->Color[i][2], IM->Color[i][3]);
|
|---|
| 1055 |
|
|---|
| 1056 | if (req & flags[i] & VERT_INDEX)
|
|---|
| 1057 | fprintf(stderr, " Index %u ", IM->Index[i]);
|
|---|
| 1058 |
|
|---|
| 1059 | if (req & flags[i] & VERT_EDGE)
|
|---|
| 1060 | fprintf(stderr, " Edgeflag %d ", IM->EdgeFlag[i]);
|
|---|
| 1061 |
|
|---|
| 1062 | if (req & flags[i] & VERT_MATERIAL)
|
|---|
| 1063 | fprintf(stderr, " Material ");
|
|---|
| 1064 |
|
|---|
| 1065 |
|
|---|
| 1066 | /* The order of these two is not easily knowable, but this is
|
|---|
| 1067 | * the usually correct way to look at them.
|
|---|
| 1068 | */
|
|---|
| 1069 | if (req & flags[i] & VERT_END)
|
|---|
| 1070 | fprintf(stderr, " END ");
|
|---|
| 1071 |
|
|---|
| 1072 | if (req & flags[i] & VERT_BEGIN)
|
|---|
| 1073 | fprintf(stderr, " BEGIN(%s) ", gl_prim_name[IM->Primitive[i]]);
|
|---|
| 1074 |
|
|---|
| 1075 | fprintf(stderr, "\n");
|
|---|
| 1076 | }
|
|---|
| 1077 | }
|
|---|
| 1078 |
|
|---|
| 1079 |
|
|---|
| 1080 |
|
|---|
| 1081 |
|
|---|
| 1082 |
|
|---|
| 1083 |
|
|---|
| 1084 |
|
|---|
| 1085 |
|
|---|
| 1086 |
|
|---|
| 1087 |
|
|---|
| 1088 |
|
|---|
| 1089 |
|
|---|
| 1090 |
|
|---|