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>2019-01-30 12:29:08 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2019-01-30 12:29:08 +0300
commit3e098791313ecc8c91cbfa9d29ab36346db0f355 (patch)
treed3d083a4d4d9025643b022b19e9700d1addd458f
parent5ff12d780b36d75c9a7c7c8886e18c54d7b8ec10 (diff)
Support initializers on StorageClassOutput.fix-838
-rw-r--r--reference/opt/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag23
-rw-r--r--reference/opt/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag24
-rw-r--r--reference/opt/shaders/asm/frag/storage-class-output-initializer.asm.frag11
-rw-r--r--reference/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag23
-rw-r--r--reference/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag24
-rw-r--r--reference/shaders/asm/frag/storage-class-output-initializer.asm.frag11
-rw-r--r--shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag41
-rw-r--r--shaders-msl/asm/frag/storage-class-output-initializer.asm.frag41
-rw-r--r--shaders/asm/frag/storage-class-output-initializer.asm.frag41
-rw-r--r--spirv_cross.cpp6
-rw-r--r--spirv_glsl.cpp9
-rw-r--r--spirv_msl.cpp18
12 files changed, 268 insertions, 4 deletions
diff --git a/reference/opt/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag b/reference/opt/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..1905b5ea
--- /dev/null
+++ b/reference/opt/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,23 @@
+static const float4 _20[2] = { float4(1.0f, 2.0f, 3.0f, 4.0f), 10.0f.xxxx };
+
+static float4 FragColors[2] = _20;
+static float4 FragColor = 5.0f.xxxx;
+
+struct SPIRV_Cross_Output
+{
+ float4 FragColors[2] : SV_Target0;
+ float4 FragColor : SV_Target2;
+};
+
+void frag_main()
+{
+}
+
+SPIRV_Cross_Output main()
+{
+ frag_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.FragColors = FragColors;
+ stage_output.FragColor = FragColor;
+ return stage_output;
+}
diff --git a/reference/opt/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag b/reference/opt/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..1bafc695
--- /dev/null
+++ b/reference/opt/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,24 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+constant float4 _20[2] = { float4(1.0, 2.0, 3.0, 4.0), float4(10.0) };
+
+struct main0_out
+{
+ float4 FragColors_0 [[color(0)]];
+ float4 FragColors_1 [[color(1)]];
+ float4 FragColor [[color(2)]];
+};
+
+fragment main0_out main0()
+{
+ main0_out out = {};
+ float4 FragColors[2] = { float4(1.0, 2.0, 3.0, 4.0), float4(10.0) };
+ out.FragColor = float4(5.0);
+ out.FragColors_0 = FragColors[0];
+ out.FragColors_1 = FragColors[1];
+ return out;
+}
+
diff --git a/reference/opt/shaders/asm/frag/storage-class-output-initializer.asm.frag b/reference/opt/shaders/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..22935875
--- /dev/null
+++ b/reference/opt/shaders/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,11 @@
+#version 450
+
+layout(location = 0) out vec4 FragColors[2];
+layout(location = 2) out vec4 FragColor;
+
+void main()
+{
+ FragColors = vec4[](vec4(1.0, 2.0, 3.0, 4.0), vec4(10.0));
+ FragColor = vec4(5.0);
+}
+
diff --git a/reference/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag b/reference/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..1905b5ea
--- /dev/null
+++ b/reference/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,23 @@
+static const float4 _20[2] = { float4(1.0f, 2.0f, 3.0f, 4.0f), 10.0f.xxxx };
+
+static float4 FragColors[2] = _20;
+static float4 FragColor = 5.0f.xxxx;
+
+struct SPIRV_Cross_Output
+{
+ float4 FragColors[2] : SV_Target0;
+ float4 FragColor : SV_Target2;
+};
+
+void frag_main()
+{
+}
+
+SPIRV_Cross_Output main()
+{
+ frag_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.FragColors = FragColors;
+ stage_output.FragColor = FragColor;
+ return stage_output;
+}
diff --git a/reference/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag b/reference/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..1bafc695
--- /dev/null
+++ b/reference/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,24 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+constant float4 _20[2] = { float4(1.0, 2.0, 3.0, 4.0), float4(10.0) };
+
+struct main0_out
+{
+ float4 FragColors_0 [[color(0)]];
+ float4 FragColors_1 [[color(1)]];
+ float4 FragColor [[color(2)]];
+};
+
+fragment main0_out main0()
+{
+ main0_out out = {};
+ float4 FragColors[2] = { float4(1.0, 2.0, 3.0, 4.0), float4(10.0) };
+ out.FragColor = float4(5.0);
+ out.FragColors_0 = FragColors[0];
+ out.FragColors_1 = FragColors[1];
+ return out;
+}
+
diff --git a/reference/shaders/asm/frag/storage-class-output-initializer.asm.frag b/reference/shaders/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..22935875
--- /dev/null
+++ b/reference/shaders/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,11 @@
+#version 450
+
+layout(location = 0) out vec4 FragColors[2];
+layout(location = 2) out vec4 FragColor;
+
+void main()
+{
+ FragColors = vec4[](vec4(1.0, 2.0, 3.0, 4.0), vec4(10.0));
+ FragColor = vec4(5.0);
+}
+
diff --git a/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag b/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..7763b7c1
--- /dev/null
+++ b/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,41 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 25
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %FragColors %FragColor
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 450
+ OpName %main "main"
+ OpName %FragColors "FragColors"
+ OpName %FragColor "FragColor"
+ OpDecorate %FragColors Location 0
+ OpDecorate %FragColor Location 2
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
+%_ptr_Output__arr_v4float_uint_2 = OpTypePointer Output %_arr_v4float_uint_2
+ %float_1 = OpConstant %float 1
+ %float_2 = OpConstant %float 2
+ %float_3 = OpConstant %float 3
+ %float_4 = OpConstant %float 4
+ %17 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+ %float_10 = OpConstant %float 10
+ %19 = OpConstantComposite %v4float %float_10 %float_10 %float_10 %float_10
+ %20 = OpConstantComposite %_arr_v4float_uint_2 %17 %19
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %float_5 = OpConstant %float 5
+ %24 = OpConstantComposite %v4float %float_5 %float_5 %float_5 %float_5
+ %FragColors = OpVariable %_ptr_Output__arr_v4float_uint_2 Output %20
+ %FragColor = OpVariable %_ptr_Output_v4float Output %24
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag b/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..7763b7c1
--- /dev/null
+++ b/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,41 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 25
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %FragColors %FragColor
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 450
+ OpName %main "main"
+ OpName %FragColors "FragColors"
+ OpName %FragColor "FragColor"
+ OpDecorate %FragColors Location 0
+ OpDecorate %FragColor Location 2
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
+%_ptr_Output__arr_v4float_uint_2 = OpTypePointer Output %_arr_v4float_uint_2
+ %float_1 = OpConstant %float 1
+ %float_2 = OpConstant %float 2
+ %float_3 = OpConstant %float 3
+ %float_4 = OpConstant %float 4
+ %17 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+ %float_10 = OpConstant %float 10
+ %19 = OpConstantComposite %v4float %float_10 %float_10 %float_10 %float_10
+ %20 = OpConstantComposite %_arr_v4float_uint_2 %17 %19
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %float_5 = OpConstant %float 5
+ %24 = OpConstantComposite %v4float %float_5 %float_5 %float_5 %float_5
+ %FragColors = OpVariable %_ptr_Output__arr_v4float_uint_2 Output %20
+ %FragColor = OpVariable %_ptr_Output_v4float Output %24
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/shaders/asm/frag/storage-class-output-initializer.asm.frag b/shaders/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 00000000..7763b7c1
--- /dev/null
+++ b/shaders/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,41 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 25
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %FragColors %FragColor
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 450
+ OpName %main "main"
+ OpName %FragColors "FragColors"
+ OpName %FragColor "FragColor"
+ OpDecorate %FragColors Location 0
+ OpDecorate %FragColor Location 2
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
+%_ptr_Output__arr_v4float_uint_2 = OpTypePointer Output %_arr_v4float_uint_2
+ %float_1 = OpConstant %float 1
+ %float_2 = OpConstant %float 2
+ %float_3 = OpConstant %float 3
+ %float_4 = OpConstant %float 4
+ %17 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+ %float_10 = OpConstant %float 10
+ %19 = OpConstantComposite %v4float %float_10 %float_10 %float_10 %float_10
+ %20 = OpConstantComposite %_arr_v4float_uint_2 %17 %19
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %float_5 = OpConstant %float 5
+ %24 = OpConstantComposite %v4float %float_5 %float_5 %float_5 %float_5
+ %FragColors = OpVariable %_ptr_Output__arr_v4float_uint_2 Output %20
+ %FragColor = OpVariable %_ptr_Output_v4float Output %24
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/spirv_cross.cpp b/spirv_cross.cpp
index ef3ec249..19bac301 100644
--- a/spirv_cross.cpp
+++ b/spirv_cross.cpp
@@ -701,6 +701,12 @@ unordered_set<uint32_t> Compiler::get_active_interface_variables() const
InterfaceVariableAccessHandler handler(*this, variables);
traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
+ // Make sure we preserve output variables which are only initialized, but never accessed by any code.
+ ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
+ if (var.storage == StorageClassOutput && var.initializer != 0)
+ variables.insert(var.self);
+ });
+
// If we needed to create one, we'll need it.
if (dummy_sampler_id)
variables.insert(dummy_sampler_id);
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index e4d54e0d..a0b826d7 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -1743,6 +1743,15 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
add_resource_name(var.self);
statement(layout_for_variable(var), to_qualifiers_glsl(var.self),
variable_decl(type, to_name(var.self), var.self), ";");
+
+ // If a StorageClassOutput variable has an initializer, we need to initialize it in main().
+ if (var.storage == StorageClassOutput && var.initializer)
+ {
+ auto &entry_func = this->get<SPIRFunction>(ir.default_entry_point);
+ entry_func.fixup_hooks_in.push_back([&]() {
+ statement(to_name(var.self), " = ", to_expression(var.initializer), ";");
+ });
+ }
}
}
}
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index 7f2d3c6f..fd90160f 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -851,10 +851,10 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co
// Update the original variable reference to include the structure reference
string qual_var_name = ib_var_ref + "." + mbr_name;
+ auto &entry_func = get<SPIRFunction>(ir.default_entry_point);
if (padded_output)
{
- auto &entry_func = get<SPIRFunction>(ir.default_entry_point);
entry_func.add_local_variable(var.self);
vars_needing_early_declaration.push_back(var.self);
@@ -866,6 +866,13 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co
else
ir.meta[var.self].decoration.qualified_alias = qual_var_name;
+ if (var.storage == StorageClassOutput && var.initializer != 0)
+ {
+ entry_func.fixup_hooks_in.push_back([=, &var]() {
+ statement(qual_var_name, " = ", to_expression(var.initializer), ";");
+ });
+ }
+
// Copy the variable location from the original variable to the member
if (get_decoration_bitset(var.self).get(DecorationLocation))
{
@@ -3383,10 +3390,13 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
for (auto var_id : vars_needing_early_declaration)
{
auto &ed_var = get<SPIRVariable>(var_id);
- if (!ed_var.initializer)
- ed_var.initializer = ir.increase_bound_by(1);
+ uint32_t &initializer = ed_var.initializer;
+ if (!initializer)
+ initializer = ir.increase_bound_by(1);
- set<SPIRExpression>(ed_var.initializer, "{}", ed_var.basetype, true);
+ // Do not override proper initializers.
+ if (ir.ids[initializer].get_type() == TypeNone || ir.ids[initializer].get_type() == TypeExpression)
+ set<SPIRExpression>(ed_var.initializer, "{}", ed_var.basetype, true);
}
}