Add MonoGame 3.8.5 Content Builder export mode (closes DX12/Vulkan shader gate)#120
Open
vchelaru wants to merge 5 commits into
Open
Add MonoGame 3.8.5 Content Builder export mode (closes DX12/Vulkan shader gate)#120vchelaru wants to merge 5 commits into
vchelaru wants to merge 5 commits into
Conversation
3.8.5 shipped stable on nuget.org, replacing the preview line. Removes the now-dead preview/stable duality (version props, UI selector, .Native version-gating, the monoGameVersion override) — WindowsDX12 and DesktopVK are now regular, always-available MonoGame targets. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ader gate) Opt-in ContentBuildMode.ContentBuilder routes assets and shaders through MonoGame's new code-first Content Builder (Builder.cs + BuildContent.targets) instead of raw/ShadowDusk/MGCB, superseding ShaderCompileMode when chosen. Unlike mgcb.exe it isn't limited to a fixed platform list, so it also closes the DX12/Vulkan shader gate from issue #52. MonoGame.Content.Builder.Task stays installed on classic targets for buildTransitive-only libraries (Apos.Shapes/Gum) that the new pipeline can't see. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
MonoGame's DX12/Vulkan Content Builder compiles via DXC, which requires Shader Model 6 (vs_6_0/ps_6_0), rejects the legacy sampler2D/tex2D combo, and requires SV_Target0 instead of COLOR/COLOR0 for the pixel output. None of the example shaders had an SM6 branch, so ContentBuilder exports to MonoGameWindowsDX12/MonoGameDesktopVK failed to compile every shader. Adds an `#elif defined(SM6) || defined(VULKAN)` branch to each file's shader-model defines, a matching Texture2D<float4>/SamplerState declaration for the texture(s), and a fully separate SM6 pixel-shader entry point (ShadowDusk's OpenGL translator requires the classic `: COLOR` / `tex2D(...)` entry point to stay literal and unsplit, so the two shader models get independent function bodies rather than sharing one via macros or a split signature). The `#if OPENGL` / classic branches are untouched. Verified: ShadowDuskCLI /Profile:OpenGL produces byte-identical .mgfx output before/after for all 16 files; a real `dotnet build` of a ContentBuildMode.ContentBuilder export targeting MonoGameWindowsDX12 compiles all 16 shaders with zero errors; full XnaFiddle.Tests suite (337 tests) passes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… Vulkan backend ShadowDusk 0.12.0 adds a real Vulkan backend that compiles the same plain .fx source as every other target (no SM6 source rewrite needed, verified against the pre-SM6-branch form of Grayscale.fx via ShadowDuskCLI and a real dotnet build). GetShaderExportInfo now wires MonoGameDesktopVK through ShadowDusk.Compiler/PlatformTarget.Vulkan, closing the DesktopVK half of issue #52; MonoGameWindowsDX12 is unchanged (still gated, still needs ContentBuildMode.ContentBuilder for shaders). Verified the 0.11.0 -> 0.12.0 GL codegen fidelity change (pow/division strength-reduction) produces byte-identical .mgfx for all 16 bundled example shaders, so no rendering regression risk there. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
"Shader compilation:" and "Content pipeline:" silently overrode each other and both used the words "Content Pipeline"/"MGCB" for different things. Replaced with a single "Content strategy:" group (ShadowDusk / Classic MGCB / MonoGame Content Builder) backed by one UI-only ContentStrategy enum that maps to ProjectExporter's existing (ShaderCompileMode, ContentBuildMode) pair. No changes to ProjectExporter's public API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ContentBuildMode.ContentBuilderexport choice, available for every MonoGame target. It routes both assets and shipped.fxshaders through MonoGame 3.8.5 GA's new code-first Content Builder (a generated{ProjectName}.Contentconsole project +Builder.cs+BuildContent.targets) instead of raw/ShadowDusk/MGCB, supersedingShaderCompileModefor that export.mgcb.exe, the new Content Builder isn't limited to a fixed platform list — so this is the mechanism that finally closes the DX12/Vulkan shader gate from issue Export shaders to gated targets: iOS, MonoGame DX12/Vulkan #52 (CompilesShippedShadersnow returnstruethere under Content Builder mode).MonoGame.Content.Builder.Taskstays installed on classic MonoGame targets even in Content Builder mode: Apos.Shapes/Gum ship their own.fx+Content.mgcbviabuildTransitive, invisible to the new pipeline (which only walks the fiddle's ownAssets/folder). Both pipelines deliberately coexist there.ExportRuntime.MonoGame; picking Content Builder hides the now-superseded shader-compilation radio and updates the status banner.Stacks on #119 (
chore/monogame-3.8.5-ga, not yet merged) — this branch is based on that PR's HEAD, so the diff includes its commit until #119 merges.Implementation notes / deviations from the plan
.achx/.fntas needing to stay raw (no pipeline importer). A grep ofIndex.razor.cs'sSupportedAssetExtensions(broadened by Broaden asset allowlist to include tilemap/level and text-data formats #115, the commit right before this stack) turned up the full set that XnaFiddle ships raw viaTitleContainer.OpenStream/dedicated loaders rather thanContentManager.Load<T>:.achx .fnt .ttf .ember .xnb .tmx .tsx .world .ldtk .ogmo .json .txt .xml. Only.png/.wavare actuallyContentManager-loadable, so those are the only ones routed into{ProjectName}.Content/Assets/; everything else keeps shipping into the head's ownContent/folder as before.UsesShadowDuskShaders/UsesMgcbShadersguarded oncontentMode != ContentBuildMode.ContentBuilder(global), which would have gated all shaders — including KNI/FNA — to "unsupported" the momentContentBuildMode.ContentBuilderwas passed toExport(), even for a non-MonoGame target. Changed the guard to!UsesContentBuilder(target, contentMode)(target-aware) so KNI/FNA stay a true no-op, matching the plan's own required "KNI/FNA no-op" test.GenerateCsproj's raw-copy suppression is conditional, not unconditional. The plan said to unconditionally suppress the<None Include>/<AndroidAsset Include>raw-copy block under Content Builder mode. That would silently drop the.achx/.fnt-style excluded files from the build output entirely (they'd still be zipped into the head'sContent/folder, but never copied to the output dir). Instead the block now stays gated on whether there's any Content-Builder-excluded content left (hasRawContentBuilderAssets), so those files still copy correctly.Verification
dotnet test— 337/337 passing (7 new facts + 5 newTheoryrows for Content Builder mode).dotnet build—XnaFiddle.Core,XnaFiddle.Tests,XnaFiddle.BlazorGLall clean.MonoGame.Tool.Dxcetc. packages): generated a real Content-Builder-mode zip for a classic target (MonoGameDesktopGL) and a next-gen target (MonoGameWindowsDX12),dotnet restore+dotnet buildboth..png) and shader (.fx) both correctly picked up byWildcardRule("*")and compiled to.xnb. Confirms the asset-routing/exclusion logic is correct and there's noMonoGame.Content.Builder.Taskvs. Content Builder target-name collision.Invalid DirectX 12 pixel profile 'ps_3_0'! Requires ps_6_0) — my throwaway test.fxused a legacy SM3 profile, which DX12's real DXC-based compiler correctly rejects. This confirms the DX12 plumbing (packages,Import,WildcardRulerouting) works end-to-end; it's not an exporter bug, just a reminder that a real shipped.fxneeds an SM6-compatible technique to build on DX12.dotnet buildon the whole.slnx(default multi-core parallelism) races — the Content project is both a normal top-level.slnxmember and invoked via a nested<MSBuild Projects="...Content.csproj">insideBuildContent.targets, and the two concurrent builds of the same project collide on the output DLL (CS2012: ... being used by another process). Verified this is not something this PR introduced — MonoGame's own official 3.8.5 GA template (fetched fromMonoGame/MonoGame.Templates) has the exact same structure (byte-for-byte matchingBuildContent.targets/{Name}.Content.csproj, confirmed by direct comparison) and would hit the identical race. Two verified workarounds:dotnet build *.slnx -maxcpucount:1, ordotnet restore *.slnxonce followed bydotnet buildon just the single head.csproj. AProjectReference ReferenceOutputAssembly="false"fix doesn't work as-is (cross-TFM error: head is net8.0, Content project is net9.0 per the reference template). Flagging this for follow-up rather than fixing here, since it's an upstream MonoGame template characteristic, not specific to this PR's logic.Test plan
dotnet test(337/337)dotnet buildacrossXnaFiddle.Core/XnaFiddle.Tests/XnaFiddle.BlazorGLdotnet restore/dotnet buildof a generated Content-Builder-mode export (classic + DX12 targets)🤖 Generated with Claude Code