http://bugs.winehq.org/show_bug.cgi?id=34266
Bug #: 34266 Summary: Division by zero in shader results in NaNs Product: Wine Version: 1.7.0 Platform: x86 OS/Version: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: directx-d3d AssignedTo: wine-bugs@winehq.org ReportedBy: achurch+wine@achurch.org Classification: Unclassified
Created attachment 45619 --> http://bugs.winehq.org/attachment.cgi?id=45619 Proof-of-concept patch
As reported in the AppDB, if the HDR rendering option is enabled in Final Fantasy XIV, some scenes have large black squares covering the screen. This appears to stem from NaNs getting stored in floating-point framebuffers as the result of division by zero in a fragment shader.
Granted there's a whole bunch of wild guessing involved, but changing the translation of the HLSL rcp instruction to explicitly check for zero and return a huge value instead of performing the division seems to fix the problem without causing any side effects (see attached patch).
I do note that HLSL defines the rcp instruction to return infinity for a zero operand (*1), while the GLSL spec says that division by zero "result[s] in an unspecified value" (*2).
(*1) http://msdn.microsoft.com/en-us/library/windows/desktop/hh447205%28v=vs.85%2... (*2) http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf (section 5.9 "Expressions") -- bizarrely, the GLSL 4.4 spec keeps that language but adds section 4.7.1 "Range and Precision" which says that "dividing a non-zero by 0 results in the appropriately signed IEEE Inf", so the spec is internally inconsistent and who knows what you'll get.