There are a couple of cases where we can't use immediates though; relative addressing of constants is one case, and having non-finite values without GL_ARB_shader_bit_encoding is another.
The non-finite values part makes sense to me, but I don't see how relative addressing would require uniforms: is it not possible in GLSL to declare a const array of values and dynamically index that? Or are there actually applications that require dynamically indexing such that we need to return both internal and external constants?
As far as I know nothing prevents an application from mixing these, and it was not uncommon for shader model 1-3 shaders to be written in assembler, so "the HLSL compiler never generates mixed accesses" wouldn't generally be sufficient to stop us from worrying about them.
It's perhaps also worth pointing out that Direct3D 8 can load shader constants from the vertex declaration using "D3DVSD_CONST"; we have a couple of examples of that in the Wine d3d8 tests.
Is there any reason we can't just implement that on top of wined3d_stateblock_set_vs_consts_f() these days?
It might be possible. The tricky part is probably mostly that D3DVSD_CONST constants override those set by SetVertexShaderConstant(), but we should still need to keep track of constants set by SetVertexShaderConstant() for when we switch vertex shaders.
+ /** + * Register index of the Direct3D resource. + * + * When mapping legacy Direct3D constants to constant buffers in the target + * environment, this parameter instead names the register set to map, and + * must be a member of enum vkd3d_shader_d3dbc_constant_register. + */
The clarification here seems helpful, but I'm not sure I agree with "instead". From the point of view of struct vkd3d_shader_resource_binding this is consistent with the existing usage of the structure; we map the different d3dbc constant files to CBVs, and then simply specify the register indices of those CBVs here.
It's a CBV slot, yeah, and it makes a lot of sense that way. But the name of the parameter is register_index, and in sm4 it always is a register index (one of two in the case of constant buffers, perhaps), whereas in sm1 the distinction between "b*" / "c*" / "i*" is not one of register index; it is rather a distinction of register set.
Saying that this describes a "register index", for someone familiar with sm1, would be confusing; it'd imply the distinction between "c0" and "c1", which it doesn't. Changing the documentation to eschew the term "register index" in favor of something more neutral like "CBV slot" might help, but the parameter name is still register_index. I want to be clear about what this actually is, so that someone setting up their bindings knows exactly which binding they're setting up.
Right, as I said, the clarification is probably helpful. I'd just prefer phrasing it as something along the lines of "Note that vkd3d-shader maps constant registers in d3dbc sources to CBV registers in the following way: ..., so use enum vkd3d_shader_d3dbc_constant_register here for those.", in order to avoid (seemingly) implying that the "register_index" field works in a fundamentally different way for d3dbc sources.