Skip to content

Instantly share code, notes, and snippets.

@bellbind
Last active August 17, 2017 21:45
Show Gist options
  • Select an option

  • Save bellbind/6269a2d5a2df48eea53768fa6c304ca8 to your computer and use it in GitHub Desktop.

Select an option

Save bellbind/6269a2d5a2df48eea53768fa6c304ca8 to your computer and use it in GitHub Desktop.
[swift3][osx][ios][metal]Metal app on iOS with Simulator (metal not run)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>metalview</string>
<key>CFBundleIdentifier</key>
<string>bellbind.example.metalview</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>MetalView</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiresFullScreen</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
phone:="iPhone 7"
#phone:="iPhone 7 Plus"
udid:=$(shell xcrun simctl list|ruby -ne 'exit(print($$1).to_i) if /^ '$(phone)' \(([\-a-fA-F0-9]+)\)/')
#bin:=webkit
bin:=$(shell xmllint --xpath '//key[text()="CFBundleExecutable"]/following::string[1]/text()' Info.plist)
src:=$(bin).swift
appdir:=$(bin).app/
appid:=$(shell xmllint --xpath '//key[text()="CFBundleIdentifier"]/following::string[1]/text()' Info.plist)
echo:
echo "$(phone)"
echo "$(udid)"
default.metallib: shaders.metal
xcrun -sdk iphoneos metal -Wall -Wextra -std=ios-metal1.2 \
shaders.metal -o shaders.air
xcrun -sdk iphoneos metal-ar rcs shaders.metal-ar shaders.air
xcrun -sdk iphoneos metallib -o default.metallib shaders.metal-ar
rm shaders.metal-ar shaders.air
simapp: default.metallib
xcrun -sdk iphonesimulator swiftc -target x86_64-apple-ios10.2 $(src)
mkdir -p $(appdir)
cp Info.plist $(bin) default.metallib $(appdir)
phoneapp: default.metallib
xcrun -sdk iphoneos swiftc -target arm64-apple-ios10.2 $(src)
mkdir -p $(appdir)
cp Info.plist $(bin) default.metallib $(appdir)
open:
open -a Simulator --args -CurrentDeviceUDID $(udid)
# install and uninstall app to the booted simulator (require to open)
install:
xcrun simctl install $(udid) $(appdir)
uninstall:
xcrun simctl uninstall $(udid) $(appid)
showlog:
tail -f ~/Library/Logs/CoreSimulator/$(udid)/system.log
import UIKit
import MetalKit
class MetalDelegate: UIResponder, MTKViewDelegate {
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
NSLog("mtkView called")
}
func draw(in view: MTKView) {
// data
let verts = [
vector_float2(-1, -1), vector_float2(-1, 1), vector_float2(1, 1),
vector_float2(-1, -1), vector_float2(1, 1), vector_float2(1, -1),
]
NSLog("**********3********")
// device
guard let device = view.device else {
NSLog("Fail to get device")
return
}
NSLog("**********4********")
// shaders
let plDesc = MTLRenderPipelineDescriptor()
plDesc.colorAttachments[0].pixelFormat = view.colorPixelFormat
do {
let lib = try device.makeLibrary(filepath: "default.metallib")
plDesc.vertexFunction = lib.makeFunction(name: "vertexShaeder")
plDesc.fragmentFunction = lib.makeFunction(name: "fragmentShaeder")
} catch let error {
NSLog("Fail to load library: \(error)")
return
}
NSLog("**********5********")
// commands
let commandBuf = device.makeCommandQueue().makeCommandBuffer()
guard let passDesc = view.currentRenderPassDescriptor else {
NSLog("Fail to get passDesc")
return
}
let encoder = commandBuf.makeRenderCommandEncoder(descriptor: passDesc)
NSLog("**********7********")
do {
let plState =
try device.makeRenderPipelineState(descriptor: plDesc)
encoder.setRenderPipelineState(plState)
NSLog("**********6********")
} catch let error {
NSLog("\(error)")
return
}
let vertsBuf = device.makeBuffer(
bytes: verts,
length: verts.count * MemoryLayout.size(ofValue: vector_float2.self))
encoder.setVertexBuffer(vertsBuf, offset: 0, at: 0) //=> [[buffer(0)]]
encoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3)
encoder.endEncoding()
NSLog("**********8********")
guard let drawable = view.currentDrawable else {
NSLog("Fail to get drawable")
return
}
commandBuf.present(drawable)
commandBuf.commit()
NSLog("**********9********")
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchingOptions:
[UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
let frame = UIScreen.main.bounds
let win = UIWindow(frame: frame)
win.rootViewController = UIViewController(nibName: nil, bundle: nil)
win.backgroundColor = UIColor.white
win.makeKeyAndVisible()
NSLog("**********1********")
let device = MTLCreateSystemDefaultDevice()
NSLog("\(device): when nil, Metal would not use (ins Simulator)")
let metalView = MTKView(frame: frame, device: device)
metalView.clearColor = MTLClearColorMake(1.0, 1.0, 1.0, 1.0)
metalView.colorPixelFormat = .rgba8Unorm
metalView.delegate = MetalDelegate()
win.addSubview(metalView)
NSLog("**********2********")
window = win
return true
}
}
CommandLine.unsafeArgv.withMemoryRebound(
to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc)) {
argv -> Void in
UIApplicationMain(
CommandLine.argc, argv, nil, NSStringFromClass(AppDelegate.self))
}
//-*- mode: c++ -*-
#include <metal_stdlib>
vertex metal::float4
vertexShader(const device metal::float2* verts [[buffer(0)]],
metal::uint vid [[vertex_id]]) {
return metal::float4(verts[vid], 0.0, 1.0);
}
fragment metal::float4
fragmentShader(metal::float4 pos [[stage_in]]) {
return metal::float4((1.0 + pos.x) / 2.0, (1.0 + pos.y) / 2.0,
(2 + pos.x + pos.y) / 4, 1.0);
}
@bellbind
Copy link
Author

IMPORTANT: Simulator cannot run iOS app with Metal

(This is a preparation for someday would run Metal on Simulator)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment