nv2a: Use trunc in vertex rounding instead of floor

Xbox seems to truncate instead of flooring, which can be inferred from
interpolated depth buffer values.
This commit is contained in:
coldhex 2025-05-05 21:56:31 +03:00 committed by mborgerson
parent 11dcae01b9
commit a316d74872
3 changed files with 10 additions and 5 deletions

View File

@ -474,7 +474,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
" oPos.w = clampAwayZeroInf(oPos.w);\n"
" oPos.xy /= oPos.w;\n"
" oPos.xy += c[" stringify(NV_IGRAPH_XF_XFCTX_VPOFF) "].xy;\n"
" oPos.xy = floor(oPos.xy * 16.0f) / 16.0f;\n"
" oPos.xy = roundScreenCoords(oPos.xy);\n"
" oPos.xy = (2.0f * oPos.xy - surfaceSize) / surfaceSize;\n"
" oPos.xy *= oPos.w;\n"
);

View File

@ -822,11 +822,9 @@ void pgraph_gen_vsh_prog_glsl(uint16_t version,
mstring_append(body,
/* The shaders leave the result in screen space, while OpenGL expects it
* in clip space. Xbox NV2A rasterizer appears to have 4 bit precision
* fixed point fractional part and to convert floating point coordinates
* by flooring.
* in clip space.
*/
" oPos.xy = floor(oPos.xy * 16.0f) / 16.0f;\n"
" oPos.xy = roundScreenCoords(oPos.xy);\n"
" oPos.xy = (2.0f * oPos.xy - surfaceSize) / surfaceSize;\n"
" oPos.z = oPos.z / clipRange.y;\n"

View File

@ -85,6 +85,13 @@ MString *pgraph_gen_vsh_glsl(const ShaderState *state, bool prefix_outputs)
"\n"
"vec4 NaNToOne(vec4 src) {\n"
" return mix(src, vec4(1.0), isnan(src));\n"
"}\n"
"\n"
// Xbox NV2A rasterizer appears to have 4 bit precision fixed-point
// fractional part and to convert floating-point coordinates by
// by truncating (not flooring).
"vec2 roundScreenCoords(vec2 pos) {\n"
" return trunc(pos * 16.0f) / 16.0f;\n"
"}\n");
pgraph_get_glsl_vtx_header(header, state->vulkan, state->smooth_shading,