mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
e0ef45c0a3
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
791 lines
11 KiB
Plaintext
791 lines
11 KiB
Plaintext
% Uppercase register set names
|
|
[pixel shader]
|
|
cbuffer Constants : register(B1)
|
|
{
|
|
};
|
|
Texture2D tex : register(T1);
|
|
float4 foo : register(C0);
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return foo;
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 2.0 3.0 4.0
|
|
draw quad
|
|
probe all rgba (1.0, 2.0, 3.0, 4.0)
|
|
|
|
[pixel shader]
|
|
// Test empty constant buffer.
|
|
cbuffer Constants : register(b1)
|
|
{
|
|
};
|
|
|
|
float4 foo;
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return foo;
|
|
}
|
|
|
|
[pixel shader fail(sm>=6)]
|
|
// The 'single' modifier is not a keyword. It's meaningful only for fx_5_0.
|
|
single cbuffer cb
|
|
{
|
|
float4 single;
|
|
};
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return single;
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 2.0 3.0 4.0
|
|
draw quad
|
|
probe all rgba (1.0, 2.0, 3.0, 4.0)
|
|
|
|
[pixel shader fail(sm>=6)]
|
|
// 'single' modifier is usable when there is a variable with the same name
|
|
cbuffer cb
|
|
{
|
|
float4 single;
|
|
};
|
|
|
|
single cbuffer cb2
|
|
{
|
|
float4 var;
|
|
};
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return single;
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 2.0 3.0 4.0
|
|
draw quad
|
|
probe all rgba (1.0, 2.0, 3.0, 4.0)
|
|
|
|
[pixel shader]
|
|
typedef float4 single;
|
|
single var;
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return var;
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 2.0 3.0 4.0
|
|
draw quad
|
|
probe all rgba (1.0, 2.0, 3.0, 4.0)
|
|
|
|
[pixel shader fail]
|
|
typedef float4 single;
|
|
single cbuffer cb
|
|
{
|
|
float4 var;
|
|
};
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return var;
|
|
}
|
|
|
|
% SM1 buffer offset allocation follows different rules than SM4.
|
|
% Those would have to be tested separately.
|
|
[require]
|
|
shader model >= 4.0
|
|
|
|
|
|
[pixel shader fail]
|
|
cbuffer buffer
|
|
{
|
|
float4 a : packoffset(c1invalid_extra_chars);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
% Respect register boundaries
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float2 a;
|
|
float2 b;
|
|
float2 c;
|
|
float3 d;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return float4(a.x, b.x, c.x, d.x);
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 0.0 1.0 2.0 3.0
|
|
uniform 4 float4 4.0 5.0 6.0 7.0
|
|
uniform 8 float4 8.0 9.0 10.0 11.0
|
|
uniform 12 float4 12.0 13.0 14.0 15.0
|
|
draw quad
|
|
probe all rgba (0.0, 2.0, 4.0, 8.0)
|
|
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float a;
|
|
float b[2];
|
|
float c;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return float4(a, b[0], b[1], c);
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 0.0 1.0 2.0 3.0
|
|
uniform 4 float4 4.0 5.0 6.0 7.0
|
|
uniform 8 float4 8.0 9.0 10.0 11.0
|
|
draw quad
|
|
probe all rgba (0.0, 4.0, 8.0, 9.0)
|
|
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float a;
|
|
struct
|
|
{
|
|
float b;
|
|
float c;
|
|
} p;
|
|
float d;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return float4(a, p.b, p.c, d);
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 0.0 1.0 2.0 3.0
|
|
uniform 4 float4 4.0 5.0 6.0 7.0
|
|
uniform 8 float4 8.0 9.0 10.0 11.0
|
|
uniform 12 float4 12.0 13.0 14.0 15.0
|
|
draw quad
|
|
probe all rgba (0.0, 4.0, 5.0, 6.0)
|
|
|
|
|
|
[pixel shader fail(sm<6)]
|
|
// Elements cannot overlap if buffer is used.
|
|
cbuffer buffer
|
|
{
|
|
float c : packoffset(c0);
|
|
float4 a[2] : packoffset(c1);
|
|
float4 b[2] : packoffset(c2);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return float4(c, a[1].x, b[0].x, b[1].x);
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 0.0 0.0 0.0
|
|
uniform 4 float4 2.0 0.0 0.0 0.0
|
|
uniform 8 float4 3.0 0.0 0.0 0.0
|
|
uniform 12 float4 4.0 0.0 0.0 0.0
|
|
todo(sm<6) draw quad
|
|
probe all rgba (1.0, 3.0, 3.0, 4.0)
|
|
|
|
|
|
[pixel shader]
|
|
// Elements can overlap if buffer is not used.
|
|
cbuffer buffer
|
|
{
|
|
float4 a[2] : packoffset(c1);
|
|
float4 b[2] : packoffset(c2);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float4 a : packoffset(c1);
|
|
float4 b : packoffset(C2);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 100 * a + b;
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 2.0 3.0 4.0
|
|
uniform 4 float4 5.0 6.0 7.0 8.0
|
|
uniform 8 float4 9.0 10.0 11.0 12.0
|
|
draw quad
|
|
probe all rgba (509, 610, 711, 812)
|
|
|
|
|
|
[pixel shader]
|
|
struct apple
|
|
{
|
|
float2 a;
|
|
float b;
|
|
float4 c;
|
|
};
|
|
|
|
cbuffer buffer
|
|
{
|
|
float4 foo : packoffset(c3);
|
|
struct apple bar : packoffset(c1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 1000 * foo + 100 * float4(bar.a, 0, 0) + 10 * float4(bar.b, 0, 0, 0) + bar.c;
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 0.0 1.0 2.0 3.0
|
|
uniform 4 float4 4.0 5.0 6.0 7.0
|
|
uniform 8 float4 8.0 9.0 10.0 11.0
|
|
uniform 12 float4 12.0 13.0 14.0 15.0
|
|
draw quad
|
|
probe all rgba (12468.0, 13509.0, 14010.0, 15011.0)
|
|
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float2 c : packoffset(c0.y);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return float4(c, c);
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 2.0 3.0 4.0
|
|
draw quad
|
|
probe all rgba (2.0, 3.0, 2.0, 3.0)
|
|
|
|
|
|
[pixel shader fail]
|
|
// Elements must respect register boundaries.
|
|
cbuffer buffer
|
|
{
|
|
float4 c : packoffset(c0.z);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader fail(sm<6)]
|
|
// Matrices must be aligned.
|
|
cbuffer buffer
|
|
{
|
|
float1x1 m : packoffset(c0.y);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader fail(sm<6)]
|
|
// Arrays must be aligned.
|
|
cbuffer buffer
|
|
{
|
|
float a[1] : packoffset(c0.y);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader fail(sm<6)]
|
|
// Structs must be aligned.
|
|
struct apple
|
|
{
|
|
float p;
|
|
};
|
|
|
|
cbuffer buffer
|
|
{
|
|
struct apple a : packoffset(c0.y);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader fail]
|
|
// Invalid offset on unused buffer.
|
|
cbuffer buffer
|
|
{
|
|
float3 a : packoffset(c0.z);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader fail]
|
|
// Invalid offset on unused variable.
|
|
cbuffer buffer
|
|
{
|
|
float a : packoffset(c0);
|
|
float3 b : packoffset(c0.z);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return a;
|
|
}
|
|
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float4 a : packoffset(c1);
|
|
float1 b : packoffset(c0);
|
|
float1 c : packoffset(c0.y);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 100 * a + 10 * b + c;
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float 1.0
|
|
uniform 1 float 2.0
|
|
uniform 4 float4 5.0 6.0 7.0 8.0
|
|
draw quad
|
|
probe all rgba (512.0, 612.0, 712.0, 812.0)
|
|
|
|
|
|
[pixel shader fail(sm<6)]
|
|
// packoffset cannot be used unless all elements use it.
|
|
cbuffer buffer
|
|
{
|
|
float4 a : packoffset(c0);
|
|
float4 b;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return a + b;
|
|
}
|
|
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float2 c : packoffset(c0.b);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return float4(c, c);
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 2.0 3.0 4.0
|
|
draw quad
|
|
probe all rgba (3.0, 4.0, 3.0, 4.0)
|
|
|
|
|
|
[pixel shader fail]
|
|
cbuffer buffer
|
|
{
|
|
float2 c : packoffset(c0.xy);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader fail]
|
|
cbuffer buffer
|
|
{
|
|
float4x4 mat : packoffset(c0._m00);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader fail]
|
|
cbuffer buffer
|
|
{
|
|
float4 a : packoffset(c0._m00);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[pixel shader fail]
|
|
cbuffer buffer
|
|
{
|
|
float2 c : packoffset(c0.xz);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
% packoffset cannot be used outside a constant buffer.
|
|
[pixel shader fail]
|
|
float4 a : packoffset(c0);
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader fail]
|
|
float4 foo(float4 a : packoffset(c0))
|
|
{
|
|
return a;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader fail]
|
|
float4 foo(float4 a) : packoffset(c0)
|
|
{
|
|
return a;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader fail]
|
|
struct apple
|
|
{
|
|
float4 a : packoffset(c0);
|
|
};
|
|
|
|
cbuffer buffer
|
|
{
|
|
struct apple a;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader fail]
|
|
cbuffer buffer
|
|
{
|
|
struct
|
|
{
|
|
float4 a : packoffset(c0);
|
|
} s;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[srv 0]
|
|
size (2d, 1, 1)
|
|
0.0 0.0 0.0 4.0
|
|
|
|
[sampler 0]
|
|
filter linear linear linear
|
|
address clamp clamp clamp
|
|
|
|
|
|
[pixel shader]
|
|
// Resources are allowed inside constant buffers but they behave as regular resources.
|
|
cbuffer buffer
|
|
{
|
|
float4 a;
|
|
Texture2D tex;
|
|
sampler sam;
|
|
float4 b;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return a + b + tex.Sample(sam, float2(0, 0));
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 1.0 0.0 0.0 0.0
|
|
uniform 4 float4 0.0 2.0 0.0 0.0
|
|
uniform 8 float4 0.0 0.0 3.0 0.0
|
|
draw quad
|
|
probe all rgba (1.0, 2.0, 0.0, 4.0)
|
|
|
|
|
|
% packoffset() cannot be used to specify other types of registers
|
|
[pixel shader fail]
|
|
cbuffer buffer
|
|
{
|
|
sampler sam : packoffset(s0);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader fail]
|
|
cbuffer buffer
|
|
{
|
|
Texture2D tex : packoffset(t0);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[srv 0]
|
|
size (2d, 1, 1)
|
|
1.0 1.0 1.0 1.0
|
|
|
|
[srv 1]
|
|
size (2d, 1, 1)
|
|
2.0 2.0 2.0 2.0
|
|
|
|
|
|
[pixel shader]
|
|
// packoffset() can be used in Textures, doesn't change the allocated t register.
|
|
cbuffer buffer
|
|
{
|
|
Texture2D tex : packoffset(c1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return tex.Load(int3(0, 0, 0));
|
|
}
|
|
|
|
[test]
|
|
draw quad
|
|
probe all rgba (1.0, 1.0, 1.0, 1.0)
|
|
|
|
|
|
% Samplers cannot have packoffset(), unless register() is also specified, or they are not used.
|
|
% Note: In SM1 the rules are different: packoffset() is allowed for samplers, but they cannot be
|
|
% used together with other numeric fields, which seems like a bug.
|
|
[pixel shader fail(sm<6) todo]
|
|
Texture2D tex;
|
|
|
|
cbuffer buffer
|
|
{
|
|
sampler sam : packoffset(c1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return tex.Sample(sam, float2(0, 0));
|
|
}
|
|
|
|
[pixel shader todo]
|
|
Texture2D tex;
|
|
|
|
cbuffer buffer
|
|
{
|
|
sampler sam : packoffset(c1) : register(s0);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return tex.Sample(sam, float2(0, 0));
|
|
}
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
sampler sam : packoffset(c1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
sampler sam : packoffset(c1);
|
|
float4 a : packoffset(c0);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return a;
|
|
}
|
|
|
|
|
|
% When packoffset is used in one field, resources are also expected to have a reservation.
|
|
[pixel shader fail(sm<6)]
|
|
cbuffer buffer
|
|
{
|
|
float4 foo : packoffset(c0);
|
|
Texture2D tex;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader fail(sm<6)]
|
|
cbuffer buffer
|
|
{
|
|
float4 foo : packoffset(c0);
|
|
sampler sam;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
% register() can be used instead of packoffset().
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float4 foo : packoffset(c0);
|
|
Texture2D tex : register(T1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float4 foo : packoffset(c0);
|
|
sampler sam : register(s1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
% Using register() alone is considered manual packing for resources, so the other fields expect packoffset().
|
|
[pixel shader fail(sm<6)]
|
|
cbuffer buffer
|
|
{
|
|
float4 foo;
|
|
Texture2D tex : register(t1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[pixel shader fail(sm<6)]
|
|
cbuffer buffer
|
|
{
|
|
float4 foo;
|
|
sampler sam : register(s1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
% Using register() alone is not considered manual packing for non-resources.
|
|
[pixel shader]
|
|
cbuffer buffer
|
|
{
|
|
float4 foo : register(c0);
|
|
Texture2D tex;
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
[require]
|
|
shader model >= 5.0
|
|
|
|
[srv 0]
|
|
size (2d, 1, 1)
|
|
0.0 0.0 0.0 0.5
|
|
|
|
[pixel shader]
|
|
struct apple
|
|
{
|
|
float2 a;
|
|
Texture2D tex;
|
|
float b;
|
|
};
|
|
|
|
cbuffer buffer
|
|
{
|
|
float4 foo : packoffset(c3);
|
|
struct apple bar : packoffset(c1);
|
|
}
|
|
|
|
float4 main() : sv_target
|
|
{
|
|
return 10 * foo + float4(bar.a, 0, 0) + float4(0, 0, bar.b, 0) + bar.tex.Load(int3(0, 0, 0));
|
|
}
|
|
|
|
[test]
|
|
uniform 0 float4 0.0 1.0 2.0 3.0
|
|
uniform 4 float4 4.0 5.0 6.0 7.0
|
|
uniform 8 float4 8.0 9.0 10.0 11.0
|
|
uniform 12 float4 12.0 13.0 14.0 15.0
|
|
draw quad
|
|
probe all rgba (124.0, 135.0, 146.0, 150.5)
|