#swift #metal
#swift #Металлические
Вопрос:
Рассмотрим следующий MSL:
#include <metal_stdlib>
using namespace metal;
struct VertexIn {
float3 position [[attribute(0)]];
float3 normal [[attribute(1)]];
float3 color [[attribute(2)]];
};
// Void just for demonstration
vertex void vertexFunc(const VertexIn vIn [[stage_in]]) {}
Концепция MTLBuffer
объектов и MTLVertexDescriptor
objects ясна: последнее описывает, как данные для металлической структуры ( VertexIn
в данном случае) распределяются между различными MTLBuffer
объектами. Затем, добавляя [[stage_in]]
атрибут к аргументу в вершинную функцию с типом структуры, создается экземпляр с элементами структуры, соответствующими данным.
У меня есть один вопрос: [[stage_in]]
автоматически ли выполняется смещение буфера на общий размер всех атрибутов с использованием определенного буфера ( totalSize
) totalSize * [[vertex_id]]
внутри каждого MTLBuffer
перед привязкой элементов структуры к данным с информацией о макете атрибута? Я полагаю, что это должно произойти, но я еще не нашел ничего, что указывало бы, происходит ли / как / когда это с [[stage_in]]
.
Например, если мы использовали
let descriptor = MTLVertexDescriptor()
// Position
descriptor.attributes[0].format = .float3
descriptor.attributes[0].bufferIndex = 0
descriptor.attributes[0].offset = 0
// Normal
descriptor.attributes[1].format = .float3
descriptor.attributes[1].bufferIndex = 0
descriptor.attributes[1].offset = MemoryLayout<vector_float3>.stride
// Color
descriptor.attributes[2].format = .float3
descriptor.attributes[2].bufferIndex = 1
descriptor.attributes[2].offset = 0
descriptor.layouts[0].stride = 2 * MemoryLayout<vector_float3>.stride
descriptor.layouts[1].stride = MemoryLayout<vector_float3>.stride
и установить два буфера, один с чередующимися позициями и обычными данными, а другой с цветовыми данными, будет ли вершинный шейдер получать данные n-й вершины (buffer0Start) n * (sizeof(float3) sizeof(float3))
в буфере 0 и (buffer1Start) n * (sizeof(float3))
в буфере 1 с [[stage_in]]
?
Ответ №1:
Похоже, что это так. Раздел 5.2.4, страница 87 «Спецификации языка металлического затенения» Apple версии 2.2 гласит
Вершинная функция может считывать входные данные для каждой вершины путем индексации в буфер (ы), переданный в качестве аргументов вершинной функции, используя идентификаторы вершины и экземпляра. Чтобы собрать входные данные для каждой вершины и передать их в качестве аргументов вершинной функции, объявите входные данные с
[[stage_in]]
атрибутом.