Open floooh opened 1 month ago
NOTE: on macOS this requires to drop MTKView because WebGPU wants a CAMetalLayer object to setup the swapchain surface, but MTKView doesn't seem to allow access to its internal CAMetalLayer.
...so probably better to move the 'native Dawn support in sokol_app.h' stuff into a separate update after the bindings cleanup.
@floooh Hi! Did you have a chance to start a CAMetalLayer thing yet? Maybe I can help if you could tell me roughly which parts of sokol app we need to adjust?
Not yet, in any case, search for _sapp_macos_view
and _sapp_ios_view
in sokol_app.h these are 'subclasses' of MTKView and this stuff needs to be ripped out.
Also here's a (too simple) example which just uses a fixed-size CAMetalLayer without also managing depth-stencil and msaa-surface.
https://github.com/floooh/sokol-samples/blob/master/glfw/metal-glfw.m
E.g. what's missing is:
I think you can also look at the D3D11 and WebGPU swapchain management code both in sokol_app.h and in the 'raw' D3D11 and WebGPU samples for inspiration because their swapchain management looks quite similar, e.g.:
Argh, I had written a comment here that was for another issue (deleted now), sorry for the confusion :D
PS: I guess to actually drive the frame callback we might also need a DisplayLink object... (which isn't needed in the GLFW example because that just runs the rendering in a loop).
I had tinkered with CVDisplayLink in the abandondend multiwindow branch here:
https://github.com/floooh/sokol/blob/sapp-multiwindow/sokol_app.h
...just search for CVDisplayLink and you'll find all the relevant places.
...or maybe we can continue to just hook into the NSView's drawRect method? Not sure tbh, don't know enough Cocoa for that...
...I think I used this documentation page as reference when I worked on the CVDisplayLink stuff in the multiwindow-branch:
...maybe googling around a bit with the keywords Metal and CADisplayLink or CVDisplayLink also helps, e.g. bringing things like https://www.delasign.com/blog/metal-animations-cadisplaylink/
Hmm, also apparently the macOS specific CVDisplayLink is deprecated, and the common CADisplayLink is now supposed to be also used on macOS, but only since macOS 14 (which is too recent IMHO)... not sure what to do about that, probably best to use CVDisplayLink for a little longer if it is not available before macOS 14...
https://developer.apple.com/documentation/quartzcore/cadisplaylink?language=objc
At times like this I kind of appreciate Win32 API 😅 I'll make some attempts next week, will see if anything works!
Btw, one thing I didn't think of when arguing that WebGPU can't be used together with MTKView.
Since MTKView is a subclass of NSView, maybe we can access the CAMetalLayer needed by WebGPU via the parent class NSView.layer member. But I'm not sure if it's as simple as that, because I think both the MTKView and the WebGPU swapchain code need to call the nextDrawable
method on the CAMetalLayer and that might confuse the view. Worth a try though and would require only little code.
...maybe I get around trying that in a separate branch. Long term I think it's a better idea to get rid of MTKView because it was a constant source of regressions between macOS updates.
@floooh It works! So here is roughly what I have so far: https://github.com/floooh/sokol/pull/1136 In a nutshell, I've tried merge WGPU and Metal backends as much as possible.
Hope it helps a bit!
Just linking this here as reminder in case we run into a similar issue with the new code (see comment at the bottom):
Didn't noticed anything like this yet. Though I had to add manual sync with wgpuQueueOnSubmittedWorkDone
and
while (!IsFrameReady)
{
usleep(1000);
wgpuInstanceProcessEvents ((WGPUInstance) sapp_wgpu_get_instance());
}
Otherwise it would accumulate a multiple frames worth of work before finally blocking and waiting for it to be done. Strangely on Windows it was not necessary.
Hmm, that looks very hacky :D
But now that you say it, I've seen Dawn queuing up to 4 (or was it even 8?) frames. I noticed this when building my own 'buffer conveyor belt' in early sokol-gfx WebGPU backends (that conveyor belt got very long with 4 or 8 buffers in flight).
In the web browser this extreme frame latency doesn't seem to exists...
(this was also on macOS btw, I didn't try to get the native wgpu samples in sokol-samples run anywhere else yet).
...use the new surface functions instead of the deprecated swapchain functions.
See the updated
wgpu_entry_*
code in sokol-samples.PS: while at it, also add 'native' support to the sokol_app.h WebGPU backend so that it is possible to use sokol_app.h with Dawn. It's not much code needed to connect WebGPU to the OS window system, see:
https://github.com/eliemichel/glfw3webgpu/blob/main/glfw3webgpu.c