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

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r200/r200_vertprog.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:
28
28
/*
29
29
 * Authors:
30
30
 *   Aapo Tahkola <aet@rasterburn.org>
 
31
 *   Roland Scheidegger <rscheidegger_lists@hispeed.ch>
31
32
 */
32
33
#include "glheader.h"
33
34
#include "macros.h"
39
40
#include "r200_ioctl.h"
40
41
#include "r200_tcl.h"
41
42
#include "program_instruction.h"
 
43
#include "programopt.h"
42
44
#include "tnl/tnl.h"
43
45
 
44
46
#if SWIZZLE_X != VSF_IN_COMPONENT_X || \
101
103
   r200ContextPtr rmesa = R200_CONTEXT( ctx );
102
104
   GLfloat *fcmd = (GLfloat *)&rmesa->hw.vpp[0].cmd[VPP_CMD_0 + 1];
103
105
   int pi;
104
 
   struct gl_vertex_program *mesa_vp = (void *)vp;
 
106
   struct gl_vertex_program *mesa_vp = &vp->mesa_program;
105
107
   struct gl_program_parameter_list *paramList;
106
108
   drm_radeon_cmd_header_t tmp;
107
109
 
132
134
         break;
133
135
      }
134
136
      if (pi == 95) {
135
 
         fcmd = (GLfloat *)rmesa->hw.vpp[1].cmd[VPP_CMD_0 + 1];
 
137
         fcmd = (GLfloat *)&rmesa->hw.vpp[1].cmd[VPP_CMD_0 + 1];
136
138
      }
137
139
   }
138
140
   /* hack up the cmd_size so not the whole state atom is emitted always. */
386
388
#define UNUSED_SRC_2 ((o_inst->src2 & ~15) | 9)
387
389
 
388
390
 
389
 
/* DP4 version seems to trigger some hw peculiarity - fglrx does this on r200 however */
390
 
#define PREFER_DP4
391
 
 
392
 
static GLboolean r200_translate_vertex_program(struct r200_vertex_program *vp)
 
391
/**
 
392
 * Generate an R200 vertex program from Mesa's internal representation.
 
393
 *
 
394
 * \return  GL_TRUE for success, GL_FALSE for failure.
 
395
 */
 
