Merge pull request #103 from brenwill/master

Remove emission of function prototypes in MSL.
This commit is contained in:
Hans-Kristian Arntzen 2017-01-20 20:39:22 +01:00 committed by GitHub
commit 2c7359d1d3
4 changed files with 65 additions and 64 deletions

View File

@ -131,12 +131,8 @@ static uint32_t pls_format_to_components(PlsFormat format)
static const char *vector_swizzle(int vecsize, int index)
{
static const char* swizzle[4][4] =
{
{ ".x", ".y", ".z", ".w" },
{ ".xy", ".yz", ".zw" },
{ ".xyz", ".yzw" },
{ "" }
static const char *swizzle[4][4] = {
{ ".x", ".y", ".z", ".w" }, { ".xy", ".yz", ".zw" }, { ".xyz", ".yzw" }, { "" }
};
assert(vecsize >= 1 && vecsize <= 4);
@ -3290,7 +3286,8 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
return expr;
}
string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, bool* need_transpose)
string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type,
bool *need_transpose)
{
if (flattened_buffer_blocks.count(base))
{
@ -3305,7 +3302,8 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
}
}
std::string CompilerGLSL::flattened_access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset)
std::string CompilerGLSL::flattened_access_chain(uint32_t base, const uint32_t *indices, uint32_t count,
const SPIRType &target_type, uint32_t offset)
{
if (!target_type.array.empty())
{
@ -3325,7 +3323,8 @@ std::string CompilerGLSL::flattened_access_chain(uint32_t base, const uint32_t *
}
}
std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset)
std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uint32_t *indices, uint32_t count,
const SPIRType &target_type, uint32_t offset)
{
std::string expr;
@ -3348,7 +3347,8 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin
return expr;
}
std::string CompilerGLSL::flattened_access_chain_matrix(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset)
std::string CompilerGLSL::flattened_access_chain_matrix(uint32_t base, const uint32_t *indices, uint32_t count,
const SPIRType &target_type, uint32_t offset)
{
std::string expr;
@ -3368,7 +3368,8 @@ std::string CompilerGLSL::flattened_access_chain_matrix(uint32_t base, const uin
return expr;
}
std::string CompilerGLSL::flattened_access_chain_vector_scalar(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset)
std::string CompilerGLSL::flattened_access_chain_vector_scalar(uint32_t base, const uint32_t *indices, uint32_t count,
const SPIRType &target_type, uint32_t offset)
{
if (target_type.basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Access chains that use non-floating-point base types can not be flattened");
@ -3393,7 +3394,9 @@ std::string CompilerGLSL::flattened_access_chain_vector_scalar(uint32_t base, co
return expr;
}
std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uint32_t base, const uint32_t *indices, uint32_t count, uint32_t offset, bool *need_transpose)
std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uint32_t base, const uint32_t *indices,
uint32_t count, uint32_t offset,
bool *need_transpose)
{
const auto *type = &expression_type(base);
uint32_t type_size = 0;
@ -3444,7 +3447,8 @@ std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uin
offset += type_struct_member_offset(*type, index);
type_size = uint32_t(get_declared_struct_member_size(*type, index));
row_major_matrix_needs_conversion = (combined_decoration_for_member(*type, index) & (1ull << DecorationRowMajor)) != 0;
row_major_matrix_needs_conversion =
(combined_decoration_for_member(*type, index) & (1ull << DecorationRowMajor)) != 0;
type = &get<SPIRType>(type->member_types[index]);
}
// Matrix -> Vector

View File

@ -315,13 +315,20 @@ protected:
bool suppress_usage_tracking = false);
std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, bool index_is_literal,
bool chain_only = false, bool *need_transpose = nullptr);
std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, bool *need_transpose = nullptr);
std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type,
bool *need_transpose = nullptr);
std::string flattened_access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset);
std::string flattened_access_chain_struct(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset);
std::string flattened_access_chain_matrix(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset);
std::string flattened_access_chain_vector_scalar(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset);
std::pair<std::string, uint32_t> flattened_access_chain_offset(uint32_t base, const uint32_t *indices, uint32_t count, uint32_t offset, bool *need_transpose = nullptr);
std::string flattened_access_chain(uint32_t base, const uint32_t *indices, uint32_t count,
const SPIRType &target_type, uint32_t offset);
std::string flattened_access_chain_struct(uint32_t base, const uint32_t *indices, uint32_t count,
const SPIRType &target_type, uint32_t offset);
std::string flattened_access_chain_matrix(uint32_t base, const uint32_t *indices, uint32_t count,
const SPIRType &target_type, uint32_t offset);
std::string flattened_access_chain_vector_scalar(uint32_t base, const uint32_t *indices, uint32_t count,
const SPIRType &target_type, uint32_t offset);
std::pair<std::string, uint32_t> flattened_access_chain_offset(uint32_t base, const uint32_t *indices,
uint32_t count, uint32_t offset,
bool *need_transpose = nullptr);
const char *index_to_swizzle(uint32_t index);
std::string remap_swizzle(uint32_t result_type, uint32_t input_components, uint32_t expr);

View File

@ -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.
@ -398,10 +401,15 @@ 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 +427,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 +631,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 +694,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.
@ -1732,13 +1719,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:

View File

@ -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,18 @@ 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_)
OpCodePreprocessor(CompilerMSL &compiler_)
: 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;
CompilerMSL &compiler;
bool suppress_missing_prototypes = false;
};
// Sorts the members of a SPIRType and associated Meta info based on a settable sorting