飛び道具ではないMetal #iOSDC

19d7ae634445d4bd9b10c7961a462260?s=47 shu223
September 17, 2017

飛び道具ではないMetal #iOSDC

iOSDC 2017での登壇資料です。

[概要]

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

19d7ae634445d4bd9b10c7961a462260?s=128

shu223

September 17, 2017
Tweet

Transcript

  1. 2.
  2. 5.
  3. 6.
  4. 10.

    ! !

  5. 12.

    " "

  6. 16.

  7. 17.
  8. 18.

    Metal GPU • Core ML • Vision • Core Image

    • SceneKit • SpriteKit • MapKit
  9. 19.

    Metal GPU • Core ML • Vision • Core Image

    • SceneKit • SpriteKit • MapKit • Core Animation • UIKit
  10. 26.
  11. 36.
  12. 39.
  13. 44.
  14. 46.
  15. 48.

    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 }
  16. 50.
  17. 53.
  18. 64.

    MTLTexture, MTKTextureLoader // ϩʔμʔΛॳظԽ loader = MTKTextureLoader(device: device) // ςΫενϟΛΞηοτΧλϩά͔Βڞ༗ϝϞϦྖҬʹϩʔυ

    texture = try! loader.newTexture(
 name: “hoge", 
 scaleFactor: view.contentScaleFactor, 
 bundle: nil) ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢
  19. 65.

    MTLCommandQueue, MTLCommandBuffer // ίϚϯυΩϡʔ͔ΒίϚϯυόοϑΝΛ࡞੒ let commandBuffer = commandQueue.makeCommandBuffer()! // …

    ίϚϯυόοϑΝʹίϚϯυ௥Ճ // ίϚϯυόοϑΝΛίϛοτʢʹΤϯΩϡʔ͞ΕΔʣ commandBuffer.commit() ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢ // ίϚϯυΩϡʔΛॳظԽ commandQueue = device.makeCommandQueue()
  20. 67.

    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() ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢
  21. 68.

    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() ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢ ίϐʔݩ ίϐʔઌ
  22. 69.

    // ίϚϯυΩϡʔ͔ΒίϚϯυόοϑΝΛ࡞੒ 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() ※Τϥʔॲཧ౳͸লུ͍ͯ͠·͢
  23. 70.

    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() }
  24. 71.

    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() } ɾɾɾίϚϯυΩϡʔੜ੒ ςΫενϟΛϩʔυ ϏϡʔͷηοτΞοϓ ɾɾɾσόΠεੜ੒
  25. 77.

    ·ͱΊ • Metal͸ؔ܎ͳ͘ͳ͍ - UIKitͷԼճΓͱͯ͠΋҉༂ • GPU͕ಘҙͳ࢓ࣄ͸GPUʹ೚ͤΑ͏ • Metalͷجૅ -

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