396
static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_vertex_program *vp)
393
397
{
394
 
   struct gl_vertex_program *mesa_vp = (void *)vp;
 
398
   struct gl_vertex_program *mesa_vp = &vp->mesa_program;
395
399
   struct prog_instruction *vpi;
396
400
   int i;
397
401
   VERTEX_SHADER_INSTRUCTION *o_inst;
398
402
   unsigned long operands;
399
403
   int are_srcs_scalar;
400
404
   unsigned long hw_op;
 
405
   int dofogfix = 0;
 
406
   int fog_temp_i = 0;
 
407
   int free_inputs;
 
408
   int free_inputs_conv;
 
409
   int array_count = 0;
401
410
 
402
411
   vp->native = GL_FALSE;
403
 
 
 
412
   vp->translated = GL_TRUE;
 
413
   vp->fogmode = ctx->Fog.Mode;
 
414
 
 
415
   if (mesa_vp->Base.NumInstructions == 0)
 
416
      return GL_FALSE;
 
417
 
 
418
#if 0
404
419
   if ((mesa_vp->Base.InputsRead &
405
420
      ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
406
421
      VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
411
426
      }
412
427
      return GL_FALSE;
413
428
   }
 
429
#endif
 
430
 
 
431
   if ((mesa_vp->Base.OutputsWritten &
 
432
      ~((1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_COL0) | (1 << VERT_RESULT_COL1) |
 
433
      (1 << VERT_RESULT_FOGC) | (1 << VERT_RESULT_TEX0) | (1 << VERT_RESULT_TEX1) |
 
434
      (1 << VERT_RESULT_TEX2) | (1 << VERT_RESULT_TEX3) | (1 << VERT_RESULT_TEX4) |
 
435
      (1 << VERT_RESULT_TEX5) | (1 << VERT_RESULT_PSIZ))) != 0) {
 
436
      if (R200_DEBUG & DEBUG_FALLBACKS) {
 
437
         fprintf(stderr, "can't handle vert prog outputs 0x%x\n",
 
438
            mesa_vp->Base.OutputsWritten);
 
439
      }
 
440
      return GL_FALSE;
 
441
   }
414
442
 
415
443
   if (mesa_vp->IsNVProgram) {
416
444
   /* subtle differences in spec like guaranteed initialized regs could cause
422
450
      Smart enough to realize that it doesnt need it? */
423
451
   int u_temp_i = R200_VSF_MAX_TEMPS - 1;
424
452
   struct prog_src_register src[3];
425
 
 
426
 
/*   if (getenv("R300_VP_SAFETY")) {
427
 
      WARN_ONCE("R300_VP_SAFETY enabled.\n");
428
 
 
429
 
      vpi = malloc((mesa_vp->Base.NumInstructions + VSF_MAX_FRAGMENT_TEMPS) * sizeof(struct prog_instruction));
430
 
      memset(vpi, 0, VSF_MAX_FRAGMENT_TEMPS * sizeof(struct prog_instruction));
431
 
 
432
 
      for (i=0; i < VSF_MAX_FRAGMENT_TEMPS; i++) {
433
 
         vpi[i].Opcode = OPCODE_MOV;
434
 
         vpi[i].StringPos = 0;
435
 
         vpi[i].Data = 0;
436
 
 
437
 
         vpi[i].DstReg.File = PROGRAM_TEMPORARY;
438
 
         vpi[i].DstReg.Index = i;
439
 
         vpi[i].DstReg.WriteMask = WRITEMASK_XYZW;
440
 
         vpi[i].DstReg.CondMask = COND_TR;
441
 
 
442
 
         vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
443
 
         vpi[i].SrcReg[0].Index = 0;
444
 
         vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE);
445
 
      }
446
 
 
447
 
      memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
448
 
 
449
 
      free(mesa_vp->Base.Instructions);
450
 
 
451
 
      mesa_vp->Base.Instructions = vpi;
452
 
 
453
 
      mesa_vp->Base.NumInstructions += VSF_MAX_FRAGMENT_TEMPS;
454
 
      vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
455
 
 
456
 
      assert(vpi->Opcode == OPCODE_END);
457
 
   }*/
 
453
   struct prog_dst_register dst;
 
454
 
458
455
/* FIXME: is changing the prog safe to do here? */
459
 
   if (mesa_vp->IsPositionInvariant) {
 
456
   if (mesa_vp->IsPositionInvariant &&
 
457
      /* make sure we only do this once */
 
458
       !(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
 
459
         _mesa_insert_mvp_code(ctx, mesa_vp);
 
460
      }
 
461
 
 
462
   /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with
 
463
      base e isn't directly available neither. */
 
464
   if (mesa_vp->Base.OutputsWritten & VERT_RESULT_FOGC && !vp->fogpidx) {
460
465
      struct gl_program_parameter_list *paramList;
461
 
      GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
462
 
 
463
 
#ifdef PREFER_DP4
464
 
      tokens[5] = STATE_MATRIX;
465
 
#else
466
 
      tokens[5] = STATE_MATRIX_TRANSPOSE;
467
 
#endif
 
466
      GLint tokens[6] = { STATE_FOG_PARAMS, 0, 0, 0, 0, 0 };
468
467
      paramList = mesa_vp->Base.Parameters;
469
 
 
470
 
      vpi = malloc((mesa_vp->Base.NumInstructions + 4) * sizeof(struct prog_instruction));
471
 
      memset(vpi, 0, 4 * sizeof(struct prog_instruction));
472
 
 
473
 
      for (i=0; i < 4; i++) {
474
 
         GLint idx;
475
 
         tokens[3] = tokens[4] = i;
476
 
         idx = _mesa_add_state_reference(paramList, tokens);
477
 
#ifdef PREFER_DP4
478
 
         vpi[i].Opcode = OPCODE_DP4;
479
 
         vpi[i].StringPos = 0;
480
 
         vpi[i].Data = 0;
481
 
 
482
 
         vpi[i].DstReg.File = PROGRAM_OUTPUT;
483
 
         vpi[i].DstReg.Index = VERT_RESULT_HPOS;
484
 
         vpi[i].DstReg.WriteMask = 1 << i;
485
 
         vpi[i].DstReg.CondMask = COND_TR;
486
 
 
487
 
         vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
488
 
         vpi[i].SrcReg[0].Index = idx;
489
 
         vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
490
 
 
491
 
         vpi[i].SrcReg[1].File = PROGRAM_INPUT;
492
 
         vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
493
 
         vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
494
 
#else
495
 
         if (i == 0)
496
 
            vpi[i].Opcode = OPCODE_MUL;
497
 
         else
498
 
            vpi[i].Opcode = OPCODE_MAD;
499
 
 
500
 
         vpi[i].StringPos = 0;
501
 
         vpi[i].Data = 0;
502
 
 
503
 
         if (i == 3)
504
 
            vpi[i].DstReg.File = PROGRAM_OUTPUT;
505
 
         else
506
 
            vpi[i].DstReg.File = PROGRAM_TEMPORARY;
507
 
         vpi[i].DstReg.Index = 0;
508
 
         vpi[i].DstReg.WriteMask = 0xf;
509
 
         vpi[i].DstReg.CondMask = COND_TR;
510
 
 
511
 
         vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
512
 
         vpi[i].SrcReg[0].Index = idx;
513
 
         vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
514
 
 
515
 
         vpi[i].SrcReg[1].File = PROGRAM_INPUT;
516
 
         vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
517
 
         vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i);
518
 
 
519
 
         if (i > 0) {
520
 
            vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
521
 
            vpi[i].SrcReg[2].Index = 0;
522
 
            vpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
523
 
         }
524
 
#endif  
525
 
      }
526
 
 
527
 
      memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
528
 
 
529
 
      free(mesa_vp->Base.Instructions);
530
 
 
531
 
      mesa_vp->Base.Instructions = vpi;
532
 
 
533
 
      mesa_vp->Base.NumInstructions += 4;
534
 
      vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
535
 
 
536
 
      assert(vpi->Opcode == OPCODE_END);
537
 
 
538
 
      mesa_vp->Base.InputsRead |= (1 << VERT_ATTRIB_POS);
539
 
      mesa_vp->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
540
 
 
541
 
      //fprintf(stderr, "IsPositionInvariant is set!\n");
542
 
      //_mesa_print_program(&mesa_vp->Base);
 
468
      vp->fogpidx = _mesa_add_state_reference(paramList, tokens);
543
469
   }
544
470
 
545
471
   vp->pos_end = 0;
546
472
   mesa_vp->Base.NumNativeInstructions = 0;
547
 
   mesa_vp->Base.NumNativeParameters = mesa_vp->Base.Parameters->NumParameters;
 
473
   if (mesa_vp->Base.Parameters)
 
474
      mesa_vp->Base.NumNativeParameters = mesa_vp->Base.Parameters->NumParameters;
 
475
   else
 
476
      mesa_vp->Base.NumNativeParameters = 0;
548
477
 
549
 
   for(i=0; i < VERT_ATTRIB_MAX; i++)
 
478
   for(i = 0; i < VERT_ATTRIB_MAX; i++)
550
479
      vp->inputs[i] = -1;
 
480
   free_inputs = 0x2ffd;
 
481
 
551
482
/* fglrx uses fixed inputs as follows for conventional attribs.
552
 
   generic attribs use non-fixed assignment, fglrx will always use the lowest attrib values available.
553
 
   There are 12 generic attribs possible, corresponding to attrib 0, 2-11 and 13 in a hw vertex prog.
554
 
   attr 1 and 12 are not available for generic attribs as those cannot be made vec4 (correspond to
555
 
   vertex normal/weight)
 
483
   generic attribs use non-fixed assignment, fglrx will always use the
 
484
   lowest attrib values available. We'll just do the same.
 
485
   There are 12 generic attribs possible, corresponding to attrib 0, 2-11
 
486
   and 13 in a hw vertex prog.
 
487
   attr 1 and 12 aren't used for generic attribs as those cannot be made vec4
 
488
   (correspond to vertex normal/weight - maybe weight actually could be made vec4).
 
489
   Additionally, not more than 12 arrays in total are possible I think.
556
490
   attr 0 is pos, R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0
557
491
   attr 2-5 use colors 0-3 (R200_VTX_FP_RGBA << R200_VTX_COLOR_0/1/2/3_SHIFT in R200_SE_VTX_FMT_0)
558
492
   attr 6-11 use tex 0-5 (4 << R200_VTX_TEX0/1/2/3/4/5_COMP_CNT_SHIFT in R200_SE_VTX_FMT_1)
559
493
   attr 13 uses vtx1 pos (R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0)
560
 
   generic attribs would require some more work (dma regions, renaming). */
 
494
*/
561
495
 
562
 
/* may look different when using idx buf / input_route instead of se_vtx_fmt? */
563
 
   vp->inputs[VERT_ATTRIB_POS] = 0;
564
 
   vp->inputs[VERT_ATTRIB_WEIGHT] = 12;
565
 
   vp->inputs[VERT_ATTRIB_NORMAL] = 1;
566
 
   vp->inputs[VERT_ATTRIB_COLOR0] = 2;
567
 
   vp->inputs[VERT_ATTRIB_COLOR1] = 3;
568
 
   vp->inputs[VERT_ATTRIB_FOG] = 15;
569
 
   vp->inputs[VERT_ATTRIB_TEX0] = 6;
570
 
   vp->inputs[VERT_ATTRIB_TEX1] = 7;
571
 
   vp->inputs[VERT_ATTRIB_TEX2] = 8;
572
 
   vp->inputs[VERT_ATTRIB_TEX3] = 9;
573
 
   vp->inputs[VERT_ATTRIB_TEX4] = 10;
574
 
   vp->inputs[VERT_ATTRIB_TEX5] = 11;
575
496
/* attr 4,5 and 13 are only used with generic attribs.
576
497
   Haven't seen attr 14 used, maybe that's for the hw pointsize vec1 (which is
577
498
   not possibe to use with vertex progs as it is lacking in vert prog specification) */
578
 
 
579
 
   assert(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS));
580
 
 
581
 
   vp->translated = GL_TRUE;
 
499
/* may look different when using idx buf / input_route instead of se_vtx_fmt? */
 
500
   if (mesa_vp->Base.InputsRead & VERT_BIT_POS) {
 
501
      vp->inputs[VERT_ATTRIB_POS] = 0;
 
502
      free_inputs &= ~(1 << 0);
 
503
      array_count++;
 
504
   }
 
505
   if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) {
 
506
   /* we don't actually handle that later. Then again, we don't have to... */
 
507
      vp->inputs[VERT_ATTRIB_WEIGHT] = 12;
 
508
      array_count++;
 
509
   }
 
510
   if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) {
 
511
      vp->inputs[VERT_ATTRIB_NORMAL] = 1;
 
512
      array_count++;
 
513
   }
 
