Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

飛び道具ではないMetal #iOSDC

5,612 views

Published on

iOSDC 2017での登壇資料です。

[概要]

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

Published in: Mobile
  • Hey guys! Who wants to chat with me? More photos with me here 👉 http://www.bit.ly/katekoxx
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

飛び道具ではないMetal #iOSDC

  1. 1. iOSDC 2017 Shuichi Tsutsumi @shu223
  2. 2. WWDC 2014
  3. 3. Swift Metal !
  4. 4. WWDC2014 Metal
  5. 5. WWDC2014 Swift
  6. 6. ! !
  7. 7. Metal
  8. 8. " "
  9. 9. Metal
  10. 10.
  11. 11.
  12. 12. Metal GPU • Core ML • Vision • Core Image • SceneKit • SpriteKit • MapKit
  13. 13. Metal GPU • Core ML • Vision • Core Image • SceneKit • SpriteKit • MapKit • Core Animation • UIKit
  14. 14. 143,000 Metal API
  15. 15. 143,000 17,000,000 Metal API Metal API
  16. 16. Metal
  17. 17. ✓Metal ✓Metal ✓Metal
  18. 18. imageView.image = image
  19. 19.
  20. 20.
  21. 21. 
 

  22. 22. 
 

  23. 23. 
 

  24. 24. CPU GPU CPU • • GPU • • CPU
  25. 25. • CPU - 100% • GPU GPU - - - -
  26. 26. 
 1 60 • CPU • OK 1
  27. 27. 
 1 60 • CPU • OK GPU 1
  28. 28. : GPU GPU
  29. 29. GPU
  30. 30. GPU GPU Your app ???
  31. 31. OpenGL
  32. 32. OpenGL • API • • Apple
  33. 33. Metal • Apple • Apple • OpenGL 10 • OpenGL Metal
  34. 34. imageView.image = image
  35. 35. Metal API
  36. 36. 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 }
  37. 37. • MTLDevice • MTLCommandQueue • MTLCommandBuffer • MTLCommandEncoder • MTLTexture • MTKView • MTKTextureLoader • etc…
  38. 38. $
  39. 39.
  40. 40.
  41. 41.
  42. 42.
  43. 43. MTLCommandBuffer MTLTexture MTLDevice
  44. 44. MTLCommandBuffer MTLTexture MTLDevice MTLCommandEncoder
  45. 45. MTLCommandBuffer MTLTexture MTLDevice MTLCommandQueue MTLCommandEncoder
  46. 46. MTLCommandBuffer MTLTexture MTLDevice MTLCommandQueue MTKTextureLoader MTLCommandEncoder
  47. 47. MTLDevice let device = MTLCreateSystemDefaultDevice()! ※
  48. 48. MTLTexture, MTKTextureLoader // loader = MTKTextureLoader(device: device) // texture = try! loader.newTexture(
 name: “hoge", 
 scaleFactor: view.contentScaleFactor, 
 bundle: nil) ※
  49. 49. MTLCommandQueue, MTLCommandBuffer // let commandBuffer = commandQueue.makeCommandBuffer()! // … // commandBuffer.commit() ※ // commandQueue = device.makeCommandQueue()
  50. 50. MTLCommandEncoder • MTLRenderCommandEncoder MTLComputeCommandEncoder MTLBlitCommandEncode
  51. 51. 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() ※
  52. 52. 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() ※
  53. 53. // 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() ※
  54. 54. 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() }
  55. 55. 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() }
  56. 56. %
  57. 57. Powered by
  58. 58. GPU GPU Your app ???
  59. 59. Metal • ARKit • MPS CNN / RNN • Core Image
  60. 60. GPU Metal
  61. 61. • Metal - UIKit • GPU GPU • Metal - Metal / OpenGL • Metal -
  62. 62. https://github.com/shu223

×