-
-
Notifications
You must be signed in to change notification settings - Fork 289
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: Offset vertices to match HW rounding #1362
base: master
Are you sure you want to change the base?
Conversation
As an FYI, the place where I eventually got stuck was in Tiger Woods where a single screen uses a mix of the fixed function and programmable pipelines. The difference in the way that vertexes are unprojected leads to twinkling seams between polys that were rendered via dissimilar paths. I think my test cases were SC:DA (and/or Spongebob) and Tiger Woods 2005 during the course flyover sequence. I think the ProjAdjacentGeometry test is the important one: https://github.com/abaire/nxdk_pgraph_tests/blob/main/src/tests/vertex_shader_rounding_tests.cpp#L710 |
Thanks for the context, I'll see about picking up Tiger Woods as another test case. The only ProjAdjacentGeometry test case that this code fails is the one with 0.5625 bias. What's interesting is that HW rounds the leftmost dark square off one pixel to the right, but not the other three. The behavior in this PR rounds all four of them off to the right. |
Hopefully it'll turn out that your fix is sufficient and I created the problem in Tiger Woods while chasing down other issues :) I believe @Triticum0 found the issue w/ TW while testing my PR and can probably say definitively which version is problematic (though I suspect they used the same engine year after year so it might not matter). I'm away from my HW for an indeterminate amount of time and unfortunately I don't appear to have left a comment tracking the specific version I was testing, sorry! |
Can confirm this works with Splinter Cell: Double Agent, removing the blue/green lines at the top and left. |
There seem to be a few small artifacts with this PR vs master in tiger woods 2005 in the form of white dots that flash in and out. tigerwoods-comparison.mp4 |
Exactly, I believe that's the background color showing through the gaps caused by (presumably numerical precision induced) differences between the fixed and programmable pipelines. Before I had to step back from this, I was beginning to consider simply merging the fixed and programmable paths by defining one or more static nv2a shaders to reproduce the fixed pipeline behavior. I hoped that would eliminate this issue and would reduce/remove the potential for other cases where behavior unintentionally ends up differing between the two paths. |
@@ -855,6 +857,26 @@ GLSL_DEFINE(texMat3, GLSL_C_MAT4(NV_IGRAPH_XF_XFCTX_T3MAT)) | |||
} | |||
mstring_append(header, "\n"); | |||
|
|||
mstring_append_fmt(header, "\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming you're able to fix the mismatch between fixed & programmable: I think it's worth bringing over some of the comments explaining why this is necessary, particularly the magic numbers involved. I don't think any of this would make sense to a future maintainer without understanding the context of the nv2a-specific rounding behavior, which differs from the generally well known/documented 0.5 delta between old DirectX and OpenGL.
I also don't know if it's actually possible to address higher render scales with a simple offsetting approach. 2x and higher will turn garbage that would've been truncated to 0 into a full pixel or more. I had started to look at using a viewport to handle the 9/16th rounding instead but I think I stopped on realizing that glViewportIndexedf
requires OGL 4.1.
That's odd, the hardware I had been testing on matches the golden results. Your output is interesting because at a glance, the upper programmable pipeline squares round up along the y-axis and all fixed squares round down, but there are no gaps in between the programmable and fixed squares like would be expected. Flooring to the nearest 1/16 is an interesting idea, it's worth trying. Doing that alone doesn't fully address the issue though, because we would still need to handle differing rounding behavior at 8/16. |
Co-authored-by: Erik Abair <[email protected]>
e322517
to
5ce8573
Compare
This is a continuation of the work done in #735 . Hardware will round vertices at 0.5625 instead of OpenGL's 0.5.
The approach taken in this PR shifts each vertex up and to the left by 0.0625, so that the HW rounding point 0.5625 is mapped to 0.5. A small bias is then added based on whether the subpixel was above or below the boundary, to correct for precision errors. This passes all but one of the test cases that abaire made (specifically, the projected adjacent geometry test with a bias of 0.5625 is not entirely matching HW), which is why I'm leaving it in draft for now.
This approach does not work at resolution scales higher than 1x. I'm not sure that there is a general solution that both works above 1x and does not introduce z-fighting or flickering.
Known Issues: