From 8be96dee03f7a8cfccf5389e92c8456f981b3f46 Mon Sep 17 00:00:00 2001 From: Marcin Koƛcielnicki Date: Wed, 28 Dec 2016 03:57:38 +0000 Subject: hwtest/pgraph: Model Celsius PIPE vtx, xfrm, light, and junk state. --- hwtest/pgraph_class_celsius.cc | 376 ++++++++++++++++++++++++++++++--------- hwtest/pgraph_class_emu_d3d56.cc | 61 ++++++- hwtest/pgraph_state.cc | 292 +++++++++++++++++++++++++----- hwtest/pgraph_state_tests.cc | 14 ++ include/nvhw/pgraph.h | 8 + 5 files changed, 615 insertions(+), 136 deletions(-) diff --git a/hwtest/pgraph_class_celsius.cc b/hwtest/pgraph_class_celsius.cc index 3e7d5fd4..ee625b3f 100644 --- a/hwtest/pgraph_class_celsius.cc +++ b/hwtest/pgraph_class_celsius.cc @@ -131,6 +131,8 @@ class MthdCelsiusTexOffset : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_offset[idx] = val; + exp.celsius_pipe_junk[0] = idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_offset[idx]; } insrt(exp.valid[1], idx ? 22 : 14, 1, 1); } @@ -221,6 +223,8 @@ class MthdCelsiusTexFormat : public SingleMthdTest { insrt(rval, 12, 4, mips); if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_format[idx] = rval | (exp.celsius_tex_format[idx] & 8); + exp.celsius_pipe_junk[0] = 0x10 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_format[idx]; } insrt(exp.valid[1], idx ? 21 : 15, 1, 1); } @@ -239,6 +243,12 @@ class MthdCelsiusTexControl : public SingleMthdTest { if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_control[idx] = val & 0x7fffffff; insrt(exp.celsius_xf_misc_b, idx ? 14 : 0, 1, extr(val, 30, 1)); + exp.celsius_pipe_junk[0] = 0x18 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_control[idx]; + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } using SingleMthdTest::SingleMthdTest; @@ -265,6 +275,8 @@ class MthdCelsiusTexPitch : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_pitch[idx] = val & 0xffff0000; + exp.celsius_pipe_junk[0] = 0x20 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_pitch[idx]; } } using SingleMthdTest::SingleMthdTest; @@ -274,6 +286,8 @@ class MthdCelsiusTexUnk238 : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_unk238[idx] = val; + exp.celsius_pipe_junk[0] = 0x28 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_unk238[idx]; } } using SingleMthdTest::SingleMthdTest; @@ -312,6 +326,8 @@ class MthdCelsiusTexRect : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_rect[idx] = val & 0x07ff07ff; + exp.celsius_pipe_junk[0] = 0x30 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_rect[idx]; } } using SingleMthdTest::SingleMthdTest; @@ -346,6 +362,8 @@ class MthdCelsiusTexFilter : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_filter[idx] = val & 0x77001fff; + exp.celsius_pipe_junk[0] = 0x38 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_filter[idx]; } insrt(exp.valid[1], idx ? 23 : 16, 1, 1); } @@ -370,6 +388,8 @@ class MthdCelsiusTexPalette : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_palette[idx] = val & 0xffffffc1; + exp.celsius_pipe_junk[0] = 8 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_palette[idx]; } } using SingleMthdTest::SingleMthdTest; @@ -409,6 +429,8 @@ class MthdCelsiusRcInAlpha : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_rc_in[0][idx] = val; + exp.celsius_pipe_junk[0] = 0x40 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_rc_in[0][idx]; } } using SingleMthdTest::SingleMthdTest; @@ -448,6 +470,8 @@ class MthdCelsiusRcInColor : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_rc_in[1][idx] = val; + exp.celsius_pipe_junk[0] = 0x48 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_rc_in[1][idx]; } } using SingleMthdTest::SingleMthdTest; @@ -457,6 +481,8 @@ class MthdCelsiusRcFactor : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_rc_factor[idx] = val; + exp.celsius_pipe_junk[0] = 0x50 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_rc_factor[idx]; } } using SingleMthdTest::SingleMthdTest; @@ -509,6 +535,8 @@ class MthdCelsiusRcOutAlpha : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_rc_out[0][idx] = val & 0x3cfff; + exp.celsius_pipe_junk[0] = 0x58 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_rc_out[0][idx]; } } using SingleMthdTest::SingleMthdTest; @@ -575,42 +603,13 @@ class MthdCelsiusRcOutColor : public SingleMthdTest { } if (!extr(exp.nsource, 1, 1)) { exp.celsius_rc_out[1][idx] = rval; + exp.celsius_pipe_junk[0] = 0x60 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_rc_out[1][idx]; } } using SingleMthdTest::SingleMthdTest; }; -class MthdDmaClipid : public SingleMthdTest { - bool takes_dma() override { return true; } - void emulate_mthd() override { - uint32_t offset_mask = pgraph_offset_mask(&chipset) | 0xf; - uint32_t base = (pobj[2] & ~0xfff) | extr(pobj[0], 20, 12); - uint32_t limit = pobj[1]; - uint32_t dcls = extr(pobj[0], 0, 12); - exp.celsius_surf_limit_clipid = (limit & offset_mask) | (dcls != 0x30) << 31; - exp.celsius_surf_base_clipid = base & offset_mask; - bool bad = true; - if (dcls == 0x30 || dcls == 0x3d) - bad = false; - if (dcls == 3 && (cls == 0x38 || cls == 0x88)) - bad = false; - if (extr(exp.debug[3], 23, 1) && bad) { - nv04_pgraph_blowup(&exp, 0x2); - } - bool prot_err = false; - if (extr(base, 0, 6)) - prot_err = true; - if (extr(pobj[0], 16, 2)) - prot_err = true; - if (dcls == 0x30) - prot_err = false; - if (prot_err) - nv04_pgraph_blowup(&exp, 4); - insrt(exp.ctx_valid, 28, 1, dcls != 0x30 && !(bad && extr(exp.debug[3], 23, 1))); - } - using SingleMthdTest::SingleMthdTest; -}; - class MthdCelsiusRcFinal0 : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) { @@ -636,6 +635,8 @@ class MthdCelsiusRcFinal0 : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_rc_final[0] = val & 0x3f3f3f3f; + exp.celsius_pipe_junk[0] = 0x68; + exp.celsius_pipe_junk[1] = exp.celsius_rc_final[0]; } } using SingleMthdTest::SingleMthdTest; @@ -666,6 +667,8 @@ class MthdCelsiusRcFinal1 : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_rc_final[1] = val & 0x3f3f3fe0; + exp.celsius_pipe_junk[0] = 0x6c; + exp.celsius_pipe_junk[1] = exp.celsius_rc_final[1]; } } using SingleMthdTest::SingleMthdTest; @@ -703,6 +706,8 @@ class MthdCelsiusConfig : public SingleMthdTest { if (nv04_pgraph_is_nv17p(&chipset)) insrt(exp.celsius_config_b, 14, 2, extr(val, 28, 2)); insrt(exp.celsius_raster, 29, 1, extr(val, 12, 1)); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } using SingleMthdTest::SingleMthdTest; @@ -729,6 +734,10 @@ class MthdCelsiusLightModel : public SingleMthdTest { insrt(exp.celsius_xf_misc_a, 19, 1, extr(val, 0, 1)); insrt(exp.celsius_xf_misc_a, 20, 1, extr(val, 1, 1)); insrt(exp.celsius_xf_misc_b, 28, 1, extr(val, 16, 1)); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } using SingleMthdTest::SingleMthdTest; @@ -755,6 +764,10 @@ class MthdCelsiusLightMaterial : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_xf_misc_a, 21, 4, val); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -779,7 +792,7 @@ class MthdCelsiusFogMode : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -828,7 +841,7 @@ class MthdCelsiusFogCoord : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -844,6 +857,10 @@ class MthdCelsiusFogCoord : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_xf_misc_a, 16, 2, val); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -865,7 +882,7 @@ class MthdCelsiusFogEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -882,6 +899,12 @@ class MthdCelsiusFogEnable : public SingleMthdTest { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_b, 8, 1, val); insrt(exp.celsius_xf_misc_b, 31, 1, val); + exp.celsius_pipe_junk[0] = 0x7c; + exp.celsius_pipe_junk[1] = exp.celsius_config_b; + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -891,7 +914,7 @@ class MthdCelsiusFogEnable : public SingleMthdTest { class MthdCelsiusFogColor : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -905,6 +928,8 @@ class MthdCelsiusFogColor : public SingleMthdTest { insrt(exp.celsius_fog_color, 8, 8, extr(val, 8, 8)); insrt(exp.celsius_fog_color, 16, 8, extr(val, 0, 8)); insrt(exp.celsius_fog_color, 24, 8, extr(val, 24, 8)); + exp.celsius_pipe_junk[0] = 0x8c; + exp.celsius_pipe_junk[1] = exp.celsius_fog_color; } } insrt(exp.valid[1], 13, 1, 1); @@ -915,7 +940,7 @@ class MthdCelsiusFogColor : public SingleMthdTest { class MthdCelsiusTexColorKey : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -926,6 +951,8 @@ class MthdCelsiusTexColorKey : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_color_key[idx] = val; + exp.celsius_pipe_junk[0] = 0xa0 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_color_key[idx]; } } if (idx == 0) @@ -1030,7 +1057,7 @@ class MthdCelsiusAlphaFuncEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1046,6 +1073,8 @@ class MthdCelsiusAlphaFuncEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_a, 12, 1, val); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } } @@ -1067,7 +1096,7 @@ class MthdCelsiusBlendFuncEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1083,6 +1112,8 @@ class MthdCelsiusBlendFuncEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_blend, 3, 1, val); + exp.celsius_pipe_junk[0] = 0x80; + exp.celsius_pipe_junk[1] = exp.celsius_blend; } } } @@ -1104,7 +1135,7 @@ class MthdCelsiusCullFaceEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1120,6 +1151,8 @@ class MthdCelsiusCullFaceEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 28, 1, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -1141,7 +1174,7 @@ class MthdCelsiusDepthTestEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1157,6 +1190,8 @@ class MthdCelsiusDepthTestEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_a, 14, 1, val); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } } @@ -1178,7 +1213,7 @@ class MthdCelsiusDitherEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1194,6 +1229,8 @@ class MthdCelsiusDitherEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_a, 22, 1, val); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } } @@ -1215,7 +1252,7 @@ class MthdCelsiusLightingEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1231,6 +1268,10 @@ class MthdCelsiusLightingEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_xf_misc_b, 29, 1, val); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -1252,7 +1293,7 @@ class MthdCelsiusPointParamsEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1269,6 +1310,12 @@ class MthdCelsiusPointParamsEnable : public SingleMthdTest { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_b, 9, 1, val); insrt(exp.celsius_xf_misc_a, 25, 1, val); + exp.celsius_pipe_junk[0] = 0x7c; + exp.celsius_pipe_junk[1] = exp.celsius_config_b; + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -1290,7 +1337,7 @@ class MthdCelsiusPointSmoothEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1306,6 +1353,8 @@ class MthdCelsiusPointSmoothEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 9, 1, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -1327,7 +1376,7 @@ class MthdCelsiusLineSmoothEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1343,6 +1392,8 @@ class MthdCelsiusLineSmoothEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 10, 1, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -1364,7 +1415,7 @@ class MthdCelsiusPolygonSmoothEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1380,6 +1431,8 @@ class MthdCelsiusPolygonSmoothEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 11, 1, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -1401,7 +1454,7 @@ class MthdCelsiusWeightEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1417,6 +1470,10 @@ class MthdCelsiusWeightEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_xf_misc_a, 27, 1, val); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -1438,7 +1495,7 @@ class MthdCelsiusStencilEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1454,6 +1511,8 @@ class MthdCelsiusStencilEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_stencil_func, 0, 1, val); + exp.celsius_pipe_junk[0] = 0x74; + exp.celsius_pipe_junk[1] = exp.celsius_stencil_func; } } } @@ -1475,7 +1534,7 @@ class MthdCelsiusPolygonOffsetPointEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1491,6 +1550,8 @@ class MthdCelsiusPolygonOffsetPointEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 6, 1, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -1512,7 +1573,7 @@ class MthdCelsiusPolygonOffsetLineEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1528,6 +1589,8 @@ class MthdCelsiusPolygonOffsetLineEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 7, 1, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -1549,7 +1612,7 @@ class MthdCelsiusPolygonOffsetFillEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1565,6 +1628,8 @@ class MthdCelsiusPolygonOffsetFillEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 8, 1, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -1589,7 +1654,7 @@ class MthdCelsiusAlphaFuncFunc : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1607,6 +1672,8 @@ class MthdCelsiusAlphaFuncFunc : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_a, 8, 4, val); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } } @@ -1628,7 +1695,7 @@ class MthdCelsiusAlphaFuncRef : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1644,6 +1711,8 @@ class MthdCelsiusAlphaFuncRef : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_a, 0, 8, val); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } } @@ -1669,7 +1738,7 @@ class MthdCelsiusBlendFunc : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1734,6 +1803,8 @@ class MthdCelsiusBlendFunc : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_blend, 4 + which * 4, 4, rv); + exp.celsius_pipe_junk[0] = 0x80; + exp.celsius_pipe_junk[1] = exp.celsius_blend; } } } @@ -1745,7 +1816,7 @@ public: class MthdCelsiusBlendColor : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1756,6 +1827,8 @@ class MthdCelsiusBlendColor : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { exp.celsius_blend_color = val; + exp.celsius_pipe_junk[0] = 0x84; + exp.celsius_pipe_junk[1] = exp.celsius_blend_color; } } } @@ -1780,7 +1853,7 @@ class MthdCelsiusBlendEquation : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1815,6 +1888,8 @@ class MthdCelsiusBlendEquation : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_blend, 0, 3, rv); + exp.celsius_pipe_junk[0] = 0x80; + exp.celsius_pipe_junk[1] = exp.celsius_blend; } } } @@ -1839,7 +1914,7 @@ class MthdCelsiusDepthFunc : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1857,6 +1932,8 @@ class MthdCelsiusDepthFunc : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_a, 16, 4, val); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } } @@ -1875,7 +1952,7 @@ class MthdCelsiusColorMask : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1894,6 +1971,8 @@ class MthdCelsiusColorMask : public SingleMthdTest { insrt(exp.celsius_config_a, 28, 1, extr(val, 8, 1)); insrt(exp.celsius_config_a, 27, 1, extr(val, 16, 1)); insrt(exp.celsius_config_a, 26, 1, extr(val, 24, 1)); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } } @@ -1915,7 +1994,7 @@ class MthdCelsiusDepthWriteEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1931,6 +2010,8 @@ class MthdCelsiusDepthWriteEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_a, 24, 1, val); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } } @@ -1953,7 +2034,7 @@ class MthdCelsiusStencilVal : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -1969,6 +2050,8 @@ class MthdCelsiusStencilVal : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_stencil_func, 8 + 8 * which, 8, val); + exp.celsius_pipe_junk[0] = 0x74; + exp.celsius_pipe_junk[1] = exp.celsius_stencil_func; } } } @@ -1995,7 +2078,7 @@ class MthdCelsiusStencilFunc : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2013,6 +2096,8 @@ class MthdCelsiusStencilFunc : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_stencil_func, 4, 4, val); + exp.celsius_pipe_junk[0] = 0x74; + exp.celsius_pipe_junk[1] = exp.celsius_stencil_func; } } } @@ -2042,7 +2127,7 @@ class MthdCelsiusStencilOp : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2085,6 +2170,8 @@ class MthdCelsiusStencilOp : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_stencil_op, 4 * which, 4, rv); + exp.celsius_pipe_junk[0] = 0x78; + exp.celsius_pipe_junk[1] = exp.celsius_stencil_op; } } } @@ -2115,7 +2202,7 @@ class MthdCelsiusShadeMode : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2137,6 +2224,8 @@ class MthdCelsiusShadeMode : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_b, 7, 1, val); + exp.celsius_pipe_junk[0] = 0x7c; + exp.celsius_pipe_junk[1] = exp.celsius_config_b; } } } @@ -2147,7 +2236,7 @@ class MthdCelsiusLineWidth : public SingleMthdTest { void adjust_orig_mthd() override { val = sext(val, rnd() & 0x1f); if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2166,6 +2255,8 @@ class MthdCelsiusLineWidth : public SingleMthdTest { if (chipset.chipset == 0x10) rv &= 0xff; insrt(exp.celsius_raster, 12, 9, rv); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -2175,7 +2266,7 @@ class MthdCelsiusLineWidth : public SingleMthdTest { class MthdCelsiusPolygonOffsetFactor : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2189,6 +2280,8 @@ class MthdCelsiusPolygonOffsetFactor : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { exp.celsius_polygon_offset_factor = val; + exp.celsius_pipe_junk[0] = 0x90; + exp.celsius_pipe_junk[1] = exp.celsius_polygon_offset_factor; } } } @@ -2198,7 +2291,7 @@ class MthdCelsiusPolygonOffsetFactor : public SingleMthdTest { class MthdCelsiusPolygonOffsetUnits : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2212,6 +2305,8 @@ class MthdCelsiusPolygonOffsetUnits : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { exp.celsius_polygon_offset_units = val; + exp.celsius_pipe_junk[0] = 0x94; + exp.celsius_pipe_junk[1] = exp.celsius_polygon_offset_units; } } } @@ -2241,7 +2336,7 @@ class MthdCelsiusPolygonMode : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2269,6 +2364,8 @@ class MthdCelsiusPolygonMode : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, which * 2, 2, rv); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -2280,7 +2377,7 @@ public: class MthdCelsiusDepthRangeNear : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2294,6 +2391,8 @@ class MthdCelsiusDepthRangeNear : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { exp.celsius_depth_range_near = val; + exp.celsius_pipe_junk[0] = 0x98; + exp.celsius_pipe_junk[1] = exp.celsius_depth_range_near; } } } @@ -2303,7 +2402,7 @@ class MthdCelsiusDepthRangeNear : public SingleMthdTest { class MthdCelsiusDepthRangeFar : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2317,6 +2416,8 @@ class MthdCelsiusDepthRangeFar : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { exp.celsius_depth_range_far = val; + exp.celsius_pipe_junk[0] = 0x9c; + exp.celsius_pipe_junk[1] = exp.celsius_depth_range_far; } } } @@ -2345,7 +2446,7 @@ class MthdCelsiusCullFace : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2373,6 +2474,8 @@ class MthdCelsiusCullFace : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 21, 2, rv); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -2401,7 +2504,7 @@ class MthdCelsiusFrontFace : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2423,6 +2526,8 @@ class MthdCelsiusFrontFace : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 23, 1, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -2444,7 +2549,7 @@ class MthdCelsiusNormalizeEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2460,6 +2565,10 @@ class MthdCelsiusNormalizeEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_xf_misc_b, 30, 1, val); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -2481,7 +2590,7 @@ class MthdCelsiusSpecularEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2497,6 +2606,8 @@ class MthdCelsiusSpecularEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_b, 5, 1, val); + exp.celsius_pipe_junk[0] = 0x7c; + exp.celsius_pipe_junk[1] = exp.celsius_config_b; } } } @@ -2515,7 +2626,7 @@ class MthdCelsiusLightEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool is_valid_val() override { if (val & ~0xffff) @@ -2542,6 +2653,10 @@ class MthdCelsiusLightEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_xf_misc_a, 0, 16, val); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -2571,7 +2686,7 @@ class MthdCelsiusTexGenMode : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2619,6 +2734,10 @@ class MthdCelsiusTexGenMode : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_xf_misc_b, 3 + idx * 14 + which * 3, which == 3 ? 2 : 3, rv); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -2642,7 +2761,7 @@ class MthdCelsiusTexMatrixEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2658,6 +2777,10 @@ class MthdCelsiusTexMatrixEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_xf_misc_b, 1 + idx * 14, 1, val); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -2676,7 +2799,7 @@ class MthdCelsiusTlMode : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2694,6 +2817,10 @@ class MthdCelsiusTlMode : public SingleMthdTest { insrt(exp.celsius_xf_misc_a, 28, 1, extr(val, 0, 1)); insrt(exp.celsius_xf_misc_b, 2, 1, extr(val, 1, 1)); insrt(exp.celsius_xf_misc_b, 16, 1, extr(val, 2, 1)); + if (!extr(exp.debug[3], 28, 1)) { + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; + } } } } @@ -2704,7 +2831,7 @@ class MthdCelsiusPointSize : public SingleMthdTest { void adjust_orig_mthd() override { val = sext(val, rnd() & 0x1f); if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2720,6 +2847,8 @@ class MthdCelsiusPointSize : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { exp.celsius_point_size = val & 0x1ff; + exp.celsius_pipe_junk[0] = 0xa8; + exp.celsius_pipe_junk[1] = exp.celsius_point_size; } } } @@ -2738,7 +2867,7 @@ class MthdCelsiusUnk3f0 : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool is_valid_val() override { return val < 4; @@ -2755,6 +2884,8 @@ class MthdCelsiusUnk3f0 : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 26, 2, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -2773,7 +2904,7 @@ class MthdCelsiusUnk3f4 : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool is_valid_val() override { return val < 2; @@ -2790,6 +2921,8 @@ class MthdCelsiusUnk3f4 : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_b, 0, 1, val); + exp.celsius_pipe_junk[0] = 0x7c; + exp.celsius_pipe_junk[1] = exp.celsius_config_b; } } } @@ -2808,7 +2941,7 @@ class MthdCelsiusOldUnk3f8 : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2824,6 +2957,8 @@ class MthdCelsiusOldUnk3f8 : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_raster, 30, 2, val); + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; } } } @@ -2842,7 +2977,7 @@ class MthdCelsiusColorLogicOpEnable : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2858,6 +2993,8 @@ class MthdCelsiusColorLogicOpEnable : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_blend, 16, 1, val); + exp.celsius_pipe_junk[0] = 0x80; + exp.celsius_pipe_junk[1] = exp.celsius_blend; } } } @@ -2882,7 +3019,7 @@ class MthdCelsiusColorLogicOpOp : public SingleMthdTest { } } if (rnd() & 1) - insrt(exp.notify, 28, 3, 0); + insrt(orig.notify, 28, 3, 0); } bool can_warn() override { return true; @@ -2900,12 +3037,47 @@ class MthdCelsiusColorLogicOpOp : public SingleMthdTest { } else { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_blend, 12, 4, val); + exp.celsius_pipe_junk[0] = 0x80; + exp.celsius_pipe_junk[1] = exp.celsius_blend; } } } using SingleMthdTest::SingleMthdTest; }; +class MthdDmaClipid : public SingleMthdTest { + bool takes_dma() override { return true; } + void emulate_mthd() override { + uint32_t offset_mask = pgraph_offset_mask(&chipset) | 0xf; + uint32_t base = (pobj[2] & ~0xfff) | extr(pobj[0], 20, 12); + uint32_t limit = pobj[1]; + uint32_t dcls = extr(pobj[0], 0, 12); + exp.celsius_surf_limit_clipid = (limit & offset_mask) | (dcls != 0x30) << 31; + exp.celsius_surf_base_clipid = base & offset_mask; + exp.celsius_pipe_junk[0] = 0xc8; + exp.celsius_pipe_junk[1] = exp.celsius_surf_limit_clipid; + bool bad = true; + if (dcls == 0x30 || dcls == 0x3d) + bad = false; + if (dcls == 3 && (cls == 0x38 || cls == 0x88)) + bad = false; + if (extr(exp.debug[3], 23, 1) && bad) { + nv04_pgraph_blowup(&exp, 0x2); + } + bool prot_err = false; + if (extr(base, 0, 6)) + prot_err = true; + if (extr(pobj[0], 16, 2)) + prot_err = true; + if (dcls == 0x30) + prot_err = false; + if (prot_err) + nv04_pgraph_blowup(&exp, 4); + insrt(exp.ctx_valid, 28, 1, dcls != 0x30 && !(bad && extr(exp.debug[3], 23, 1))); + } + using SingleMthdTest::SingleMthdTest; +}; + class MthdDmaZcull : public SingleMthdTest { bool takes_dma() override { return true; } void emulate_mthd() override { @@ -2915,6 +3087,8 @@ class MthdDmaZcull : public SingleMthdTest { uint32_t dcls = extr(pobj[0], 0, 12); exp.celsius_surf_limit_zcull = (limit & offset_mask) | (dcls != 0x30) << 31; exp.celsius_surf_base_zcull = base & offset_mask; + exp.celsius_pipe_junk[0] = 0xb8; + exp.celsius_pipe_junk[1] = exp.celsius_surf_limit_zcull; bool bad = true; if (dcls == 0x30 || dcls == 0x3d) bad = false; @@ -2951,8 +3125,11 @@ class MthdSurfPitchClipid : public SingleMthdTest { return !(val & ~0xff80) && !!val; } void emulate_mthd() override { - if (!extr(exp.nsource, 1, 1)) + if (!extr(exp.nsource, 1, 1)) { exp.celsius_surf_pitch_clipid = val & 0xffff; + exp.celsius_pipe_junk[0] = 0xd0; + exp.celsius_pipe_junk[1] = exp.celsius_surf_pitch_clipid; + } } using SingleMthdTest::SingleMthdTest; }; @@ -2971,8 +3148,11 @@ class MthdSurfOffsetClipid : public SingleMthdTest { return !(val & ~0xffffffc0); } void emulate_mthd() override { - if (!extr(exp.nsource, 1, 1)) + if (!extr(exp.nsource, 1, 1)) { exp.celsius_surf_offset_clipid = val & 0x07ffffff; + exp.celsius_pipe_junk[0] = 0xcc; + exp.celsius_pipe_junk[1] = exp.celsius_surf_offset_clipid; + } } using SingleMthdTest::SingleMthdTest; }; @@ -2991,8 +3171,11 @@ class MthdSurfPitchZcull : public SingleMthdTest { return !(val & ~0xff80) && !!val; } void emulate_mthd() override { - if (!extr(exp.nsource, 1, 1)) + if (!extr(exp.nsource, 1, 1)) { exp.celsius_surf_pitch_zcull = val & 0xffff; + exp.celsius_pipe_junk[0] = 0xc0; + exp.celsius_pipe_junk[1] = exp.celsius_surf_pitch_zcull; + } } using SingleMthdTest::SingleMthdTest; }; @@ -3011,8 +3194,11 @@ class MthdSurfOffsetZcull : public SingleMthdTest { return !(val & ~0xffffffc0); } void emulate_mthd() override { - if (!extr(exp.nsource, 1, 1)) + if (!extr(exp.nsource, 1, 1)) { exp.celsius_surf_offset_zcull = val & 0x3fffffff; + exp.celsius_pipe_junk[0] = 0xbc; + exp.celsius_pipe_junk[1] = exp.celsius_surf_offset_zcull; + } } using SingleMthdTest::SingleMthdTest; }; @@ -3053,6 +3239,8 @@ class MthdClearZeta : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_clear_zeta = val; + exp.celsius_pipe_junk[0] = 0xdc; + exp.celsius_pipe_junk[1] = exp.celsius_clear_zeta; } } using SingleMthdTest::SingleMthdTest; @@ -3072,6 +3260,8 @@ class MthdClipidEnable : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_d, 6, 1, val); + exp.celsius_pipe_junk[0] = 0xd8; + exp.celsius_pipe_junk[1] = exp.celsius_config_d; } } using SingleMthdTest::SingleMthdTest; @@ -3091,6 +3281,8 @@ class MthdClipidId : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_clipid_id = val & 0xf; + exp.celsius_pipe_junk[0] = 0xd4; + exp.celsius_pipe_junk[1] = exp.celsius_clipid_id; } } using SingleMthdTest::SingleMthdTest; @@ -3116,6 +3308,8 @@ class MthdClearHv : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_clear_hv[which] = val & 0x0fff0fff; + exp.celsius_pipe_junk[0] = 0xac + which * 4; + exp.celsius_pipe_junk[1] = exp.celsius_clear_hv[which]; } } public: @@ -3138,6 +3332,8 @@ class MthdCelsiusUnkd84 : public SingleMthdTest { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_d, 1, 2, val); insrt(exp.celsius_config_d, 31, 1, extr(val, 31, 1)); + exp.celsius_pipe_junk[0] = 0xd8; + exp.celsius_pipe_junk[1] = exp.celsius_config_d; } } using SingleMthdTest::SingleMthdTest; @@ -3157,6 +3353,8 @@ class MthdCelsiusTexUnk258 : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_tex_format[idx], 3, 1, val); + exp.celsius_pipe_junk[0] = 0x10 + idx * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_format[idx]; } } using SingleMthdTest::SingleMthdTest; @@ -3218,6 +3416,8 @@ class MthdCelsiusUnk3f8 : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_config_a, 31, 1, val); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } } using SingleMthdTest::SingleMthdTest; @@ -3227,6 +3427,8 @@ class MthdCelsiusUnk3fc : public SingleMthdTest { void emulate_mthd() override { if (!extr(exp.nsource, 1, 1)) { exp.celsius_mthd_unk3fc = val; + exp.celsius_pipe_junk[0] = 0xe0; + exp.celsius_pipe_junk[1] = exp.celsius_mthd_unk3fc; } } using SingleMthdTest::SingleMthdTest; diff --git a/hwtest/pgraph_class_emu_d3d56.cc b/hwtest/pgraph_class_emu_d3d56.cc index dd2e6ea8..6b5589db 100644 --- a/hwtest/pgraph_class_emu_d3d56.cc +++ b/hwtest/pgraph_class_emu_d3d56.cc @@ -32,8 +32,11 @@ namespace pgraph { class MthdEmuD3D56TexColorKey : public SingleMthdTest { void emulate_mthd() override { - if (!extr(exp.nsource, 1, 1)) + if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_color_key[0] = val; + exp.celsius_pipe_junk[0] = 0xa0; + exp.celsius_pipe_junk[1] = val; + } insrt(exp.valid[1], 12, 1, 1); } using SingleMthdTest::SingleMthdTest; @@ -53,11 +56,17 @@ class MthdEmuD3D56TexOffset : public SingleMthdTest { void emulate_mthd() override { for (int j = 0; j < 2; j++) { if (which & (1 << j)) { - if (!extr(exp.nsource, 1, 1)) + if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_offset[j] = val; + exp.celsius_pipe_junk[0] = j * 4; + exp.celsius_pipe_junk[1] = val; + } insrt(exp.valid[1], j ? 22 : 14, 1, 1); } } + if (chipset.chipset != 0x10 && which == 3) { + exp.celsius_pipe_junk[0] = 4; + } } public: MthdEmuD3D56TexOffset(hwtest::TestOptions &opt, uint32_t seed, const std::string &name, int trapbit, uint32_t cls, uint32_t mthd, int which) @@ -159,9 +168,13 @@ class MthdEmuD3D56TexFormat : public SingleMthdTest { insrt(rval, 7, 5, fmt); insrt(rval, 12, 4, mips); if (!extr(exp.nsource, 1, 1)) { - for (int i = 0; i < 2; i++) - if (which & 1 << i) + for (int i = 0; i < 2; i++) { + if (which & 1 << i) { exp.celsius_tex_format[i] = rval | (exp.celsius_tex_format[i] & 8); + exp.celsius_pipe_junk[0] = 0x10 + i * 4; + exp.celsius_pipe_junk[1] = exp.celsius_tex_format[i]; + } + } if (cls == 0x94 || cls == 0x54) { exp.celsius_tex_control[0] = 0x4003ffc0 | extr(val, 2, 2); exp.celsius_tex_control[1] = 0x3ffc0 | extr(val, 2, 2); @@ -169,6 +182,8 @@ class MthdEmuD3D56TexFormat : public SingleMthdTest { extr(exp.celsius_config_b, 6, 1) && !extr(rval, 27, 1) && !extr(rval, 31, 1)); insrt(exp.celsius_xf_misc_b, 16, 1, 0); + exp.celsius_pipe_junk[0] = 0x1c; + exp.celsius_pipe_junk[1] = exp.celsius_tex_control[1]; } else { if (which == 2) { insrt(exp.celsius_xf_misc_b, 16, 1, @@ -182,6 +197,8 @@ class MthdEmuD3D56TexFormat : public SingleMthdTest { !extr(rval, 27, 1) && !extr(rval, 31, 1)); } insrt(exp.celsius_xf_misc_a, 28, 1, 1); + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; } if (which & 1) insrt(exp.valid[1], 15, 1, 1); @@ -224,6 +241,8 @@ class MthdEmuD3D56TexFilter : public SingleMthdTest { insrt(rval, 5, 8, extr(val, 16, 8)); if (!extr(exp.nsource, 1, 1)) { exp.celsius_tex_filter[which == 2] = rval; + exp.celsius_pipe_junk[0] = 0x38 + (which == 2) * 4; + exp.celsius_pipe_junk[1] = rval; } insrt(exp.valid[1], which == 2 ? 23 : 16, 1, 1); } @@ -334,6 +353,14 @@ class MthdEmuD3D6CombineControl : public SingleMthdTest { exp.celsius_tex_control[0] = 0x4003ffc0; } insrt(exp.celsius_config_c, 20 + ac + which * 2, 1, comp); + exp.celsius_pipe_junk[0] = 0x6c; + uint32_t jval = exp.celsius_rc_final[1]; + uint32_t cc = exp.celsius_config_c; + if (extr(cc, 23, 1) || (extr(cc, 19, 1) && extr(cc, 21, 1))) + insrt(jval, 5, 1, 1); + if (extr(cc, 22, 1) || (extr(cc, 18, 1) && extr(cc, 20, 1))) + insrt(jval, 13, 1, 1); + exp.celsius_pipe_junk[1] = jval; } } public: @@ -346,6 +373,8 @@ class MthdEmuD3D6CombineFactor : public SingleMthdTest { if (!extr(exp.nsource, 1, 1)) { exp.celsius_rc_factor[0] = val; exp.celsius_rc_factor[1] = val; + exp.celsius_pipe_junk[0] = 0x54; + exp.celsius_pipe_junk[1] = val; } insrt(exp.valid[1], 24, 1, 1); } @@ -464,6 +493,10 @@ class MthdEmuD3D56Blend : public SingleMthdTest { exp.celsius_rc_out[0][0] = 0x00c00; exp.celsius_rc_out[1][0] = 0x00c00; } + exp.celsius_pipe_junk[0] = 0x80; + exp.celsius_pipe_junk[1] = exp.celsius_blend; + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; } insrt(exp.valid[1], 19, 1, 1); } @@ -520,6 +553,10 @@ class MthdEmuD3D56Config : public SingleMthdTest { if (!is_d3d6) { exp.celsius_stencil_func = 0x70; } + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; } insrt(exp.valid[1], 17, 1, 1); if (!is_d3d6) @@ -546,6 +583,8 @@ class MthdEmuD3D6StencilFunc : public SingleMthdTest { uint32_t rval = val & 0xfffffff1; insrt(rval, 4, 4, extr(val, 4, 4) - 1); exp.celsius_stencil_func = rval; + exp.celsius_pipe_junk[0] = 0x74; + exp.celsius_pipe_junk[1] = exp.celsius_stencil_func; } } using SingleMthdTest::SingleMthdTest; @@ -578,6 +617,8 @@ class MthdEmuD3D6StencilOp : public SingleMthdTest { insrt(exp.valid[1], 20, 1, 1); if (!extr(exp.nsource, 1, 1)) { exp.celsius_stencil_op = val & 0xfff; + exp.celsius_pipe_junk[0] = 0x78; + exp.celsius_pipe_junk[1] = exp.celsius_stencil_op; } } using SingleMthdTest::SingleMthdTest; @@ -588,6 +629,8 @@ class MthdEmuD3D56FogColor : public SingleMthdTest { insrt(exp.valid[1], 13, 1, 1); if (!extr(exp.nsource, 1, 1)) { exp.celsius_fog_color = val; + exp.celsius_pipe_junk[0] = 0x8c; + exp.celsius_pipe_junk[1] = val; } } using SingleMthdTest::SingleMthdTest; @@ -640,6 +683,8 @@ class MthdEmuEmuD3D0TexFormat : public SingleMthdTest { } exp.celsius_tex_control[0] = 0x4003ffc0 | extr(val, 16, 2); exp.celsius_tex_control[1] = 0x3ffc0 | extr(val, 16, 2); + exp.celsius_pipe_junk[0] = 0x1c; + exp.celsius_pipe_junk[1] = exp.celsius_tex_control[1]; } } using SingleMthdTest::SingleMthdTest; @@ -650,6 +695,8 @@ class MthdEmuEmuD3D0TexFilter : public SingleMthdTest { if (!extr(exp.nsource, 1, 1)) { insrt(exp.celsius_tex_filter[0], 0, 13, extrs(val, 16, 8) << 4); insrt(exp.celsius_tex_filter[1], 0, 13, extrs(val, 16, 8) << 4); + exp.celsius_pipe_junk[0] = 0x3c; + exp.celsius_pipe_junk[1] = exp.celsius_tex_filter[1]; } insrt(exp.valid[1], 23, 1, 1); insrt(exp.valid[1], 16, 1, 1); @@ -760,6 +807,10 @@ class MthdEmuEmuD3D0Config : public SingleMthdTest { insrt(exp.celsius_rc_out[1][1], 27, 3, 2); exp.celsius_rc_final[0] = 0xc; exp.celsius_rc_final[1] = rc_final_1; + exp.celsius_pipe_junk[0] = 0x88; + exp.celsius_pipe_junk[1] = exp.celsius_raster; + exp.celsius_pipe_junk[2] = exp.celsius_xf_misc_a; + exp.celsius_pipe_junk[3] = exp.celsius_xf_misc_b; } insrt(exp.valid[1], 17, 1, 1); insrt(exp.valid[1], 24, 1, 1); @@ -793,6 +844,8 @@ class MthdEmuEmuD3D0Alpha : public SingleMthdTest { insrt(exp.celsius_config_a, 0, 8, val); insrt(exp.celsius_config_a, 8, 4, extr(val, 8, 4) - 1); insrt(exp.celsius_config_a, 12, 1, 1); + exp.celsius_pipe_junk[0] = 0x70; + exp.celsius_pipe_junk[1] = exp.celsius_config_a; } insrt(exp.valid[1], 18, 1, 1); } diff --git a/hwtest/pgraph_state.cc b/hwtest/pgraph_state.cc index 0b1a4adb..52d79f4c 100644 --- a/hwtest/pgraph_state.cc +++ b/hwtest/pgraph_state.cc @@ -412,90 +412,160 @@ std::vector> pgraph_d3d56_regs(const chipset_info &chi return res; } -class CelsiusRcInRegister : public MmioRegister { +class CelsiusRegister : public MmioRegister { + void sim_write(struct pgraph_state *state, uint32_t val) override { + MmioRegister::sim_write(state, val); + uint32_t cls = extr(state->ctx_switch[0], 0, 8); + uint32_t rval = ref(state); + uint32_t cc = state->celsius_config_c; + if (cls == 0x55 || cls == 0x95) { + if (addr == 0x400e44 || addr == 0x400e4c) { + bool color = addr == 0x400e4c; + if (extr(cc, 20 + color, 1) && !extr(cc, 18 + color, 1)) { + for (int i = 0; i < 4; i++) + if (extr(rval, i * 8, 4) == 0xc) + rval ^= 1 << (i * 8 + 5); + } + } + } + state->celsius_pipe_junk[0] = addr & 0xfc; + state->celsius_pipe_junk[1] = rval; + } + using MmioRegister::MmioRegister; +}; + +class SimpleCelsiusRegister : public SimpleMmioRegister { + void sim_write(struct pgraph_state *state, uint32_t val) override { + MmioRegister::sim_write(state, val); + state->celsius_pipe_junk[0] = addr & 0xfc; + state->celsius_pipe_junk[1] = ref(state); + } + using SimpleMmioRegister::SimpleMmioRegister; +}; + +template +class IndexedCelsiusRegister : public IndexedMmioRegister { + void sim_write(struct pgraph_state *state, uint32_t val) override { + MmioRegister::sim_write(state, val); + uint32_t cls = extr(state->ctx_switch[0], 0, 8); + uint32_t rval = IndexedMmioRegister::ref(state); + uint32_t ad = IndexedMmioRegister::addr; + uint32_t cc = state->celsius_config_c; + if (cls == 0x55 || cls == 0x95) { + if (ad == 0x400e1c) + insrt(rval, 30, 1, extr(cc, 16, 4) != 0xf); + if (ad == 0x400e6c) { + if (extr(cc, 23, 1) || (extr(cc, 19, 1) && extr(cc, 21, 1))) + insrt(rval, 5, 1, 1); + if (extr(cc, 22, 1) || (extr(cc, 18, 1) && extr(cc, 20, 1))) + insrt(rval, 13, 1, 1); + } + } + state->celsius_pipe_junk[0] = ad & 0xfc; + state->celsius_pipe_junk[1] = rval; + } + using IndexedMmioRegister::IndexedMmioRegister; +}; + +class CelsiusRcInRegister : public CelsiusRegister { public: int idx; int which; CelsiusRcInRegister(int idx, int which) : - MmioRegister(0x400e40 + which * 8 + idx * 4, 0xffffffff), idx(idx), which(which) {} + CelsiusRegister(0x400e40 + which * 8 + idx * 4, 0xffffffff), idx(idx), which(which) {} std::string name() override { return (which ? "CELSIUS_RC_IN_COLOR[" : "CELSIUS_RC_IN_ALPHA[") + std::to_string(idx) + "]"; } uint32_t &ref(struct pgraph_state *state) override { return state->celsius_rc_in[which][idx]; } }; -class CelsiusRcOutRegister : public MmioRegister { +class CelsiusRcOutRegister : public CelsiusRegister { public: int idx; int which; CelsiusRcOutRegister(int idx, int which) : - MmioRegister(0x400e58 + which * 8 + idx * 4, which ? idx ? 0x3803ffff : 0x0003ffff : 0x0003cfff), idx(idx), which(which) {} + CelsiusRegister(0x400e58 + which * 8 + idx * 4, which ? idx ? 0x3803ffff : 0x0003ffff : 0x0003cfff), idx(idx), which(which) {} std::string name() override { return (which ? "CELSIUS_RC_OUT_COLOR[" : "CELSIUS_RC_OUT_ALPHA[") + std::to_string(idx) + "]"; } uint32_t &ref(struct pgraph_state *state) override { return state->celsius_rc_out[which][idx]; } }; +class CelsiusXfMiscBRegister : public SimpleMmioRegister { +public: + CelsiusXfMiscBRegister() : + SimpleMmioRegister(0x400f44, 0xffffffff, "CELSIUS_XF_MISC_B", &pgraph_state::celsius_xf_misc_b) {} + void sim_write(struct pgraph_state *state, uint32_t val) override { + MmioRegister::sim_write(state, val); + state->celsius_pipe_junk[2] = state->celsius_xf_misc_a; + state->celsius_pipe_junk[3] = state->celsius_xf_misc_b; + } +}; + +#define CREG(a, m, n, f) res.push_back(std::unique_ptr(new SimpleCelsiusRegister(a, m, n, &pgraph_state::f))) +#define ICREGF(a, m, n, f, i, x, fx) res.push_back(std::unique_ptr(new IndexedCelsiusRegister(a, m, n, &pgraph_state::f, i, fx))) +#define ICREG(a, m, n, f, i, x) ICREGF(a, m, n, f, i, x, 0) + std::vector> pgraph_celsius_regs(const chipset_info &chipset) { std::vector> res; bool is_nv15p = nv04_pgraph_is_nv15p(&chipset); bool is_nv17p = nv04_pgraph_is_nv17p(&chipset); for (int i = 0; i < 2; i++) { - IREG(0x400e00 + i * 4, 0xffffffff, "CELSIUS_TEX_OFFSET", celsius_tex_offset, i, 2); - IREG(0x400e08 + i * 4, 0xffffffc1, "CELSIUS_TEX_PALETTE", celsius_tex_palette, i, 2); - IREG(0x400e10 + i * 4, is_nv17p ? 0xffffffde : 0xffffffd6, "CELSIUS_TEX_FORMAT", celsius_tex_format, i, 2); - IREG(0x400e18 + i * 4, 0x7fffffff, "CELSIUS_TEX_CONTROL", celsius_tex_control, i, 2); - IREG(0x400e20 + i * 4, 0xffff0000, "CELSIUS_TEX_PITCH", celsius_tex_pitch, i, 2); - IREG(0x400e28 + i * 4, 0xffffffff, "CELSIUS_TEX_UNK238", celsius_tex_unk238, i, 2); - IREG(0x400e30 + i * 4, 0x07ff07ff, "CELSIUS_TEX_RECT", celsius_tex_rect, i, 2); - IREG(0x400e38 + i * 4, 0x77001fff, "CELSIUS_TEX_FILTER", celsius_tex_filter, i, 2); + ICREG(0x400e00 + i * 4, 0xffffffff, "CELSIUS_TEX_OFFSET", celsius_tex_offset, i, 2); + ICREG(0x400e08 + i * 4, 0xffffffc1, "CELSIUS_TEX_PALETTE", celsius_tex_palette, i, 2); + ICREG(0x400e10 + i * 4, is_nv17p ? 0xffffffde : 0xffffffd6, "CELSIUS_TEX_FORMAT", celsius_tex_format, i, 2); + ICREG(0x400e18 + i * 4, 0x7fffffff, "CELSIUS_TEX_CONTROL", celsius_tex_control, i, 2); + ICREG(0x400e20 + i * 4, 0xffff0000, "CELSIUS_TEX_PITCH", celsius_tex_pitch, i, 2); + ICREG(0x400e28 + i * 4, 0xffffffff, "CELSIUS_TEX_UNK238", celsius_tex_unk238, i, 2); + ICREG(0x400e30 + i * 4, 0x07ff07ff, "CELSIUS_TEX_RECT", celsius_tex_rect, i, 2); + ICREG(0x400e38 + i * 4, 0x77001fff, "CELSIUS_TEX_FILTER", celsius_tex_filter, i, 2); } for (int i = 0; i < 2; i++) { res.push_back(std::unique_ptr(new CelsiusRcInRegister(0, i))); res.push_back(std::unique_ptr(new CelsiusRcInRegister(1, i))); - IREG(0x400e50 + i * 4, 0xffffffff, "CELSIUS_RC_FACTOR", celsius_rc_factor, i, 2); + ICREG(0x400e50 + i * 4, 0xffffffff, "CELSIUS_RC_FACTOR", celsius_rc_factor, i, 2); res.push_back(std::unique_ptr(new CelsiusRcOutRegister(0, i))); res.push_back(std::unique_ptr(new CelsiusRcOutRegister(1, i))); } - IREG(0x400e68, 0x3f3f3f3f, "CELSIUS_RC_FINAL", celsius_rc_final, 0, 2); - IREG(0x400e6c, 0x3f3f3fe0, "CELSIUS_RC_FINAL", celsius_rc_final, 1, 2); - REG(0x400e70, is_nv17p ? 0xbfcf5fff : 0x3fcf5fff, "CELSIUS_CONFIG_A", celsius_config_a); - REG(0x400e74, 0xfffffff1, "CELSIUS_STENCIL_FUNC", celsius_stencil_func); - REG(0x400e78, 0x00000fff, "CELSIUS_STENCIL_OP", celsius_stencil_op); - REG(0x400e7c, is_nv17p ? 0x0000fff5 : 0x00003ff5, "CELSIUS_CONFIG_B", celsius_config_b); - REG(0x400e80, is_nv15p ? 0x0001ffff : 0x00000fff, "CELSIUS_BLEND", celsius_blend); - REG(0x400e84, 0xffffffff, "CELSIUS_BLEND_COLOR", celsius_blend_color); - REG(0x400e88, 0xfcffffcf, "CELSIUS_RASTER", celsius_raster); - REG(0x400e8c, 0xffffffff, "CELSIUS_FOG_COLOR", celsius_fog_color); - REG(0x400e90, 0xffffffff, "CELSIUS_POLYGON_OFFSET_FACTOR", celsius_polygon_offset_factor); - REG(0x400e94, 0xffffffff, "CELSIUS_POLYGON_OFFSET_UNITS", celsius_polygon_offset_units); - REG(0x400e98, 0xffffffff, "CELSIUS_DEPTH_RANGE_NEAR", celsius_depth_range_near); - REG(0x400e9c, 0xffffffff, "CELSIUS_DEPTH_RANGE_FAR", celsius_depth_range_far); - IREG(0x400ea0, 0xffffffff, "CELSIUS_TEX_COLOR_KEY", celsius_tex_color_key, 0, 2); - IREG(0x400ea4, 0xffffffff, "CELSIUS_TEX_COLOR_KEY", celsius_tex_color_key, 1, 2); - REG(0x400ea8, 0x000001ff, "CELSIUS_POINT_SIZE", celsius_point_size); + ICREG(0x400e68, 0x3f3f3f3f, "CELSIUS_RC_FINAL", celsius_rc_final, 0, 2); + ICREG(0x400e6c, 0x3f3f3fe0, "CELSIUS_RC_FINAL", celsius_rc_final, 1, 2); + CREG(0x400e70, is_nv17p ? 0xbfcf5fff : 0x3fcf5fff, "CELSIUS_CONFIG_A", celsius_config_a); + CREG(0x400e74, 0xfffffff1, "CELSIUS_STENCIL_FUNC", celsius_stencil_func); + CREG(0x400e78, 0x00000fff, "CELSIUS_STENCIL_OP", celsius_stencil_op); + CREG(0x400e7c, is_nv17p ? 0x0000fff5 : 0x00003ff5, "CELSIUS_CONFIG_B", celsius_config_b); + CREG(0x400e80, is_nv15p ? 0x0001ffff : 0x00000fff, "CELSIUS_BLEND", celsius_blend); + CREG(0x400e84, 0xffffffff, "CELSIUS_BLEND_COLOR", celsius_blend_color); + CREG(0x400e88, 0xfcffffcf, "CELSIUS_RASTER", celsius_raster); + CREG(0x400e8c, 0xffffffff, "CELSIUS_FOG_COLOR", celsius_fog_color); + CREG(0x400e90, 0xffffffff, "CELSIUS_POLYGON_OFFSET_FACTOR", celsius_polygon_offset_factor); + CREG(0x400e94, 0xffffffff, "CELSIUS_POLYGON_OFFSET_UNITS", celsius_polygon_offset_units); + CREG(0x400e98, 0xffffffff, "CELSIUS_DEPTH_RANGE_NEAR", celsius_depth_range_near); + CREG(0x400e9c, 0xffffffff, "CELSIUS_DEPTH_RANGE_FAR", celsius_depth_range_far); + ICREG(0x400ea0, 0xffffffff, "CELSIUS_TEX_COLOR_KEY", celsius_tex_color_key, 0, 2); + ICREG(0x400ea4, 0xffffffff, "CELSIUS_TEX_COLOR_KEY", celsius_tex_color_key, 1, 2); + CREG(0x400ea8, 0x000001ff, "CELSIUS_POINT_SIZE", celsius_point_size); if (is_nv17p) { - IREG(0x400eac, 0x0fff0fff, "CELSIUS_CLEAR_HV[0]", celsius_clear_hv, 0, 2); - IREG(0x400eb0, 0x0fff0fff, "CELSIUS_CLEAR_HV[1]", celsius_clear_hv, 1, 2); - REG(0x400eb4, 0x3fffffff, "CELSIUS_SURF_BASE_ZCULL", celsius_surf_base_zcull); - REG(0x400eb8, 0xbfffffff, "CELSIUS_SURF_LIMIT_ZCULL", celsius_surf_limit_zcull); - REG(0x400ebc, 0x3fffffff, "CELSIUS_SURF_OFFSET_ZCULL", celsius_surf_offset_zcull); - REG(0x400ec0, 0x0000ffff, "CELSIUS_SURF_PITCH_ZCULL", celsius_surf_pitch_zcull); - REG(0x400ec4, 0x07ffffff, "CELSIUS_SURF_BASE_CLIPID", celsius_surf_base_clipid); - REG(0x400ec8, 0x87ffffff, "CELSIUS_SURF_LIMIT_CLIPID", celsius_surf_limit_clipid); - REG(0x400ecc, 0x07ffffff, "CELSIUS_SURF_OFFSET_CLIPID", celsius_surf_offset_clipid); - REG(0x400ed0, 0x0000ffff, "CELSIUS_SURF_PITCH_CLIPID", celsius_surf_pitch_clipid); - REG(0x400ed4, 0x0000000f, "CELSIUS_CLIPID_ID", celsius_clipid_id); - REG(0x400ed8, 0x80000046, "CELSIUS_CONFIG_D", celsius_config_d); - REG(0x400edc, 0xffffffff, "CELSIUS_CLEAR_ZETA", celsius_clear_zeta); - REG(0x400ee0, 0xffffffff, "CELSIUS_MTHD_UNK3FC", celsius_mthd_unk3fc); + ICREG(0x400eac, 0x0fff0fff, "CELSIUS_CLEAR_HV[0]", celsius_clear_hv, 0, 2); + ICREG(0x400eb0, 0x0fff0fff, "CELSIUS_CLEAR_HV[1]", celsius_clear_hv, 1, 2); + CREG(0x400eb4, 0x3fffffff, "CELSIUS_SURF_BASE_ZCULL", celsius_surf_base_zcull); + CREG(0x400eb8, 0xbfffffff, "CELSIUS_SURF_LIMIT_ZCULL", celsius_surf_limit_zcull); + CREG(0x400ebc, 0x3fffffff, "CELSIUS_SURF_OFFSET_ZCULL", celsius_surf_offset_zcull); + CREG(0x400ec0, 0x0000ffff, "CELSIUS_SURF_PITCH_ZCULL", celsius_surf_pitch_zcull); + CREG(0x400ec4, 0x07ffffff, "CELSIUS_SURF_BASE_CLIPID", celsius_surf_base_clipid); + CREG(0x400ec8, 0x87ffffff, "CELSIUS_SURF_LIMIT_CLIPID", celsius_surf_limit_clipid); + CREG(0x400ecc, 0x07ffffff, "CELSIUS_SURF_OFFSET_CLIPID", celsius_surf_offset_clipid); + CREG(0x400ed0, 0x0000ffff, "CELSIUS_SURF_PITCH_CLIPID", celsius_surf_pitch_clipid); + CREG(0x400ed4, 0x0000000f, "CELSIUS_CLIPID_ID", celsius_clipid_id); + CREG(0x400ed8, 0x80000046, "CELSIUS_CONFIG_D", celsius_config_d); + CREG(0x400edc, 0xffffffff, "CELSIUS_CLEAR_ZETA", celsius_clear_zeta); + CREG(0x400ee0, 0xffffffff, "CELSIUS_MTHD_UNK3FC", celsius_mthd_unk3fc); } for (int i = 0; i < 8; i++) { IREG(0x400f00 + i * 4, 0x0fff0fff, "CELSIUS_CLIP_RECT_HORIZ", celsius_clip_rect_horiz, i, 8); IREG(0x400f20 + i * 4, 0x0fff0fff, "CELSIUS_CLIP_RECT_VERT", celsius_clip_rect_vert, i, 8); } REG(0x400f40, 0x3bffffff, "CELSIUS_XF_MISC_A", celsius_xf_misc_a); - REG(0x400f44, 0xffffffff, "CELSIUS_XF_MISC_B", celsius_xf_misc_b); + res.push_back(std::unique_ptr(new CelsiusXfMiscBRegister())); REG(0x400f48, 0x17ff0117, "CELSIUS_CONFIG_C", celsius_config_c); REG(0x400f4c, 0xffffffff, "CELSIUS_DMA", celsius_dma); return res; @@ -779,9 +849,52 @@ void pgraph_gen_state_d3d56(int cnum, std::mt19937 &rnd, struct pgraph_state *st } } +static uint32_t canonical_light_sx_float(uint32_t v) { + // 0 + if (!extr(v, 23, 8)) + return 0; + // NaN + if (extr(v, 23, 8) == 0xff) + return v & 1 ? 0x7f800000 : 0x7ffffc00; + return v & 0xfffffc00; +} + void pgraph_gen_state_celsius(int cnum, std::mt19937 &rnd, struct pgraph_state *state) { for (auto ® : pgraph_celsius_regs(state->chipset)) { reg->ref(state) = (rnd() & reg->mask) | reg->fixed; + for (int i = 0; i < 0x1c; i++) + state->celsius_pipe_vtx[i] = rnd(); + for (int i = 0; i < 4; i++) + state->celsius_pipe_junk[i] = rnd(); + for (int i = 0; i < 0x3c; i++) + for (int j = 0; j < 4; j++) { + state->celsius_pipe_xfer[i][j] = rnd(); + } + for (int i = 0; i < 0x30; i++) + for (int j = 0; j < 3; j++) { + state->celsius_pipe_light_v[i][j] = rnd() & 0xfffffc00; + } + for (int i = 0; i < 3; i++) + state->celsius_pipe_light_sa[i] = canonical_light_sx_float(rnd()); + for (int i = 0; i < 19; i++) + state->celsius_pipe_light_sb[i] = canonical_light_sx_float(rnd()); + for (int i = 0; i < 12; i++) + state->celsius_pipe_light_sc[i] = canonical_light_sx_float(rnd()); + for (int i = 0; i < 12; i++) + state->celsius_pipe_light_sd[i] = canonical_light_sx_float(rnd()); + state->celsius_pipe_light_sa[0] = 0x3f800000; + state->celsius_pipe_light_sb[0] = 0; + state->celsius_pipe_light_sc[0] = 0x3f800000; + state->celsius_pipe_light_sd[0] = 0; + if (state->chipset.chipset == 0x10) { + state->celsius_pipe_xfer[59][0] = 0; + state->celsius_pipe_xfer[59][1] = 0; + state->celsius_pipe_xfer[59][2] = 0; + state->celsius_pipe_xfer[59][3] = 0; + state->celsius_pipe_light_v[47][0] = 0; + state->celsius_pipe_light_v[47][1] = 0; + state->celsius_pipe_light_v[47][2] = 0; + } } } @@ -957,10 +1070,43 @@ void pgraph_load_d3d56(int cnum, struct pgraph_state *state) { } } +void pgraph_load_pipe(int cnum, uint32_t addr, uint32_t *data, int num) { + nva_wr32(cnum, 0x400f50, addr); + for (int i = 0; i < num; i++) + nva_wr32(cnum, 0x400f54, data[i]); + int ctr = 0; + while (nva_rd32(cnum, 0x400700)) { + ctr++; + if (ctr == 10000) { + printf("PIPE write hang on %04x: %08x\n", addr, nva_rd32(cnum, 0x400700)); + } + } +} + void pgraph_load_celsius(int cnum, struct pgraph_state *state) { for (auto ® : pgraph_celsius_regs(state->chipset)) { reg->write(cnum, reg->ref(state)); } + pgraph_load_pipe(cnum, 0x4400, state->celsius_pipe_vtx, 0x1c); + for (int i = 0; i < 0x3c; i++) { + pgraph_load_pipe(cnum, 0x6400 + i * 0x10, state->celsius_pipe_xfer[i], 4); + } + for (int i = 0; i < 0x30; i++) { + pgraph_load_pipe(cnum, 0x6800 + i * 0x10, state->celsius_pipe_light_v[i], 3); + } + for (int i = 0; i < 3; i++) { + pgraph_load_pipe(cnum, 0x6c00 + i * 0x10, state->celsius_pipe_light_sa + i, 1); + } + for (int i = 0; i < 19; i++) { + pgraph_load_pipe(cnum, 0x7000 + i * 0x10, state->celsius_pipe_light_sb + i, 1); + } + for (int i = 0; i < 12; i++) { + pgraph_load_pipe(cnum, 0x7400 + i * 0x10, state->celsius_pipe_light_sc + i, 1); + } + for (int i = 0; i < 12; i++) { + pgraph_load_pipe(cnum, 0x7800 + i * 0x10, state->celsius_pipe_light_sd + i, 1); + } + pgraph_load_pipe(cnum, 0x7bf0, state->celsius_pipe_junk, 0x4); } void pgraph_load_fifo(int cnum, struct pgraph_state *state) { @@ -1220,12 +1366,41 @@ void pgraph_dump_d3d56(int cnum, struct pgraph_state *state) { } } +void pgraph_dump_pipe(int cnum, uint32_t addr, uint32_t *data, int num) { + nva_wr32(cnum, 0x400f50, addr); + for (int i = 0; i < num; i++) + data[i] = nva_rd32(cnum, 0x400f54); +} + void pgraph_dump_celsius(int cnum, struct pgraph_state *state) { for (auto ® : pgraph_celsius_regs(state->chipset)) { reg->ref(state) = reg->read(cnum); } } +void pgraph_dump_celsius_pipe(int cnum, struct pgraph_state *state) { + pgraph_dump_pipe(cnum, 0x4400, state->celsius_pipe_vtx, 0x1c); + pgraph_dump_pipe(cnum, 0x4470, state->celsius_pipe_junk, 4); + for (int i = 0; i < 0x3c; i++) { + pgraph_dump_pipe(cnum, 0x6400 + i * 0x10, state->celsius_pipe_xfer[i], 4); + } + for (int i = 0; i < 0x30; i++) { + pgraph_dump_pipe(cnum, 0x6800 + i * 0x10, state->celsius_pipe_light_v[i], 3); + } + for (int i = 0; i < 3; i++) { + pgraph_dump_pipe(cnum, 0x6c00 + i * 0x10, state->celsius_pipe_light_sa + i, 1); + } + for (int i = 0; i < 19; i++) { + pgraph_dump_pipe(cnum, 0x7000 + i * 0x10, state->celsius_pipe_light_sb + i, 1); + } + for (int i = 0; i < 12; i++) { + pgraph_dump_pipe(cnum, 0x7400 + i * 0x10, state->celsius_pipe_light_sc + i, 1); + } + for (int i = 0; i < 12; i++) { + pgraph_dump_pipe(cnum, 0x7800 + i * 0x10, state->celsius_pipe_light_sd + i, 1); + } +} + void pgraph_dump_debug(int cnum, struct pgraph_state *state) { state->debug[0] = nva_rd32(cnum, 0x400080); state->debug[1] = nva_rd32(cnum, 0x400084); @@ -1287,6 +1462,9 @@ void pgraph_dump_state(int cnum, struct pgraph_state *state) { nva_wr32(cnum, 0x000200, 0xffffffff); } + if (state->chipset.card_type == 0x10) + pgraph_dump_celsius_pipe(cnum, state); + pgraph_dump_vtx(cnum, state); } @@ -1522,6 +1700,30 @@ restart: broke = true; } } + for (int i = 0; i < 0x1c; i++) + CMP(celsius_pipe_vtx[i], "CELSIUS_PIPE_VTX[%d]", i) + for (int i = 0; i < 4; i++) + CMP(celsius_pipe_junk[i], "CELSIUS_PIPE_JUNK[%d]", i) + for (int i = 0; i < 0x3c; i++) { + for (int j = 0; j < 4; j++) + CMP(celsius_pipe_xfer[i][j], "CELSIUS_PIPE_XFER[%d][%d]", i, j) + } + for (int i = 0; i < 0x30; i++) { + for (int j = 0; j < 3; j++) + CMP(celsius_pipe_light_v[i][j], "CELSIUS_PIPE_LIGHT_V[%d][%d]", i, j) + } + for (int i = 0; i < 3; i++) { + CMP(celsius_pipe_light_sa[i], "CELSIUS_PIPE_LIGHT_SA[%d]", i) + } + for (int i = 0; i < 19; i++) { + CMP(celsius_pipe_light_sb[i], "CELSIUS_PIPE_LIGHT_SB[%d]", i) + } + for (int i = 0; i < 12; i++) { + CMP(celsius_pipe_light_sc[i], "CELSIUS_PIPE_LIGHT_SC[%d]", i) + } + for (int i = 0; i < 12; i++) { + CMP(celsius_pipe_light_sd[i], "CELSIUS_PIPE_LIGHT_SD[%d]", i) + } } // DMA diff --git a/hwtest/pgraph_state_tests.cc b/hwtest/pgraph_state_tests.cc index 93841792..847b4a2f 100644 --- a/hwtest/pgraph_state_tests.cc +++ b/hwtest/pgraph_state_tests.cc @@ -688,8 +688,22 @@ private: std::string name; protected: bool supported() override { return chipset.card_type == 0x10; } + void adjust_orig() override { + if (rnd() & 1) + insrt(orig.ctx_switch[0], 0, 8, rnd() & 1 ? 0x95 : 0x55); + if (rnd() & 1) + insrt(orig.celsius_config_c, 16, 4, 0xf); + if (chipset.chipset == 0x10) { + uint32_t cls = extr(orig.ctx_switch[0], 0, 8); + // XXX: setting celsius methods when one of these is up hangs things. + if (cls == 0x37 || cls == 0x77 || cls == 0x63 || cls == 0x67 || cls == 0x89 || cls == 0x87 || cls == 0x38 || cls == 0x88 || cls == 0x60 || cls == 0x64) + orig.ctx_switch[0] ^= 0x80; + } + } void mutate() override { val = rnd(); + if (rnd() & 1) + insrt(val, 8 * (rnd() & 3), 4, 0xc); auto ® = regs[rnd() % regs.size()]; reg->sim_write(&exp, val); reg->write(cnum, val); diff --git a/include/nvhw/pgraph.h b/include/nvhw/pgraph.h index 5c86e569..c970d59f 100644 --- a/include/nvhw/pgraph.h +++ b/include/nvhw/pgraph.h @@ -219,6 +219,14 @@ struct pgraph_state { uint32_t celsius_xf_misc_b; uint32_t celsius_config_c; uint32_t celsius_dma; + uint32_t celsius_pipe_vtx[0x1c]; + uint32_t celsius_pipe_xfer[0x3c][4]; + uint32_t celsius_pipe_light_v[0x30][3]; + uint32_t celsius_pipe_light_sa[3]; + uint32_t celsius_pipe_light_sb[19]; + uint32_t celsius_pipe_light_sc[12]; + uint32_t celsius_pipe_light_sd[12]; + uint32_t celsius_pipe_junk[4]; }; enum { -- cgit v1.2.3