arrays - Swift Int 数组到 MetalBuffer<Int>

标签 arrays swift integer metal metalkit

我正在研究使用 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)
}

View Controller 每帧都会调用updateIntArray。 我在着色器调用后打印了 sizeof(Buffers[i]),它是 4!

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

谢谢!

最佳答案

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

我有一个 ShaderTypes.h 文件来创建可与 Swift 和 MSL( Metal 着色语言)一起使用的自定义值类型。如果您想在 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)

您还需要传入 count,因为 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 也有些陌生,所以我不确定这是否是最好的做事方式。我感谢有更多经验的人提供的任何反馈。

关于arrays - Swift Int 数组到 MetalBuffer<Int>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70693994/

相关文章:

ios - 保存到 NSData 数组时出现内存警告

json - 解析字典行为奇怪

ios - 需要以编程方式创建 plist 并访问今天的小部件扩展目标

ios - iOS 12 中的自定义导航标题

java - 扫描仪需要更多字符?

c - C 程序将用户输入转换为整数,然后将整数转换为(HEX、Bin、Alpha)的问题

c - 二维字符数组和字符指针

javascript - 在 JavaScript 中创建一个可点击的数组

以科学记数法返回的 Bash 数字序列?

java数组声明