On Mon Oct 31 23:31:44 2022 +0000, Zebediah Figura wrote:
It's perhaps also worth pointing out that this touches on ongoing
conversations about the HLSL compiler's IRs. We currently essentially go from "HLSL IR" (almost) straight to d3dbc or dxbc-tpf bytecode. However, it turns out there may be some value in introducing an IR between that, on a level slightly higher than vkd3d_shader_instruction. The discussion about that has mostly been along the lines of having separate sm1 and sm4 IR, although it's been vague and I think it's reasonable that we could use a common struct on the same level as vkd3d_shader_instruction instead. I don't think there's any reason that we want anything higher-level than that (with the possible caveat that maybe we want to use pointers rather than register numbers?), particularly because most of the impetus for introducing this new IR is that the current HLSL IR is *too* high-level (e.g. around things like variable loads and stores, and not being able to express the more CISC aspects of the smX assembly, like source modifiers.) Maybe there's an argument to have one or more unified IRs across all of vkd3d-shader? It would be nice in some respects, but I imagine that compilation speed would be a concern. I gather that one reason that the dxbc->glsl/spirv path is arranged the way it is, is that we only want to do one pass over the dxbc, and want to avoid allocating memory as much as we can.
After a signature name is emitted, no realignment occurs. I've raised an issue: https://github.com/microsoft/DirectXShaderCompiler/issues/4755
The idea behind the vkd3d_shader_parser interface is not applicable to DXIL, and existing backends are unusable. The only resemblance DXIL bears to TPF is it ends up doing the same shader operations expressed in the HLSL source. It's much closer to SPIR-V because it uses static single assignment. Instructions don't use registers, and contain none of the information in the 'declaration' union in vkd3d_shader_instruction. This information is contained elsewhere. Reading instructions from a stream of 32-bit words until the end is reached doesn't make sense given the way DXIL is organised. Because vkd3d_shader_parser and the current backends are designed for doing that on a complex instruction set, it won't work for DXIL.
Code for converting TPF to DXIL would probably be at least as complex as the existing SPIR-V backend, possibly more so, and introduce many regressions.
Converting DXIL to TPF may be simpler, but there are still complications. DXIL doesn't use vectors; instead it extracts scalars from any load/sample/read operations which return vectors, and operates on the scalars. We would need to analyse the code and reconstruct vector inputs for each TPF instruction. PHI instructions would need to be replaced with temporary variables. But the most complex problem is building loop, if and else constructs. Hans-Kristian's structuriser probably builds most or all of the needed info but assembling it may turn out to be a major pain. I doubt this route would be less code than a separate backend either.