KhronosGroup / MoltenVK

MoltenVK is a Vulkan Portability implementation. It layers a subset of the high-performance, industry-standard Vulkan graphics and compute API over Apple's Metal graphics framework, enabling Vulkan applications to run on macOS, iOS and tvOS.
Apache License 2.0
4.76k stars 419 forks source link

Texture creation crashing in b56c152a1245 #2168

Closed tycho closed 7 months ago

tycho commented 7 months ago

This is on an Apple M1 system.

Since yesterday's merge at revision b56c152a1245a95e7d4e8d64baca8ae42e85ae6a (Merge pull request #2164 from js6i/native-atomics), texture creation has been crashing in my game. If I build my game with MoltenVK revision 37361ccd5595ff08c050981856903713f96221d2 then the problem goes away.

When running the application directly, I get:

_mtlValidateStrideTextureParameters:1864: failed assertion `Texture Descriptor Validation
Linear texture: cannot be mipmapped, mipmapLevelCount (6) disallowed
'

When running with Xcode (and Metal API validation enabled), the error message changes a bit:

-[MTLDebugBuffer newTextureWithDescriptor:offset:bytesPerRow:]:283: failed assertion `New Texture With Descriptor Validation
linear texture mipmapLevelCount(6) must be 1

The callstack of the crash:

#0  0x00000001843160dc in __pthread_kill ()
#1  0x0000000100ebac50 in pthread_kill ()
#2  0x0000000184259a40 in abort ()
#3  0x0000000184258d30 in __assert_rtn ()
#4  0x000000018e634694 in MTLReportFailure.cold.1 ()
#5  0x000000018e611508 in MTLReportFailure ()
#6  0x000000018e607468 in _MTLMessageContextEnd ()
#7  0x0000000184b9c64c in -[MTLDebugBuffer newTextureWithDescriptor:offset:bytesPerRow:] ()
#8  0x000000010166c28c in -[CaptureMTLBuffer newTextureWithDescriptor:offset:bytesPerRow:] ()
#9  0x00000001029d0c9c in MVKImagePlane::getMTLTexture() at /Users/steven/Development/darwinia/contrib/angle/MoltenVK/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm:57
#10 0x00000001029d6c2c in MVKImage::hasPixelFormatView(unsigned int) [inlined] at /Users/steven/Development/darwinia/contrib/angle/MoltenVK/MoltenVK/MoltenVK/GPUObjects/MVKImage.h:315
#11 0x00000001029d6c20 in MVKImageViewPlane::initSwizzledMTLPixelFormat(VkImageViewCreateInfo const*) at /Users/steven/Development/darwinia/contrib/angle/MoltenVK/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm:1826
#12 0x00000001029d785c in MVKImageViewPlane::MVKImageViewPlane(MVKImageView*, unsigned char, MTLPixelFormat, VkImageViewCreateInfo const*) [inlined] at /Users/steven/Development/darwinia/contrib/angle/MoltenVK/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm:1610
#13 0x00000001029d7838 in MVKImageViewPlane::MVKImageViewPlane(MVKImageView*, unsigned char, MTLPixelFormat, VkImageViewCreateInfo const*) [inlined] at /Users/steven/Development/darwinia/contrib/angle/MoltenVK/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm:1604
#14 0x00000001029d7838 in MVKImageView::MVKImageView(MVKDevice*, VkImageViewCreateInfo const*) at /Users/steven/Development/darwinia/contrib/angle/MoltenVK/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm:2078
#15 0x0000000102a1757c in MVKDevice::createImageView(VkImageViewCreateInfo const*, VkAllocationCallbacks const*) at /Users/steven/Development/darwinia/contrib/angle/MoltenVK/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm:3868
#16 0x00000001029ab518 in vkCreateImageView at /Users/steven/Development/darwinia/contrib/angle/MoltenVK/MoltenVK/MoltenVK/Vulkan/vulkan.mm:964
#17 0x0000000106f77a0c in rx::vk::ImageView::init(VkDevice_T*, VkImageViewCreateInfo const&) [inlined] at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/renderer/vulkan/vk_wrapper.h:1432
#18 0x0000000106f779f4 in rx::vk::ImageHelper::initLayerImageViewImpl(rx::vk::Context*, gl::TextureType, unsigned int, gl::SwizzleState const&, rx::vk::ImageView*, gl::LevelIndexWrapper<unsigned int>, unsigned int, unsigned int, unsigned int, VkFormat, unsigned int, gl::YuvSamplingMode) const at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/renderer/vulkan/vk_helpers.cpp:6241
#19 0x0000000106f82a24 in rx::vk::ImageHelper::initLayerImageView(rx::vk::Context*, gl::TextureType, unsigned int, gl::SwizzleState const&, rx::vk::ImageView*, gl::LevelIndexWrapper<unsigned int>, unsigned int, unsigned int, unsigned int, gl::SrgbWriteControlMode, gl::YuvSamplingMode, unsigned int) const [inlined] at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/renderer/vulkan/vk_helpers.cpp:6165
#20 0x0000000106f829ec in rx::vk::ImageViewHelper::initReadViewsImpl(rx::ContextVk*, gl::TextureType, rx::vk::ImageHelper const&, gl::SwizzleState const&, gl::SwizzleState const&, gl::LevelIndexWrapper<unsigned int>, unsigned int, unsigned int, unsigned int, unsigned int) at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/renderer/vulkan/vk_helpers.cpp:10849
#21 0x0000000106f82834 in rx::vk::ImageViewHelper::initReadViews(rx::ContextVk*, gl::TextureType, rx::vk::ImageHelper const&, gl::SwizzleState const&, gl::SwizzleState const&, gl::LevelIndexWrapper<unsigned int>, unsigned int, unsigned int, unsigned int, bool, unsigned int) at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/renderer/vulkan/vk_helpers.cpp:10806
#22 0x0000000106f30d38 in rx::TextureVk::initImageViews(rx::ContextVk*, unsigned int) at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp:3770
#23 0x0000000106f30898 in rx::TextureVk::initImage(rx::ContextVk*, angle::FormatID, angle::FormatID, rx::ImageMipLevels) at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp:3740
#24 0x0000000106f301c4 in rx::TextureVk::setStorageMultisample(gl::Context const*, gl::TextureType, int, int, gl::Extents const&, bool) at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp:1729
#25 0x0000000107068cd8 in gl::Texture::setStorage(gl::Context*, gl::TextureType, int, unsigned int, gl::Extents const&) at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/Texture.cpp:1761
#26 0x0000000106fef614 in gl::Context::texStorage2D(gl::TextureType, int, unsigned int, int, int) at /Users/steven/Development/darwinia/contrib/angle/angle/src/libANGLE/Context.cpp:6448
#27 0x00000001000f4fd4 in BitmapRGBA::UploadTextureData(Texture::Storage, unsigned int, unsigned int, unsigned int, unsigned char*) [inlined] at /Users/steven/Development/darwinia/code/lib/bitmap.cpp:308

