~ubuntu-branches/ubuntu/jaunty/mesa/jaunty

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i965/brw_wm_fp.c

  • Committer: Bazaar Package Importer
  • Author(s): Timo Aaltonen
  • Date: 2009-04-03 12:42:06 UTC
  • mfrom: (1.2.16 upstream) (3.1.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20090403124206-0oo9dl0tcmd0qr38
Tags: 7.4-0ubuntu1
* New upstream release, merge from debian-experimental
  (LP: #330476, #347171, #349127)
* Drop 103_rs600_support.patch, included in this version.
* Drop 104_swrast_fbconfigs.patch, included in this version.
* Add 103_bump_965_texture_limit.diff. (LP: #146298)
* Add 104_fix_dri2_ext_tfp.diff. (LP: #324854)

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
   "PINTERP",
59
59
   "CINTERP",
60
60
   "WPOSXY",
61
 
   "FB_WRITE"
 
61
   "FB_WRITE",
 
62
   "FRONTFACING",
62
63
};
63
64
 
64
65
#if 0
123
124
   reg.Index = idx;
124
125
   reg.WriteMask = WRITEMASK_XYZW;
125
126
   reg.RelAddr = 0;
126
 
   reg.CondMask = 0;
 
127
   reg.CondMask = COND_TR;
127
128
   reg.CondSwizzle = 0;
128
129
   reg.CondSrc = 0;
129
130
   reg.pad = 0;
177
178
{
178
179
   struct prog_instruction *inst = get_fp_inst(c);
179
180
   *inst = *inst0;
180
 
   inst->Data = (void *)inst0;
181
181
   return inst;
182
182
}
183
183
 
184
 
static struct prog_instruction * emit_op(struct brw_wm_compile *c,
 
184
static struct prog_instruction * emit_tex_op(struct brw_wm_compile *c,
185
185
                                       GLuint op,
186
186
                                       struct prog_dst_register dest,
187
187
                                       GLuint saturate,
207
207
}
208
208
   
209
209
 
 
210
static struct prog_instruction * emit_op(struct brw_wm_compile *c,
 
211
                                       GLuint op,
 
212
                                       struct prog_dst_register dest,
 
213
                                       GLuint saturate,
 
214
                                       struct prog_src_register src0,
 
215
                                       struct prog_src_register src1,
 
216
                                       struct prog_src_register src2 )
 
217
{
 
218
   return emit_tex_op(c, op, dest, saturate,
 
219
                      0, 0,  /* tex unit, target */
 
220
                      src0, src1, src2);
 
221
}
 
222
   
 
223
 
210
224
 
211
225
 
212
226
/***********************************************************************
228
242
      emit_op(c,
229
243
              WM_PIXELXY,
230
244
              dst_mask(pixel_xy, WRITEMASK_XY),
231
 
              0, 0, 0,
 
245
              0,
232
246
              payload_r0_depth,
233
247
              src_undef(),
234
248
              src_undef());
251
265
      emit_op(c,
252
266
              WM_DELTAXY,
253
267
              dst_mask(delta_xy, WRITEMASK_XY),
254
 
              0, 0, 0,
 
268
              0,
255
269
              pixel_xy, 
256
270
              payload_r0_depth,
257
271
              src_undef());
275
289
      emit_op(c,
276
290
              WM_PIXELW,
277
291
              dst_mask(pixel_w, WRITEMASK_W),
278
 
              0, 0, 0,
 
292
              0,
279
293
              interp_wpos,
280
294
              deltas, 
281
295
              src_undef());
293
307
   struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
294
308
   struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
295
309
   struct prog_src_register deltas = get_delta_xy(c);
296
 
   struct prog_src_register arg2;
297
 
   GLuint opcode;
298
 
   
 
310
 
299
311
   /* Need to use PINTERP on attributes which have been
300
312
    * multiplied by 1/W in the SF program, and LINTERP on those
301
313
    * which have not:
302
314
    */
303
315
   switch (idx) {
304
316
   case FRAG_ATTRIB_WPOS:
305
 
      opcode = WM_LINTERP;
306
 
      arg2 = src_undef();
307
 
 
308
317
      /* Have to treat wpos.xy specially:
309
318
       */
310
319
      emit_op(c,
311
320
              WM_WPOSXY,
312
321
              dst_mask(dst, WRITEMASK_XY),
313
 
              0, 0, 0,
 
322
              0,
314
323
              get_pixel_xy(c),
315
324
              src_undef(),
316
325
              src_undef());
322
331
      emit_op(c,
323
332
              WM_LINTERP,
324
333
              dst,
325
 
              0, 0, 0,
 
334
              0,
326
335
              interp,
327
336
              deltas,
328
 
              arg2);
 
337
              src_undef());
329
338
      break;
330
339
   case FRAG_ATTRIB_COL0:
331
340
   case FRAG_ATTRIB_COL1:
333
342
         emit_op(c,
334
343
                 WM_CINTERP,
335
344
                 dst,
336
 
                 0, 0, 0,
 
345
                 0,
337
346
                 interp,
338
347
                 src_undef(),
339
348
                 src_undef());
342
351
         emit_op(c,
343
352
                 WM_LINTERP,
344
353
                 dst,
345
 
                 0, 0, 0,
 
354
                 0,
346
355
                 interp,
347
356
                 deltas,
348
357
                 src_undef());
349
358
      }
350
359
      break;
 
360
   case FRAG_ATTRIB_FOGC:
 
361
      /* The FOGC input is really special.  When a program uses glFogFragCoord,
 
362
       * the results returned are supposed to be (f,0,0,1).  But for Mesa GLSL,
 
363
       * the glFrontFacing and glPointCoord values are also stashed in FOGC.
 
364
       * So, write the interpolated fog value to X, then either 0, 1, or the
 
365
       * stashed values to Y, Z, W.  Note that this means that
 
366
       * glFogFragCoord.yzw can be wrong in those cases!
 
367
       */
 
368
 
 
369
      /* Interpolate the fog coordinate */
 
370
      emit_op(c,
 
371
              WM_PINTERP,
 
372
              dst_mask(dst, WRITEMASK_X),
 
373
              0,
 
374
              interp,
 
375
              deltas,
 
376
              get_pixel_w(c));
 
377
 
 
378
      /* Move the front facing value into FOGC.y if it's needed. */
 
379
      if (c->fp->program.UsesFrontFacing) {
 
380
         emit_op(c,
 
381
                 WM_FRONTFACING,
 
382
                 dst_mask(dst, WRITEMASK_Y),
 
383
                 0,
 
384
                 src_undef(),
 
385
                 src_undef(),
 
386
                 src_undef());
 
387
      } else {
 
388
         emit_op(c,
 
389
                 OPCODE_MOV,
 
390
                 dst_mask(dst, WRITEMASK_Y),
 
391
                 0,
 
392
                 src_swizzle1(interp, SWIZZLE_ZERO),
 
393
                 src_undef(),
 
394
                 src_undef());
 
395
      }
 
396
 
 
397
      /* Should do the PointCoord thing here. */
 
398
      emit_op(c,
 
399
              OPCODE_MOV,
 
400
              dst_mask(dst, WRITEMASK_ZW),
 
401
              0,
 
402
              src_swizzle(interp,
 
403
                          SWIZZLE_ZERO,
 
404
                          SWIZZLE_ZERO,
 
405
                          SWIZZLE_ZERO,
 
406
                          SWIZZLE_ONE),
 
407
              src_undef(),
 
408
              src_undef());
 
409
      break;
351
410
   default:
352
411
      emit_op(c,
353
412
              WM_PINTERP,
354
413
              dst,
355
 
              0, 0, 0,
 
414
              0,
356
415
              interp,
357
416
              deltas,
358
417
              get_pixel_w(c));
372
431
    emit_op(c,
373
432
            OPCODE_DDX,
374
433
            inst->DstReg,
375
 
            0, 0, 0,
 
434
            0,
376
435
            interp,
377
436
            get_pixel_w(c),
378
437
            src_undef());
388
447
    emit_op(c,
389
448
            OPCODE_DDY,
390
449
            inst->DstReg,
391
 
            0, 0, 0,
 
450
            0,
392
451
            interp,
393
452
            get_pixel_w(c),
394
453
            src_undef());
483
542
      emit_op(c,
484
543
              OPCODE_MUL,
485
544
              dst_mask(dst, WRITEMASK_Y),
486
 
              inst->SaturateMode, 0, 0,
 
545
              inst->SaturateMode,
487
546
              src0,
488
547
              src1,
489
548
              src_undef());
499
558
      swz = emit_op(c,
500
559
                    OPCODE_SWZ,
501
560
                    dst_mask(dst, WRITEMASK_XZ),
502
 
                    inst->SaturateMode, 0, 0,
 
561
                    inst->SaturateMode,
503
562
                    src_swizzle(src0, SWIZZLE_ONE, z, z, z),
504
563
                    src_undef(),
505
564
                    src_undef());
512
571
      emit_op(c,
513
572
              OPCODE_MOV,
514
573
              dst_mask(dst, WRITEMASK_W),
515
 
              inst->SaturateMode, 0, 0,
 
574
              inst->SaturateMode,
516
575
              src1,
517
576
              src_undef(),
518
577
              src_undef());
534
593
      swz = emit_op(c,
535
594
                    OPCODE_SWZ,
536
595
                    dst_mask(dst, WRITEMASK_XW),
537
 
                    0, 0, 0,
 
596
                    0,
538
597
                    src_swizzle1(src0, SWIZZLE_ONE),
539
598
                    src_undef(),
540
599
                    src_undef());
547
606
      emit_op(c,
548
607
              OPCODE_LIT,
549
608
              dst_mask(dst, WRITEMASK_YZ),
550
 
              inst->SaturateMode, 0, 0,
 
609
              inst->SaturateMode,
551
610
              src0,
552
611
              src_undef(),
553
612
              src_undef());
554
613
   }
555
614
}
556
615
 
 
616
 
 
617
/**
 
618
 * Some TEX instructions require extra code, cube map coordinate
 
619
 * normalization, or coordinate scaling for RECT textures, etc.
 
620
 * This function emits those extra instructions and the TEX
 
621
 * instruction itself.
 
622
 */
557
623
static void precalc_tex( struct brw_wm_compile *c,
558
624
                         const struct prog_instruction *inst )
559
625
{
560
626
   struct prog_src_register coord;
561
627
   struct prog_dst_register tmpcoord;
562
 
   GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
 
628
   const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
563
629
 
564
630
   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
565
631
       struct prog_instruction *out;
569
635
       struct prog_src_register tmp1src = src_reg_from_dst(tmp1);
570
636
       struct prog_src_register src0 = inst->SrcReg[0];
571
637
 
 
638
       /* find longest component of coord vector and normalize it */
572
639
       tmpcoord = get_temp(c);
573
640
       coord = src_reg_from_dst(tmpcoord);
574
641
 
 
642
       /* tmpcoord = src0 (i.e.: coord = src0) */
575
643
       out = emit_op(c, OPCODE_MOV,
576
644
                     tmpcoord,
577
 
                     0, 0, 0,
 
645
                     0,
578
646
                     src0,
579
647
                     src_undef(),
580
648
                     src_undef());
581
649
       out->SrcReg[0].NegateBase = 0;
582
650
       out->SrcReg[0].Abs = 1;
583
651
 
 
652
       /* tmp0 = MAX(coord.X, coord.Y) */
584
653
       emit_op(c, OPCODE_MAX,
585
654
               tmp0,
586
 
               0, 0, 0,
 
655
               0,
587
656
               src_swizzle1(coord, X),
588
657
               src_swizzle1(coord, Y),
589
658
               src_undef());
590
659
 
 
660
       /* tmp1 = MAX(tmp0, coord.Z) */
591
661
       emit_op(c, OPCODE_MAX,
592
662
               tmp1,
593
 
               0, 0, 0,
 
663
               0,
594
664
               tmp0src,
595
665
               src_swizzle1(coord, Z),
596
666
               src_undef());
597
667
 
 
668
       /* tmp0 = 1 / tmp1 */
598
669
       emit_op(c, OPCODE_RCP,
599
670
               tmp0,
600
 
               0, 0, 0,
 
671
               0,
601
672
               tmp1src,
602
673
               src_undef(),
603
674
               src_undef());
604
675
 
 
676
       /* tmpCoord = src0 * tmp0 */
605
677
       emit_op(c, OPCODE_MUL,
606
678
               tmpcoord,
607
 
               0, 0, 0,
 
679
               0,
608
680
               src0,
609
681
               tmp0src,
610
682
               src_undef());
611
683
 
612
684
       release_temp(c, tmp0);
613
685
       release_temp(c, tmp1);
614
 
   } else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
 
686
   }
 
