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

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r300/r300_vertexprog.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:
95
95
};
96
96
#undef OPN
97
97
        
98
 
int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp, float *dst)
 
98
int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont *vp, float *dst)
99
99
{
100
100
        int pi;
101
 
        struct gl_vertex_program *mesa_vp=(void *)vp;
 
101
        struct gl_vertex_program *mesa_vp = &vp->mesa_program;
102
102
        float *dst_o=dst;
103
103
        struct gl_program_parameter_list *paramList;
104
104
        
177
177
 
178
178
static unsigned long t_dst_index(struct r300_vertex_program *vp, struct prog_dst_register *dst)
179
179
{
180
 
        if(dst->File == PROGRAM_OUTPUT) {
181
 
                if (vp->outputs[dst->Index] != -1)
182
 
                        return vp->outputs[dst->Index];
183
 
                else {
184
 
                        WARN_ONCE("Unknown output %d\n", dst->Index);
185
 
                        return 10;
186
 
                }
187
 
        }else if(dst->File == PROGRAM_ADDRESS) {
188
 
                assert(dst->Index == 0);
189
 
        }
190
 
        
 
180
        if(dst->File == PROGRAM_OUTPUT)
 
181
                return vp->outputs[dst->Index];
 
182
 
191
183
        return dst->Index;
192
184
}
193
185
 
335
327
        return 0;
336
328
}
337
329
 
 
330
static GLboolean valid_dst(struct r300_vertex_program *vp, struct prog_dst_register *dst)
 
331
{
 
332
        if(dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1){
 
333
                WARN_ONCE("Output %d not used by fragment program\n", dst->Index);
 
334
                return GL_FALSE;
 
335
        }else if(dst->File == PROGRAM_ADDRESS) {
 
336
                assert(dst->Index == 0);
 
337
        }
 
338
        
 
339
        return GL_TRUE;
 
340
}
 
341
 
338
342
/* TODO: Get rid of t_src_class call */
339
343
#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \
340
344
                       ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \
384
388
                u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
385
389
        } while (0)
386
390
 
387
 
void r300_translate_vertex_shader(struct r300_vertex_program *vp)
 
391
static void r300_translate_vertex_shader(struct r300_vertex_program *vp, struct prog_instruction *vpi)
388
392
{
389
 
        struct gl_vertex_program *mesa_vp=(void *)vp;
390
 
        struct prog_instruction *vpi;
391
393
        int i, cur_reg=0;
392
394
        VERTEX_SHADER_INSTRUCTION *o_inst;
393
395
        unsigned long operands;
399
401
        int u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1;
400
402
        struct prog_src_register src[3];
401
403
 
402
 
        if (getenv("R300_VP_SAFETY")) {
403
 
                WARN_ONCE("R300_VP_SAFETY enabled.\n");
404
 
                
405
 
                vpi = malloc((mesa_vp->Base.NumInstructions + VSF_MAX_FRAGMENT_TEMPS) * sizeof(struct prog_instruction));
406
 
                memset(vpi, 0, VSF_MAX_FRAGMENT_TEMPS * sizeof(struct prog_instruction));
407
 
                
408
 
                for (i=0; i < VSF_MAX_FRAGMENT_TEMPS; i++) {
409
 
                        vpi[i].Opcode = OPCODE_MOV;
410
 
                        vpi[i].StringPos = 0;
411
 
                        vpi[i].Data = 0;
412
 
                        
413
 
                        vpi[i].DstReg.File = PROGRAM_TEMPORARY;
414
 
                        vpi[i].DstReg.Index = i;
415
 
                        vpi[i].DstReg.WriteMask = WRITEMASK_XYZW;
416
 
                        vpi[i].DstReg.CondMask = COND_TR;
417
 
                                        
418
 
                        vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
419
 
                        vpi[i].SrcReg[0].Index = 0;
420
 
                        vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE);
421
 
                }
422
 
                
423
 
                memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
424
 
                
425
 
                free(mesa_vp->Base.Instructions);
426
 
                
427
 
                mesa_vp->Base.Instructions = vpi;
428
 
                
429
 
                mesa_vp->Base.NumInstructions += VSF_MAX_FRAGMENT_TEMPS;
430
 
                vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
431
 
                
432
 
                assert(vpi->Opcode == OPCODE_END);
433
 
        }
