2021 Developer ToolsGraphics & Games
WWDC21 · 32 min · Developer Tools / Graphics & Games
Optimize high-end games for Apple GPUs
Optimize your high-end games for Apple GPUs: We’ll show you how you can use our rendering and debugging tools to eliminate performance issues and make your games great on Apple platforms. Learn from our experiences working with developers at Larian Studios and 4A Games as we help them optimize their games for Apple GPUs. We’ll explore various techniques for improving your game’s performance, including optimizing shaders, reducing memory bandwidth utilization, and increasing the overlap of your GPU workloads. We’ll also dive into the new GPU Timeline profiling tool in Xcode 13 to identify possible performance bottlenecks in “Divinity: Original Sin 2” when running on iPad. For this session, you should be familiar with the tile-based deferred rendering architecture in Apple GPUs, and have a working knowledge of Xcode and the Metal API. Check out “Discover Metal debugging, profiling, and asset creation tools” or the WWDC20 session “Optimize Metal apps and games with GPU counters” to learn more about using our tools to profile graphics workloads.
Watch at developer.apple.com ↗Code shown on screen · 2 snippets
Pseudocode to choose shared and private buffer count
// Number of frames application is processing
static const uint32_t MAX_FRAMES_IN_FLIGHT = 3;
uint32_t sharedBuffersCount = 0; // Number of buffers with MTLStorageModeShared to create
uint32_t privateBuffersCount = 0; // Number of buffers with MTLStorageModePrivate to create
if (device.hasUnifiedMemory)
{
// Use extra buffer to reduce impact of completion handler
sharedBuffersCount = MAX_FRAMES_IN_FLIGHT + 1;
privateBuffersCount = 0;
}
else // GPUs with dedicated memory
{
sharedBuffersCount = MAX_FRAMES_IN_FLIGHT;
privateBuffersCount = 1;
}
// Create shared buffers MTLStorageModeShared
// If applicable, create private buffer Pseudocode to avoid redundant bindings
void Renderer::SetFragmentTexture(uint32_t index, id<MTLTexture> texture)
{
if (m_FragmentTextures[index] != texture)
{
m_FragmentTextures[index] = texture;
m_FragmentTexturesChanged = true;
}
}
void Renderer::BindFragmentTextures()
{
if (m_FragmentTexturesChanged)
{
[m_RenderCommandEncoder setFragmentTextures:m_FragmentTextures
withRange:NSMakeRange(0, m_LastFragmentTexture + 1)];
m_FragmentTexturesChanged = false;
}
} Resources
Related sessions
-
30 min -
30 min -
40 min -
21 min -
24 min -
33 min