CompilerMSL fixes to support pull-request feedback.

Make Compiler::OpcodeHandler and Compiler::traverse_all_reachable_opcodes protected
instead of private, for use by subclasses.
Add CompilerMSL::CustomFunctionHandler and traverse_all_reachable_opcodes() to detect
active opcodes that require the output of a custom function.
CompilerMSL::custom_function_ops use std::set to retain ordering to improve testability.
This commit is contained in:
Bill Hollings 2016-12-21 16:31:13 -05:00
parent b1b68db835
commit 7d38f1822a
3 changed files with 59 additions and 38 deletions

View File

@ -483,7 +483,7 @@ protected:
void analyze_variable_scope(SPIRFunction &function);
private:
protected:
void parse();
void parse(const Instruction &i);

View File

@ -104,19 +104,8 @@ string CompilerMSL::compile()
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;
}
}
CustomFunctionHandler handler(*this, custom_function_ops);
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
}
// Adds any builtins used by this shader to the builtin_vars collection
@ -2005,9 +1994,24 @@ 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)
{
switch (opcode)
{
case OpFMod:
custom_function_ops.insert(opcode);
break;
default:
break;
}
return true;
}
// Sort both type and meta member content based on builtin status (put builtins at end),
// then by the required sorting aspect.
void MemberSorter::sort()
void CompilerMSL::MemberSorter::sort()
{
// Create a temporary array of consecutive member indices and sort it base on how
// the members should be reordered, based on builtin and sorting aspect meta info.
@ -2029,7 +2033,7 @@ void MemberSorter::sort()
}
// Sort first by builtin status (put builtins at end), then by the sorting aspect.
bool MemberSorter::operator()(uint32_t mbr_idx1, uint32_t mbr_idx2)
bool CompilerMSL::MemberSorter::operator()(uint32_t mbr_idx1, uint32_t mbr_idx2)
{
auto &mbr_meta1 = meta.members[mbr_idx1];
auto &mbr_meta2 = meta.members[mbr_idx2];

View File

@ -18,6 +18,7 @@
#define SPIRV_CROSS_MSL_HPP
#include "spirv_glsl.hpp"
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
@ -151,7 +152,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::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;
@ -163,32 +164,48 @@ protected:
std::string stage_in_var_name = "in";
std::string stage_out_var_name = "out";
std::string sampler_name_suffix = "Smplr";
};
// Sorts the members of a SPIRType and associated Meta info based on a settable sorting
// aspect, which defines which aspect of the struct members will be used to sort them.
// Regardless of the sorting aspect, built-in members always appear at the end of the struct.
struct MemberSorter
{
enum SortAspect
// 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
{
Location,
LocationReverse,
Offset,
OffsetThenLocationReverse,
CustomFunctionHandler(const CompilerMSL &compiler_, std::set<uint32_t> &custom_function_ops_)
: compiler(compiler_)
, custom_function_ops(custom_function_ops_)
{
}
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
const CompilerMSL &compiler;
std::set<uint32_t> &custom_function_ops;
};
void sort();
bool operator()(uint32_t mbr_idx1, uint32_t mbr_idx2);
MemberSorter(SPIRType &t, Meta &m, SortAspect sa)
: type(t)
, meta(m)
, sort_aspect(sa)
// Sorts the members of a SPIRType and associated Meta info based on a settable sorting
// aspect, which defines which aspect of the struct members will be used to sort them.
// Regardless of the sorting aspect, built-in members always appear at the end of the struct.
struct MemberSorter
{
}
SPIRType &type;
Meta &meta;
SortAspect sort_aspect;
enum SortAspect
{
Location,
LocationReverse,
Offset,
OffsetThenLocationReverse,
};
void sort();
bool operator()(uint32_t mbr_idx1, uint32_t mbr_idx2);
MemberSorter(SPIRType &t, Meta &m, SortAspect sa)
: type(t)
, meta(m)
, sort_aspect(sa)
{
}
SPIRType &type;
Meta &meta;
SortAspect sort_aspect;
};
};
}