Skip to content

Comments

Apple Silicon macOS port#1230

Closed
Anthony-Gaudino wants to merge 27 commits intoturanszkij:masterfrom
Anthony-Gaudino:apple-silicon-macos-port
Closed

Apple Silicon macOS port#1230
Anthony-Gaudino wants to merge 27 commits intoturanszkij:masterfrom
Anthony-Gaudino:apple-silicon-macos-port

Conversation

@Anthony-Gaudino
Copy link

@Anthony-Gaudino Anthony-Gaudino commented Oct 1, 2025

This is an initial Apple Silicon macOS port.

Application builds, but trying to run the editor fails due to Vulkan issues.

Metal doesn't support Geometry shaders which are used in WickedEngine , these seem to be the shaders:

for f in shaders/spirv/*.cso; do 
  spirv-dis "$f" -o - 2>/dev/null | grep -n "OpCapability Geometry" && echo " -> $f"
done
7:               OpCapability Geometry
 -> shaders/spirv/envMap_skyPS_dynamic.cso
7:               OpCapability Geometry
 -> shaders/spirv/envMap_skyPS_static.cso
7:               OpCapability Geometry
 -> shaders/spirv/envMapPS.cso
6:               OpCapability Geometry
 -> shaders/spirv/objectGS_voxelizer.cso
8:               OpCapability Geometry
 -> shaders/spirv/objectPS_prepass_alphatest.cso
8:               OpCapability Geometry
 -> shaders/spirv/objectPS_prepass.cso
6:               OpCapability Geometry
 -> shaders/spirv/voxelGS.cso

I tried simply ignoring geometry shaders without success, the editor runs without a crash, but it still point to errors, probably because of the unsupported geometry shaders.

There's a PR to implement geometry shaders in MoltenVK, so I also tried implementing it on latest stable forks: forking latest stable MoltenVK and also the necessary SPIRV-Cross

With this I got stuck on this crashing error while what seems to trying to render the first frame using Vulkan:

-[MTLDebugRenderCommandEncoder validateCommonDrawErrors:]:5843: failed assertion `Draw Errors Validation
Vertex Function(main0): missing buffer binding at index 30 for spvDynamicOffsets[0].

I built MoltenVK shared library and placed it on same dir as editor and have been using this command to run it to try to capture debug info:

MTL_DEBUG_LAYER=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation VK_LOADER_DEBUG=all VK_ICD_FILENAMES=./MoltenVK_icd.json DYLD_LIBRARY_PATH=./ ./Editor

I would probably need help to get this done.


Update

The editor runs stable, Sponza, Terrain with weather and the character controller scene works, but some tradeoffs were taken, unsolved bugs exists and some settings are unstable:

  • The terrain works, but it's texturing uses a new path since MoltenVK doesn't support virtual textures. Some thin seams are visible between terrain chunks.

  • There's a very annoying bug where black squares/stripes are visible on faces, the larger the face the higher the change that it happens. These back areas are not being processed trough a fragment shader.

Screenshot 2025-10-19 at 18 11 24
  • Voxel GI, SSGI and DDGI work, but they are not stable and might hang the process emitting errors like:
[Error] [CopyAllocator::submit] vkWaitForFences resulted in VK_TIMEOUT
[Error] [SubmitCommandLists] vkWaitForFences resulted in VK_TIMEOUT, fence statuses:
QUEUE_GRAPHICS = VK_NOT_READY
QUEUE_COMPUTE = VK_NOT_READY
QUEUE_COPY = VK_NOT_READY
QUEUE_VIDEO_DECODE = OK

Or just crash.

  • Voxel GI uses a different path to bypass geometry shaders, it's quite hacky.

  • There's a bug on the gizmo, while trying to move some element using the XY handle then the object coordinates are all set to nan. The same happens with the scale all axis handle.

  • For some reason impostors visualized in a certain angle appear with incorrect colors (pink).

  • Seems like IK and swimming are jittering.

Other issues might be present, I didn't test every single feature.

@turanszkij
Copy link
Owner

Looks pretty good, I skimmed through the changes. I can't test it on Apple, and I don't know what is causing the problems.

This is odd:
-> shaders/spirv/objectPS_prepass.cso
6: OpCapability Geometry

It is a pixel shader which uses SV_PrimitiveID, if the primitiveID is not supported by hardware then we can emulate it with geometry shader, but you said that geometry shader is also not available so I'm not sure what could be done except using mesh shader. Is mesh shader supported?

@Snowapril
Copy link

Hello, I’m also interested in this project and working on porting it to the Metal API.

All M-series Macs support mesh shading, and on A-series devices it’s supported starting from the A14 (with some limitations before Apple9), according to the feature set table (https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf).

Have you considered trying the Metal Shader Converter (https://developer.apple.com/metal/shader-converter/)?
It can convert traditional geometry and tessellation shader stages into object/mesh shader stages relatively easily.

@brakhane
Copy link
Collaborator

brakhane commented Oct 3, 2025

The DirectXShaderCompiler also seems to (now?) support compiling to Metal IR, might be worth taking a look.

@brakhane
Copy link
Collaborator

brakhane commented Oct 3, 2025

This is odd:
-> shaders/spirv/objectPS_prepass.cso
6: OpCapability Geometry

According to the docs DXC declares Geometry capability when PrimitiveId is used as an input in a pixel shader.

@Anthony-Gaudino
Copy link
Author

Anthony-Gaudino commented Oct 3, 2025

Have you considered trying the Metal Shader Converter (https://developer.apple.com/metal/shader-converter/)? It can convert traditional geometry and tessellation shader stages into object/mesh shader stages relatively easily.

No, haven't tried that. Looks promising.

I was able to bypass the missing buffer binding at index 30 for spvDynamicOffsets[0] but then got into GPU page faults. The problem is probably within SPIRV-Cross or MoltenVK. If Metal Shader Converter can convert geometry and tessellation shader stages into object/mesh shaders then it could work.


The DirectXShaderCompiler also seems to (now?) support compiling to Metal IR, might be worth taking a look.

Will investigate this too.

* Disable geometry-shader dependency
* Replace voxel GS with non-GS path
* Gate primitiveID & update offline shader compiler
* Fix Vulkan present/device-lost renderpass mismatch
@Snowapril
Copy link

Snowapril commented Oct 5, 2025

The DirectXShaderCompiler also seems to (now?) support compiling to Metal IR, might be worth taking a look.

I didn’t know that DXC supports Metal IR generation, but it seems to rely on the Metal Shader Converter and is still missing several features (such as compatibility flags, ray tracing pipelines, etc.).
The Metal IR generation pipeline using the Metal Shader Converter is quite straightforward — it involves generating DXIL with DXC and then converting it through the Metal Shader Converter, which is essentially the same process as DXC’s internal Metal generation flow.

Will investigate this too.

@Anthony-Gaudino I see your work now, and it looks like you’re aiming to use MoltenVK to leverage existing Vulkan implementations.
If you decide to use the Metal Shader Converter instead, you’ll need to implement your own native Metal API code.

Clamp requested MSAA sample count to device-supported value and update
TextureDesc to prevent Metal MTLTextureDescriptor sampleCount errors

Fixes this error:
`Texture Descriptor Validation
MTLTextureDescriptor sampleCount (8) is not supported by device.`

While trying to create a terrain.
@Anthony-Gaudino
Copy link
Author

@Anthony-Gaudino I see your work now, and it looks like you’re aiming to use MoltenVK to leverage existing Vulkan implementations. If you decide to use the Metal Shader Converter instead, you’ll need to implement your own native Metal API code.

Yes, I used MoltenVK because I though it would be easier and require less changes.

I looked into the Metal shader converter and for handling Geometry and Tesellation pipelines I would need to use the Metal shader converter companion header. For this I would need to either implement this in MoltenKV or on a Native Metal API as you said.

Another option is to continue on forked MoltenVK path and try to make it work.

And the third option is to use the stable MoltenVK and change existing shaders so that they don't depend on Geometry pipeline or Tesselation; or have separate shaders or code paths for Metal.

I created another branch that follows option 3. In this new branch I was able to run the Editor and basic features work, complex actions, like trying to add a terrain still crash.

Fix cartoon outline sample-count mismatch by
rendering into MSAA target and resolving to a
single-sample texture

- Create an MSAA outline render target and a
  matching single-sample resolved texture when
  MSAA>1
- Resolve MSAA outline into the single-sampled
  texture and feed that into the outline
  postprocess
- Ensure resource creation/cleanup and pipeline
  sample-counts are kept in sync to avoid Metal
  validation errors (MTLTextureDescriptor
  sampleCount mismatch)
- Add logging and guards so pipelines/resources
  recreate correctly when sample count changes
Ensure SDL mouse coordinates are scaled only by
the OS DPI (not the user UI scale) and map deltas
consistently to the canvas logical space in
wiInput.cpp. This resolves cursor/picking offsets
when the Editor UI scaling is changed.
turanszkij added a commit that referenced this pull request Oct 7, 2025
The SV_PrimitiveID is no longer used as PS input, instead two additional index buffers are used for indirection. The "provoke" contains primitiveIDs for every provoking vertex. The "reorder" contains the vertexID remapping from "provoke". On PS5 this removes the need to do additional geometry shader fallback for prepass rendering. It will be also helpful for MacOS port that doesn't support SV_PrimitiveID or geometry shader (PR: #1230 )
@turanszkij
Copy link
Owner

turanszkij commented Oct 7, 2025

I implemented a workaround for SV_PrimitiveID, which will be useful for this pull request, now the prepass object rendering shaders (objectPS_prepass.cso) don't use the SV_PrimitiveID, so the problem will be gone for those.

turanszkij added a commit that referenced this pull request Oct 8, 2025
@turanszkij
Copy link
Owner

The commit above removes SV_RenderTargetArrayIndex from envmap pixel shaders, so they are not marked with Geometry shader capability.

@turanszkij
Copy link
Owner

The objectGS_voxelizer is a proper geometry shader, that will just have to be not used on Apple, but it will be kept for other platforms (it is optional, not required usually, only used for voxel gi)

@Anthony-Gaudino
Copy link
Author

The commit above removes SV_RenderTargetArrayIndex from envmap pixel shaders, so they are not marked with Geometry shader capability.

Thank you! I will merge those changes!

@Anthony-Gaudino
Copy link
Author

HI @turanszkij

Sky PS shaders are still reported as using GS:

for f in shaders/spirv/*.cso; do                                                    
  spirv-dis "$f" -o - 2>/dev/null | grep -n "OpCapability Geometry" && echo " -> $f"
done
7:               OpCapability Geometry
 -> shaders/spirv/envMap_skyPS_dynamic.cso
7:               OpCapability Geometry
 -> shaders/spirv/envMap_skyPS_static.cso
6:               OpCapability Geometry
 -> shaders/spirv/objectGS_voxelizer.cso
6:               OpCapability Geometry
 -> shaders/spirv/voxelGS.cso

@turanszkij
Copy link
Owner

@Anthony-Gaudino You're right, now it should be fixed.

@Anthony-Gaudino
Copy link
Author

@turanszkij,

Currently on macOS, textures are being rendered with greyscale colors.
I would like to confirm with you if Base Color is really supposed to be BC1_UNORM.
Screenshot 2025-10-11 at 21 24 21

@turanszkij
Copy link
Owner

BC1 is correct, it supports RGB colors. You can disable the compression to have regular RGBA format for the material by this checkbox, and also check that saturation slider is at default (1) because that can be used to make colors greyscale if it's at 0.
image

@Anthony-Gaudino
Copy link
Author

BC1 is correct, it supports RGB colors. You can disable the compression to have regular RGBA format for the material by this checkbox, and also check that saturation slider is at default (1) because that can be used to make colors greyscale if it's at 0.

@turanszkij

Have looked into those, but it must be something different.
Would you have any other clue of what could cause this issue?

@turanszkij
Copy link
Owner

You could take a look at that correct swizzle is used for textures (no idea how to look at it on Apple though). By the way if you set just material color that shows up correctly?

@Anthony-Gaudino
Copy link
Author

You could take a look at that correct swizzle is used for textures (no idea how to look at it on Apple though). By the way if you set just material color that shows up correctly?

Yes, it does. If I set the color using the color picker it displays the correct color.

Remove or comment code that is not strictly
necessary for the functionality of the Editor.
Switch shadow atlas accesses to
bindless_textures_float and treat
SampleCmp/SampleLevel results as scalar floats
(accumulate scalars, construct float3 only for
blending). Complements previous commit: "Fix base
color texturing appearing as grayscale".
Force 4-component vertex position format to avoid
unsupported RGB32 texel

Solves crash with:

-[MTLDebugDevice
minimumLinearTextureAlignmentForPixelFormat:]:3064:
failed assertion `MTLPixelFormatInvalid is not
supported on this device.'

When activating `Quantization Disabled` in the
mesh settings or when loading some meshes like the
teapot.
Solves:
-[MTLTextureDescriptorInternal
validateWithDevice:]:1416: failed assertion
`Texture Descriptor Validation
MTLTextureDescriptor sampleCount (8) is not
supported by device.

While trying to add a terrain and loading some
scenes like Sponza.
Compute depth resolve & linearization

Fixes multiple visible issues:
* Clouds visible trough objects
* Lights disappearing after moving the camera
  not very far away
* Lighting artifacts on objects
* Water without transparency
Disable terrain virtual textures when sparse
residency unsupported, allowing to load terrain on
macOS. The terrain appears untextured on
unsupported platforms, but at least it loads
without crashing.
Ensure environment-probe pipeline state objects
are created for sample counts {1,2,4,8}, so a
valid PSO exists if the driver clamps a requested
MSAA (e.g. 8× -> 4× on MoltenVK/Apple Silicon).
This fixes env probes capturing only the sky when
MSAA is enabled and scene geometry was previously
missing.
Add a non-sparse terrain texturing path that
decodes virtual texture data into per-chunk GPU
textures, wiring mip generation and material
binding so Metal/MoltenVK runs no longer show flat
gray terrain. The new fallback also preserves
underwater lighting, making the ocean caustics
visible on terrain surfaces even without sparse
residency support.
Makes Voxel GI functional on Apple builds by
adding a no-geometry-shader fallback and ensuring
the shader permutation system and pipeline state
match that fallback. Changes include defining
WI_DISABLE_VOXELIZATION_GEOMETRY_SHADER for macOS,
guarding VOXELIZATION_GEOMETRY_SHADER_ENABLED in
ShaderInterop_VXGI.h, injecting the platform
define into shader compilation so the correct
shader variants produced.

This solution is not good and not optimal
performance-wise, banding artifacts may occur and
it's not stable, crashes might occur on large
scenes, but at least it provides a functional
fallback for Apple Silicon macOS users until a
better solution is implemented.
@Anthony-Gaudino
Copy link
Author

Hi @turanszkij,

I’ve updated the branch with the latest changes and also updated the PR comment. There are still a few unresolved issues that I haven’t been able to fix, and I won’t be able to continue working on the macOS port for now. Hopefully, the current progress will be useful for anyone who wants to continue from here.

Someone with more graphics programming experience, like @Snowapril, might be able to make good progress on it if interested.

@turanszkij
Copy link
Owner

Thanks, it would be nice if the compile errors were resolved, after that I consider merging it to not lose all progress.

@Snowapril
Copy link

Snowapril commented Nov 9, 2025

@Anthony-Gaudino Thanks for sharing! I'm also interested in getting Wicked Engine running on macOS, so providing fixes for various compile errors with the Apple Clang compiler would be really helpful.

@brakhane brakhane mentioned this pull request Nov 30, 2025
@turanszkij
Copy link
Owner

turanszkij commented Jan 12, 2026

Mac OS support was added here, renderer is using Metal API: 3899e47
I've used some of your work in it:

  • NeonIntrinsicsAppleShim.h
  • libdxcompiler.dylib

Thank you for the work.

@turanszkij turanszkij closed this Jan 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants