Upgrade to Pro — share decks privately, control downloads, hide ads and more …

飛び道具ではないMetal #iOSDC

shu223
September 17, 2017

飛び道具ではないMetal #iOSDC

iOSDC 2017での登壇資料です。

[概要]

WWDC17でもMetalのセッション会場は閑古鳥が鳴いてました。Metalって3Dゲームとかカメラアプリとかのトリッキーなエフェクト用でしょ、うちには関係ないなぁ・・・と思われている方も多いかもしれません。しかし、UIKitの下回りもMetalですし、色んな所で実はMetalは暗躍しています。そんなMetalにもっと多くの開発者に興味を持ってもらうため、非ゲーム・非カメラアプリ開発者にも関係しそうな切り口からMetalやGPUについて紹介してみたいと思います。

shu223

September 17, 2017
Tweet

More Decks by shu223

Other Decks in Programming

Transcript

  1. ! !

  2. " "

  3. Metal GPU • Core ML • Vision • Core Image

    • SceneKit • SpriteKit • MapKit
  4. Metal GPU • Core ML • Vision • Core Image

    • SceneKit • SpriteKit • MapKit • Core Animation • UIKit
  5. func draw(in view: MTKView) { guard let drawable = view.currentDrawable

    else {return} guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalError()} 
 guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fatalError()} let targetW = min(texture.width, drawable.texture.width) let targetH = min(texture.height, drawable.texture.height) blitEncoder.copy(from: texture, sourceSlice: 0, sourceLevel: 0, sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0), sourceSize: MTLSizeMake(targetW, targetH, texture.depth), to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0)) blitEncoder.endEncoding() commandBuffer.present(drawable) commandBuffer.commit() commandBuffer.waitUntilCompleted() } private let device = MTLCreateSystemDefaultDevice()! 
 private func setup() { commandQueue = device.makeCommandQueue() let textureLoader = MTKTextureLoader(device: device) texture = try! textureLoader.newTexture(name: "highsierra", scaleFactor: view.contentScaleFactor, bundle: nil) mtkView.device = device mtkView.delegate = self mtkView.colorPixelFormat = texture.pixelFormat }
  6. MTLTexture, MTKTextureLoader // ϩʔμʔΛॳظԽ loader = MTKTextureLoader(device: device) // ςΫενϟΛΞηοτΧλϩά͔Βڞ༗ϝϞϦྖҬʹϩʔυ

    texture = try! loader.newTexture(
 name: “hoge", 
 scaleFactor: view.contentScaleFactor, 
 bundle: nil) ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢
  7. MTLCommandQueue, MTLCommandBuffer // ίϚϯυΩϡʔ͔ΒίϚϯυόοϑΝΛ࡞੒ let commandBuffer = commandQueue.makeCommandBuffer()! // …

    ίϚϯυόοϑΝʹίϚϯυ௥Ճ // ίϚϯυόοϑΝΛίϛοτʢʹΤϯΩϡʔ͞ΕΔʣ commandBuffer.commit() ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢ // ίϚϯυΩϡʔΛॳظԽ commandQueue = device.makeCommandQueue()
  8. MTLCommandEncoder (MTLBlitCommandEncoder) let blitEncoder = commandBuffer.makeBlitCommandEncoder()! blitEncoder.copy(from: texture, sourceSlice: 0,

    sourceLevel: 0, sourceOrigin: srcOrigin, sourceSize: srcSize, to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin:dstOrigin) blitEncoder.endEncoding() ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢
  9. MTLCommandEncoder (MTLBlitCommandEncoder) let blitEncoder = commandBuffer.makeBlitCommandEncoder()! blitEncoder.copy(from: texture, sourceSlice: 0,

    sourceLevel: 0, sourceOrigin: srcOrigin, sourceSize: srcSize, to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin:dstOrigin) blitEncoder.endEncoding() ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢ ίϐʔݩ ίϐʔઌ
  10. // ίϚϯυΩϡʔ͔ΒίϚϯυόοϑΝΛ࡞੒ let commandBuffer = commandQueue.makeCommandBuffer()! // ίϚϯυΤϯίʔμΛ࡞੒ let blitEncoder

    = commandBuffer.makeBlitCommandEncoder()! blitEncoder.copy(from: texture, sourceSlice: 0, sourceLevel: 0, sourceOrigin: srcOrigin, sourceSize: srcSize, to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin:dstOrigin) // ίϚϯυ௥Ճ׬ྃ blitEncoder.endEncoding() // ίϚϯυόοϑΝΛίϛοτʢʹΤϯΩϡʔ͞ΕΔʣ commandBuffer.commit() ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢
  11. private let device = MTLCreateSystemDefaultDevice()! private func setup() { commandQueue

    = device.makeCommandQueue() let textureLoader = MTKTextureLoader(device: device) texture = try! textureLoader.newTexture(name: "highsierra", scaleFactor: view.contentScaleFactor, bundle: nil) mtkView.device = device mtkView.delegate = self mtkView.colorPixelFormat = texture.pixelFormat } func draw(in view: MTKView) { guard let drawable = view.currentDrawable else {return} guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalError()} 
 guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fatalError()} let targetW = min(texture.width, drawable.texture.width) let targetH = min(texture.height, drawable.texture.height) blitEncoder.copy(from: texture, sourceSlice: 0, sourceLevel: 0, sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0), sourceSize: MTLSizeMake(targetW, targetH, texture.depth), to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0)) blitEncoder.endEncoding() commandBuffer.present(drawable) commandBuffer.commit() commandBuffer.waitUntilCompleted() }
  12. private let device = MTLCreateSystemDefaultDevice()! private func setup() { commandQueue

    = device.makeCommandQueue() let textureLoader = MTKTextureLoader(device: device) texture = try! textureLoader.newTexture(name: "highsierra", scaleFactor: view.contentScaleFactor, bundle: nil) mtkView.device = device mtkView.delegate = self mtkView.colorPixelFormat = texture.pixelFormat } ίϚϯυόοϑΝ࡞੒ → ΤϯΩϡʔ →ʢGPU΁ૹ৴ʣ →ʢGPUͰίϚϯυ࣮ߦʣ →ʢඳըʣ func draw(in view: MTKView) { guard let drawable = view.currentDrawable else {return} guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalError()} 
 guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fatalError()} let targetW = min(texture.width, drawable.texture.width) let targetH = min(texture.height, drawable.texture.height) blitEncoder.copy(from: texture, sourceSlice: 0, sourceLevel: 0, sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0), sourceSize: MTLSizeMake(targetW, targetH, texture.depth), to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0)) blitEncoder.endEncoding() commandBuffer.present(drawable) commandBuffer.commit() commandBuffer.waitUntilCompleted() } ɾɾɾίϚϯυΩϡʔੜ੒ ςΫενϟΛϩʔυ ϏϡʔͷηοτΞοϓ ɾɾɾσόΠεੜ੒
  13. ·ͱΊ • Metal͸ؔ܎ͳ͘ͳ͍ - UIKitͷԼճΓͱͯ͠΋҉༂ • GPU͕ಘҙͳ࢓ࣄ͸GPUʹ೚ͤΑ͏ • Metalͷجૅ -

    Metalͱ͸ / OpenGLͱͷൺֱ • Metalͷ࣮૷ - എܠʹ͋Δ֓೦Λཧղ͢Δͱ؆୯