diff --git a/Makefile.am b/Makefile.am
index cafa8f2f0f2ef9f63df0382f8ba46a4bd54eeec7..b5e77f4eeccdebea26567b5846728bd952ad1817 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -70,6 +70,7 @@ vkd3d_shader_tests = \
 	tests/hlsl/cbuffer.shader_test \
 	tests/hlsl/clamp.shader_test \
 	tests/hlsl/clip.shader_test \
+	tests/hlsl/combined-samplers.shader_test \
 	tests/hlsl/comma.shader_test \
 	tests/hlsl/compute.shader_test \
 	tests/hlsl/conditional.shader_test \
diff --git a/tests/hlsl/combined-samplers.shader_test b/tests/hlsl/combined-samplers.shader_test
new file mode 100644
index 0000000000000000000000000000000000000000..c14de4bc5cf51b69ea183e32916cc09769972119
--- /dev/null
+++ b/tests/hlsl/combined-samplers.shader_test
@@ -0,0 +1,153 @@
+[require]
+shader model >= 4.0
+
+
+[sampler 0]
+filter linear linear linear
+address clamp clamp clamp
+
+[sampler 1]
+filter linear linear linear
+address clamp clamp clamp
+
+[sampler 2]
+filter linear linear linear
+address clamp clamp clamp
+
+[texture 0]
+size (1, 1)
+0.0 0.0 0.0 1.0
+
+[texture 1]
+size (1, 1)
+1.0 1.0 1.0 1.0
+
+[texture 2]
+size (1, 1)
+2.0 2.0 2.0 1.0
+
+[texture 3]
+size (1, 1)
+3.0 3.0 3.0 1.0
+
+[texture 4]
+size (1, 1)
+4.0 4.0 4.0 1.0
+
+
+[pixel shader todo]
+sampler sam;
+
+float4 main() : sv_target
+{
+    return tex2D(sam, float2(0, 0));
+}
+
+[test]
+todo draw quad
+todo probe all rgba (0, 0, 0, 1)
+
+
+% Textures for new separated samplers are allocated before regular textures.
+[pixel shader todo]
+Texture2D tex;
+sampler sam;
+
+float4 main() : sv_target
+{
+    return 10 * tex.Sample(sam, float2(0, 0)) + tex2D(sam, float2(0, 0));
+}
+
+[test]
+todo draw quad
+todo probe all rgba (10, 10, 10, 11)
+
+
+[pixel shader todo]
+Texture2D tex;
+sampler sam[2];
+
+float4 main() : sv_target
+{
+    return 10 * tex.Sample(sam[0], float2(0, 0)) + tex2D(sam[1], float2(0, 0));
+}
+
+[test]
+todo draw quad
+todo probe all rgba (21, 21, 21, 11)
+
+
+[pixel shader todo]
+sampler sam0;
+sampler sam1;
+sampler sam2;
+
+float4 main() : sv_target
+{
+    return 100 * tex2D(sam1, float2(0, 0)) + 10 * tex2D(sam0, float2(0, 0))
+            + tex2D(sam2, float2(0, 0));
+}
+
+[test]
+todo draw quad
+todo probe all rgba (12, 12, 12, 111)
+
+
+[pixel shader todo]
+Texture2D tex[2][2];
+sampler sam;
+
+float4 main() : sv_target
+{
+    return 100 * tex[0][0].Load(int3(0, 0, 0)) + 10 * tex2D(sam, float2(0, 0))
+            + tex[1][1].Sample(sam, float2(0, 0));
+}
+
+[test]
+todo draw quad
+todo probe all rgba (104, 104, 104, 111)
+
+
+% Sampler arrays with components that have different usage dimensions are only forbidden in SM4 upwards.
+% However, tex2D and tex1D are considered the same dimension for these purposes.
+[pixel shader fail todo]
+sampler sam[2];
+
+float4 main() : sv_target
+{
+    return tex2D(sam[0], float2(0, 0)) + tex3D(sam[1], float3(0, 0, 0));
+}
+
+
+[pixel shader todo]
+sampler sam[2];
+
+float4 main() : sv_target
+{
+    return 10 * tex2D(sam[0], float2(0, 0)) + tex1D(sam[1], 0);
+}
+
+[test]
+todo draw quad
+todo probe all rgba (1, 1, 1, 11)
+
+
+[require]
+shader model >= 5.0
+
+
+[pixel shader todo]
+struct
+{
+  Texture2D tex;
+  sampler sam;
+} foo;
+
+float4 main() : sv_target
+{
+    return 10 * foo.tex.Sample(foo.sam, float2(0, 0)) + tex2D(foo.sam, float2(0, 0));
+}
+
+[test]
+todo draw quad
+todo probe all rgba (10, 10, 10, 11)