399
401
int u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1;
400
402
struct prog_src_register src[3];
402
if (getenv("R300_VP_SAFETY")) {
403
WARN_ONCE("R300_VP_SAFETY enabled.\n");
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));
408
for (i=0; i < VSF_MAX_FRAGMENT_TEMPS; i++) {
409
vpi[i].Opcode = OPCODE_MOV;
410
vpi[i].StringPos = 0;
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;
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);
423
memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
425
free(mesa_vp->Base.Instructions);
427
mesa_vp->Base.Instructions = vpi;
429
mesa_vp->Base.NumInstructions += VSF_MAX_FRAGMENT_TEMPS;
430
vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
432
assert(vpi->Opcode == OPCODE_END);
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 };
440
tokens[5] = STATE_MATRIX;
442
tokens[5] = STATE_MATRIX_TRANSPOSE;
444
paramList = mesa_vp->Base.Parameters;
446
vpi = malloc((mesa_vp->Base.NumInstructions + 4) * sizeof(struct prog_instruction));
447
memset(vpi, 0, 4 * sizeof(struct prog_instruction));
449
for (i=0; i < 4; i++) {
451
tokens[3] = tokens[4] = i;
452
idx = _mesa_add_state_reference(paramList, tokens);
454
vpi[i].Opcode = OPCODE_DP4;
455
vpi[i].StringPos = 0;
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;
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);
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);
472
vpi[i].Opcode = OPCODE_MUL;
474
vpi[i].Opcode = OPCODE_MAD;
476
vpi[i].StringPos = 0;
480
vpi[i].DstReg.File = PROGRAM_OUTPUT;
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;
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);
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);
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);
503
memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
505
free(mesa_vp->Base.Instructions);
507
mesa_vp->Base.Instructions = vpi;
509
mesa_vp->Base.NumInstructions += 4;
510
vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
512
assert(vpi->Opcode == OPCODE_END);
514
mesa_vp->Base.InputsRead |= (1 << VERT_ATTRIB_POS);
515
mesa_vp->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
517
//fprintf(stderr, "IsPositionInvariant is set!\n");
518
//_mesa_print_program(&mesa_vp->Base);
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;*/
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;
531
assert(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS));
414
assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS));
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++;
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++;
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++;
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++;
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++;
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++;
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++;
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++;
561
444
vp->translated = GL_TRUE;
562
445
vp->native = GL_TRUE;
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++){
451
if(!valid_dst(vp, &vpi->DstReg))
453
/* redirect result to unused temp */
454
vpi->DstReg.File = PROGRAM_TEMPORARY;
455
vpi->DstReg.Index = u_temp_i;
568
458
operands=op_operands(vpi->Opcode);
569
459
are_srcs_scalar=operands & SCALAR_FLAG;
877
static void position_invariant(struct gl_program *prog)
879
struct prog_instruction *vpi;
880
struct gl_program_parameter_list *paramList;
883
GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
886
tokens[5] = STATE_MATRIX;
888
tokens[5] = STATE_MATRIX_TRANSPOSE;
890
paramList = prog->Parameters;
892
vpi = malloc((prog->NumInstructions + 4) * sizeof(struct prog_instruction));
893
memset(vpi, 0, 4 * sizeof(struct prog_instruction));
895
for (i=0; i < 4; i++) {
897
tokens[3] = tokens[4] = i;
898
idx = _mesa_add_state_reference(paramList, tokens);
900
vpi[i].Opcode = OPCODE_DP4;
901
vpi[i].StringPos = 0;
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;
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);
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);
918
vpi[i].Opcode = OPCODE_MUL;
920
vpi[i].Opcode = OPCODE_MAD;
922
vpi[i].StringPos = 0;
926
vpi[i].DstReg.File = PROGRAM_OUTPUT;
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;
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);
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);
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);
949
memcpy(&vpi[i], prog->Instructions, prog->NumInstructions * sizeof(struct prog_instruction));
951
free(prog->Instructions);
953
prog->Instructions = vpi;
955
prog->NumInstructions += 4;
956
vpi = &prog->Instructions[prog->NumInstructions-1];
958
assert(vpi->Opcode == OPCODE_END);
961
static void insert_wpos(struct r300_vertex_program *vp,
962
struct gl_program *prog,
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;
973
vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction));
974
memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction));
976
vpi_insert = &vpi[pos];
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;
983
memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction));
985
vpi_insert[i].Opcode = OPCODE_MOV;
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;
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);
997
/* perspective divide */
998
vpi_insert[i].Opcode = OPCODE_RCP;
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;
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);
1010
vpi_insert[i].Opcode = OPCODE_MUL;
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;
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);
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);
1026
/* viewport transformation */
1027
window_index = _mesa_add_state_reference(prog->Parameters, tokens);
1029
vpi_insert[i].Opcode = OPCODE_MAD;
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;
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);
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);
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);
1049
vpi_insert[i].Opcode = OPCODE_MUL;
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;
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);
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);
1065
memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction));
1067
free(prog->Instructions);
1069
prog->Instructions = vpi;
1071
prog->NumInstructions += i;
1072
vpi = &prog->Instructions[prog->NumInstructions-1];
1074
assert(vpi->Opcode == OPCODE_END);
1077
static void pos_as_texcoord(struct r300_vertex_program *vp,
1078
struct gl_program *prog)
1080
struct prog_instruction *vpi;
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);
1093
static struct r300_vertex_program *build_program(struct r300_vertex_program_key *wanted_key,
1094
struct gl_vertex_program *mesa_vp,
1097
struct r300_vertex_program *vp;
1099
vp = _mesa_calloc(sizeof(*vp));
1100
_mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
1102
vp->wpos_idx = wpos_idx;
1104
if(mesa_vp->IsPositionInvariant)
1105
position_invariant(&mesa_vp->Base);
1108
pos_as_texcoord(vp, &mesa_vp->Base);
1110
assert(mesa_vp->Base.NumInstructions);
1112
vp->num_temporaries=mesa_vp->Base.NumTemporaries;
1114
r300_translate_vertex_shader(vp, mesa_vp->Base.Instructions);
1119
void r300_select_vertex_shader(r300ContextPtr r300)
1121
GLcontext *ctx = ctx = r300->radeon.glCtx;
1123
struct r300_vertex_program_key wanted_key = { 0 };
1125
struct r300_vertex_program_cont *vpc;
1126
struct r300_vertex_program *vp;
1129
vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
1130
InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
1132
wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
1135
if (InputsRead & FRAG_BIT_WPOS){
1136
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
1137
if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
1140
if(i == ctx->Const.MaxTextureUnits){
1141
fprintf(stderr, "\tno free texcoord found\n");
1145
InputsRead |= (FRAG_BIT_TEX0 << i);
1149
if (InputsRead & FRAG_BIT_COL0)
1150
wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
1152
if ((InputsRead & FRAG_BIT_COL1) /*||
1153
(InputsRead & FRAG_BIT_FOGC)*/)
1154
wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1;
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);
1160
wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
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;
1168
//_mesa_print_program(&vpc->mesa_program.Base);
1170
vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx);
1171
vp->next = vpc->progs;
1174
r300->selected_vp = vp;