MSL: Deal with padded fragment output + Component decoration.

This commit is contained in:
Hans-Kristian Arntzen 2020-01-07 17:02:12 +01:00
parent 8871502a20
commit c024e24d45
3 changed files with 51 additions and 14 deletions

View File

@ -0,0 +1,22 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 FragColor0 [[color(0)]];
};
fragment main0_out main0()
{
main0_out out = {};
float FragColor0 = {};
float2 FragColor1 = {};
FragColor0 = 1.0;
FragColor1 = float2(2.0, 3.0);
out.FragColor0.x = FragColor0;
out.FragColor0.yz = FragColor1;
return out;
}

View File

@ -0,0 +1,10 @@
#version 450
layout(location = 0, component = 0) out float FragColor0;
layout(location = 0, component = 1) out vec2 FragColor1;
void main()
{
FragColor0 = 1.0;
FragColor1 = vec2(2.0, 3.0);
}

View File

@ -1487,25 +1487,19 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co
location_meta = &location_meta_itr->second;
}
// Check if we need to pad fragment output to match a certain number of components.
if (get_decoration_bitset(var.self).get(DecorationLocation) && msl_options.pad_fragment_output_components &&
get_entry_point().model == ExecutionModelFragment && storage == StorageClassOutput)
{
assert(!location_meta);
uint32_t locn = get_decoration(var.self, DecorationLocation);
target_components = get_target_components_for_fragment_location(locn);
if (type_components < target_components)
{
// Make a new type here.
type_id = build_extended_vector_type(type_id, target_components);
padded_output = true;
}
}
bool pad_fragment_output = has_decoration(var.self, DecorationLocation) && msl_options.pad_fragment_output_components &&
get_entry_point().model == ExecutionModelFragment && storage == StorageClassOutput;
// Check if we need to pad fragment output to match a certain number of components.
if (location_meta)
{
start_component = get_decoration(var.self, DecorationComponent);
uint32_t num_components = location_meta->num_components;
if (pad_fragment_output)
{
uint32_t locn = get_decoration(var.self, DecorationLocation);
num_components = std::max(num_components, get_target_components_for_fragment_location(locn));
}
if (location_meta->ib_index != ~0u)
{
@ -1542,6 +1536,17 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co
padded_output = true;
}
}
else if (pad_fragment_output)
{
uint32_t locn = get_decoration(var.self, DecorationLocation);
target_components = get_target_components_for_fragment_location(locn);
if (type_components < target_components)
{
// Make a new type here.
type_id = build_extended_vector_type(type_id, target_components);
padded_output = true;
}
}
ib_type.member_types.push_back(type_id);