Skip to content

Commit ff637cc

Browse files
author
Marcin Kościelnicki
committed
hwtest/pgraph: Model XFPR.
1 parent 01b3ed2 commit ff637cc

File tree

1 file changed

+113
-4
lines changed

1 file changed

+113
-4
lines changed

Diff for: nvhw/pgraph_kelvin.c

+113-4
Original file line numberDiff line numberDiff line change
@@ -456,15 +456,98 @@ void pgraph_ld_xfpr(struct pgraph_state *state, uint32_t which, int comp, uint32
456456
pgraph_xf_cmd(state, 2, addr, addr & 4 ? 2 : 1, a, a);
457457
state->vab[0x10][comp] = a;
458458
if (state->chipset.card_type == 0x20) {
459+
if (which >= 0x88)
460+
return;
459461
state->xfpr[which][0] = state->vab[0x10][3];
460462
state->xfpr[which][1] = state->vab[0x10][2];
461463
state->xfpr[which][2] = state->vab[0x10][1] & 0x0fffffff;
462464
state->xfpr[which][3] = 0;
463465
} else {
464-
state->xfpr[which][0] = state->vab[0x10][3];
465-
state->xfpr[which][1] = state->vab[0x10][2];
466-
state->xfpr[which][2] = state->vab[0x10][1];
467-
state->xfpr[which][3] = state->vab[0x10][0] & 0x03ffffff;
466+
if (which >= 0x118)
467+
return;
468+
if (nv04_pgraph_is_kelvin_class(state)) {
469+
uint32_t swa = state->vab[0x10][3];
470+
uint32_t swb = state->vab[0x10][2];
471+
uint32_t swc = state->vab[0x10][1];
472+
uint32_t wa = 0, wb = 0, wc = 0, wd = 0;
473+
insrt(wa, 0, 1, extr(swa, 0, 1)); // END
474+
insrt(wa, 1, 1, extr(swa, 1, 1)); // INDEX_CONST
475+
int rdst_wm_sca = extr(swa, 16, 4);
476+
int rdst = extr(swa, 20, 4);
477+
int rdst_wm_vec = extr(swa, 24, 4);
478+
int vop = extr(swc, 21, 4);
479+
int sop = extr(swc, 25, 3);
480+
if (vop == 0xd)
481+
rdst = 0;
482+
if (rdst > 0xb) {
483+
rdst = 0xb;
484+
rdst_wm_vec = 0;
485+
if (vop == 0 || vop > 0xd)
486+
rdst_wm_sca = 0;
487+
}
488+
int dst = extr(swa, 3, 8);
489+
if (!extr(swa, 11, 1)) {
490+
dst += 0x3c;
491+
} else {
492+
switch (dst) {
493+
case 0x7: dst = 0x1; break;
494+
case 0x8: dst = 0x2; break;
495+
case 0x9: dst = 0x8; break;
496+
case 0xa: dst = 0x9; break;
497+
case 0xb: dst = 0xa; break;
498+
case 0xc: dst = 0xb; break;
499+
case 0xd: dst = 0xc; break;
500+
case 0xe: dst = 0xd; break;
501+
case 0xf: dst = 0xe; break;
502+
case 0xff: dst = 0x1ff; break; // wtf?
503+
}
504+
}
505+
insrt(wa, 2, 9, dst);
506+
insrt(wa, 11, 1, extr(swa, 11, 1)); // DST_TYPE
507+
if (extr(swa, 2, 1))
508+
insrt(wa, 16, 4, extr(swa, 12, 4));
509+
else
510+
insrt(wa, 12, 4, extr(swa, 12, 4));
511+
insrt(wa, 20, 4, rdst_wm_vec);
512+
insrt(wa, 24, 4, rdst_wm_sca);
513+
int src[3];
514+
src[2] = extr(swa, 28, 4) | extr(swb, 0, 11) << 4;
515+
src[1] = extr(swb, 11, 15);
516+
src[0] = extr(swb, 26, 6) | extr(swc, 0, 9) << 6;
517+
for (int i = 0; i < 3; i++) {
518+
int type = extr(src[i], 0, 2);
519+
if (type == 0 && i != 2)
520+
insrt(src[i], 0, 2, 2);
521+
int reg = extr(src[i], 2, 4);
522+
if (reg > 0xc)
523+
insrt(src[i], 2, 4, 0xc);
524+
}
525+
insrt(wa, 28, 4, extr(src[2], 0, 4));
526+
insrt(wb, 0, 11, extr(src[2], 4, 11));
527+
insrt(wb, 11, 15, src[1]);
528+
insrt(wb, 26, 6, extr(src[0], 0, 6));
529+
insrt(wc, 0, 9, extr(src[0], 6, 9));
530+
insrt(wc, 9, 4, pgraph_vtx_attr_xlat_kelvin(state, extr(swc, 9, 4)));
531+
insrt(wc, 14, 9, extr(swc, 13, 8) + 0x3c);
532+
if (vop > 0xd)
533+
vop = 0;
534+
insrt(wc, 23, 5, vop);
535+
insrt(wc, 28, 4, extr(sop, 0, 4));
536+
insrt(wd, 0, 1, extr(sop, 4, 1));
537+
insrt(wd, 3, 8, 0x1b);
538+
insrt(wd, 11, 3, 7);
539+
insrt(wd, 16, 4, rdst);
540+
state->xfpr[which][0] = wa;
541+
state->xfpr[which][1] = wb;
542+
state->xfpr[which][2] = wc;
543+
state->xfpr[which][3] = wd;
544+
} else {
545+
// Wtf happens to bit 121?
546+
state->xfpr[which][0] = state->vab[0x10][3];
547+
state->xfpr[which][1] = state->vab[0x10][2];
548+
state->xfpr[which][2] = state->vab[0x10][1];
549+
state->xfpr[which][3] = state->vab[0x10][0] & 0x01ffffff;
550+
}
468551
}
469552
}
470553

