有效地将Swift Array复制到iOS Metal的内存缓冲区 [英] Efficiently copying Swift Array to memory buffer for iOS Metal

查看:480
本文介绍了有效地将Swift Array复制到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.


  1. 如何有效地将[Matrix4]对象数组复制到此缓冲区?

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