Remove emission of function prototypes in MSL.
Do not emit function prototypes. If secondary functions are used, suppress compiler -Wmissing-prototypes warnings. Refactor Compiler::emit_function_prototype() functions to simplify. Rename Compiler_msl::CustomFunctionHandler to OpCodePreprocessor, and Compiler_msl::register_custom_functions() to preprocess_op_codes() to perform more generic preprocessing. Add space between dynamic header lines and fixed header lines.
This commit is contained in:
Родитель
f2d56a4600
Коммит
4c198bbce9
|
@ -57,9 +57,9 @@ string CompilerMSL::compile(MSLConfiguration &msl_cfg, vector<MSLVertexAttr> *p_
|
|||
for (auto &rb : *p_res_bindings)
|
||||
resource_bindings.push_back(&rb);
|
||||
|
||||
// Establish the need to output any custom functions
|
||||
// Preprocess OpCodes to extract the need to output additional header content
|
||||
set_enabled_interface_variables(get_active_interface_variables());
|
||||
register_custom_functions();
|
||||
preprocess_op_codes();
|
||||
|
||||
// Create structs to hold input and output variables
|
||||
qual_pos_var_name = "";
|
||||
|
@ -98,7 +98,6 @@ 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);
|
||||
|
||||
pass_count++;
|
||||
|
@ -114,11 +113,15 @@ string CompilerMSL::compile()
|
|||
}
|
||||
|
||||
// Register the need to output any custom functions.
|
||||
void CompilerMSL::register_custom_functions()
|
||||
void CompilerMSL::preprocess_op_codes()
|
||||
{
|
||||
custom_function_ops.clear();
|
||||
CustomFunctionHandler handler(*this, custom_function_ops);
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
|
||||
|
||||
OpCodePreprocessor preproc(*this);
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), preproc);
|
||||
|
||||
if (preproc.suppress_missing_prototypes)
|
||||
add_header_line("#pragma clang diagnostic ignored \"-Wmissing-prototypes\"");
|
||||
}
|
||||
|
||||
// Move the Private global variables to the entry function.
|
||||
|
@ -399,9 +402,13 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage)
|
|||
// Emits the file header info
|
||||
void CompilerMSL::emit_header()
|
||||
{
|
||||
if ( !header_lines.empty() ) {
|
||||
for (auto &header : header_lines)
|
||||
statement(header);
|
||||
|
||||
statement("");
|
||||
}
|
||||
|
||||
statement("#include <metal_stdlib>");
|
||||
statement("#include <simd/simd.h>");
|
||||
statement("");
|
||||
|
@ -419,8 +426,6 @@ void CompilerMSL::emit_custom_functions()
|
|||
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);");
|
||||
|
@ -625,28 +630,9 @@ void CompilerMSL::emit_interface_block(uint32_t ib_var_id)
|
|||
}
|
||||
}
|
||||
|
||||
// Output a declaration statement for each function.
|
||||
void CompilerMSL::emit_function_declarations()
|
||||
{
|
||||
for (auto &id : ids)
|
||||
if (id.get_type() == TypeFunction)
|
||||
{
|
||||
auto &func = id.get<SPIRFunction>();
|
||||
if (func.self != entry_point)
|
||||
emit_function_prototype(func, true);
|
||||
}
|
||||
|
||||
statement("");
|
||||
}
|
||||
|
||||
void CompilerMSL::emit_function_prototype(SPIRFunction &func, uint64_t)
|
||||
{
|
||||
emit_function_prototype(func, false);
|
||||
}
|
||||
|
||||
// Emits the declaration signature of the specified function.
|
||||
// If this is the entry point function, Metal-specific return value and function arguments are added.
|
||||
void CompilerMSL::emit_function_prototype(SPIRFunction &func, bool is_decl)
|
||||
void CompilerMSL::emit_function_prototype(SPIRFunction &func, uint64_t)
|
||||
{
|
||||
local_variable_names = resource_names;
|
||||
string decl;
|
||||
|
@ -707,7 +693,7 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, bool is_decl)
|
|||
}
|
||||
|
||||
decl += ")";
|
||||
statement(decl, (is_decl ? ";" : ""));
|
||||
statement(decl);
|
||||
}
|
||||
|
||||
// Returns the texture sampling function string for the specified image and sampling characteristics.
|
||||
|
@ -1723,13 +1709,20 @@ size_t CompilerMSL::get_declared_type_size(uint32_t type_id, uint64_t dec_mask)
|
|||
}
|
||||
}
|
||||
|
||||
// If the opcode requires a bespoke custom function be output, remember it.
|
||||
bool CompilerMSL::CustomFunctionHandler::handle(Op opcode, const uint32_t * /*args*/, uint32_t /*length*/)
|
||||
bool CompilerMSL::OpCodePreprocessor::handle(Op opcode, const uint32_t * /*args*/, uint32_t /*length*/)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
// If an opcode requires a bespoke custom function be output, remember it.
|
||||
case OpFMod:
|
||||
custom_function_ops.insert(opcode);
|
||||
compiler.custom_function_ops.insert(uint32_t(opcode));
|
||||
break;
|
||||
|
||||
// Since MSL exists in a single execution scope, function prototype declarations are not
|
||||
// needed, and clutter the output. If secondary functions are output (as indicated by the
|
||||
// presence of OpFunctionCall, then suppress compiler warnings of missing function prototypes.
|
||||
case OpFunctionCall:
|
||||
suppress_missing_prototypes = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -117,7 +117,7 @@ protected:
|
|||
uint32_t comp, uint32_t sample, bool *p_forward) override;
|
||||
std::string clean_func_name(std::string func_name) override;
|
||||
|
||||
void register_custom_functions();
|
||||
void preprocess_op_codes();
|
||||
void emit_custom_functions();
|
||||
void localize_global_variables();
|
||||
void extract_global_variables_from_functions();
|
||||
|
@ -128,8 +128,6 @@ protected:
|
|||
void mark_location_as_used_by_shader(uint32_t location, spv::StorageClass storage);
|
||||
void emit_resources();
|
||||
void emit_interface_block(uint32_t ib_var_id);
|
||||
void emit_function_prototype(SPIRFunction &func, bool is_decl);
|
||||
void emit_function_declarations();
|
||||
void populate_func_name_overrides();
|
||||
|
||||
std::string func_type_decl(SPIRType &type);
|
||||
|
@ -161,20 +159,17 @@ protected:
|
|||
std::string stage_out_var_name = "out";
|
||||
std::string sampler_name_suffix = "Smplr";
|
||||
|
||||
// Extracts a set of opcodes that should be implemented as a bespoke custom function
|
||||
// whose full source code is output as part of the shader source code.
|
||||
struct CustomFunctionHandler : OpcodeHandler
|
||||
// OpcodeHandler that handles several MSL preprocessing operations.
|
||||
struct OpCodePreprocessor : OpcodeHandler
|
||||
{
|
||||
CustomFunctionHandler(const CompilerMSL &compiler_, std::set<uint32_t> &custom_function_ops_)
|
||||
: compiler(compiler_)
|
||||
, custom_function_ops(custom_function_ops_)
|
||||
OpCodePreprocessor(CompilerMSL &compiler_) : compiler(compiler_)
|
||||
{
|
||||
}
|
||||
|
||||
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
|
||||
|
||||
const CompilerMSL &compiler;
|
||||
std::set<uint32_t> &custom_function_ops;
|
||||
CompilerMSL &compiler;
|
||||
bool suppress_missing_prototypes = false;
|
||||
};
|
||||
|
||||
// Sorts the members of a SPIRType and associated Meta info based on a settable sorting
|
||||
|
|
Загрузка…
Ссылка в новой задаче