-
-
Notifications
You must be signed in to change notification settings - Fork 300
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
nv2a: Fix pixel center offset problem #735
base: master
Are you sure you want to change the base?
Conversation
This removes the edge bloom (top and left) present in Fable: The Lost Chapters. 👍 |
c2ed9f3
to
72164fb
Compare
Still need to fix this at higher render scales, and I just found that it doesn't quite work correctly on M1 (at 0.5 there is already a red bar along the left side, though not along the top) so there may be some device/GL dependency to work through as well. |
72164fb
to
451f7d6
Compare
The current state of this PR also causes some corruption in certain games like Splinter Cell:Double Agent when combined with #879 (which unmasks the issue by allowing compounding errors). In the pgraph test for #879, I see that there's a yellow column along the right hand side of the texture after it is drawn the second time. I suspect that this happens in games as well, leading textures that go through multiple phases of compositing to be smeared (this is exactly what @revix-0 has reported in SC:DA w/ this fix). Here is a screenshot from xemu, and this is the same screenshot zoomed in to look at the right column Removing this PR and running #879 alone results in correct output. |
It looks like there is differing behavior between cases where we are rendering to the framebuffer versus to a texture. When rendering direct to the framebuffer, it appears to be correct that we should adjust the coordinate by flooring the (screenspace) output of the xbox vertex shader + 0.5625 to match hardware rounding behavior. When rendering to a texture, it seems like even without this PR (and with any offset values I've tried) there is texture smearing, which makes me think that it's related to the way xemu handles render targets (it looks like it's being filtered rather than faithfully copied). |
Here is an illustration of the problem. This screen is the result of compositing the left hand side of a texture on top of itself (leaving the right hand side as the initial value, a hand-defined checkerboard pattern that I've verified is correct by dumping the memory passed to glTexImage2D in Whenever xemu does compositing, it does a partial pixel shift, despite the s2t_rndr being set up with correct coordinates and even if I force GL_NEAREST filtering. I'm not yet sure where the failure is coming from, but this is probably the root cause of the texture corruption that can be seen in combination with #879. |
A note on debugging this: Unfortunately renderdoc seems to fail to capture interim states for some of the textures. If I take the hand-initialized texture and just render it to the standard color surface I can look at the input texture in renderdoc and confirm that it is as expected (a crisp checkerboard). If I add a self-modifying step (input texture renders to a surface pointing at the same memory address), renderdoc ends up showing the final modification as the input stage, so it becomes very confusing as to whether the input texture was corrupted somehow (doesn't seem likely given the above check) or if renderdoc ends up updating its view of the texture after xemu updates it post-render. This step also corrupts the input (in renderdoc) for the test draw that is not self modifying it. E.g.,
|
With nsight it's a bit more clear:
So I think we can rule out the s2t_rndr, but I'm still left wondering why we don't get consistently shifted results (e.g., if I don't render back into the surface at the same hwaddr as the texture, I get a pixel-aligned image). |
It looks like the way xemu handles the WINDOW_CLIP commands may be incorrect, which also contributes to this problem (and may explain uninitialized data along the outer edges of surfaces) |
I have a fix that gets a pixel perfect match in my test case, but still breaks SC:DA (it does a bunch of downscaling + jitter to do lighting effects and with this fix the resultant overlay is misaligned compared to the plain framebuffer). |
451f7d6
to
fea4227
Compare
can you rebase this with master please so i can do more testing |
fea4227
to
742eb66
Compare
@ryzendew - it should've already been automatically mergable, but rebased anyway |
f154dbe
to
f2e2c3c
Compare
f2f5254
to
222e746
Compare
222e746
to
61f48c5
Compare
This addresses the difference in pixel center between OpenGL and the DirectX 8 approach used by the hardware as well as the fact that the nv2a rounds at 9/16 rather than 0.5. [Tests](https://github.com/abaire/nxdk_pgraph_tests/blob/main/src/tests/vertex_shader_rounding_tests.cpp) [HW Results](https://github.com/abaire/nxdk_pgraph_tests_golden_results/wiki/Results-Vertex_shader_rounding_tests) Fixes xemu-project#725 Fixes xemu-project#57
15f900f
to
a9b70a9
Compare
Just to make this a bit easier to parse through, I've made a list for simplicity to combat the comment bloat Partial fixes |
@Triticum0 Where´s Counter Strike? |
I never tested the game, only add games I tested that were fixed. |
|
This addresses the difference in pixel center between OpenGL and the DirectX 8
approach used by the hardware.
Note that the resultant behavior still does not fully match the hardware, where
screen-space pixel coordinates below (x + 0.5625) => x, but it is close enough
to fix issues with surface-target rendering.
Test
HW results
With this patch, xemu will produce correct output for the render-target but will not fully match the geometry-based test output.
Fixes #725
Fixes #57