vkd3d/tests/object-references.shader_test
Giovanni Mascellani d2f8a576a8 vkd3d-shader/hlsl: Avoid infinite loop and invalid derefs in copy-prop.
Co-authored-by: Francisco Casas <fcasas@codeweavers.com>
Co-authored-by: Zebediah Figura <zfigura@codeweavers.com>

Because copy_propagation_transform_object_load() replaces a deref
instead of an instruction, it is currently prone to two problems:

1- It can replace a deref with the same deref, returning true every
time and getting the compilation stuck in an endless loop of
copy-propagation iterations.

2- When performed multiple times in the same deref, the second time it
can replace the deref with a deref from a temp that is only valid in
another point of the program execution, resulting in an incorrect value.

This patch preempts this by avoiding replacing derefs when the new deref
doesn't point to a uniform variable. Because, uniform variables cannot
be written to.
2023-01-26 21:52:07 +01:00

241 lines
3.6 KiB
Plaintext

[pixel shader fail]
sampler sam;
float4 main() : sv_target
{
Texture2D tex;
tex = tex; // Uninitialized assignment to self.
return tex.Sample(sam, float2(0, 0));
}
[require]
shader model >= 4.0
[texture 0]
size (1, 1)
0.77 0.77 0.77 0.77
[texture 1]
size (1, 1)
0.64 0.64 0.64 0.64
[sampler 0]
filter linear linear linear
address clamp clamp clamp
[pixel shader]
Texture2D t_good, t_bad;
sampler sam;
float4 main() : sv_target
{
Texture2D a, b[1];
// This is basically a 'b[0] = t_good' but so that the copy-prop is delayed
int4 co = {0, 0, 0, 0};
b[(int) co.x + (int) co.y] = t_good;
a = b[0];
b[0] = t_bad;
// 'a' should be 't_good', not 't_bad' at this point
return 100 * a.Sample(sam, float2(0, 0)) + t_good.Sample(sam, float2(0, 0));
}
[test]
draw quad
probe all rgba (77.77, 77.77, 77.77, 77.77)
[texture 0]
size (2, 2)
0.1 0.2 0.3 0.4 0.5 0.7 0.6 0.8
0.6 0.5 0.2 0.1 0.8 0.0 0.7 1.0
[pixel shader]
Texture2D t;
struct foo {
int3 a;
Texture2D b;
};
float4 main(float4 pos : sv_position) : sv_target
{
struct foo q;
q.a = int3(pos.xy, 0);
q.b = t;
return q.b.Load(q.a);
}
[test]
draw quad
probe (0, 0) rgba (0.1, 0.2, 0.3, 0.4)
probe (1, 0) rgba (0.5, 0.7, 0.6, 0.8)
probe (0, 1) rgba (0.6, 0.5, 0.2, 0.1)
probe (1, 1) rgba (0.8, 0.0, 0.7, 1.0)
[texture 0]
size (1, 1)
1.0 1.0 1.0 1.0
[texture 1]
size (1, 1)
2.0 2.0 2.0 1.0
[texture 2]
size (1, 1)
3.0 3.0 3.0 1.0
[pixel shader todo]
Texture2D tex[3];
struct foo {
float4 p;
Texture2D t;
};
float4 main() : sv_target
{
struct foo s[3];
s[0].t = tex[0];
s[1].t = tex[1];
s[2].t = tex[2];
return 100 * s[2].t.Load(0) + 10 * s[0].t.Load(0) + s[1].t.Load(0);
}
[test]
todo draw quad
todo probe all rgba (312, 312, 312, 111)
[pixel shader]
Texture2D tex1;
Texture2D tex2;
Texture2D tex3;
float4 main() : sv_target
{
Texture2D t[3][2];
t[0][0] = tex1; // Note: Only invalid in shader model 5.1, array ref. cannot be used as l-value.
t[0][1] = tex2;
t[1][0] = tex3;
t[1][1] = tex1;
t[2][0] = tex2;
t[2][1] = tex3;
return 1000 * t[2][0].Load(0) + 100 * t[1][1].Load(0) + 10 * t[2][1].Load(0) + t[0][1].Load(0);
}
[test]
draw quad
probe all rgba (2132, 2132, 2132, 1111)
[pixel shader fail]
Texture2D tex[3];
uniform int n;
struct foo {
float4 p;
Texture2D t;
};
float4 main() : sv_target
{
struct foo s[3];
s[0].t = tex[0];
s[1].t = tex[1];
s[2].t = tex[2];
return s[n].t.Load(0);
}
[pixel shader fail]
// Note: Only valid in shader model 5.1
Texture2D tex[3];
uniform int n;
float4 main() : sv_target
{
return tex[n].Load(0);
}
[pixel shader fail]
// Note: Only valid in shader model 5.1
RWTexture2D<float4> tex[3];
uniform int n;
float4 main() : sv_target
{
tex[n][int2(0, 0)] = 0.6;
return 0;
}
[pixel shader]
Texture2D tex;
uniform float f;
struct apple
{
Texture2D tex1;
Texture2D tex2;
float3 aa;
};
float4 main() : sv_target
{
struct apple a = {tex, tex, 1.0, 2.0, 3.0};
a.aa += f;
return a.aa.xyzx;
}
[test]
uniform 0 float 10.0
draw quad
probe (0, 0) rgba (11.0, 12.0, 13.0, 11.0)
[pixel shader fail]
float4 main(Texture2D tex2) : sv_target
{
Texture2D tex1;
tex2 = tex1;
return tex2.Load(int3(0, 0, 0));
}
[require]
shader model >= 5.0
[texture 0]
size (1, 1)
1.0 2.0 3.0 4.0
[pixel shader todo]
struct apple {
Texture2D tex;
float4 fo : COLOR;
};
float4 main(struct apple input) : sv_target
{
input.tex = input.tex; // Assignment to self.
return input.tex.Load(int3(0, 0, 0));
}
[test]
todo draw quad
todo probe (0, 0) rgba (1.0, 2.0, 3.0, 4.0)