xemu-project / xemu

Original Xbox Emulator for Windows, macOS, and Linux (Active Development)
https://xemu.app
Other
2.78k stars 279 forks source link

[Assertion] (index_count*vertex_size) == (pg->inline_array_length*4) #926

Closed Triticum0 closed 2 years ago

Triticum0 commented 2 years ago

Title

Conker: Live & Reloaded Murakumo: Renegade Mech Pursuit Murakumo Shenmue 2

Bug Description

These Games Suffer from this assertion https://github.com/mborgerson/xemu/blob/38a0e46f8c59c6da50029c1b53712070f211ac74/hw/xbox/nv2a/pgraph.c#L6785

This Assertion is hit when...

Conker: Live & Reloaded

When you face the giant poo boss - during the cutscene when the dung beetle tells you to run and multiple times after 

Murakumo: Renegade Mech Pursuit/Murakumo

When Going in-game after the intro cutscene

Shenmue 2

Boot game
Start single player campaign (load save)
make the riddle of the keys in the statue
pass the animation
fight against the henchmen
pass the animation
leave the room walk to the stairs when going up
the error happens. 

Expected Behavior

Should not crash at all

xemu Version

0.7.13

System Information

Field Value
OS Windows 10 64-bit (21H1)
CPU AMD Ryzen 5 2600 Six-Core Processor @ 3.40GHz
Graphics Device AMD Radeon RX 5700 XT
Graphics Driver 4.0.148202 Core Profile Context 21.3.2 27.20.15003.5017

Additional Context

Realised there was 3 issue with the same assertion so I'm reducing them into one.Close #423 and #424

Fighter19 commented 2 years ago

In Conker that also happened the first time after an earthworm cutscene played. Afterwards the next time I tried to boot the game it said my disc might be damaged. Then after I restarted the emulator, the game booted as normal, but my savegame was gone, telling me it was corrupted.

So I assume that maybe some autosave icon I've never seen caused that issue.

Triticum0 commented 2 years ago

424 has all the times where it crashes. this is mostly for consideration of issues.

BatConker commented 2 years ago

https://user-images.githubusercontent.com/68554598/170745589-7c15c71d-6b50-4d26-8fd7-a8a3733eb04e.mp4

In Conker (multiplayer mode), anytime a character suicides with a grenade in close proximity to you, or you commit suicide with your own grenade, it crashes 100% of the time. Does not need to be on Xlink Kai, you can perform this crash in Dumbots (bots) mode offline. (To suicide, equip any grenade and hold RT until it explodes) My specs: Win 10, 1060 6gb, 3900x, 32gb ram

Capture

abaire commented 2 years ago

Some values from a test of the Conker grenade scenario around the assert for context

index_count = 198 vertex_size = 28 pg->inline_array_length = 1392

icvs = 5544 pg->ial4 = 5568

Looking at the vertex attributes: [0]: count = 4, size=4 <- In subsequent tests the count seemed to be 3 as expected from the pgraph [1]: count = 4, size = 1 [2]: count = 2, size = 4 [3-15]: count = 0 Looking at some of the shaders, this appears to be the vertex position, color, UV coords, respectively.

And a pgraph dump of the frame that precipitates the crash: conker_grenade.txt

Of interest is the data array format definitions for the triggering draw:

nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__POS<0x1760> (0x32 {Type:Float, Size:3, Stride:0 (0x0)})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__WEIGHT<0x1764> (0x40 {Type:UB D3D, Size:4, Stride:0 (0x0)})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__NORMAL<0x1768> (0x22 {Type:Float, Size:2, Stride:0 (0x0)})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__DIFFUSE<0x176C> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__SPECULAR<0x1770> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__FOG_COORD<0x1774> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__POINT_SIZE<0x1778> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__BACK_DIFFUSE<0x177C> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__BACK_SPECULAR<0x1780> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__TEX0<0x1784> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__TEX1<0x1788> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__TEX2<0x178C> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__TEX3<0x1790> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__13<0x1794> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__14<0x1798> (0x2 {Disabled})
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_SET_VERTEX_DATA_ARRAY_FORMAT__15<0x179C> (0x2 {Disabled})

Particularly interesting is the fact that there seems to be a mismatch in counts: [0] is a float 3, [1] is a unsigned byte D3D 4, [2] is a float * 2. I'm not sure why the count would be expanded from 3 to 4 on the [0] attribute, but if it was actually 3 as specified 5568/24 would be 287 (rather than /28 = 198.85...) and this assert wouldn't fail.

Doing some additional tests, it seems like this does not always fail in the same state, I've seen cases where vertex_size is 24 and inline_array_length is 688 which also trigger the assert.

abaire commented 2 years ago

