简体   繁体   中英

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

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?

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.

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
} 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM