如何将数组从 Swift 传递到 MSL 参数 (C++)
How do I pass an array from Swift to MSL parameter (C++)
我想制作这个自定义 CIFilter。
var dummyColors = [
CIVector(x: 0.9, y: 0.3, z: 0.4),
CIVector(x: 0.2, y: 0.5, z: 0.9),
CIVector(x: 0.5, y: 0.9, z: 0.3)
]
var normal = dummyColors.withUnsafeMutableBufferPointer { (buffer) -> UnsafeMutablePointer<CIVector> in
var p = buffer.baseAddress
print(p)
return p!
}
//this is parameter and how to pass bvalue to the kernel function
return self.kernel.apply(extent: inputExtent,
roiCallback: roiCallback,
arguments: [inputImage, reddish, greenish, blueish, normal]) // (5)
这是我尝试用指针传递参数。然而,代码似乎不喜欢它,它只是在没有打印错误的情况下崩溃了。
这里是 metal 函数
extern "C" { namespace coreimage { // (3)
//this is how you define parameter on the top of the function
float4 dyeInThree(sampler src,
float3 redVector,
float3 greenVector,
float3 blueVector,
device float3 *a)
还有其他方法可以将参数传递给我的金属代码吗?
您使用 withUnsafeMutableBufferPointer
获得的指针仅在您传递给函数的闭包内有效。您需要为参数分配一个更“永久”的存储空间。
您可以先使用 UnsafeMutableBufferPointer.allocate
之类的方法来分配内存,但您必须在某处跟踪内存,因为在使用完后需要 deallocate
它。
我对你的用例采纳了这个答案:
这是我用于内存分配的内容:
var dummyColors = [
SIMD3<Float>(x: 1.1, y: 0.1, z: 0.1),
SIMD3<Float>(x: 0.1, y: 1.1, z: 0.1),
SIMD3<Float>(x: 0.1, y: 0.1, z: 1.1)
]
let pointer = UnsafeMutableRawPointer.allocate(
byteCount: 3 * MemoryLayout<SIMD3<Float>>.stride,
alignment: MemoryLayout<SIMD3<Float>>.alignment)
let sPointer = dummyColors.withUnsafeMutableBufferPointer { (buffer) -> UnsafeMutablePointer<SIMD3<Float>> in
let p = pointer.initializeMemory(as: SIMD3<Float>.self,
from: buffer.baseAddress!,
count: buffer.count)
return p
}
let data = Data(bytesNoCopy: sPointer, count: 3 * MemoryLayout<SIMD3<Float>>.stride, deallocator: .free)
在将缓冲区传递给内核之前,您需要将其转换为 NSData。这是 Metal 函数声明:
extern "C" { namespace coreimage { // (3)
float4 dyeInThree(sampler src,
float3 redVector,
float3 greenVector,
float3 blueVector,
constant float3 a[]) {
请注意 'constant' 命名空间而不是 'device'。否则 Metal 编译器会在运行时报错。
我想制作这个自定义 CIFilter。
var dummyColors = [
CIVector(x: 0.9, y: 0.3, z: 0.4),
CIVector(x: 0.2, y: 0.5, z: 0.9),
CIVector(x: 0.5, y: 0.9, z: 0.3)
]
var normal = dummyColors.withUnsafeMutableBufferPointer { (buffer) -> UnsafeMutablePointer<CIVector> in
var p = buffer.baseAddress
print(p)
return p!
}
//this is parameter and how to pass bvalue to the kernel function
return self.kernel.apply(extent: inputExtent,
roiCallback: roiCallback,
arguments: [inputImage, reddish, greenish, blueish, normal]) // (5)
这是我尝试用指针传递参数。然而,代码似乎不喜欢它,它只是在没有打印错误的情况下崩溃了。
这里是 metal 函数
extern "C" { namespace coreimage { // (3)
//this is how you define parameter on the top of the function
float4 dyeInThree(sampler src,
float3 redVector,
float3 greenVector,
float3 blueVector,
device float3 *a)
还有其他方法可以将参数传递给我的金属代码吗?
您使用 withUnsafeMutableBufferPointer
获得的指针仅在您传递给函数的闭包内有效。您需要为参数分配一个更“永久”的存储空间。
您可以先使用 UnsafeMutableBufferPointer.allocate
之类的方法来分配内存,但您必须在某处跟踪内存,因为在使用完后需要 deallocate
它。
我对你的用例采纳了这个答案:
这是我用于内存分配的内容:
var dummyColors = [
SIMD3<Float>(x: 1.1, y: 0.1, z: 0.1),
SIMD3<Float>(x: 0.1, y: 1.1, z: 0.1),
SIMD3<Float>(x: 0.1, y: 0.1, z: 1.1)
]
let pointer = UnsafeMutableRawPointer.allocate(
byteCount: 3 * MemoryLayout<SIMD3<Float>>.stride,
alignment: MemoryLayout<SIMD3<Float>>.alignment)
let sPointer = dummyColors.withUnsafeMutableBufferPointer { (buffer) -> UnsafeMutablePointer<SIMD3<Float>> in
let p = pointer.initializeMemory(as: SIMD3<Float>.self,
from: buffer.baseAddress!,
count: buffer.count)
return p
}
let data = Data(bytesNoCopy: sPointer, count: 3 * MemoryLayout<SIMD3<Float>>.stride, deallocator: .free)
在将缓冲区传递给内核之前,您需要将其转换为 NSData。这是 Metal 函数声明:
extern "C" { namespace coreimage { // (3)
float4 dyeInThree(sampler src,
float3 redVector,
float3 greenVector,
float3 blueVector,
constant float3 a[]) {
请注意 'constant' 命名空间而不是 'device'。否则 Metal 编译器会在运行时报错。