434
 
        
435
 
        if (mesa_vp->IsPositionInvariant) {
436
 
                struct gl_program_parameter_list *paramList;
437
 
                GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
438
 
 
439
 
#ifdef PREFER_DP4
440
 
                tokens[5] = STATE_MATRIX;
441
 
#else
442
 
                tokens[5] = STATE_MATRIX_TRANSPOSE;
443
 
#endif
444
 
                paramList = mesa_vp->Base.Parameters;
445
 
                
446
 
                vpi = malloc((mesa_vp->Base.NumInstructions + 4) * sizeof(struct prog_instruction));
447
 
                memset(vpi, 0, 4 * sizeof(struct prog_instruction));
448
 
                
449
 
                for (i=0; i < 4; i++) {
450
 
                        GLint idx;
451
 
                        tokens[3] = tokens[4] = i;
452
 
                        idx = _mesa_add_state_reference(paramList, tokens);
453
 
#ifdef PREFER_DP4
454
 
                        vpi[i].Opcode = OPCODE_DP4;
455
 
                        vpi[i].StringPos = 0;
456
 
                        vpi[i].Data = 0;
457
 
                        
458
 
                        vpi[i].DstReg.File = PROGRAM_OUTPUT;
459
 
                        vpi[i].DstReg.Index = VERT_RESULT_HPOS;
460
 
                        vpi[i].DstReg.WriteMask = 1 << i;
461
 
                        vpi[i].DstReg.CondMask = COND_TR;
462
 
                                        
463
 
                        vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
464
 
                        vpi[i].SrcReg[0].Index = idx;
465
 
                        vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
466
 
                        
467
 
                        vpi[i].SrcReg[1].File = PROGRAM_INPUT;
468
 
                        vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
469
 
                        vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
470
 
#else
471
 
                        if (i == 0)
472
 
                                vpi[i].Opcode = OPCODE_MUL;
473
 
                        else
474
 
                                vpi[i].Opcode = OPCODE_MAD;
475
 
                        
476
 
                        vpi[i].StringPos = 0;
477
 
                        vpi[i].Data = 0;
478
 
                        
479
 
                        if (i == 3)
480
 
                                vpi[i].DstReg.File = PROGRAM_OUTPUT;
481
 
                        else
482
 
                                vpi[i].DstReg.File = PROGRAM_TEMPORARY;
483
 
                        vpi[i].DstReg.Index = 0;
484
 
                        vpi[i].DstReg.WriteMask = 0xf;
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(i, i, i, i);
494
 
                        
495
 
                        if (i > 0) {
496
 
                                vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
497
 
                                vpi[i].SrcReg[2].Index = 0;
498
 
                                vpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
499
 
                        }
500
 
#endif                                  
501
 
                }
502
 
                
503
 
                memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
504
 
                
505
 
                free(mesa_vp->Base.Instructions);
506
 
                
507
 
                mesa_vp->Base.Instructions = vpi;
508
 
                
509
 
                mesa_vp->Base.NumInstructions += 4;
510
 
                vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
511
 
                
512
 
                assert(vpi->Opcode == OPCODE_END);
513
 
                
514
 
                mesa_vp->Base.InputsRead |= (1 << VERT_ATTRIB_POS);
515
 
                mesa_vp->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
516
 
                
517
 
                //fprintf(stderr, "IsPositionInvariant is set!\n");
518
 
                //_mesa_print_program(&mesa_vp->Base);
519
 
        }
520
 
        
521
404
        vp->pos_end=0; /* Not supported yet */
522
405
        vp->program.length=0;
523
 
        vp->num_temporaries=mesa_vp->Base.NumTemporaries;
 
406
        /*vp->num_temporaries=mesa_vp->Base.NumTemporaries;*/
524
407
        
525
408
        for(i=0; i < VERT_ATTRIB_MAX; i++)
526
409
                vp->inputs[i] = -1;
528
411
        for(i=0; i < VERT_RESULT_MAX; i++)
529
412
                vp->outputs[i] = -1;
530
413
        
531
 
        assert(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS));
 
414
        assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS));
532
415
        
533
416
        /* Assign outputs */
534
 
        if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))
 
417
        if(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS))
535
418
                vp->outputs[VERT_RESULT_HPOS] = cur_reg++;
536
419
        
537
 
        if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ))
 
420
        if(vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ))
538
421
                vp->outputs[VERT_RESULT_PSIZ] = cur_reg++;
539
422
        
540
 
        if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL0))
 
423
        if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL0))
541
424
                vp->outputs[VERT_RESULT_COL0] = cur_reg++;
542
425
        
543
 
        if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL1))
 
426
        if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL1))
544
427
                vp->outputs[VERT_RESULT_COL1] = cur_reg++;
