Emulator Issues #267
Sonic Heroes graphical problems (EFB scaling issue)
What steps will reproduce the problem?
1. Use OGL plugin
2. Dual Core enabled
3. Play Sonic heroes
What is the expected output? What do you see instead?
The ground is the wrong colour and whenever you move forward that graphical
glitch moves with you.
What version of the product are you using? On what operating system?
Dolphin 32 bit Rev 1029
Please provide any additional information below.
Intel Core 2 Duo 2.40GHz
ATI Radeon HD2600 XT 256MB of VRAM
#5 Updated by knuckles500 over 11 years ago
Sorry for the bump, but even though it's fixed for the OpenGL plugin - it isn't for
the DX9 plugin. But other than this bug, it should be a fully playable game.
As of R4878, the bug is still present in the DX9 plugin:
I don't know the revision number that fixed this problem with the OGL plugin, though. :(
#8 Updated by jayork42 over 11 years ago
I did see this recently, but I can't remember the plugin that was used. It has to do
with EFB copy reading from junk data in RAM and mapping random pixels I believe. I
also think that the reason why it stretches out everywhere might be because those
pixels would otherwise be transprent if EFB copy were handling the character shadows
correctly. But I'm not sure, that's just my guess.
#9 Updated by jayork42 about 11 years ago
This issue still remains in the latest revisions. I've come to find out that
disabling EFB copy, enabling native, enabling EFB copy, and disabling native in that
order fix the problem until I get to a certain part of the level where the issue
happens all over again. Native fixes the problem.
#12 Updated by knuckles500 over 10 years ago
Just FYI, I finally figured out the fix for this issue, but with a catch.
You need to use the DirectX11 plugin.
The fix itself is very simple, and it's the only way to fix it (no other settings or video plugin besides the software one or maybe the OpenGL plugin will correct it).
What you have to do is set the EFB Scale to 1x. That's all you have to do.
#13 Updated by DimitriPilot3 over 10 years ago
- Status changed from Fixed to Accepted
I'm reopening this issue, as it still exists. I guess this might be an issue with EFB scaling which results into the main character's shadow's texture having non-transparent edges, causing that texture to be "extended" beyond its edges...
According to my experiments, I can say the following:
- It apparently occurs all the time in DX9 (meaning that no option can make the glitch disappear)
- In DX11 and OGL, it doesn't occur all the time - it mainly depends on the EFB scale option (example from DX11 which may vary in OGL):
- no problem using values lower or equal to 1 (0.375x, 0.5x, 0.75x, or 1x)
- when using values greater than 1 (2x or 3x), the problem appears (2 edges of the shadow texture are affected)
- when using Integral or Fractional scaling, the problem appears whenever the renderer window's width and/or height are greater than the native EFB resolution (640x574 - the affected edges depend on the width and the height)
Other notable things (example from DX11 which may vary in OGL):
- When the problem occurs (horizontally, "vertically" or both), some lines on the left/top borders of the screen look like they aren't drawn/refreshed correctly
(see http://i51.tinypic.com/2edm7at.jpg and http://i53.tinypic.com/2qtvez4.jpg and http://i55.tinypic.com/ny79dh.jpg)
- The problem disappears for about one frame when the renderer is resized, which effectively refreshes the buggy lines I mentioned above...
I suspect the issue in DX9 to be different (worse?) from the one in DX11/OGL... But that's only a guess :P
#14 Updated by DimitriPilot3 over 10 years ago
#17 Updated by NeoBrainX over 9 years ago
Is this still an issue?
If it is, could anyone upload a fifo player file for a frame where the problem is visible? (preferably at a place where it's VERY obvious)
To create one, follow these steps:
1. Start Dolphin
2. Select "Tools->Fifo Player" from the menu
3. Select the "Record" tab in the dialog that pops up.
4. Set the number of "frames to record" to 1.
5. Start the game (do NOT close the dialog) and get to the place where the problem occurs
6. When you've reached a place in the game where the problem is obvious, press the "Record" button in the Fifo Player dialog.
7. Wait a bit until the "Save" button isn't grayed out anymore.
8. Press the Save button and pick a location to store the fifo log.
9. Post the fifo log here; do NOT attach it to this bug report, upload it to an external host instead and just put a link here.
Please create multiple log files of the same scene:
1. With DX11, native internal resolution, EFB to texture (the problem should NOT be visible in this case)
2. With DX9 (problem should be visible)
2. With any configuration where it happens in both OGL and DX9 (problem should be visible)
#18 Updated by jayork42 over 9 years ago
This is still a problem with the latest binary, 3.0-415. This still slways happens with DX9. Same behavior with OpenGL, issue only appears if setting the EFB resolution is greater than 1x or enabling AA. I'm unable to test DX11 because I'm running Windows XP. Can someone test this with the 3.0-415 32-bit build?
Here are the 2 fifo snapshots. DX9.dff is DX9 with EFB resolution set to 1x and no AA. OGL_15.dff is OpenGL using 1.5x and no AA. I would've tested AA between plugins but these settings differ, so we should ignore AA for the moment to keep variables to a minimum.
I may have a hypothesis as to what's going on here. I think we can agree by now that the edges of the mapped texture are nontransparent when this problem appears. Let's also assume the game engine is always stretching this texture to infnity in all directions. My guess for this is when upscaling EFB copies to 1.5x and above, the area of the actual image of the shadow exceeds the area of the bounding box used by the game engine to map the shadow to the terrain. I'm thinking the size of this bounding box doesn't change, yet the engine has no way of detecting that there are nontransparent pixels out of bounds of the box (because all of these settings are hacks). Because AA also upscales everything, this must be why AA breaks this too (but should AA really effect EFB copies other than the main frame buffer?) The images below explain this; the first being 1x and the second 1.5x.
These are EFB copies ripped using "Dump EFB to texture." With 1x the frame size is 128x128, with 1.5x it's 192x192, as expected. The image of the shadow is scaling with the frame.
#20 Updated by jayork42 over 9 years ago
Hmm. That's not the case. According to Dimitri's screenshots the shadows are clearly NOT going out of bounds. Something else is going on here. If you move around you'll notice the streaks change colors, even when you're not moving. My next guess is that something in memory is overflowing into the space used for the current shadow frame. Maybe a texture that's being upscaled next to this buffer. The interesting thing is these pixels appear to be garbage. Perhaps a nearby texture of a different format? If you move around you will eventually notice the lower right skew is flashing in a predictable pattern. This appears to be reflecting the current memory space used for the animated coin on screen as the flashing pattern is spot on with the coin's looping animation. If someone takes the time to debug VRAM this should explain what's happening.
#29 Updated by Anonymous almost 9 years ago
The issue doesn't seem to be related to the specific IR value. For me, the game looks correct in two circumstances:
2.5x IR with EFB scaled copy disabled
auto (window size) IR with EFB scaled copy disabled, and i randomly change window size
perhaps it is related to some discrepancy between "window size" and the actual rendering size not being linearly related.
#34 Updated by JMC4789 over 7 years ago
I found out the one surefire way to make the problem go away at higher resolutions IS... to keep dragging the window size as you play. The game's effects still draw properly, but the game runs at 30 fps/60 VPS and it's kinda hard to see. But still, it's something? I think?
#36 Updated by JMC4789 over 7 years ago
Ask and ye shall receive.
#37 Updated by magumagu9 about 7 years ago
Comment 18 is on the right track. The game is trying to be a bit clever and skip some register updates, so there are four textures active when it draws the whole road: the road texture, and textures for the shadows of each of the three characters. The problem is, we aren't computing these textures accurately: http://imgur.com/00QkZvO . Note in particular the top line of the texture. That color tints the road, leading to the discoloration.
I still need to look into how exactly the texture gets corrupted.
#40 Updated by magumagu9 about 7 years ago
I think comment #13 actually provides the answer to that: the problem with the shadows only happens when the top line of the screen has garbage pixels. The game draws the shadow texture in the top left corner of the screen. So the problem with shadows is actually the same issue as the garbage pixels at the top of the screen (which basically boils down to us using floating-point math to compute the top-left corner of the EFB, and rounding the result inconsistently).
#41 Updated by NeoBrainX about 7 years ago
Note: The fifo log provided in comment #39 is unsuitable for debugging.
I uploaded a good fifo log at https://dl.dolphin-emu.org/nbx/dffs/sonic_heroes_issue_267.dff . Indeed, the software renderer does not suffer from the issue pointed out here.
#42 Updated by magumagu9 about 7 years ago
There was a bunch of discussion on IRC about this today. Quick summary:
- This game clears the screen by drawing a black rectangle where the top left corner is something like (0.50007, 0.50009) in screen coordinates.
- Due to the way the console does rasterization, this coordinate covers the pixel at (0,0).
- There's a bug in the OpenGL backend which means we don't rasterize the black rectangle correctly at 1xIR. This doesn't affect the D3D backend for reasons which we haven't figured out yet. neobrain is looking into it.
- Anything other than 1xIR not working is a consequence of the fact that higher IR levels aren't accurate emulation: if we pretend the resolution is twice as high, the top left corner of the rectangle is at (1, 1), and that simply doesn't cover the corner of the screen. It might be possible to enhance 2xIR mode to deal with cases like this more gracefully, or we could use something game-specific like a cheat code, but it's a separate issue.
#43 Updated by NeoBrainX about 7 years ago
- we now know for sure that each pixel is divided into a 12x12 grid with one grid point per subsample.
- hence it seems logical to have (fixed-point) screen coordinates as multiples of 1/12th.
- in the default configuration, multisampling is disabled, hence all subsamples are concentrated in the center of the subsampling grid.
- As tested in hwtests ( https://github.com/dolphin-emu/hwtests/blob/872cd517cc3f8edb20161506109344652bbd02b5/gxtest/source/main.cpp#L498 ), the screen coordinate of the center of the subsampling grid is roughly 7/12th (i.e. 0.58333333). However, the tests currently indicate that it's somewhat less than that, but I'm not sure if that's really true or just because the test suffers from rounding errors.
- the point is: the screen coordinate of (what we can consider to be) the pixel center is not at 0.5 as is the case normally*, but slightly shifted further to the bottom-right.
- hence, the current hw renderers put the black rectangle mentioned in point 1 of comment #49 at (1,1) instead of (0,0). I'm not completely sure why D3D works fine with 1xIR, and it really shouldn't.
As far as I can tell, a perfectly fine approximation of this behavior would be to shift all of our screen space coordinates by 0.08333333 (as a hardcoded value). Given that the reason for this offset is well-understood but the actual fix (namely to emulate limited screen space coordinate precision) is needlessly complicated and probably won't yield any better emulation, I'd say we should indeed go with that hardcoded solution. Note that I don't see any good way to fix this for non-native rendering resolutions.
Any other opinions for this?
- As far as I could tell, both D3D and OpenGL guarantee the pixel center to be located at (0.5,0.5).
#44 Updated by NeoBrainX about 7 years ago
P.S.: With a ridiculous amount of effort and care, it would be possible to fix this game even for higher internal resolutions. What you basically need to do at the end of the vertex shader stage is to preliminary convert the output coordinates to the theoretical screen space of 1xIR and then transform it back to clipspace such that the output is the same. Note that I'm intentionally being vague here because I'm not even sure myself how it would look in detail, nevertheless it will likely be quite the mess.
#45 Updated by JMC4789 about 7 years ago
- Status changed from Accepted to Fixed
#48 Updated by seapancake over 5 years ago
- File G9SP8P-2.png G9SP8P-2.png added
- File G9SP8P-4.png G9SP8P-4.png added
- File G9SP8P.dff G9SP8P.dff added
This issue is still present both in 4.0-8459 as well as 4.0-1474 which was supposed to have fixed this issue. Present on both ends whenever AA is enabled regardless of IR. 3-frame FIFI log attached as well.
Initial issue describes this is a general issue however later on there is a series of comments relating to AA so figure best to re-open this, if not happy to log a new bug.