Поскольку Swift не дает никаких гарантий относительно макета структуры, было бы опасно копировать содержимое такой структуры напрямую в буфер Metal (также, как написано, массив содержит Double
s, которые в настоящее время не поддерживаются Metal. тем не мение). Есть несколько разных подходов, которые могут работать, в зависимости от формы реальной проблемы.
Если вы знаете максимальное количество элементов в массиве, вы можете добавить член структуры, указывающий фактическое количество, и сделать последний элемент структуры, ожидаемой вашим шейдером, представляет собой массив фиксированной длины:
#define MAX_VALUE_COUNT 1024
struct ShaderUniforms {
float t;
uint32_t valueCount;
float values[MAX_VALUE_COUNT];
};
Затем в Swift вы можете выделить металлический буфер максимального размера (4104 байта в этом надуманном случае) и скопируйте необходимое количество элементов массива в буфер (которому, конечно же, предшествуют другие элементы структуры).
В качестве альтернативы, да, вы можете использовать отдельный параметр буфера типа указателя (например, constant float *values [[buffer(1)]]
) . Это позволит вам иметь счетчик значений, который не ограничен ничем, явно закодированным в шейдере.