Delve into the world of graphics and game development. Discuss creating stunning visuals, optimizing game mechanics, and share resources for game developers.

All subtopics
Posts under Graphics & Games topic

Post

Replies

Boosts

Views

Activity

How to properly pass a Metal layer from SwiftUI MTKView to C++ for use with metal-cpp?
Hello! I'm currently porting a videogame console emulator to iOS and I'm trying to make the renderer (tested on MacOS) work on iOS as well. The emulator core is written in C++ and uses metal-cpp for rendering, whereas the iOS frontend is written in Swift with SwiftUI. I have an Objective-C++ bridging header for bridging the Swift and C++ sides. On the Swift side, I create an MTKView. Inside the MTKView delegate, I run the emulator for 1 video frame and pass it the view's backing layer for it to render the final output image with. The emulator runs and returns, but when it returns I get a crash in Swift land (callstack attached below), inside objc_release, which indicates I'm doing something wrong with memory management. My bridging interface (ios_driver.h): #pragma once #include <Foundation/Foundation.h> #include <QuartzCore/QuartzCore.h> void iosCreateEmulator(); void iosRunFrame(CAMetalLayer* layer); Bridge implementation (ios_driver.mm): #import <Foundation/Foundation.h> extern "C" { #include "ios_driver.h" } <...> #define IOS_EXPORT extern "C" __attribute__((visibility("default"))) std::unique_ptr<Emulator> emulator = nullptr; IOS_EXPORT void iosCreateEmulator() { ... } // Runs 1 video frame of the emulator and IOS_EXPORT void iosRunFrame(CAMetalLayer* layer) { void* layerBridged = (__bridge void*)layer; // Pass the CAMetalLayer to the emulator emulator->getRenderer()->setMTKLayer(layerBridged); // Runs the emulator for 1 frame and renders the output image using our layer emulator->runFrame(); } My MTKView delegate: class Renderer: NSObject, MTKViewDelegate { var parent: ContentView var device: MTLDevice! init(_ parent: ContentView) { self.parent = parent if let device = MTLCreateSystemDefaultDevice() { self.device = device } super.init() } func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} func draw(in view: MTKView) { var metalLayer = view.layer as! CAMetalLayer // Run the emulator for 1 frame & display the output image iosRunFrame(metalLayer) } } Finally, the emulator's render function that interacts with the layer: void RendererMTL::setMTKLayer(void* layer) { metalLayer = (CA::MetalLayer*)layer; } void RendererMTL::display() { CA::MetalDrawable* drawable = metalLayer->nextDrawable(); if (!drawable) { return; } MTL::Texture* texture = drawable->texture(); <rest of rendering follows here using the drawable & its texture> } This is the Swift callstack at the time of the crash: To my understanding, I shouldn't be violating ARC rules as my bridging header uses CAMetalLayer* instead of void* and Swift will automatically account for ARC when passing CoreFoundation objects to Objective-C. However I don't have any other idea as to what might be causing this. I've been trying to debug this code for a couple of days without much success. If you need more info, the emulator code is also on Github Metal renderer: https://github.com/wheremyfoodat/Panda3DS/blob/ios/src/core/renderer_mtl/renderer_mtl.cpp#L58-L68 Bridge implementation: https://github.com/wheremyfoodat/Panda3DS/blob/ios/src/ios_driver.mm Bridging header: https://github.com/wheremyfoodat/Panda3DS/blob/ios/include/ios_driver.h Any help is more than appreciated. Thank you for your time in advance.
0
0
549
Mar ’25
Error: "CoreImage Metal library does not contain function"
Hey I'm using the CIDepthBlurEffect Core Image Filter in my app. It seems to work ok but I get these errors in the console when calling the class. CoreImage Metal library does not contain function for name: sparserendering_xhlrb_scan CoreImage Metal library does not contain function for name: sparserendering_xhlrb_diffuse CoreImage Metal library does not contain function for name: sparserendering_xhlrb_copy_back CoreImage Metal library does not contain function for name: plain_or_sRGB_copy Am I missing some sort of import to gain these Metal functions? I am using my own custom shaders but I assume you'd be able to use them along side the built in ones.
0
0
507
Dec ’25
MTLCaptureManager.sharedCaptureManager generates corrupted .gputrace files (0KB, invalid internal structure)
Hello, I am experiencing an issue with programmatically capturing a GPU trace using MTLCaptureManager. The .gputrace file that is generated appears to be corrupted, and I'm looking for guidance or a solution. Description of the Problem: I am using MTLCaptureManager.sharedCaptureManager to capture a Metal frame and save it to disk. The generated .gputrace file is consistently reported as 0 bytes in size by the file system. Crucially, when I compress this 0-byte .gputrace file into a .zip archive, the resulting archive contains the full, expected data. After unzipping, the file can be opened and viewed correctly in Xcode. However,When inspecting the file's contents using NSFileManager in Objective-C (treating it as a directory), the internal structure is different from a .gputrace file captured directly from Xcode's Metal Debugger. capture in xcode capture in file Finally,When capturing multiple frames programmatically, the first captured frame contains valid buffer data. However, for subsequent frames (starting from the second frame), the corresponding buffer contents are all zero-filled. Frame 1: All MTLBuffer data is correctly captured and populated. Frame 2 and onward: The same MTLBuffer objects are present in the trace, but their contents are entirely 0 (i.e., the data is not captured or is corrupted). In this case, the on-screen display is normal, but the captured frame is incorrect. The frame captured directly in Xcode is also correct. Only the frame captured to a file is abnormal.
1
0
520
Aug ’25
The App Store purchase button disappears when another window approaches
Since macOS 15.3.2, we have observed that when another window is moved near the App Store's install button, the button disappears. We have attached a related video in the Feedback submission here https://feedbackassistant.apple.com/feedback/20444423 Our application overlays a transparent, watermark-window on top of the system window, which causes the install button in the App Store to be hidden when a user attempts to install an application.Could you advise on how to avoid this issue?
0
0
228
Nov ’25
Regression: RealityKit spatial audio crackles and pops on iOS 26.0 beta 5 (FB19423059)
RealityKit spatial audio crackles and pops on iOS 26.0 beta 5. It works correctly on iOS 18.6 and visionOS 26.0 beta 5. The APIs used are AudioPlaybackController, Entity.prepareAudio, Entity.play Videos of the expected and observed behavior are attached to the feedback FB19423059. The audio should be a consistent, repeating sound, but it seems oddly abbreviated and the volume varies unexpectedly. Thank you for investigating this issue.
0
0
276
Aug ’25
Multiple App Icons
Hi, I have an Unity game. I need to have multiple App Icons for my game for it to be able to be recognized in different countries. In other words, is it possible to have an iOS app in which the App Icon changes based on device locale/language? On Android this is possible using Unity Localization package "com.unity.localization"
0
0
258
Oct ’25
unable to find boardcast extension
Issue Summary: In our Flutter application, we utilize Tencent's TRTC API for voice and video communication. While the broadcast functionality operates correctly on Android, it fails to respond on iOS devices. Attempting to initiate a broadcast results in no action, and long-pressing the broadcast button does not reveal the broadcast extension. Steps to Reproduce: Add Broadcast Upload Extension: In Xcode, navigate to File > New > Target. Select Broadcast Upload Extension and add it to the project. 2. Build the Project: Attempt to build the project. Encounter the error: "Cycle inside Runner; building could produce unreliable results." 3. Resolve Build Cycle Error: Go to the project’s Build Phases. Locate the Embed App Extensions phase. Move Embed App Extensions just below Copy Bundle Resources. Ensure the Copy only when installing option is selected. Rebuild the project; the cycle error is resolved. 4.Test Broadcast Functionality: Install the app on an iOS device. Tap the broadcast button; observe no response. Long-press the broadcast button in the top right hand scroll down menu; the broadcast extension is not listed. 5. Isolate the Issue: Create a new Flutter project. Repeat the above steps to add the broadcast upload extension. The issue persists: broadcast functionality remains unresponsive on iOS.
1
0
571
Feb ’25
Game Center Authentication Crashing - Unity 6, Gamekit 3.0.2
When testing my development build for gamecenter authentication, the game crashes. I've breadcrumbed it to the "await GKLocalPlayer.Authenticate();" call. Can't find any documentation on this issue and have been looking through the forums! I've already done all of the usual stuff like verifying bundle identifiers match, ensuring game center is enabled for the app, setting up app store connect, using a sandbox account, etc... Please point me to some resources if you know any. Any help is appreciated, I'm starting to lose hope here!
2
0
186
Apr ’25
MPSMatrixRandom SEGFAULTs when ran in an async context
The following minimal snippet SEGFAULTS with SDK 26.0 and 26.1. Won't crash if I remove async from the enclosing function signature - but it's impractical in a real project. import Metal import MetalPerformanceShaders let SEED = UInt64(0x0) typealias T = Float16 /* Why ran in async context? Because global GPU object, and async makeMTLFunction, and async makeMTLComputePipelineState. Nevertheless, can trigger the bug without using global @MainActor let myGPU = MyGPU() */ @main struct CMDLine { static func main() async { let ptr = UnsafeMutablePointer<T>.allocate(capacity: 0) async let future: Void = randomFillOnGPU(ptr, count: 0) print("Main thread is playing around") await future print("Successfully reached the end.") } static func randomFillOnGPU(_ buf: UnsafeMutablePointer<T>, count destbufcount: Int) async { // let (device, queue) = await (myGPU.device, myGPU.commandqueue) let myGPU = MyGPU() let (device, queue) = (myGPU.device, myGPU.commandqueue) // Init MTLBuffer, async let makeFunction, makeComputePipelineState, etc. let tempDataType = MPSDataType.uInt32 let randfiller = MPSMatrixRandomMTGP32(device: device, destinationDataType: tempDataType, seed: Int(bitPattern:UInt(SEED))) print("randomFillOnGPU: successfully created MPSMatrixRandom.") // try await computePipelineState // ^ Crashes before this could return // Or in this minimal case, after randomFillOnGPU() returns // make encoder, set pso, dispatch, commit... } } actor MyGPU { let device : MTLDevice let commandqueue : MTLCommandQueue init() { guard let dev: MTLDevice = MPSGetPreferredDevice(.skipRemovable), let cq = dev.makeCommandQueue(), dev.supportsFamily(.apple6) || dev.supportsFamily(.mac2) else { print("Unable to get Metal Device! Exiting"); exit(EX_UNAVAILABLE) } print("Selected device: \(String(format: "%llX", dev.registryID))") self.device = dev self.commandqueue = cq print("myGPU: initialization complete.") } } See FB20916929. Apparently objc autorelease pool is releasing the wrong address during context switch (across suspension points). I wonder why such obvious case has not been caught before.
0
0
119
Nov ’25
Building Game Porting Toolkit on Sequoia
Like many folks here, I've recently attempted to build Apple's Game Porting Toolkit on my machine and ran into compiler errors, but instead of going the usual route of downloading the prebuilt package (kindly provided by GCenX), I decided to see if I could force it to build (since it was obviously buildable at some point). Down below is the list of things I had to do to make it work. Disclaimer: There are several dirty hacks I had to attempt to force the system to do what I needed. Use at your own risk. Don't forget to run all brew commands from a Rosetta prompt: arch -x86_64 zsh Install openssl This one is easy. Just run brew tap rbenv/tap brew install rbenv/tap/openssl@1.1 Install Command Line Tools 15.1 This specific version is required since newer versions come with the linker that is not compatible with the custom compiler (game-porting-toolkit-compiler) that GPTK is using. However, by default 15.1 tools won't install on Sequoia since the installer complains that macOS version is too new. Obviously, Apple has their reasons to not allow this, but all we need is a compiler which should be mostly indifferent to the OS version. To trick the installer, we need to change OS requirement of the installer package. You can do it in four easy steps: Copy Command Line Tools.pkg from the mounted Command_Line_Tools_for_Xcode_15.1.dmg to some other directory. Expand the installer package: pkgutil --expand "Command Line Tools.pkg" CLT You might be prompted to install Command Line Tools when you call pkgutil, just install any version. Go to the newly created CLT folder and edit the Distribution file (it may appear as executable but it's just an xml). You would want to change allowed-os-versions to something greater than 15. Removing this section altogether might also work. When done, re-wrap the package: pkgutil --flatten CLT "Command Line Tools 2.pkg" Congratulations, now you should be able to install 15.1 tools on your OS! If you had to install newer Command Line Tools for pkgutil, delete them before installing 15.1: sudo rm -rf /Library/Developer/CommandLineTools Next step is to make Homebrew accept the outdated 15.1 tools, as by default it'll complain that they're outdated or corrupted. To shut it up, open /usr/local/Homebrew/Library/Homebrew/extend/os/Mac/diagnostic.rb and remove references to check_if_supported_sdk_available from a couple of fatal build check collections. Note - by default, Homebrew will auto-update on any invocation, which will overwrite any changes you've made to its internals. To disable this behavior, before running any brew commands in the terminal, run export HOMEBREW_NO_AUTO_UPDATE=1 After these manipulations, Homebrew might still complain about outdated Command Line Tools, but it won't be a fatal error anymore. Finally, we need to downgrade MinGW to 11.0.1, since the latest version spits out compiler errors when compiling Wine. Unfortunately, Homebrew does a bad job tracking versions of MinGW, so there is no automatic way to do it. Instead, you have to manually download and install old MinGW 11.0.1 formula from the Homebrew git repository. I used the commit from Sep 16, 2023: https://github.com/Homebrew/homebrew-core/blob/b95f4f9491394af667943bd92b081046ba3406f2/Formula/m/mingw-w64.rb Download the file above, save it in your current working directory, and then run brew install ./mingw-w64.rb If you had a newer version of MinGW already installed from the previous build attempts, you can unlink it before installing the one above: brew unlink mingw-w64 With Command Line Tools 15.1 and MinGW 11.0.1 you should now be able to build GPTK without errors: brew -v install apple/apple/game-porting-toolkit In the end, steps above worked for me, although more things could break in the future. I'm leaving the instructions here just to show that it's still possible to build GPTK manually instead of relying on third parties, but with all the hoops I had to jump through I can't really recommend it.
1
0
738
Mar ’25
请问Game Center的数据保存逻辑
我们想在游戏类 App 内接入 Game Center。用户可以在游戏内创建多个角色,若用户在游戏内创建了2个角色:角色1、角色2,请问: 当用户将角色1与 Game Center 绑定后,数据将上报至 Game Center。此时玩家想要将角色1与 Game Center 解除绑定,解绑后,再将角色2与 Game Center 绑定。那么这时角色1的数据是留存在 Game Center 中,还是将被移除?
0
0
302
Oct ’25
Game Center Sandbox: Achievements not unlocking in development build?
Hello Everyone I am new here, I am testing game center integration and using a development build of my IOS game. I have set up a couple of achievements in app store connect, but when I trigger them in the game then they do not unlock or show up. Okay so i am signed into the game center with a sandbox account on a test advice. Is there anything else I need to configure, or do achievements usually only work after the game is released?. I will appreciate any guidance… Thanks in Advance!!!
0
0
181
May ’25
GKObstacleGraph<GKGraphNode2D> copy() not work (Bad ACCESS) (SpriteKit)
Given a graph with added obstacles I want to make a copy of it. When I make the copy: currentGrath added 20 obstacles. var newGrapth = currentGrath.copy() as? GKObstacleGraph newGrapth2.removeObstacles([newGrapth!.obstacles.first!]) This returns a BAD ACCESS. I don't understand what's going on or what the problem is. If I do this same thing with the main network there is no problem: currentGrath.removeObstacles([currentGrath!.obstacles.first!]) Thanks for the help
0
0
465
Feb ’25
authenticateHandler events not being received on iOS 18
I work on a team that provides an SDK for another game to handle various tasks like authentication. They are experiencing a case where devices using iOS 17 are failing to authenticate with GameCenter, receiving the message "The requested operation could not be completed because local player has not been authenticated." We imagine this is because they still have some setup to finish regarding GameCenter itself, and we're working with them to take care of that. However, on iOS 18, their app ends up waiting indefinitely for GameCenter authentication messages that it never receives. That's where we're puzzled. We expect them to have the same outcome regardless of OS version. We initiate GameCenter authentication by setting an authenticateHandler after some initial application setup. The handler has code to account for UI, errors, and successful authentication. On iOS 17, it's clear that it's getting called as expected because they receive an indication that the player isn't authenticated. But on iOS 18, it looks like the same handler code on iOS 18 isn't being called at all. Are there differences in how iOS 18 interacts with the authenticationHandler that we somehow aren't accounting for? Or is there potentially something else that we're doing incorrectly that is manifesting only on iOS 18? Here's a simplified version of our login function code (in Obj-C++). There is no OS-specific code, and the job that owns this function does stay in scope until after authentication is complete. void beginLogin() { // Snip: Check if the user is already logged in. // Snip: Prevent multiple concurrent calls to this function. auto authenticateHandler = ^(UIViewController* gcViewController, NSError* error) { if (gcViewController != nil) { // Snip: Display the UI } else if (error != nil) { // Snip: Handle the error. } else { if ([[GKLocalPlayer localPlayer] isAuthenticated]) { // Snip: Handle successful authentication. } else { // Snip: Handle other case. } } }; [[GKLocalPlayer localPlayer] setAuthenticateHandler: authenticateHandler]; }
2
0
176
May ’25
Metal 4 & Acceleration Structures
I have really enjoyed looking through the code and videos related to Metal 4. Currently, my interest is to update a ReSTIR Project and take advantage of more robust ways to refit acceleration Structures and more powerful ways to access resources. I am working in Swift and have encountered a couple of puzzles: What is the 'accepted' way to create a MTL4BufferRange to store indices and vertices? How do I properly rewrite Swift code to build and compact an Acceleration Structure? I do realize that this is all in Beta and will happily look through Code Samples this Fall. If other guidance is available earlier, that would be fabulous! Thank you
4
0
661
Sep ’25
How to apply the same SystemImage to both mainEmitter and spawnedEmitter without clipping in ParticleEmitterComponent?
Hi everyone, I’m currently learning about ParticleEmitterComponentParticleEmitterComponent and exploring the sample app provided in the Simulating particles in your visionOS app documentation. In the sample app, when I set the EmitterPreset to fireworks from the settings panel on the left side of the window and choose SystemImage, I noticed two issues: The image applied to mainEmitter appears clipped or cropped. The image on spawnedEmitter does not update to the selected SystemImage. What I want to achieve: Apply the same SystemImage to both mainEmittermainEmitter and spawnedEmitterspawnedEmitter so that it displays correctly without clipping. Remove the animation that changes the size of spawnedEmitterspawnedEmitter over time and keep it at a constant size. Could someone explain which properties should be adjusted to achieve this behavior? Any guidance or examples would be greatly appreciated. Thanks in advance!
0
0
474
Sep ’25
iOS Matchmaker ViewController Info Button
I'm updating an existing distributed game to add turn-based matches. When the Matchmaker ViewController Info Button next to a game is pressed, the results vary: iOS 15.x - Button under avatar says "Accept Invite" or "View Game" (depending on if invite has already been accepted) iOS 18.x - Button always says "App Store" - I assume that means it would lead one to the App store to install the game. Both devices (iPad 15.x and iPhone 18.x) have the same version of the game installed. The results are the same when running in the simulator. When the game is released, I assume this button will work properly, no?
0
0
374
Dec ’25