~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/shader/nvvertexec.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Mesa 3-D graphics library
3
 
 * Version:  6.5
 
3
 * Version:  6.5.2
4
4
 *
5
5
 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
6
6
 *
47
47
 * per-vertex.
48
48
 */
49
49
void
50
 
_mesa_init_vp_per_vertex_registers(GLcontext *ctx)
 
50
_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine)
51
51
{
52
52
   /* Input registers get initialized from the current vertex attribs */
53
 
   MEMCPY(ctx->VertexProgram.Inputs, ctx->Current.Attrib,
 
53
   MEMCPY(machine->Inputs, ctx->Current.Attrib,
54
54
          MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat));
55
55
 
56
56
   if (ctx->VertexProgram.Current->IsNVProgram) {
57
57
      GLuint i;
58
58
      /* Output/result regs are initialized to [0,0,0,1] */
59
59
      for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
60
 
         ASSIGN_4V(ctx->VertexProgram.Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F);
 
60
         ASSIGN_4V(machine->Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F);
61
61
      }
62
62
      /* Temp regs are initialized to [0,0,0,0] */
63
63
      for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
64
 
         ASSIGN_4V(ctx->VertexProgram.Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F);
 
64
         ASSIGN_4V(machine->Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F);
65
65
      }
66
 
      ASSIGN_4V(ctx->VertexProgram.AddressReg, 0, 0, 0, 0);
 
66
      ASSIGN_4V(machine->AddressReg, 0, 0, 0, 0);
67
67
   }
68
68
}
69
69
 
139
139
            continue;
140
140
         }
141
141
 
142
 
         /* load the matrix */
 
142
         /* load the matrix values into sequential registers */
143
143
         if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
144
144
            load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
145
145
         }
161
161
      }
162
162
   }
163
163
   else {
164
 
      /* Using and ARB vertex program */
 
164
      /* ARB vertex program */
165
165
      if (ctx->VertexProgram.Current->Base.Parameters) {
166
166
         /* Grab the state GL state and put into registers */
167
167
         _mesa_load_state_parameters(ctx,
176
176
 * For debugging.  Dump the current vertex program machine registers.
177
177
 */
178
178
void
179
 
_mesa_dump_vp_state( const struct gl_vertex_program_state *state )
 
179
_mesa_dump_vp_state( const struct gl_vertex_program_state *state,
 
180
                     const struct vp_machine *machine)
180
181
{
181
182
   int i;
182
183
   _mesa_printf("VertexIn:\n");
183
184
   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) {
184
185
      _mesa_printf("%d: %f %f %f %f   ", i,
185
 
                   state->Inputs[i][0],
186
 
                   state->Inputs[i][1],
187
 
                   state->Inputs[i][2],
188
 
                   state->Inputs[i][3]);
 
186
                   machine->Inputs[i][0],
 
187
                   machine->Inputs[i][1],
 
188
                   machine->Inputs[i][2],
 
189
                   machine->Inputs[i][3]);
189
190
   }
190
191
   _mesa_printf("\n");
191
192
 
192
193
   _mesa_printf("VertexOut:\n");
193
194
   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
194
195
      _mesa_printf("%d: %f %f %f %f   ", i,
195
 
                  state->Outputs[i][0],
196
 
                  state->Outputs[i][1],
197
 
                  state->Outputs[i][2],
198
 
                  state->Outputs[i][3]);
 
196
                  machine->Outputs[i][0],
 
197
                  machine->Outputs[i][1],
 
198
                  machine->Outputs[i][2],
 
199
                  machine->Outputs[i][3]);
199
200
   }
200
201
   _mesa_printf("\n");
201
202
 
202
203
   _mesa_printf("Registers:\n");
203
204
   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
204
205
      _mesa_printf("%d: %f %f %f %f   ", i,
205
 
                  state->Temporaries[i][0],
206
 
                  state->Temporaries[i][1],
207
 
                  state->Temporaries[i][2],
208
 
                  state->Temporaries[i][3]);
 
206
                  machine->Temporaries[i][0],
 
207
                  machine->Temporaries[i][1],
 
208
                  machine->Temporaries[i][2],
 
