Ahh, right. To be clear, structs *do* appear in the RDEF, but not in the bound resources list, and sm4_sort_externs() only affects the order of bound resources.
Ah, yes, sorry, the structs indeed appear inside the Buffer definitions (except for their resource elements). I had that considered in following patches.
Actually, I didn't remember or notice, but sm4_sort_externs() only sorts variables with a data type of HLSL_CLASS_OBJECT. We should probably just change that to hlsl_type_is_resource() and then we don't need this check.
Yes, but they still get compared with non-object variables, so these cannot be forgotten in `sm4_compare_externs()`.
Uniform structs containing objects are only allowed in profiles >= 5, and in those profiles these components have to be promoted to individual variables, so they are not to be shown either.
I know that they show up as separate variables in the RDEF section, but I... don't think we actually need to make them separate hlsl_ir_vars, do we? I don't hate the idea, but let me pitch an alternative to see if it's more appealing:
Thinking out loud here, but what if we did multiple passes over the extern vars list—sampler, then texture, then UAV or whatever the order is—and instead of the aforementioned "hlsl_type_is_resource()" check for sorting it'd become "var->regs[regset].allocated"?
We already do 3 "passes" over ctx->extern_vars (one for the count, one to write most of the data, one to write the strings) and this would make that uglier, but we could, say, build some sort of temporary array first instead, and that might help a bit. (And that would also sort of collapse the cbuffer/resource difference a bit.)
Well, I don't think that making separate variables at this point of the compilation is too ugly (FTR, [this](https://gitlab.winehq.org/fcasas/vkd3d/-/commit/50c5816af8a7370bf0851943855a...) is my current implementation).
I understand your idea though: we would be putting most of the code of `write_sm4_rdef` inside a loop that iterates regsets, and we would be sorting on each iteration, according to the allocated id of the variables in that regset.
A benefit I can think on, of separating variables, is that we recover the data type of the referenced component, which is lost when the deref is turned into a single offset, i.e. we can keep using `deref->var->data_type` in our functions to write the different types of IR nodes. But it is not that we can't implement a function to iterate the type for recovering it from the offset, or, with a lot more work, making path derefs reach this part of the code.
I will give it more thought, since I don't have a strong preference for either option yet. Perhaps we should discuss it once we reach that patch and not in this MR, though.