What s New in Metal, Part 2

Similar documents
Metal for OpenGL Developers

Working with Metal Overview

From Art to Engine with Model I/O

What s New in Metal. Part 2 #WWDC16. Graphics and Games. Session 605

Working With Metal Advanced

What s New in Core Image

Introducing Metal 2. Graphics and Games #WWDC17. Michal Valient, GPU Software Engineer Richard Schreyer, GPU Software Engineer

Metal for Ray Tracing Acceleration

Metal. GPU-accelerated advanced 3D graphics rendering and data-parallel computation. source rebelsmarket.com

Integrating Apps and Content with AR Quick Look

Introducing the Photos Frameworks

Building Watch Apps #WWDC15. Featured. Session 108. Neil Desai watchos Engineer

Building a Game with SceneKit

The Application Stage. The Game Loop, Resource Management and Renderer Design

Copyright Khronos Group Page 1

Creating Great App Previews

Metal Feature Set Tables

SceneKit: What s New Session 604

Building Visually Rich User Experiences

What s New in SpriteKit

What's New in UIKit Dynamics and Visual Effects Session 229

Mysteries of Auto Layout, Part 1

Adopting Advanced Features of the New UI

Advanced Scrollviews and Touch Handling Techniques

Best practices for effective OpenGL programming. Dan Omachi OpenGL Development Engineer

Using Metal 2 for Compute

Understanding M3G 2.0 and its Effect on Producing Exceptional 3D Java-Based Graphics. Sean Ellis Consultant Graphics Engineer ARM, Maidenhead

Copyright Khronos Group, Page Graphic Remedy. All Rights Reserved

Accessibility on OS X

More frames per second. Alex Kan and Jean-François Roy GPU Software

Streaming Massive Environments From Zero to 200MPH

Image Processing Tricks in OpenGL. Simon Green NVIDIA Corporation

Creating Complications with ClockKit Session 209

NVIDIA Parallel Nsight. Jeff Kiel

PowerVR Hardware. Architecture Overview for Developers

Profiling in Depth. Do you know where your code is? Session 412. Kris Markel Performance Tools Engineer Chad Woolf Performance Tools Engineer

Enhancing Traditional Rasterization Graphics with Ray Tracing. March 2015

What s New in SpriteKit

Designing for Apple Watch

Getting fancy with texture mapping (Part 2) CS559 Spring Apr 2017

Core ML in Depth. System Frameworks #WWDC17. Krishna Sridhar, Core ML Zach Nation, Core ML

Kenneth Dyke Sr. Engineer, Graphics and Compute Architecture

What s New in Xcode App Signing

WatchKit In-Depth, Part 2

Adapting to the New UI of OS X Yosemite

SceneKit in Swift Playgrounds

EECS 487: Interactive Computer Graphics

Octree-Based Sparse Voxelization for Real-Time Global Illumination. Cyril Crassin NVIDIA Research

CSE 167: Introduction to Computer Graphics Lecture #11: Visibility Culling

Leveraging Touch Input on ios

ios Accessibility Developing for everyone Session 201 Ian Fisch ios Accessibility

SECTION 5 IMAGE PROCESSING 2

Introducing On Demand Resources

PowerVR Framework. October 2015

Wed, October 12, 2011

What s New in tvos #WWDC16. App Frameworks. Session 206. Hans Kim tvos Engineer

Networking with NSURLSession

Inside VR on Mobile. Sam Martin Graphics Architect GDC 2016

Storyboards and Controllers on OS X

E6895 Advanced Big Data Analytics Lecture 8: GPU Examples and GPU on ios devices

Rendering. Converting a 3D scene to a 2D image. Camera. Light. Rendering. View Plane

Enabling immersive gaming experiences Intro to Ray Tracing

Enhancing Traditional Rasterization Graphics with Ray Tracing. October 2015

What s New in NSCollectionView Session 225

Voxel Cone Tracing and Sparse Voxel Octree for Real-time Global Illumination. Cyril Crassin NVIDIA Research

Windowing System on a 3D Pipeline. February 2005

Dominic Filion, Senior Engineer Blizzard Entertainment. Rob McNaughton, Lead Technical Artist Blizzard Entertainment

Monetize and Promote Your App with iad

Case 1:17-cv SLR Document 1-3 Filed 01/23/17 Page 1 of 33 PageID #: 60 EXHIBIT C

Mastering Xcode for iphone OS Development Part 1. Todd Fernandez Sr. Manager, IDEs

Mastering UIKit on tvos

GPU Accelerating Speeded-Up Robust Features Timothy B. Terriberry, Lindley M. French, and John Helmsen

Introducing the Contacts Framework

Using and Extending the Xcode Source Editor

Game Graphics & Real-time Rendering

Profiling and Debugging Games on Mobile Platforms

DirectX 11 First Elements

GPU Memory Model Overview

Deus Ex is in the Details

CS8803SC Software and Hardware Cooperative Computing GPGPU. Prof. Hyesoon Kim School of Computer Science Georgia Institute of Technology

What s New in CloudKit

Mastering Drag and Drop

Mastering Xcode for iphone OS Development Part 2. Marc Verstaen Sr. Manager, iphone Tools

CSE 167: Lecture #5: Rasterization. Jürgen P. Schulze, Ph.D. University of California, San Diego Fall Quarter 2012

Advanced Debugging and the Address Sanitizer

How to Work on Next Gen Effects Now: Bridging DX10 and DX9. Guennadi Riguer ATI Technologies

Creating Photo and Video Effects Using Depth

Inter-Process Communication and Synchronization of Processes, Threads and Tasks: Lesson-1: PROCESS

Accessibility on ios. Developing for everyone. Frameworks #WWDC14. Session 210 Clare Kasemset ios Accessibility

Power, Performance, and Diagnostics

CSE 167: Introduction to Computer Graphics Lecture #4: Vertex Transformation

Adding Advanced Shader Features and Handling Fragmentation

IOS PERFORMANCE. Getting the most out of your Games and Apps

Spring 2011 Prof. Hyesoon Kim

Mali Developer Resources. Kevin Ho ARM Taiwan FAE

Adaptive Point Cloud Rendering

CSE 167: Introduction to Computer Graphics Lecture #9: Visibility. Jürgen P. Schulze, Ph.D. University of California, San Diego Fall Quarter 2018

What s New in ARKit 2

Advances in AVFoundation Playback

Hardware Accelerated Volume Visualization. Leonid I. Dimitrov & Milos Sramek GMI Austrian Academy of Sciences

Transcription:

Graphics and Games #WWDC15 What s New in Metal, Part 2 Session 607 Dan Omachi GPU Software Frameworks Engineer Anna Tikhonova GPU Software Frameworks Engineer 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

MetalKit Utility functionality for Metal Apps

MetalKit

MetalKit MetalKit provides efficient implementations for commonly used scenarios Less effort to get up and rendering Increased performance and stability

MetalKit Overview

MetalKit Overview MetalKit View Unified view class for rendering Metal scenes

MetalKit Overview MetalKit View Unified view class for rendering Metal scenes Texture Loader Metal texture object creation from image files

MetalKit Overview MetalKit View Unified view class for rendering Metal scenes Texture Loader Metal texture object creation from image files Model I/O Integration Load and manage mesh data for Metal rendering

MetalKit View Overview Simplest way to get Metal rendering on screen

MetalKit View Overview Simplest way to get Metal rendering on screen Unified between ios and OS X Subclass of UIView for ios Subclass of NSView for OS X

MetalKit View Overview Simplest way to get Metal rendering on screen Unified between ios and OS X Subclass of UIView for ios Subclass of NSView for OS X Manages render targets Creates render pass descriptors

MetalKit View Overview Simplest way to get Metal rendering on screen Unified between ios and OS X Subclass of UIView for ios Subclass of NSView for OS X Manages render targets Creates render pass descriptors Multiple draw loop modes supported Timer, event, or explicitly driven draw loop

MetalKit View Setup Approaches to using MTKView

MetalKit View Setup Approaches to using MTKView A. Implement a delegate - (void)drawinview:(mtkview *)view - (void)view:(mtkview *)view willlayoutwithsize:(cgsize)size

MetalKit View Setup Approaches to using MTKView A. Implement a delegate - (void)drawinview:(mtkview *)view - (void)view:(mtkview *)view willlayoutwithsize:(cgsize)size

MetalKit View Setup Approaches to using MTKView A. Implement a delegate - (void)drawinview:(mtkview *)view - (void)view:(mtkview *)view willlayoutwithsize:(cgsize)size B. Subclass MTKView ios OS X - (void)drawrect:(cgrect)rect - (void)layoutsubviews - (void)drawrect:(cgrect)rect - (void)setframesize:(nssize)newsize

MetalKit View Setup Approaches to using MTKView A. Implement a delegate - (void)drawinview:(mtkview *)view - (void)view:(mtkview *)view willlayoutwithsize:(cgsize)size B. Subclass MTKView ios OS X - (void)drawrect:(cgrect)rect - (void)layoutsubviews - (void)drawrect:(cgrect)rect - (void)setframesize:(nssize)newsize

MetalKit View Setup Approaches to using MTKView A. Implement a delegate - (void)drawinview:(mtkview *)view - (void)view:(mtkview *)view willlayoutwithsize:(cgsize)size B. Subclass MTKView ios OS X - (void)drawrect:(cgrect)rect - (void)layoutsubviews - (void)drawrect:(cgrect)rect - (void)setframesize:(nssize)newsize

MetalKit View Setup Initializing view properties - (void)viewdidload { MTKView *view = (MTKView *)self.view; view.delegate = self; view.device = device; view.colorpixelformat = MTLPixelFormatBGRA8Unorm_sRGB; view.depthstencilpixelformat = MTLPixelFormatDepth32Float_Stencil8; view.samplecount = 4; view.clearcolor = MTLClearColorMake(0.8, 0.8, 0.8, 1.0); }

MetalKit View Setup Initializing view properties - (void)viewdidload { MTKView *view = (MTKView *)self.view; view.delegate = self; view.device = device; view.colorpixelformat = MTLPixelFormatBGRA8Unorm_sRGB; view.depthstencilpixelformat = MTLPixelFormatDepth32Float_Stencil8; view.samplecount = 4; view.clearcolor = MTLClearColorMake(0.8, 0.8, 0.8, 1.0); }

MetalKit View Setup Initializing view properties - (void)viewdidload { MTKView *view = (MTKView *)self.view; view.delegate = self; view.device = device; view.colorpixelformat = MTLPixelFormatBGRA8Unorm_sRGB; view.depthstencilpixelformat = MTLPixelFormatDepth32Float_Stencil8; view.samplecount = 4; view.clearcolor = MTLClearColorMake(0.8, 0.8, 0.8, 1.0); }

MetalKit View Setup Initializing view properties - (void)viewdidload { MTKView *view = (MTKView *)self.view; view.delegate = self; view.device = device; view.colorpixelformat = MTLPixelFormatBGRA8Unorm_sRGB; view.depthstencilpixelformat = MTLPixelFormatDepth32Float_Stencil8; view.samplecount = 4; view.clearcolor = MTLClearColorMake(0.8, 0.8, 0.8, 1.0); }

MetalKit View Setup Initializing view properties - (void)viewdidload { MTKView *view = (MTKView *)self.view; view.delegate = self; view.device = device; view.colorpixelformat = MTLPixelFormatBGRA8Unorm_sRGB; view.depthstencilpixelformat = MTLPixelFormatDepth32Float_Stencil8; view.samplecount = 4; view.clearcolor = MTLClearColorMake(0.8, 0.8, 0.8, 1.0); }

MetalKit View Setup Initializing view properties - (void)viewdidload { MTKView *view = (MTKView *)self.view; view.delegate = self; view.device = device; view.colorpixelformat = MTLPixelFormatBGRA8Unorm_sRGB; view.depthstencilpixelformat = MTLPixelFormatDepth32Float_Stencil8; view.samplecount = 4; view.clearcolor = MTLClearColorMake(0.8, 0.8, 0.8, 1.0); }

MetalKit View Setup Initializing view properties - (void)viewdidload { MTKView *view = (MTKView *)self.view; view.delegate = self; view.device = device; view.colorpixelformat = MTLPixelFormatBGRA8Unorm_sRGB; view.depthstencilpixelformat = MTLPixelFormatDepth32Float_Stencil8; view.samplecount = 4; view.clearcolor = MTLClearColorMake(0.8, 0.8, 0.8, 1.0); }

MetalKit View Drawing Simple usage - (void)drawinview:(nonnull MTKView *)view { id <MTLRenderPassDescriptor> descriptor = view.currentrenderpassdescriptor; // Create render command encoder and encode final pass... } [commandbuffer presentdrawable:view.currentdrawable]; [commandbuffer commit];

MetalKit View Drawing Simple usage - (void)drawinview:(nonnull MTKView *)view { id <MTLRenderPassDescriptor> descriptor = view.currentrenderpassdescriptor; // Create render command encoder and encode final pass... } [commandbuffer presentdrawable:view.currentdrawable]; [commandbuffer commit];

MetalKit View Drawing Simple usage - (void)drawinview:(nonnull MTKView *)view { id <MTLRenderPassDescriptor> descriptor = view.currentrenderpassdescriptor; // Create render command encoder and encode final pass... } [commandbuffer presentdrawable:view.currentdrawable]; [commandbuffer commit];

MetalKit View Drawing Simple usage - (void)drawinview:(nonnull MTKView *)view { id <MTLRenderPassDescriptor> descriptor = view.currentrenderpassdescriptor; // Create render command encoder and encode final pass... } [commandbuffer presentdrawable:view.currentdrawable]; [commandbuffer commit];

Managing Drawables

Managing Drawables Limited pool of drawables

Managing Drawables Limited pool of drawables Drawables concurrently used in many stages of the display pipeline

Managing Drawables Limited pool of drawables Drawables concurrently used in many stages of the display pipeline Frame 1 Application

Managing Drawables Limited pool of drawables Drawables concurrently used in many stages of the display pipeline Frame 1 Frame 2 Application GPU

Managing Drawables Limited pool of drawables Drawables concurrently used in many stages of the display pipeline Frame 1 Frame 2 Frame 3 Application GPU Display

Managing Drawables Limited pool of drawables Drawables concurrently used in many stages of the display pipeline Frame 1 Frame 2 Frame 3 Frame 4 Application GPU Display

Application Frame

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

Application Frame [MTKView currentrenderpassdescriptor] Reserves a drawable Encodes to the drawable [MTLCommandBuffer presentdrawable:] [MTLCommandBuffer commit] Releases the drawable

MetalKit View Drawing Efficient usage - (void)drawinview:(nonnull MTKView *)view { // Update app s render state and encode offscreen passes... id <MTLRenderPassDescriptor> descriptor = view.currentrenderpassdescriptor; // Create render command encoder and encode final pass... } [commandbuffer presentdrawable:view.currentdrawable]; [commandbuffer commit];

MetalKit View Drawing Efficient usage - (void)drawinview:(nonnull MTKView *)view { // Update app s render state and encode offscreen passes... id <MTLRenderPassDescriptor> descriptor = view.currentrenderpassdescriptor; // Create render command encoder and encode final pass... } [commandbuffer presentdrawable:view.currentdrawable]; [commandbuffer commit];

MetalKit View Drawing Efficient usage - (void)drawinview:(nonnull MTKView *)view { // Update app s render state and encode offscreen passes... id <MTLRenderPassDescriptor> descriptor = view.currentrenderpassdescriptor; // Create render command encoder and encode final pass... } [commandbuffer presentdrawable:view.currentdrawable]; [commandbuffer commit];

MetalKit View Drawing Efficient usage - (void)drawinview:(nonnull MTKView *)view { // Update app s render state and encode offscreen passes... id <MTLRenderPassDescriptor> descriptor = view.currentrenderpassdescriptor; // Create render command encoder and encode final pass... [commandbuffer presentdrawable:view.currentdrawable]; [commandbuffer commit]; }

MetalKit Texture Loader

MetalKit Texture Loader Texture loading made simple Give a reference, get a Metal texture

MetalKit Texture Loader Texture loading made simple Give a reference, get a Metal texture Fast and fully featured Asynchronously decodes files and creates textures Support for common image file formats including JPG, TIFF, and PNG Also support for PVR and KTX texture file formats

Texture Loader Basic usage 1. Initialize with Metal device MTKTextureLoader *textureloader = [[MTKTextureLoader alloc] initwithdevice:device]; 2. Load texture [textureloader texturewithcontentsofurl:fileurl options:nil completionhandler:mycompletionhandler];

Texture Loader Basic usage 1. Initialize with Metal device MTKTextureLoader *textureloader = [[MTKTextureLoader alloc] initwithdevice:device]; 2. Load texture [textureloader texturewithcontentsofurl:fileurl options:nil completionhandler:mycompletionhandler];

Texture Loader Basic usage 1. Initialize with Metal device MTKTextureLoader *textureloader = [[MTKTextureLoader alloc] initwithdevice:device]; 2. Load texture [textureloader texturewithcontentsofurl:fileurl options:nil completionhandler:mycompletionhandler];

Texture Loader Basic usage 1. Initialize with Metal device MTKTextureLoader *textureloader = [[MTKTextureLoader alloc] initwithdevice:device]; 2. Load texture [textureloader texturewithcontentsofurl:fileurl fileurl options:nil completionhandler:mycompletionhandler];

Texture Loader Basic usage 1. Initialize with Metal device MTKTextureLoader *textureloader = [[MTKTextureLoader alloc] initwithdevice:device]; 2. Load texture [textureloader texturewithcontentsofurl:fileurl options:nil nil completionhandler:mycompletionhandler];

Texture Loader Basic usage 1. Initialize with Metal device MTKTextureLoader *textureloader = 2. Load texture [[MTKTextureLoader alloc] initwithdevice:device]; [textureloader texturewithcontentsofurl:fileurl options:nil completionhandler:mycompletionhandler]; mycompletionhandler

Model I/O Review Model I/O introduced in ios 9 and OS X El Capitan

Model I/O Review Model I/O introduced in ios 9 and OS X El Capitan 3D Asset loading from various file formats Importers and exporters for proprietary formats possible

Model I/O Review Model I/O introduced in ios 9 and OS X El Capitan 3D Asset loading from various file formats Importers and exporters for proprietary formats possible Offline baking operations Static ambient occlusion Light map generation Voxelization of meshes

Model I/O Review Model I/O introduced in ios 9 and OS X El Capitan 3D Asset loading from various file formats Importers and exporters for proprietary formats possible Offline baking operations Static ambient occlusion Light map generation Voxelization of meshes Allows you to focus on your rendering code

MetalKit and Model I/O Utilities to efficiently use Model I/O with Metal Optimized loading of Model I/O meshes into Metal buffers Encapsulation of mesh data for Metal Functions to prepare mesh data for Metal pipelines

Rendering a Model I/O Asset

Rendering a Model I/O Asset

Rendering a Model I/O Asset Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing

Rendering a Model I/O Asset Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing

Rendering a Model I/O Asset Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing

Rendering a Model I/O Asset Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing

Rendering a Model I/O Asset Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing

Setup for Model Rendering Pipeline setup Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing

Setup for Model Rendering Pipeline setup Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing

Vertex Shader Setting up Per-Vertex Inputs struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; vertex VertexOutput vertexfunction(vertexinput current [[ stage_in ]]) {... }

Vertex Shader Setting up Per-Vertex Inputs struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; vertex VertexOutput vertexfunction(vertexinput current [[ stage_in ]]) {... }

Vertex Shader Setting up Per-Vertex Inputs struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; vertex VertexOutput vertexfunction(vertexinput current [[ stage_in ]]) {... }

Vertex Shader Setting up Per-Vertex Inputs struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; vertex VertexOutput vertexfunction(vertexinput current [[ stage_in ]]) {... }

Vertex Shader Setting up Per-Vertex Inputs struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; vertex VertexOutput vertexfunction(vertexinput current [[ stage_in ]]) {... }

struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; };

struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; };

struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; };

struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; };

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; MTLVertexDescriptor *metalvertexdesc = [MTLVertexDescriptor new];

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[0].format = MTLVertexFormatFloat3; metalvertexdesc.attributes[0].offset = 0;

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[0].format = MTLVertexFormatFloat3; metalvertexdesc.attributes[0].offset = 0; 0 : position Float3

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[1].format = MTLVertexFormatUChar4Normalized; metalvertexdesc.attributes[1].offset = 12; 0 : position Float3

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[1].format = MTLVertexFormatUChar4Normalized; metalvertexdesc.attributes[1].offset = 12; 0 : position Float3 1 : color UChar4

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[1].format = MTLVertexFormatUChar4Normalized; metalvertexdesc.attributes[1].offset = 12; 0 : position Float3 1 : color UChar4

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[1].format = MTLVertexFormatUChar4Normalized; metalvertexdesc.attributes[1].offset = 12; 0 : position Float3 1 : color UChar4 12

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[2].format = MTLVertexFormatHalfFloat2; metalvertexdesc.attributes[2].offset = 16; 0 : position Float3 1 : color UChar4

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[2].format = MTLVertexFormatHalfFloat2; metalvertexdesc.attributes[2].offset = 16; 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[2].format = MTLVertexFormatHalfFloat2; metalvertexdesc.attributes[2].offset = 16; 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.attributes[2].format = MTLVertexFormatHalfFloat2; metalvertexdesc.attributes[2].offset = 16; 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2 16

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.layouts[0].stride = 20; 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2

Vertex Descriptor struct VertexInput { float3 position [[ attribute(0) ]]; float4 color [[ attribute(1) ]]; float2 texuv [[ attribute(2) ]]; }; metalvertexdesc.layouts[0].stride = 20; 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2 20

Vertex Array Layout 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2

Vertex Array Layout 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2

Vertex Array Layout

Vertex Array Layout...

Building the Pipeline renderpipelinedescriptor.vertexdescriptor = metalvertexdesc; MTLRenderStatePipeline *pipeline = [device.newrenderpipelinestatewithdescriptor:renderpipelinedescriptor error:error];

Building the Pipeline renderpipelinedescriptor.vertexdescriptor = metalvertexdesc; MTLRenderStatePipeline *pipeline = [device.newrenderpipelinestatewithdescriptor:renderpipelinedescriptor error:error];

Building the Pipeline renderpipelinedescriptor.vertexdescriptor = metalvertexdesc; MTLRenderStatePipeline *pipeline = [device.newrenderpipelinestatewithdescriptor:renderpipelinedescriptor renderpipelinedescriptor error:error];

Setup for Model Rendering Asset initialization Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing MetalKit Mesh Buffer Allocator

Setup for Model Rendering Asset initialization Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing MetalKit Mesh Buffer Allocator

Setup for Model Rendering Asset initialization Vertex Descriptor Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing MetalKit Mesh Buffer Allocator

Setup for Model Rendering Asset initialization Vertex Descriptor Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing MetalKit Mesh Buffer Allocator

Asset Initialization Model I/O Vertex Descriptor vs. Metal Vertex Descriptor

Asset Initialization Model I/O Vertex Descriptor vs. Metal Vertex Descriptor Model I/O Vertex Descriptor Describes the layout of vertex attributes in a mesh

Asset Initialization Model I/O Vertex Descriptor vs. Metal Vertex Descriptor Model I/O Vertex Descriptor Describes the layout of vertex attributes in a mesh Metal Vertex Descriptor Describes the layout of vertex attribute inputs to a render state pipeline

Asset Initialization Model I/O Vertex Descriptor vs. Metal Vertex Descriptor Model I/O Vertex Descriptor Describes the layout of vertex attributes in a mesh Metal Vertex Descriptor Describes the layout of vertex attribute inputs to a render state pipeline Intentionally designed to look similar Both contain an array of attribute and buffer layout objects Simplifies translation from one type to other

Asset Initialization Defaults and layout efficiency Each attribute in a Model I/O Vertex Descriptor has an identifying string-based name Model I/O assigns a default name if one does not exist in the model file - Names include @ position, @ normal, @ texturecoordinate, and @ color - Model I/O defines these with the string-based MDLVertexAttribute name constants

Asset Initialization Defaults and layout efficiency Each attribute in a Model I/O Vertex Descriptor has an identifying string-based name Model I/O assigns a default name if one does not exist in the model file - Names include @ position, @ normal, @ texturecoordinate, and @ color - Model I/O defines these with the string-based MDLVertexAttribute name constants Custom MDLVertexDescriptor recommended By default, Model I/O loads vertices as high-precision floating point types Feed pipelines with the smallest type that meets your precision requirements Improves vertex bandwidth efficiency

Asset Initialization 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2

Asset Initialization 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2 MDLVertexDescriptor *modeliovertexdesc = MTKModelIOVertexFormatFromMetal(metalVertexDesc); modeliovertexdesc.attributes[0].name = MDLVertexAttributePosition; modeliovertexdesc.attributes[1].name = MDLVertexAttributeColor; modeliovertexdesc.attributes[2].name = MDLVertexAttributeTextureCoordinate;

Asset Initialization 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2 MDLVertexDescriptor *modeliovertexdesc = MTKModelIOVertexFormatFromMetal(metalVertexDesc); modeliovertexdesc.attributes[0].name = MDLVertexAttributePosition; modeliovertexdesc.attributes[1].name = MDLVertexAttributeColor; modeliovertexdesc.attributes[2].name = MDLVertexAttributeTextureCoordinate;

Asset Initialization 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2 MDLVertexDescriptor *modeliovertexdesc = MTKModelIOVertexFormatFromMetal(metalVertexDesc); metalvertexdesc modeliovertexdesc.attributes[0].name = MDLVertexAttributePosition; modeliovertexdesc.attributes[1].name = MDLVertexAttributeColor; modeliovertexdesc.attributes[2].name = MDLVertexAttributeTextureCoordinate;

Asset Initialization 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2 MDLVertexDescriptor *modeliovertexdesc = MTKModelIOVertexFormatFromMetal(metalVertexDesc); modeliovertexdesc.attributes[0].name = MDLVertexAttributePosition; modeliovertexdesc.attributes[1].name = MDLVertexAttributeColor; modeliovertexdesc.attributes[2].name = MDLVertexAttributeTextureCoordinate;

Asset Initialization 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2 MDLVertexDescriptor *modeliovertexdesc = MTKModelIOVertexFormatFromMetal(metalVertexDesc); modeliovertexdesc.attributes[0].name = MDLVertexAttributePosition; modeliovertexdesc.attributes[1].name = MDLVertexAttributeColor; modeliovertexdesc.attributes[2].name = MDLVertexAttributeTextureCoordinate;

Asset Initialization 0 : position Float3 1 : color UChar4 2 : texuv HalfFloat2 MDLVertexDescriptor *modeliovertexdesc = MTKModelIOVertexFormatFromMetal(metalVertexDesc); modeliovertexdesc.attributes[0].name = MDLVertexAttributePosition; modeliovertexdesc.attributes[1].name = MDLVertexAttributeColor; modeliovertexdesc.attributes[2].name = MDLVertexAttributeTextureCoordinate;

Asset Initialization MetalKit Mesh Buffer Allocator MTKMeshBufferAllocator *mtkbufferallocator = [[MTKMeshBufferAllocator alloc] initwithdevice:metaldevice];

Asset Initialization Creating the Asset Object MDLAsset *asset = [[MDLAsset alloc] initwithurl:fileurl vertexdescriptor:modeliovertexdesc bufferallocator:mtkbufferallocator];

Asset Initialization Creating the Asset Object MDLAsset *asset = [[MDLAsset alloc] initwithurl:fileurl vertexdescriptor:modeliovertexdesc bufferallocator:mtkbufferallocator];

Asset Initialization Creating the Asset Object MDLAsset *asset = [[MDLAsset alloc] initwithurl:fileurl vertexdescriptor:modeliovertexdesc bufferallocator:mtkbufferallocator];

Asset Initialization Creating the Asset Object MDLAsset *asset = [[MDLAsset alloc] initwithurl:fileurl vertexdescriptor:modeliovertexdesc bufferallocator:mtkbufferallocator];

MetalKit Meshes Initialization Setup for model rendering Vertex Descriptor Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing MetalKit Mesh Buffer Allocator

MetalKit Meshes Initialization Setup for model rendering Vertex Descriptor Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing MetalKit Mesh Buffer Allocator

Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh

Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh

Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh

Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh

NSArray<MTKMesh *> *meshes = [MTKMesh meshesfromasset:asset device:device]; Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh

NSArray<MTKMesh *> *meshes = [MTKMesh meshesfromasset:asset device:device]; Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh

NSArray<MTKMesh *> *meshes = [MTKMesh meshesfromasset:asset device:device]; Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh

NSArray<MTKMesh *> *meshes = [MTKMesh meshesfromasset:asset device:device]; Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh meshes Mesh Mesh Mesh Mesh Mesh

NSArray<MTKMesh *> *meshes = [MTKMesh meshesfromasset:asset device:device]; Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh meshes Mesh Mesh Mesh Mesh Mesh

NSArray<MTKMesh *> *meshes = [MTKMesh meshesfromasset:asset device:device]; Asset Camera Mesh Mesh Light Mesh Camera Mesh Light Mesh meshes Mesh Mesh Mesh Mesh Mesh

NSArray<MTKMesh *> *meshes = [MTKMesh meshesfromasset:asset device:device]; Asset Camera Mesh Mesh Mesh Light Mesh Camera Mesh Light Mesh meshes Mesh Mesh Mesh Mesh

Mesh

Mesh VertexBuffers

VertexBuffers Mesh VertexDescriptor

VertexBuffers Mesh VertexDescriptor

VertexBuffers Mesh VertexDescriptor Submesh

VertexBuffers Mesh VertexDescriptor IndexBuffer Submesh

VertexBuffers Mesh VertexDescriptor IndexBuffer Submesh

VertexBuffers Mesh VertexDescriptor IndexBuffer Submesh Draw Properties

VertexBuffers Mesh VertexDescriptor IndexBuffer Submesh Draw Properties

Mesh Rendering with Metal Setup for model rendering Vertex Descriptor Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing MetalKit Mesh Buffer Allocator

Mesh Rendering with Metal Setup for model rendering Vertex Descriptor Vertex Descriptor Metal Render State Pipeline Model I/O Asset Initialization MetalKit Mesh and Submesh Objects Metal Render State Setup and Drawing MetalKit Mesh Buffer Allocator

Setting Mesh State NSUInteger bufferindex = 0; for(mtkmeshbuffer *vertexbuffer in mesh.vertexbuffers) { if(vertexbuffer.buffer!= nil) { [renderencoder setvertexbuffer:vertexbuffer.buffer offset:vertexbuffer.offset atindex:bufferindex]; } bufferindex++; }

Setting Mesh State NSUInteger bufferindex = 0; for(mtkmeshbuffer *vertexbuffer in mesh.vertexbuffers) { if(vertexbuffer.buffer!= nil) { [renderencoder setvertexbuffer:vertexbuffer.buffer offset:vertexbuffer.offset atindex:bufferindex]; } bufferindex++; }

Setting Mesh State NSUInteger bufferindex = 0; for(mtkmeshbuffer *vertexbuffer in mesh.vertexbuffers) { if(vertexbuffer.buffer!= nil) { [renderencoder setvertexbuffer:vertexbuffer.buffer offset:vertexbuffer.offset atindex:bufferindex]; } bufferindex++; }

Setting Mesh State NSUInteger bufferindex = 0; for(mtkmeshbuffer *vertexbuffer in mesh.vertexbuffers) { if(vertexbuffer.buffer!= nil) { [renderencoder setvertexbuffer:vertexbuffer.buffer offset:vertexbuffer.offset atindex:bufferindex]; } bufferindex++; }

Setting Mesh State NSUInteger bufferindex = 0; for(mtkmeshbuffer *vertexbuffer in mesh.vertexbuffers) { if(vertexbuffer.buffer!= nil) { [renderencoder setvertexbuffer:vertexbuffer.buffer offset:vertexbuffer.offset atindex:bufferindex]; } bufferindex++; }

Setting Mesh State NSUInteger bufferindex = 0; for(mtkmeshbuffer *vertexbuffer in mesh.vertexbuffers) { if(vertexbuffer.buffer!= nil) { [renderencoder setvertexbuffer:vertexbuffer.buffer offset:vertexbuffer.offset atindex:bufferindex]; } bufferindex++; }

Rendering the Mesh for(mtksubmesh *submesh in mesh.submeshes) { [renderencoder drawindexedprimitives:submesh.primitivetype indexcount:submesh.indexcount indextype:submesh.indextype indexbuffer:submesh.indexbuffer.buffer indexbufferoffset:submesh.indexbuffer.offset]; }

Rendering the Mesh for(mtksubmesh *submesh in mesh.submeshes) { [renderencoder drawindexedprimitives:submesh.primitivetype indexcount:submesh.indexcount indextype:submesh.indextype indexbuffer:submesh.indexbuffer.buffer indexbufferoffset:submesh.indexbuffer.offset]; }

Rendering the Mesh for(mtksubmesh *submesh in mesh.submeshes) { [renderencoder drawindexedprimitives:submesh.primitivetype indexcount:submesh.indexcount indextype:submesh.indextype indexbuffer:submesh.indexbuffer.buffer indexbufferoffset:submesh.indexbuffer.offset]; }

Rendering the Mesh for(mtksubmesh *submesh in mesh.submeshes) { [renderencoder drawindexedprimitives:submesh.primitivetype submesh indexcount:submesh.indexcount indextype:submesh.indextype indexbuffer:submesh.indexbuffer.buffer indexbufferoffset:submesh.indexbuffer.offset]; submesh }

MetalKit Essentials

Metal Performance Shaders Anna Tikhonova GPU Software Frameworks Engineer

Metal Performance Shaders Introduction A framework of data-parallel algorithms for the GPU CPU-style library for the GPU

Metal Performance Shaders Introduction Optimized for ios Available in ios 9 for the A8 processor ipad Air 2 iphone 6 Plus iphone 6

Metal Performance Shaders Introduction Designed to integrate easily into your Metal applications As simple as calling a library function

Metal Performance Shaders Supported image operators Histogram, Equalization, and Specification Morphology Min, Max, Dilate, and Erode Lanczos Resampling Median Thresholding Integral Convolution General, Gaussian Blur, Box, Tent, and Sobel

Metal Performance Shaders Supported image operators Histogram, Equalization, and Specification Morphology Min, Max, Dilate, and Erode Lanczos Resampling Median Thresholding Integral Convolution General, Gaussian Blur, Box, Tent, and Sobel

Equalization

Equalization

Metal Performance Shaders Supported image operators Histogram, Equalization and Specification Morphology Min, Max, Dilate, and Erode Lanczos Resampling Median Thresholding Integral Convolution General, Gaussian Blur, Box, Tent, and Sobel

Lanczos Resampling

Lanczos Resampling

Metal Performance Shaders Supported image operators Histogram, Equalization and Specification Morphology Min, Max, Dilate, and Erode Lanczos Resampling Median Thresholding Integral Convolution General, Gaussian Blur, Box, Tent, and Sobel

Thresholding

Thresholding

Thresholding and Sobel

Thresholding and Sobel

Metal Performance Shaders Supported image operators Histogram, Equalization and Specification Morphology Min, Max, Dilate, and Erode Lanczos Resampling Median Thresholding Integral Convolution General, Gaussian Blur, Box, Tent, and Sobel

Gaussian Blur

Gaussian Blur

Using Metal Performance Shaders Use a blur filter // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; Command Buffer // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter Command Buffer // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; Draw Draw Draw // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter Command Buffer // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; Draw Draw Draw // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer Dispatch Kernel Dispatch Kernel source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter Command Buffer // Create a filter object MPSImageGaussianBlur *blurfilter = [[MPSImageGaussianBlur alloc] initwithdevice: device sigma: 3]; Draw Draw Draw // Encode filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer Dispatch Kernel Dispatch Kernel source: sourcetexture destination: destinationtexture];

Using Metal Performance Shaders Use a blur filter Command Buffer Draw Draw Draw Dispatch Kernel Dispatch Kernel // Create a filter object MPSImageGaussianBlur *blurfilter [[MPSImageGaussianBlur alloc] initwithdevice: device Encode MPS Blur // filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture

Using Metal Performance Shaders Use a blur filter Command Buffer Draw Draw Draw Dispatch Kernel Dispatch Kernel // Create a filter object MPSImageGaussianBlur *blurfilter [[MPSImageGaussianBlur alloc] initwithdevice: device Encode MPS Blur // filter to the command buffer [blurfilter encodetocommandbuffer: commandbuffer source: sourcetexture destination: destinationtexture Commit

Download Sample Code https://developer.apple.com/library/prerelease/ios/samplecode/ MetalPerformanceShadersHelloWorld

Performance Behind the scenes Choose the right algorithm Tune for Kernel radius Pixel format Memory hierarchy Number of pixels per thread Threadgroup dimensions CPU optimizations

Performance Behind the scenes Choose the right algorithm Tune for Kernel radius Pixel format Memory hierarchy Number of pixels per thread Threadgroup dimensions CPU optimizations

Performance Behind the scenes Choose the right algorithm Tune for Kernel radius Pixel format Memory hierarchy Number of pixels per thread Threadgroup dimensions CPU optimizations

Performance Behind the scenes Choose the right algorithm Tune for Kernel radius Pixel format Memory hierarchy Number of pixels per thread Threadgroup dimensions CPU optimizations

Performance Behind the scenes Choose the right algorithm Tune for Kernel radius Pixel format Memory hierarchy Number of pixels per thread Threadgroup dimensions CPU optimizations

Optimized Gaussian Blur Statistics

Optimized Gaussian Blur Statistics 49 Metal kernels 2000 Lines of kernel code 821 Different Gaussian filter implementations

Demo

Filter Performance Not capped by screen refresh rate Smaller is better 16.6 ms = 60 FPS 16 12 ms 8 4 0 6 20 50 100 Sigma (Blur Radius)

A Few More Details

Source offset and Destination cliprect Filter properties Source Destination

Source offset and Destination cliprect Filter properties Source cliprect Destination

Source offset and Destination cliprect Filter properties offset Source cliprect Destination

Source offset and Destination cliprect Filter properties offset Source cliprect Destination

Source offset and Destination cliprect Filter properties offset Source cliprect Destination

In-place Operation Save memory Source == Destination

In-place Operation Save memory cliprect Source == Destination

In-place Operation Save memory offset cliprect Source == Destination

In-place Operation Save memory offset cliprect Source == Destination

In-place Operation Save memory offset cliprect Source == Destination

In-place Operation How? // Encode filter in-place in a Metal command buffer [blurfilter encodetocommandbuffer: commandbuffer inplacetexture: sourcetexture fallbackcopyallocator: myallocator];

In-place Operation How? // Encode filter in-place in a Metal command buffer [blurfilter encodetocommandbuffer: commandbuffer inplacetexture: sourcetexture fallbackcopyallocator: myallocator]; It s not always possible for Metal Performance Shaders filters to run in-place Depends on filter, filter parameters and properties Copy allocator will create a destination texture, so operation can proceed out-of-place

Fallback Copy Allocator Example MPSCopyAllocator myallocator = ^id <MTLTexture>( MPSKernel * filter, id <MTLCommandBuffer> commandbuffer, id <MTLTexture> sourcetexture) { MTLTextureDescriptor * desc = descriptorfromtexture(sourcetexture); id <MTLTexture> destinationtexture = [commandbuffer.device newtexturewithdescriptor: desc]; }; return destinationtexture;

Fallback Copy Allocator Example MPSCopyAllocator myallocator = ^id <MTLTexture>( MPSKernel * filter, id <MTLCommandBuffer> commandbuffer, id <MTLTexture> sourcetexture) { MTLTextureDescriptor * desc = descriptorfromtexture(sourcetexture); id <MTLTexture> destinationtexture = [commandbuffer.device newtexturewithdescriptor: desc]; // Use Metal encoder to initialize the destinationtexture from // sourcetexture, if necessary }; return destinationtexture;

Fallback Copy Allocator Example MPSCopyAllocator myallocator = ^id <MTLTexture>( MPSKernel * filter, id <MTLCommandBuffer> commandbuffer, id <MTLTexture> sourcetexture) { MTLTextureDescriptor * desc = descriptorfromtexture(sourcetexture); id <MTLTexture> destinationtexture = [commandbuffer.device newtexturewithdescriptor: desc]; // Use Metal encoder to initialize the destinationtexture from // sourcetexture, if necessary }; return destinationtexture;

Summary Make use of the new Metal support frameworks Robust, optimized, easy to integrate Faster bring-up of your application Less code to write and maintain Give us your feedback!

More Information Metal Documentation and Videos http://developer.apple.com/metal Apple Developer Forums http://developer.apple.com/forums Developer Technical Support http://developer.apple.com/support/technical General Inquiries Allan Schaffer, Game Technologies Evangelist aschaffer@apple.com

Related Sessions Managing 3D Assets with Model I/O Mission Tuesday 2:30PM What s New in Metal, Part 1 Presidio Tuesday 3:30PM Metal Performance Optimization Techniques Pacific Heights Friday 11:00AM

Related Labs Metal Lab Graphics D Friday 12:00PM