545
428
        
546
429
#if 0 /* Not supported yet */
547
 
        if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC0))
 
430
        if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0))
548
431
                vp->outputs[VERT_RESULT_BFC0] = cur_reg++;
549
432
        
550
 
        if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC1))
 
433
        if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1))
551
434
                vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
552
435
        
553
 
        if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC))
 
436
        if(vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC))
554
437
                vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
555
438
#endif
556
439
        
557
440
        for(i=VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++)
558
 
                if(mesa_vp->Base.OutputsWritten & (1 << i))
 
441
                if(vp->key.OutputsWritten & (1 << i))
559
442
                        vp->outputs[i] = cur_reg++;
560
443
        
561
444
        vp->translated = GL_TRUE;
562
445
        vp->native = GL_TRUE;
563
446
        
564
447
        o_inst=vp->program.body.i;
565
 
        for(vpi=mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
 
448
        for(; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
566
449
                FREE_TEMPS();
 
450
 
 
451
                if(!valid_dst(vp, &vpi->DstReg))
 
452
                {
 
453
                        /* redirect result to unused temp */
 
454
                        vpi->DstReg.File = PROGRAM_TEMPORARY;
 
455
                        vpi->DstReg.Index = u_temp_i;
 
456
                }
567
457
                
568
458
                operands=op_operands(vpi->Opcode);
569
459
                are_srcs_scalar=operands & SCALAR_FLAG;
984
874
#endif
985
875
}
986
876
 
 
877
static void position_invariant(struct gl_program *prog)
 
878
{
 
879
        struct prog_instruction *vpi;
 
880
        struct gl_program_parameter_list *paramList;
 
881
        int i;
 
882
 
 
883
        GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
 
884
 
 
885
#ifdef PREFER_DP4
 
886
        tokens[5] = STATE_MATRIX;
 
887
#else
 
888
        tokens[5] = STATE_MATRIX_TRANSPOSE;
 
889
#endif
 
890
        paramList = prog->Parameters;
 
891
 
 
892
        vpi = malloc((prog->NumInstructions + 4) * sizeof(struct prog_instruction));
 
893
        memset(vpi, 0, 4 * sizeof(struct prog_instruction));
 
894
 
 
895
        for (i=0; i < 4; i++) {
 
896
                GLint idx;
 
897
                tokens[3] = tokens[4] = i;
 
898
                idx = _mesa_add_state_reference(paramList, tokens);
 
899
#ifdef PREFER_DP4
 
900
                vpi[i].Opcode = OPCODE_DP4;
 
901
                vpi[i].StringPos = 0;
 
902
                vpi[i].Data = 0;
 
903
 
 
904
                vpi[i].DstReg.File = PROGRAM_OUTPUT;
 
905
                vpi[i].DstReg.Index = VERT_RESULT_HPOS;
 
906
                vpi[i].DstReg.WriteMask = 1 << i;
 
907
                vpi[i].DstReg.CondMask = COND_TR;
 
908
 
 
909
                vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
 
910
                vpi[i].SrcReg[0].Index = idx;
 
911
                vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
 
912
 
 
913
                vpi[i].SrcReg[1].File = PROGRAM_INPUT;
 
914
                vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
 
915
                vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
 
916
#else
 
917
                if (i == 0)
 
918
                        vpi[i].Opcode = OPCODE_MUL;
 
919
                else
 
920
                        vpi[i].Opcode = OPCODE_MAD;
 
921
 
 
922
                vpi[i].StringPos = 0;
 
923
                vpi[i].Data = 0;
 
924
 
 
925
                if (i == 3)
 
926
                        vpi[i].DstReg.File = PROGRAM_OUTPUT;
 
927
                else
 
928
                        vpi[i].DstReg.File = PROGRAM_TEMPORARY;
 
929
                vpi[i].DstReg.Index = 0;
 
930
                vpi[i].DstReg.WriteMask = 0xf;
 
931
                vpi[i].DstReg.CondMask = COND_TR;
 
932
 
 
933
                vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
 
934
                vpi[i].SrcReg[0].Index = idx;
 
935
                vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
 
936
 
 
937
                vpi[i].SrcReg[1].File = PROGRAM_INPUT;
 
938
                vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
 
939
                vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i);
 
940
 
 
941
                if (i > 0) {
 
942
                        vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
 
943
                        vpi[i].SrcReg[2].Index = 0;
 
944
                        vpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
 
945
                }
 
946
#endif                                  
 
947
        }
 
948
 
 
949
        memcpy(&vpi[i], prog->Instructions, prog->NumInstructions * sizeof(struct prog_instruction));
 
950
 
 
951
        free(prog->Instructions);
 
952
 
 
953
        prog->Instructions = vpi;
 
954
 
 
955
        prog->NumInstructions += 4;
 
956
        vpi = &prog->Instructions[prog->NumInstructions-1];
 
957
 
 
958
        assert(vpi->Opcode == OPCODE_END);
 
959
}
 