514
   if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) {
 
515
      vp->inputs[VERT_ATTRIB_COLOR0] = 2;
 
516
      free_inputs &= ~(1 << 2);
 
517
      array_count++;
 
518
   }
 
519
   if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) {
 
520
      vp->inputs[VERT_ATTRIB_COLOR1] = 3;
 
521
      free_inputs &= ~(1 << 3);
 
522
      array_count++;
 
523
   }
 
524
   if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) {
 
525
      vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++;
 
526
   }
 
527
   for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) {
 
528
      if (mesa_vp->Base.InputsRead & (1 << i)) {
 
529
         vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6;
 
530
         free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6));
 
531
         array_count++;
 
532
      }
 
533
   }
 
534
   free_inputs_conv = free_inputs;
 
535
   /* using VERT_ATTRIB_TEX6/7 would be illegal */
 
536
   /* completely ignore aliasing? */
 
537
   for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
 
538
      int j;
 
539
   /* completely ignore aliasing? */
 
540
      if (mesa_vp->Base.InputsRead & (1 << i)) {
 
541
         array_count++;
 
542
         if (array_count > 12) {
 
543
            if (R200_DEBUG & DEBUG_FALLBACKS) {
 
544
               fprintf(stderr, "more than 12 attribs used in vert prog\n");
 
545
            }
 
546
            return GL_FALSE;
 
547
         }
 
548
         for (j = 0; j < 14; j++) {
 
549
            /* will always find one due to limited array_count */
 
550
            if (free_inputs & (1 << j)) {
 
551
               free_inputs &= ~(1 << j);
 
552
               vp->inputs[i] = j;
 
553
               vp->rev_inputs[j] = i;
 
554
               break;
 
555
            }
 
556
         }
 
557
      }
 
