Skip to content

vkd3d-shader/hlsl: Implement copy-prop of derefs with a non-constant index.

We implement a transformation that propagates loads with a single non-constant index in its deref path. Consider a load of the form var[[a0][a1]...[i]...[an]], where ak are integral constants, and i is an arbitrary non-constant node. If, for all j, the following holds:

  var[[a0][a1]...[j]...[an]] = x[[c0*j + d0][c1*j + d1]...[cm*j + dm]],

where ck, dk are constants, then we can replace the load with x[[c0*i + d0]...[cm*i + dm]]. This pass is implemented by copy_propagation_replace_with_deref().

This is especially helpful for, for example, hull shaders, where the input patch is often accessed with a non-constant index.


Consider the following hull shader:

struct hs_data
{
    float4 pos : SV_Position;
    float4 color : COLOR;
};
struct patch_constant_data
{
    float edges[2] : SV_TessFactor;
};

patch_constant_data patch_constant()
{
    return (patch_constant_data)1;
}

[domain("isoline")]
[outputcontrolpoints(3)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
hs_data main(InputPatch<hs_data, 3> patch, uint i : SV_OutputControlPointID)
{
    return patch[i];
}

Before this MR, the main function gets compiled to the following HLSL IR:

 1:      uint1 | <input-SV_OutputControlPointID0>[0c]
 2:     float4 | <inputpatch-SV_Position0>[0c]
 3:     float4 | <inputpatch-COLOR0>[0c]
 4:     float4 | <inputpatch-SV_Position0>[4c]
 5:     float4 | <inputpatch-COLOR0>[4c]
 6:     float4 | <inputpatch-SV_Position0>[8c]
 7:     float4 | <inputpatch-COLOR0>[8c]
 8:            | = (<index-val-4>[0c] @2)
 9:            | = (<index-val-4>[4c] @3)
10:            | = (<index-val-4>[8c] @4)
11:            | = (<index-val-4>[12c] @5)
12:            | = (<index-val-4>[16c] @6)
13:            | = (<index-val-4>[20c] @7)
14:       uint | 2
15:       uint | * (@1 @14 )
16:     float4 | <index-val-4>[@15]
17:       uint | 2
18:       uint | * (@1 @17 )
19:       uint | 1
20:       uint | + (@18 @19 )
21:     float4 | <index-val-4>[@20]
22:            | = (<output-SV_Position0>[0c] @16)
23:            | = (<output-COLOR0>[0c] @21)

Now we get:

1:      uint1 | <input-SV_OutputControlPointID0>[0c]
2:     float4 | <inputpatch-SV_Position0>[@1]
3:     float4 | <inputpatch-COLOR0>[@1]
4:            | = (<output-SV_Position0>[0c] @2)
5:            | = (<output-COLOR0>[0c] @3)
Edited by Shaun Ren

Merge request reports

Loading