Chiarimento su come si trovano i dati degli argomenti per una funzione di vertice utilizzando MTLVertexDescriptor e l'attributo [[attribute(n)]]

Aug 24 2020

Considera il seguente 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]]) {}

Il concetto di MTLBufferoggetti e MTLVertexDescriptoroggetti è chiaro: quest'ultimo descrive come i dati per una struttura Metal ( VertexInin questo caso) sono distribuiti tra diversi MTLBufferoggetti. Quindi, aggiungendo l' [[stage_in]]attributo all'argomento in una funzione di vertice con il tipo di struttura, viene creata un'istanza con i membri della struttura abbinati ai dati.

Ho una domanda: [[stage_in]]compensa automaticamente il buffer in base alla dimensione totale di tutti gli attributi utilizzando un particolare buffer ( totalSize) totalSize * [[vertex_id]]all'interno di ciascuno MTLBufferprima di associare i membri della struttura ai dati con le informazioni sul layout dell'attributo? Immagino che questo debba accadere, ma non ho ancora trovato nulla che menzioni se/come/quando ciò si verifica con [[stage_in]].

Ad esempio, se abbiamo usato

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

e impostare due buffer, uno con la posizione interlacciata e i dati normali e l'altro con i dati del colore, il vertex shader riceverebbe i dati dell'ennesimo vertice (buffer0Start) + n * (sizeof(float3) + sizeof(float3))nel buffer 0 e (buffer1Start) + n * (sizeof(float3))nel buffer 1 con [[stage_in]]?

Risposte

Leftasanexercise Aug 25 2020 at 08:01

Sembra che questo sia il caso. La sezione 5.2.4, pagina 87 della versione 2.2 di "Metal Shading Language Specification" di Apple recita

Una funzione di vertice può leggere gli input per vertice indicizzando in buffer (s) passati come argomenti alla funzione di vertice utilizzando gli ID di vertice e di istanza. Per assemblare input per vertice e passarli come argomenti a una funzione di vertice, dichiarare gli input con l' [[stage_in]]attributo.