On 9/23/22 14:14, Francisco Casas wrote:
+ while (store_index < size) + hlsl_initialize_var_components(ctx, broadcast_instrs, var, &store_index, cast->operands[0].node);
You're only initializing from a single component, so you should just be able to use hlsl_new_cast() plus hlsl_new_store_component(). [Note we probably want to use hlsl_new_cast() rather than add_implicit_conversion(), mostly because the difference is type checking, and we should already have done that.]
A reason for using initialize_var_components() (and thus, add_implicit_conversion()), is that if dst_type is a struct that contains an object type, the broadcast should fail.
The alternative could be adding checks for these cases in the functions for checking compatible data types, but this may require more heavy thought.
I think that's the right place to do it, yes. There may be an argument to changing the way that compatible_data_types() / implicit_compatible_data_types() / add_cast() are organized, but ultimately I think we want to do the check in one of those places.
Note also that initialize_var_components() ultimately ends up calling add_cast(), so e.g. v2 will recurse, which is probably best avoided.
(Side note: do we have a test for that object-broadcast failure?)
P.S. I realized that, in native, it is a allowed to casts from a complex type to another "component-wise-compatible" complex type.
For instance, the following shader compiles in native:
struct apple { Texture2D tex; float2 col1; float2 col2; };
struct banana { Texture2D rex; float4 color; };
Texture2D tex;
float4 PSMain() : SV_TARGET { struct apple a1 = {tex, 1, 2, 3, 4}; struct banana b1 = (struct banana)a1; return b1.color + b1.rex.Load(int3(0, 1, 2)); }
Sounds familiar :-)
Actually, doesn't this already work, what with your recent initializer patches?