687
   else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
615
688
      struct prog_src_register scale = 
616
689
         search_or_add_param5( c, 
617
690
                               STATE_INTERNAL, 
626
699
      emit_op(c,
627
700
              OPCODE_MUL,
628
701
              tmpcoord,
629
 
              0, 0, 0,
 
702
              0,
630
703
              inst->SrcReg[0],
631
704
              scale,
632
705
              src_undef());
642
715
    * conversion requires allocating a temporary variable which we
643
716
    * don't have the facility to do that late in the compilation.
644
717
    */
645
 
   if (!(c->key.yuvtex_mask & (1<<unit))) {
646
 
      emit_op(c, 
647
 
              OPCODE_TEX,
648
 
              inst->DstReg,
649
 
              inst->SaturateMode,
650
 
              unit,
651
 
              inst->TexSrcTarget,
652
 
              coord,
653
 
              src_undef(),
654
 
              src_undef());
655
 
   }
656
 
   else {
657
 
       GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
 
718
   if (c->key.yuvtex_mask & (1 << unit)) {
 
719
      /* convert ycbcr to RGBA */
 
720
      GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
658
721
 
659
722
      /* 
660
723
         CONST C0 = { -.5, -.0625,  -.5, 1.164 }
676
739
     
677
740
      /* tmp     = TEX ...
678
741
       */
679
 
      emit_op(c, 
680
 
              OPCODE_TEX,
681
 
              tmp,
682
 
              inst->SaturateMode,
683
 
              unit,
684
 
              inst->TexSrcTarget,
685
 
              coord,
686
 
              src_undef(),
687
 
              src_undef());
 
742
      emit_tex_op(c, 
 
743
                  OPCODE_TEX,
 
744
                  tmp,
 
745
                  inst->SaturateMode,
 
746
                  unit,
 
747
                  inst->TexSrcTarget,
 
748
                  coord,
 
749
                  src_undef(),
 
750
                  src_undef());
688
751
 
689
752
      /* tmp.xyz =  ADD TMP, C0
690
753
       */
691
754
      emit_op(c,
692
755
              OPCODE_ADD,
693
756
              dst_mask(tmp, WRITEMASK_XYZ),
694
 
              0, 0, 0,
 
757
              0,
695
758
              tmpsrc,
696
759
              C0,
697
760
              src_undef());
702
765
      emit_op(c,
703
766
              OPCODE_MUL,
704
767
              dst_mask(tmp, WRITEMASK_Y),
705
 
              0, 0, 0,
 
768
              0,
706
769
              tmpsrc,
707
770
              src_swizzle1(C0, W),
708
771
              src_undef());
717
780
      emit_op(c,
718
781
              OPCODE_MAD,
719
782
              dst_mask(dst, WRITEMASK_XYZ),
720
 
              0, 0, 0,
 
783
              0,
721
784
              swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
722
785
              C1,
723
786
              src_swizzle1(tmpsrc, Y));
727
790
      emit_op(c,
728
791
              OPCODE_MAD,
729
792
              dst_mask(dst, WRITEMASK_Y),
730
 
              0, 0, 0,
 
793
              0,
731
794
              src_swizzle1(tmpsrc, Z),
732
795
              src_swizzle1(C1, W),
733
796
              src_swizzle1(src_reg_from_dst(dst), Y));
734
797
 
735
798
      release_temp(c, tmp);
736
799
   }
 
800
   else {
 
801
      /* ordinary RGBA tex instruction */
 
802
      emit_tex_op(c, 
 
803
                  OPCODE_TEX,
 
804
                  inst->DstReg,
 
805
                  inst->SaturateMode,
 
806
                  unit,
 
807
                  inst->TexSrcTarget,
 
808
                  coord,
 
809
                  src_undef(),
 
810
                  src_undef());
 
811
   }
737
812
 
738
813
   if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
739
814
       (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
778
853
      emit_op(c,
779
854
              OPCODE_RCP,
780
855
              dst_mask(tmp, WRITEMASK_W),
781
 
              0, 0, 0,
 
856
              0,
782
857
              src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
783
858
              src_undef(),
784
859
              src_undef());
788
863
      emit_op(c,
789
864
              OPCODE_MUL,
790
865
              dst_mask(tmp, WRITEMASK_XYZ),
791
 
              0, 0, 0,
 
866
              0,
792
867
              src0,
793
868
              src_swizzle1(src_reg_from_dst(tmp), W),
794
869
              src_undef());
828
903
       for (i = 0 ; i < brw->state.nr_draw_regions; i++) {
829
904
           outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
830
905
           last_inst = inst = emit_op(c,
831
 
                   WM_FB_WRITE, dst_mask(dst_undef(),0), 0, 0, 0,
 
906
                   WM_FB_WRITE, dst_mask(dst_undef(),0), 0,
832
907
                   outcolor, payload_r0_depth, outdepth);
833
908
           inst->Sampler = (i<<1);
834
909
           if (c->fp_fragcolor_emitted) {
835
910
               outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
836
911
               last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
837
 
                       0, 0, 0, outcolor, payload_r0_depth, outdepth);
 
912
                       0, outcolor, payload_r0_depth, outdepth);
838
913
               inst->Sampler = (i<<1);
839
914
           }
840
915
       }
848
923
         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
849
924
 
850
925
       inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
851
 
               0, 0, 0, outcolor, payload_r0_depth, outdepth);
 
926
               0, outcolor, payload_r0_depth, outdepth);
852
927
       inst->Sampler = 1|(0<<1);
853
928
   }
854
929
}
902
977
                                     3);
903
978
      }
904
979
      else 
905
 
         _mesa_printf("UNKNOWN\n");
906
 
           
 
980
         _mesa_printf("965 Opcode %d\n", insn->Opcode);
907
981
   }
908
982
}
909
983