diff --git a/tests/hlsl/interface-packing.shader_test b/tests/hlsl/interface-packing.shader_test new file mode 100644 index 00000000..f2b98ebc --- /dev/null +++ b/tests/hlsl/interface-packing.shader_test @@ -0,0 +1,104 @@ +% Test handling of arrays in interface blocks + +[require] +shader model >= 4.0 +shader model < 6.0 + +[vertex shader] +// Rules: +// 1. Arrays always start on .x +// 2. When placing a scalar or vector, search through the allocated slots for space *vertically* +// (So check if you can place at o1.y, then o2.y, o3.y before o1.z, o2.z, etc.) +// 3. Elements with different interpolation cannot share a slot +struct data +{ + float4 position : SV_Position; // Should be placed in o0 + float array1[2] : ARRAY1; // Should be placed in o1.x, o2.x + float3 array3[1] : ARRAY3; // Should be placed in o3.xyz + float array4[2] : ARRAY4; // Should be placed in o4.x, o5.x + nointerpolation float ndata : NDATA; // Should be placed in o6.x + uint udata : UDATA; // Should be placed in o6.y + float4 data1 : DATA1; // Should be placed in o7.xyzw + float3 data2 : DATA2; // Should be placed in o1.yzw + float2 data3 : DATA3; // Should be placed in o2.yz + float data4 : DATA4; // Should be placed in o4.y + float2 data5 : DATA5; // Should be placed in o5.yz + float2 data6 : DATA6; // Should be placed in o4.zw + float data7 : DATA7; // Should be placed in o2.w + float2 data8 : DATA8; // Should be placed in o8.xy + float data9 : DATA9; // Should be placed in o8.z (not o3.w) + float data10 : DATA10; // Should be placed in o3.w +}; + +void main(uint id : SV_VertexID, out data output) +{ + output.position = float4(id & 1 ? 3 : -1, id & 2 ? -3 : 1, 0, 1); + output.array1[0] = 1.0; + output.array1[1] = 2.0; + output.array3[0] = float3(3.0, 4.0, 5.0); + output.array4[0] = 6.0; + output.array4[1] = 7.0; + output.data1 = float4(8.0, 9.0, 10.0, 11.0); + output.data2 = float3(12.0, 13.0, 14.0); + output.data3 = float2(15.0, 16.0); + output.data4 = 17.0; + output.data5 = float2(18.0, 19.0); + output.data6 = float2(20.0, 21.0); + output.data7 = 22.0; + output.data8 = float2(23.0, 24.0); + output.data9 = 25.0; + output.data10 = 26.0; + output.ndata = 27.0; + output.udata = 28; +} + +[pixel shader] +struct data +{ + float4 position : SV_Position; // v0.xyzw + float array1 : ARRAY1; // v1.x + float3 data2 : DATA2; // v1.yzw + float array2 : ARRAY2; // v2.x + float2 data3 : DATA3; // v2.yz + float data7 : DATA7; // v2.w + float3 array3 : ARRAY3; // v3.xyz + float data10 : DATA10; // v3.w + float array4 : ARRAY4; // v4.x + float data4 : DATA4; // v4.y + float2 data6 : DATA6; // v4.zw + float array5 : ARRAY5; // v5.x + float2 data5 : DATA5; // v5.yz + nointerpolation float ndata : NDATA; // v6.x + uint udata : UDATA; // v6.y + float4 data1 : DATA1; // v7.xyzw + float2 data8 : DATA8; // v8.xy + float data9 : DATA9; // v8.z +}; + +float4 main(data input) : SV_Target +{ + switch (int(input.position.x)) + { + case 1: return float4(input.array1, input.data2); + case 2: return float4(input.array2, input.data3, input.data7); + case 3: return float4(input.array3, input.data10); + case 4: return float4(input.array4, input.data4, input.data6); + case 5: return float4(input.array5, input.data5, 0); + case 6: return float4(input.ndata, input.udata, 0, 0); + case 7: return input.data1; + case 8: return float4(input.data8, input.data9, 0); + default: return 0; + } +} + +[test] +todo(glsl) draw triangle list 3 + probe (0, 0) rgba ( 0.0, 0.0, 0.0, 0.0) +todo probe (1, 0) rgba ( 1.0, 12.0, 13.0, 14.0) +todo probe (2, 0) rgba ( 2.0, 15.0, 16.0, 22.0) +todo probe (3, 0) rgba ( 3.0, 4.0, 5.0, 26.0) +todo probe (4, 0) rgba ( 6.0, 17.0, 20.0, 21.0) +todo probe (5, 0) rgba ( 7.0, 18.0, 19.0, 0.0) +todo probe (6, 0) rgba (27.0, 28.0, 0.0, 0.0) +todo probe (7, 0) rgba ( 8.0, 9.0, 10.0, 11.0) +todo probe (8, 0) rgba (23.0, 24.0, 25.0, 0.0)