CompilerMSL support emitting custom functions for SPIR-V ops.

CompilerMSL use custom mod() function instead of Metal's fmod() function.
This commit is contained in:
Bill Hollings 2016-12-18 21:42:10 -05:00
parent 32ae2eceed
commit 1a5dc0edcd
2 changed files with 50 additions and 5 deletions

View File

@ -51,6 +51,7 @@ string CompilerMSL::compile(MSLConfiguration &msl_cfg, vector<MSLVertexAttr> *p_
set_enabled_interface_variables(get_active_interface_variables());
register_custom_functions();
extract_builtins();
localize_global_variables();
add_interface_structs();
@ -83,6 +84,7 @@ string CompilerMSL::compile(MSLConfiguration &msl_cfg, vector<MSLVertexAttr> *p_
emit_header();
emit_resources();
emit_custom_functions();
emit_function_declarations();
emit_function(get<SPIRFunction>(entry_point), 0);
@ -98,6 +100,25 @@ string CompilerMSL::compile()
return compile(default_msl_cfg, nullptr, nullptr);
}
// Register the need to output any custom functions.
void CompilerMSL::register_custom_functions()
{
custom_function_ops.clear();
for (auto &i : inst)
{
auto op = static_cast<Op>(i.op);
switch (op)
{
case OpFMod:
custom_function_ops.insert(op);
break;
default:
break;
}
}
}
// Adds any builtins used by this shader to the builtin_vars collection
void CompilerMSL::extract_builtins()
{
@ -542,6 +563,31 @@ void CompilerMSL::emit_header()
statement("");
}
// Emits any needed custom function bodies.
void CompilerMSL::emit_custom_functions()
{
for (auto &op : custom_function_ops)
{
switch (op)
{
case OpFMod:
statement("// Support GLSL mod(), which is slightly different than Metal fmod()");
statement("template<typename Tx, typename Ty>");
statement("Tx mod(Tx x, Ty y);");
statement("template<typename Tx, typename Ty>");
statement("Tx mod(Tx x, Ty y)");
begin_scope();
statement("return x - y * floor(x / y);");
end_scope();
statement("");
break;
default:
break;
}
}
}
void CompilerMSL::emit_resources()
{
@ -611,11 +657,6 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
switch (opcode)
{
// ALU
case OpFMod:
BFOP(fmod);
break;
// Comparisons
case OpIEqual:
case OpLogicalEqual:

View File

@ -18,6 +18,7 @@
#define SPIRV_CROSS_MSL_HPP
#include "spirv_glsl.hpp"
#include <unordered_map>
#include <unordered_set>
#include <vector>
@ -113,6 +114,8 @@ protected:
std::string to_func_call_arg(uint32_t id) override;
std::string to_name(uint32_t id, bool allow_alias = true) override;
void register_custom_functions();
void emit_custom_functions();
void extract_builtins();
void add_builtin(spv::BuiltIn builtin_type);
void localize_global_variables();
@ -148,6 +151,7 @@ protected:
size_t get_declared_type_size(uint32_t type_id, uint64_t dec_mask) const;
MSLConfiguration msl_config;
std::unordered_set<uint32_t> custom_function_ops;
std::unordered_map<uint32_t, MSLVertexAttr *> vtx_attrs_by_location;
std::vector<MSLResourceBinding *> resource_bindings;
std::unordered_map<uint32_t, uint32_t> builtin_vars;