558
   }
 
559
   vp->gen_inputs_mapped = free_inputs ^ free_inputs_conv;
 
560
 
 
561
   if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
 
562
      if (R200_DEBUG & DEBUG_FALLBACKS) {
 
563
         fprintf(stderr, "can't handle vert prog without position output\n");
 
564
      }
 
565
      return GL_FALSE;
 
566
   }
 
567
   if (free_inputs & 1) {
 
568
      if (R200_DEBUG & DEBUG_FALLBACKS) {
 
569
         fprintf(stderr, "can't handle vert prog without position input\n");
 
570
      }
 
571
      return GL_FALSE;
 
572
   }
582
573
 
583
574
   o_inst = vp->instr;
584
 
   for(vpi = mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
585
 
      if (u_temp_i < mesa_vp->Base.NumTemporaries) {
586
 
         if (R200_DEBUG & DEBUG_FALLBACKS) {
587
 
            fprintf(stderr, "Ran out of temps, num temps %d, us %d\n", mesa_vp->Base.NumTemporaries, u_temp_i);
588
 
         }
589
 
         return GL_FALSE;
590
 
      }
591
 
      u_temp_i = R200_VSF_MAX_TEMPS - 1;
592
 
      if(o_inst - vp->instr >= R200_VSF_MAX_INST) {
593
 
         mesa_vp->Base.NumNativeInstructions = 129;
594
 
         if (R200_DEBUG & DEBUG_FALLBACKS) {
595
 
            fprintf(stderr, "more than 128 native instructions\n");
596
 
         }
597
 
         return GL_FALSE;
598
 
      }
599
 
 
 
575
   for (vpi = mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
600
576
      operands = op_operands(vpi->Opcode);
601
577
      are_srcs_scalar = operands & SCALAR_FLAG;
602
578
      operands &= OP_MASK;
603
579
 
604
 
      for(i = 0; i < operands; i++)
 
580
      for(i = 0; i < operands; i++) {
605
581
         src[i] = vpi->SrcReg[i];
 
582
         /* hack up default attrib values as per spec as swizzling.
 
583
            normal, fog, secondary color. Crazy?
 
584
            May need more if we don't submit vec4 elements? */
 
585
         if (src[i].File == PROGRAM_INPUT) {
 
586
            if (src[i].Index == VERT_ATTRIB_NORMAL) {
 
587
               int j;
 
588
               for (j = 0; j < 4; j++) {
 
589
                  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {
 
590
                     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));
 
591
                     src[i].Swizzle |= SWIZZLE_ONE << (j*3);
 
592
                  }
 
593
               }
 
594
            }
 
595
            else if (src[i].Index == VERT_ATTRIB_COLOR1) {
 
596
               int j;
 
597
               for (j = 0; j < 4; j++) {
 
598
                  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {
 
599
                     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));
 
600
                     src[i].Swizzle |= SWIZZLE_ZERO << (j*3);
 
601
                  }
 
602
               }
 
603
            }
 
