mirror of
				https://gitlab.winehq.org/wine/vkd3d.git
				synced 2025-09-12 18:50:22 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			723 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			723 lines
		
	
	
		
			9.9 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;
 | |
| }
 | |
| 
 | |
| [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)
 | |
| 
 | |
| % 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]
 | |
| // 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 c;
 | |
| }
 | |
| 
 | |
| 
 | |
| [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]
 | |
| // Matrices must be aligned.
 | |
| cbuffer buffer
 | |
| {
 | |
|     float1x1 m : packoffset(c0.y);
 | |
| }
 | |
| 
 | |
| float4 main() : sv_target
 | |
| {
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| [pixel shader fail]
 | |
| // Arrays must be aligned.
 | |
| cbuffer buffer
 | |
| {
 | |
|     float a[1] : packoffset(c0.y);
 | |
| }
 | |
| 
 | |
| float4 main() : sv_target
 | |
| {
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| [pixel shader fail]
 | |
| // 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]
 | |
| // 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;
 | |
| }
 | |
| 
 | |
| 
 | |
| [texture 0]
 | |
| size (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;
 | |
| }
 | |
| 
 | |
| 
 | |
| [texture 0]
 | |
| size (1, 1)
 | |
| 1.0 1.0 1.0 1.0
 | |
| 
 | |
| [texture 1]
 | |
| size (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 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]
 | |
| cbuffer buffer
 | |
| {
 | |
|     float4 foo : packoffset(c0);
 | |
|     Texture2D tex;
 | |
| }
 | |
| 
 | |
| float4 main() : sv_target
 | |
| {
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| [pixel shader fail]
 | |
| 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]
 | |
| cbuffer buffer
 | |
| {
 | |
|     float4 foo;
 | |
|     Texture2D tex : register(t1);
 | |
| }
 | |
| 
 | |
| float4 main() : sv_target
 | |
| {
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| [pixel shader fail]
 | |
| 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
 | |
| 
 | |
| [texture 0]
 | |
| size (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)
 |