For my testing, it was always on a brand new launch of the machine after shutting down. I put the CGDirectDisplayCopyCurrentMetalDevice() on a button press, so it was definitely checking after the device was assigned to the CAMetalLayer and had already rendered frames to it.
As for the question about other Metal apps running that would prevent it, this is why I would test on a new launch of the machine in each OS, with no other applications running. And by using the simple "Using Metal to Draw a View's Contents" app on both OS's it was very easy to tell that what was working in Catalina, is not working on Big Sur, since the amount of code is much smaller to check. You can very easily add a menu item or button on screen to check CGDirectDisplayCopyCurrentMetalDevice() and confirm that on Catalina it switches to the Discrete GPU but on Big Sur it does not.
Since I can’t attach files here, I attached to the feedback ticket the demo app where I added a menu item to the main app menu named “Check Display GPU” and it prints out the description of the GPU coming from the main display. On Catalina, after it runs it tells me the display is now being driven by the Discrete GPU. On Big Sur, it still says the Intel. Both fresh launches of the OS on the same machine, no other applications running.
The fact that the display will update to the discrete GPU on Big Sur if I run an app using Open GL (for example the default Chess.app) seems to confirm that there isn't another app running preventing the switching from occurring. You can run my demo on a fresh launch of Big Sur, see that the menu prints out the description of the Intel GPU to console. Then launch the Chess.app and once that is launched, the menu on the demo app will print out the description of the Discrete GPU. Close the Chess.app and then check the menu button again with the demo app, and it prints out the description of the Intel GPU cause it went back. Even though the app is set to use the Discrete GPU using the api and should be keeping the display in that state. Hopefully this can help show what's wrong.
Post
Replies
Boosts
Views
Activity
The problem is that the Mac's display is not switching to the discrete GPU in response to the MTLCreateSystemDefaultDevice() like it used to in Catalina (and how the comments for the method describe).
I have Automatic Graphics Switching enabled in the Battery settings on the Mac and have tested the same build of our app on both Catalina and Big Sur on the same machine. On Catalina, I have verified that the display switched to the discrete GPU in response to the MTLCreateSystemDefaultDevice(). This would be reflected in the Activity Monitor like I mentioned, but I also tested it by requesting the metal device running the display using CGDirectDisplayCopyCurrentMetalDevice() where I pass in the display ID of the display (no external displays connected). On Catalina, it would return the discrete gpu as I expected from it switching, but on Big Sur this method will return the Integrated gpu instead. I put that method on a button press so I could test after command buffers have been committed like you said and there is no change.
I verified the same behavior I describe above by using the small Apple sample app I mentioned as well. That way the problem could be isolated to a much smaller code base.
The FB number for my ticket is FB9029620.
In the case of my Mac, the MTLCreateSystemDefaultDevice() call returns the MTLDevice for my AMD Radeon Pro 560 and the call to MTLCopyAllDevices() returns an array of two devices: the same AMD Radeon Pro 560 and the Intel(R) HD Graphics 630. So yes, it does return the discrete GPU device as one of the devices.