Porting Direct3D 11 to Metal : How to handle Input Layouts?

Started by
0 comments, last by zealouselixir 7 years, 9 months ago

In Metal, MTLVertexDescriptor + [[stage_in]] is very similar to input layout in DX11, but [[ stage_in ]] does not support packed vector type, why?

The problem is metal::float3 need to be align on 16Byte boundary, while metal::packed_float3 does not.

If i don't use [[ stage_in ]], vertex buffer and constant buffer will be forced to use the same [[ buffer(...) ]] name space, while in DX11 constant has it's own namespace, which means the same cb would have to use different index in DX and metal shader.

Any suggestions? Thank you!

Advertisement

[[stage_in]] doesn't support packed types, but you can get the same effect using the properties of your vertex descriptor's attributes. For example, if you wanted [[attribute(0)]] (which might represent position) to be laid out as three packed floats followed immediately by [[attribute(1)]] (which might represent a surface normal), also consisting of three packed floats, you'd just set the formats and offsets correspondingly, ensuring that your buffer data is packed as described:


vertexDesc.attributes[0].format = MTLVertexFormatFloat3;
vertexDesc.attributes[0].offset = 0;
vertexDesc.attributes[0].bufferIndex = 0;
vertexDesc.attributes[1].format = MTLVertexFormatFloat3;
vertexDesc.attributes[1].offset = sizeof(float) * 3;
vertexDesc.attributes[1].bufferIndex = 0;
The struct that you use as the type of your stage_in vertex function parameter will still have each of these members aligned to 4 bytes, as you observe, but the properties will be fetched from the buffer according to the specified vertex descriptor, allowing you to store your data tightly packed.
HTH,
ZE

[twitter]warrenm[/twitter]

This topic is closed to new replies.

Advertisement