Monogame: Numbers in generated GLSL are invalid on PCs with non-English culture

Created on 26 Feb 2013  Â·  11Comments  Â·  Source: MonoGame/MonoGame

Problem:
I build a simple shader using the MGEffectProcessor. At runtime the generated GLSL cannot be compiled because it contains invalid constants like these:

const vec4 vs_c0 = vec4(-1,000000.0, 1,000000.0, 0,000000.0, 0,000000.0);
const vec4 vs_cl = vec4(0,002500.0, -0,004167.0. l,00000.0, 0,000000.0);

Cause:
My PC uses English as the UI language but German for the number formatting. I guess this causes mojoshader to produce invalid numbers???

Workaround:
In the control panel of your PC set the culture for formats to English(United States). Restart VisualStudio and try again. Then following correct GLSL is produced.

const vec4 vs_c0 = vec4(-1.0. 1.0, 0.0, 0.0);
const vec4 vs_c1 = vec4(0.0025, -0.004167, 1.0, 0.0);

More information:
The problem only occurs when shaders are generated in the content pipeline. If I debug 2MGFX.exe, the problem is not there.

MGFX Needs Testing

Most helpful comment

Does the mojoshader fork MG is using have specific hacks?

Seems like it: https://github.com/MonoGame/mojoshader/commit/39fd1b5893ee81487f01b01ced6138c9e52a3fe4
There's some more MG changes in the most recent commits.
I don't know if upgrading is worth it right now. Ethan made a bunch of changes to MojoShader, including changes to the API so it would take some effort. And since this issue hasn't come up again it's not that big a deal. I don't know of any other issues that would be fixed by upgrading. IMO we should focus on getting a more full-featured shader compiler chain going (#2167).

All 11 comments

Very interesting.

MojoShader only reads compiled HLSL shaders... so I think it has to be the HLSL compiler doing this. I've never seen any sort setting which defines the culture for the HLSL compiler... it is all internal to the compiler DLL.

The only think I can think of is that maybe the content pipeline itself is changing the culture in some weird way and it is affecting the compiler DLL.

May be should force invariant culture?

In another open source project we had to force it to fix problems while reading our data;

Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; // Use invariant culture - we have to set it explicitly for every thread we create to prevent any mpq-reading problems (mostly because of number formats).

I have tried to add this in MGEffectProcessor, but it has no effect. Numbers are still invalid.
Funny thing is that the problem only occurs in the content pipeline.

This function in mojoshader.c is used to build the GLSL returned by
MOJOSHADER_parse()

// !!! FIXME: this is sort of nasty.
static void floatstr(Context *ctx, char *buf, size_t bufsize, float f,
                 int leavedecimal)

It uses snprintf(buf, bufsize, "%f", f), which uses the current locale for
formatting. That's where the problem appears to be. Mojoshader needs to
call setlocale(LC_ALL, "C") to make sure it outputs the numbers in the
expected format no matter the locale of the user.

On 26 February 2013 23:10, Helikin [email protected] wrote:

I have tried to add this in MGEffectProcessor, but it has no effect.
Numbers are still invalid.
Funny thing is that the problem only occurs in the content pipeline.

—
Reply to this email directly or view it on GitHubhttps://github.com/mono/MonoGame/issues/1458#issuecomment-14111836
.

Hum... I guess I was wrong there. I guess the HLSL binary shader contains some strings which is what MojoShader is parsing incorrectly.

The hacked version of MojoShader we're using is here:

https://github.com/espes/mojoshader

We would need to fix it there and build a new set of binaries.

Mojoshader is reading the binary HLSL fine. It is creating the incorrectly
formatted numbers when it generates the GLSL code that is included in the
mgfx file. The GLSL is then compiled at runtime, which is where it is
failing.

Ah... duh. That makes perfect sense now.

Huh, I don't think we ever upgraded MojoShader but seems like no one else that ran into the problem came across this issue.

I use PCs with different cultures, including French which has comas for floating point, and never encountered this issue.

Does the mojoshader fork MG is using have specific hacks? We could rebuild a fresh binary with the latest upstream fixes (until we move to another solution).

Does the mojoshader fork MG is using have specific hacks?

Seems like it: https://github.com/MonoGame/mojoshader/commit/39fd1b5893ee81487f01b01ced6138c9e52a3fe4
There's some more MG changes in the most recent commits.
I don't know if upgrading is worth it right now. Ethan made a bunch of changes to MojoShader, including changes to the API so it would take some effort. And since this issue hasn't come up again it's not that big a deal. I don't know of any other issues that would be fixed by upgrading. IMO we should focus on getting a more full-featured shader compiler chain going (#2167).

I agree.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MichaelDePiazzi picture MichaelDePiazzi  Â·  4Comments

willmotil picture willmotil  Â·  5Comments

bjornenalfa picture bjornenalfa  Â·  5Comments

tomspilman picture tomspilman  Â·  4Comments

SenpaiSharp picture SenpaiSharp  Â·  3Comments