@@ -482,6 +565,32 @@ void pgraph_ld_xfunk8(struct pgraph_state *state, uint32_t addr, uint32_t a) {
482565
if (nv04_pgraph_is_rankine_class(state)) {
483566
insrt(state->idx_state_b, 10, 6, 0);
484567
}
568+
uint32_t which = addr >> 4;
569+
if (which > 4)
570+
return;
571+
uint32_t src[4];
572+
src[0] = state->vab[0x10][0];
573+
src[1] = state->vab[0x10][1];
574+
src[2] = state->vab[0x10][2];
575+
src[3] = state->vab[0x10][3];
576+
if (which < 2) {
577+
uint32_t res[3] = {0};
578+
insrt(res[0], 0, 9, extr(src[0], 0, 9));
579+
insrt(res[0], 9, 9, extr(src[0], 16, 9));
580+
insrt(res[0], 18, 9, extr(src[1], 0, 9));
581+
insrt(res[0], 27, 5, extr(src[1], 16, 5));
582+
insrt(res[1], 0, 4, extr(src[1], 21, 4));
583+
insrt(res[1], 4, 9, extr(src[2], 0, 9));
584+
insrt(res[1], 13, 9, extr(src[2], 16, 9));
585+
insrt(res[1], 22, 9, extr(src[3], 0, 9));
586+
insrt(res[1], 31, 1, extr(src[3], 16, 1));
587+
insrt(res[2], 0, 8, extr(src[3], 17, 8));
588+
state->xfprunk1[which][0] = res[0];
589+
state->xfprunk1[which][1] = res[1];
590+
state->xfprunk1[which][2] = res[2];
591+
} else if (which == 2) {
592+
state->xfprunk2 = src[0] & 0xffff;
593+
}
485594
}
486595

487596
void pgraph_ld_vab_raw(struct pgraph_state *state, int which, int comp, uint32_t a) {

0 commit comments

Comments
 (0)