Skip to content

Getting Effect .fx files to compile and run Hints, Tips and Gotchas

iamthefaker edited this page Apr 19, 2013 · 38 revisions

Summary of some gotchas and work arounds I came across in the process of transferring my effects files across to MonoGame from XNA.

(a.k.a. things I wish I had known 3 days ago).

If you are just starting look at these pages first:

(0) https://github.com/mono/MonoGame/wiki/MonoGame-Content-Processing

(1) https://github.com/mono/MonoGame/wiki/Effects-And-Shaders

Then come back here for troubleshooting hints and tips.

(0) Aligning your version of the content processor and the runtime

For shader .fx files, the version of the of the content processor you are using to compile your xnb files (ie. MonoGameContentProcessors.dll) must be aligned with the version of the runtime you are running your game against (ie. MonoGame.Framework.dll)

Otherwise you may get "Wrong MGFX file version!" raised by ReadEffect() in Effect.cs when you do a content.Load [because the version written in to the .xnb file is not a match with the value of MGFXVersion that has been put in the run time].

So if you have this error, the first thing to check is that your content processor is the same up-to-dateness as the version of the runtime you are running your game against.

(1) Shader model compilation:

(a) For OpenGL versions of MonoGame (eg. Mac, Linus, WindowsGL) the shader model must be SM 3.0 or lower

(b) For DirectX versions of MonoGame (eg. WinRT, Windows8) the shader model must be SM 4.0 or higher.

(see: https://monogame.codeplex.com/discussions/432060 )

In the DirectX case it is typical for people to use the:

vs_4_0_level_9_1 and ps_4_0_level_9_1

compilation profiles, because these provide backwards compatibility for Shader Model 2 shaders.

(see https://github.com/mono/MonoGame/wiki/Effects-And-Shaders )

(2) "Windows8" configuration == DX11 (inside the content processor)

(a) The "Windows8" build configuration is used internally in the MonoGame content processor code to indicate compilation to target DX11.

Look at the code on line 29 of MGEffectProcessor.cs!

options.DX11Profile = platform == MonoGamePlatform.Windows8 ? true : false;

(again see: https://monogame.codeplex.com/discussions/432060 )

The ContentHelper.cs file in the ContentProcessors project reads the build configuration name you are using then does this:

switch (platform.ToUpper())
{
case "WINDOWS":
return MonoGamePlatform.Windows;
case "WINDOWS8":
return MonoGamePlatform.Windows8;
case "IOS":
return MonoGamePlatform.iOS;
case "ANDROID":
return MonoGamePlatform.Android;
case "LINUX":
return MonoGamePlatform.Linux;
case "OSX":
return MonoGamePlatform.OSX;
case "PSM":
return MonoGamePlatform.PSM;
etc.
}

Which then gets used by MGEffectProcessor.cs (as above) options.DX11Profile = platform == MonoGamePlatform.Windows8 ? true : false; to set the flag specifying DX11.

In other words, in order to compile .xnb files from your .fx files that will be able to run against the Windows DirectX version of MonoGame, you MUST use build profile that is specifically called "Windows8" !! ... either the one supplied with the project code or one you make yourself.

At some point (which I haven't tracked down, yet) this getting written into a registry key
called "MONOGAME_PLATFORM" (HKEY_CURRENT_USER/Environment/MONOGAME_PLATFORM), and then gets read back from that key via: var platform = Environment.GetEnvironmentVariable("MONOGAME_PLATFORM", EnvironmentVariableTarget.User);

If you don't realize this, having just converted all your .fx files to run against
SM 4.0, when you come to compile them for DX11, you will cryptically be told:
"Vertex shader 'SimpleVS' must be SM 3.0 or lower!"

(And your brain says:
"Ein minuten, bitter! I just specifically changed them all to SM 4.0!" as per the previous tip.)

(b) The "Windows" build configuration is used for the WindowsGL target.

(c) Aside: The WindowsGL version of MonoGame is primarily intended to be a test environment. Don't necessarily expect great performance from this build.

(3) Windows8, DX11 profile, switch POSITION0 to SV_POSITION (in .fx file)

When compiling for the Windows8, DX11 profile, the POSITION and POSITION0 semantics must be replaced by SV_POSITION.

Otherwise you will get: A first chance exception of type 'SharpDX.SharpDXException' occurred in SharpDX.DLL Additional information: HRESULT: [0x80070057], Module: [Unknown], ApiCode: [Unknown/Unknown], Message: The parameter is incorrect.

in new SharpDX.Direct3D11.InputLayout

There may be other similars.

(see: https://monogame.codeplex.com/discussions/402753 )

Clone this wiki locally