On Mon Nov 7 06:25:27 2022 +0000, Conor McCarthy wrote:
I wouldn't say the impedance mismatch is minimal, but it's much less than for TPF->SPIR-V. Resource register space/idx are contained in the metadata, and there's a createHandle instruction which is a subset of TPF's DCL_RESOURCE instructions and which results in creation of an id. DCL_RESOURCE must be synthesised with all of the info. Builtins still have mismatches, but because DXIL uses scalars it's trivial to read/write the relevant scalar within the SPIR-V vector. Fixups are no trouble either. DXIL doesn't define anything like a shader phase, and I don't know why they exist in TPF. Tessellation I/O is straightforward.
I have a complete picture of this after dealing with converting DXIL to our existing IR. Introducing new backend functions for SM 6 input/output and eventually fixing up TPF in the frontend to use the new functions is the best solution I think.
- Multiple semantics packed into the same v# register: DXIL refers to inputs/outputs by signature element index rather than register index. The equivalent of a register index in TPF is now a row index, and component index is a column index. Using the element index as a register index in the IR works well, and results in separate declarations for separate elements within the same row. This eliminates the need for a private variable. TPF can be fixed up in the frontend to match this since it expresses the same information but in a messier way. - Registers which are arrayed in spirv but might not be arrayed in sm4: Where a builtin is arrayed in spir-v it is also an array in DXIL, i.e. the declaration has a start row and row count, with a single component on each row. TPF can be converted to this format by merging multiple signature elements. The only backend complication is emitting a zero index when loading from an array of size 1, because DXIL treats it as a scalar in this case but the spir-v variable is still an array. - Hull shader vicp/vocp: These are implicit declarations with no sysval. They are handled pretty simply for SM 6 by emitting an input or output declaration to the IR. No private variable is needed in the backend. The TPF frontend can be fixed up to do this too. - Impedance mismatches between spirv builtins and sm4 builtins/sysvals: It's not complicated to store a fixup_pfn in register_info and apply the fixup on loading. For scalar loads the component index must be passed to the fixup so frag coord w can be handled. For cases where the value is loaded more than once it may be worth caching the result, but in branched shaders the code would have to go in the entry block. - Output swizzle: probably still a private variable.