209
                  machine->Temporaries[i][3]);
209
210
   }
210
211
   _mesa_printf("\n");
211
212
 
227
228
 * source register.
228
229
 */
229
230
static INLINE const GLfloat *
230
 
get_register_pointer( const struct prog_src_register *source,
231
 
                      const struct gl_vertex_program_state *state )
 
231
get_register_pointer( GLcontext *ctx,
 
232
                      const struct prog_src_register *source,
 
233
                      struct vp_machine *machine,
 
234
                      const struct gl_vertex_program *program )
232
235
{
233
236
   if (source->RelAddr) {
234
 
      const GLint reg = source->Index + state->AddressReg[0];
 
237
      const GLint reg = source->Index + machine->AddressReg[0];
235
238
      ASSERT( (source->File == PROGRAM_ENV_PARAM) || 
236
239
        (source->File == PROGRAM_STATE_VAR) );
237
240
      if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
238
241
         return ZeroVec;
239
242
      else if (source->File == PROGRAM_ENV_PARAM)
240
 
         return state->Parameters[reg];
241
 
      else
242
 
         return state->Current->Base.Parameters->ParameterValues[reg];
 
243
         return ctx->VertexProgram.Parameters[reg];
 
244
      else {
 
245
         ASSERT(source->File == PROGRAM_LOCAL_PARAM);
 
246
         return program->Base.Parameters->ParameterValues[reg];
 
247
      }
243
248
   }
244
249
   else {
245
250
      switch (source->File) {
246
251
         case PROGRAM_TEMPORARY:
247
252
            ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_TEMPS);
248
 
            return state->Temporaries[source->Index];
 
253
            return machine->Temporaries[source->Index];
249
254
         case PROGRAM_INPUT:
250
255
            ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS);
251
 
            return state->Inputs[source->Index];
 
256
            return machine->Inputs[source->Index];
252
257
         case PROGRAM_OUTPUT:
253
258
            /* This is only needed for the PRINT instruction */
254
259
            ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
255
 
            return state->Outputs[source->Index];
 
260
            return machine->Outputs[source->Index];
256
261
         case PROGRAM_LOCAL_PARAM:
257
262
            ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
258
 
            return state->Current->Base.LocalParams[source->Index];
 
263
            return program->Base.LocalParams[source->Index];
259
264
         case PROGRAM_ENV_PARAM:
260
265
            ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_PARAMS);
261
 
            return state->Parameters[source->Index];
 
266
            return ctx->VertexProgram.Parameters[source->Index];
262
267
         case PROGRAM_STATE_VAR:
263
 
            ASSERT(source->Index < state->Current->Base.Parameters->NumParameters);
264
 
            return state->Current->Base.Parameters->ParameterValues[source->Index];
 
268
            ASSERT(source->Index < program->Base.Parameters->NumParameters);
 
269
            return program->Base.Parameters->ParameterValues[source->Index];
265
270
         default:
266
271
            _mesa_problem(NULL,
267
272
                          "Bad source register file in get_register_pointer");
277
282
 * Apply swizzling and negating as needed.
278
283
 */
279
284
static INLINE void
280
 
