Skip to content
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: Adjust NaN handling to be similar to HW #913

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions hw/xbox/nv2a/shaders.c
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,23 @@ GLSL_DEFINE(texMat3, GLSL_C_MAT4(NV_IGRAPH_XF_XFCTX_T3MAT))
i, i);
}
}
mstring_append(header,
"/* Converts the input to vec4, pads with last component */\n"
"vec4 _in(float v) { return vec4(v); }\n"
"vec4 _in(vec2 v) { return v.xyyy; }\n"
"vec4 _in(vec3 v) { return v.xyzz; }\n"
"vec4 _in(vec4 v) { return v.xyzw; }\n"
"#define FixNaN(src, mask) _FixNaN(_in(src)).mask\n"
"vec4 _FixNaN(vec4 src)\n"
"{\n"
" bvec4 nans = isnan(src);\n"
" if (!any(nans)) {\n"
" return src;\n"
" }\n"
" ivec4 signs = floatBitsToInt(src);\n"
" vec4 negative = vec4(lessThan(signs, ivec4(0)));"
" return mix(src, mix(vec4(1.0), vec4(0.0), negative), vec4(nans));\n"
Comment on lines +865 to +871

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
" bvec4 nans = isnan(src);\n"
" if (!any(nans)) {\n"
" return src;\n"
" }\n"
" ivec4 signs = floatBitsToInt(src);\n"
" vec4 negative = vec4(lessThan(signs, ivec4(0)));"
" return mix(src, mix(vec4(1.0), vec4(0.0), negative), vec4(nans));\n"
" if (isnan(src.x)) {\n"
" src.x = step(0.0, sign(src.x));\n"
" }\n"
" if (isnan(src.y)) {\n"
" src.y = step(0.0, sign(src.y));\n"
" }\n"
" if (isnan(src.z)) {\n"
" src.z = step(0.0, sign(src.z));\n"
" }\n"
" if (isnan(src.w)) {\n"
" src.w = step(0.0, sign(src.w));\n"
" }\n"
" return src;\n"

Hi @abaire, may a suggest to change the code to what I wrote? I tried your current solution but it didn't fix anything on my PC. It behaves exactly as master. From my tests, my change behaves almost exactly as real hardware. Almost because there's a slight difference in the -NaNQ_NaNQ and -NaNS_NaNS tests cases in the N/A column, but I'm pretty sure that it's safe to ignore.

I tested a lot of games I couldn't find any regressions in any of them. Games that are fixed by this change:

  • Otogi
  • Otogi 2
  • Pro Cast: Sports Fishing Game
  • Trigger Man

HW - PC (AMD RX 6600M )

Attrib_float_0_1
Attrib_float_0_8
Attrib_float_-1_1
Attrib_float_-8_1
Attrib_float_-INF_INF
Attrib_float_-Max_Max
Attrib_float_-MaxSN_MaxSN
Attrib_float_-Min_Min
Attrib_float_-MinN_MinN
Attrib_float_-NaNq_NaNq
Attrib_float_-NaNs_NaNs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're very welcome to take this one over, I've got some other projects going at the moment and don't have much time for xemu. It'd be good to test on an nvidia card as well, I'm not sure if glsl guarantees NaN behavior so it may be manufacturer or device specific.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a gtx 3060 and can test nvidia, just need the build and the test program...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's too bad to heard. I will need to open a new PR then but I will link it to this one. Once is merged we can close both. Thanks for your research and I hope that you are back to xemu in the future.

@medievil1 you can download the build once I open the new PR.

"}\n");
mstring_append(header, "\n");

MString *body = mstring_from_str("void main() {\n");
Expand Down Expand Up @@ -964,15 +981,15 @@ GLSL_DEFINE(texMat3, GLSL_C_MAT4(NV_IGRAPH_XF_XFCTX_T3MAT))
/* Set outputs */
const char *shade_model_mult = state->smooth_shading ? "vtx_inv_w" : "vtx_inv_w_flat";
mstring_append_fmt(body, "\n"
" vtxD0 = clamp(oD0, 0.0, 1.0) * %s;\n"
" vtxD1 = clamp(oD1, 0.0, 1.0) * %s;\n"
" vtxB0 = clamp(oB0, 0.0, 1.0) * %s;\n"
" vtxB1 = clamp(oB1, 0.0, 1.0) * %s;\n"
" vtxFog = oFog.x * vtx_inv_w;\n"
" vtxT0 = oT0 * vtx_inv_w;\n"
" vtxT1 = oT1 * vtx_inv_w;\n"
" vtxT2 = oT2 * vtx_inv_w;\n"
" vtxT3 = oT3 * vtx_inv_w;\n"
" vtxD0 = clamp(FixNaN(oD0, xyzw), 0.0, 1.0) * %s;\n"
" vtxD1 = clamp(FixNaN(oD1, xyzw), 0.0, 1.0) * %s;\n"
" vtxB0 = clamp(FixNaN(oB0, xyzw), 0.0, 1.0) * %s;\n"
" vtxB1 = clamp(FixNaN(oB1, xyzw), 0.0, 1.0) * %s;\n"
" vtxFog = FixNaN(oFog, x) * vtx_inv_w;\n"
" vtxT0 = FixNaN(oT0, xyzw) * vtx_inv_w;\n"
" vtxT1 = FixNaN(oT1, xyzw) * vtx_inv_w;\n"
" vtxT2 = FixNaN(oT2, xyzw) * vtx_inv_w;\n"
" vtxT3 = FixNaN(oT3, xyzw) * vtx_inv_w;\n"
" gl_Position = oPos;\n"
" gl_PointSize = oPts.x;\n"
"\n"
Expand Down
11 changes: 0 additions & 11 deletions hw/xbox/nv2a/vsh.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,17 +614,6 @@ static const char* vsh_header =
* https://www.opengl.org/registry/specs/NV/vertex_program1_1.txt
*/
"\n"
//QQQ #ifdef NICE_CODE
"/* Converts the input to vec4, pads with last component */\n"
"vec4 _in(float v) { return vec4(v); }\n"
"vec4 _in(vec2 v) { return v.xyyy; }\n"
"vec4 _in(vec3 v) { return v.xyzz; }\n"
"vec4 _in(vec4 v) { return v.xyzw; }\n"
//#else
// "/* Make sure input is always a vec4 */\n"
// "#define _in(v) vec4(v)\n"
//#endif
"\n"
"#define INFINITY (1.0 / 0.0)\n"
"\n"
"#define MOV(dest, mask, src) dest.mask = _MOV(_in(src)).mask\n"
Expand Down