有效地将Swift Array复制到iOS Metal的内存缓冲区 [英] Efficiently copying Swift Array to memory buffer for iOS Metal
问题描述
我正在使用Apple的新Metal框架编写iOS应用程序。我有一系列Matrix4对象(参见 Ray Wenderlich's教程)我需要通过MTLDevice.newBufferWithLength()方法传入着色器。 Matrix4对象正在利用Apple的GLKit(它包含一个GLKMatrix4对象)。
I am writing an iOS application using Apple's new Metal framework. I have an array of Matrix4 objects (see Ray Wenderlich's tutorial) that I need to pass in to a shader via the MTLDevice.newBufferWithLength() method. The Matrix4 object is leveraging Apple's GLKit (it contains a GLKMatrix4 object).
我正在利用GPU调用实例化。
I'm leveraging instancing with the GPU calls.
我稍后会将其更改为一个结构,其中包含每个实例的更多数据(超出Matrix4对象。
I will later change this to a struct which includes more data per instance (beyond just the Matrix4 object.
-
如何有效地将[Matrix4]对象数组复制到此缓冲区?
How can I efficiently copy the array of [Matrix4] objects into this buffer?
有更好的方法吗?再次,我将扩展这将在未来使用包含更多数据的结构。
Is there a better way to do this? Again, I'll expand this to use a struct with more data in the future.
以下是我的代码的子集:
Below is a subset of my code:
let sizeofMatrix4 = sizeof(Float) * Matrix4.numberofElements()
// This returns an array of [Matrix4] objects.
let boxArray = createBoxArray(parentModelViewMatrix)
let sizeOfUniformBuffer = boxArray.count * sizeOfMatrix4
var uniformBuffer = device.newBufferWithLength(sizeofUniformBuffer, options: .CPUCacheModeDefaultCache)
let bufferPointer = uniformBuffer?.contents()
// Ouch - way too slow. How can I optimize?
for i in 0..<boxArray.count
{
memcpy(bufferPointer! + (i * sizeOfMatrix4), boxArray[i].raw(), sizeOfMatrix4)
}
renderEncoder.setVertexBuffer(uniformBuffer, offset: 0, atIndex: 2)
注意:
boxArray [i] .raw()方法在Objective-C代码中定义如下:
Note: The boxArray[i].raw() method is defined as this in the Objective-C code:
- (void *)raw {
return glkMatrix.m;
}
你可以看到我循环遍历每个数组对象,然后做一个memcpy 。我这样做是因为我遇到了将数组视为连续内存集的问题。
You can see I'm looping through each array object and then doing a memcpy. I did this since I was experiencing problems treating the array as a contiguous set of memory.
谢谢!
推荐答案
Swift数组被认为是连续的内存,但你需要确保它真的是一个Swift数组而不是秘密的NSArray。如果您想完全确定,请使用ContiguousArray。这将确保连续的内存,即使其中的对象可以桥接到ObjC。如果你想要更多地控制内存,请查看 ManagedBuffer
。
A Swift Array is promised to be contiguous memory, but you need to make sure it's really a Swift Array and not secretly an NSArray. If you want to be completely certain, use a ContiguousArray. That will ensure contiguous memory even if the objects in it are bridgeable to ObjC. If you want even more control over the memory, look at ManagedBuffer
.
有了这个,你应该使用 newBufferWithBytesNoCopy(length:options:deallocator)
在你现有的内存周围创建一个MTL缓冲区。
With that, you should be using newBufferWithBytesNoCopy(length:options:deallocator)
to create a MTL buffer around your existing memory.
这篇关于有效地将Swift Array复制到iOS Metal的内存缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!