[Solved][Shader] Different MGFX binary format between mono and .net core?

Hello,

I am transitioning to .net core using @harry-cpp nuget packages, and doing so I noticed that the compiled fx files compiled with the excellent Infinitespace Studios Remote Effect Processor (from @dellis1972) do no work anymore. I get the following error:

System.Exception : This MGFX effect is for an older release of MonoGame and needs to be rebuilt.

Is this expected? I noticed that the .net core package version is a bit older than the official one.

If so, is there a way to make the binaries built using the remote effect processor compatible with the .net core package?

I am using Ubuntu 18.04, and comparing my older solution using MonoGame.Framework.DesktopGL (version 3.7.1.189) and the new one using MonoGame.Framework.DesktopGL.Core (version 3.7.0.7).

I saw a workaround here, but it is a bit heavier to set up compared to the remote processor.

Thanks a lot!

The binary format for compiled effects can change every once in a while. I don’t have a workaround for you right now, but I have an idea on how we could improve shader compilation on Mac/Linux.

We could host the plug-in on this website and have the different versions available. Then users could select the version they want to build as a property of the content processor.

Okay, thanks for your answer. Will be happy to test the plug-in you mention when it is available, I think it would really be a nice feature for Mac/Linux users.

For now I will try the workaround linked in my previous post.

One last question: are there plans to update the MonoGame.Framework.DesktopGL.Core nuget package to version 3.7.1?

We’re working right now on getting the main repo set up with .NET Core. In fact, if you build from source you can already build the .NET Standard build. There are no instructions in the readme or docs yet though. But you can build the MonoGame.Framework.DesktopGL.csproj file in the MonoGame.Framework folder either with MSBuild or dotnet build. You’ll need to pull in the submodules, but you don’t have to run Protobuild to get it built.

Ok, I tried to build it from source as you suggested with msbuild, dotnet and cake build, but it failed each time:

  • with msbuild /p:Configuration=Release MonoGame.Framework.DesktopGL.csproj (it strangely works in debug though)
    /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: The "GenerateDepsFile" task failed unexpectedly. [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj] /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: System.TypeLoadException: Could not load type of field 'Microsoft.NET.Build.Tasks.DependencyContextBuilder:_filteredPackages' (12) due to: Could not resolve type with token 01000027 from typeref (expected class 'NuGet.Packaging.Core.PackageIdentity' in assembly 'NuGet.Packaging, Version=5.1.0.5, Culture=neutral, PublicKeyToken=31bf3856ad364e35') assembly:NuGet.Packaging, Version=5.1.0.5, Culture=neutral, PublicKeyToken=31bf3856ad364e35 type:NuGet.Packaging.Core.PackageIdentity member:(null) [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj] /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: at Microsoft.NET.Build.Tasks.TaskBase.Execute () [0x00000] in <924592ebce6d45ffb749fbc6226bc386>:0 [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj] /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute () [0x00029] in <58f0218f988743a48dd7c84cbe933f4e>:0 [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj] /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask (Microsoft.Build.BackEnd.ITaskExecutionHost taskExecutionHost, Microsoft.Build.BackEnd.Logging.TaskLoggingContext taskLoggingContext, Microsoft.Build.BackEnd.TaskHost taskHost, Microsoft.Build.BackEnd.ItemBucket bucket, Microsoft.Build.BackEnd.TaskExecutionMode howToExecuteTask) [0x001f6] in <58f0218f988743a48dd7c84cbe933f4e>:0 [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj]

  • with dotnet build:
    /usr/share/dotnet/sdk/2.2.300/Microsoft.Common.CurrentVersion.targets(1175,5): error MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.5.1" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend. [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj]

  • with cake using instructions found here, I got the same error as with msbuild:

/usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: The "GenerateDepsFile" task failed unexpectedly. [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj] /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: System.TypeLoadException: Could not load type of field 'Microsoft.NET.Build.Tasks.DependencyContextBuilder:_filteredPackages' (12) due to: Could not resolve type with token 01000027 from typeref (expected class 'NuGet.Packaging.Core.PackageIdentity' in assembly 'NuGet.Packaging, Version=5.1.0.5, Culture=neutral, PublicKeyToken=31bf3856ad364e35') assembly:NuGet.Packaging, Version=5.1.0.5, Culture=neutral, PublicKeyToken=31bf3856ad364e35 type:NuGet.Packaging.Core.PackageIdentity member:(null) [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj] /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: at Microsoft.NET.Build.Tasks.TaskBase.Execute () [0x00000] in <924592ebce6d45ffb749fbc6226bc386>:0 [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj] /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute () [0x00029] in <58f0218f988743a48dd7c84cbe933f4e>:0 [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj] /usr/share/dotnet/sdk/2.2.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(129,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask (Microsoft.Build.BackEnd.ITaskExecutionHost taskExecutionHost, Microsoft.Build.BackEnd.Logging.TaskLoggingContext taskLoggingContext, Microsoft.Build.BackEnd.TaskHost taskHost, Microsoft.Build.BackEnd.ItemBucket bucket, Microsoft.Build.BackEnd.TaskExecutionMode howToExecuteTask) [0x001f6] in <58f0218f988743a48dd7c84cbe933f4e>:0 [/home/spaaaaam/git_repos/MonoGame/MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj]

I didn’t have time to dig further.

I might get access to a windows machine next Saturday, maybe it is the easiest way to get my shaders to work with the .net core version of MG.

If you see something I did wrong or if I can test something else to help, please tell me!

Thanks again for your help

The DesktopGL project multitargets .NET Standard 2.0 and .NET Framework 4.5.1. On Linux you need to have Mono installed to build for .NET Framework and there’s currently a bug in dotnet build that causes it to fail multitarget builds that target both .NET Framework and non .NET Framework on non-Windows platforms (https://github.com/dotnet/sdk/issues/826). The solution is to specify which framework to build for:
dotnet build MonoGame.Framework.DesktopGL -f netstandard 2.0

Ok, thanks again for your help.

I succeeded in building the DesktopGL project with dotnet build MonoGame.Framework.DesktopGL.csproj -f netstandard2.0 -c Release.

Then when I try to build the DesktopGL nuget package with nuget pack MonoGame.Framework.DesktopGL.nuspec in the NugetPackages folder, it fails because of a bad path:
Could not find a part of the path '/home/spaaaaam/git_repos/NuGetPackages/build/DesktopGL'.

The correct path is indeed /home/spaaaaam/git_repos/MonoGame/NuGetPackages/build/DesktopGL.

I tried to play a bit with the paths in the nuspec file, but didn’t get it to work. I noticed that WindowsGL is mentioned (instead of DesktopGL) in the C# assemblies and Native Libs sections of this file, which seems weird. Any idea?

To build the nupkg, run dotnet pack MonoGame.Framework.DesktopGL.csproj -f netstandard2.0 -c Release. The nuspec file is for the old project. In the new SDK-style csproj nuget information can be included so you can simply use dotnet pack :slight_smile:

Sorry for the late reply.

I managed to build the nuget package with the following command:
dotnet pack MonoGame.Framework.DesktopGL.csproj -c Release -p:TargetFrameworks=netstandard2.0 -p:PackageVersion=3.7.1

Now I am struggling to make dotnet restore accept the compiled nupkg.

I have put it in a dedicated folder using the same structure as the official one (i.e. /home/spaaaaam/.nuget/packages/monogame.framework.desktopgl.core/3.7.1/monogame.framework.desktopgl.core.3.7.1.nupkg), and followed these instructions to add a RestoreSources tag in my csproj, but without luck so far:
error NU1102: - Found 0 version(s) in /home/spaaaaam/.nuget/packages/monogame.framework.desktopgl.core/3.7.1

Any suggestions? Thanks!

You can reference the source project directly using a ProjectReference. That’s a lot easier: dotnet add reference <path to MG DesktopGL csproj> (cli doc).

Regarding the NuGet with a local feed, I’m not sure you should put your local feed in .nuget/packages, because that’s used for caching. That might cause issues. You might also run into an issue with local feeds: https://github.com/NuGet/Home/issues/6219.

Indeed, that’s much simpler.

Many thanks for your help, it works now, and I can enjoy MG in a shiny .net core environment! :slight_smile:

1 Like

You’re welcome! Once we finish the migration we’ll get a new release pushed out and we’ll have the NuGet up on nuget.org. That’ll make things a lot easier :slight_smile:

Hold on, it is not over yet… :sob:

After cleaning things a bit and replacing the reference to the nuget by the reference to the source project in all the csproj, building now fails:
`/home/spaaaaam/.nuget/packages/monogame.content.builder/3.7.0.4/build/MonoGame.Content.Builder.targets(48,5): error MSB4044: The “CollectContentReferences” task was not given a value for the required parameter “MonoGamePlatform”.

Not sure why I did not have this error the first time.

Do I need to build the ContentPipeline from source and reference it as well?

For now I have bypassed the problem using MG 3.7.0 compiled shaders (under windows) and pipeline preprocessor macros as explained here.

You should add <MonoGamePlatform>DesktopGL</MonoGamePlatform> to a PropertyGroup in the csproj. Maybe we should add it to the templates in case people switch out the nuget reference for a source reference. If you use the NuGet the property gets defined in a .targets file that gets pulled in.

Ok, I finally got time to give it a try, and it works as expected. :champagne: Thanks a lot once again!

For the record, I have the impression that the source compiled version (release config) is a bit slower than the 3.7 nupkg (based on some perf tests with slightly less stable fps) but it is perfectly usable.

1 Like

It really shouldn’t be slower. Any performance differences are most likely due to the .NET runtime.

@spaaaaam Wait. Do you need help to set it up on linux or you just use windows now?
Or you guys made something new and solved it other way? @Jjagg ?

The NuGet MG .NET Core package is built from an old MG version that was not compatible with the shader compiler from the remote plugin. If you build the very recently added DesktopGL .NET Standard project from source (not on nuget yet) it works with the remote shader compiler.