-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Medal Of Honor Heroes Saga [ULES00561][ULES00988] - Bad graphics ingame. #6554
Comments
The cause of this is actually already known, #3607. -[Unknown] |
Any progress on this? |
Edit: Probably should note on the start that this issue is no longer suspected to be caused by Unexpected prim type: 7 / PRIM_CONTINUE which is already implemented in softGpu, hence why this ancient issue was reopened to keep the two separate:]. Overall there's something buggy with TRIANGLE_STRIP prims for sure, it might even be more than one problem, as there are two cases seen in-game:
Couldn't find anything affecting the latter, except camera movement itself it might show different triangles depending on angle, generally if less triangles show up(staring at the ground or some corner of the map) it seems to have higher chance of drawing something correctly, it also looks like there are many bad triangles under terrain that stretch to a longer distance which could be somehow related. To me it kind of looks like we have possibly unrelated strips, that somehow due to some incorrect logic existing in both software and hardware rendering get their points mixed. |
I'll note that triangle strips in general are very popular. Gods Eater Burst, for example, uses them for almost all graphics. That said, maybe there's an issue when switching prims? What happens if you change this code in IndexGenerator.h: bool PrimCompatible(int prim1, int prim2) {
if (prim1 == GE_PRIM_INVALID || prim2 == GE_PRIM_KEEP_PREVIOUS)
return true;
return indexedPrimitiveType[prim1] == indexedPrimitiveType[prim2];
}
bool PrimCompatible(int prim) const {
if (prim_ == GE_PRIM_INVALID || prim == GE_PRIM_KEEP_PREVIOUS)
return true;
return indexedPrimitiveType[prim] == prim_;
} To: bool PrimCompatible(int prim1, int prim2) {
if (prim1 == GE_PRIM_INVALID || prim2 == GE_PRIM_KEEP_PREVIOUS)
return true;
return false;
}
bool PrimCompatible(int prim) const {
if (prim_ == GE_PRIM_INVALID || prim == GE_PRIM_KEEP_PREVIOUS)
return true;
return false;
} This will prevent it from combining prims. It should be a lot slower, but if this fixes something, it's a bug. Are any of the vertex positions crazy for any of the prims? I think the PSP silently drops primitives with crazy coordinates, which we don't do. Crazy meaning very large negative or positive, after transform. Oh, I guess this game has a demo. -[Unknown] |
Yeah like unknown says, strips are in nearly every game so there has to be something that's a little different here. Maybe a strip can actually continue a list, or a fan? |
Tried that change just now and nothing changed as far as I can tell. Some vertices do get rather high values "shooting" through whole map, but guardband-culling branch wasn't really affecting anything visually last time I tried, through I guess it wasn't working for all games where it should, so maybe. It's stupidly hard to skip into a prim that's drawn in visible space to tell whenever it's glitched or not and almost impossible to tell whenever the empty hole near it should will be filled by some following prims or was bugged in that place, so it's pretty time consuming and confusing at the same time:]. I also noticed UV coordinates get negative at some of those prims, it might not be related, but this reminded me of that japanese dungeon crawler discussed here which had a tiny glitch somehow showing texture when it should be showing "the other side" of it aka nothing.(edit: here's a frame dump of it just in case ULJM05167_0001.zip ) Maybe this is the other way around and just doesn't show it when it should. Edit: I just remembered we can now record frames so here's from MOHH1: |
Hmm, for that dungeon game, I personally think it's plausible that culling may function even in throughmode. Not sure if related to this game though, will look. -[Unknown] |
MOHH2.zip They also show black screen when played and take time to go through debugger, so just to visualize it: |
Culling doesn't make much sense RECTANGLE primitives at least, because drawing them "backwards" invokes the UV rotation functionality which is used very deliberately by many games. Though I suppose they could be always flipping around culling to match... hm. Hm, I don't have a good explanation for that, though it would seem to indicate the CPU is involved ... |
Agreed, but the dungeon game is drawing a triangle strip - not a rectangle - in through mode. From the recording, it seems to work fine in softgpu, which it turns out is already allowing culling in through mode. -[Unknown] |
When messing around with some debug asserts I found what I think is a fix for the RECTANGLES/TRIANGLES issue. Won't fix the majority of the broken geometry though, but committing shortly. |
I'm sure checking this with Render Doc might be useless since it will not show emulation problems, but I really like how it visualize prims, might be slightly easier to imagine what's broken by looking at it, so here's an example of just flat piece of ground that has a relatively few messed up triangles: ~ |
Oh I think that's actually nice discovery, I looked at quite a few shapes and all broken ones starts by(Edit: actually they can be anywhere on the list to break stuff) list of vertices with (-32.0,-32.0) while the correct shapes does not have them! Edit: I can't find anything with weird negative(nor positive) constant X,Y in PPSSPP GE debugger, but seems like the same broken shapes repeat a bunch of stuff with UV (-2048.0, -2048.0) or UV (-4096.0,-4096.0) :]. I think removing vertices with those UV might fix this problem. |
Things seem a little bit too broken for this to be a guardband-issue but you never know I guess. Can you check what vertex format the geometry is being drawn with? Are index buffers used, and if so is there anything suspicious in them? Seems odd that bad positions would be used as a marker or triangle strip splitter, but yeah, interesting find. -32,-32 is just two coordinates, X,Y I guess, is Z=0? |
As in my edit above in PPSSPP GE debugger I can't find any repeated X,Y at all, but there are many with very fishy UV values UV (-2048.0, -2048.0) or UV (-4096.0,-4096.0), I'm convinced those are broken. |
Does that mean that UV scale/offset are set? I don't think any discard is done based on UVs. It would just be based on X/Y/Z, I think? At least, I've never seen any indication in tests of UVs causing discard, but I haven't gone hunting for it. -[Unknown] |
Here's all tabs when some potentially bad UV's going to (-2048.0,-2048.0) vertices are used together with good ones - https://gist.github.com/LunaMoo/6489173ba4453d85180f5bbd92a47c95 Maybe it is XYZ but GE debugger is inverted somehow for d3d11? That third party software was showing only weird XY's but in same places as GE debugger is showing those weird UV's... Edit: OGL shows those as UV as well... heh dunno. Edit: Oh nah sorry, that Render Doc also shows UV... I didn't notice it says "Texcoord":P.... oops(yes I totally assumed different software keeps same order ;f) |
Hmm, indeed, UV scale:
Hmm, the UVs are formatting a bit misleadingly. Since the texture is 64x64, a value of 65535 corresponds to "64". Effectively, that means (-2048,-2048) - (29,12) is (-2, -2) - (0, 0). Since UV wrap is enabled, that means it's texturing from the bottom right corner of 2x2. It's a bit weird though. Seems like badly decoded vertices. I wonder if the vertices are not (fully?) written yet, and it writes them right after enqueuing the list, or something? Maybe we're seeing verts from the last frame, with a few places randomly overwritten by other vars? It seems not bad enough for that, though... The vert type is fairly usual but does use weights: u16 texcoords, ABGR 8888 colors, s16 positions, u8 weights (1) -[Unknown] |
As far as I can tell all(all affected that is;p) vertices and draws are loaded when stage loads, they aren't generated while playing and from my comparison of memory dump made on PSP they seem to be the same there. So they are buggy and depend on psp behaviour. |
Well, if you want to try any tests, these are some instructions I think: But haven't tried it on anything newer than Windows 7 - I've heard there may be problems with drivers. I'm not sure here - if the memory dump is right, at least that seems to eliminate it being a CPU bug. Maybe we're somehow handling 1 weight incorrectly, or there's some alignment issue? Hmm. We could also try testing discard, probably by drawing full screen triangles with different wrong verts, and resetting VRAM to 0 in between. That way we could just log which types of verts caused a discard and which drew (this is basically the same strategy as the recent mipmap test.) But not sure, I mean, maybe we're just reading the verts wrong... -[Unknown] |
I have it up and running:3 at least I think I do, when testing gentest.py misc/libc it gave expected file, but when I tried gentest.py gpu/primitives/trianglestrip the .expected file was still empty:P, well BMP at least was showing stuff so maybe that's right. Not sure how to write that test you mentioned, but going to look and see how those tests work:]. |
Heh got a bit busy, but either way coming back at this I can't even figure out how to create a simple texture for a test:|. I guess the test will need one to actually test texcoords, it might also need to test color, as all the suspicious vertices here also have 0x00000000 for color, we don't know if PSP could ignore vertices based on texcoords, color or both of those being set to 0, nor what exactly happens when triangle_strips starts from such vertices or includes them somehwere in between valid ones. Maybe other prim types also will have to be tested for it althrough at least for this issue doesn't seem necessary. |
Seems highly dubious that it would completely ignore vertices with certain attribute contents. It's kind of the wrong place in the pipeline for that kind of thing. But yeah, I guess with custom hardware like the PSP GPU you never really know... and I don't have a better explanation :( Some games rely on the GPU advancing the vertex or index pointers after a draw to provide the next vertex/index pointer. Maybe there's some edge case in that advancing that we're not taking into account, leading to slightly misaligned vertex pointers which could totally lead to issues like this... |
Well when intentionally searching for an offset I noticed a pattern with those weird vertices, for example in a place like this:
It starts from 8 of those "broken" vertices and suspiciously the command BBOX_TEST mentions 8.
which also repeats that pattern, 8 broken vertices and BBOX_TEST: 000008 before it. Not sure if that's the case everywhere, but maybe that is something. Also it seems that memory which stores vertices in those places has more than when it finishes last one, so maybe that does require an offset like you say.:] |
Oh wow! That must be it, look at this:
Now first draw:
second draw
and third draw:
Exactly 8 right after that command in different prims, so as you say, it must be an offset thing. Edit: Hah made a stupid implementation of adding 0x90 to gstate_c.vertexAddr in GE_CMD_BOUNDINGBOX when VADDR was used before and it fixed the problem in first instance of the problem which hopefully confirms it:) ~ my change also broke further draws, but whatever I just wanted to test the theory the offset probably needs to vary instead of being 0x90 like I hardcoded by looking where vertices are stored. Another edit: I think it needs to be 2x BBOX_JUMP: target |
AH! Yeah! BBOX needs to also advance the vertex pointer. How could we have missed this... |
Well it was easy to miss considering it broke only 2 games, or maybe more, who knows, maybe it was somehow affecting other ancient mysteries, maybe even that infamous Tekken leg shaking^^. |
Highly doubt that it has anything to do with the leg shaking... I'll whip up a fix later today, anyway. |
There we go. I wish I could be bothered to write those monthly update style articles like Dolphin, if so this would definitely be in it :) |
Title: Medal of Honor Heroes 1 & 2
Genre: FPS
Region: EU
Format: ISO & CSO
Version: 0.9.8-1611-g2da02f9
Game ID: ULES00561 & ULES00988
OS: Windows 8.1.1 64bits
Compatability: Ingame
Notes: Menus and sound are good in both games, same graphic glitches. Tested also softgpu, Non-FB and CPU/GPU, no changes.
Screenshots:
The text was updated successfully, but these errors were encountered: