Swift Int 数组到 MetalBuffer<Int>

问题描述 投票:0回答:2

我正在研究使用 Swift 和 Metal Kit 进行应用程序开发

我想将int类型数组转换为Metalbuffer,因为我必须在Shader.h中覆盖该数组数据

在操作shader.h之前,数组的值没有问题。 但是,在shader.h中和之后,从数组转换的缓冲区存在一些问题。

例如,我将 [1, 2, 3, 4] 发送到 Metalbuffer,然后调用

renderEncoder.setVertexBuffer(Metalbuffer)
。 然后,在 Shader.h 中它看起来像 [1, 0, 2, 0] 有什么问题吗???

这是我的示例代码

var int_array = Array(reapeating: 1, count: 100)

init(){
    Buffers = MetalBuffer<Int>(device: device, array: int_array, index: kBuffers.rawValue, options: [])
    
}
 
func updateIntArray(){
    for i in 0..<100 {
        int_array[i] = i % 20
    }
    Buffers = MetalBuffer<Int>(device: device, array: int_array, index: kBuffers.rawValue, options: [])
    
    (other codes about rendering)
    renderEncoder.setVertexBuffer(Buffers)
}

updateIntArray
被视图控制器每帧调用。 我在着色器调用后打印了 sizeof(Buffers[i]),它是 4!

如何保留数据而不插入0?

谢谢!

arrays swift integer metal metalkit
2个回答
2
投票

您的问题缺少很多代码,但我将向您展示如何将数组作为参数传递给我的片段着色器。

我有一个 ShaderTypes.h 文件来创建可与 Swift 和 MSL(金属着色语言)一起使用的自定义值类型。如果您想在 Swift 端使用它,您将需要一个桥接头。

#ifndef ShaderTypes_h
#define ShaderTypes_h
#include <simd/simd.h>

typedef struct {
    float intensity;
    float time;
    float width;
    float height;
    float originX;
    float originY;
}KeyPointValues;

我的目标是将 KeyPointValues 数组作为参数传递给我的片段着色器。在快速方面,我做了这样的事情:

var keyPoints = [KeyPointValues()]

for index in 0...10 {
   keyPoints.append(KeyPointValues())
}

var count = keyPoints.count

guard let keyPointBuffer = context.device.makeBuffer(bytes: keyPoints, length: MemoryLayout<KeyPointValues>.stride * count) else { return }

commandEncoder.setFragmentBuffer(keyPointBuffer, offset: 0, index: 0)
commandEncoder.setFragmentBytes(&count, length: MemoryLayout.size(ofValue: count), index: 1)

您还需要传入计数,因为 MSL 中没有

keyPoints.count
对应项。

然后片段着色器看起来像这样:

#include <metal_stdlib>
#include <simd/simd.h>
#import "ShaderTypes.h"

using namespace metal;

fragment half4 rosyFilter(device const KeyPointValues *keyPoints [[buffer(0)]],
                          constant uint &count [[ buffer(1) ]]
                          ) {

   for(uint index = 0; index < count; index++) {
      float intensity = keyPoints[index].intensity;
   }
}

希望这能让您朝着正确的方向开始。您使用的是 Int 数组,因此它应该更容易,因为可能不需要定义在 Swift 和 MSL 之间使用的自定义结构。

我对 Metal 也有些陌生,所以我不确定这是否是最好的做事方式。我感谢有更多经验的人提供的任何反馈。


0
投票

我认为你的问题是你认为 Swift 中的 Int 是 MSL 中的 int 。实际上 Int = long 并且 Int32=int 因此,要么发送 Int32 要么将您的输入读取为 long

© www.soinside.com 2019 - 2024. All rights reserved.