根据文档(https://developer.apple.com/documentation/metal/gpu_features/understanding_gpu_family_4)“在基于 A7 到 A10 的设备上,Metal 没有明确描述这种基于图块的架构”。在同一篇文章中,我看到“A11 GPU 上的 Metal 2”并感到困惑,因为在金属着色语言规范中没有找到有关 Metal 2 支持的更多信息。例如,我找到了表“片段函数图块输入参数的属性”并注释“iOS:自 Metal 2.0 起支持表 5.5 中的属性”。Metal 2 支持特定于 GPU 系列吗?
我正在使用a SCNRenderer来渲染屏幕,然后将一些后期渲染效果应用到MTLLayer,然后将其显示在CAMetalLayer中.
Xcode/LLVM给我的一个性能提示就是我在需要nextDrawable()之前调用它.在应用后期渲染效果后,我正在为每一帧调用它.
我想知道我什么时候打电话nextDrawable()?
我想在Objective-C中为我的iOS应用程序使用Metal中定义的一些矢量数据类型(例如uint2,docs).但是,我无法找到有关这是否可行的任何信息.
对于我的项目(编译为框架),我有一个文件ops.metal:
kernel void add(device float *lhs [[buffer(0)]],
device float *rhs [[buffer(1)]],
device float *result [[buffer(2)]],
uint id [[ thread_position_in_grid ]])
{
result[id] = lhs[id] + rhs[id];
}
Run Code Online (Sandbox Code Playgroud)
以及以下Swift代码:
@available(OSX 10.11, *)
public class MTLContext {
var device: MTLDevice!
var commandQueue:MTLCommandQueue!
var library:MTLLibrary!
var commandBuffer:MTLCommandBuffer
var commandEncoder:MTLComputeCommandEncoder
init() {
if let defaultDevice = MTLCreateSystemDefaultDevice() {
device = defaultDevice
print("device created")
} else {
print("Metal is not supported")
}
commandQueue = device.makeCommandQueue()
library = device.newDefaultLibrary()
if let defaultLibrary = device.newDefaultLibrary() …Run Code Online (Sandbox Code Playgroud) 我在大阵列(图像)上做循环,通过仪器我发现主要的瓶颈是Array.subscript.nativePinningMutableAddressor,所以我做了这个单元测试来比较,
// average: 0.461 seconds (iPhone6 iOS 10.2) ~5.8 times slower than native arrays
func testArrayPerformance() {
self.measure {
var array = [Float](repeating: 1, count: 2048 * 2048)
for i in 0..<array.count {
array[(i+1)%array.count] = Float(i)
}
}
}
// average: 0.079 seconds
func testNativeArrayPerformance() {
self.measure {
let count = 2048 * 2048
let array = UnsafeMutablePointer<Float>.allocate(capacity: count)
for i in 0..<count {
array[(i+1)%count] = Float(i)
}
array.deallocate(capacity: count)
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,本机数组要快得多.还有其他方法可以更快地访问阵列吗?"不安全"听起来并不"安全",但在这种情况下你会做些什么呢?是否有其他类型的数组包装本机?
有关更复杂的示例,您可以看到本文中的注释:使用带符号距离字段在Metal中呈现文本 我在Swift中重新实现了该示例,并且原始实现需要52秒才能启动,https:// github …
我正在使用iOS 11,XCode 9和Metal2。我MTLTexture使用像素格式bgra8Unorm。我无法更改此像素格式,因为根据pixelFormat文档:
金属层的像素格式必须为bgra8Unorm,bgra8Unorm_srgb,rgba16Float,BGRA10_XR或bgra10_XR_sRGB。
其他像素格式不适合我的应用程序。
现在,我想UIImage从纹理创建一个。我可以通过从纹理(doc)中提取像素字节来做到这一点:
getBytes(_:bytesPerRow:bytesPerImage:from:mipmapLevel:slice:)
Run Code Online (Sandbox Code Playgroud)
我正在处理这些字节以获取UIImage:
func getUIImageForRGBAData(data: Data) -> UIImage? {
let d = (data as NSData)
let width = GlobalConfiguration.textureWidth
let height = GlobalConfiguration.textureHeight
let rowBytes = width * 4
let size = rowBytes * height
let pointer = malloc(size)
memcpy(pointer, d.bytes, d.length)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let context = CGContext(data: pointer, width: width, height: height, bitsPerComponent: 8, bytesPerRow: rowBytes, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)! …Run Code Online (Sandbox Code Playgroud) 尝试在SCNRender对象的每个调用渲染中从MTLTexture创建CVPixelBufferRef:
CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let bytesPerRow = 4 * Int(textureSizeX)
let region = MTLRegionMake2D(0, 0, Int(textureSizeX), Int(textureSizeY))
var tmpBuffer = CVPixelBufferGetBaseAddress(pixelBuffer!);
offscreenTexture.getBytes(tmpBuffer!, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)
CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
Run Code Online (Sandbox Code Playgroud)
然后转换为UIImage以显示在屏幕上
let ciImage = CIImage.init(cvPixelBuffer: pixelBuffer!)
let temporaryContext = CIContext(options: nil)
let tempImage = temporaryContext.createCGImage(ciImage, from: CGRect(x: 0, y: 0, width: textureSizeX, height: textureSizeY))
let uiImage = UIImage.init(cgImage: tempImage!)
Run Code Online (Sandbox Code Playgroud)
但是不显示图像
我有一个可以长时间运行的功能(具有多个内部循环)。我假设在GPU而不是CPU上运行它会更快?
有没有办法在GPU上运行任意功能?
苹果已经表示金属:
Metal 2提供对图形处理单元(GPU)的近乎直接访问,使您能够最大程度地发挥应用程序的... 计算潜力
我看到了使用Metal进行游戏和图形渲染的示例,但是有没有任何示例或链接可以帮助我运行常规功能?
我有以下Filter.metal文件
#include <metal_stdlib>
using namespace metal;
#include <CoreImage/CoreImage.h> // includes CIKernelMetalLib.h
extern "C" { namespace coreimage {
float4 myColor(sample_t s) {
return s.grba;
}
}}
Run Code Online (Sandbox Code Playgroud)
我正在尝试将其编译为:
xcrun metal -fcikernel Filter.metal -o Filter.air
xcrun metallib -cikernel Filter.air -o Filter.metallib
Run Code Online (Sandbox Code Playgroud)
但是我得到这个错误:
metallib: Error reading module: Invalid bitcode signature
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建自定义CIFIlter,我遵循以下步骤:https ://medium.com/@shu223/core-image-filters-with-metal-71afd6377f4 教程。
我从https://developer.apple.com/metal/MetalCIKLReference6.pdf获得的命令行。
如何编译没有此错误的文件?
在Metal shader中,声明类似const constant Vertex *vertexArray [[buffer(0)]](const constant我的意思是)的变量的目的是什么?为什么仅靠常数还不够?而且,constant和之间有什么区别const?
同样,const device和之间的区别是constant什么?