605 working with metal advanced

Upload: joeburnett

Post on 02-Jun-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/10/2019 605 Working With Metal Advanced

    1/161

    2014 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

    #WWD

    Working With MetalAdvanced

    Graphics and Games

    Session 605

    Gokhan Avkarogullari

    GPU Software

    Aaftab Munshi

    GPU Software

    Serhat Tekin

    GPU Software

  • 8/10/2019 605 Working With Metal Advanced

    2/161

    Agenda

    Introduction to Metal

    Fundamentals of Metal

    Building a Metal application

    Metal shading language

    Advanced Metal Deep dive into creating a graphics application with Metal

    Data-Parallel Computing with Metal

    Developer Tools Review

  • 8/10/2019 605 Working With Metal Advanced

    3/161

    Creating Multi-Pass Graphics

    Applications with Metal

  • 8/10/2019 605 Working With Metal Advanced

    4/161

    Graphics Application with Multiple Passe

    Multiple framebuffer configurations

    Render to off-screen and on-screen textures

    Meshes that are used with multiple shaders

    Multiple encoders

  • 8/10/2019 605 Working With Metal Advanced

    5/161

    Deferred Lighting with Shadow Maps

    Shadow Map

    Depth-only render from the perspective of the directional light

    Deferred Lighting

    Multiple render targets

    Framebuffer fetch for in-place light accumulation Stencil buffer for light culling

  • 8/10/2019 605 Working With Metal Advanced

    6/161

    Deferred Lighting with Shadow Maps

    Shadow Map

    Depth-only render from the perspective of the directional light

    Deferred Lighting

    Multiple render targets

    Framebuffer fetch for in-place light accumulation Stencil buffer for light culling

    Dont worry about the algorithm

    Focus on the details of how the API is used

  • 8/10/2019 605 Working With Metal Advanced

    7/161

    Deferred Lighting with Shadow Maps

    Command Queue

    Render Command Encoderfor Deferred Lighting Pass

    Command Buffer #1

    Render Command Encoderfor Shadow Pass

    Pipeline State

    Shaders Blend, etc.

    Depth State

    Buffers

    Textures

    Pipeline State

    Shaders Blend, etc.

    Depth State

    Buffers

    Textures

  • 8/10/2019 605 Working With Metal Advanced

    8/161

    Demo

    Deferred Lighting

  • 8/10/2019 605 Working With Metal Advanced

    9/161

    Render Setup

    Actions to take once at application start time

    Actions that are taken as needed

    Level load time

    Texture streaming

    Mesh streamingActions to take every frame

    Actions to take every render-to-texture pass

  • 8/10/2019 605 Working With Metal Advanced

    10/161

    Render SetupDo once

    Create device

    Create command queue

  • 8/10/2019 605 Working With Metal Advanced

    11/161

    Render SetupDo as needed

    Create framebuffer textures

    Create render pass descriptors

    Create buffers for meshes

    Create render pipeline objects

    Create texturesCreate state objects

    Create uniform buffers

  • 8/10/2019 605 Working With Metal Advanced

    12/161

    Render SetupDo every frame

    Create command buffer

    Update frame-based uniform buffers

    Submit command buffer

  • 8/10/2019 605 Working With Metal Advanced

    13/161

    Render SetupDo every render to texture pass

    Create command encoder

    Draw many times

    Update uniform buffers

    Set states

    Make draw calls

  • 8/10/2019 605 Working With Metal Advanced

    14/161

    Render SetupDo as needed

    Create framebuffer textures

    Create render pass descriptors

    Create buffers for meshes

    Create render pipeline objects

    Create texturesCreate state objects

    Create uniform buffers

  • 8/10/2019 605 Working With Metal Advanced

    15/161

    Render SetupA word on descriptors

    Descriptors are like blueprints

    Once the object is created the connection to the descriptor is gone

    Changing descriptors will not change the object

    Same descriptor can be reused to create another object

    Descriptor can be modified and then reused to create a new object

  • 8/10/2019 605 Working With Metal Advanced

    16/161

    Render SetupCreating render pass descriptors

    MTLRenderPassDescriptor

    Color Color

    Color Color

    Depth Stencil

  • 8/10/2019 605 Working With Metal Advanced

    17/161

    Render SetupCreating render pass descriptors

    MTLRenderPassDes

    Color Co

    Color Co

    Depth Ste

  • 8/10/2019 605 Working With Metal Advanced

    18/161

    Render SetupCreating render pass descriptors

    MTLRenderPassAttachmentDescriptor

    MTLTexture

    MTLResolveTexture

    loadActionstoreAction

    -

    MTLRenderPassDes

    Color Co

    Color Co

    Depth Ste

  • 8/10/2019 605 Working With Metal Advanced

    19/161

    Render SetupCreating render pass descriptors

    Texture

    MTLRenderPassAttachmentDescriptor

    MTLTexture

    MTLResolveTexture

    loadActionstoreAction

    -

    MTLRenderPassDes

    Color Co

    Color Co

    Depth Ste

  • 8/10/2019 605 Working With Metal Advanced

    20/161

    Render SetupRender pass descriptor for shadowMap pass

    shadowRenderPassDescriptor

    Depth

  • 8/10/2019 605 Working With Metal Advanced

    21/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create texture

    id shadow_texture;

    MTLTextureDescriptor *shadowTextureDesc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float

    width: 1024

    height: 1024

    mipmapped: NO];shadow_texture = [device newTextureWithDescriptor: shadowTextureDesc];

  • 8/10/2019 605 Working With Metal Advanced

    22/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create texture

    id shadow_texture;

    MTLTextureDescriptor *shadowTextureDesc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float

    width: 1024

    height: 1024

    mipmapped: NO];shadow_texture = [device newTextureWithDescriptor: shadowTextureDesc];

  • 8/10/2019 605 Working With Metal Advanced

    23/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create texture

    id shadow_texture;

    MTLTextureDescriptor *shadowTextureDesc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float

    width: 1024

    height: 1024

    mipmapped: NO];shadow_texture = [devicenewTextureWithDescriptor: shadowTextureDesc];

  • 8/10/2019 605 Working With Metal Advanced

    24/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create render pass descriptor

    MTLRenderPassDescriptor *shadowMapPassDesc =

    [MTLRenderPassDescriptor renderPassDescriptor];

  • 8/10/2019 605 Working With Metal Advanced

    25/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create render pass descriptor

    MTLRenderPassDescriptor *shadowMapPassDesc =

    [MTLRenderPassDescriptor renderPassDescriptor];

    // Set the texture on the render pass descriptor

    shadowMapPassDesc.depthAttachment.texture = shadow_texture;

    d

  • 8/10/2019 605 Working With Metal Advanced

    26/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create render pass descriptor

    MTLRenderPassDescriptor *shadowMapPassDesc =

    [MTLRenderPassDescriptor renderPassDescriptor];

    // Set the texture on the render pass descriptor

    shadowMapPassDesc.depthAttachment.texture = shadow_texture;

    R d S

  • 8/10/2019 605 Working With Metal Advanced

    27/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create render pass descriptor

    MTLRenderPassDescriptor *shadowMapPassDesc =

    [MTLRenderPassDescriptor renderPassDescriptor];

    // Set the texture on the render pass descriptor

    shadowMapPassDesc.depthAttachment.texture = shadow_texture;

    // Set other properties on the render pass descriptor

    shadowMapPassDesc.depthAttachment.clearValue = MTLClearValueMakeDepth(1.0

    shadowMapPassDesc.depthAttachment.loadAction = MTLLoadActionClear;

    shadowMapPassDesc.depthAttachment.setStoreAction = MTLStoreActionStore;

    R d S

  • 8/10/2019 605 Working With Metal Advanced

    28/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create render pass descriptor

    MTLRenderPassDescriptor *shadowMapPassDesc =

    [MTLRenderPassDescriptor renderPassDescriptor];

    // Set the texture on the render pass descriptor

    shadowMapPassDesc.depthAttachment.texture = shadow_texture;

    // Set other properties on the render pass descriptor

    shadowMapPassDesc.depthAttachment.clearValue = MTLClearValueMakeDepth(1.0

    shadowMapPassDesc.depthAttachment.loadAction = MTLLoadActionClear;

    shadowMapPassDesc.depthAttachment.setStoreAction = MTLStoreActionStore;

    R d S t

  • 8/10/2019 605 Working With Metal Advanced

    29/161

    Render SetupRender pass descriptor for shadowMap pass

    // Create render pass descriptor

    MTLRenderPassDescriptor *shadowMapPassDesc =

    [MTLRenderPassDescriptor renderPassDescriptor];

    // Set the texture on the render pass descriptor

    shadowMapPassDesc.depthAttachment.texture = shadow_texture;

    // Set other properties on the render pass descriptor

    shadowMapPassDesc.depthAttachment.clearValue = MTLClearValueMakeDepth(1.0

    shadowMapPassDesc.depthAttachment.loadAction= MTLLoadActionClear;

    shadowMapPassDesc.depthAttachment.setStoreAction= MTLStoreActionStore;

    R d S t

  • 8/10/2019 605 Working With Metal Advanced

    30/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    deferredPassDesc

    Color Color

    Color Color

    Depth Stencil

    R d S t

  • 8/10/2019 605 Working With Metal Advanced

    31/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm

    width: desc.width

    height: desc.height

    mipmapped: NO];

    R d S t

  • 8/10/2019 605 Working With Metal Advanced

    32/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm

    width: desc.width

    height: desc.height

    mipmapped: NO];

    // Create textures based on the descriptors

    gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    33/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm

    width: desc.width

    height: desc.height

    mipmapped: NO];

    // Create textures based on the descriptors

    gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    34/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm

    width: desc.width

    height: desc.height

    mipmapped: NO];

    // Create textures based on the descriptors

    gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc

    // Modify descriptor and create new texture

    [attachmentX_texture_desc setPixelFormat: ];

    gbuffer_texture2 = [device newTextureWithDescriptor: attachmentX_tex_desc

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    35/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm

    width: desc.width

    height: desc.height

    mipmapped: NO];

    // Create textures based on the descriptors

    gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc

    // Modify descriptor and create new texture

    [attachmentX_texture_desc setPixelFormat: ];

    gbuffer_texture2 = [device newTextureWithDescriptor: attachmentX_tex_desc

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    36/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Create descriptorMTLTextureDescriptor *attachmentX_texture_desc = [MTLTextureDescriptor

    texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm

    width: desc.width

    height: desc.height

    mipmapped: NO];

    // Create textures based on the descriptors

    gbuffer_texture1 = [device newTextureWithDescriptor: attachmentX_tex_desc

    // Modify descriptor and create new texture

    [attachmentX_texture_desc setPixelFormat: ];

    gbuffer_texture2 = [device newTextureWithDescriptor: attachmentX_tex_desc

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    37/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Create render pass descriptorMTLRenderPassDescriptor *deferredPassDesc =

    [MTLRenderPassDescriptor renderPassDescriptor];

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    38/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil; //will come from draw

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    39/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil; //will come from draw

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    40/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;

    deferredPassDesc.colorAttachments[0].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    41/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;

    deferredPassDesc.colorAttachments[0].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    42/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;

    deferredPassDesc.colorAttachments[0].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;

    // Describe color attachment 1

    deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    43/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;

    deferredPassDesc.colorAttachments[0].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;

    // Describe color attachment 1

    deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    44/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;

    deferredPassDesc.colorAttachments[0].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;

    // Describe color attachment 1

    deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    45/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;

    deferredPassDesc.colorAttachments[0].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;

    // Describe color attachment 1

    deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;

    deferredPassDesc.colorAttachments[1].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[1].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[1].storeAction = MTLStoreActionDontCare

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    46/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;

    deferredPassDesc.colorAttachments[0].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;

    // Describe color attachment 1

    deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;

    deferredPassDesc.colorAttachments[1].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[1].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[1].storeAction = MTLStoreActionDontCare

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    47/161

    Render SetupRender pass descriptor for the Deferred Lighting pass

    // Describe color attachment 0deferredPassDesc.colorAttachments[0].texture = nil;

    deferredPassDesc.colorAttachments[0].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;

    // Describe color attachment 1

    deferredPassDesc.colorAttachments[1].texture = gbuffer_texture1;

    deferredPassDesc.colorAttachments[1].clearValue = clearColor1;

    deferredPassDesc.colorAttachments[1].loadAction = MTLLoadActionClear;

    deferredPassDesc.colorAttachments[1].storeAction = MTLStoreActionDontCare

    Render Setup

  • 8/10/2019 605 Working With Metal Advanced

    48/161

    pDo as needed

    Create framebuffer textures

    Create render pass descriptors

    Create textures

    Create buffers for meshes

    Create state objects

    Create pipeline objects

    Create uniform buffers

    Creating Textures

  • 8/10/2019 605 Working With Metal Advanced

    49/161

    g

    // Copy texture data to bitmapDataunsigned Npixels = tex_info.width * tex_info.height;

    id texture = [device newTextureWithDescriptor: ];

    Creating Textures

  • 8/10/2019 605 Working With Metal Advanced

    50/161

    // Copy texture data to bitmapDataunsigned Npixels = tex_info.width * tex_info.height;

    id texture = [device newTextureWithDescriptor: ];

    [texture replaceRegion: bitmapData

    g

    Creating Textures

  • 8/10/2019 605 Working With Metal Advanced

    51/161

    // Copy texture data to bitmapDataunsigned Npixels = tex_info.width * tex_info.height;

    id texture = [device newTextureWithDescriptor: ];

    [texture replaceRegion: bitmapData

    g

    Creating Buffers for Meshes

  • 8/10/2019 605 Working With Metal Advanced

    52/161

    g

    float4 temple[100];

    spriteBuffer = [device newBufferWithBytes: &temple

    length: sizeof(temple)

    options: 0];

    Creating Buffers for Meshes

  • 8/10/2019 605 Working With Metal Advanced

    53/161

    g

    float4 temple[100];

    spriteBuffer = [device newBufferWithBytes: &temple

    length: sizeof(temple)

    options: 0];

    Creating State Objects

  • 8/10/2019 605 Working With Metal Advanced

    54/161

    g j

    MTLDepthStencilDescriptor*desc = [[MTLDepthStencilDescriptor alloc] initdesc.depthCompareFunction = MTLCompareFunctionLessEqual;

    desc.depthWriteEnabled = YES;

    MTLStencilDescriptor *stencilStateDesc = [[MTLStencilDescriptor alloc] in

    stencilState.stencilCompareFunction = MTLCompareFunctionAlways;

    stencilState.stencilFailureOperation = MTLStencilOperationKeep;

    desc.frontFaceStencilDescriptor = stencilStateDesc;

    desc.backFaceStencilDescriptor = stencilStateDesc;

    id shadowDepthStencilState= [devicenewDepthStencilStateWithDescriptor: desc];

    Creating State Objects

  • 8/10/2019 605 Working With Metal Advanced

    55/161

    MTLDepthStencilDescriptor*desc = [[MTLDepthStencilDescriptor alloc] initdesc.depthCompareFunction = MTLCompareFunctionLessEqual;

    desc.depthWriteEnabled = YES;

    MTLStencilDescriptor*stencilStateDesc = [[MTLStencilDescriptor alloc] in

    stencilState.stencilCompareFunction = MTLCompareFunctionAlways;

    stencilState.stencilFailureOperation = MTLStencilOperationKeep;

    desc.frontFaceStencilDescriptor = stencilStateDesc;

    desc.backFaceStencilDescriptor= stencilStateDesc;

    id shadowDepthStencilState = [devicenewDepthStencilStateWithDescriptor: desc];

    GPU Render Pipeline

  • 8/10/2019 605 Working With Metal Advanced

    56/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    BuffersTextures

    Samplers

    Buffers

    Render Pipeline State Object

  • 8/10/2019 605 Working With Metal Advanced

    57/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Buffers

    Render Pipeline State Object

  • 8/10/2019 605 Working With Metal Advanced

    58/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Buffers

    Shaders

    Render Pipeline State Object

  • 8/10/2019 605 Working With Metal Advanced

    59/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Buffers

    Framebuffer configuration

    Number of render targets, pixel format, sample co

    Render Pipeline State Object

  • 8/10/2019 605 Working With Metal Advanced

    60/161

    Buffers

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Depth and stencil state

    Render Pipeline State Object

  • 8/10/2019 605 Working With Metal Advanced

    61/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Buffers

    Render Pipeline State ObjectNot Includ

  • 8/10/2019 605 Working With Metal Advanced

    62/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Inputs

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Render Pipeline State ObjectNot Includ

  • 8/10/2019 605 Working With Metal Advanced

    63/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Buffers

    Outputs

    Render Pipeline State ObjectNot Includ

  • 8/10/2019 605 Working With Metal Advanced

    64/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Buffers

    Primitive setup

    Cull mode, facing orientation

    depth clipping, polygon mode

    Render Pipeline State ObjectNot Includ

  • 8/10/2019 605 Working With Metal Advanced

    65/161

    Vertex Fetch

    Vertex Shader

    Rasterizer

    FragmentShader

    Framebuffer

    Primitive Setup

    Buffers

    Buffers

    Textures

    Samplers

    Buffers

    Textures

    Samplers

    Buffers

    Viewport and scissorDepth bias/slope/clamp

    Occlusion queries

    Creating Render Pipeline State Object

  • 8/10/2019 605 Working With Metal Advanced

    66/161

    Every draw call requires a render pipeline state object to be setSame mesh usually has multiple pipeline state objects

    The temple object in our demo is rendered twice

    - The shadow passDepth only render with simple vertex shader

    - The deferred passRendered to generate g-buffer attributes

    - Each one requires a different render pipeline state object to be created

    Creating Render Pipeline State Objecth d M

  • 8/10/2019 605 Working With Metal Advanced

    67/161

    shadowMap pass

    // Create the descriptorMTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];

    Creating Render Pipeline State Objecth d M

  • 8/10/2019 605 Working With Metal Advanced

    68/161

    shadowMap pass

    // Create the descriptor

    MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];

    // Get the shaders from the library

    id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];

    Creating Render Pipeline State ObjectshadowMap pass

  • 8/10/2019 605 Working With Metal Advanced

    69/161

    shadowMap pass

    // Create the descriptor

    MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];

    // Get the shaders from the library

    id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];

    Creating Render Pipeline State ObjectshadowMap pass

  • 8/10/2019 605 Working With Metal Advanced

    70/161

    shadowMap pass

    // Create the descriptor

    MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];

    // Get the shaders from the library

    id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];

    // Set the states

    desc.label = @"Shadow Render";desc.vertexFunction = zOnlyVert;

    desc.stencilWriteEnabled = false;

    desc.depthWriteEnabled = true;

    desc.fragmentFunction = nil; //depth write only

    desc.depthAttachmentPixelFormat = pixelFormat;

    Creating Render Pipeline State ObjectshadowMap pass

  • 8/10/2019 605 Working With Metal Advanced

    71/161

    shadowMap pass

    // Create the descriptor

    MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];

    // Get the shaders from the library

    id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];

    // Set the states

    desc.label = @"Shadow Render";desc.vertexFunction = zOnlyVert;

    desc.stencilWriteEnabled = false;

    desc.depthWriteEnabled = true;

    desc.fragmentFunction = nil; //depth write only

    desc.depthAttachmentPixelFormat = pixelFormat;

    Creating Render Pipeline State ObjectshadowMap pass

  • 8/10/2019 605 Working With Metal Advanced

    72/161

    shadowMap pass

    MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];

    id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];

    desc.label = @"Shadow Render";

    desc.vertexFunction = zOnlyVert;

    desc.stencilWriteEnabled = false;

    desc.depthWriteEnabled = true;desc.fragmentFunction = nil; //depth write only

    desc.depthAttachmentPixelFormat = pixelFormat;

    // Create the render pipeline state object

    id pipeline = [device

    newRenderPipelineStateWithDescriptor: desc error: &err];

    Creating Render Pipeline State ObjectshadowMap pass

  • 8/10/2019 605 Working With Metal Advanced

    73/161

    shadowMap pass

    MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];

    id zOnlyVert = [zOnlyLibrary newFunctionWithName:@"ZOnly"];

    desc.label = @"Shadow Render";

    desc.vertexFunction = zOnlyVert;

    desc.stencilWriteEnabled = false;

    desc.depthWriteEnabled = true;desc.fragmentFunction = nil; //depth write only

    desc.depthAttachmentPixelFormat = pixelFormat;

    // Create the render pipeline state object

    id pipeline = [device

    newRenderPipelineStateWithDescriptor: desc error: &err];

    Creating Render Pipeline State ObjectDeferred Lighting pass

  • 8/10/2019 605 Working With Metal Advanced

    74/161

    Deferred Lighting pass

    desc.vertexFunction = gBufferVert;

    desc.fragmentFunction = gBufferFrag;

    desc.colorAttachments[0].pixelFormat = gbuffer_texture0.pixelFormat;

    desc.colorAttachments[1].pixelFormat = gbuffer_texture1.pixelFormat;

    desc.depthAttachmentPixelFormat = depth_texture.pixelFormat;

    desc.stencilAttachmentPixelFormat = stencil_texture.pixelFormat;

    Creating Render Pipeline State ObjectDeferred Lighting pass

  • 8/10/2019 605 Working With Metal Advanced

    75/161

    Deferred Lighting pass

    desc.vertexFunction = gBufferVert;

    desc.fragmentFunction = gBufferFrag;

    desc.colorAttachments[0].pixelFormat = gbuffer_texture0.pixelFormat;

    desc.colorAttachments[1].pixelFormat = gbuffer_texture1.pixelFormat;

    desc.depthAttachmentPixelFormat = depth_texture.pixelFormat;

    desc.stencilAttachmentPixelFormat = stencil_texture.pixelFormat;

    Creating Render Pipeline State ObjectDeferred Lighting pass

  • 8/10/2019 605 Working With Metal Advanced

    76/161

    Deferred Lighting pass

    desc.vertexFunction = gBufferVert;

    desc.fragmentFunction = gBufferFrag;

    desc.colorAttachments[0].pixelFormat = gbuffer_texture0.pixelFormat;

    desc.colorAttachments[1].pixelFormat = gbuffer_texture1.pixelFormat;

    desc.depthAttachmentPixelFormat = depth_texture.pixelFormat;

    desc.stencilAttachmentPixelFormat = stencil_texture.pixelFormat;

    Render SetupDo every frame

  • 8/10/2019 605 Working With Metal Advanced

    77/161

    Do every frame

    Create command bufferUpdate frame-based uniform buffers

    Submit command buffer

    Render SetupCreate and submit command buffer

  • 8/10/2019 605 Working With Metal Advanced

    78/161

    Create and submit command buffer

    // BeginFrame

    commandBuffer = [commandQueue commandBuffer];

    // EndFrame

    [commandBuffer addPresent: drawable];

    [commandBuffer commit];

    commandBuffer = nil;

    Render SetupCreate and submit command buffer

  • 8/10/2019 605 Working With Metal Advanced

    79/161

    Create and submit command buffer

    // BeginFrame

    commandBuffer = [commandQueue commandBuffer];

    // EndFrame

    [commandBuffer addPresent: drawable];

    [commandBuffer commit];

    commandBuffer = nil;

    Render SetupCreate and submit command buffer

  • 8/10/2019 605 Working With Metal Advanced

    80/161

    Create and submit command buffer

    // BeginFrame

    commandBuffer = [commandQueue commandBuffer];

    // EndFrame

    [commandBuffer addPresent: drawable];

    [commandBuffer commit];

    commandBuffer = nil;

    Render SetupDo every render to texture pass

  • 8/10/2019 605 Working With Metal Advanced

    81/161

    y p

    Create command encoder

    Draw many times

    Update uniform buffers

    Set states

    Make draw calls

    Render SetupshadowMap pass render encoding

  • 8/10/2019 605 Working With Metal Advanced

    82/161

    p p g

    // Create encoder

    id encoder = [commandBuffer

    renderCommandEncoderWithDescriptor: shadowMapPassDesc];

    Render SetupshadowMap pass render encoding

  • 8/10/2019 605 Working With Metal Advanced

    83/161

    p p g

    // Create encoder

    id encoder = [commandBuffer

    renderCommandEncoderWithDescriptor: shadowMapPassDesc];

    // Set states and draw

    [encoder setRenderPipelineState: shadow_render_pipeline];

    [encoder setDepthStencilState: shadowDepthStencilState];

    [encoder setVertexBuffer: structureVertexBuffer offset:0 atIndex: 0

    [encoder drawIndexedPrimitives:

    Render SetupshadowMap pass render encoding

  • 8/10/2019 605 Working With Metal Advanced

    84/161

    p p g

    // Create encoder

    id encoder = [commandBuffer

    renderCommandEncoderWithDescriptor: shadowMapPassDesc];

    // Set states and draw

    [encoder setRenderPipelineState: shadow_render_pipeline];

    [encoder setDepthStencilState: shadowDepthStencilState];

    [encoder setVertexBuffer: structureVertexBuffer offset:0 atIndex: 0

    [encoder drawIndexedPrimitives:

    Render SetupshadowMap pass render encoding

  • 8/10/2019 605 Working With Metal Advanced

    85/161

    g

    // Create encoder

    id encoder = [commandBuffer

    renderCommandEncoderWithDescriptor: shadowMapPassDesc];

    // Set states and draw

    [encoder setRenderPipelineState: shadow_render_pipeline];

    [encoder setDepthStencilState: shadowDepthStencilState];

    [encoder setVertexBuffer: structureVertexBuffer offset:0 atIndex: 0

    [encoder drawIndexedPrimitives:

    // end encoding

    [encoder endEncoding];

    Render SetupshadowMap pass render encoding

  • 8/10/2019 605 Working With Metal Advanced

    86/161

    // Create encoder

    id encoder = [commandBuffer

    renderCommandEncoderWithDescriptor: shadowMapPassDesc];

    // Set states and draw

    [encoder setRenderPipelineState: shadow_render_pipeline];

    [encoder setDepthStencilState: shadowDepthStencilState];

    [encoder setVertexBuffer: structureVertexBuffer offset:0 atIndex: 0

    [encoder drawIndexedPrimitives:

    // end encoding

    [encoder endEncoding];

    Render SetupDeferred Lighting pass render encoding

  • 8/10/2019 605 Working With Metal Advanced

    87/161

    deferredPassDesc.colorAttachments[0].texture = texture_from_drawable;

    Render SetupDeferred Lighting pass render encoding

  • 8/10/2019 605 Working With Metal Advanced

    88/161

    deferredPassDesc.colorAttachments[0].texture = texture_from_drawable;

    // Create encoder

    id encoder = [commandBuffer

    renderCommandEncoderWithDescriptor: deferredPassDesc];

    Render SetupDeferred Lighting pass render encoding

  • 8/10/2019 605 Working With Metal Advanced

    89/161

    deferredPassDesc.colorAttachments[0].texture = texture_from_drawable;

    // Create encoder

    id encoder = [commandBuffer

    renderCommandEncoderWithDescriptor: deferredPassDesc];

    // End encoding

    [encoder endEncoding];

    Agenda

  • 8/10/2019 605 Working With Metal Advanced

    90/161

    Introduction to Metal

    Fundamentals of Metal

    Building a Metal application

    Metal shading language

    Advanced Metal

    Data-Parallel Computing with Metal

    Developer Tools Review

  • 8/10/2019 605 Working With Metal Advanced

    91/161

    Data-Parallel Computing with Metal

    Aaftab MunshiGPU Software

    Data-Parallel Computing with MetalWhat youll learn

  • 8/10/2019 605 Working With Metal Advanced

    92/161

    Data-Parallel Computing with MetalWhat youll learn

  • 8/10/2019 605 Working With Metal Advanced

    93/161

    What is data-parallel computing?

    Data-Parallel Computing with MetalWhat youll learn

  • 8/10/2019 605 Working With Metal Advanced

    94/161

    What is data-parallel computing?

    Data-parallel computing in Metal

    Data-Parallel Computing with MetalWhat youll learn

  • 8/10/2019 605 Working With Metal Advanced

    95/161

    What is data-parallel computing?

    Data-parallel computing in Metal

    Writing data-parallel kernels in Metal

    Data-Parallel Computing with MetalWhat youll learn

  • 8/10/2019 605 Working With Metal Advanced

    96/161

    What is data-parallel computing?

    Data-parallel computing in Metal

    Writing data-parallel kernels in Metal

    Executing kernels in Metal

    Data-Parallel ComputingA brief introduction

  • 8/10/2019 605 Working With Metal Advanced

    97/161

    Data-Parallel ComputingA brief introduction

  • 8/10/2019 605 Working With Metal Advanced

    98/161

    Similar and independent computations on multiple data elements

    Data-Parallel ComputingA brief introduction

  • 8/10/2019 605 Working With Metal Advanced

    99/161

    Similar and independent computations on multiple data elements

    ExampleBlurring an image

    Same computation for each input

    All results are independent

    Data-Parallelism in Metal

  • 8/10/2019 605 Working With Metal Advanced

    100/161

    Data-Parallelism in Metal

  • 8/10/2019 605 Working With Metal Advanced

    101/161

    Code that describes computation is called a kernel

    Data-Parallelism in Metal

  • 8/10/2019 605 Working With Metal Advanced

    102/161

    Code that describes computation is called a kernel

    Independent computation instance

    Work-item

    Data-Parallelism in Metal

  • 8/10/2019 605 Working With Metal Advanced

    103/161

    Code that describes computation is called a kernel

    Independent computation instance

    Work-item

    Work-items that execute together

    Work-group

    Cooperate by sharing data Can synchronize execution

    Data-Parallelism in MetalComputation domain

  • 8/10/2019 605 Working With Metal Advanced

    104/161

    Data-Parallelism in MetalComputation domain

  • 8/10/2019 605 Working With Metal Advanced

    105/161

    Number of dimensions

    1D, 2D, or 3D

    Data-Parallelism in MetalComputation domain

  • 8/10/2019 605 Working With Metal Advanced

    106/161

    Number of dimensions

    1D, 2D, or 3D

    For each dimension specify

    Number of work-items in work-group also known as work-group size

    Number of work-groups

    Data-Parallelism in MetalComputation domain

  • 8/10/2019 605 Working With Metal Advanced

    107/161

    Number of dimensions

    1D, 2D, or 3D

    For each dimension specify

    Number of work-items in work-group also known as work-group size

    Number of work-groups

    Choose the dimensions that are best for your algorithm

    Pseudo Code for a Data-Parallel Kernel

  • 8/10/2019 605 Working With Metal Advanced

    108/161

    voidsquare(const float* input,

    float* output,uint id

    {output[id] = input[id] * input[id];

    }

    Pseudo Code for a Data-Parallel Kernel

  • 8/10/2019 605 Working With Metal Advanced

    109/161

    #include

    using namespace metal;voidsquare(const float* input,

    float* output,uint id

    {output[id] = input[id] * input[id];

    }

    Pseudo Code for a Data-Parallel Kernel

  • 8/10/2019 605 Working With Metal Advanced

    110/161

    #include

    using namespace metal;kernel voidsquare(const float* input,

    float* output,uint id

    {output[id] = input[id] * input[id];

    }

    Pseudo Code for a Data-Parallel Kernel

  • 8/10/2019 605 Working With Metal Advanced

    111/161

    #include

    using namespace metal;kernelvoidsquare(const global float* input [[ buffer(0)]],

    global float* output [[ buffer(1)]],uint id

    {output[id] = input[id] * input[id];

    }

    Metal Kernel

  • 8/10/2019 605 Working With Metal Advanced

    112/161

    #include

    using namespace metal;kernelvoidsquare(const global float* input [[ buffer(0)]],

    global float* output [[ buffer(1)]],uint id [[ global_id]])

    {output[id] = input[id] * input[id];

    }

    Another Kernel Example in MetalUsing images in a kernel

  • 8/10/2019 605 Working With Metal Advanced

    113/161

    Another Kernel Example in MetalUsing images in a kernel

  • 8/10/2019 605 Working With Metal Advanced

    114/161

    kernel void

    horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}

    Another Kernel Example in MetalUsing images in a kernel

  • 8/10/2019 605 Working With Metal Advanced

    115/161

    kernel void

    horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}

    Another Kernel Example in MetalUsing images in a kernel

  • 8/10/2019 605 Working With Metal Advanced

    116/161

    kernel void

    horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}

    Another Kernel Example in MetalUsing images in a kernel

  • 8/10/2019 605 Working With Metal Advanced

    117/161

    kernel void

    horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}

    Another Kernel Example in MetalUsing images in a kernel

  • 8/10/2019 605 Working With Metal Advanced

    118/161

    kernel void

    horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}

    Another Kernel Example in MetalUsing images in a kernel

  • 8/10/2019 605 Working With Metal Advanced

    119/161

    kernel void

    horizontal_reflect(texture2d src [[ texture(0) ]],texture2d dst [[ texture(1) ]], uint2id[[ global_id ]]){ float4 c = src.read(uint2(src.get_width()-1-id.x, id.y)); dst.write(c, id);}

    Built-in Kernel VariablesAttributes for kernel arguments

  • 8/10/2019 605 Working With Metal Advanced

    120/161

    kernel void

    my_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)

    {

    }

    Built-in Kernel VariablesAttributes for kernel arguments

    k l id

  • 8/10/2019 605 Working With Metal Advanced

    121/161

    kernel void

    my_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)

    {

    }

    Built-in Kernel VariablesAttributes for kernel arguments

    k l id

  • 8/10/2019 605 Working With Metal Advanced

    122/161

    kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],

    uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)

    {

    }

    Built-in Kernel VariablesAttributes for kernel arguments

    kernel void

  • 8/10/2019 605 Working With Metal Advanced

    123/161

    kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],

    uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)

    {

    }

    Built-in Kernel VariablesAttributes for kernel arguments

    kernel void

  • 8/10/2019 605 Working With Metal Advanced

    124/161

    kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],

    uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)

    {

    }

    Built-in Kernel VariablesAttributes for kernel arguments

    kernel void

  • 8/10/2019 605 Working With Metal Advanced

    125/161

    kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],

    uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)

    {

    }

    Built-in Kernel VariablesAttributes for kernel arguments

    kernel void

  • 8/10/2019 605 Working With Metal Advanced

    126/161

    kernel voidmy_kernel(texture2d img [[ texture(0) ]], ushort2 gid [[ global_id]],

    uint glinear [[ global_linear_id]],ushort2 lid [[ local_id]],ushort linear [[ local_linear_id]],uint wgid [[ work_group_id]],)

    {

    }

  • 8/10/2019 605 Working With Metal Advanced

    127/161

    Executing Kernels in MetalPost-processing example

    Post-Processing KernelKernel source

  • 8/10/2019 605 Working With Metal Advanced

    128/161

    Post-Processing KernelKernel source

    kernel void

  • 8/10/2019 605 Working With Metal Advanced

    129/161

    kernel voidpostprocess_filter(texture2d inImage[[ texture(0) ]], texture2d outImage [[ texture(1) texture2d curveImage [[ texture(2) ]], constant Parameters& param [[ buffer(0) ]], uint2 gid [[ global_id ]]){ // Transform global ID using param.transformMatrix

    float4 color = inImage.sample(s, transformedCoord);

    // Apply post-processing effect

    outImage.write(color, gid);}

    Post-Processing KernelKernel source

    kernel void

  • 8/10/2019 605 Working With Metal Advanced

    130/161

    postprocess_filter(texture2d inImage[[ texture(0) ]], texture2d outImage [[ texture(1) texture2d curveImage [[ texture(2) ]], constant Parameters& param [[ buffer(0) ]], uint2 gid [[ global_id ]]){ // Transform global ID using param.transformMatrix

    float4 color = inImage.sample(s, transformedCoord);

    // Apply post-processing effect

    outImage.write(color, gid);}

    Post-Processing KernelKernel source

    kernel void

  • 8/10/2019 605 Working With Metal Advanced

    131/161

    postprocess_filter(texture2d inImage[[ texture(0) ]], texture2d outImage [[ texture(1) texture2d curveImage [[ texture(2) ]], constant Parameters& param [[ buffer(0) ]], uint2 gid [[ global_id ]]){ // Transform global ID using param.transformMatrix

    float4 color = inImage.sample(s, transformedCoord);

    // Apply post-processing effect

    outImage.write(color, gid);}

    Post-Processing KernelKernel source

    kernel void

  • 8/10/2019 605 Working With Metal Advanced

    132/161

    postprocess_filter(texture2d inImage[[ texture(0) ]], texture2d outImage [[ texture(1) texture2d curveImage [[ texture(2) ]], constant Parameters& param [[ buffer(0) ]], uint2 gid [[ global_id ]]){ // Transform global ID using param.transformMatrix

    float4 color = inImage.sample(s, transformedCoord);

    // Apply post-processing effect

    outImage.write(color, gid);}

    Post-Processing KernelProcessing multiple pixels/work-item

    constexpr constant int num_pixels_work_item = 4;

  • 8/10/2019 605 Working With Metal Advanced

    133/161

    kernel voidpostprocess_filter(, uint2 gid [[global_id]],

    uint2 lsize [[local_size]]){ for (int i=0; i

  • 8/10/2019 605 Working With Metal Advanced

    134/161

    kernel voidpostprocess_filter(, uint2 gid [[global_id]],

    uint2 lsize [[local_size]]){ for (int i=0; i

  • 8/10/2019 605 Working With Metal Advanced

    135/161

    kernel voidpostprocess_filter(, uint2 gid [[global_id]],

    uint2 lsize [[local_size]]){ for (int i=0; i

  • 8/10/2019 605 Working With Metal Advanced

    136/161

    Executing a KernelCompute command encoder

    //Load library and kernel function

  • 8/10/2019 605 Working With Metal Advanced

    137/161

    id library = [device newLibraryWithFile:libnameerror:&err];id filterFunc = [library

    newFunctionWithName:@postprocess_filter]

    Executing a KernelCompute command encoder

    //Load library and kernel function

  • 8/10/2019 605 Working With Metal Advanced

    138/161

    id library = [device newLibraryWithFile:libnameerror:&err];id filterFunc = [library

    newFunctionWithName:@postprocess_filter]

    // Create compute state

    id filterKernel=[device newComputePipelineStateWithFunction:filterFuncerror:&err];

    Executing a KernelCompute command encoder

    //Load library and kernel function

  • 8/10/2019 605 Working With Metal Advanced

    139/161

    id library = [device newLibraryWithFile:libnameerror:&err];id filterFunc = [library

    newFunctionWithName:@postprocess_filter]

    // Create compute state

    id filterKernel=[device newComputePipelineStateWithFunction:filterFuncerror:&err];

    // Create compute command encoder

    Executing a KernelCompute command encoder

    //Load library and kernel function

  • 8/10/2019 605 Working With Metal Advanced

    140/161

    id library = [device newLibraryWithFile:libnameerror:&err];id filterFunc = [library

    newFunctionWithName:@postprocess_filter]

    // Create compute state

    id filterKernel=[device newComputePipelineStateWithFunction:filterFuncerror:&err];

    // Create compute command encoder

    id computeEncoder=[commandBuffer computeCommandEncoder];

    Executing a KernelEncode compute commands

  • 8/10/2019 605 Working With Metal Advanced

    141/161

    Executing a KernelEncode compute commands

    // Set compute state

    [ t E d tC t Pi li St t filt K l]

  • 8/10/2019 605 Working With Metal Advanced

    142/161

    [computeEncoder setComputePipelineState:filterKernel];

    Executing a KernelEncode compute commands

    // Set compute state

    [comp teEncoder setComp tePipelineState filterKernel]

  • 8/10/2019 605 Working With Metal Advanced

    143/161

    [computeEncoder setComputePipelineState:filterKernel];

    // Set Resources used by kernel

    [computeEncoder setTexture:inputImage atIndex:0];[computeEncoder setTexture:outputImage atIndex:1];[computeEncoder setTexture:curveImage atIndex:2];[computeEncoder setBuffer:params offset:0 atIndex:0];

    Executing a KernelEncode compute commands

  • 8/10/2019 605 Working With Metal Advanced

    144/161

    Executing a KernelEncode compute commands

    // Calculate the work-group size and number of work-groups

    MTLSize wgSize = { 16 16 1 };

  • 8/10/2019 605 Working With Metal Advanced

    145/161

    MTLSize wgSize = { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };

    Executing a KernelEncode compute commands

    // Calculate the work-group size and number of work-groups

    MTLSize wgSize = { 16 16 1 };

  • 8/10/2019 605 Working With Metal Advanced

    146/161

    MTLSize wgSize = { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };

    Executing a KernelEncode compute commands

    // Calculate the work-group size and number of work-groups

    MTLSize wgSize = { 16 16 1 };

  • 8/10/2019 605 Working With Metal Advanced

    147/161

    MTLSize wgSize = { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };

    // Execute Kernel

    [computeEncoder executeKernelWithWorkGroupSize:wgSizeworkGroupCount:numWorkGroups];

    Executing a KernelEncode compute commands

    // Calculate the work-group size and number of work-groups

    MTLSize wgSize = { 16, 16, 1 };

  • 8/10/2019 605 Working With Metal Advanced

    148/161

    MTLSize wgSize { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };

    // Execute Kernel

    [computeEncoder executeKernelWithWorkGroupSize:wgSizeworkGroupCount:numWorkGroups];

    Executing a KernelEncode compute commands

    // Calculate the work-group size and number of work-groups

    MTLSize wgSize = { 16, 16, 1 };

  • 8/10/2019 605 Working With Metal Advanced

    149/161

    MTLSize wgSize { 16, 16, 1 };MTLSize numWorkGroups = { (outputImage.width + wgSize - 1)/wgSize. (outputImage.height + wgSize - 1)/wgSize 1 };

    // Execute Kernel

    [computeEncoder executeKernelWithWorkGroupSize:wgSizeworkGroupCount:numWorkGroups];

    // Finish encoding

    [computeEncoder endEncoding];

    Executing a KernelSubmit commands to the GPU

    // Commit the command buffer

    [commandBuffer commit];

  • 8/10/2019 605 Working With Metal Advanced

    150/161

    [ ];

  • 8/10/2019 605 Working With Metal Advanced

    151/161

    Demo

    Post-processing kernels

    Agenda

    Introduction to Metal

  • 8/10/2019 605 Working With Metal Advanced

    152/161

    Fundamentals of Metal Building a Metal application

    Metal shading language

    Advanced Metal

    Developer Tools Review

  • 8/10/2019 605 Working With Metal Advanced

    153/161

    ToolsDebugging and profiling Metal applications in Xcode

    Summary

  • 8/10/2019 605 Working With Metal Advanced

    154/161

    Summary

    A deeper dive into Metal

  • 8/10/2019 605 Working With Metal Advanced

    155/161

    Structuring your application for Metal Using descriptors and state objects for rendering

    Multi-pass encoding in Metal

    Summary

    A deeper dive into Metal

  • 8/10/2019 605 Working With Metal Advanced

    156/161

    Structuring your application for Metal Using descriptors and state objects for rendering

    Multi-pass encoding in Metal

    Data-parallel computing in Metal

    How data-parallelism works in Metal

    Write and execute kernels in Metal

    Summary

    A deeper dive into Metal

    S i li i f l

  • 8/10/2019 605 Working With Metal Advanced

    157/161

    Structuring your application for Metal Using descriptors and state objects for rendering

    Multi-pass encoding in Metal

    Data-parallel computing in Metal

    How data-parallelism works in Metal

    Write and execute kernels in Metal

    Tools

    How to create and compile Metal Shaders in Xcode

    Debug and profile a Metal application

    More Information

    Filip IliescuGraphics and Games Technologies Evangelist

    fili @ l

  • 8/10/2019 605 Working With Metal Advanced

    158/161

    [email protected]

    Allan SchafferGraphics and Games Technologies Evangelist

    [email protected]

    Documentation

    http://developer.apple.com

    Apple Developer Forumshttp://devforums.apple.com

    Related Sessions

    http://devforums.apple.com/http://devforums.apple.com/
  • 8/10/2019 605 Working With Metal Advanced

    159/161

    Labs

  • 8/10/2019 605 Working With Metal Advanced

    160/161

  • 8/10/2019 605 Working With Metal Advanced

    161/161