我可以从Metal Shader获取缓冲区的大小吗?

时间:2014-10-20 08:09:09

标签: ios metal

在我的iOS应用程序中,用Swift编写,我使用:

生成一个Metal缓冲区
vertexBuffer = device.newBufferWithBytes(vertices, length: vertices.count * sizeofValue(vertices[0]), options: nil)

并将其绑定到我的着色器程序:

renderCommandEncoder.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 1)

在我的着色器程序中,用Metal着色语言编写,我可以访问缓冲区的大小吗?我想访问缓冲区中的下一个顶点来进行差分计算。类似的东西:

vertex float4 my_vertex(const device packed_float3* vertices [[buffer(1)]],
                         unsigned int vid[[vertex_id]]) {
    float4 vertex = vertices[vid];
    // Need to clamp this to not go beyond buffer, 
    // but how do I know the max value of vid? 
    float4 nextVertex = vertices[vid + 1]; 
    float4 tangent = nextVertex - vertex;
    // ...
}

我唯一的选择是将顶点数传递为制服?

3 个答案:

答案 0 :(得分:5)

据我所知,不,你不能因为顶点指向一个地址。就像C ++一样,必须有两件事要知道数组的数量或大小:
1)知道数组的数据类型(浮点数或某些结构)

2a)数据类型OR的数组计数 2b)数组的总字节数。

所以是的,您需要将数组计数作为统一传递。

答案 1 :(得分:-1)

其实你可以。您可以将结果值用于循环或条件。您无法使用它来初始化对象。 (所以动态数组失败)

uint tempUint = 0; // some random type
uint uintSize = sizeof(tempUint); // get the size for the type
uint aVectorSize = sizeof(aVector) / uintSize; // divide the buffer by the type.

float dynamicArray[aVectorSize]; // this fails

for (uint counter = 0; counter < aVectorSize; ++ counter) {
    // do stuff
};

if (aVectorSize > 10) {
    // do more stuff
} 

答案 2 :(得分:-1)

可以使用纹理缓冲区。

您可以从着色器代码中获取 纹理 缓冲区的大小。
纹理缓冲区具有public Flux<TestItemBatch> batch() { Flux<TestItem> items= //...; Flux<List<TestItem>> itemsLists = items.buffer(100); return itemsLists.map(list -> new TestItemBatch(list)); } get_width()函数,它们返回get_height()

uint

但这可能无法回答OP关于 vertex 缓冲区的问题。