Can I get the size of a buffer from my Metal shader?

混江龙づ霸主 提交于 2019-12-22 08:36:45

问题


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?


回答1:


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.




回答2:


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.




回答3:


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
} 


来源:https://stackoverflow.com/questions/26461063/can-i-get-the-size-of-a-buffer-from-my-metal-shader

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!