960
 
 
961
static void insert_wpos(struct r300_vertex_program *vp,
 
962
                       struct gl_program *prog,
 
963
                       GLint pos)
 
964
{
 
965
 
 
966
        GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0, 0 };
 
967
        struct prog_instruction *vpi;
 
968
        struct prog_instruction *vpi_insert;
 
969
        GLuint temp_index;
 
970
        GLuint window_index;
 
971
        int i = 0;
 
972
        
 
973
        vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction));
 
974
        memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction));
 
975
        
 
976
        vpi_insert = &vpi[pos];
 
977
 
 
978
        /* make a copy before outputting VERT_RESULT_HPOS */
 
979
        vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File;
 
980
        vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index;
 
981
        
 
982
        vpi_insert++;
 
983
        memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction));
 
984
 
 
985
        vpi_insert[i].Opcode = OPCODE_MOV;
 
986
 
 
987
        vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
 
988
        vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS;
 
989
        vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
 
990
        vpi_insert[i].DstReg.CondMask = COND_TR;
 
991
 
 
992
        vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
 
993
        vpi_insert[i].SrcReg[0].Index = temp_index;
 
994
        vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
 
995
        i++;
 
996
 
 
997
        /* perspective divide */
 
998
        vpi_insert[i].Opcode = OPCODE_RCP;
 
999
 
 
1000
        vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
 
1001
        vpi_insert[i].DstReg.Index = temp_index;
 
1002
        vpi_insert[i].DstReg.WriteMask = WRITEMASK_W;
 
1003
        vpi_insert[i].DstReg.CondMask = COND_TR;
 
1004
 
 
1005
        vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
 
1006
        vpi_insert[i].SrcReg[0].Index = temp_index;
 
1007
        vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
 
1008
        i++;
 
1009
 
 
1010
        vpi_insert[i].Opcode = OPCODE_MUL;
 
1011
 
 
1012
        vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
 
1013
        vpi_insert[i].DstReg.Index = temp_index;
 
1014
        vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
 
1015
        vpi_insert[i].DstReg.CondMask = COND_TR;
 
1016
 
 
1017
        vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
 
1018
        vpi_insert[i].SrcReg[0].Index = temp_index;
 
1019
        vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
 
1020
 
 
1021
        vpi_insert[i].SrcReg[1].File = PROGRAM_TEMPORARY;
 
1022
        vpi_insert[i].SrcReg[1].Index = temp_index;
 
1023
        vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_ZERO);
 
1024
        i++;
 
1025
 
 
1026
        /* viewport transformation */
 
1027
        window_index = _mesa_add_state_reference(prog->Parameters, tokens);
 
1028
 
 
1029
        vpi_insert[i].Opcode = OPCODE_MAD;
 
1030
 
 
1031
        vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
 
1032
        vpi_insert[i].DstReg.Index = temp_index;
 
1033
        vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
 
1034
        vpi_insert[i].DstReg.CondMask = COND_TR;
 
1035
 
 
1036
        vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
 
1037
        vpi_insert[i].SrcReg[0].Index = temp_index;
 
1038
        vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
 
1039
 
 
1040
        vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR;
 
1041
        vpi_insert[i].SrcReg[1].Index = window_index;
 
1042
        vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_ZERO);
 
1043
 
 
1044
        vpi_insert[i].SrcReg[2].File = PROGRAM_STATE_VAR;
 
1045
        vpi_insert[i].SrcReg[2].Index = window_index;
 
1046
        vpi_insert[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_ZERO);
 
1047
        i++;
 
1048
 
 
1049
        vpi_insert[i].Opcode = OPCODE_MUL;
 
1050
 
 
1051
        vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
 
1052
        vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0+vp->wpos_idx;
 
1053
        vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
 
1054
        vpi_insert[i].DstReg.CondMask = COND_TR;
 
1055
 
 
1056
        vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
 
1057
        vpi_insert[i].SrcReg[0].Index = temp_index;
 
1058
        vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
 
1059
 
 
1060
        vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR;
 
1061
        vpi_insert[i].SrcReg[1].Index = window_index;
 
