将制服结构中的数组传递给Metal shader

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

我在Swift中将Uniforms结构定义为:

struct Uniforms {
    var t = Float(0.0)
    var arr = [0.2, 0.2, 0.2, 0.2, 0.2]
}

但是,我无法为其分配适当的MTLBuffer,因为MemoryLayout<Uniforms>.stride返回16。这与Swift规范中关于数组是值类型的说法相矛盾。实际上,MemoryLayout将其视为引用类型。

长话短说,我如何将包含数组的Uniforms结构传递给着色器(我使用常量名称空间将其传递,在那里一切都很好)。我是否需要通过一个单独的[[buffer(n)]]参数分别传递数组,我将从数组中复制内存?还有更简单的选择吗?

swift metal
1个回答
0
投票

由于Swift无法保证结构布局,因此将这样的结构的内容直接复制到Metal缓冲区中是很危险的(同样,正如所写的那样,该数组包含Double,但Metal目前尚不支持) )。根据实际问题的形状,可以使用几种不同的方法。

如果知道数组中元素的最大数量,则可以添加指示实际计数的struct成员,并将着色器期望的struct的最后一个元素设为固定长度的数组:

#define MAX_VALUE_COUNT 1024
struct ShaderUniforms {
    float t;
    uint32_t valueCount;
    float values[MAX_VALUE_COUNT];
};

然后,在Swift中,您可以分配最大大小的Metal缓冲区(在这种情况下为4104字节),然后将所需的许多数组元素复制到缓冲区中(当然,在其他struct成员之前)。

或者,可以使用指针类型的单独缓冲区参数(例如constant float *values [[buffer(1)]])。这将使您拥有不受显式编码到着色器中的任何内容限制的值计数。

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