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:
parent
b1b68db835
commit
7d38f1822a
@ -483,7 +483,7 @@ protected:
|
||||
|
||||
void analyze_variable_scope(SPIRFunction &function);
|
||||
|
||||
private:
|
||||
protected:
|
||||
void parse();
|
||||
void parse(const Instruction &i);
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user