[require]
shader model >= 4.0


[srv 0]
size (2d, 1, 1)
0.0 0.0 0.0 99.0

[srv 1]
size (2d, 1, 1)
1.0 1.0 1.0 99.0

[srv 2]
size (2d, 1, 1)
2.0 2.0 2.0 99.0

[srv 3]
size (2d, 1, 1)
3.0 3.0 3.0 99.0

[srv 4]
size (2d, 1, 1)
4.0 4.0 4.0 99.0


% If a single component in a texture array is used, all registers are reserved.
[pixel shader]
Texture2D partially_used[2][2];
Texture2D tex;

float4 main() : sv_target
{
    return 10 * tex.Load(int3(0, 0, 0)) + partially_used[0][1].Load(int3(0, 0, 0));
}

[test]
todo(mvk & sm>=6) draw quad
probe (0, 0) f32(41.0, 41.0, 41.0, 1089.0)

% If no component in a texture array is used, and it doesn't have a register reservation, no
% register is reserved.
[pixel shader]
Texture2D unused[4];
Texture2D tex;

float4 main() : sv_target
{
    return tex.Load(int3(0, 0, 0));
}

[test]
draw quad
probe (0, 0) f32(0.0, 0.0, 0.0, 99.0)

% Register reservations force to reserve all the resource registers. Even if unused.
[pixel shader]
Texture2D unused : register(t0);
Texture2D tex;

float4 main() : sv_target
{
    return tex.Load(int3(0, 0, 0));
}

[test]
draw quad
probe (0, 0) f32(1.0, 1.0, 1.0, 99.0)

% Register reservation with incorrect register type.
[pixel shader]
Texture2D unused : register(s0);
Texture2D tex;

float4 main() : sv_target
{
    return tex.Load(int3(0, 0, 0));
}

[require]
shader model >= 4.0
shader model < 6.0

[test]
todo(msl & sm>=6) draw quad
probe (0, 0) rgba (0.0, 0.0, 0.0, 99.0)

[require]
shader model >= 6.0

[test]
draw quad
probe (0, 0) f32(1.0, 1.0, 1.0, 99.0)

[require]
shader model >= 4.0


% Register reservation with incorrect register type.
[pixel shader fail(sm>=5.1) todo(sm>=5.1)]
sampler2D unused : register(t0);
Texture2D tex;

float4 main() : sv_target
{
    return tex.Load(int3(0, 0, 0));
}

[test]
draw quad
probe (0, 0) f32(0.0, 0.0, 0.0, 99.0)

[pixel shader]
Texture2D unused[2][2] : register(t0);
Texture2D tex;

float4 main() : sv_target
{
    return tex.Load(int3(0, 0, 0));
}

[test]
draw quad
probe (0, 0) f32(4.0, 4.0, 4.0, 99.0)

% Overlapping reservations, both overlapping objects are unused.
[pixel shader]
Texture2D tex1 : register(t0);
Texture2D tex2 : register(t0);
Texture2D tex3;

float4 main() : sv_target
{
    return tex3.Load(int3(0, 0, 0));
}

[test]
draw quad
probe (0, 0) f32(1.0, 1.0, 1.0, 99.0)

% Overlapping reservations
[pixel shader]
Texture2D tex1 : register(t2);
Texture2D tex2 : register(t2);

float4 main() : sv_target
{
    return tex1.Load(int3(0, 0, 0));
}

[test]
draw quad
probe (0, 0) f32(2.0, 2.0, 2.0, 99.0)

[pixel shader]
Texture2D tex1 : register(t2);
Texture2D tex2 : register(t2);

float4 main() : sv_target
{
    return tex2.Load(int3(0, 0, 0));
}

[test]
draw quad
probe (0, 0) f32(2.0, 2.0, 2.0, 99.0)

[require]
shader model >= 5.0

[srv 0]
size (2d, 2, 2)
0.0 0.0 0.0 99.0
0.0 0.0 0.0 99.0
0.0 0.0 0.0 99.0
0.0 0.0 0.0 99.0

[srv 1]
size (2d, 2, 2)
1.0 1.0 1.0 99.0
1.0 1.0 1.0 99.0
0.0 0.0 0.0 99.0
0.0 0.0 0.0 99.0

[sampler 0]
filter point point point
address clamp clamp clamp

[sampler 1]
filter linear linear linear
address clamp clamp clamp

% If a struct spans many object register sets and one is reserved, all other used object register sets must be.
[pixel shader fail(sm<6)]
struct
{
     Texture2D tex;
     sampler sam;
} foo : register(t1);

float4 main() : sv_target
{
    return foo.tex.Sample(foo.sam, float2(0.4, 0));
}


[pixel shader todo]
struct
{
     Texture2D tex;
     sampler sam;
} foo : register(t1) : register(s1);

float4 main() : sv_target
{
    return foo.tex.Sample(foo.sam, float2(0, 0.5));
}

[test]
todo(sm<6) draw quad
todo(sm<6) probe (0,0) rgba (0.5, 0.5, 0.5, 99.0)


[pixel shader]
struct
{
     Texture2D tex;
     sampler sam; // unused.
} foo : register(t1);

float4 main() : sv_target
{
    return foo.tex.Load(int3(0, 0, 0));
}

[test]
draw quad
probe (0, 0) f32(1.0, 1.0, 1.0, 99.0)