604
            else if (src[i].Index == VERT_ATTRIB_FOG) {
 
605
               int j;
 
606
               for (j = 0; j < 4; j++) {
 
607
                  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {
 
608
                     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));
 
609
                     src[i].Swizzle |= SWIZZLE_ONE << (j*3);
 
610
                  }
 
611
                  else if ((GET_SWZ(src[i].Swizzle, j) == SWIZZLE_Y) ||
 
612
                            GET_SWZ(src[i].Swizzle, j) == SWIZZLE_Z) {
 
613
                     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));
 
614
                     src[i].Swizzle |= SWIZZLE_ZERO << (j*3);
 
615
                  }
 
616
               }
 
617
            }
 
618
         }
 
619
      }
606
620
 
607
621
      if(operands == 3){
608
622
         if( CMP_SRCS(src[1], src[2]) || CMP_SRCS(src[0], src[2]) ){
648
662
         }
649
663
      }
650
664
 
 
665
      dst = vpi->DstReg;
 
666
      if (dst.File == PROGRAM_OUTPUT &&
 
667
          dst.Index == VERT_RESULT_FOGC &&
 
668
          dst.WriteMask & WRITEMASK_X) {
 
669
          fog_temp_i = u_temp_i;
 
670
          dst.File = PROGRAM_TEMPORARY;
 
671
          dst.Index = fog_temp_i;
 
672
          dofogfix = 1;
 
673
          u_temp_i--;
 
674
      }
 
675
 
651
676
      /* These ops need special handling. */
652
677
      switch(vpi->Opcode){
653
678
      case OPCODE_POW:
655
680
   So may need to insert additional instruction */
656
681
         if ((src[0].File == src[1].File) &&
657
682
             (src[0].Index == src[1].Index)) {
658
 
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&vpi->DstReg),
659
 
                   t_dst_mask(vpi->DstReg.WriteMask));
 
683
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&dst),
 
684
                   t_dst_mask(dst.WriteMask));
660
685
            o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
661
686
                   t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
662
687
                   SWIZZLE_ZERO,
684
709
            o_inst->src2 = UNUSED_SRC_1;
685
710
            o_inst++;
