Well, we'd want it to return the same information as we'd get when first compiling to TPF or d3dbc and then scanning the resulting shader. (And the straightforward though perhaps not entirely optimal way to implement HLSL scans would of course be to do just that.) That does imply that e.g. the HLSL target profile may make a difference.
This probably fundamentally comes down to the points raised below, but this especially doesn't make sense to me. It doesn't seem consistent that we'd return information about the DXBC shader for a DXBC shader, but information *also* about the DXBC shader for an HLSL shader. It's also completely redundant; if someone really wants information about the DXBC shader, she can just compile to DXBC first.
Perhaps the discussion is getting a bit too abstract, and maybe that's a point in favour of your point of view. Regardless, the way I look at it is that a shader is a set of operations to be performed by a GPU (which may in fact end up being a CPU, but anyway...), and both the source and target shader are different representations of the same set of operations; at the same time, that set of operations isn't necessarily fully defined by the original source code, and that's where the additional source/target info comes in. The implication would be that [HLSL->SPIR-V] should return the same information as [HLSL->TPF->SPIR-V] given the same/equivalent compilation options. I.e., we are just as much returning information about the target SPIR-V as we're returning information about the source HLSL or TPF.
I don't know; I think that over the years I've come to appreciate the fact that ambiguity is the glue that holds many things together. :)
This may end up being a sticking point, if not here than in the future. I don't understand this viewpoint at all. Having consumed a dozen APIs by this point this is consistently the thing that distinguishes the pleasant ones (Vulkan, X11) from the unpleasant ones (GStreamer, all of Win32). Finding out there's no way to perform some task is frustrating, but wasting time trying to figure out whether I can perform some task—and then later worrying about whether the approach taken is safe—is worse. Or wasting time trying to guess whose bug something is and how it should be fixed.
Vagueness makes things nice for the implementers, but it has always made my life unpleasant as a consumer. I intend to argue as hard as I can for putting the consumer first in any API I design. With all of that said, I certainly haven't been programming as long as you, and if it can be communicated I'd definitely like to understand why vagueness can be a good thing (or inevitable, or whatever it is).
Sorry, I didn't mean to imply being vague in the API documentation was desirable or appropriate here; I was just making a rather general comment in reply to a fairly broad statement. :)
To be clear, I think accurate, unambiguous, complete API documentation is an immense asset.
I tend to think of vkd3d_shader_scan() as providing the information needed to use the shader in the target environment. (And note that the function fairly deliberately takes a vkd3d_shader_compile_info structure as its input.) For modern formats like TPF and DXIL that can largely be derived purely from the original shader source; for something like d3dbc there is a lot more implicit state (e.g., fixed-function fog state) provided by the environment, as I'm sure you've already encountered.
There may be value in providing information purely about the original shader in its original intended environment, and we could potentially support that in vkd3d_shader_scan() by supporting VKD3D_SHADER_TARGET_NONE as target, but it's not quite how vkd3d_shader_scan() is currently intended.
This doesn't seem intuitive to me at all, and I don't think it's how API users are going to interpret vkd3d_shader_scan(), despite the function signature. I think this also makes vkd3d-shader more confusing, if we're introducing behaviour that's implicit on the target type or environment. It's more to keep track of for the implementer and the user. *Especially* if we aren't going to explicitly document these "implementation details"—that's a sure way to confuse a user about "why is vkd3d-shader returning different data between these two cases?"
I fear you may be right, if perhaps largely by the fact that we're having this discussion.
And it seems like scope creep. I don't want to argue about this point because I don't think the scope can be rigidly defined, but I think trying to change information about the shader we return *based on* the target environment seems to me like it's outside of the scope of a shader manipulation library. Let the API user change BLENDINDICES if they want to.
There are implications to that though.
Suppose we invent this imaginary graphics API; we could call it the "Fairly Interactive Graphics System", because figs are delicious. We'll make it accept SPIR-V—because, why not?—and add VKD3D_SHADER_SPIRV_ENVIRONMENT_FIGS_1_0 to vkd3d-shader. Due to an unfortunate oversight, FIGS 1.0 doesn't support scaled floating-point vertex attribute formats, so we decide that it would be most appropriate for vkd3d-shader to translate d3dbc BLENDINDICES inputs to pure integer inputs when targetting FIGS 1.0. So far, so good.
Now we're going to port an application to the brand new FIGS 1.0 API, and it uses these d3dbc shaders. Since vkd3d-shader supports translating them to SPIR-V we figure we might as well use them, instead of spending a bunch of time writing brand new shaders using spirv-as. ;) So we use vkd3d_shader_scan() to retrieve the information needed to setup our resource and attribute bindings, and we use vkd3d_shader_compile() to generate a corresponding SPIR-V shader. We run our application, and... all our character models are weird. [Debugging session omitted for brevity.] As it turns out, we should have ignored vkd3d_shader_scan() telling us BLENDINDICES receives floating-point data and sent pure integers instead.
So we go through the data we receive from vkd3d_shader_scan(), fix it up, and now everything works well enough to ship the application. :) That's not an entirely satisfying solution though, because now we're relying on vkd3d-shader internals in our application. The vkd3d-shader API documentation doesn't promise this is something we can rely on, but hopefully they'll remember not to break this... right?
So where did things go wrong?
**Obviously, we should have called vkd3d_shader_scan() on the resulting SPIR-V instead of the d3dbc source.** Possibly, except that vkd3d-shader doesn't support SPIR-V as a source format. **So vkd3d-shader should just add that, right?** Sure, it could. But that then implies it should accept any target format as source format as well. And while parsing SPIR-V is relatively straightforward, that's not necessarily true for something like GLSL or MSL.
**Obviously, we should have used SPIRV-Reflect instead of vkd3d-shader to get this information.** Sure, that works. In that case we're adding an extra dependency just to workaround a relatively minor issues though. And what is the point of providing vkd3d_shader_scan() then? If we were going to run the original source shaders we wouldn't have needed vkd3d-shader to translate them to SPIR-V...
**Obviously, we should have used our own shader I/O metadata embedded in our application's assets.** Yeah, that works too. Unfortunately the metadata was lost in an accident several years ago, along with the Cg source for the shaders. Also, what is the point of vkd3d_shader_scan() then?
**Obviously, vkd3d-shader should have left BLENDINDICES alone.** Well, that means potentially converting vertex data at runtime in the application. A bunch of extra code, and likely some performance impact. **How about making it a vkd3d_shader_compile_option instead of changing behaviour based on VKD3D_SHADER_SPIRV_ENVIRONMENT_FIGS_1_0?** Maybe that's better, but it doesn't change the fundamental problem; we're still not going to get the information we want from vkd3d_shader_scan().
**Clearly we should have written new shaders using spirv-as instead of using vkd3d-shader.** That would be a bit of an unfortunate conclusion...