Merge pull request #699 from cdavis5e/msl-sample-pos

MSL: Handle the SamplePosition builtin.
This commit is contained in:
Hans-Kristian Arntzen 2018-09-18 09:23:31 +02:00 committed by GitHub
commit ecc4da4cd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 176 additions and 8 deletions

View File

@ -0,0 +1,23 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 FragColor [[color(0)]];
};
struct main0_in
{
int index [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], uint gl_SampleID [[sample_id]])
{
main0_out out = {};
float2 gl_SamplePosition = get_sample_position(gl_SampleID);
out.FragColor = float4(gl_SamplePosition, float(in.index), 1.0);
return out;
}

View File

@ -0,0 +1,18 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 FragColor [[color(0)]];
};
fragment main0_out main0(uint gl_SampleID [[sample_id]])
{
main0_out out = {};
float2 gl_SamplePosition = get_sample_position(gl_SampleID);
out.FragColor = float4(gl_SamplePosition, float(gl_SampleID), 1.0);
return out;
}

View File

@ -0,0 +1,31 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 FragColor [[color(0)]];
};
struct main0_in
{
int index [[user(locn0)]];
};
float4 getColor(thread const int& i, thread float2& gl_SamplePosition)
{
return float4(gl_SamplePosition, float(i), 1.0);
}
fragment main0_out main0(main0_in in [[stage_in]], uint gl_SampleID [[sample_id]])
{
main0_out out = {};
float2 gl_SamplePosition = get_sample_position(gl_SampleID);
int param = in.index;
out.FragColor = getColor(param, gl_SamplePosition);
return out;
}

View File

@ -0,0 +1,18 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 FragColor [[color(0)]];
};
fragment main0_out main0(uint gl_SampleID [[sample_id]])
{
main0_out out = {};
float2 gl_SamplePosition = get_sample_position(gl_SampleID);
out.FragColor = float4(gl_SamplePosition, float(gl_SampleID), 1.0);
return out;
}

View File

@ -0,0 +1,15 @@
#version 450
layout(location = 0) in flat int index;
layout(location = 0) out vec4 FragColor;
vec4 getColor(int i)
{
return vec4(gl_SamplePosition, i, 1.0);
}
void main()
{
FragColor = getColor(index);
}

View File

@ -0,0 +1,8 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(gl_SamplePosition, gl_SampleID, 1.0);
}

View File

@ -56,9 +56,11 @@ CompilerMSL::CompilerMSL(const uint32_t *ir, size_t word_count, MSLVertexAttr *p
void CompilerMSL::build_implicit_builtins()
{
if (need_subpass_input)
bool need_sample_pos = active_input_builtins.get(BuiltInSamplePosition);
if (need_subpass_input || need_sample_pos)
{
bool has_frag_coord = false;
bool has_sample_id = false;
for (auto &id : ids)
{
@ -67,16 +69,24 @@ void CompilerMSL::build_implicit_builtins()
auto &var = id.get<SPIRVariable>();
if (var.storage == StorageClassInput && meta[var.self].decoration.builtin &&
if (need_subpass_input && var.storage == StorageClassInput && meta[var.self].decoration.builtin &&
meta[var.self].decoration.builtin_type == BuiltInFragCoord)
{
builtin_frag_coord_id = var.self;
has_frag_coord = true;
break;
}
if (need_sample_pos && var.storage == StorageClassInput && meta[var.self].decoration.builtin &&
meta[var.self].decoration.builtin_type == BuiltInSampleId)
{
builtin_sample_id_id = var.self;
has_sample_id = true;
break;
}
}
if (!has_frag_coord)
if (!has_frag_coord && need_subpass_input)
{
uint32_t offset = increase_bound_by(3);
uint32_t type_id = offset;
@ -102,6 +112,32 @@ void CompilerMSL::build_implicit_builtins()
set_decoration(var_id, DecorationBuiltIn, BuiltInFragCoord);
builtin_frag_coord_id = var_id;
}
if (!has_sample_id && need_sample_pos)
{
uint32_t offset = increase_bound_by(3);
uint32_t type_id = offset;
uint32_t type_ptr_id = offset + 1;
uint32_t var_id = offset + 2;
// Create gl_SampleID.
SPIRType uint_type;
uint_type.basetype = SPIRType::UInt;
uint_type.width = 32;
set<SPIRType>(type_id, uint_type);
SPIRType uint_type_ptr;
uint_type_ptr = uint_type;
uint_type_ptr.pointer = true;
uint_type_ptr.parent_type = type_id;
uint_type_ptr.storage = StorageClassInput;
auto &ptr_type = set<SPIRType>(type_ptr_id, uint_type_ptr);
ptr_type.self = type_id;
set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
set_decoration(var_id, DecorationBuiltIn, BuiltInSampleId);
builtin_sample_id_id = var_id;
}
}
}
@ -3558,15 +3594,28 @@ string CompilerMSL::entry_point_args(bool append_comma)
auto &var = id.get<SPIRVariable>();
uint32_t var_id = var.self;
BuiltIn bi_type = meta[var_id].decoration.builtin_type;
// Don't emit SamplePosition as a separate parameter. In the entry
// point, we get that by calling get_sample_position() on the sample ID.
if (var.storage == StorageClassInput && is_builtin_variable(var))
{
if (!ep_args.empty())
ep_args += ", ";
if (bi_type != BuiltInSamplePosition)
{
if (!ep_args.empty())
ep_args += ", ";
BuiltIn bi_type = meta[var_id].decoration.builtin_type;
ep_args += builtin_type_decl(bi_type) + " " + to_expression(var_id);
ep_args += " [[" + builtin_qualifier(bi_type) + "]]";
ep_args += builtin_type_decl(bi_type) + " " + to_expression(var_id);
ep_args += " [[" + builtin_qualifier(bi_type) + "]]";
}
else
{
auto &entry_func = get<SPIRFunction>(entry_point);
entry_func.fixup_hooks_in.push_back([=]() {
statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = get_sample_position(",
to_expression(builtin_sample_id_id), ");");
});
}
}
}
}
@ -4166,6 +4215,9 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
return "sample_id";
case BuiltInSampleMask:
return "sample_mask";
case BuiltInSamplePosition:
// Shouldn't be reached.
SPIRV_CROSS_THROW("Sample position is retrieved by a function in MSL.");
// Fragment function out
case BuiltInFragDepth:
@ -4239,6 +4291,8 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin)
return "uint";
case BuiltInSampleMask:
return "uint";
case BuiltInSamplePosition:
return "float2";
// Fragment function out
case BuiltInFragDepth:

View File

@ -373,6 +373,7 @@ protected:
void build_implicit_builtins();
void emit_entry_point_declarations() override;
uint32_t builtin_frag_coord_id = 0;
uint32_t builtin_sample_id_id = 0;
void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
void bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override;