On Thu Nov 9 19:54:26 2023 +0000, Zebediah Figura wrote:
What about types other than 'c'? I know 'i' and 'b' do something that we don't implement [and should maybe have a hlsl_fixme() for]; what about invalid types?
I did manual testing and got to the following (I hope correct) conclusions:
The data type of the variable of each variable doesn't matter directly, it only matters whether its usage needs it to be passed in the 'c', 'i', or 'b' register group (as they are called on error messages).
Most variables are needed in the 'c' register group (used for floating point ops), if the variable is needed in the 'c' register group another reservation like `register(iX)` or `register(bX)` cannot be passed unless `register(cX)` is also provided.
As you have discovered, the need for the variable to be on the 'i' group can be forced using a 'for' loop.
Some examples:
The following shader results in the following error: ``` error X4509: invalid register semantic 'i0', or variable must be bound to multiple register banks (c register binding required) ``` ```hlsl int k : register(i0);
float4 main() : sv_target { return k; } ```
So, some `register(cX)` must be also provided for it to compile: ```hlsl int k : register(i0) : register(c1);
float4 main() : sv_target { return k; } ```
The 'b' group seems to be bound to the same rules as the 'i' group, it is allowed to pass `register(bX)` to any variable regardless of the type but, like for the 'i' group, if it is needed in the 'c' register group, a `register(cX)` must be specified.
This shader is exceptional because the variable 'k' is only needed in the 'i' group, so in this rare case a `register(cX)` is not necessary: ```hlsl int k : register(i0);
float4 main() : sv_target { float f = 0;
for (int i = 0; i < k; ++i) f += i; return f; } ```
The converse is not true, if a variable is needed in the 'i' register group any other reservation is allowed:
```hlsl int k : register(c0) : register(b0);
float4 main() : sv_target { float f = 0;
for (int i = 0; i < k; ++i) f += i; return f; } ```
Besides 'i', 'b', and 'c', the 's', 't', and 'u' register groups are also valid regardless of the variable type. The 's' register group is required for used samplers if another reservation is specified. The remaining letters result in an error.
SM4 is a lot more permissive, and any letter can be used. I would prefer for us to also be permissive for SM1, and basically ignore unused register() reservations and don't error out when register(cX) reservations are not provided if any other is.
If we choose to be permissive, should these tests be included or not?