686
711
 
687
 
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&vpi->DstReg),
688
 
                   t_dst_mask(vpi->DstReg.WriteMask));
 
712
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&dst),
 
713
                   t_dst_mask(dst.WriteMask));
689
714
            o_inst->src0 = MAKE_VSF_SOURCE(u_temp_i,
690
715
                   VSF_IN_COMPONENT_X,
691
716
                   VSF_IN_COMPONENT_Y,
701
726
 
702
727
      case OPCODE_MOV://ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO} 
703
728
      case OPCODE_SWZ:
704
 
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&vpi->DstReg),
705
 
                t_dst_mask(vpi->DstReg.WriteMask));
 
729
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst),
 
730
                t_dst_mask(dst.WriteMask));
706
731
         o_inst->src0 = t_src(vp, &src[0]);
707
732
         o_inst->src1 = ZERO_SRC_0;
708
733
         o_inst->src2 = UNUSED_SRC_1;
713
738
            src[1].File == PROGRAM_TEMPORARY &&
714
739
            src[2].File == PROGRAM_TEMPORARY) ? R200_VPI_OUT_OP_MAD_2 : R200_VPI_OUT_OP_MAD;
715
740
 
716
 
         o_inst->op = MAKE_VSF_OP(hw_op, t_dst(&vpi->DstReg),
717
 
            t_dst_mask(vpi->DstReg.WriteMask));
 
741
         o_inst->op = MAKE_VSF_OP(hw_op, t_dst(&dst),
 
742
            t_dst_mask(dst.WriteMask));
718
743
         o_inst->src0 = t_src(vp, &src[0]);
719
744
#if 0
720
745
if ((o_inst - vp->instr) == 31) {
739
764
         goto next;
740
765
 
741
766
      case OPCODE_DP3://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO} 
742
 
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&vpi->DstReg),
743
 
                t_dst_mask(vpi->DstReg.WriteMask));
 
767
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&dst),
 
768
                t_dst_mask(dst.WriteMask));
744
769
 
745
770
         o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
746
771
                t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
762
787
         goto next;
763
788
 
764
789
      case OPCODE_DPH://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W} 
765
 
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&vpi->DstReg),
766
 
                t_dst_mask(vpi->DstReg.WriteMask));
 
790
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&dst),
 
791
                t_dst_mask(dst.WriteMask));
767
792
 
768
793
         o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
769
794
                t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
777
802
         goto next;
778
803
 
779
804
      case OPCODE_SUB://ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
780
 
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&vpi->DstReg),
781
 
                t_dst_mask(vpi->DstReg.WriteMask));
 
805
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst),
 
806
                t_dst_mask(dst.WriteMask));
782
807
 
783
808
         o_inst->src0 = t_src(vp, &src[0]);
784
809
         o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
792
817
         goto next;
793
818
 
794
819
      case OPCODE_ABS://MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
795
 
         o_inst->op=MAKE_VSF_OP(R200_VPI_OUT_OP_MAX, t_dst(&vpi->DstReg),
796
 
                t_dst_mask(vpi->DstReg.WriteMask));
 
820
         o_inst->op=MAKE_VSF_OP(R200_VPI_OUT_OP_MAX, t_dst(&dst),
 
821
                t_dst_mask(dst.WriteMask));
797
822
 
798
823
         o_inst->src0=t_src(vp, &src[0]);
799
824
         o_inst->src1=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
812
837
 
813
838
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_FRC,
814
839
            (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
815
 
            t_dst_mask(vpi->DstReg.WriteMask));
 
840
            t_dst_mask(dst.WriteMask));
816
841
 
817
842
         o_inst->src0 = t_src(vp, &src[0]);
818
843
         o_inst->src1 = UNUSED_SRC_0;
819
844
         o_inst->src2 = UNUSED_SRC_1;
820
845
         o_inst++;
821
846
 
822
 
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&vpi->DstReg),
823
 
                t_dst_mask(vpi->DstReg.WriteMask));
 
847
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst),
 
848
                t_dst_mask(dst.WriteMask));
824
849
 
825
850
         o_inst->src0 = t_src(vp, &src[0]);
826
851
         o_inst->src1 = MAKE_VSF_SOURCE(u_temp_i,
844
869
 
845
870
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
846
871
            (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
847
 
            t_dst_mask(vpi->DstReg.WriteMask));
 
872
            t_dst_mask(dst.WriteMask));
848
873
 
849
874
         o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