The game uses ANGLE's Vulkan backend with MoltenVK for rendering. It's trying to create a swizzled 256x256 GL_RG8 texture with 6 mip levels.

Here's a demo game build with symbols if that helps: https://www.uplinklabs.net/files/Darwinia-macOS-demo-2.3.2-1108-g98f6e5d4a.zip

cdavis5e commented 7 months ago

It looks like MoltenVK is trying to create a linear texture in anticipation of using image atomics with it, even though on macOS 14 that should no longer be necessary. (Are you on macOS 14?)

I should've taken a look at that change...

tycho commented 7 months ago

Yep, currently on 14.2.1.

Also not sure what leads it to think it needs atomics, that seems like an exceptional situation (e.g. image load/store in shaders?)

cdavis5e commented 7 months ago

If you create an image with format R32_UINT or R32_SINT, and you set VK_IMAGE_USAGE_STORAGE, then MoltenVK will create it as a linear texture, because there's no specific usage bit for image atomics. It's part of a hack that Epic Games implemented in SPIRV-Cross, which I then hooked up to MoltenVK, to use atomics on a buffer passed alongside the image. (This was, of course, pre-macOS-14, before Metal finally got support for texture atomics.) But it's only supposed to do this now prior to macOS 14. And regardless, it's only supposed to do this for images with one mip level and one array layer. Your image has six mip levels, so the condition to create a linear Metal texture shouldn't have been met.

@js6i Tag!

I would've directly assigned this issue to you, but I noticed @billhollings's invitation too late, so I no longer have admin privs here.

tycho commented 7 months ago

Another case of mismatched requirements, as I was trying to debug this issue in my game demo build:

-[_MTLDevice minimumLinearTextureAlignmentForPixelFormat:]:4870: failed assertion `Linear textures do not support depth/stencil pixel formats'

This is a VK_FORMAT_D32_SFLOAT image, but _isLinearForAtomics is true for some reason.

js6i commented 7 months ago

I got used to things being initialised by default, and apparently got "lucky" when testing. Sorry!

tycho commented 7 months ago

Thanks @js6i, that change does seem to be sufficient to fix it for my use cases.

m154k1 commented 7 months ago

@js6i sorry this might be unrelated, but I'm getting this error after #2164:

[MTLTextureDescriptorInternal validateWithDevice:]:1357: failed assertion `Texture Descriptor Validation
MTLPixelFormatR8Unorm is not a valid format to be used with texture atomics.

2169 doesn't help unfortunately.

js6i commented 7 months ago

@js6i sorry this might be unrelated, but I'm getting this error after #2164:

[MTLTextureDescriptorInternal validateWithDevice:]:1357: failed assertion `Texture Descriptor Validation
MTLPixelFormatR8Unorm is not a valid format to be used with texture atomics.

2169 doesn't help unfortunately.

I'm aware of that issue (it't the one I mentioned in the PR) and I'm working on a fix.

m154k1 commented 7 months ago

Ah I see, thanks!

billhollings commented 7 months ago

I would've directly assigned this issue to you, but I noticed @billhollings's invitation too late, so I no longer have admin privs here.

@cdavis5e Invite happily resent! I don't know why we lost you in the first place! 😉

billhollings commented 7 months ago

PR #2169 fixes the initial issue posted above.

The additional texture format Metal validation issue above has been moved to issue #2172.