-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Metal Graphics Backend #6385
Metal Graphics Backend #6385
Conversation
Matches OpenGL behavior.
This is needed to differentiate between the open-source Mesa drivers and their binary counterparts for Intel and AMD.
A more-or-less drop-in solution (as far as I know) has just become available: https://www.anandtech.com/show/12465/khronos-group-extends-vulkan-portability-with-opensource. |
It's not often we switch out to draw to the EFB anyway.
Since we use the common pipelines here and draw vertices if a batch is currently being built by the vertex loader, we end up trampling over its pointer, as we share the buffer with the loader, and it has not been unmapped yet. Force a pipeline flush to avoid this.
We would want to improve the granularity here in the future, but for now, this should avoid any performance loss from switching to the VideoCommon shader cache.
As these are stored in a map, operator< will become a hot function when doing lookups, which happen every frame. std::tie generated a rather large function here with quite a few branches.
This enables shaders to be compiled while the game is starting, instead of blocking startup. If a shader is needed before it is compiled, emulation will block.
Line count has grown even further due to now depending on 6 related branches. The actual backend itself is only +5000 lines. I've also switched from generating MSL directly to generating GLSL, then SPIR-V, and using SPIRV-Cross to translate these shaders to MSL. This means that we don't need to significantly modify shadergen, as the changes there were quite intrusive. This means the Metal backend now supports ubershaders, although performance could be terrible, I haven't really benchmarked it. Oh, and you should be able to get framerates above 60fps now. I've implemented psuedo-triple-buffering, it's not ideal, but seems to work fine. |
@microbug I suspect that going via MoltenVK will be slower than this backend, as there is a considerable difference in the API versus Vulkan, which requires translation. But feel free to make a PR integrating MoltenVK and prove me wrong ;) I did try for laughs a while back, and I couldn't get the swap chain functioning. Entirely possible I did something wrong though. Also you won't be able to get a higher frame rate than the screen refresh with MoltenVK. |
@stenzek I'm nowhere near experienced enough to make a PR integrating MoltenVK. Just thought it might be useful, but a (faster) native Metal backend is of course preferable. |
This doesn't mean the resulting binaries will require 10.13 to run, however, it enables us to use the new Metal functions introduced in 10.13.
Works around the cached value in the buildbots of 10.9
Just gave this build a spin. Looks quite stable. Twilight Princess fails to render the mini-map and therefore runs at full speed. Also glitches galore (water overlay effects being opaque, sense mode producing a white screen ). EDIT: Some more testing revealed some performance differences in Twilight Princess regarding the Hyrule Field Slowdowns (Post-Lanayru Spring): OpenGL: 15 VPS Interestingly Metal and Vulkan cap GPU usage at about 70% during those phases, while OpenGL produces close to 100% GPU usage. All four physical CPU cores get about 30% load equally (Hyperthreading doesn't seem to be active, apparently) Setup: 3.1 GHz Haswell i7 and GeForce 750M in a late 2013 iMac running macOS 10.13.6 So, basically yes, MoltenVK is slower than pure Metal (dunno the impact of the graphics not rendering properly). Will test it against Windows, if I get to it. |
When will we see the metal backend get implemented in Dolphin? Or is something like a beta already out? (I have a MakBookPro mid2010 so Wind Waker runs terribly with opengl and I don’t know how to improve the performance and than I heard a Metal backend is in work) |
This pull request has been indefinitely postponed, but stenzek is working on a Vulkan backend for macOS using MoltenVK that should offer much improved performance compared to OpenGL. |
Do you know how long it’s probably going to take until it’s finished? |
@MrGcGamer It's making good progress, you can follow it here: #7039 |
One little question left is my mac supported for moltenvk (geforce 320m)? |
@MrGcGamer After some searching it seems your MacBook doesn't support Metal. Per this article the cutoff for Metal support is the NVIDIA GTX 400 series GPUs. Your GPU is one generation too old. No Metal means no MoltenVK either (because that essentially wraps Vulkan to be run under Metal). So whether a native Metal backend or a MoltenVK backend were to be implemented, either way your computer would not support it. I'm sorry. There's nothing the Dolphin developers can do about it. |
This is probably not the best place to ask, but I am running dolphin on high Sierra (hackintosh) and i have a huge lag even with native resolution and minimum graphics. will the metal graphics backend help fix this ? and I still can't see it when choosing backends on config. |
@moda20 The Metal backend isn’t completed yet, that’s why you can’t select it. Even if you downloaded a build of this pull request, it probably wouldn’t be usable due to bugs. If the Metal backend is completed it will give much improved performance. However this pull request is indefinitely postponed, so I’d be watching this other pull request that’s working to implement a Vulkan backend on macOS using MoltenVK: #7039. It will still be a big performance improvement, but not quite as good as a native Metal backend. In the meantime you could try asynchronous shaders in the ubershader graphics options. But since you’re running a hackintosh anyway, you’re best off using Dolphin on Linux or Windows. That’s the only way you’ll get decent performance anytime soon. |
@stenzek do you have an idea about how much time is PR is gonna by postponed? I try using this PR version with Metal backend, I tested the games Wind Waker and Metroid Prime 2 and I could see a big improvement(really big) in Mac OS X. This work is amazing, I hope you could complete this PR, even after Vulcan for MacOS to improve greatly gameplay in MAC. PD: Are there specifics trainings or documentations that you recommend to understand and use C++ and Metal. To help and create a better dolphin for Mac users. |
MoltenVK is the solution for now. I simply don't have the time to maintain another backend, even if I did complete the missing features. At some point in the future I may resurrect this branch, but for now it's dead. If someone does want to pick it up, there's an untested/rebased version in stenzek/metal. |
Off topic comments not related to testing and feedback will be strictly moderated.
This branch introduces (yet another) backend to Dolphin: Metal. It is largely a work-in-progress, and several features are missing. The main motivation of developing this backend was to ensure the new videocommon interface design provided sufficient capabilities to move the majority of logic currently in the backends to common code.
Thus, the Metal backend has the abstract framebuffer and pipeline branches as prerequisites. All functionality is built using these primitives, avoiding any Metal-specific code where possible, outside of the derived abstract classes themselves.
Rather than mixing Objective C and C++, I used a C++ metal wrapper library (mtlpp). This in my opinion improves code clarity, and also has the benefit of handling object lifetimes, removing the need to sprinkle release and retain calls all over the source.
These two reasons are why the diff line count is huge. The backend itself is only around 5k lines. I'm not expecting anyone to review it just yet, at least not until the prerequisites are merged.
The changes to shadergen are rather intrusive, in some ways the code we were generating did not fit well with the Metal shading language. Perhaps there is a better way to support all the languages, aside from using an external translator.
Also, being a heavier language (C++-based), shader compilation "stutter" is likely worse than OpenGL, ubershaders and UID caches will be the solution here. But these will be implemented in common rather than the backend, so until that happens the backend will not support ubershaders.
Rough TODO list is as follows: