mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-09 22:00:05 +00:00
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:
parent
32ae2eceed
commit
1a5dc0edcd
@ -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:
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user