Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Counter Terrorist Special Forces: loading animation corrupts title screen #665

Open
abaire opened this issue Jan 19, 2022 · 19 comments
Open
Labels
bug Something isn't working

Comments

@abaire
Copy link
Contributor

abaire commented Jan 19, 2022

Title

https://xemu.app/titles/48500002/#Counter-Terrorist-Special-Forces-Fire-for-Effect

Bug Description

Just after the initial splash screen, a green rotating indicator is displayed in the lower left corner. In xemu, this explodes to cover the entire screen:

Screenshot_20220119_134719

Expected Behavior

The animation should not cover the screen:
loading_indicator

and should fade into the entry screen:

loaded_screen

xemu Version

Latest master:

Version: 0.6.2-52-gb3f56db428
Branch: master
Commit: b3f56db
Date: Wed Jan 19 09:52:45 PM UTC 2022

System Information

OS: Kubuntu 21.04 - 5.11.0-38-generic
CPU: Core i7-6700K @ 4GHz
GPU: NVIDIA GeForce GTX 1070
GPU Driver: 4.6.0 NVIDIA 470.74

Additional Context

No response

@abaire abaire added the bug Something isn't working label Jan 19, 2022
@abaire
Copy link
Contributor Author

abaire commented Jan 19, 2022

The vertex shader seems to be interesting, it appears to "misuse" the input registers (v1 looks like it's used as diffuse instead of weight, v2 is used as tex0 instead of normal (lighting is disabled))

It also sets the z coordinate with MUL(oPos,z, R12.z, c[58].z); but it looks like constant[58] is never loaded (I see a block of loads at 0xC and 0x21 but I think the last load would be at c[34]).

@abaire
Copy link
Contributor Author

abaire commented Jan 19, 2022

It looks like it gets set to 0x4B7FFFFF (16777215.0) which is interesting as it's also the max clip depth. The game is using z24s8 at this point in the rendering.

@abaire
Copy link
Contributor Author

abaire commented Jan 19, 2022

Stepping through the draw commands it actually looks like it's rendering the spiral loader into the backbuffer properly, but then it's obliterated, possibly by stale info in the framebuffer?

Screenshot_20220119_154440

@abaire
Copy link
Contributor Author

abaire commented Jan 20, 2022

Looking into the actual vertex data, the program sets z to 0 for all vertices (so the c[58].z is meaningless) and interestingly sets a mix of infinity, 0.0, and various reasonable values for w.

(Drawn as a triangle strip)

pos[0]: 99.059753 421.075928 0.000000 inf
pos[1]: 97.377518 427.886261 0.000000 inf
pos[2]: 88.875854 420.005554 0.000000 inf
pos[3]: 87.866516 424.091766 0.000000 inf
pos[4]: 87.866516 424.091766 0.000000 0.000000
pos[5]: 86.329880 417.062042 0.000000 0.000000
pos[6]: 86.329880 417.062042 0.000000 inf
pos[7]: 85.488762 413.656860 0.000000 inf
pos[8]: 81.237930 417.597229 0.000000 inf
pos[9]: 80.733253 415.554108 0.000000 inf
pos[10]: 80.733253 415.554108 0.000000 0.000000
pos[11]: 79.964935 419.068970 0.000000 0.000000
pos[12]: 79.964935 419.068970 0.000000 inf
pos[13]: 79.544380 420.771576 0.000000 inf
pos[14]: 77.418961 418.801392 0.000000 inf
pos[15]: 77.166626 419.822937 0.000000 inf
pos[16]: 77.166626 419.822937 0.000000 0.980578
pos[17]: 96.097717 430.615265 0.000000 0.000000
pos[18]: 96.097717 430.615265 0.000000 inf
pos[19]: 91.937325 436.263428 0.000000 inf
...

This appears to trigger the break, if I change the shader code to blindly force oPos.w to 1.0 it renders something that looks more correct, though there's no loading text and the game appears to crash before reaching the point where the loading text would be hidden and the 3d scene would be rendered.

@abaire
Copy link
Contributor Author

abaire commented Jan 20, 2022

Setting up a trivial test case, it's not the inf or 0 or even positive w values that are the problem, it's the negative w's. On hardware these render correctly, on xemu they create geometry off screen (in this particular data set).

Test case
HW results

@abaire
Copy link
Contributor Author

abaire commented Jan 20, 2022

Note, this may be due to the same underlying cause as #174

(It was not, 174 is due to lack of special casing of stride=0 vertex attributes)

@Triticum0
Copy link

When i tested this game back in April on my AMD GPU there was an issue with some of the text causing artifacts in menu and Fmv. Is is this still the case?
3
2

@Triticum0
Copy link

Also this corruption also affect the in-game HUD
1

@abaire
Copy link
Contributor Author

abaire commented Jan 20, 2022

At the moment I can't seem to get that far, for me the game never gets past the loading indicator (it never even shows the "Loading in progress" text). I can hack around the graphical corruption (in a way that breaks other games) but never see anything more than the green spinner.

If you can re-test with the latest xemu and get past the loading screen it might indicate that the dump I made is bad and needs to be re-dumped (though it seems to work fine running off the HDD on hardware) .

@abaire
Copy link
Contributor Author

abaire commented Jan 21, 2022

This only seems to affect vertices rendered as triangle strips; if I send the same vertices as discrete triangles they render as expected.

@abaire
Copy link
Contributor Author

abaire commented Jan 21, 2022

And digging some more, it looks like the hardware actually does render the vertices, it just discards them in the pixel shader.

Test
Results

@abaire
Copy link
Contributor Author

abaire commented Jan 21, 2022

So far I can only replicate this in cases where the negative w vertex is stacked top of the previous vertex (e.g., intentionally degenerate triangles).

If I perturb it slightly in any direction other than the camera view axis, both xemu and the xbox will fill the resultant clipped surface (that runs up to the camera position).

If I perturb it in the camera view axis, xemu will fill a sliver of the triangle, xbox does not seem to.

@abaire
Copy link
Contributor Author

abaire commented Jan 21, 2022

At this point I suspect some precision/rounding issue.

I've checked with RenderDoc and implemented the (relevant part of the) vertex shader in Python and the output vertices look correct. In particular, the last non-negative vertex is projected to (0, 0.666..., -1, 1) and the negative vertex to (0, -0.0666..., 0.1, -0.1). Doing the perspective divide, these should both map to (0.0, 0.666..., -1.0, 1.0), creating a degenerate triangle that should not result in any fragment filling.

Interestingly, in RenderDoc's mesh view, the output matches the xbox hardware until the camera is slightly tweaked, at which point the broken red triangle is displayed.

@abaire
Copy link
Contributor Author

abaire commented Jan 22, 2022

Maybe not, setting the test vertex's w to -1.0 still results in incorrect behavior.

@Triticum0
Copy link

FYI: This issue properly related as it cause exploding geometry in menus. #537

@Triticum0
Copy link

Triticum0 commented Jan 27, 2022

@abaire I retested and got this disc is dirty or damage so it's probably a regression.

@Triticum0
Copy link

Test it before the render scale was implemented that probably what broke the game

@Triticum0
Copy link

@abaire this game now goes in-game
xemu-2022-06-03-00-47-04

@abaire
Copy link
Contributor Author

abaire commented Jun 4, 2022

@Triticum0 confirmed that I can get in game with the latest release as well. The vertex explosion on the loading screen still happens and the pgraph tests I wrote while diagnosing this still fail in the same way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants