DesktopVK crashes with swapchain null issue on Apple M3
Prerequisites
- [x] I have verified this issue is present in the
developbranch - [x] I have searched open and closed issues to ensure it has not already been reported.
MonoGame Version
MonoGame develop
Which MonoGame platform are you using?
N/A
Operating System
Mac
Description
I am in the process of porting my application from DesktopDX to DesktopVK to support cross-platform builds. I'm running off the latest version of develop and can build MonoGame without issue. My application and its MonoGame content builds successfully, however on runtime I receive an almost immediate crash.
Vulkan instance version: 1.4.323
Selected GPU: Apple M3
Supported Vulkan API version: 1.0.323
VK_EXT_custom_border_color is not supported by this driver!
Swapchain was null before acquiring a frame. This shouldn't happen.
After searching this repo I have a feeling it may be related to #9000, but I'm not familiar enough with the underlying logic to be certain. I've also tried the current WIP fix PR #9044 with no improvement - it still crashes at the same point.
Steps to Reproduce
Debugging the application shows that it crashes when calling _graphics.ApplyChanges().
internal class DemoGame : Game
{
private readonly GraphicsDeviceManager _graphics;
private DemoGame()
{
_graphics = new(this)
{
// GraphicsProfile = GraphicsProfile.HiDef,
// PreferredBackBufferWidth = 1280,
// PreferredBackBufferHeight = 720,
// SynchronizeWithVerticalRetrace = false
};
_graphics.ApplyChanges(); // <---- crashes here
}
}
After commenting out ApplyChanges the application still crashes before the Game.Draw method is called. Update: After further debugging the crash occurs in the call to MGG.GraphicsDevice_BeginFrame
Device is a 2024 MacBook Air (Apple M3) running macOS 15.7.2.
Minimal Example Repo
No response
Expected Behavior
It does not crash.
Resulting Behavior
It does crash.
Files
No response
I added some extra logging to see if I could get information about what is causing the crash, it seems to be a result of this case here:
https://github.com/MonoGame/MonoGame/blob/bc6ed38e5c05d499159b33aa021a1d8ad7ac56ca/native/monogame/vulkan/MGG_Vulkan.cpp#L1605
On my device the surface format that is requested when this method is called (37, VK_FORMAT_R8G8B8A8_UNORM I assume) is not an available surface format. After adding some logic to make it fallback to another format that does exist, the game does boot and render basic 2D graphics. Is this something that needs to be fixed in MonoGame?
There does seem to be an issue preventing shaders / drawing textured 3D geometry from working however:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Microsoft.Xna.Framework.Graphics.TextureCollection.set_Item(Int32 index, Texture value) in /Users/mitch/git/MonoGame/MonoGame.Framework/Graphics/TextureCollection.cs:line 42
at Microsoft.Xna.Framework.Graphics.EffectPass.SetShaderSamplers(Shader shader, TextureCollection textures, SamplerStateCollection samplerStates) in /Users/mitch/git/MonoGame/MonoGame.Framework/Graphics/Effect/EffectPass.cs:line 138
at Microsoft.Xna.Framework.Graphics.EffectPass.Apply() in /Users/mitch/git/MonoGame/MonoGame.Framework/Graphics/Effect/EffectPass.cs:line 111
~and many of my shader parameters aren't available in the effect parameters collection to SetValue on either... this could be my quick & dirty translation from shader versions 4/5 to 6 so will keep investigating that at least, but thought I'd mention in case it hints at a wider underlying issue.~ Update: my shaders were incorrect, the effect parameters work now except the outside bounds issue above still remains.
@mitchwilliamson Can you give a list of the surfFormat.format and surfFormat.colorSpace you get from the loop here:
https://github.com/MonoGame/MonoGame/blob/bc6ed38e5c05d499159b33aa021a1d8ad7ac56ca/native/monogame/vulkan/MGG_Vulkan.cpp#L1592
I wonder what your device is actually returning here.
I wonder what your device is actually returning here.
This is what I get in that loop:
Checking surface format support. Requested format: 37
Available surface formats:
Format: 44, ColorSpace: 0
Format: 50, ColorSpace: 0
Format: 97, ColorSpace: 0
Format: 64, ColorSpace: 0
Format: 58, ColorSpace: 0
Format: 44, ColorSpace: 1000104001
Format: 50, ColorSpace: 1000104001
Format: 97, ColorSpace: 1000104001
Format: 64, ColorSpace: 1000104001
Format: 58, ColorSpace: 1000104001
Format: 44, ColorSpace: 1000104004
Format: 50, ColorSpace: 1000104004
Format: 97, ColorSpace: 1000104004
Format: 64, ColorSpace: 1000104004
Format: 58, ColorSpace: 1000104004
Format: 44, ColorSpace: 1000104006
Format: 50, ColorSpace: 1000104006
Format: 97, ColorSpace: 1000104006
Format: 64, ColorSpace: 1000104006
Format: 58, ColorSpace: 1000104006
Format: 44, ColorSpace: 1000104012
Format: 50, ColorSpace: 1000104012
Format: 97, ColorSpace: 1000104012
Format: 64, ColorSpace: 1000104012
Format: 58, ColorSpace: 1000104012
Format: 44, ColorSpace: 1000104013
Format: 50, ColorSpace: 1000104013
Format: 97, ColorSpace: 1000104013
Format: 64, ColorSpace: 1000104013
Format: 58, ColorSpace: 1000104013
Format: 44, ColorSpace: 1000104002
Format: 50, ColorSpace: 1000104002
Format: 97, ColorSpace: 1000104002
Format: 64, ColorSpace: 1000104002
Format: 58, ColorSpace: 1000104002
Format: 44, ColorSpace: 1000104014
Format: 50, ColorSpace: 1000104014
Format: 97, ColorSpace: 1000104014
Format: 64, ColorSpace: 1000104014
Format: 58, ColorSpace: 1000104014
Format: 44, ColorSpace: 1000104003
Format: 50, ColorSpace: 1000104003
Format: 97, ColorSpace: 1000104003
Format: 64, ColorSpace: 1000104003
Format: 58, ColorSpace: 1000104003
Format: 44, ColorSpace: 1000104007
Format: 50, ColorSpace: 1000104007
Format: 97, ColorSpace: 1000104007
Format: 64, ColorSpace: 1000104007
Format: 58, ColorSpace: 1000104007
Format: 44, ColorSpace: 1000104010
Format: 50, ColorSpace: 1000104010
Format: 97, ColorSpace: 1000104010
Format: 64, ColorSpace: 1000104010
Format: 58, ColorSpace: 1000104010
Format: 44, ColorSpace: 1000104008
Format: 50, ColorSpace: 1000104008
Format: 97, ColorSpace: 1000104008
Format: 64, ColorSpace: 1000104008
Format: 58, ColorSpace: 1000104008
and the code to repro these logs:
printf("Checking surface format support. Requested format: %d\n", vkColor);
printf("Available surface formats:\n");
for (const auto& surfFormat : surfFormats)
{
printf(" Format: %d, ColorSpace: %d\n", surfFormat.format, surfFormat.colorSpace);
if (surfFormat.format == vkColor &&
surfFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{
// The expected format is supported
surface_format = surfFormat.format;
break;
}
}
Here is the table as identifiers:
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_BT709_LINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_BT709_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_BT709_LINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_BT709_LINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_BT709_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_PASS_THROUGH_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_PASS_THROUGH_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_PASS_THROUGH_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_PASS_THROUGH_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_PASS_THROUGH_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_DCI_P3_LINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_DCI_P3_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_DCI_P3_LINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_DCI_P3_LINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_DCI_P3_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_BT709_NONLINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_BT709_NONLINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_BT709_NONLINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_BT709_NONLINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_BT709_NONLINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_HDR10_ST2084_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_HDR10_ST2084_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_HDR10_ST2084_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_HDR10_ST2084_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_HDR10_ST2084_EXT
Format: VK_FORMAT_B8G8R8A8_UNORM, ColorSpace: VK_COLOR_SPACE_BT2020_LINEAR_EXT
Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, ColorSpace: VK_COLOR_SPACE_BT2020_LINEAR_EXT
Format: VK_FORMAT_B8G8R8A8_SRGB, ColorSpace: VK_COLOR_SPACE_BT2020_LINEAR_EXT
Format: VK_FORMAT_D16_UNORM, ColorSpace: VK_COLOR_SPACE_BT2020_LINEAR_EXT
Format: VK_FORMAT_R16G16B16A16_SFLOAT, ColorSpace: VK_COLOR_SPACE_BT2020_LINEAR_EXT
So the colorspace wasn't the issue... it was just that we were looking for VK_FORMAT_R8G8B8A8_UNORM and that wasn't in the list. VK_FORMAT_B8G8R8A8_UNORM should be acceptable for the back buffer as well since you never really call GetData on it.
So maybe this is the right fix... supporting VK_FORMAT_B8G8R8A8_UNORM as well for the backbuffer. I think maybe we need to accept both VK_FORMAT_B8G8R8A8_UNORM and VK_FORMAT_R8G8B8A8_UNORM as Color for the swapchain creation in particular.
From my experience, B8G8R8A8_UNORM is the baseline on Windows, macOS, and iOS. It's guaranteed to be supported.
Android only supports R8G8B8A8_UNORM.
Linux is a mixed bag, most drivers support BGRA, and those who don't are RGBA.
Supporting both of them covers 100% of devices (as far as color targets go).
@mitchwilliamson i pushed a fix in #9044 and once it is merged this should be working for you. If you can test it before then it would be good.
@mitchwilliamson i pushed a fix in #9044 and once it is merged this should be working for you. If you can test it before then it would be good.
Thanks @tomspilman! I've checked out & built the PR and can confirm it does resolve this crash.
The logs are quite noisy (when building in debug mode) and I haven't tested DesktopVK on Windows yet to cross reference what's macOS specific, but thought I'd paste them here as a fyi:
Vulkan instance version: 1.2.296
Validation layers aren't supported (you might want to install the Vulkan SDK to support them).
Selected GPU: Apple M3
Supported Vulkan API version: 1.2.296
VK_EXT_custom_border_color is not supported by this driver!
VK_GOOGLE_hlsl_functionality1 is not supported by this driver!
VK_GOOGLE_user_type is not supported by this driver!
[mvk-error] VK_ERROR_FORMAT_NOT_SUPPORTED: VkFormat VK_FORMAT_D24_UNORM_S8_UINT is not supported on this device. Using VkFormat VK_FORMAT_D32_SFLOAT_S8_UINT instead.
Warning: Potentially unhandled layout transition from 5 to 7 in vulkan/MGG_Vulkan.cpp:2590
Warning: Potentially unhandled layout transition from 5 to 7 in vulkan/MGG_Vulkan.cpp:2590
Warning: Potentially unhandled layout transition from 5 to 7 in vulkan/MGG_Vulkan.cpp:2590
...and the warning repeats every frame