Created
July 16, 2017 20:51
-
-
Save astarasikov/9e4f58e540a6ff066806d37eb5b2af29 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.swift | |
// ComputeTexWrite | |
// | |
// Created by Alexander Tarasikov on 23/12/2016. | |
// Copyright © 2016 test. All rights reserved. | |
// | |
import Foundation | |
import Metal | |
func byteSize(array : [Int32] ) -> Int { | |
return array.count * MemoryLayout.size(ofValue: array[0]) | |
} | |
func runMetal() { | |
print("Hello, World!") | |
let dataLength = 1 << 8 | |
let useTexture = true | |
var input = [Int32](repeating:0, count: dataLength) | |
for i in (0...(dataLength - 1)) { | |
input[i] = Int32(arc4random_uniform(1024)) | |
} | |
let dataByteLength = dataLength * MemoryLayout.size(ofValue: input[0]) | |
/** | |
* The buffer to store the "stage" and "pass" indices (arguments for the kernel). | |
*/ | |
var paramData = [Int32](repeating:0, count: 2) | |
let device = MTLCreateSystemDefaultDevice() | |
print("Metal Device:", device as Any) | |
let defaultLibrary = device?.newDefaultLibrary() | |
let sigmoidFunction = defaultLibrary?.makeFunction(name: "stripe_Kernel") | |
let cmdQueue = device?.makeCommandQueue() | |
let width = 1024 | |
let height = 768 | |
let threadsPerGroup = MTLSize(width: 8, height: 8, depth: 1) | |
let numThreadGroups = MTLSize(width: width / threadsPerGroup.width, height: height / threadsPerGroup.height, depth: 1) | |
let inBuffer = device?.makeBuffer(bytes: &input, length:dataByteLength, options: MTLResourceOptions()) | |
let paramBuffer = device?.makeBuffer(bytes: ¶mData, length:byteSize(array:paramData), options: MTLResourceOptions.storageModeManaged) | |
let texBuffer = device?.makeBuffer(length:4 * width * height, options: MTLResourceOptions.storageModeShared) | |
var pipeline : MTLComputePipelineState? = nil | |
do { | |
pipeline = try device?.makeComputePipelineState(function: sigmoidFunction!) | |
} | |
catch { | |
print("Failed to make compute pipeline") | |
return | |
} | |
var textureDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: MTLPixelFormat.r32Float, width: width, height: height, mipmapped: false) | |
textureDesc.usage = MTLTextureUsage.shaderWrite | |
let metalTexture = device?.makeTexture(descriptor: textureDesc) | |
paramData[0] = Int32(0) | |
paramData[1] = Int32(0) | |
memcpy(paramBuffer?.contents(), ¶mData, byteSize(array: paramData)) | |
paramBuffer?.didModifyRange(NSMakeRange(0, byteSize(array: paramData))) | |
let cmdBuffer = cmdQueue?.makeCommandBuffer() | |
let cmdEncoder = cmdBuffer?.makeComputeCommandEncoder() | |
cmdEncoder?.setComputePipelineState(pipeline!) | |
cmdEncoder?.setTexture(metalTexture, at: 0) | |
cmdEncoder?.setBuffer(inBuffer, offset: 0, at: 0) | |
cmdEncoder?.setBuffer(paramBuffer, offset: 0, at: 1) | |
cmdEncoder?.setBuffer(paramBuffer, offset: 0, at: 2) | |
cmdEncoder?.setBuffer(texBuffer, offset:0, at:3) | |
cmdEncoder?.dispatchThreadgroups(numThreadGroups, threadsPerThreadgroup: threadsPerGroup) | |
cmdEncoder?.endEncoding() | |
let blitEncoder = cmdBuffer?.makeBlitCommandEncoder() | |
blitEncoder?.synchronize(texture: metalTexture!, slice: 0, level: 0) | |
blitEncoder?.endEncoding() | |
cmdBuffer?.commit() | |
cmdBuffer?.waitUntilCompleted() | |
let textureBufferSize = 4 * width * height | |
var result = [Float](repeating:0, count: textureBufferSize) | |
if useTexture { | |
let region = MTLRegionMake2D(0, 0, width, height) | |
metalTexture?.getBytes(&result, bytesPerRow: width * 4, from: region, mipmapLevel: 0) | |
} | |
else { | |
let data = NSData(bytesNoCopy: texBuffer!.contents(), length: textureBufferSize, freeWhenDone: false) | |
data.getBytes(&result, length: textureBufferSize) | |
} | |
print("Done") | |
for item in result { | |
if (item != 0.0) { | |
print(String(format:"%4.4f", item)) | |
} | |
} | |
} | |
runMetal() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment