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);
|
void analyze_variable_scope(SPIRFunction &function);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void parse();
|
void parse();
|
||||||
void parse(const Instruction &i);
|
void parse(const Instruction &i);
|
||||||
|
|
||||||
|
@ -104,19 +104,8 @@ string CompilerMSL::compile()
|
|||||||
void CompilerMSL::register_custom_functions()
|
void CompilerMSL::register_custom_functions()
|
||||||
{
|
{
|
||||||
custom_function_ops.clear();
|
custom_function_ops.clear();
|
||||||
for (auto &i : inst)
|
CustomFunctionHandler handler(*this, custom_function_ops);
|
||||||
{
|
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
|
||||||
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
|
// 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),
|
// Sort both type and meta member content based on builtin status (put builtins at end),
|
||||||
// then by the required sorting aspect.
|
// 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
|
// 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.
|
// 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.
|
// 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_meta1 = meta.members[mbr_idx1];
|
||||||
auto &mbr_meta2 = meta.members[mbr_idx2];
|
auto &mbr_meta2 = meta.members[mbr_idx2];
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#define SPIRV_CROSS_MSL_HPP
|
#define SPIRV_CROSS_MSL_HPP
|
||||||
|
|
||||||
#include "spirv_glsl.hpp"
|
#include "spirv_glsl.hpp"
|
||||||
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -151,7 +152,7 @@ protected:
|
|||||||
size_t get_declared_type_size(uint32_t type_id, uint64_t dec_mask) const;
|
size_t get_declared_type_size(uint32_t type_id, uint64_t dec_mask) const;
|
||||||
|
|
||||||
MSLConfiguration msl_config;
|
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::unordered_map<uint32_t, MSLVertexAttr *> vtx_attrs_by_location;
|
||||||
std::vector<MSLResourceBinding *> resource_bindings;
|
std::vector<MSLResourceBinding *> resource_bindings;
|
||||||
std::unordered_map<uint32_t, uint32_t> builtin_vars;
|
std::unordered_map<uint32_t, uint32_t> builtin_vars;
|
||||||
@ -163,32 +164,48 @@ protected:
|
|||||||
std::string stage_in_var_name = "in";
|
std::string stage_in_var_name = "in";
|
||||||
std::string stage_out_var_name = "out";
|
std::string stage_out_var_name = "out";
|
||||||
std::string sampler_name_suffix = "Smplr";
|
std::string sampler_name_suffix = "Smplr";
|
||||||
};
|
|
||||||
|
|
||||||
// Sorts the members of a SPIRType and associated Meta info based on a settable sorting
|
// Extracts a set of opcodes that should be implemented as a bespoke custom function
|
||||||
// aspect, which defines which aspect of the struct members will be used to sort them.
|
// whose full source code is output as part of the shader source code.
|
||||||
// Regardless of the sorting aspect, built-in members always appear at the end of the struct.
|
struct CustomFunctionHandler : OpcodeHandler
|
||||||
struct MemberSorter
|
|
||||||
{
|
|
||||||
enum SortAspect
|
|
||||||
{
|
{
|
||||||
Location,
|
CustomFunctionHandler(const CompilerMSL &compiler_, std::set<uint32_t> &custom_function_ops_)
|
||||||
LocationReverse,
|
: compiler(compiler_)
|
||||||
Offset,
|
, custom_function_ops(custom_function_ops_)
|
||||||
OffsetThenLocationReverse,
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
// Sorts the members of a SPIRType and associated Meta info based on a settable sorting
|
||||||
bool operator()(uint32_t mbr_idx1, uint32_t mbr_idx2);
|
// aspect, which defines which aspect of the struct members will be used to sort them.
|
||||||
MemberSorter(SPIRType &t, Meta &m, SortAspect sa)
|
// Regardless of the sorting aspect, built-in members always appear at the end of the struct.
|
||||||
: type(t)
|
struct MemberSorter
|
||||||
, meta(m)
|
|
||||||
, sort_aspect(sa)
|
|
||||||
{
|
{
|
||||||
}
|
enum SortAspect
|
||||||
SPIRType &type;
|
{
|
||||||
Meta &meta;
|
Location,
|
||||||
SortAspect sort_aspect;
|
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