vkd3d/tests/hlsl/register-reservations-numeric.shader_test

949 lines
14 KiB
Plaintext
Raw Normal View History

[pixel shader fail(sm<6)]
2023-11-08 19:00:27 -03:00
// Overlapping register(cX) reservations are not allowed except on SM6, where they are aliased.
// On SM1 this gives hr 0x88760b59.
float a : register(c0);
float b : register(c0);
float4 main() : sv_target
{
return a + b;
}
[pixel shader]
// It is not required to provide a register(cX) for all elements in the $Globals buffer.
float4 a; // will get register(c1)
float4 b : register(c0);
float4 main() : sv_target
{
return float4(a.xw, b.yz);
}
[test]
uniform 0 float4 0.1 0.2 0.3 0.4
uniform 4 float4 1.1 1.2 1.3 1.4
todo(glsl) draw quad
probe (0, 0) rgba (1.1, 1.4, 0.2, 0.3)
2023-11-08 19:00:27 -03:00
[pixel shader]
float4 a[3]; // will get register(c3)
float4 b[2] : register(c1);
float4 main() : sv_target
{
return float4(a[1].xy, b[0].zw);
}
[test]
uniform 0 float4 0.1 0.2 0.3 0.4
uniform 4 float4 1.1 1.2 1.3 1.4
uniform 8 float4 2.1 2.2 2.3 2.4
uniform 12 float4 3.1 3.2 3.3 3.4
uniform 16 float4 4.1 4.2 4.3 4.4
todo(glsl) draw quad
probe (0, 0) rgba (4.1, 4.2, 1.3, 1.4)
2023-11-08 19:00:27 -03:00
[require]
shader model < 4.0
[pixel shader]
float a : register(c2);
float b; // will get register c0 in SM1
float4 main() : sv_target
{
return float4(a, b, 0.0, 0.0);
}
[test]
uniform 0 float4 0.1 0.2 0.3 0.4
uniform 4 float4 1.1 1.2 1.3 1.4
uniform 8 float4 2.1 2.2 2.3 2.4
uniform 12 float4 3.1 3.2 3.3 3.4
draw quad
probe (0, 0) rgba (2.1, 0.1, 0.0, 0.0)
2023-11-08 19:00:27 -03:00
[require]
shader model >= 4.0
[pixel shader]
float a : register(c2);
float b; // will get offset equivalent to c2.y in SM4 and SM6
float4 main() : sv_target
{
return float4(a, b, 0.0, 0.0);
}
[test]
uniform 0 float4 0.1 0.2 0.3 0.4
uniform 4 float4 1.1 1.2 1.3 1.4
uniform 8 float4 2.1 2.2 2.3 2.4
uniform 12 float4 3.1 3.2 3.3 3.4
todo(glsl) draw quad
probe (0, 0) rgba (2.1, 2.2, 0.0, 0.0)
2023-11-08 19:00:27 -03:00
[require]
shader model >= 6.0
[pixel shader]
// Variables with overlapping register(cX) reservations are aliased in SM6.
float2 a : register(c2);
float3 b : register(c2);
float4 main() : sv_target
{
return float4(a, b.yz);
}
[test]
uniform 0 float4 0.1 0.2 0.3 0.4
uniform 4 float4 1.1 1.2 1.3 1.4
uniform 8 float4 2.1 2.2 2.3 2.4
draw quad
probe (0, 0) rgba (2.1, 2.2, 2.2, 2.3)
2023-11-08 19:00:27 -03:00
% Results differ between SM1 and SM4 because in the latter variables can share the same register,
% using different writemasks.
[require]
shader model < 4.0
[pixel shader]
struct
{
float2 a;
float b;
} apple : register(c2);
float4 main() : sv_target
{
return float4(apple.a, apple.b, 0);
}
[test]
uniform 0 float4 0.1 0.2 0.3 0.4
uniform 4 float4 1.1 1.2 1.3 1.4
uniform 8 float4 2.1 2.2 2.3 2.4
uniform 12 float4 3.1 3.2 3.3 3.4
draw quad
probe (0, 0) rgba (2.1, 2.2, 3.1, 0.0)
2023-11-08 19:00:27 -03:00
[require]
shader model >= 4.0
[pixel shader]
struct
{
float2 a;
float b;
} apple : register(c2);
float4 main() : sv_target
{
return float4(apple.a, apple.b, 0);
}
[test]
uniform 0 float4 0.1 0.2 0.3 0.4
uniform 4 float4 1.1 1.2 1.3 1.4
uniform 8 float4 2.1 2.2 2.3 2.4
uniform 12 float4 3.1 3.2 3.3 3.4
todo(glsl) draw quad
probe (0, 0) rgba (2.1, 2.2, 2.3, 0.0)
2023-11-08 19:00:27 -03:00
[pixel shader]
// On SM4, register(cX) has no effect unless in the $Globals buffer.
cbuffer extra
{
float a : register(c1);
};
float4 main() : sv_target
{
return a;
}
[test]
uniform 0 float 100
uniform 4 float 101
todo(glsl) draw quad
probe (0, 0) rgba (100, 100, 100, 100)
2023-11-08 19:00:27 -03:00
[pixel shader fail(sm>=6)]
// On SM4 register(cX) has no effect unless in the $Globals buffer.
float4 main(uniform float a : register(c1)) : sv_target
{
return a;
}
[test]
uniform 0 float 100
uniform 4 float 101
todo(glsl) draw quad
probe (0, 0) rgba (100, 100, 100, 100)
2023-11-08 19:00:27 -03:00
[pixel shader todo]
cbuffer c
{
float a : packoffset(c1);
float b : packoffset(c2) : register(c1);
// ^ register(c1) ignored for cbuffer that is not $Globals.
}
float4 main() : sv_target
{
return float4(a, b, 0, 0);
}
[test]
uniform 0 float 200
uniform 4 float 201
uniform 8 float 202
todo(sm<6) draw quad
todo(sm<6) probe (0,0) rgba (201.0, 202.0, 0.0, 0.0)
2023-11-08 19:00:27 -03:00
[pixel shader fail(sm<4)]
int k : register(i0); // register(cX) is also required.
float4 main() : sv_target
{
return k;
}
[require]
% All shader models.
% In SM1, most variables are needed in the "c" register group, for float operations.
% If a variable is needed in the "c" register group, register() reservations in other groups can be
% provided only if a register(cX) reservation is also provided.
[pixel shader fail(sm<4) todo(sm<4)]
int k : register(i0);
// ^^ register(cX) is also required in SM1.
float4 main() : sv_target
{
return k;
}
[pixel shader todo]
int k : register(i0) : register(c1);
// Shader compiles because a "c" register reservation is provided for "k".
float4 main() : sv_target
{
return k;
}
[require]
shader model >= 3.0
% model 2.0 doesn't support unrollable loops.
[pixel shader todo(sm<4)]
int k : register(i0);
// ^^ register(cX) is not required since "k" is just needed in the "i" register group.
float4 main() : sv_target
{
float f = 0;
for (int i = 0; i < k; ++i)
f += i;
return f;
}
[pixel shader todo]
int k : register(c0) : register(b0);
// ^^ unlike the "c" register group, a reservation is not required for the "i" group, even though "k" is needed on it.
float4 main() : sv_target
{
float f = 0;
for (int i = 0; i < k; ++i)
f += i;
return f;
}
% Expressions as offsets.
[require]
% All shader models.
[pixel shader]
// no offset at all, implicitly c0.
float a : register (c);
float4 main() : sv_target
{
return a;
}
[test]
uniform 0 float 1.0
todo(glsl) draw quad
probe (0, 0) rgba (1.0, 1.0, 1.0, 1.0)
[pixel shader]
// Numeric expr, no offset in the identifier. DXC ignores this.
float a : register (c[1 + 1 * 2 * 0]);
float4 main() : sv_target
{
return a;
}
[test]
uniform 0 float 1.0
uniform 4 float 2.0
todo(glsl) draw quad
if(sm<6) probe (0, 0) rgba (2.0, 2.0, 2.0, 2.0)
if(sm>=6) probe (0, 0) rgba(1.0, 1.0, 1.0, 1.0)
[pixel shader]
// Numeric expr. DXC also ignores this.
float a : register (c0[1 + 1 * 2 * 0]);
float4 main() : sv_target
{
return a;
}
[test]
uniform 0 float 0.0
uniform 4 float 1.0
todo(glsl) draw quad
if(sm<6) probe (0, 0) rgba (1.0, 1.0, 1.0, 1.0)
if(sm>=6) probe (0, 0) rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader]
// Float offsets truncate.
float a : register (c0[0.6 + 0.6]);
float4 main() : sv_target
{
return a;
}
[test]
uniform 0 float 0.0
uniform 4 float 1.0
todo(glsl) draw quad
if(sm<6) probe (0, 0) rgba (1.0, 1.0, 1.0, 1.0)
if(sm>=6) probe (0, 0) rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader]
// Booleans are interpreted as integers in the usual way.
float a : register (c0[true + false * true]);
float4 main() : sv_target
{
return a;
}
[test]
uniform 0 float 0.0
uniform 4 float 1.0
todo(glsl) draw quad
if(sm<6) probe (0, 0) rgba (1.0, 1.0, 1.0, 1.0)
if(sm>=6) probe (0, 0) rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader fail(sm>=6)]
// Negative offsets. DXC fails to compile this.
float a : register (c2[-1]);
float4 main() : sv_target
{
return a;
}
[test]
uniform 4 float 1.0
todo(glsl) draw quad
probe (0, 0) rgba (1.0, 1.0, 1.0, 1.0)
% Weird FXC behavior.
% SM4 accepts anything for 'b' reservations and discards it silently for global numeric variables.
[pixel shader fail(sm<4 | sm>=6)]
float a : register(banana);
float4 main() : sv_target
{
return a;
}
[test]
uniform 0 float 1.0
todo(glsl) draw quad
probe (0, 0) rgba(1.0, 1.0, 1.0, 1.0)
% Testing other reservation types. This is a parse failure, i.e "X3530: register sa not valid"
[pixel shader fail]
sampler s : register(samply);
float4 main() : sv_target
{
return tex2D(s, float2(0, 0));
}
% This seems to parse fine, but fails with a different error message: "X3530: sampler requires an 's' or 't' register".
% Resource types probably have extra validation.
[pixel shader fail]
sampler s : register(banana);
float4 main() : sv_target
{
return tex2D(s, float2(0, 0));
}
% Trailing characters after the reservation index are okay in SM < 6, except for 'b' reservations
[pixel shader fail(sm>=6)]
float a : register(c1manymanyletters);
float4 main() : sv_target
{
return a;
}
[test]
uniform 0 float 0.0
uniform 4 float 2.0
todo(glsl) draw quad
probe (0, 0) rgba(2.0, 2.0, 2.0, 2.0)
[require]
shader model >= 4.0
[pixel shader fail]
cbuffer buf : register(b0manymanyletters)
{
float a;
}
float4 main() : sv_target
{
return a;
}
% SM4 fails, but not during parsing: it tries to reserve slot 4294967295 (i.e UINT_MAX) for the constant buffer.
% It'll attempt to reserve the same slot even if an offset is passed in brackets, which suggests it uses -1
% as a "parsing failure" flag.
% DXC fails during parsing.
[pixel shader fail]
cbuffer buf : register(banana)
{
float a;
}
float4 main() : sv_target
{
return a;
}
% Some versions of fxc's SM5.1 completely ignore bracket exprs for samplers and textures.
% This was fixed (?) in later versions.
[sampler 0]
filter linear linear linear
address clamp clamp clamp
[sampler 1]
filter point point point
address clamp clamp clamp
[srv 0]
size (2d, 1, 2)
0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
[srv 1]
size (2d, 1, 2)
1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0
[require]
shader model >= 4.0
[pixel shader]
Texture2D tex : register(t[1]);
sampler sam : register(s[1]);
float4 main() : sv_target
{
return tex.Sample(sam, float2(0, 0.5));
}
[test]
todo(glsl) draw quad
if(sm<6) probe (0, 0) rgba(2.0, 2.0, 2.0, 2.0)
if(sm>=6) probe (0, 0) rgba(0.5, 0.5, 0.5, 0.5)
% cbuffer reservation limits.
[pixel shader]
cbuffer buf0 : register(b0)
{
float a;
};
cbuffer buf1 : register(b1)
{
float b;
};
cbuffer buf2 : register(b2)
{
float c;
};
cbuffer buf3 : register(b3)
{
float d;
};
cbuffer buf4 : register(b4)
{
float e;
};
cbuffer buf5 : register(b5)
{
float f;
};
cbuffer buf6 : register(b6)
{
float g;
};
cbuffer buf7 : register(b7)
{
float h;
};
cbuffer buf8 : register(b8)
{
float i;
};
cbuffer buf9 : register(b9)
{
float j;
};
cbuffer buf10 : register(b10)
{
float k;
};
cbuffer buf11 : register(b11)
{
float l;
};
cbuffer buf12 : register(b12)
{
float m;
};
cbuffer buf13 : register(b13)
{
float n;
};
float4 main() : sv_target
{
return a * b * c * d * e * f * g * h * i * j * k * l * m * n;
}
[pixel shader fail(sm>=6)]
// $Globals and $Params count towards the 14 cbuffer limit.
float glob;
cbuffer buf0 : register(b0)
{
float a;
};
cbuffer buf1 : register(b1)
{
float b;
};
cbuffer buf2 : register(b2)
{
float c;
};
cbuffer buf3 : register(b3)
{
float d;
};
cbuffer buf4 : register(b4)
{
float e;
};
cbuffer buf5 : register(b5)
{
float f;
};
cbuffer buf6 : register(b6)
{
float g;
};
cbuffer buf7 : register(b7)
{
float h;
};
cbuffer buf8 : register(b8)
{
float i;
};
cbuffer buf9 : register(b9)
{
float j;
};
cbuffer buf10 : register(b10)
{
float k;
};
cbuffer buf11 : register(b11)
{
float l;
};
float4 main(uniform float param) : sv_target
{
return glob * param * a * b * c * d * e * f * g * h * i * j * k * l;
}
[pixel shader fail]
float glob;
cbuffer buf0 : register(b0)
{
float a;
};
cbuffer buf1 : register(b1)
{
float b;
};
cbuffer buf2 : register(b2)
{
float c;
};
cbuffer buf3 : register(b3)
{
float d;
};
cbuffer buf4 : register(b4)
{
float e;
};
cbuffer buf5 : register(b5)
{
float f;
};
cbuffer buf6 : register(b6)
{
float g;
};
cbuffer buf7 : register(b7)
{
float h;
};
cbuffer buf8 : register(b8)
{
float i;
};
cbuffer buf9 : register(b9)
{
float j;
};
cbuffer buf10 : register(b10)
{
float k;
};
cbuffer buf11 : register(b11)
{
float l;
};
cbuffer buf12 : register(b12)
{
float m;
};
float4 main(uniform float param) : sv_target
{
return glob * param * a * b * c * d * e * f * g * h * i * j * k * l * m;
}
[pixel shader fail]
// Unused cbuffers still reserve their slot, and count towards the limit.
float glob;
cbuffer buf0 : register(b0)
{
float a;
};
cbuffer buf1 : register(b1)
{
float b;
};
cbuffer buf2 : register(b2)
{
float c;
};
cbuffer buf3 : register(b3)
{
float d;
};
cbuffer buf4 : register(b4)
{
float e;
};
cbuffer buf5 : register(b5)
{
float f;
};
cbuffer buf6 : register(b6)
{
float g;
};
cbuffer buf7 : register(b7)
{
float h;
};
cbuffer buf8 : register(b8)
{
float i;
};
cbuffer buf9 : register(b9)
{
float j;
};
cbuffer buf10 : register(b10)
{
float k;
};
cbuffer buf11 : register(b11)
{
float l;
};
cbuffer buf12 : register(b12)
{
float m;
};
float4 main(uniform float param) : sv_target
{
return glob * param * a * b * c * d * e * f * g * h * i * j * k * l;
}
[require]
shader model >= 5.1
[pixel shader fail(sm>=6)]
// 5.1 and up have unlimited CBV slots.
float glob;
cbuffer buf0 : register(b0)
{
float a;
};
cbuffer buf1 : register(b1)
{
float b;
};
cbuffer buf2 : register(b2)
{
float c;
};
cbuffer buf3 : register(b3)
{
float d;
};
cbuffer buf4 : register(b4)
{
float e;
};
cbuffer buf5 : register(b5)
{
float f;
};
cbuffer buf6 : register(b6)
{
float g;
};
cbuffer buf7 : register(b7)
{
float h;
};
cbuffer buf8 : register(b8)
{
float i;
};
cbuffer buf9 : register(b9)
{
float j;
};
cbuffer buf10 : register(b10)
{
float k;
};
cbuffer buf11 : register(b11)
{
float l;
};
cbuffer buf12 : register(b12)
{
float m;
};
float4 main(uniform float param) : sv_target
{
return glob * param * a * b * c * d * e * f * g * h * i * j * k * l * m;
}
[pixel shader]
// SM6 doesn't support uniform parameters (why??)
float glob;
cbuffer buf0 : register(b0)
{
float a;
};
cbuffer buf1 : register(b1)
{
float b;
};
cbuffer buf2 : register(b2)
{
float c;
};
cbuffer buf3 : register(b3)
{
float d;
};
cbuffer buf4 : register(b4)
{
float e;
};
cbuffer buf5 : register(b5)
{
float f;
};
cbuffer buf6 : register(b6)
{
float g;
};
cbuffer buf7 : register(b7)
{
float h;
};
cbuffer buf8 : register(b8)
{
float i;
};
cbuffer buf9 : register(b9)
{
float j;
};
cbuffer buf10 : register(b10)
{
float k;
};
cbuffer buf11 : register(b11)
{
float l;
};
cbuffer buf12 : register(b12)
{
float m;
};
cbuffer buf13 : register(b13)
{
float n;
};
float4 main() : sv_target
{
return glob * a * b * c * d * e * f * g * h * i * j * k * l * m * n;
}