1062
        vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE);
 
1063
        i++;
 
1064
 
 
1065
        memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction));
 
1066
 
 
1067
        free(prog->Instructions);
 
1068
 
 
1069
        prog->Instructions = vpi;
 
1070
 
 
1071
        prog->NumInstructions += i;
 
1072
        vpi = &prog->Instructions[prog->NumInstructions-1];
 
1073
 
 
1074
        assert(vpi->Opcode == OPCODE_END);
 
1075
}
 
1076
 
 
1077
static void pos_as_texcoord(struct r300_vertex_program *vp,
 
1078
                            struct gl_program *prog)
 
1079
{
 
1080
        struct prog_instruction *vpi;
 
1081
        int pos = 0;
 
1082
        
 
1083
        for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){
 
1084
                if( vpi->DstReg.File == PROGRAM_OUTPUT &&
 
1085
                    vpi->DstReg.Index == VERT_RESULT_HPOS ){
 
1086
                        insert_wpos(vp, prog, pos);
 
1087
                        break;
 
1088
                }
 
1089
        }
 
1090
 
 
1091
}
 
1092
 
 
1093
static struct r300_vertex_program *build_program(struct r300_vertex_program_key *wanted_key,
 
1094
                                                 struct gl_vertex_program *mesa_vp,
 
1095
                                                 GLint wpos_idx)
 
1096
{
 
1097
        struct r300_vertex_program *vp;
 
1098
 
 
1099
        vp = _mesa_calloc(sizeof(*vp));
 
1100
        _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
 
1101
 
 
1102
        vp->wpos_idx = wpos_idx;
 
1103
 
 
1104
        if(mesa_vp->IsPositionInvariant)
 
1105
                position_invariant(&mesa_vp->Base);
 
1106
 
 
1107
        if(wpos_idx > -1)
 
1108
                pos_as_texcoord(vp, &mesa_vp->Base);
 
1109
 
 
1110
        assert(mesa_vp->Base.NumInstructions);
 
1111
 
 
1112
        vp->num_temporaries=mesa_vp->Base.NumTemporaries;
 
1113
 
 
1114
        r300_translate_vertex_shader(vp, mesa_vp->Base.Instructions);
 
1115
 
 
1116
        return vp;      
 
1117
}
 
1118
 
 
1119
void r300_select_vertex_shader(r300ContextPtr r300)
 
1120
{
 
1121
        GLcontext *ctx = ctx = r300->radeon.glCtx;
 
1122
        GLuint InputsRead;
 
1123
        struct r300_vertex_program_key wanted_key = { 0 };
 
1124
        GLint i;
 
1125
        struct r300_vertex_program_cont *vpc;
 
1126
        struct r300_vertex_program *vp;
 
1127
        GLint wpos_idx;
 
1128
 
 
1129
        vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
 
1130
        InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
 
1131
 
 
1132
        wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
 
1133
 
 
1134
        wpos_idx = -1;
 
1135
        if (InputsRead & FRAG_BIT_WPOS){
 
1136
                for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
 
1137
                        if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
 
1138
                                break;
 
1139
                
 
1140
                if(i == ctx->Const.MaxTextureUnits){
 
1141
                        fprintf(stderr, "\tno free texcoord found\n");
 
1142
                        exit(0);
 
1143
                }
 
1144
 
 
1145
                InputsRead |= (FRAG_BIT_TEX0 << i);
 
1146
                wpos_idx = i;
 
1147
        }
 
1148
 
 
1149
        if (InputsRead & FRAG_BIT_COL0)
 
1150
                wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
 
1151
 
 
1152
        if ((InputsRead & FRAG_BIT_COL1) /*||
 
1153
            (InputsRead & FRAG_BIT_FOGC)*/)
 
1154
                wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1;
 
1155
        
 
1156
        for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
 
1157
                if (InputsRead & (FRAG_BIT_TEX0 << i))
 
1158
                        wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
 
1159
 
 
1160
        wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
 
1161
 
 
1162
        for (vp = vpc->progs; vp; vp = vp->next)
 
1163
                if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) {
 
1164
                        r300->selected_vp = vp;
 
1165
                        return ;
 
1166
                }
 
1167
 
 
1168
        //_mesa_print_program(&vpc->mesa_program.Base);
 
1169
 
 
1170
        vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx);
 
1171
        vp->next = vpc->progs;
 
1172
        vpc->progs = vp;
 
1173
 
 
1174
        r300->selected_vp = vp;
 
1175
}