850
875
                t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
866
891
         o_inst++;
867
892
         u_temp_i--;
868
893
 
869
 
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MAD, t_dst(&vpi->DstReg),
870
 
                t_dst_mask(vpi->DstReg.WriteMask));
 
894
         o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MAD, t_dst(&dst),
 
895
                t_dst_mask(dst.WriteMask));
871
896
 
872
897
         o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
873
898
                t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y
895
920
         goto next;
896
921
 
897
922
      case OPCODE_END:
898
 
         break;
 
923
         assert(0);
899
924
      default:
900
925
         break;
901
926
      }
902
927
 
903
 
      o_inst->op = MAKE_VSF_OP(t_opcode(vpi->Opcode), t_dst(&vpi->DstReg),
904
 
            t_dst_mask(vpi->DstReg.WriteMask));
 
928
      o_inst->op = MAKE_VSF_OP(t_opcode(vpi->Opcode), t_dst(&dst),
 
929
            t_dst_mask(dst.WriteMask));
905
930
 
906
931
      if(are_srcs_scalar){
907
932
         switch(operands){
955
980
         }
956
981
      }
957
982
      next:
 
983
 
 
984
      if (dofogfix) {
 
985
         o_inst++;
 
986
         if (vp->fogmode == GL_EXP) {
 
987
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
 
988
                (fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
 
989
                VSF_FLAG_X);
 
990
            o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
 
991
            o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, X, X, X, X, PARAM, NONE);
 
992
            o_inst->src2 = UNUSED_SRC_1;
 
993
            o_inst++;
 
994
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_EXP_E,
 
995
                R200_VSF_OUT_CLASS_RESULT_FOGC,
 
996
                VSF_FLAG_X);
 
997
            o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL);
 
998
            o_inst->src1 = UNUSED_SRC_0;
 
999
            o_inst->src2 = UNUSED_SRC_1;
 
1000
         }
 
1001
         else if (vp->fogmode == GL_EXP2) {
 
1002
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
 
1003
                (fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
 
1004
                VSF_FLAG_X);
 
1005
            o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
 
1006
            o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, X, X, X, X, PARAM, NONE);
 
1007
            o_inst->src2 = UNUSED_SRC_1;
 
1008
            o_inst++;
 
1009
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
 
1010
                (fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
 
1011
                VSF_FLAG_X);
 
1012
            o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
 
1013
            o_inst->src1 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
 
1014
            o_inst->src2 = UNUSED_SRC_1;
 
1015
            o_inst++;
 
1016
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_EXP_E,
 
1017
                R200_VSF_OUT_CLASS_RESULT_FOGC,
 
1018
                VSF_FLAG_X);
 
1019
            o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL);
 
1020
            o_inst->src1 = UNUSED_SRC_0;
 
1021
            o_inst->src2 = UNUSED_SRC_1;
 
1022
         }
 
1023
         else { /* fogmode == GL_LINEAR */
 
1024
                /* could do that with single op (dot) if using params like
 
1025
                   with fixed function pipeline fog */
 
1026
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD,
 
1027
                (fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
 
1028
                VSF_FLAG_X);
 
1029
            o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL);
 
1030
            o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, Z, Z, Z, Z, PARAM, NONE);
 
1031
            o_inst->src2 = UNUSED_SRC_1;
 
1032
            o_inst++;
 
1033
            o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
 
1034
                R200_VSF_OUT_CLASS_RESULT_FOGC,
 
1035
                VSF_FLAG_X);
 
1036
            o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
 
1037
            o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, W, W, W, W, PARAM, NONE);
 
1038
            o_inst->src2 = UNUSED_SRC_1;
 
1039
 
 
1040
         }
 
1041
         dofogfix = 0;
 
1042
      }
 
1043
 
 
1044
      if (mesa_vp->Base.NumNativeTemporaries <
 
1045
         (mesa_vp->Base.NumTemporaries + (R200_VSF_MAX_TEMPS - 1 - u_temp_i))) {
 
1046
         mesa_vp->Base.NumNativeTemporaries =
 
1047
            mesa_vp->Base.NumTemporaries + (R200_VSF_MAX_TEMPS - 1 - u_temp_i);
 
1048
      }
 
1049
      if (u_temp_i < mesa_vp->Base.NumTemporaries) {
 
1050
         if (R200_DEBUG & DEBUG_FALLBACKS) {
 
1051
            fprintf(stderr, "Ran out of temps, num temps %d, us %d\n", mesa_vp->Base.NumTemporaries, u_temp_i);
 
1052
         }
 
1053
         return GL_FALSE;
 
1054
      }
 