I did a bit more debugging by adding some code to trigger a renderdoc frame capture when the bad draw is detected. Surprisingly, the shader during this stage is substantially different than expected:

  /* Slot 0: 0x00000000 0x00520003 0x0C36106C 0x2F200FF8 */
  MUL(R2,xyzw, c[144].xxxw, v0);

  /* Slot 1: 0x00000000 0x01A00200 0x0836106C 0x20700FF8 */
  ARL(A0, v1.x);

  /* Slot 2: 0x00000000 0x0020001B 0x2436106C 0x2F900FF8 */
  MOV(R9,xyzw, R2);

  /* Slot 3: 0x00000000 0x004D841B 0x0C00106C 0x2F300FFA */
  MUL(R3,xyzw, c[A0+108], v2.x);

  /* Slot 4: 0x00000000 0x004DA41B 0x0C00106C 0x2F400FFA */
  MUL(R4,xyzw, c[A0+109], v2.x);

  /* Slot 5: 0x00000000 0x004DC41B 0x0C00106C 0x2F500FFA */
  MUL(R5,xyzw, c[A0+110], v2.x);

  /* Slot 6: 0x00000000 0x01A00255 0x0836106C 0x20700FF8 */
  ARL(A0, v1.y);

  /* Slot 7: 0x00000000 0x008D841B 0x0CAA106C 0xDF600FFA */
  MAD(R6,xyzw, c[A0+108], v2.y, R3);

  /* Slot 8: 0x00000000 0x008DA41B 0x0CAA106D 0x1F700FFA */
  MAD(R7,xyzw, c[A0+109], v2.y, R4);

  /* Slot 9: 0x00000000 0x008DC41B 0x0CAA106D 0x5F800FFA */
  MAD(R8,xyzw, c[A0+110], v2.y, R5);

  /* Slot 10: 0x00000000 0x00E0001B 0x9436C86C 0x28A00FF8 */
  DP4(R10,x, R9, R6);

  /* Slot 11: 0x00000000 0x00E0001B 0x9436E86C 0x24A00FF8 */
  DP4(R10,y, R9, R7);

  /* Slot 12: 0x00000000 0x00E0001B 0x9437086C 0x22A00FF8 */
  DP4(R10,z, R9, R8);

  /* Slot 13: 0x00000000 0x00CC601B 0xA436186C 0x20708800 */
  DPH(oPos,x, R10, c[99]);

  /* Slot 14: 0x00000000 0x00CC801B 0xA436186C 0x20704800 */
  DPH(oPos,y, R10, c[100]);

  /* Slot 15: 0x00000000 0x00CCA01B 0xA436186C 0x20702800 */
  DPH(oPos,z, R10, c[101]);

  /* Slot 16: 0x00000000 0x00CCC01B 0xA436186C 0x20701800 */
  DPH(oPos,w, R10, c[102]);

  /* Slot 17: 0x00000000 0x00D6A01A 0xA436186C 0x2070F818 */
  DPH(oD0,xyzw, R10.xyz, c[181]);

  /* Slot 18: 0x00000000 0x0647401B 0xC4361BFF 0x1078E800 */
  MUL(oPos,xyz, R12, c[58]);
  RCC(R1,x, R12.w);

  /* Slot 19: 0x00000000 0x0087601B 0xC400286C 0x3070E801 */
  MAD(oPos,xyz, R12, R1.x, c[59]);

v0 still seems to affect oPos, but v1 is a pair of relative addresses to index into the constant registers rather than a color and the combination of that lookup with v2 affects both the position and diffuse color.

The associated data doesn't seem to fit expectations, however, and follows a pattern of 3 non-zero floats followed by a float 0:

nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x408DF70E => 4.436408)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC22484DE => -41.129753)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC4D01196 => -1664.549561)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x00B9B9B9 => 0.000000)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x408DF70E => 4.436408)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC23251A2 => -44.579720)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC4D01196 => -1664.549561)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x00B9B9B9 => 0.000000)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x3F7C8792 => 0.986444)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC23251A2 => -44.579720)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC4D01196 => -1664.549561)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x00B9B9B9 => 0.000000)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x3F7C8792 => 0.986444)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC22484DE => -41.129753)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC4D01196 => -1664.549561)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x00B9B9B9 => 0.000000)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC266E31E => -57.721794)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC21F9EFE => -39.905266)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC4D0795E => -1667.792725)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x00B9B9B9 => 0.000000)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC266E31E => -57.721794)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC22D6BC2 => -43.355232)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0xC4D0795E => -1667.792725)
nv2a_pgraph_method 0: NV20_KELVIN_PRIMITIVE<0x97> -> NV097_INLINE_ARRAY<0x1818> (0x00B9B9B9 => 0.000000)
Fighter19 commented 2 years ago

Maybe it's a bug in the game code that went unnoticed?

abaire commented 2 years ago

FYI @Triticum0 the fix is now merged, hopefully all of these work with v0.7.23 and later

Triticum0 commented 2 years ago

They do all work but I haven't tested Shenmue 2 as I did not understand how to reproduce the issue