Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-02-16 18:39:45 +0300
committerGitHub <noreply@github.com>2022-02-16 18:39:45 +0300
commit188dc8b13c29f8547c8fb52182111c9ada741a70 (patch)
treeb9dfd7476fd52e14959e7d9656c1f9d66871a2f4
parent64e058aa9b0c7a0d1cbc645b4496ddf4cdbca00d (diff)
parented4ded040e693a3e37a0187de68929aef50fd988 (diff)
Merge pull request #1862 from flokart-world/feature/flatten-ubo-for-hlsl
HLSL: Make --flatten-ubo work correctly
-rw-r--r--main.cpp3
-rw-r--r--reference/opt/shaders-hlsl/flatten/array.flatten.vert28
-rw-r--r--reference/opt/shaders-hlsl/flatten/basic.flatten.vert35
-rw-r--r--reference/opt/shaders-hlsl/flatten/copy.flatten.vert50
-rw-r--r--reference/opt/shaders-hlsl/flatten/dynamic.flatten.vert49
-rw-r--r--reference/opt/shaders-hlsl/flatten/matrix-conversion.flatten.frag29
-rw-r--r--reference/opt/shaders-hlsl/flatten/matrixindex.flatten.vert41
-rw-r--r--reference/opt/shaders-hlsl/flatten/multiindex.flatten.vert28
-rw-r--r--reference/opt/shaders-hlsl/flatten/push-constant.flatten.vert35
-rw-r--r--reference/opt/shaders-hlsl/flatten/rowmajor.flatten.vert28
-rw-r--r--reference/opt/shaders-hlsl/flatten/struct.flatten.vert44
-rw-r--r--reference/opt/shaders-hlsl/flatten/struct.rowmajor.flatten.vert43
-rw-r--r--reference/opt/shaders-hlsl/flatten/swizzle.flatten.vert45
-rw-r--r--reference/opt/shaders-hlsl/flatten/types.flatten.frag23
-rw-r--r--reference/shaders-hlsl/flatten/array.flatten.vert30
-rw-r--r--reference/shaders-hlsl/flatten/basic.flatten.vert35
-rw-r--r--reference/shaders-hlsl/flatten/copy.flatten.vert53
-rw-r--r--reference/shaders-hlsl/flatten/dynamic.flatten.vert47
-rw-r--r--reference/shaders-hlsl/flatten/matrix-conversion.flatten.frag29
-rw-r--r--reference/shaders-hlsl/flatten/matrixindex.flatten.vert41
-rw-r--r--reference/shaders-hlsl/flatten/multiindex.flatten.vert28
-rw-r--r--reference/shaders-hlsl/flatten/push-constant.flatten.vert35
-rw-r--r--reference/shaders-hlsl/flatten/rowmajor.flatten.vert29
-rw-r--r--reference/shaders-hlsl/flatten/struct.flatten.vert44
-rw-r--r--reference/shaders-hlsl/flatten/struct.rowmajor.flatten.vert48
-rw-r--r--reference/shaders-hlsl/flatten/swizzle.flatten.vert45
-rw-r--r--reference/shaders-hlsl/flatten/types.flatten.frag23
-rw-r--r--shaders-hlsl/flatten/array.flatten.vert19
-rw-r--r--shaders-hlsl/flatten/basic.flatten.vert16
-rw-r--r--shaders-hlsl/flatten/copy.flatten.vert34
-rw-r--r--shaders-hlsl/flatten/dynamic.flatten.vert33
-rw-r--r--shaders-hlsl/flatten/matrix-conversion.flatten.frag14
-rw-r--r--shaders-hlsl/flatten/matrixindex.flatten.vert25
-rw-r--r--shaders-hlsl/flatten/multiindex.flatten.vert13
-rw-r--r--shaders-hlsl/flatten/push-constant.flatten.vert17
-rw-r--r--shaders-hlsl/flatten/rowmajor.flatten.vert16
-rw-r--r--shaders-hlsl/flatten/struct.flatten.vert30
-rw-r--r--shaders-hlsl/flatten/struct.rowmajor.flatten.vert26
-rw-r--r--shaders-hlsl/flatten/swizzle.flatten.vert47
-rw-r--r--shaders-hlsl/flatten/types.flatten.frag27
-rw-r--r--spirv_glsl.cpp27
-rw-r--r--spirv_hlsl.cpp12
-rwxr-xr-xtest_shaders.py2
43 files changed, 1318 insertions, 8 deletions
diff --git a/main.cpp b/main.cpp
index 4e9fa849..dc3ca489 100644
--- a/main.cpp
+++ b/main.cpp
@@ -791,6 +791,9 @@ static void print_help_hlsl()
// clang-format off
fprintf(stderr, "\nHLSL options:\n"
"\t[--shader-model]:\n\t\tEnables a specific shader model, e.g. --shader-model 50 for SM 5.0.\n"
+ "\t[--flatten-ubo]:\n\t\tEmit UBOs as plain uniform arrays.\n"
+ "\t\tE.g.: uniform MyUBO { vec4 a; float b, c, d, e; }; will be emitted as uniform float4 MyUBO[2];\n"
+ "\t\tCaveat: You cannot mix and match floating-point and integer in the same UBO with this option.\n"
"\t[--hlsl-enable-compat]:\n\t\tAllow point size and point coord to be used, even if they won't work as expected.\n"
"\t\tPointSize is ignored, and PointCoord returns (0.5, 0.5).\n"
"\t[--hlsl-support-nonzero-basevertex-baseinstance]:\n\t\tSupport base vertex and base instance by emitting a special cbuffer declared as:\n"
diff --git a/reference/opt/shaders-hlsl/flatten/array.flatten.vert b/reference/opt/shaders-hlsl/flatten/array.flatten.vert
new file mode 100644
index 00000000..c709893c
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/array.flatten.vert
@@ -0,0 +1,28 @@
+uniform float4 UBO[56];
+
+static float4 gl_Position;
+static float4 aVertex;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = (mul(aVertex, float4x4(UBO[40], UBO[41], UBO[42], UBO[43])) + UBO[55]) + ((UBO[50] + UBO[45]) + UBO[54].x.xxxx);
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/basic.flatten.vert b/reference/opt/shaders-hlsl/flatten/basic.flatten.vert
new file mode 100644
index 00000000..778acd48
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/basic.flatten.vert
@@ -0,0 +1,35 @@
+uniform float4 UBO[4];
+
+static float4 gl_Position;
+static float4 aVertex;
+static float3 vNormal;
+static float3 aNormal;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+ float3 aNormal : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float3 vNormal : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3]));
+ vNormal = aNormal;
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ aNormal = stage_input.aNormal;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vNormal = vNormal;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/copy.flatten.vert b/reference/opt/shaders-hlsl/flatten/copy.flatten.vert
new file mode 100644
index 00000000..5d857ad6
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/copy.flatten.vert
@@ -0,0 +1,50 @@
+struct Light
+{
+ float3 Position;
+ float Radius;
+ float4 Color;
+};
+
+uniform float4 UBO[12];
+
+static float4 gl_Position;
+static float4 aVertex;
+static float4 vColor;
+static float3 aNormal;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+ float3 aNormal : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 vColor : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3]));
+ vColor = 0.0f.xxxx;
+ for (int _96 = 0; _96 < 4; )
+ {
+ Light _51 = {UBO[_96 * 2 + 4].xyz, UBO[_96 * 2 + 4].w, UBO[_96 * 2 + 5]};
+ float3 _68 = aVertex.xyz - _51.Position;
+ vColor += ((UBO[_96 * 2 + 5] * clamp(1.0f - (length(_68) / _51.Radius), 0.0f, 1.0f)) * dot(aNormal, normalize(_68)));
+ _96++;
+ continue;
+ }
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ aNormal = stage_input.aNormal;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vColor = vColor;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/dynamic.flatten.vert b/reference/opt/shaders-hlsl/flatten/dynamic.flatten.vert
new file mode 100644
index 00000000..98d5e1b3
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/dynamic.flatten.vert
@@ -0,0 +1,49 @@
+struct Light
+{
+ float3 Position;
+ float Radius;
+ float4 Color;
+};
+
+uniform float4 UBO[12];
+
+static float4 gl_Position;
+static float4 aVertex;
+static float4 vColor;
+static float3 aNormal;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+ float3 aNormal : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 vColor : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3]));
+ vColor = 0.0f.xxxx;
+ for (int _82 = 0; _82 < 4; )
+ {
+ float3 _54 = aVertex.xyz - UBO[_82 * 2 + 4].xyz;
+ vColor += ((UBO[_82 * 2 + 5] * clamp(1.0f - (length(_54) / UBO[_82 * 2 + 4].w), 0.0f, 1.0f)) * dot(aNormal, normalize(_54)));
+ _82++;
+ continue;
+ }
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ aNormal = stage_input.aNormal;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vColor = vColor;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/matrix-conversion.flatten.frag b/reference/opt/shaders-hlsl/flatten/matrix-conversion.flatten.frag
new file mode 100644
index 00000000..59ec525f
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/matrix-conversion.flatten.frag
@@ -0,0 +1,29 @@
+uniform float4 UBO[4];
+
+static float3 FragColor;
+static float3 vNormal;
+
+struct SPIRV_Cross_Input
+{
+ nointerpolation float3 vNormal : TEXCOORD0;
+};
+
+struct SPIRV_Cross_Output
+{
+ float3 FragColor : SV_Target0;
+};
+
+void frag_main()
+{
+ float4x4 _19 = float4x4(UBO[0], UBO[1], UBO[2], UBO[3]);
+ FragColor = mul(vNormal, float3x3(_19[0].xyz, _19[1].xyz, _19[2].xyz));
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ vNormal = stage_input.vNormal;
+ frag_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.FragColor = FragColor;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/matrixindex.flatten.vert b/reference/opt/shaders-hlsl/flatten/matrixindex.flatten.vert
new file mode 100644
index 00000000..b69a72dc
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/matrixindex.flatten.vert
@@ -0,0 +1,41 @@
+uniform float4 UBO[14];
+
+static float4 gl_Position;
+static float4 oA;
+static float4 oB;
+static float4 oC;
+static float4 oD;
+static float4 oE;
+
+struct SPIRV_Cross_Output
+{
+ float4 oA : TEXCOORD0;
+ float4 oB : TEXCOORD1;
+ float4 oC : TEXCOORD2;
+ float4 oD : TEXCOORD3;
+ float4 oE : TEXCOORD4;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = 0.0f.xxxx;
+ oA = UBO[1];
+ oB = float4(UBO[4].y, UBO[5].y, UBO[6].y, UBO[7].y);
+ oC = UBO[9];
+ oD = float4(UBO[10].x, UBO[11].x, UBO[12].x, UBO[13].x);
+ oE = float4(UBO[1].z, UBO[6].y, UBO[9].z, UBO[12].y);
+}
+
+SPIRV_Cross_Output main()
+{
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.oA = oA;
+ stage_output.oB = oB;
+ stage_output.oC = oC;
+ stage_output.oD = oD;
+ stage_output.oE = oE;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/multiindex.flatten.vert b/reference/opt/shaders-hlsl/flatten/multiindex.flatten.vert
new file mode 100644
index 00000000..f21f05ec
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/multiindex.flatten.vert
@@ -0,0 +1,28 @@
+uniform float4 UBO[15];
+
+static float4 gl_Position;
+static int2 aIndex;
+
+struct SPIRV_Cross_Input
+{
+ int2 aIndex : TEXCOORD0;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = UBO[aIndex.x * 5 + aIndex.y * 1 + 0];
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aIndex = stage_input.aIndex;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/push-constant.flatten.vert b/reference/opt/shaders-hlsl/flatten/push-constant.flatten.vert
new file mode 100644
index 00000000..5bfb4dc0
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/push-constant.flatten.vert
@@ -0,0 +1,35 @@
+uniform float4 PushMe[6];
+
+static float4 gl_Position;
+static float4 Pos;
+static float2 vRot;
+static float2 Rot;
+
+struct SPIRV_Cross_Input
+{
+ float2 Rot : TEXCOORD0;
+ float4 Pos : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float2 vRot : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(Pos, float4x4(PushMe[0], PushMe[1], PushMe[2], PushMe[3]));
+ vRot = mul(Rot, float2x2(PushMe[4].xy, PushMe[4].zw)) + PushMe[5].z.xx;
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ Pos = stage_input.Pos;
+ Rot = stage_input.Rot;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vRot = vRot;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/rowmajor.flatten.vert b/reference/opt/shaders-hlsl/flatten/rowmajor.flatten.vert
new file mode 100644
index 00000000..2560484e
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/rowmajor.flatten.vert
@@ -0,0 +1,28 @@
+uniform float4 UBO[12];
+
+static float4 gl_Position;
+static float4 aVertex;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3])) + mul(aVertex, transpose(float4x4(UBO[4], UBO[5], UBO[6], UBO[7])));
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/struct.flatten.vert b/reference/opt/shaders-hlsl/flatten/struct.flatten.vert
new file mode 100644
index 00000000..41ad8ce9
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/struct.flatten.vert
@@ -0,0 +1,44 @@
+struct Light
+{
+ float3 Position;
+ float Radius;
+ float4 Color;
+};
+
+uniform float4 UBO[6];
+
+static float4 gl_Position;
+static float4 aVertex;
+static float4 vColor;
+static float3 aNormal;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+ float3 aNormal : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 vColor : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3]));
+ vColor = 0.0f.xxxx;
+ float3 _39 = aVertex.xyz - UBO[4].xyz;
+ vColor += ((UBO[5] * clamp(1.0f - (length(_39) / UBO[4].w), 0.0f, 1.0f)) * dot(aNormal, normalize(_39)));
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ aNormal = stage_input.aNormal;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vColor = vColor;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/struct.rowmajor.flatten.vert b/reference/opt/shaders-hlsl/flatten/struct.rowmajor.flatten.vert
new file mode 100644
index 00000000..bb702907
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/struct.rowmajor.flatten.vert
@@ -0,0 +1,43 @@
+struct Foo
+{
+ column_major float3x4 MVP0;
+ column_major float3x4 MVP1;
+};
+
+uniform float4 UBO[8];
+
+static float4 v0;
+static float4 v1;
+static float3 V0;
+static float3 V1;
+
+struct SPIRV_Cross_Input
+{
+ float4 v0 : TEXCOORD0;
+ float4 v1 : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float3 V0 : TEXCOORD0;
+ float3 V1 : TEXCOORD1;
+};
+
+void vert_main()
+{
+ Foo _19 = {transpose(float4x3(UBO[0].xyz, UBO[1].xyz, UBO[2].xyz, UBO[3].xyz)), transpose(float4x3(UBO[4].xyz, UBO[5].xyz, UBO[6].xyz, UBO[7].xyz))};
+ Foo _20 = _19;
+ V0 = mul(_20.MVP0, v0);
+ V1 = mul(_20.MVP1, v1);
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ v0 = stage_input.v0;
+ v1 = stage_input.v1;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.V0 = V0;
+ stage_output.V1 = V1;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/swizzle.flatten.vert b/reference/opt/shaders-hlsl/flatten/swizzle.flatten.vert
new file mode 100644
index 00000000..1091a17e
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/swizzle.flatten.vert
@@ -0,0 +1,45 @@
+uniform float4 UBO[8];
+
+static float4 gl_Position;
+static float4 oA;
+static float4 oB;
+static float4 oC;
+static float4 oD;
+static float4 oE;
+static float4 oF;
+
+struct SPIRV_Cross_Output
+{
+ float4 oA : TEXCOORD0;
+ float4 oB : TEXCOORD1;
+ float4 oC : TEXCOORD2;
+ float4 oD : TEXCOORD3;
+ float4 oE : TEXCOORD4;
+ float4 oF : TEXCOORD5;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = 0.0f.xxxx;
+ oA = UBO[0];
+ oB = float4(UBO[1].xy, UBO[1].zw);
+ oC = float4(UBO[2].x, UBO[3].xyz);
+ oD = float4(UBO[4].xyz, UBO[4].w);
+ oE = float4(UBO[5].x, UBO[5].y, UBO[5].z, UBO[5].w);
+ oF = float4(UBO[6].x, UBO[6].zw, UBO[7].x);
+}
+
+SPIRV_Cross_Output main()
+{
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.oA = oA;
+ stage_output.oB = oB;
+ stage_output.oC = oC;
+ stage_output.oD = oD;
+ stage_output.oE = oE;
+ stage_output.oF = oF;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-hlsl/flatten/types.flatten.frag b/reference/opt/shaders-hlsl/flatten/types.flatten.frag
new file mode 100644
index 00000000..feb0b360
--- /dev/null
+++ b/reference/opt/shaders-hlsl/flatten/types.flatten.frag
@@ -0,0 +1,23 @@
+uniform int4 UBO1[2];
+uniform uint4 UBO2[2];
+uniform float4 UBO0[2];
+
+static float4 FragColor;
+
+struct SPIRV_Cross_Output
+{
+ float4 FragColor : SV_Target0;
+};
+
+void frag_main()
+{
+ FragColor = ((((float4(UBO1[0]) + float4(UBO1[1])) + float4(UBO2[0])) + float4(UBO2[1])) + UBO0[0]) + UBO0[1];
+}
+
+SPIRV_Cross_Output main()
+{
+ frag_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.FragColor = FragColor;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/array.flatten.vert b/reference/shaders-hlsl/flatten/array.flatten.vert
new file mode 100644
index 00000000..948a198e
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/array.flatten.vert
@@ -0,0 +1,30 @@
+uniform float4 UBO[56];
+
+static float4 gl_Position;
+static float4 aVertex;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ float4 a4 = UBO[23];
+ float4 offset = (UBO[50] + UBO[45]) + UBO[54].x.xxxx;
+ gl_Position = (mul(aVertex, float4x4(UBO[40], UBO[41], UBO[42], UBO[43])) + UBO[55]) + offset;
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/basic.flatten.vert b/reference/shaders-hlsl/flatten/basic.flatten.vert
new file mode 100644
index 00000000..778acd48
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/basic.flatten.vert
@@ -0,0 +1,35 @@
+uniform float4 UBO[4];
+
+static float4 gl_Position;
+static float4 aVertex;
+static float3 vNormal;
+static float3 aNormal;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+ float3 aNormal : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float3 vNormal : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3]));
+ vNormal = aNormal;
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ aNormal = stage_input.aNormal;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vNormal = vNormal;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/copy.flatten.vert b/reference/shaders-hlsl/flatten/copy.flatten.vert
new file mode 100644
index 00000000..f85c890b
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/copy.flatten.vert
@@ -0,0 +1,53 @@
+struct Light
+{
+ float3 Position;
+ float Radius;
+ float4 Color;
+};
+
+uniform float4 UBO[12];
+
+static float4 gl_Position;
+static float4 aVertex;
+static float4 vColor;
+static float3 aNormal;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+ float3 aNormal : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 vColor : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3]));
+ vColor = 0.0f.xxxx;
+ Light light;
+ for (int i = 0; i < 4; i++)
+ {
+ Light _51 = {UBO[i * 2 + 4].xyz, UBO[i * 2 + 4].w, UBO[i * 2 + 5]};
+ Light _52 = _51;
+ light.Position = _52.Position;
+ light.Radius = _52.Radius;
+ light.Color = _52.Color;
+ float3 L = aVertex.xyz - light.Position;
+ vColor += ((UBO[i * 2 + 5] * clamp(1.0f - (length(L) / light.Radius), 0.0f, 1.0f)) * dot(aNormal, normalize(L)));
+ }
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ aNormal = stage_input.aNormal;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vColor = vColor;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/dynamic.flatten.vert b/reference/shaders-hlsl/flatten/dynamic.flatten.vert
new file mode 100644
index 00000000..787eefcd
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/dynamic.flatten.vert
@@ -0,0 +1,47 @@
+struct Light
+{
+ float3 Position;
+ float Radius;
+ float4 Color;
+};
+
+uniform float4 UBO[12];
+
+static float4 gl_Position;
+static float4 aVertex;
+static float4 vColor;
+static float3 aNormal;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+ float3 aNormal : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 vColor : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3]));
+ vColor = 0.0f.xxxx;
+ for (int i = 0; i < 4; i++)
+ {
+ float3 L = aVertex.xyz - UBO[i * 2 + 4].xyz;
+ vColor += ((UBO[i * 2 + 5] * clamp(1.0f - (length(L) / UBO[i * 2 + 4].w), 0.0f, 1.0f)) * dot(aNormal, normalize(L)));
+ }
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ aNormal = stage_input.aNormal;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vColor = vColor;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/matrix-conversion.flatten.frag b/reference/shaders-hlsl/flatten/matrix-conversion.flatten.frag
new file mode 100644
index 00000000..59ec525f
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/matrix-conversion.flatten.frag
@@ -0,0 +1,29 @@
+uniform float4 UBO[4];
+
+static float3 FragColor;
+static float3 vNormal;
+
+struct SPIRV_Cross_Input
+{
+ nointerpolation float3 vNormal : TEXCOORD0;
+};
+
+struct SPIRV_Cross_Output
+{
+ float3 FragColor : SV_Target0;
+};
+
+void frag_main()
+{
+ float4x4 _19 = float4x4(UBO[0], UBO[1], UBO[2], UBO[3]);
+ FragColor = mul(vNormal, float3x3(_19[0].xyz, _19[1].xyz, _19[2].xyz));
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ vNormal = stage_input.vNormal;
+ frag_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.FragColor = FragColor;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/matrixindex.flatten.vert b/reference/shaders-hlsl/flatten/matrixindex.flatten.vert
new file mode 100644
index 00000000..b69a72dc
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/matrixindex.flatten.vert
@@ -0,0 +1,41 @@
+uniform float4 UBO[14];
+
+static float4 gl_Position;
+static float4 oA;
+static float4 oB;
+static float4 oC;
+static float4 oD;
+static float4 oE;
+
+struct SPIRV_Cross_Output
+{
+ float4 oA : TEXCOORD0;
+ float4 oB : TEXCOORD1;
+ float4 oC : TEXCOORD2;
+ float4 oD : TEXCOORD3;
+ float4 oE : TEXCOORD4;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = 0.0f.xxxx;
+ oA = UBO[1];
+ oB = float4(UBO[4].y, UBO[5].y, UBO[6].y, UBO[7].y);
+ oC = UBO[9];
+ oD = float4(UBO[10].x, UBO[11].x, UBO[12].x, UBO[13].x);
+ oE = float4(UBO[1].z, UBO[6].y, UBO[9].z, UBO[12].y);
+}
+
+SPIRV_Cross_Output main()
+{
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.oA = oA;
+ stage_output.oB = oB;
+ stage_output.oC = oC;
+ stage_output.oD = oD;
+ stage_output.oE = oE;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/multiindex.flatten.vert b/reference/shaders-hlsl/flatten/multiindex.flatten.vert
new file mode 100644
index 00000000..f21f05ec
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/multiindex.flatten.vert
@@ -0,0 +1,28 @@
+uniform float4 UBO[15];
+
+static float4 gl_Position;
+static int2 aIndex;
+
+struct SPIRV_Cross_Input
+{
+ int2 aIndex : TEXCOORD0;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = UBO[aIndex.x * 5 + aIndex.y * 1 + 0];
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aIndex = stage_input.aIndex;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/push-constant.flatten.vert b/reference/shaders-hlsl/flatten/push-constant.flatten.vert
new file mode 100644
index 00000000..5bfb4dc0
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/push-constant.flatten.vert
@@ -0,0 +1,35 @@
+uniform float4 PushMe[6];
+
+static float4 gl_Position;
+static float4 Pos;
+static float2 vRot;
+static float2 Rot;
+
+struct SPIRV_Cross_Input
+{
+ float2 Rot : TEXCOORD0;
+ float4 Pos : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float2 vRot : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(Pos, float4x4(PushMe[0], PushMe[1], PushMe[2], PushMe[3]));
+ vRot = mul(Rot, float2x2(PushMe[4].xy, PushMe[4].zw)) + PushMe[5].z.xx;
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ Pos = stage_input.Pos;
+ Rot = stage_input.Rot;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vRot = vRot;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/rowmajor.flatten.vert b/reference/shaders-hlsl/flatten/rowmajor.flatten.vert
new file mode 100644
index 00000000..801def3b
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/rowmajor.flatten.vert
@@ -0,0 +1,29 @@
+uniform float4 UBO[12];
+
+static float4 gl_Position;
+static float4 aVertex;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ float2 v = mul(transpose(float4x2(UBO[8].xy, UBO[9].xy, UBO[10].xy, UBO[11].xy)), aVertex);
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3])) + mul(aVertex, transpose(float4x4(UBO[4], UBO[5], UBO[6], UBO[7])));
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/struct.flatten.vert b/reference/shaders-hlsl/flatten/struct.flatten.vert
new file mode 100644
index 00000000..9b97bf59
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/struct.flatten.vert
@@ -0,0 +1,44 @@
+struct Light
+{
+ float3 Position;
+ float Radius;
+ float4 Color;
+};
+
+uniform float4 UBO[6];
+
+static float4 gl_Position;
+static float4 aVertex;
+static float4 vColor;
+static float3 aNormal;
+
+struct SPIRV_Cross_Input
+{
+ float4 aVertex : TEXCOORD0;
+ float3 aNormal : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float4 vColor : TEXCOORD0;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = mul(aVertex, float4x4(UBO[0], UBO[1], UBO[2], UBO[3]));
+ vColor = 0.0f.xxxx;
+ float3 L = aVertex.xyz - UBO[4].xyz;
+ vColor += ((UBO[5] * clamp(1.0f - (length(L) / UBO[4].w), 0.0f, 1.0f)) * dot(aNormal, normalize(L)));
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ aVertex = stage_input.aVertex;
+ aNormal = stage_input.aNormal;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.vColor = vColor;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/struct.rowmajor.flatten.vert b/reference/shaders-hlsl/flatten/struct.rowmajor.flatten.vert
new file mode 100644
index 00000000..39b0a808
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/struct.rowmajor.flatten.vert
@@ -0,0 +1,48 @@
+struct Foo
+{
+ column_major float3x4 MVP0;
+ column_major float3x4 MVP1;
+};
+
+uniform float4 UBO[8];
+
+static float4 v0;
+static float4 v1;
+static float3 V0;
+static float3 V1;
+
+struct SPIRV_Cross_Input
+{
+ float4 v0 : TEXCOORD0;
+ float4 v1 : TEXCOORD1;
+};
+
+struct SPIRV_Cross_Output
+{
+ float3 V0 : TEXCOORD0;
+ float3 V1 : TEXCOORD1;
+};
+
+void vert_main()
+{
+ Foo _19 = {transpose(float4x3(UBO[0].xyz, UBO[1].xyz, UBO[2].xyz, UBO[3].xyz)), transpose(float4x3(UBO[4].xyz, UBO[5].xyz, UBO[6].xyz, UBO[7].xyz))};
+ Foo _20 = _19;
+ Foo f;
+ f.MVP0 = _20.MVP0;
+ f.MVP1 = _20.MVP1;
+ float3 a = mul(f.MVP0, v0);
+ float3 b = mul(f.MVP1, v1);
+ V0 = a;
+ V1 = b;
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+ v0 = stage_input.v0;
+ v1 = stage_input.v1;
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.V0 = V0;
+ stage_output.V1 = V1;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/swizzle.flatten.vert b/reference/shaders-hlsl/flatten/swizzle.flatten.vert
new file mode 100644
index 00000000..1091a17e
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/swizzle.flatten.vert
@@ -0,0 +1,45 @@
+uniform float4 UBO[8];
+
+static float4 gl_Position;
+static float4 oA;
+static float4 oB;
+static float4 oC;
+static float4 oD;
+static float4 oE;
+static float4 oF;
+
+struct SPIRV_Cross_Output
+{
+ float4 oA : TEXCOORD0;
+ float4 oB : TEXCOORD1;
+ float4 oC : TEXCOORD2;
+ float4 oD : TEXCOORD3;
+ float4 oE : TEXCOORD4;
+ float4 oF : TEXCOORD5;
+ float4 gl_Position : SV_Position;
+};
+
+void vert_main()
+{
+ gl_Position = 0.0f.xxxx;
+ oA = UBO[0];
+ oB = float4(UBO[1].xy, UBO[1].zw);
+ oC = float4(UBO[2].x, UBO[3].xyz);
+ oD = float4(UBO[4].xyz, UBO[4].w);
+ oE = float4(UBO[5].x, UBO[5].y, UBO[5].z, UBO[5].w);
+ oF = float4(UBO[6].x, UBO[6].zw, UBO[7].x);
+}
+
+SPIRV_Cross_Output main()
+{
+ vert_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_Position = gl_Position;
+ stage_output.oA = oA;
+ stage_output.oB = oB;
+ stage_output.oC = oC;
+ stage_output.oD = oD;
+ stage_output.oE = oE;
+ stage_output.oF = oF;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl/flatten/types.flatten.frag b/reference/shaders-hlsl/flatten/types.flatten.frag
new file mode 100644
index 00000000..feb0b360
--- /dev/null
+++ b/reference/shaders-hlsl/flatten/types.flatten.frag
@@ -0,0 +1,23 @@
+uniform int4 UBO1[2];
+uniform uint4 UBO2[2];
+uniform float4 UBO0[2];
+
+static float4 FragColor;
+
+struct SPIRV_Cross_Output
+{
+ float4 FragColor : SV_Target0;
+};
+
+void frag_main()
+{
+ FragColor = ((((float4(UBO1[0]) + float4(UBO1[1])) + float4(UBO2[0])) + float4(UBO2[1])) + UBO0[0]) + UBO0[1];
+}
+
+SPIRV_Cross_Output main()
+{
+ frag_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.FragColor = FragColor;
+ return stage_output;
+}
diff --git a/shaders-hlsl/flatten/array.flatten.vert b/shaders-hlsl/flatten/array.flatten.vert
new file mode 100644
index 00000000..fa6da076
--- /dev/null
+++ b/shaders-hlsl/flatten/array.flatten.vert
@@ -0,0 +1,19 @@
+#version 310 es
+
+layout(std140) uniform UBO
+{
+ vec4 A4[5][4][2];
+ mat4 uMVP;
+ vec4 A1[2];
+ vec4 A2[2][3];
+ float A3[3];
+ vec4 Offset;
+};
+layout(location = 0) in vec4 aVertex;
+
+void main()
+{
+ vec4 a4 = A4[2][3][1]; // 2 * (4 * 2) + 3 * 2 + 1 = 16 + 6 + 1 = 23.
+ vec4 offset = A2[1][1] + A1[1] + A3[2];
+ gl_Position = uMVP * aVertex + Offset + offset;
+}
diff --git a/shaders-hlsl/flatten/basic.flatten.vert b/shaders-hlsl/flatten/basic.flatten.vert
new file mode 100644
index 00000000..e60a9067
--- /dev/null
+++ b/shaders-hlsl/flatten/basic.flatten.vert
@@ -0,0 +1,16 @@
+#version 310 es
+
+layout(std140) uniform UBO
+{
+ mat4 uMVP;
+};
+
+layout(location = 0) in vec4 aVertex;
+layout(location = 1) in vec3 aNormal;
+layout(location = 0) out vec3 vNormal;
+
+void main()
+{
+ gl_Position = uMVP * aVertex;
+ vNormal = aNormal;
+}
diff --git a/shaders-hlsl/flatten/copy.flatten.vert b/shaders-hlsl/flatten/copy.flatten.vert
new file mode 100644
index 00000000..4f1b8805
--- /dev/null
+++ b/shaders-hlsl/flatten/copy.flatten.vert
@@ -0,0 +1,34 @@
+#version 310 es
+
+struct Light
+{
+ vec3 Position;
+ float Radius;
+
+ vec4 Color;
+};
+
+layout(std140) uniform UBO
+{
+ mat4 uMVP;
+
+ Light lights[4];
+};
+
+layout(location = 0) in vec4 aVertex;
+layout(location = 1) in vec3 aNormal;
+layout(location = 0) out vec4 vColor;
+
+void main()
+{
+ gl_Position = uMVP * aVertex;
+
+ vColor = vec4(0.0);
+
+ for (int i = 0; i < 4; ++i)
+ {
+ Light light = lights[i];
+ vec3 L = aVertex.xyz - light.Position;
+ vColor += dot(aNormal, normalize(L)) * (clamp(1.0 - length(L) / light.Radius, 0.0, 1.0) * lights[i].Color);
+ }
+}
diff --git a/shaders-hlsl/flatten/dynamic.flatten.vert b/shaders-hlsl/flatten/dynamic.flatten.vert
new file mode 100644
index 00000000..a341d452
--- /dev/null
+++ b/shaders-hlsl/flatten/dynamic.flatten.vert
@@ -0,0 +1,33 @@
+#version 310 es
+
+struct Light
+{
+ vec3 Position;
+ float Radius;
+
+ vec4 Color;
+};
+
+layout(std140) uniform UBO
+{
+ mat4 uMVP;
+
+ Light lights[4];
+};
+
+layout(location = 0) in vec4 aVertex;
+layout(location = 1) in vec3 aNormal;
+layout(location = 0) out vec4 vColor;
+
+void main()
+{
+ gl_Position = uMVP * aVertex;
+
+ vColor = vec4(0.0);
+
+ for (int i = 0; i < 4; ++i)
+ {
+ vec3 L = aVertex.xyz - lights[i].Position;
+ vColor += dot(aNormal, normalize(L)) * (clamp(1.0 - length(L) / lights[i].Radius, 0.0, 1.0) * lights[i].Color);
+ }
+}
diff --git a/shaders-hlsl/flatten/matrix-conversion.flatten.frag b/shaders-hlsl/flatten/matrix-conversion.flatten.frag
new file mode 100644
index 00000000..427825c3
--- /dev/null
+++ b/shaders-hlsl/flatten/matrix-conversion.flatten.frag
@@ -0,0 +1,14 @@
+#version 310 es
+precision mediump float;
+layout(location = 0) out vec3 FragColor;
+layout(location = 0) flat in vec3 vNormal;
+
+layout(binding = 0, std140) uniform UBO
+{
+ mat4 m;
+};
+
+void main()
+{
+ FragColor = mat3(m) * vNormal;
+}
diff --git a/shaders-hlsl/flatten/matrixindex.flatten.vert b/shaders-hlsl/flatten/matrixindex.flatten.vert
new file mode 100644
index 00000000..0ee78384
--- /dev/null
+++ b/shaders-hlsl/flatten/matrixindex.flatten.vert
@@ -0,0 +1,25 @@
+#version 310 es
+
+layout(std140) uniform UBO
+{
+ layout(column_major) mat4 M1C;
+ layout(row_major) mat4 M1R;
+ layout(column_major) mat2x4 M2C;
+ layout(row_major) mat2x4 M2R;
+};
+
+layout(location = 0) out vec4 oA;
+layout(location = 1) out vec4 oB;
+layout(location = 2) out vec4 oC;
+layout(location = 3) out vec4 oD;
+layout(location = 4) out vec4 oE;
+
+void main()
+{
+ gl_Position = vec4(0.0);
+ oA = M1C[1];
+ oB = M1R[1];
+ oC = M2C[1];
+ oD = M2R[0];
+ oE = vec4(M1C[1][2], M1R[1][2], M2C[1][2], M2R[1][2]);
+}
diff --git a/shaders-hlsl/flatten/multiindex.flatten.vert b/shaders-hlsl/flatten/multiindex.flatten.vert
new file mode 100644
index 00000000..0b471d86
--- /dev/null
+++ b/shaders-hlsl/flatten/multiindex.flatten.vert
@@ -0,0 +1,13 @@
+#version 310 es
+
+layout(std140) uniform UBO
+{
+ vec4 Data[3][5];
+};
+
+layout(location = 0) in ivec2 aIndex;
+
+void main()
+{
+ gl_Position = Data[aIndex.x][aIndex.y];
+}
diff --git a/shaders-hlsl/flatten/push-constant.flatten.vert b/shaders-hlsl/flatten/push-constant.flatten.vert
new file mode 100644
index 00000000..c7b1b42e
--- /dev/null
+++ b/shaders-hlsl/flatten/push-constant.flatten.vert
@@ -0,0 +1,17 @@
+#version 310 es
+
+layout(push_constant, std430) uniform PushMe
+{
+ mat4 MVP;
+ mat2 Rot; // The MatrixStride will be 8 here.
+ float Arr[4];
+} registers;
+
+layout(location = 0) in vec2 Rot;
+layout(location = 1) in vec4 Pos;
+layout(location = 0) out vec2 vRot;
+void main()
+{
+ gl_Position = registers.MVP * Pos;
+ vRot = registers.Rot * Rot + registers.Arr[2]; // Constant access should work even if array stride is just 4 here.
+}
diff --git a/shaders-hlsl/flatten/rowmajor.flatten.vert b/shaders-hlsl/flatten/rowmajor.flatten.vert
new file mode 100644
index 00000000..88c468c8
--- /dev/null
+++ b/shaders-hlsl/flatten/rowmajor.flatten.vert
@@ -0,0 +1,16 @@
+#version 310 es
+
+layout(std140) uniform UBO
+{
+ layout(column_major) mat4 uMVPR;
+ layout(row_major) mat4 uMVPC;
+ layout(row_major) mat2x4 uMVP;
+};
+
+layout(location = 0) in vec4 aVertex;
+
+void main()
+{
+ vec2 v = aVertex * uMVP;
+ gl_Position = uMVPR * aVertex + uMVPC * aVertex;
+}
diff --git a/shaders-hlsl/flatten/struct.flatten.vert b/shaders-hlsl/flatten/struct.flatten.vert
new file mode 100644
index 00000000..936bb41b
--- /dev/null
+++ b/shaders-hlsl/flatten/struct.flatten.vert
@@ -0,0 +1,30 @@
+#version 310 es
+
+struct Light
+{
+ vec3 Position;
+ float Radius;
+
+ vec4 Color;
+};
+
+layout(std140) uniform UBO
+{
+ mat4 uMVP;
+
+ Light light;
+};
+
+layout(location = 0) in vec4 aVertex;
+layout(location = 1) in vec3 aNormal;
+layout(location = 0) out vec4 vColor;
+
+void main()
+{
+ gl_Position = uMVP * aVertex;
+
+ vColor = vec4(0.0);
+
+ vec3 L = aVertex.xyz - light.Position;
+ vColor += dot(aNormal, normalize(L)) * (clamp(1.0 - length(L) / light.Radius, 0.0, 1.0) * light.Color);
+}
diff --git a/shaders-hlsl/flatten/struct.rowmajor.flatten.vert b/shaders-hlsl/flatten/struct.rowmajor.flatten.vert
new file mode 100644
index 00000000..231389b8
--- /dev/null
+++ b/shaders-hlsl/flatten/struct.rowmajor.flatten.vert
@@ -0,0 +1,26 @@
+#version 310 es
+
+struct Foo
+{
+ mat3x4 MVP0;
+ mat3x4 MVP1;
+};
+
+layout(std140, binding = 0) uniform UBO
+{
+ layout(row_major) Foo foo;
+};
+
+layout(location = 0) in vec4 v0;
+layout(location = 1) in vec4 v1;
+layout(location = 0) out vec3 V0;
+layout(location = 1) out vec3 V1;
+
+void main()
+{
+ Foo f = foo;
+ vec3 a = v0 * f.MVP0;
+ vec3 b = v1 * f.MVP1;
+ V0 = a;
+ V1 = b;
+}
diff --git a/shaders-hlsl/flatten/swizzle.flatten.vert b/shaders-hlsl/flatten/swizzle.flatten.vert
new file mode 100644
index 00000000..fafff773
--- /dev/null
+++ b/shaders-hlsl/flatten/swizzle.flatten.vert
@@ -0,0 +1,47 @@
+#version 310 es
+
+// comments note the 16b alignment boundaries (see GL spec 7.6.2.2 Standard Uniform Block Layout)
+layout(std140, binding = 0) uniform UBO
+{
+ // 16b boundary
+ vec4 A;
+ // 16b boundary
+ vec2 B0;
+ vec2 B1;
+ // 16b boundary
+ float C0;
+ // 16b boundary (vec3 is aligned to 16b)
+ vec3 C1;
+ // 16b boundary
+ vec3 D0;
+ float D1;
+ // 16b boundary
+ float E0;
+ float E1;
+ float E2;
+ float E3;
+ // 16b boundary
+ float F0;
+ vec2 F1;
+ // 16b boundary (vec2 before us is aligned to 8b)
+ float F2;
+};
+
+layout(location = 0) out vec4 oA;
+layout(location = 1) out vec4 oB;
+layout(location = 2) out vec4 oC;
+layout(location = 3) out vec4 oD;
+layout(location = 4) out vec4 oE;
+layout(location = 5) out vec4 oF;
+
+void main()
+{
+ gl_Position = vec4(0.0);
+
+ oA = A;
+ oB = vec4(B0, B1);
+ oC = vec4(C0, C1);
+ oD = vec4(D0, D1);
+ oE = vec4(E0, E1, E2, E3);
+ oF = vec4(F0, F1, F2);
+}
diff --git a/shaders-hlsl/flatten/types.flatten.frag b/shaders-hlsl/flatten/types.flatten.frag
new file mode 100644
index 00000000..faab5b7e
--- /dev/null
+++ b/shaders-hlsl/flatten/types.flatten.frag
@@ -0,0 +1,27 @@
+#version 310 es
+precision mediump float;
+
+layout(std140, binding = 0) uniform UBO0
+{
+ vec4 a;
+ vec4 b;
+};
+
+layout(std140, binding = 0) uniform UBO1
+{
+ ivec4 c;
+ ivec4 d;
+};
+
+layout(std140, binding = 0) uniform UBO2
+{
+ uvec4 e;
+ uvec4 f;
+};
+
+layout(location = 0) out vec4 FragColor;
+
+void main()
+{
+ FragColor = vec4(c) + vec4(d) + vec4(e) + vec4(f) + a + b;
+}
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index 6d54d878..20739ea8 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -9184,8 +9184,13 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin
{
std::string expr;
- expr += type_to_glsl_constructor(target_type);
- expr += "(";
+ if (backend.can_declare_struct_inline)
+ {
+ expr += type_to_glsl_constructor(target_type);
+ expr += "(";
+ }
+ else
+ expr += "{";
for (uint32_t i = 0; i < uint32_t(target_type.member_types.size()); ++i)
{
@@ -9215,7 +9220,7 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin
expr += tmp;
}
- expr += ")";
+ expr += backend.can_declare_struct_inline ? ")" : "}";
return expr;
}
@@ -10232,9 +10237,19 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
// If an expression is mutable and forwardable, we speculate that it is immutable.
AccessChainMeta meta;
bool ptr_chain = opcode == OpPtrAccessChain;
- auto e = access_chain(ops[2], &ops[3], length - 3, get<SPIRType>(ops[0]), &meta, ptr_chain);
-
- auto &expr = set<SPIRExpression>(ops[1], move(e), ops[0], should_forward(ops[2]));
+ auto &target_type = get<SPIRType>(ops[0]);
+ auto e = access_chain(ops[2], &ops[3], length - 3, target_type, &meta, ptr_chain);
+
+ // If the base is flattened UBO of struct type, the expression has to be a composite.
+ // In that case, backends which do not support inline syntax need it to be bound to a temporary.
+ // Otherwise, invalid expressions like ({UBO[0].xyz, UBO[0].w, UBO[1]}).member are emitted.
+ bool requires_temporary = false;
+ if (flattened_buffer_blocks.count(ops[2]) && target_type.basetype == SPIRType::Struct)
+ requires_temporary = !backend.can_declare_struct_inline;
+
+ auto &expr = requires_temporary ?
+ emit_op(ops[0], ops[1], move(e), false) :
+ set<SPIRExpression>(ops[1], move(e), ops[0], should_forward(ops[2]));
auto *backing_variable = maybe_get_backing_variable(ops[2]);
expr.loaded_from = backing_variable ? backing_variable->self : ID(ops[2]);
diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp
index 3d834774..51d4a1ca 100644
--- a/spirv_hlsl.cpp
+++ b/spirv_hlsl.cpp
@@ -2102,7 +2102,11 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
bool is_uav = var.storage == StorageClassStorageBuffer || has_decoration(type.self, DecorationBufferBlock);
- if (is_uav)
+ if (flattened_buffer_blocks.count(var.self))
+ {
+ emit_buffer_block_flattened(var);
+ }
+ else if (is_uav)
{
Bitset flags = ir.get_buffer_block_flags(var);
bool is_readonly = flags.get(DecorationNonWritable) && !is_hlsl_force_storage_buffer_as_uav(var.self);
@@ -2207,7 +2211,11 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var)
{
- if (root_constants_layout.empty())
+ if (flattened_buffer_blocks.count(var.self))
+ {
+ emit_buffer_block_flattened(var);
+ }
+ else if (root_constants_layout.empty())
{
emit_buffer_block(var);
}
diff --git a/test_shaders.py b/test_shaders.py
index eca78c32..640baa23 100755
--- a/test_shaders.py
+++ b/test_shaders.py
@@ -462,6 +462,8 @@ def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation, iterati
hlsl_args = [spirv_cross_path, '--entry', 'main', '--output', hlsl_path, spirv_path, '--hlsl-enable-compat', '--hlsl', '--shader-model', sm, '--iterations', str(iterations)]
if '.line.' in shader:
hlsl_args.append('--emit-line-directives')
+ if '.flatten.' in shader:
+ hlsl_args.append('--flatten-ubo')
if '.force-uav.' in shader:
hlsl_args.append('--hlsl-force-storage-buffer-as-uav')
if '.zero-initialize.' in shader: