Merge pull request #843 from KhronosGroup/fix-826
Support initializers on StorageClassOutput.
This commit is contained in:
commit
8804152253
@ -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;
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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
|
@ -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
|
41
shaders/asm/frag/storage-class-output-initializer.asm.frag
Normal file
41
shaders/asm/frag/storage-class-output-initializer.asm.frag
Normal 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
|
@ -701,6 +701,12 @@ unordered_set<uint32_t> Compiler::get_active_interface_variables() const
|
|||||||
InterfaceVariableAccessHandler handler(*this, variables);
|
InterfaceVariableAccessHandler handler(*this, variables);
|
||||||
traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
|
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 we needed to create one, we'll need it.
|
||||||
if (dummy_sampler_id)
|
if (dummy_sampler_id)
|
||||||
variables.insert(dummy_sampler_id);
|
variables.insert(dummy_sampler_id);
|
||||||
|
@ -1743,6 +1743,15 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
|
|||||||
add_resource_name(var.self);
|
add_resource_name(var.self);
|
||||||
statement(layout_for_variable(var), to_qualifiers_glsl(var.self),
|
statement(layout_for_variable(var), to_qualifiers_glsl(var.self),
|
||||||
variable_decl(type, to_name(var.self), 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), ";");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
// Update the original variable reference to include the structure reference
|
||||||
string qual_var_name = ib_var_ref + "." + mbr_name;
|
string qual_var_name = ib_var_ref + "." + mbr_name;
|
||||||
|
auto &entry_func = get<SPIRFunction>(ir.default_entry_point);
|
||||||
|
|
||||||
if (padded_output)
|
if (padded_output)
|
||||||
{
|
{
|
||||||
auto &entry_func = get<SPIRFunction>(ir.default_entry_point);
|
|
||||||
entry_func.add_local_variable(var.self);
|
entry_func.add_local_variable(var.self);
|
||||||
vars_needing_early_declaration.push_back(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
|
else
|
||||||
ir.meta[var.self].decoration.qualified_alias = qual_var_name;
|
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
|
// Copy the variable location from the original variable to the member
|
||||||
if (get_decoration_bitset(var.self).get(DecorationLocation))
|
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)
|
for (auto var_id : vars_needing_early_declaration)
|
||||||
{
|
{
|
||||||
auto &ed_var = get<SPIRVariable>(var_id);
|
auto &ed_var = get<SPIRVariable>(var_id);
|
||||||
if (!ed_var.initializer)
|
uint32_t &initializer = ed_var.initializer;
|
||||||
ed_var.initializer = ir.increase_bound_by(1);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user