[HN Gopher] Low overhead C++ interface for Apple's Metal API
       ___________________________________________________________________
        
       Low overhead C++ interface for Apple's Metal API
        
       Author : oumua_don17
       Score  : 97 points
       Date   : 2021-11-20 17:01 UTC (2 days ago)
        
 (HTM) web link (developer.apple.com)
 (TXT) w3m dump (developer.apple.com)
        
       | VHRanger wrote:
       | I really think the future here is in MoltenVK becoming the
       | default cross platform GPU API
        
         | adamnemecek wrote:
         | There's also WebGPU. wgpu (https://github.com/gfx-rs/wgpu) is
         | really nice.
        
         | boardwaalk wrote:
         | Vulkan becoming the default cross platform GPU API, while using
         | MoltenVK on Apple operating systems, may be a more accurate way
         | of saying this.
        
         | nice_byte wrote:
         | not likely. the more likely scenario is webGPU becoming one,
         | and i'm mad about it because they couldn't use spir-v for
         | shaders, for legal reasons.
        
         | gjsman-1000 wrote:
         | For everyone mad about Metal, remember:
         | 
         | A. Metal came 2 years before Vulkan.
         | 
         | B. Microsoft does their own proprietary API with DirectX.
         | 
         | C. Metal is a high-level language, Vulkan is low-level. Apple
         | wants you to use a high-level language so they have more
         | flexibility in optimizing the low-level for you now and in the
         | future, which Vulkan closes off more.
         | 
         | D. Metal runs on iOS, iPadOS, and tvOS as well, not just macOS.
         | It's a graphics API for all Apple platforms.
         | 
         | E. Because of D, talent for Metal is much more likely to be
         | found with mobile game developers than AAA studios.
         | 
         | F. Game engines actually support Metal - Unity, Unreal, LWJGL,
         | the most common engines run on Metal fine. Don't use Metal as a
         | scapegoat.
        
           | pjmlp wrote:
           | G. PlayStation doesn't do Vulkan
           | 
           | H. Switch main API is NVN
        
           | jms55 wrote:
           | > C. Metal is a high-level language, Vulkan is low-level.
           | Apple wants you to use a high-level language so they have
           | more flexibility in optimizing the low-level for you now and
           | in the future, which Vulkan closes off more.
           | 
           | The problem is that historically, this is what's lead to tons
           | of issues in games. Drivers make their own "optimizations"
           | resulting in terrible performance for some task on one GPU,
           | and great performance on another. Or instead of performance
           | differences, it's outright bugs.
           | 
           | Then, combine that with GPUs being fairly expensive, and fast
           | moving when it comes to new features. Most game studios
           | aren't going to buy 20 different GPUs and test their entire
           | game on all of them. So games often ship with terrible
           | performance or bugs on various different GPUs. And it's often
           | not the game's fault: are games really supposed to detect
           | your exact GPU model, and change code paths to work around a
           | driver bug? That's crazy.
           | 
           | To combat this, GPU drivers often get updates after a game
           | launch that fix the issues with performance/bugs for specific
           | games at the driver level, when it detects that those games
           | are running. So now drivers become a pile of game-specific
           | hacks, making the problem even worse.
           | 
           | This is the reason Vulkan is so low level. The goal is to
           | make sure drivers don't get horribly bloated, and games
           | aren't working around driver-specific bugs (they still
           | happen, just hopefully less). And when games want to use
           | specific GPU features for extra performance, instead of
           | drivers trying to magically improve normal operations, they
           | can make a vendor-specific extension providing the new
           | functionality that games can opt into when the feature is
           | detected (e.g., raytracing). That's part of why Vulkan has so
           | many more extensions than OpenGL does.
           | 
           | Vulkan may be low level, but it's intended to be so. By
           | foregoing Vulkan support, Apple rejected any attempt at
           | making a higher level API on top of Vulkan that would work on
           | every system. Instead, WebGPU has to try and abstract over
           | Vulkan/Metal/DirectX12 separately, which mostly works, but
           | leads to a whole lot of clunk and longer development time
           | than if Vulkan was the standard everywhere.
           | 
           | That's not to say macOS should never have made Metal. But by
           | not adding Vulkan support in addition later on, they're
           | really hurting cross-platform compatibility. Sure, now Apple
           | can optimize their platform to the best of their ability
           | (theoretically). But that comes at a huge overall cost to the
           | ecosystem, for instance with games having poor support for
           | macOS.
        
             | gjsman-1000 wrote:
             | "But that comes at a huge overall cost to the ecosystem,
             | for instance with games having poor support for macOS."
             | 
             | I don't know if I had this point edited in when you wrote
             | this, but see point F:
             | 
             | "F. Game engines actually support Metal - Unity, Unreal,
             | LWJGL, the most common engines run on Metal fine. Don't use
             | Metal as a scapegoat."
        
               | genocidicbunny wrote:
               | Many game developers don't use any of these engines, and
               | even when using an engine, the underlying graphics API
               | can certainly matter. There's nothing saying that Unreal
               | for example, has to support all the same rendering
               | features in Vk and Dx and Metal. And even the same
               | feature can look subtly different between different
               | interfaces.
        
               | jms55 wrote:
               | A) Many games don't use these engines. The trend has
               | actually been going in the direction of less custom
               | engines, but a significant amount of games still do.
               | 
               | B) Games might not have to deal with macOS if they're
               | using an engine, but the engine themselves still do. This
               | limits what engines can do to the least common
               | denominator. And we all know Apple isn't the fastest when
               | it comes to new standards or features. In the graphics
               | world, that comes in the form of DirectX12 vendor-
               | specific extensions, with Vulkan vendor-specific
               | extensions a few months later, and then Metal support
               | whenever Apple feels like copying it.
               | 
               | Someone else in this thread linked an example about Metal
               | lacking support for a type of atomic primitive that
               | prevented the decoupled loopback algorithm from running
               | on Metal. That means the author couldn't use WebGPU to
               | implement the algorithm, and had to make an
               | implementation in Vulkan and Metal separately (iirc all
               | the details of this correctly, you get the general idea).
               | And it _wasn't_ clear that they couldn't use WebGPU to
               | begin with. The WebGPU spec had to actually be clarified
               | based on the author's investigation. Engines and other
               | APIs wouldn't have to deal with this if Apple just
               | supported Vulkan.
        
               | gjsman-1000 wrote:
               | But then we're back to the various pros and cons of Metal
               | and Vulkan. A counterpoint would be that yes, it lacks
               | the atomic primitive, but Vulkan's low-level design means
               | that games would be less optimized for future devices if
               | their developers stopped supporting them.
               | 
               | An example of this would be how Metal runs on AMD GPUs,
               | Intel iGPUs, and now Apple GPUs. Would a Vulkan-based
               | implementation that was originally written for AMD GPUs
               | be as optimized for Apple GPUs as a Metal implementation
               | would have been? What about 5 years from now?
               | 
               | My point is that there are minute details that are
               | benefits and drawbacks to both, and the decoupled
               | loopback would be one of them. I wouldn't be surprised if
               | there are algorithms Metal can do but Vulkan can't.
        
               | jms55 wrote:
               | My point isn't to talk about the various tradeoffs
               | between Metal and Vulkan. Ignore that Metal exists for
               | now. My point is that by not supporting Vulkan, Apple
               | isn't supporting the lowest common-denominator API that
               | everyone else supports. So that leads to people having to
               | make a Vulkan implementation, and then also a Metal
               | implementation if they want to support macOS. Regardless
               | of the benefits and drawbacks of each, there isn't a way
               | to support every platform with one API. And Apple causes
               | a lot of strife because of that.
               | 
               | I don't have a problem with Windows having DirectX12 in
               | addition to Vulkan. Or even that vendors typically add
               | new features to DirectX12 first, with Vulkan getting them
               | later. This is because you can still write a Vulkan
               | program, and have it run on Windows. Apple only
               | supporting Metal breaks "write once, run on any
               | platform". It's one thing for Apple to have Metal as a
               | better supported/approved API that they can make the best
               | apps with. It's another to lack Vulkan support
               | altogether. Because Apple aren't just trying to get the
               | highest Metal adoption. They could easily do that with
               | AppStore restrictions or something, or just accepting
               | that UIKit using Metal is good enough adoption. Lack of
               | Vulkan has knock on effects on every other platform,
               | because now engines have to do a ton more work, and
               | likely have more bugs.
        
               | gjsman-1000 wrote:
               | This isn't actually accurate because, if you are a game
               | engine, you can't just have a Vulkan-only implementation.
               | There's plenty of old computers that don't support
               | Vulkan. PlayStation doesn't support Vulkan - better use
               | GNM, GNMX, and PSSL. Xbox only uses DirectX, which has
               | both high and low-level variants, no Vulkan there. iOS is
               | Metal only again. You could use Vulkan on the Nintendo
               | Switch, but NVN is faster and the preferred method.
               | 
               | You might get away with just Vulkan if you were targeting
               | only Windows, Linux, and Android on hardware that isn't
               | more than roughly 5-6 years old. But Linux is a small
               | percentage and they've got Proton, so as long as you
               | don't want to port to Android and not iOS for some
               | reason, why not use DirectX?
               | 
               | "lowest common-denominator API that everyone else
               | supports" - Outside of the PC, Vulkan isn't really that
               | broadly-supported. Yes, you've got Android and Nintendo
               | Switch, but those are only individual items in their
               | respective categories and don't make sense to support
               | alone without the rest of their categories (smartphones
               | and consoles).
        
             | gfxgirl wrote:
             | > Then, combine that with GPUs being fairly expensive, and
             | fast moving when it comes to new features. Most game
             | studios aren't going to buy 20 different GPUs and test
             | their entire game on all of them.
             | 
             | This is mostly irrelevant for MacOS/iOS/iPadOS/tvOS. The
             | number of people plugging in an external GPU on Macs is
             | minuscule
             | 
             | > for instance with games having poor support for macOS.
             | 
             | Games don't have poor support on MacOS because of lack of
             | Vulkan. They have poor support because pretty much no Mac
             | (except maybe the newest M1 macs?) have gamer level GPUs
             | and no market for high end games. Gamers basically know if
             | you want to game, get a PC, and game devs know not to waste
             | money on Mac ports.
        
               | dragonwriter wrote:
               | > Games don't have poor support on MacOS because of lack
               | of Vulkan. They have poor support because pretty much no
               | Mac (except maybe the newest M1 macs?) have gamer level
               | GPUs and no market for high end games.
               | 
               | It is basically this:
               | 
               | Gamers don't buy Macs (at least not as their only system,
               | or their primary one for gaming) because there are few
               | games.
               | 
               | Few gamers buying Macs exclusively means there is little
               | unique Mac demand for games (that is, demand that can't
               | be tapped on another platform, because the potential
               | buyer has it and will buy games on it).
               | 
               | Little unique Mac demand for games means few games, and
               | thus the cycle is closed.
               | 
               | Breaking out of that is hard, and Apple would probably
               | need to be the one to expend the effort, and Apple
               | doesn't seem to want to do that.
        
           | criddell wrote:
           | Could it make sense for Metal to be ported to other
           | platforms?
           | 
           | Vulkan has never clicked for me. I can cut and paste code to
           | get something running but I don't really understand it. When
           | you say Metal is high level, that's very appealing to me.
           | 
           | > Metal is a high-level language, Vulkan is low-level.
           | 
           | Wikipedia says Metal is low-level. What do you think accounts
           | for the different description?
        
             | raphlinus wrote:
             | I totally get where you're coming from, Metal is much
             | easier to program than raw Vulkan. I think a Metal-like API
             | over "modern" APIs could be a good thing. There are things
             | like the Vulkan Memory Allocator that help, but among other
             | things that makes integration of different modules harder;
             | this is especially nice on Metal because you can just
             | allocate your own stuff off MTLDevice.
             | 
             | That said, there would be challenges, and big ones, the
             | more you tried to make it actually Metal compatible. You'd
             | need a C++ compiler for the shaders, and certain idioms
             | (pointers, scalar types other than 32 bits) would be
             | difficult to translate portably.
        
             | gjsman-1000 wrote:
             | Probably differing definitions of "low level," levels being
             | relative to what you are talking about. In terms of making
             | a game it's "low level" but it's still a much "higher
             | level" than Vulkan.
             | 
             | An interesting discussion worth reading:
             | 
             | https://developer.apple.com/forums/thread/38469
        
           | babypuncher wrote:
           | > B. Microsoft does their own proprietary API with DirectX.
           | 
           | DX12 may be proprietary and ship only with Windows, but GPU
           | vendors are able to provide OpenGL and Vulkan support through
           | their drivers. As a result, DirectX is an option, not a
           | requirement. Metal is a requirement for 3D acceleration on
           | Apple hardware.
        
           | caslon wrote:
           | "Microsoft does something bad and so anything Apple does that
           | is bad is okay, because Microsoft also does it."
           | 
           | I don't see the logic here.
        
           | [deleted]
        
           | vore wrote:
           | Inarguably though Apple not supporting Vulkan is a huge
           | stumbling block for games on macOS -- even if the common
           | engines support it, a lot of game studios who aren't using
           | something off the shelf aren't likely to support a Mac-only
           | target.
        
           | bogwog wrote:
           | I'm less mad about Metal existing, and more mad about Apple
           | deprecating/abandoning OpenGL. There was no good reason for
           | that, especially for a company with their resources.
        
             | fwsgonzo wrote:
             | I agree. It's the worst decision so far that they've done.
             | OpenGL may not be perfect, but it worked well everywhere.
             | And what about all the thousands of programs that uses
             | OpenGL? Even future programs may use OpenGL - it is not a
             | legacy API.
        
               | dvt wrote:
               | To be fair, I think just about everyone that has done any
               | OpenGL programming absolutely hates it. It uses ancient
               | paradigms that are confusing for neophytes and completely
               | out of sync with modern programming practices. It's also
               | essentially impossible to do multithreaded rendering.
        
               | daniel-thompson wrote:
               | > It's the worst decision so far that they've done.
               | OpenGL may not be perfect, but it worked well everywhere.
               | 
               | I agree with your sentiment. I like OpenGL quite a bit
               | due to its ubiquity. From my perspective as a casual
               | graphics dev, it's relatively easy to use OpenGL to get
               | triangles on the screen, compared to Vulkan (although I
               | know Vulkan has other benefits).
               | 
               | > And what about all the thousands of programs that uses
               | OpenGL?
               | 
               | Judging on past behavior - Apple isn't shy about breaking
               | compatibility with techs they're no longer interested in.
        
               | mrpippy wrote:
               | It may be deprecated, but there's no sign that support
               | will be removed from macOS (since lots of apps and games
               | still use it). If they wanted to, the Apple Silicon
               | transition would have been the time to remove it, but
               | that didn't happen. On Apple Silicon it's enabled by an
               | OpenGL->Metal translation layer.
        
               | Klonoar wrote:
               | Where is this OpenGL->Metal translation layer documented?
               | I've seen numerous mentions of it but no actual docs
               | state it clearly.
               | 
               | I _believe it to be true_ , based on my own checking, but
               | I'd love to have a link to point people to as this has
               | come up a few times.
        
               | babypuncher wrote:
               | I say this as an avid user of Apple hardware; I have no
               | faith that they will really keep it around forever. They
               | have shown very little willingness to maintain backwards
               | compatibility with software for an extended period of
               | time. Many games released for macOS less than a decade
               | ago simply no longer function. Meanwhile, the Windows PC
               | I built just a few years ago still runs software and
               | games from 25 years ago.
               | 
               | This is why I mostly refuse to buy games for my Apple
               | hardware. Until Apple makes some serious commitments (and
               | shows evidence of following through with them), I will
               | not view my MacBook as a viable gaming device. Right now,
               | I'm not even convinced Rosetta 2 will last more than 6 or
               | 7 years.
        
               | raphlinus wrote:
               | Specifically, I suspect one main reason they've kept it
               | as long as they have is for WebGL support in Safari. Now
               | they are investing in Angle[1], so going forward I expect
               | that to be the primary path to WebGL compatibility.
               | 
               | [1]: https://docs.google.com/presentation/d/1ilUE_r5WNGlR
               | hfGx71XH...
        
             | gjsman-1000 wrote:
             | OpenGL is a little weird. Windows, for example, _does not
             | actually support_ OpenGL IIRC. It 's just that Intel, AMD,
             | and NVIDIA started including OpenGL drivers in their
             | graphics drivers even though Microsoft still does not lift
             | a finger to support OpenGL.
             | 
             | [EDIT: Actually, they do, with the OpenGL compatibility
             | pack at https://www.microsoft.com/en-us/p/opencl-and-
             | opengl-compatib.... It's new for Windows 10, and it only
             | supports up to OpenGL 3.3, suspiciously around the same
             | compatibility level as macOS...]
             | 
             | MacOS, well, Apple got into a huge spat with NVIDIA in
             | ~2012. Around the same time, actually, that Apple stopped
             | updating OpenGL (though they wouldn't formally deprecate
             | OpenGL until 2018). Part of me wonders if NVIDIA was
             | writing the OpenGL for Apple, but then OpenGL just got put
             | on the shelf after the spat.
             | 
             | The result though is that neither Windows, nor Apple,
             | supports OpenCL past 1.2 or OpenGL past 3.2/3.3. It's the
             | GPU vendors that have been taking us further.
             | 
             | [EDIT 2: Correction, macOS supports OpenGL 4.1, Windows
             | tops out at 3.3 without GPU drivers if you have DirectX 12]
        
               | emersion wrote:
               | Vulkan and OpenGL are provided by drivers, not by the OS.
               | It's a perfectly normal situation, what else _could_
               | Microsoft do?
               | 
               | > OpenGL compatibility pack
               | 
               | This is using the Mesa Gallium state tracker with a
               | DirectX backend. It's not meant for vendors with a native
               | OpenGL driver.
        
               | gjsman-1000 wrote:
               | Fair enough, but I guess my point is more that,
               | technically speaking, Windows and MacOS are actually
               | identical in their OpenGL and OpenCL support level. The
               | only place this really shows up though in Windows is
               | software rendering - which lacks OpenGL because Windows
               | lacks OpenGL whereas Windows can software-render DirectX
               | AFAIK.
               | 
               | Apple didn't allow AMD though to continue updating OpenGL
               | in their MacOS drivers, possibly because (I'm just
               | speculating) they decided to invent Metal to replace
               | OpenGL around the same time as their NVIDIA spat when
               | they stopped updating OpenGL. Metal came out in 2014, the
               | NVIDIA spat + OpenGL abandonment was 2012. Just my
               | suspicion that MacOS's OpenGL is NVIDIA-based.
        
               | pier25 wrote:
               | Even before 2012, the OpenGL version included in MacOS
               | was always like 4-5 years old.
               | 
               | I don't think Nvidia had anything to do with that.
        
               | gjsman-1000 wrote:
               | MacOS ended on OpenGL 4.1, which was formally spec'd in
               | 2010 but wasn't widely-implemented until 2011 and later
               | (because there's implementation time after the spec is
               | produced).
               | 
               | This means that around 2012, Apple would have been most
               | likely working on OpenGL 4.2 (possibly with NVIDIA, and
               | maybe even with NVIDIA's source code) but that's the year
               | their relationship soured. However, depending on the
               | source you read, there are reports their relationship was
               | souring as early as 2009.
        
               | pier25 wrote:
               | I don't think it's related to that.
               | 
               | It's been many years, but even on Tiger I seem to
               | remember it shipped with an old OpenGL version. I can't
               | find the actual version anywhere though.
               | 
               | Here's a post on Google Groups from 2006 stating that
               | Tiger didn't have full support of 2.0:
               | 
               | https://groups.google.com/g/comp.graphics.api.opengl/c/AX
               | Fx1...
               | 
               | OpenGl 2.0 was released in 2004.
        
             | gfxgirl wrote:
             | There's plenty of reasons for it. For one, OpenGL is
             | arguably a crap API. For another, even with billions of
             | dollars resources are scarce. It's extremely hard to find
             | graphics programmers that want to work on drivers vs work
             | on games etc...
        
           | dhruvdh wrote:
           | Apple has had many years after Vulkan came out to support it
           | alongside Metal or phase out Metal with MoltenVk but we all
           | know that's not going to happen.
        
             | my123 wrote:
             | > phase out Metal
             | 
             | From the GPU compute perspective:
             | 
             | Vulkan has a subset of the features that Metal has.
             | 
             | Metal uses a device programming language that is C++ based,
             | has pointers... and uses AIR (an LLVM IR dialect) as the
             | bytecode.
             | 
             | Vulkan would be a big downgrade in feature levels from
             | that.
             | 
             | While it is very much possible (and done) to have a
             | compliant OpenCL implementation over Metal or D3D12, such a
             | thing isn't possible at all for Vulkan.
        
               | pcwalton wrote:
               | Metal is also a subset of Vulkan. As Raph Levien points
               | out here [1], there are certain important algorithms
               | (decoupled lookback) that can't be implemented _at all_
               | on Metal.
               | 
               | [1]: https://raphlinus.github.io/gpu/2021/11/17/prefix-
               | sum-portab...
        
               | my123 wrote:
               | > One controversial aspect of the original decoupled
               | look-back algorithm is that it depends a forward progress
               | guarantee from the GPU
               | 
               | Apple GPUs aren't very amenable to implementing recursion
               | or giving forward progress guarantees within a SIMD group
               | by design. I'll have to check if a device-wide barrier
               | type even exists on that TBDR...
               | 
               | It isn't like NVIDIA hardware (since Volta) where you
               | have a separate instruction pointer for each (SIMT-but-
               | not-quite) thread.
        
               | my123 wrote:
               | Ok checked more...
               | 
               | With #define _AIR_MEM_SCOPE_DEVICE 0x2 and:
               | 
               | typedef enum __air_mem_flags { mem_flags_global = 0x1,
               | mem_flags_local = 0x2, mem_flags_texture = 0x4 }
               | __air_mem_flags;
               | 
               | and
               | 
               | __attribute__((__no_duplicate__)) void
               | _air_llvm_mem_barrier(__air_mem_flags flags, int scope)
               | __asm("air.mem_barrier");
               | 
               | what does
               | _air_llvm_mem_barrier((__air_mem_flags)mem_flags_global,
               | _AIR_MEM_SCOPE_DEVICE) result in for you?
               | 
               | Some things in that make me go hmmmmm though, will ask
               | Apple for some answers.
        
               | raphlinus wrote:
               | "Subset" is not the right word here. Vulkan has pointers
               | now, but (as was discussed in a recent thread), there are
               | serious limitations compared with "real" C++. At the same
               | time, Metal has its own limitations, not least of which
               | it's lacking acquire/release semantics on atomics and a
               | device-scoped barrier.
               | 
               | OpenCL is a little strange because older variants don't
               | have advanced atomics (or subgroups), but does have
               | pointers. I'd be curious to know what _specific_ thing is
               | not available on DX12 and Metal but missing in Vulkan,
               | especially because I 'm not aware of any DX12 feature on
               | the critical path for OpenCL that's missing from Vulkan
               | (at least as an extension).
        
               | my123 wrote:
               | For OpenCL on DX12, the test suite doesn't pass yet.
               | Every Khronos OpenCL 1.2 CTS test passes on at least one
               | hardware driver, but there's none that pass them all.
               | That is why CLon12 isn't submitted to Khronos's compliant
               | products list yet.
               | 
               | The pointer semantics that Vulkan has aren't very
               | amenable to implementing a compliant OpenCL
               | implementation on top of. There are also some other
               | limitatons: https://github.com/google/clspv/blob/master/d
               | ocs/OpenCLCOnVu....
        
             | giantrobot wrote:
             | > Apple has had many years after Vulkan came out to support
             | it alongside Metal
             | 
             | Why would they do that? By the time Vulcan came out they
             | had _years_ of engineering effort in Metal.
        
             | jjtheblunt wrote:
             | Why would it happen if Metal is meant to support optimal
             | performance on Apple hardware?
             | 
             | I say that bearing in mind we're talking about battery
             | powered hardware, which can not spend any extra cpu cycles
             | on anything, period, without being berated in the press for
             | short battery life compared to some competitor.
        
               | gjsman-1000 wrote:
               | Besides that, remember that if you use Vulkan, you will
               | almost certainly end-up with something that is very
               | optimized for one platform, but won't immediately run
               | well on alternative platforms (see games with their
               | frequent updates for new CPU and GPU architectures).
               | 
               | Apple runs Metal on AMD GPUs, Intel iGPUs, and their own
               | in-house Apple GPUs. If you used Metal, you didn't really
               | have to do much optimization to get close-to-the-best-
               | possible performance on all three of these very-different
               | architectures.
        
       | blovescoffee wrote:
       | Will this help to get pytorch targetting metal?
        
       | posharma wrote:
       | What about binary compatibility?
        
         | pjscott wrote:
         | This library is header-only, and should have the same binary
         | compatibility as using the Objective C framework directly.
        
         | jcelerier wrote:
         | the world is a much better place without it
        
       | jokoon wrote:
       | yeah I guess most devs would rather use C++ than objective c.
        
       | comex wrote:
       | Interesting; I was wondering if they had added some magic feature
       | to Clang to enable Objective-C in pure C++ mode, but no, it
       | really is C++. It just directly calls the Objective-C runtime
       | functions like sel_registerName, objc_lookUpClass, objc_msgSend,
       | etc. The expensive lookups like sel_registerName are performed in
       | initializers of global variables, whereas for 'real' Objective-C
       | code the dynamic linker does essentially the same job itself. I
       | believe this has the disadvantage that unused selectors can't be
       | fully optimized out, as C++ doesn't allow removing global
       | initializers even if the global in question is unused. Therefore,
       | any program that includes this library will, at initialization
       | time, look up all ~1100 selectors defined in the library,
       | regardless of which ones the program actually uses. But besides
       | that, this approach may have equal performance to native
       | Objective-C.
       | 
       | Also - throwing a zip file over the fence, really? Can't you put
       | it on GitHub?
        
         | pcwalton wrote:
         | Interesting. Rust does the same thing with Obj-C selectors,
         | except each selector is looked up lazily at the first call. I
         | wonder why they didn't do that for these bindings.
        
         | waynecochran wrote:
         | Objective-C++ is already supported so this is not a big step to
         | bridge from C++ to Objective-C.
        
         | raphlinus wrote:
         | Along similar lines, from my skim of the README, it also seems
         | like deallocated things are not actually released until the
         | return from the nearest autorelease block, which is not exactly
         | convenient for Rust (and it's not properly safe either without
         | at least an extra retain). I always imagined that when you call
         | through Swift it's a more native memory management interface,
         | but perhaps it's also the same Obj-C layer under the hood.
        
           | ash_gti wrote:
           | The c++ wrappings break ARC, so if you use this library
           | you'll have to manually retain/release any object. The
           | autorelease pool is helpful if you autorelease an object but
           | you'll need to manually manage the memory when using this set
           | of helpers.
           | 
           | In obj-c or swift, ARC would handle that for you, so this
           | makes the memory management aspect of using Metal a bit more
           | of a headache.
        
             | comex wrote:
             | Huh, I'm surprised. I had just assumed without looking that
             | this library provided wrapper classes where the copy
             | constructor calls retain and the destructor calls release.
             | Apparently not.
        
             | raphlinus wrote:
             | Right. Would you happen to know if there's a way to make a
             | retained object actually deallocate on last "release,"
             | other than putting an autorelease pool around it? Would you
             | also happen to know if the Swift bindings have this same
             | wonky autorelease behavior, or more straightforward Swift-
             | style refcounting?
        
               | comex wrote:
               | From a quick grep, it looks like this wrapper does not
               | _automatically_ call autorelease, so autorelease happens
               | only when a method implementation autoreleases its own
               | return value (or if you call autorelease yourself).
               | 
               | Objective-C has a standard rule for when a method is
               | supposed to autorelease its return value: to quote the
               | metal-cpp readme, it's when "you create an object with a
               | method that does not begin with `alloc`, `new`, `copy`,
               | or `mutableCopy`". In many cases, these are convenience
               | methods that also have equivalent "initWith" methods,
               | e.g.                   [NSString stringWithFormat:@"%d",
               | 42]
               | 
               | is equivalent to                   [[[NSString alloc]
               | initWithFormat:@"%d", 42] autorelease]
               | 
               | But I'm not too familiar with Metal, and... it looks like
               | Metal doesn't have very many of these methods in the
               | first place. Instead it has a lot of 'new' methods, which
               | shouldn't use autorelease.
               | 
               | When a method does call autorelease, Swift doesn't have
               | any way of getting around it, though if there are
               | autoreleasing and alloc/init variants of the same method,
               | it will prefer alloc/init. Other than that, Swift likes
               | to use the function objc_retainAutoreleasedReturnValue
               | [1], which may prevent the object from going on the
               | autorelease pool (with the 'optimized return' magic), but
               | only as a non-guaranteed optimization.
               | 
               | [1] https://github.com/apple-
               | opensource/objc4/blob/a367941bce42b...
        
               | raphlinus wrote:
               | Thanks, this is helpful. The specific method that's
               | causing me trouble right at the moment is
               | "computeCommandEncoder"[1], which is a method off
               | MTLCommandBuffer, and I think not in the "new" class. In
               | the Rust bindings[2], this is just a msg_send! and from
               | what I can tell is getting an autoreleased reference, not
               | a retained one.
               | 
               | It looks like objc_retainAutoreleasedReturnValue might be
               | exactly what I'm looking for, even if it isn't 100%
               | guaranteed; if I'm understanding, it would be safe, and
               | wouldn't actually leak as long as you had an autorelease
               | pool somewhere in the chain. However, I'm not seeing a
               | binding to it in the objc crate[3]. Sounds like maybe I
               | should file an issue?
               | 
               | Also, given that such a method seems obviously useful, I
               | wonder why it's not being called from these C++ bindings?
               | 
               | [1]: https://developer.apple.com/documentation/metal/mtlc
               | ommandbu...
               | 
               | [2]: https://github.com/gfx-rs/metal-
               | rs/blob/master/src/commandbu...
               | 
               | [3]: https://docs.rs/objc/0.2.7/objc/runtime/index.html
        
               | ash_gti wrote:
               | If the object is not autoreleased then doing a release
               | call will deallocate the object, otherwise it will be
               | added to the nearest autorelease pool from the current
               | stack and be deallocated when the pool is drained.
               | 
               | Swift and obj-c have the same ARC semantics, so I'm not
               | sure what you mean by swift-style refcounting. It should
               | be identical to the obj-c ARC semantics.
               | 
               | https://clang.llvm.org/docs/AutomaticReferenceCounting.ht
               | ml outlines the ARC semantics, including the autorelease
               | behavior.
        
               | raphlinus wrote:
               | By "swift-style refcounting" I mean the object is
               | reliably deallocated exactly when the last release is
               | called. Following up on the response to comex, I would
               | say I would get these semantics if I called
               | objc_retainAutoreleasedReturnValue on the allocating
               | method's return value, and it actually worked.
        
               | jarpadat wrote:
               | In general, a retained object is deallocated on last
               | release. However ownership of some objects somewhere may
               | have been given to an autoreleasepool, in which case "the
               | last release" for those objects will come from the pool.
               | To what extent this happens is implementation-defined.
               | 
               | Swift and ObjC implementations have levers which
               | discourage objects being sent to the pool in common
               | cases. It is possible to pull them from other languages
               | but not easy.
        
       | nice_byte wrote:
       | github mirror: https://github.com/bkaradzic/metal-cpp
       | 
       | i'm planning to use this to rewrite the metal backend of my rhi
       | abstraction.
        
       | CyberRabbi wrote:
       | Soon: low overhead C++ interface for all of UIKit and Foundation.
        
         | Klonoar wrote:
         | Potentially the smartest way to start phasing out Objective-C.
         | I'd be down, even though I still love ObjC.
        
       ___________________________________________________________________
       (page generated 2021-11-22 23:00 UTC)