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

982 lines
15 KiB
Plaintext

[pixel shader fail(sm<6)]
// 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]
// Overlapping reservations when both variables are unused.
float4 a : register(c3);
float4 b : register(c3);
float4 main() : sv_target
{
return 42;
}
[pixel shader fail(sm>=4 & sm<6)]
// Overlapping reservations when only one variable is used.
float4 a : register(c3);
float4 b : register(c3);
float4 main() : sv_target
{
return b;
}
[pixel shader fail(sm>=4 & sm<6)]
// Overlapping reservations when both variables are used, but their bind_count (used size) doesn't
// cause an overlap.
float4 a[2] : register(c3); // bind count: 1
float4 b : register(c4);
float4 main() : sv_target
{
return a[0] + 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
draw quad
probe (0, 0) rgba (1.1, 1.4, 0.2, 0.3)
[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
draw quad
probe (0, 0) rgba (4.1, 4.2, 1.3, 1.4)
[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)
[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)
[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)
% 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)
[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)
[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
draw quad
probe (0, 0) rgba (100, 100, 100, 100)
[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
draw quad
probe (0, 0) rgba (100, 100, 100, 100)
[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)
[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
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
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
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
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
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
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
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
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;
}