fetch_vector4( const struct prog_src_register *source,
281
 
               const struct gl_vertex_program_state *state,
 
285
fetch_vector4( GLcontext *ctx, 
 
286
               const struct prog_src_register *source,
 
287
               struct vp_machine *machine,
 
288
               const struct gl_vertex_program *program,
282
289
               GLfloat result[4] )
283
290
{
284
 
   const GLfloat *src = get_register_pointer(source, state);
285
 
 
 
291
   const GLfloat *src = get_register_pointer(ctx, source, machine, program);
 
292
   ASSERT(src);
 
293
   result[0] = src[GET_SWZ(source->Swizzle, 0)];
 
294
   result[1] = src[GET_SWZ(source->Swizzle, 1)];
 
295
   result[2] = src[GET_SWZ(source->Swizzle, 2)];
 
296
   result[3] = src[GET_SWZ(source->Swizzle, 3)];
286
297
   if (source->NegateBase) {
287
 
      result[0] = -src[GET_SWZ(source->Swizzle, 0)];
288
 
      result[1] = -src[GET_SWZ(source->Swizzle, 1)];
289
 
      result[2] = -src[GET_SWZ(source->Swizzle, 2)];
290
 
      result[3] = -src[GET_SWZ(source->Swizzle, 3)];
291
 
   }
292
 
   else {
293
 
      result[0] = src[GET_SWZ(source->Swizzle, 0)];
294
 
      result[1] = src[GET_SWZ(source->Swizzle, 1)];
295
 
      result[2] = src[GET_SWZ(source->Swizzle, 2)];
296
 
      result[3] = src[GET_SWZ(source->Swizzle, 3)];
 
298
      result[0] = -result[0];
 
299
      result[1] = -result[1];
 
300
      result[2] = -result[2];
 
301
      result[3] = -result[3];
297
302
   }
298
303
}
299
304
 
303
308
 * As above, but only return result[0] element.
304
309
 */
305
310
static INLINE void
306
 
fetch_vector1( const struct prog_src_register *source,
307
 
               const struct gl_vertex_program_state *state,
 
311
fetch_vector1( GLcontext *ctx,
 
312
               const struct prog_src_register *source,
 
313
               struct vp_machine *machine,
 
314
               const struct gl_vertex_program *program,
308
315
               GLfloat result[4] )
309
316
{
310
 
   const GLfloat *src = get_register_pointer(source, state);
311
 
 
 
317
   const GLfloat *src = get_register_pointer(ctx, source, machine, program);
 
318
   ASSERT(src);
 
319
   result[0] = src[GET_SWZ(source->Swizzle, 0)];
312
320
   if (source->NegateBase) {
313
 
      result[0] = -src[GET_SWZ(source->Swizzle, 0)];
314
 
   }
315
 
   else {
316
 
      result[0] = src[GET_SWZ(source->Swizzle, 0)];
 
321
      result[0] = -result[0];
317
322
   }
318
323
}
319
324
 
322
327
 * Store 4 floats into a register.
323
328
 */
324
329
static void
325
 
store_vector4( const struct prog_dst_register *dest,
326
 
               struct gl_vertex_program_state *state,
 
330
store_vector4( const struct prog_instruction *inst,
 
331
               struct vp_machine *machine,
327
332
               const GLfloat value[4] )
328
333
{
 
334
   const struct prog_dst_register *dest = &(inst->DstReg);
329
335
   GLfloat *dst;
330
336
   switch (dest->File) {
 
337
      case PROGRAM_OUTPUT:
 
338
         dst = machine->Outputs[dest->Index];
 
339
         break;
331
340
      case PROGRAM_TEMPORARY:
332
 
         dst = state->Temporaries[dest->Index];
333
 
         break;
334
 
      case PROGRAM_OUTPUT:
335
 
         dst = state->Outputs[dest->Index];
 
341
         dst = machine->Temporaries[dest->Index];
336
342
         break;
337
343
      case PROGRAM_ENV_PARAM:
 
344
         /* Only for VP state programs */
338
345
         {
339
346
            /* a slight hack */
340
347
            GET_CURRENT_CONTEXT(ctx);
379
386
 * Execute the given vertex program
380
387
 */
381
388
void
382
 
_mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *program)
 
389
_mesa_exec_vertex_program(GLcontext *ctx,
 
390
                          struct vp_machine *machine,
 
391
                          const struct gl_vertex_program *program)
383
392
{
384
 
   struct gl_vertex_program_state *state = &ctx->VertexProgram;
385
393
   const struct prog_instruction *inst;
386
394
 
387
395
   ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */
390
398
    * by the MVP matrix and store in the vertex position result register.
391
399
    */
392
400
   if (ctx->VertexProgram.Current->IsPositionInvariant) {
393
 
      TRANSFORM_POINT( ctx->VertexProgram.Outputs[VERT_RESULT_HPOS], 
 
401
      TRANSFORM_POINT( machine->Outputs[VERT_RESULT_HPOS], 
394
402
                       ctx->_ModelProjectMatrix.m, 
395
 
                       ctx->VertexProgram.Inputs[VERT_ATTRIB_POS]);
 
403
                       machine->Inputs[VERT_ATTRIB_POS]);
396
404
 
397
405
      /* XXX: This could go elsewhere */
398
406
      ctx->VertexProgram.Current->Base.OutputsWritten |= VERT_BIT_POS;
411
419
         case OPCODE_MOV:
412
420
            {
413
421
               GLfloat t[4];
414
 
               fetch_vector4( &inst->SrcReg[0], state, t );
415
 
               store_vector4( &inst->DstReg, state, t );
 
422
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
423
               store_vector4( inst, machine, t );
416
424
            }
417
425
            break;
418
426
         case OPCODE_LIT:
419
427
            {
420
428
               const GLfloat epsilon = 1.0F / 256.0F; /* per NV spec */
421
429
               GLfloat t[4], lit[4];
422
 
               fetch_vector4( &inst->SrcReg[0], state, t );
 
430
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
423
431
               t[0] = MAX2(t[0], 0.0F);
424
432
               t[1] = MAX2(t[1], 0.0F);
425
433
               t[3] = CLAMP(t[3], -(128.0F - epsilon), (128.0F - epsilon));
427
435
               lit[1] = t[0];
428
436
               lit[2] = (t[0] > 0.0) ? (GLfloat) _mesa_pow(t[1], t[3]) : 0.0F;
429
437
               lit[3] = 1.0;
430
 
               store_vector4( &inst->DstReg, state, lit );
 
438
               store_vector4( inst, machine, lit );
431
439
            }
432
440
            break;
433
441
         case OPCODE_RCP:
434
442
            {
435
443
               GLfloat t[4];
436
 
               fetch_vector1( &inst->SrcReg[0], state, t );
 
444
               fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
437
445
               if (t[0] != 1.0F)
438
446
                  t[0] = 1.0F / t[0];  /* div by zero is infinity! */
439
447
               t[1] = t[2] = t[3] = t[0];
440
 
               store_vector4( &inst->DstReg, state, t );
 
448
               store_vector4( inst, machine, t );
441
449
            }
442
450
            break;
443
451
         case OPCODE_RSQ:
444
452
            {
445
453
               GLfloat t[4];
446
 
               fetch_vector1( &inst->SrcReg[0], state, t );
 
454
               fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
447
455
               t[0] = INV_SQRTF(FABSF(t[0]));
448
456
               t[1] = t[2] = t[3] = t[0];
449
 
               store_vector4( &inst->DstReg, state, t );
 
457
               store_vector4( inst, machine, t );
450
458
            }
451
459
            break;
452
460
         case OPCODE_EXP:
453
461
            {
454
462
               GLfloat t[4], q[4], floor_t0;
455
 
               fetch_vector1( &inst->SrcReg[0], state, t );
 
463
               fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
456
464
               floor_t0 = FLOORF(t[0]);
457
465
               if (floor_t0 > FLT_MAX_EXP) {
458
466
                  SET_POS_INFINITY(q[0]);
475
483
               }
476
484
               q[1] = t[0] - floor_t0;
477
485
               q[3] = 1.0F;
478
 
               store_vector4( &inst->DstReg, state, q );
 
486
               store_vector4( inst, machine, q );
479
487
            }
480
488
            break;
481
489
         case OPCODE_LOG:
482
490
            {
483
491
               GLfloat t[4], q[4], abs_t0;
484
 
               fetch_vector1( &inst->SrcReg[0], state, t );
 
492
               fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
485
493
               abs_t0 = FABSF(t[0]);
486
494
               if (abs_t0 != 0.0F) {
487
495
                  /* Since we really can't handle infinite values on VMS
512
520
                  SET_NEG_INFINITY(q[2]);
513
521
               }
514
522
               q[3] = 1.0;
515
 
               store_vector4( &inst->DstReg, state, q );
 
523
               store_vector4( inst, machine, q );
516
524
            }
517
525
            break;
518
526
         case OPCODE_MUL:
519
527
            {
520
528
               GLfloat t[4], u[4], prod[4];
521
 
               fetch_vector4( &inst->SrcReg[0], state, t );
522
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
529
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
530
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
523
531
               prod[0] = t[0] * u[0];
524
532
               prod[1] = t[1] * u[1];
525
533
               prod[2] = t[2] * u[2];
526
534
               prod[3] = t[3] * u[3];
527
 
               store_vector4( &inst->DstReg, state, prod );
 
535
               store_vector4( inst, machine, prod );
528
536
            }
529
537
            break;
530
538
         case OPCODE_ADD:
531
539
            {
532
540
               GLfloat t[4], u[4], sum[4];
533
 
               fetch_vector4( &inst->SrcReg[0], state, t );
534
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
541
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
542
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
535
543
               sum[0] = t[0] + u[0];
536
544
               sum[1] = t[1] + u[1];
537
545
               sum[2] = t[2] + u[2];
538
546
               sum[3] = t[3] + u[3];
539
 
               store_vector4( &inst->DstReg, state, sum );
 
547
               store_vector4( inst, machine, sum );
540
548
            }
541
549
            break;
542
550
         case OPCODE_DP3:
543
551
            {
544
552
               GLfloat t[4], u[4], dot[4];
545
 
               fetch_vector4( &inst->SrcReg[0], state, t );
546
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
553
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
554
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
547
555
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2];
548
556
               dot[1] = dot[2] = dot[3] = dot[0];
549
 
               store_vector4( &inst->DstReg, state, dot );
 
557
               store_vector4( inst, machine, dot );
550
558
            }
551
559
            break;
552
560
         case OPCODE_DP4:
553
561
            {
554
562
               GLfloat t[4], u[4], dot[4];
555
 
               fetch_vector4( &inst->SrcReg[0], state, t );
556
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
563
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
564
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
557
565
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3];
558
566
               dot[1] = dot[2] = dot[3] = dot[0];
559
 
               store_vector4( &inst->DstReg, state, dot );
 
567
               store_vector4( inst, machine, dot );
560
568
            }
561
569
            break;
562
570
         case OPCODE_DST:
563
571
            {
564
572
               GLfloat t[4], u[4], dst[4];
565
 
               fetch_vector4( &inst->SrcReg[0], state, t );
566
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
573
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
574
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
567
575
               dst[0] = 1.0F;
568
576
               dst[1] = t[1] * u[1];
569
577
               dst[2] = t[2];
570
578
               dst[3] = u[3];
571
 
               store_vector4( &inst->DstReg, state, dst );
 
579
               store_vector4( inst, machine, dst );
572
580
            }
573
581
            break;
574
582
         case OPCODE_MIN:
575
583
            {
576
584
               GLfloat t[4], u[4], min[4];
577
 
               fetch_vector4( &inst->SrcReg[0], state, t );
578
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
585
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
586
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
579
587
               min[0] = (t[0] < u[0]) ? t[0] : u[0];
580
588
               min[1] = (t[1] < u[1]) ? t[1] : u[1];
581
589
               min[2] = (t[2] < u[2]) ? t[2] : u[2];
582
590
               min[3] = (t[3] < u[3]) ? t[3] : u[3];
583
 
               store_vector4( &inst->DstReg, state, min );
 
591
               store_vector4( inst, machine, min );
584
592
            }
585
593
            break;
586
594
         case OPCODE_MAX:
587
595
            {
588
596
               GLfloat t[4], u[4], max[4];
589
 
               fetch_vector4( &inst->SrcReg[0], state, t );
590
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
597
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
598
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
591
599
               max[0] = (t[0] > u[0]) ? t[0] : u[0];
592
600
               max[1] = (t[1] > u[1]) ? t[1] : u[1];
593
601
               max[2] = (t[2] > u[2]) ? t[2] : u[2];
594
602
               max[3] = (t[3] > u[3]) ? t[3] : u[3];
595
 
               store_vector4( &inst->DstReg, state, max );
 
603
               store_vector4( inst, machine, max );
596
604
            }
597
605
            break;
598
606
         case OPCODE_SLT:
599
607
            {
600
608
               GLfloat t[4], u[4], slt[4];
601
 
               fetch_vector4( &inst->SrcReg[0], state, t );
602
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
609
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
610
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
603
611
               slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F;
604
612
               slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F;
605
613
               slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F;
606
614
               slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F;
607
 
               store_vector4( &inst->DstReg, state, slt );
 
615
               store_vector4( inst, machine, slt );
608
616
            }
609
617
            break;
610
618
         case OPCODE_SGE:
611
619
            {
612
620
               GLfloat t[4], u[4], sge[4];
613
 
               fetch_vector4( &inst->SrcReg[0], state, t );
614
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
621
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
622
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
615
623
               sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F;
616
624
               sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F;
617
625
               sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F;
618
626
               sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F;
619
 
               store_vector4( &inst->DstReg, state, sge );
 
627
               store_vector4( inst, machine, sge );
620
628
            }
621
629
            break;
622
630
         case OPCODE_MAD:
623
631
            {
624
632
               GLfloat t[4], u[4], v[4], sum[4];
625
 
               fetch_vector4( &inst->SrcReg[0], state, t );
626
 
               fetch_vector4( &inst->SrcReg[1], state, u );
627
 
               fetch_vector4( &inst->SrcReg[2], state, v );
 
633
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
634
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
 
635
               fetch_vector4( ctx, &inst->SrcReg[2], machine, program, v );
628
636
               sum[0] = t[0] * u[0] + v[0];
629
637
               sum[1] = t[1] * u[1] + v[1];
630
638
               sum[2] = t[2] * u[2] + v[2];
631
639
               sum[3] = t[3] * u[3] + v[3];
632
 
               store_vector4( &inst->DstReg, state, sum );
 
640
               store_vector4( inst, machine, sum );
633
641
            }
634
642
            break;
635
643
         case OPCODE_ARL:
636
644
            {
637
645
               GLfloat t[4];
638
 
               fetch_vector4( &inst->SrcReg[0], state, t );
639
 
               state->AddressReg[0] = (GLint) FLOORF(t[0]);
 
646
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
647
               machine->AddressReg[0] = (GLint) FLOORF(t[0]);
640
648
            }
641
649
            break;
642
650
         case OPCODE_DPH:
643
651
            {
644
652
               GLfloat t[4], u[4], dot[4];
645
 
               fetch_vector4( &inst->SrcReg[0], state, t );
646
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
653
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
654
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
647
655
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3];
648
656
               dot[1] = dot[2] = dot[3] = dot[0];
649
 
               store_vector4( &inst->DstReg, state, dot );
 
657
               store_vector4( inst, machine, dot );
650
658
            }
651
659
            break;
652
660
         case OPCODE_RCC:
653
661
            {
654
662
               GLfloat t[4], u;
655
 
               fetch_vector1( &inst->SrcReg[0], state, t );
 
663
               fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
656
664
               if (t[0] == 1.0F)
657
665
                  u = 1.0F;
658
666
               else
674
682
                  }
675
683
               }
676
684
               t[0] = t[1] = t[2] = t[3] = u;
677
 
               store_vector4( &inst->DstReg, state, t );
 
685
               store_vector4( inst, machine, t );
678
686
            }
679
687
            break;
680
688
         case OPCODE_SUB: /* GL_NV_vertex_program1_1 */
681
689
            {
682
690
               GLfloat t[4], u[4], sum[4];
683
 
               fetch_vector4( &inst->SrcReg[0], state, t );
684
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
691
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
692
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
685
693
               sum[0] = t[0] - u[0];
686
694
               sum[1] = t[1] - u[1];
687
695
               sum[2] = t[2] - u[2];
688
696
               sum[3] = t[3] - u[3];
689
 
               store_vector4( &inst->DstReg, state, sum );
 
697
               store_vector4( inst, machine, sum );
690
698
            }
691
699
            break;
692
700
         case OPCODE_ABS: /* GL_NV_vertex_program1_1 */
693
701
            {
694
702
               GLfloat t[4];
695
 
               fetch_vector4( &inst->SrcReg[0], state, t );
 
703
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
696
704
               if (t[0] < 0.0)  t[0] = -t[0];
697
705
               if (t[1] < 0.0)  t[1] = -t[1];
698
706
               if (t[2] < 0.0)  t[2] = -t[2];
699
707
               if (t[3] < 0.0)  t[3] = -t[3];
700
 
               store_vector4( &inst->DstReg, state, t );
 
708
               store_vector4( inst, machine, t );
701
709
            }
702
710
            break;
703
711
         case OPCODE_FLR: /* GL_ARB_vertex_program */
704
712
            {
705
713
               GLfloat t[4];
706
 
               fetch_vector4( &inst->SrcReg[0], state, t );
 
714
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
707
715
               t[0] = FLOORF(t[0]);
708
716
               t[1] = FLOORF(t[1]);
709
717
               t[2] = FLOORF(t[2]);
710
718
               t[3] = FLOORF(t[3]);
711
 
               store_vector4( &inst->DstReg, state, t );
 
719
               store_vector4( inst, machine, t );
712
720
            }
713
721
            break;
714
722
         case OPCODE_FRC: /* GL_ARB_vertex_program */
715
723
            {
716
724
               GLfloat t[4];
717
 
               fetch_vector4( &inst->SrcReg[0], state, t );
 
725
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
718
726
               t[0] = t[0] - FLOORF(t[0]);
719
727
               t[1] = t[1] - FLOORF(t[1]);
720
728
               t[2] = t[2] - FLOORF(t[2]);
721
729
               t[3] = t[3] - FLOORF(t[3]);
722
 
               store_vector4( &inst->DstReg, state, t );
 
730
               store_vector4( inst, machine, t );
723
731
            }
724
732
            break;
725
733
         case OPCODE_EX2: /* GL_ARB_vertex_program */
726
734
            {
727
735
               GLfloat t[4];
728
 
               fetch_vector1( &inst->SrcReg[0], state, t );
 
736
               fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
729
737
               t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]);
730
 
               store_vector4( &inst->DstReg, state, t );
 
738
               store_vector4( inst, machine, t );
731
739
            }
732
740
            break;
733
741
         case OPCODE_LG2: /* GL_ARB_vertex_program */
734
742
            {
735
743
               GLfloat t[4];
736
 
               fetch_vector1( &inst->SrcReg[0], state, t );
 
744
               fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
737
745
               t[0] = t[1] = t[2] = t[3] = LOG2(t[0]);
738
 
               store_vector4( &inst->DstReg, state, t );
 
746
               store_vector4( inst, machine, t );
739
747
            }
740
748
            break;
741
749
         case OPCODE_POW: /* GL_ARB_vertex_program */
742
750
            {
743
751
               GLfloat t[4], u[4];
744
 
               fetch_vector1( &inst->SrcReg[0], state, t );
745
 
               fetch_vector1( &inst->SrcReg[1], state, u );
 
752
               fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
 
753
               fetch_vector1( ctx, &inst->SrcReg[1], machine, program, u );
746
754
               t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]);
747
 
               store_vector4( &inst->DstReg, state, t );
 
755
               store_vector4( inst, machine, t );
748
756
            }
749
757
            break;
750
758
         case OPCODE_XPD: /* GL_ARB_vertex_program */
751
759
            {
752
760
               GLfloat t[4], u[4], cross[4];
753
 
               fetch_vector4( &inst->SrcReg[0], state, t );
754
 
               fetch_vector4( &inst->SrcReg[1], state, u );
 
761
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
 
762
               fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
755
763
               cross[0] = t[1] * u[2] - t[2] * u[1];
756
764
               cross[1] = t[2] * u[0] - t[0] * u[2];
757
765
               cross[2] = t[0] * u[1] - t[1] * u[0];
758
 
               store_vector4( &inst->DstReg, state, cross );
 
766
               store_vector4( inst, machine, cross );
759
767
            }
760
768
            break;
761
769
         case OPCODE_SWZ: /* GL_ARB_vertex_program */
762
770
            {
763
771
               const struct prog_src_register *source = &inst->SrcReg[0];
764
 
               const GLfloat *src = get_register_pointer(source, state);
 
772
               const GLfloat *src = get_register_pointer(ctx, source,
 
773
                                                         machine, program);
765
774
               GLfloat result[4];
766
775
               GLuint i;
767
776
 
768
777
               /* do extended swizzling here */
769
778
               for (i = 0; i < 4; i++) {
770
 
                  if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ZERO)
 
779
                  const GLuint swz = GET_SWZ(source->Swizzle, i);
 
780
                  if (swz == SWIZZLE_ZERO)
771
781
                     result[i] = 0.0;
772
 
                  else if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ONE)
 
782
                  else if (swz == SWIZZLE_ONE)
773
783
                     result[i] = 1.0;
774
 
                  else
775
 
                     result[i] = src[GET_SWZ(source->Swizzle, i)];
 
784
                  else {
 
785
                     ASSERT(swz >= 0);
 
786
                     ASSERT(swz <= 3);
 
787
                     result[i] = src[swz];
 
788
                  }
776
789
                  if (source->NegateBase & (1 << i))
777
790
                     result[i] = -result[i];
778
791
               }
779
 
               store_vector4( &inst->DstReg, state, result );
 
792
               store_vector4( inst, machine, result );
780
793
            }
781
794
            break;
782
795
         case OPCODE_PRINT:
783
796
            if (inst->SrcReg[0].File) {
784
797
               GLfloat t[4];
785
 
               fetch_vector4( &inst->SrcReg[0], state, t );
 
798
               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
786
799
               _mesa_printf("%s%g, %g, %g, %g\n",
787
800
                            (char *) inst->Data, t[0], t[1], t[2], t[3]);
788
801
            }
805
818
}
806
819
 
807
820
 
808
 
 
809
821
/**
810
 
Thoughts on vertex program optimization:
811
 
 
812
 
The obvious thing to do is to compile the vertex program into X86/SSE/3DNow!
813
 
assembly code.  That will probably be a lot of work.
814
 
 
815
 
Another approach might be to replace the vp_instruction->Opcode field with
816
 
a pointer to a specialized C function which executes the instruction.
817
 
In particular we can write functions which skip swizzling, negating,
818
 
masking, relative addressing, etc. when they're not needed.
819
 
 
820
 
For example:
821
 
 
822
 
void simple_add( struct prog_instruction *inst )
 
822
 * Execute a vertex state program.
 
823
 * \sa _mesa_ExecuteProgramNV
 
824
 */
 
825
void
 
826
_mesa_exec_vertex_state_program(GLcontext *ctx,
 
827
                                struct gl_vertex_program *vprog,
 
828
                                const GLfloat *params)
823
829
{
824
 
   GLfloat *sum = machine->Registers[inst->DstReg.Register];
825
 
   GLfloat *a = machine->Registers[inst->SrcReg[0].Register];
826
 
   GLfloat *b = machine->Registers[inst->SrcReg[1].Register];
827
 
   sum[0] = a[0] + b[0];
828
 
   sum[1] = a[1] + b[1];
829
 
   sum[2] = a[2] + b[2];
830
 
   sum[3] = a[3] + b[3];
 
830
   struct vp_machine machine;
 
831
   _mesa_init_vp_per_vertex_registers(ctx, &machine);
 
832
   _mesa_init_vp_per_primitive_registers(ctx);
 
833
   COPY_4V(machine.Inputs[VERT_ATTRIB_POS], params);
 
834
   _mesa_exec_vertex_program(ctx, &machine, vprog);
831
835
}
832
 
 
833
 
*/
834
 
 
835
 
/*
836
 
 
837
 
KW:
838
 
 
839
 
A first step would be to 'vectorize' the programs in the same way as
840
 
the normal transformation code in the tnl module.  Thus each opcode
841
 
takes zero or more input vectors (registers) and produces one or more
842
 
output vectors.
843
 
 
844
 
These operations would intially be coded in C, with machine-specific
845
 
assembly following, as is currently the case for matrix
846
 
transformations in the math/ directory.  The preprocessing scheme for
847
 
selecting simpler operations Brian describes above would also work
848
 
here.
849
 
 
850
 
This should give reasonable performance without excessive effort.
851
 
 
852
 
*/