1055
      u_temp_i = R200_VSF_MAX_TEMPS - 1;
 
1056
      if(o_inst - vp->instr >= R200_VSF_MAX_INST) {
 
1057
         mesa_vp->Base.NumNativeInstructions = 129;
 
1058
         if (R200_DEBUG & DEBUG_FALLBACKS) {
 
1059
            fprintf(stderr, "more than 128 native instructions\n");
 
1060
         }
 
1061
         return GL_FALSE;
 
1062
      }
958
1063
      if ((o_inst->op & R200_VSF_OUT_CLASS_MASK) == R200_VSF_OUT_CLASS_RESULT_POS) {
959
1064
         vp->pos_end = (o_inst - vp->instr);
960
1065
      }
961
1066
   }
962
1067
 
963
 
   /* need to test again since some instructions require more than one (up to 3) native inst */
964
 
   if(o_inst - vp->instr > R200_VSF_MAX_INST) {
965
 
      mesa_vp->Base.NumNativeInstructions = 129;
966
 
      if (R200_DEBUG & DEBUG_FALLBACKS) {
967
 
         fprintf(stderr, "more than 128 native instructions\n");
968
 
      }
969
 
      return GL_FALSE;
970
 
   }
971
1068
   vp->native = GL_TRUE;
972
1069
   mesa_vp->Base.NumNativeInstructions = (o_inst - vp->instr);
973
1070
#if 0
984
1081
   GLboolean fallback;
985
1082
   GLint i;
986
1083
 
987
 
   if (!vp->translated) {
 
1084
   if (!vp->translated || (ctx->Fog.Enabled && ctx->Fog.Mode != vp->fogmode)) {
988
1085
      rmesa->curr_vp_hw = NULL;
989
 
      r200_translate_vertex_program(vp);
 
1086
      r200_translate_vertex_program(ctx, vp);
990
1087
   }
991
1088
   /* could optimize setting up vertex progs away for non-tcl hw */
992
1089
   fallback = !(vp->native && r200VertexProgUpdateParams(ctx, vp) &&
993
1090
      rmesa->r200Screen->drmSupportsVertexProgram);
994
1091
   TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, fallback);
995
 
   if (fallback) return;
 
1092
   if (rmesa->TclFallback) return;
 
1093
 
 
1094
   R200_STATECHANGE( rmesa, vap );
 
1095
   /* FIXME: fglrx sets R200_VAP_SINGLE_BUF_STATE_ENABLE too. Do we need it?
 
1096
             maybe only when using more than 64 inst / 96 param? */
 
1097
   rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE /*| R200_VAP_SINGLE_BUF_STATE_ENABLE*/;
996
1098
 
997
1099
   R200_STATECHANGE( rmesa, pvs );
998
1100
 
1097
1199
r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
1098
1200
{
1099
1201
   struct r200_vertex_program *vp = (void *)prog;
 
1202
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1100
1203
 
1101
1204
   switch(target) {
1102
1205
   case GL_VERTEX_PROGRAM_ARB:
1103
1206
      vp->translated = GL_FALSE;
1104
 
      memset(&vp->translated, 0, sizeof(struct r200_vertex_program) - sizeof(struct gl_vertex_program));
1105
 
      /*r200_translate_vertex_shader(vp);*/
 
1207
      vp->fogpidx = 0;
 
1208
/*      memset(&vp->translated, 0, sizeof(struct r200_vertex_program) - sizeof(struct gl_vertex_program));*/
 
1209
      r200_translate_vertex_program(ctx, vp);
 
1210
      rmesa->curr_vp_hw = NULL;
 
1211
      break;
 
1212
   case GL_FRAGMENT_SHADER_ATI:
 
1213
      rmesa->afs_loaded = NULL;
1106
1214
      break;
1107
1215
   }
1108
1216
   /* need this for tcl fallbacks */
1118
1226
   case GL_VERTEX_STATE_PROGRAM_NV:
1119
1227
   case GL_VERTEX_PROGRAM_ARB:
1120
1228
      if (!vp->translated) {
1121
 
         r200_translate_vertex_program(vp);
 
1229
         r200_translate_vertex_program(ctx, vp);
1122
1230
      }
1123
1231
     /* does not take parameters etc. into account */
1124
1232
      return vp->native;