Merge pull request #843 from KhronosGroup/fix-826

Support initializers on StorageClassOutput.
This commit is contained in:
Hans-Kristian Arntzen 2019-01-30 12:35:50 +01:00 committed by GitHub
commit 8804152253
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 268 additions and 4 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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), ";");
});
}
}
}
}

View File

@ -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);
}
}