vkd3d-shader/ir: Normalise signatures and input/output registers to the Shader Model 6 pattern.

In Shader Model 6 each signature element can span a range of register
indices, or 'rows', and system values do not share a register index with
non-system values. Inputs and outputs are referenced by element index
instead of register index. This patch merges multiple signature elements
into a single element under the following conditions:

- The register index in a load or store is specified dynamically by
  including a relative address parameter with a base register index. The
  dcl_index_range instruction is used to identify these.
- A register declaration is split across multiple elements which declare
  different components of the register.
- A patch constant function writes tessellation factors. These are an
  array in SPIR-V, but in SM 5.x each factor is declared as a separate
  register, and these are dynamically indexed by the fork/join instance
  id. Elimination of multiple fork/join phases converts the indices to
  constants, but merging the signature elements into a single arrayed
  element matches the SPIR-V output.

All references to input/output register indices are converted to element
indices. If a relative address is present, the element index is moved up
a slot so it cannot be confused with a constant offset. Existing code
only handles register index relative addressing for tessellation factors.
This patch adds generic support for it.
This commit is contained in:
Conor McCarthy
2023-04-26 15:27:08 +10:00
committed by Alexandre Julliard
parent 110e48e54d
commit 6835e8176f
Notes: Alexandre Julliard 2023-05-24 22:33:51 +02:00
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/181
5 changed files with 859 additions and 484 deletions

View File

@@ -373,6 +373,8 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
{
uint32_t name_offset, mask;
e[i].sort_index = i;
if (has_stream_index)
read_dword(&ptr, &e[i].stream_index);
else