Table of contents
Code: Wrong data offsets in structure traversalCode: Layout out of order in respect to material parametersCode: Textures in default expression result in multiple entries- Docs: Difference between 'get_target_argument_block' and 'create_target_argument_block' is not sufficiently clear
- Docs: State offset never equals '~mi::State(0)' or '~0u' in traversal
- Docs: Confusing wording, "known" vs. "unknown" resource indices
EDIT: There are some more when using link units, that I’ll group with the link unit issues.
[s]1. Wrong data offsets in structure traversal
Using code to prints the argument block
// ...
called like
Handle< ITarget_argument_block > block_data( /* ... */ );
Handle< ITarget_value_layout > block_layout( /* ... */ );
dump_argument_block( block_layout.get(), block_data->get_data() );
we can observe that structure members always have a zero offset. It could be possible to work around this limitation by adding up the size of previous struct members IFF that size includes padding for alignment. Can you confirm whether this is the case?
Summing up the entires further reveals that we don’t end up at the reported total size of the argument block after traversal.[/s]
[s]2. Layout out of order in respect to material parameters
I could observe a material with ‘color, float3, color’ parameters (in that order) yield a traversal order of ‘color, color, float3’. Since there is no way to acquire the parameter name, this seems to be a show stopper for using target argument blocks right now.[/s]
[s]3. Textures in default expression result in multiple entries
Things get really wild when we have a default expression that contains a texture fetch. Then we get many entries for that texture. The obvious expectation would be that we just get an input of type ‘texture_return’, however, that might be too naive since we might want to let the integrating code know how to wire up that input by default somehow (but the default structurally differs from the input in that case)…[/s]
4. Difference between ‘get_target_argument_block’ and ‘create_target_argument_block’ is not sufficiently clear
In fact, I have yet to figure that one out myself. The current breakage doesn’t exactly make it easy to do that experimentally. What’s the justification for both variants’ existence? Looking at 3, I suspect we might have something conceptually half-baked here.
5. State offset never equals ‘~mi::State(0)’ or ‘~0u’ in traversal
The docs for ‘ITarget_value_layout::get_nested_state’ are lying:
The returned state’s ‘m_state_offs’, being a 32-bit unsigned integer, can never be equal to the 64-bit unsigned integer '~mi::Size(0)` with all bits set and no sign extension happening.
In practice, it also never happens to equal ‘~0u’ (a 32-bit integer with all bits set, which would be an obvious guess under “error correction by common sense”), which can easily be verified with a conditional breakpoint in line 38 of above code.
Just removing that sentence from the docs will fix it.
6. Confusing wording, “known” vs. “unknown” resource indices
Let’s see:
We have a “resource id” by which you identify the resource in your handler code. Then there’s an “index of the resource reference” (with separate index spaces for different types of resources) that describes the use of a resource in MDL target code. The former defaults to the latter, but can be changed in the target argument block if you use class compilation. A callback is provided to map resource paths to ids in this context.
With a wording like that, instead of talking about “known” vs “unknown” resource indices and what is known when, the whole story becomes rather obvious and approximately thousand times easier/faster to grok for the reader.