Can I get the size of a buffer from my Metal shade

2019-05-06 21:37发布

In my iOS app, written in Swift, I generate a Metal buffer with:

vertexBuffer = device.newBufferWithBytes(vertices, length: vertices.count * sizeofValue(vertices[0]), options: nil)

And bind it to my shader program with:

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

In my shader program, written in Metal shading language, can I access the size of the buffer? I would like to access the next vertex in my buffer to do some differential calculation. Something like:

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;
    // ...
}

Is my only option to pass the number of vertices as a uniform?

标签: ios metal
3条回答
We Are One
2楼-- · 2019-05-06 21:42

As far as I know, no you can't because the vertices points to an address. Just like C++, must have two things to know the count or size of an array:
1) know what data type of the array (float or some struct)
AND
2a) the array count for the data type OR
2b) the total bytes of the array.

So yes, you would need to pass the array count as a uniform.

查看更多
劫难
3楼-- · 2019-05-06 22:04

For texture buffers you can.

You can get the size of a texture buffer from within the shader code.
Texture buffers have a get_width() and get_height() function, which return a uint.

uint get_width() const; uint get_height() const;

But that probably does not answer OP's question about vertex buffers.

查看更多
姐就是有狂的资本
4楼-- · 2019-05-06 22:07

Actually you can. You can use the resulting value for loops or conditionals. You can't use it to initialise objects. (so dynamic arrays fail)

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
} 
查看更多
登录 后发表回答