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

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.

@Peon501, @Jjagg, thanks for the follow up.

Both solutions we tried worked fine until yesterday. I chose to use MG build from source, so a to be able to recompile my shader if need be.

So this morning I modified one of my shader and recompiled it using the remote plugin, and got the initial error message once again: System.Exception : This MGFX effect is for an older release of MonoGame and needs to be rebuilt.

So I debugged the MG code, and easily found the place where it happens in Microsoft.Xna.Framework.Graphics.Effect.ReadHeader.

Line 130, there is this check:
if (header.Version < MGFXHeader.MGFXVersion) throw new Exception("This MGFX effect is for an older release of MonoGame and needs to be rebuilt.");

In my case header.Version is 7 while MGFXHeader.MGFXVersion is 8.

I don’t understand how I was able to pass this test before modifying my shader, as it was already compiled with the same remote service.

Edit: from here, I can see that MGFXVersion was incremented to version 8 in April 2016, and hence that this change has been part of MG since 3.6. So I really don’t understand why I get effects compiled in version 7…

Edit2: from here, I think that the pipeline service tries to get the MG version used by the client, and falls back to MG 3.5 if it doesn’t recognize it.
@dellis1972: Could you please confirm?

Edit3: so my guess is that the problem root is not the header version, but rather the MG version exposed to the pipeline service when calling it from .net core. The version is ok by itself, but it is not recognized properly here.
@Jjagg: What do you think?

Edit4: submitted issue in InfinitespaceStudios.Pipeline repo.

I responded on the issue.

Update: @dellis1972 fixed the service. It works fine now.

@Jjagg: any news concerning the plans to host the service on MonoGame servers?

Thanks all for your help.