-
Notifications
You must be signed in to change notification settings - Fork 81
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 Rendering on macOS #1326
Metal Rendering on macOS #1326
Conversation
I'm also fine with breaking this PR down into smaller chunks where possible. |
|
||
#include "plMetalDevice.h" | ||
#include "plSurface/plShaderTable.h" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This entire thing is the shader program cache that I am very much not in love with. These structures are hashable representations of different pipeline states. This is to prevent lurching as new materials are loaded. If a program suitable for rendering a material was already created, it's just reused.
This also could mean that an initial set of common programs could be precompiled before the age even loads. In practice, there aren't very many.
@autoreleasepool { | ||
NSProcessInfo *processInfo = [NSProcessInfo processInfo]; | ||
NSOperatingSystemVersion version = processInfo.operatingSystemVersion; | ||
NSString *versionString = [NSString stringWithFormat:@"%li.%li.%li", (long)version.majorVersion, (long)version.minorVersion, version.patchVersion]; | ||
devRec.SetDriverVersion([versionString cStringUsingEncoding:NSUTF8StringEncoding]); | ||
} | ||
devRec.SetDriverDesc(device->name()->utf8String()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance we could use hsSystemInfo::GetOperatingSystem()
here (and avoid contaminating our C++ code with Objective C)?
It would give slightly different output ("macOS 11.0" vs "11.0.0") but should still be reasonable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't think that would be an issue. I don't think this string is used for anything critical?
I'm not sure Obj-C++ is the worst thing, but I understand the hesitation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooooof. hsSystemInfo::GetOperatingSystem()
actually uses private API. I'd discourage its use until it can be fixed. That would be a blocker if the iOS App Store was ever a thing (which I know is a longer conversation.) In since there is a working implementation it might be better to stick with that for now. I can also look at rolling GetOperatingSystem() over to public API. That might require some Obj-C++ though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the private APIs, we discussed this a bit when hsSystemInfo
was originally added: #1014 (comment)
/System/Library/CoreServices/SystemVersion.plist exists on both macOS and iOS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NSProcessInfo is the definitive way to do this under "modern" Cocoa. However, I'd still want to do some amount of digging before making a decision. IGetAppleVersion could be moved to Obj-C++.
https://developer.apple.com/documentation/foundation/nsprocessinfo/1410906-operatingsystemversion
Stuff like _kCFSystemVersionProductNameKey is actively being rejected by Apple. Not necessarily the highest priority in since this isn't going through the App Store (right now.) But I also wouldn't want to leave a risk like that lurking in the code for someone else to stumble upon.
fCurrentRenderTargetCommandEncoder = nil; | ||
|
||
//look up the shader by sigma value | ||
MPSImageGaussianBlur *blur = (MPSImageGaussianBlur *)fBlurShaders[sigma]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shame this stuff isn't part of metal-cpp (or even the metal-cpp extensions for Apple's demo projects) 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also a good reminder for me that these shader programs aren't properly lifetime managed with the device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We maybe want to rename the plClient subfolder from OSX
to macOS
since it's not 2014 anymore and they're changed their branding slightly.
There are a few parts of this that might conflict with #1325 or #1201 where the exact same changes have happened in the same files, but those should be easy enough to resolve.
I think we still want to have a discussion around how metal-cpp gets included. I don't think we love the idea of bundling it, so an automatic CMake fetch from a known URL might be the least bad option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some things (mostly minor) that I noticed while looking over the non-graphics bits...
plIMouseXEventMsg* pXMsg = new plIMouseXEventMsg; | ||
plIMouseYEventMsg* pYMsg = new plIMouseYEventMsg; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These could be local variables instead of allocated via new
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We did that in the Windows client, but there might be some threading going on here for macOS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This did used to be threaded on macOS - but I reverted it back to a main thread only model. There were some weird side effects going on. It could move back to a render thread model in the future though. I'll take a look at this chunk though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this. In plMouseDevice these are also being created as pointers, and the function for sending the mouse message expects a pointer.
MACOSX_BUNDLE_BUNDLE_VERSION "0.1" | ||
MACOSX_BUNDLE_SHORT_VERSION_STRING "0.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These (in theory) should match the values we use for the plProduct stuff:
Lines 25 to 32 in 2457af4
set(PRODUCT_BRANCH_ID "1" CACHE STRING "Branch ID") | |
set(PRODUCT_BUILD_ID "918" CACHE STRING "Build ID") | |
set(PRODUCT_BUILD_TYPE "50" CACHE STRING "Build Type") | |
set(PRODUCT_CORE_NAME "UruLive" CACHE STRING "Product Core Name") | |
set(PRODUCT_SHORT_NAME "UruLive" CACHE STRING "Product Short Name") | |
set(PRODUCT_LONG_NAME "Uru Live" CACHE STRING "Product Long Name") | |
set(PRODUCT_UUID "ea489821-6c35-4bd0-9dae-bb17c585e680" | |
CACHE STRING "Product UUID") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MACOSX_BUNDLE_BUNDLE_VERSION should likely be some sort of build version. It's supposed to always increment so I'd have to figure out how to combine the data into a number that always goes up.
For MACOSX_BUNDLE_SHORT_VERSION_STRING - do we have an actual version number thats derived anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/H-uru/Plasma/blob/master/cmake/BuildInfo.cmake is used to embed git information into the executable, but that's not currently available in project mode.
target_link_libraries(plClient PRIVATE "-framework Cocoa") | ||
target_link_libraries(plClient PRIVATE "-framework QuartzCore") | ||
target_link_libraries(plClient PRIVATE "-framework MetalPerformanceShaders") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can probably be specified below with the rest of the target_link_libraries using syntax like $<$<PLATFORM_ID:Darwin>:"-framework Cocoa">
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking into this. I'd like to figure out if there is a Mac specific platform ID so I can make sure Cocoa is only imported on macOS. (Still thinking about a future iOS build.) There probably is, I just need to look it up.
plIMouseXEventMsg* pXMsg = new plIMouseXEventMsg; | ||
plIMouseYEventMsg* pYMsg = new plIMouseYEventMsg; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We did that in the Windows client, but there might be some threading going on here for macOS
698daf0
to
ca7b78b
Compare
Main.mm isn't usually supposed to be this loaded in a Cocoa app. It would probably be good to start factoring things out into Cocoa classes. |
I had the same thought. I'll think through if there are any better options. I'm not entirely sure if Apple's URLs are guaranteed to be stable. |
Renamed the "OSX" directory to "Mac-Cocoa." Very likely if this ever makes it to iPad, I'll end up writing a new client in SwiftUI. "Mac-Cocoa" signifies a Mac Client written in Cocoa/AppKit. This leaves space for an "Apple-SwiftUI" client or something later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
16/172 files viewed
MACOSX_BUNDLE_BUNDLE_VERSION "0.1" | ||
MACOSX_BUNDLE_SHORT_VERSION_STRING "0.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/H-uru/Plasma/blob/master/cmake/BuildInfo.cmake is used to embed git information into the executable, but that's not currently available in project mode.
Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSKeyboardEventMonitor.mm
Outdated
Show resolved
Hide resolved
Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSKeyboardEventMonitor.mm
Outdated
Show resolved
Hide resolved
Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSKeyboardEventMonitor.mm
Outdated
Show resolved
Hide resolved
Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSKeyboardEventMonitor.mm
Outdated
Show resolved
Hide resolved
Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSKeyboardEventMonitor.mm
Outdated
Show resolved
Hide resolved
daef67c
to
b75b85b
Compare
Also a reminder that I'm not sure that the Mac keyboard event code works properly with internationalized keyboards. There's only a keymap for English. I remember a while ago there was discussion about USB HID keyboard ids. Mac is currently using the Mac key codes with its own lookup tables between the Plasma and Mac codes. Apple's Game Controller library also incudes keyboard support meant specifically for games - and it's possible that it would have a cleaner integration path. But that API is only available from macOS 11 onwards. The existing Mac key codes system should probably be sufficient for now. An iPad port would likely implement Game Controller keyboard integration - and might share that implementation with newer versions of macOS. |
I haven't tested the Mac version recently, but the code looks to me like it should work properly regardless of what keyboard layout you're using (as long as it has Latin letters on it). |
b560588
to
060b280
Compare
macOS builds coming out of CI aren't viable right now. Not sure why. They're missing all the embedded libraries. |
Actually - I might be wrong. Does the Github Actions/vcpkg workflow link everything statically? I'm used to seeing dynamic libraries but it might just be that static linking is occurring. |
We try to do static linking with vcpkg to cut down on the number of DLLs that need to be shipped for Windows clients. |
Python might be a bit of a problem. I think we've avoided dealing with it so far. Dynamically linked Python included all of the Python .so files in the app bundle, so they were all signed and trusted. Statically linked Python puts them all in the Python/system folder. This means they're not signed, so the app won't link to them. It's also kind of discouraged to link outside your app bundle, but not impossible. Would it be possible to have the Mac version build against and embed Python.framework? I'm also not sure what the role of Python.pak is and if any executables live in there. |
This also might be of interest, but is outside the vcpkg ecosystem: |
6e7052d
to
3824c52
Compare
a6534a0
to
cebc394
Compare
f3e4d1e
to
4c91c8a
Compare
@dpogue - Guessing that you'd like to see the Metal-cpp headers moved out of tree. I'll start thinking about what to do. In since it's a header library I don't know that it's critical that it should be managed elsewhere. But as third party code it does make reviews messy. |
…venting a delegate message from properly setting Plasma resolution on launch.
…e callback (cherry picked from commit bcb7266f29fc71b136ce9c973fe41aac445ebfec)
57297c1
to
986e8d3
Compare
The render command encoder is create lazily - and clear is not a draw call in Metal. A clear only pass meant no render was being encoded for the command buffer. The render command encoder management could use a bit of cleaning - but for now manually forcing the lazy creation of a command encoder. This could be probably moved to a non-lazy model - but it’s lazy right now because we’re holding for a clear command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Grass.metal is missing the CWE license block
- Metal files still have code style issues, mostly around stray whitespace and brackets needing to be on a new line.
- CMakeLists.txt line 62 spurious whitespace around parens
- CMakeLists.txt FetchContent call - indents are 4 spaces
plMetalDeviceRef.h
292 zero initialization doesn't need to be explicitplMetalMaterialShaderRef::EncodeArguments
std::function
parameters should probably be const references.plMetalPipeline
only base class destructors should be markedvirtual
.- Spurious whitespace in
plMetalPipeline.h
plMetalPlateManager.cpp
52 zero initialization doesn't need to be explicit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7848944
to
6c96be0
Compare
I updated the clang-format file in #1284 so it could be merged first. |
Ok, the .clang-format file is in, now that #1284 is merged. I think that, once the .clang-format files are culled from this PR, I will be 👍 on this. Then, we can start refining stuff in future PRs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If anyone has any concerns about merging this as-is, please say so ASAP. The mac and metal work is not complete, but this, IMO, will serve as a good baseline for continuing work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm 👍 on merging this, and sorting further things out in followup PRs.
I'll also rebase the OpenGL work after this is merged and see if I can consolidate anything.
💥 💥 💥 |
Update:
Welcome back! Now that the Mac client is merged, we're just down to the Metal bits.
There are still some major things missing from this PR that people should be aware of. This will be a milestone - but not quite the endpoint yet for work.
This PR is very much a draft. Getting this out there so people can look and give early feedback. A few known things:
There are probably more things I've forgotten as well. Again - early draft PR.