Merge pull request #64 from brenwill/master
Support MSL-specific functions
This commit is contained in:
commit
8199986c0e
@ -136,6 +136,8 @@ protected:
|
|||||||
|
|
||||||
// Virtualize methods which need to be overridden by subclass targets like C++ and such.
|
// Virtualize methods which need to be overridden by subclass targets like C++ and such.
|
||||||
virtual void emit_function_prototype(SPIRFunction &func, uint64_t return_flags);
|
virtual void emit_function_prototype(SPIRFunction &func, uint64_t return_flags);
|
||||||
|
virtual void emit_instruction(const Instruction &instr);
|
||||||
|
virtual void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args, uint32_t count);
|
||||||
virtual void emit_header();
|
virtual void emit_header();
|
||||||
virtual void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id);
|
virtual void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id);
|
||||||
virtual void emit_texture_op(const Instruction &i);
|
virtual void emit_texture_op(const Instruction &i);
|
||||||
@ -236,8 +238,6 @@ protected:
|
|||||||
} backend;
|
} backend;
|
||||||
|
|
||||||
void emit_struct(SPIRType &type);
|
void emit_struct(SPIRType &type);
|
||||||
void emit_instruction(const Instruction &instr);
|
|
||||||
|
|
||||||
void emit_resources();
|
void emit_resources();
|
||||||
void emit_buffer_block(const SPIRVariable &type);
|
void emit_buffer_block(const SPIRVariable &type);
|
||||||
void emit_push_constant_block(const SPIRVariable &var);
|
void emit_push_constant_block(const SPIRVariable &var);
|
||||||
@ -261,7 +261,6 @@ protected:
|
|||||||
bool should_forward(uint32_t id);
|
bool should_forward(uint32_t id);
|
||||||
void emit_mix_op(uint32_t result_type, uint32_t id, uint32_t left, uint32_t right, uint32_t lerp);
|
void emit_mix_op(uint32_t result_type, uint32_t id, uint32_t left, uint32_t right, uint32_t lerp);
|
||||||
bool to_trivial_mix_op(const SPIRType &type, std::string &op, uint32_t left, uint32_t right, uint32_t lerp);
|
bool to_trivial_mix_op(const SPIRType &type, std::string &op, uint32_t left, uint32_t right, uint32_t lerp);
|
||||||
void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args, uint32_t count);
|
|
||||||
void emit_quaternary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, uint32_t op2,
|
void emit_quaternary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, uint32_t op2,
|
||||||
uint32_t op3, const char *op);
|
uint32_t op3, const char *op);
|
||||||
void emit_trinary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, uint32_t op2,
|
void emit_trinary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, uint32_t op2,
|
||||||
|
144
spirv_msl.cpp
144
spirv_msl.cpp
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "spirv_msl.hpp"
|
#include "spirv_msl.hpp"
|
||||||
|
#include "GLSL.std.450.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ string CompilerMSL::compile(MSLConfiguration &msl_cfg, vector<MSLVertexAttr> *p_
|
|||||||
|
|
||||||
// Do not deal with ES-isms like precision, older extensions and such.
|
// Do not deal with ES-isms like precision, older extensions and such.
|
||||||
options.es = false;
|
options.es = false;
|
||||||
options.version = 1;
|
options.version = 120;
|
||||||
backend.float_literal_suffix = false;
|
backend.float_literal_suffix = false;
|
||||||
backend.uint32_t_literal_suffix = true;
|
backend.uint32_t_literal_suffix = true;
|
||||||
backend.basic_int_type = "int";
|
backend.basic_int_type = "int";
|
||||||
@ -516,19 +517,6 @@ void CompilerMSL::emit_header()
|
|||||||
statement("");
|
statement("");
|
||||||
statement("using namespace metal;");
|
statement("using namespace metal;");
|
||||||
statement("");
|
statement("");
|
||||||
emit_msl_defines();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompilerMSL::emit_msl_defines()
|
|
||||||
{
|
|
||||||
statement("// Standard GLSL->MSL redefinitions");
|
|
||||||
statement("#define dFdy dfdy");
|
|
||||||
statement("#define dFdx dfdy");
|
|
||||||
statement("#define atan(y,x) atan2((y),(x))");
|
|
||||||
statement("#define greaterThan(a,b) ((a)>(b))");
|
|
||||||
statement("inline uint2 imageSize(thread const texture2d<float>& tex) { return uint2(tex.get_width(), "
|
|
||||||
"tex.get_height()); }");
|
|
||||||
statement("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerMSL::emit_resources()
|
void CompilerMSL::emit_resources()
|
||||||
@ -578,6 +566,134 @@ void CompilerMSL::emit_resources()
|
|||||||
// TODO: Consolidate and output loose uniforms into an input struct
|
// TODO: Consolidate and output loose uniforms into an input struct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override for MSL-specific syntax instructions
|
||||||
|
void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||||
|
{
|
||||||
|
|
||||||
|
#define BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||||
|
#define BOP_CAST(op, type) emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode))
|
||||||
|
#define UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op)
|
||||||
|
#define QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op)
|
||||||
|
#define TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op)
|
||||||
|
#define BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||||
|
#define BFOP_CAST(op, type) emit_binary_func_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode))
|
||||||
|
#define BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||||
|
#define UFOP(op) emit_unary_func_op(ops[0], ops[1], ops[2], #op)
|
||||||
|
|
||||||
|
auto ops = stream(instruction);
|
||||||
|
auto opcode = static_cast<Op>(instruction.op);
|
||||||
|
|
||||||
|
switch (opcode)
|
||||||
|
{
|
||||||
|
// Comparisons
|
||||||
|
case OpIEqual:
|
||||||
|
case OpLogicalEqual:
|
||||||
|
case OpFOrdEqual:
|
||||||
|
BOP(==);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpINotEqual:
|
||||||
|
case OpLogicalNotEqual:
|
||||||
|
case OpFOrdNotEqual:
|
||||||
|
BOP(!=);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpUGreaterThan:
|
||||||
|
case OpSGreaterThan:
|
||||||
|
case OpFOrdGreaterThan:
|
||||||
|
BOP(>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpUGreaterThanEqual:
|
||||||
|
case OpSGreaterThanEqual:
|
||||||
|
case OpFOrdGreaterThanEqual:
|
||||||
|
BOP(>=);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpULessThan:
|
||||||
|
case OpSLessThan:
|
||||||
|
case OpFOrdLessThan:
|
||||||
|
BOP(<);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpULessThanEqual:
|
||||||
|
case OpSLessThanEqual:
|
||||||
|
case OpFOrdLessThanEqual:
|
||||||
|
BOP(<=);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Derivatives
|
||||||
|
case OpDPdx:
|
||||||
|
UFOP(dfdx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpDPdy:
|
||||||
|
UFOP(dfdy);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpImageQuerySize:
|
||||||
|
{
|
||||||
|
auto &type = expression_type(ops[2]);
|
||||||
|
uint32_t result_type = ops[0];
|
||||||
|
uint32_t id = ops[1];
|
||||||
|
|
||||||
|
if (type.basetype == SPIRType::Image)
|
||||||
|
{
|
||||||
|
string img_exp = to_expression(ops[2]);
|
||||||
|
auto &img_type = type.image;
|
||||||
|
switch (img_type.dim)
|
||||||
|
{
|
||||||
|
case Dim1D:
|
||||||
|
if (img_type.arrayed)
|
||||||
|
emit_op(result_type, id, join("uint2(", img_exp, ".get_width(), ", img_exp, ".get_array_size())"), false, false);
|
||||||
|
else
|
||||||
|
emit_op(result_type, id, join(img_exp, ".get_width()"), true, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Dim2D:
|
||||||
|
case DimCube:
|
||||||
|
if (img_type.arrayed)
|
||||||
|
emit_op(result_type, id, join("uint3(", img_exp, ".get_width(), ", img_exp, ".get_height(), ", img_exp, ".get_array_size())"), false, false);
|
||||||
|
else
|
||||||
|
emit_op(result_type, id, join("uint2(", img_exp, ".get_width(), ", img_exp, ".get_height())"), false, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Dim3D:
|
||||||
|
emit_op(result_type, id, join("uint3(", img_exp, ".get_width(), ", img_exp, ".get_height(), ", img_exp, ".get_depth())"), false, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw CompilerError("Invalid type for OpImageQuerySize.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
CompilerGLSL::emit_instruction(instruction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override for MSL-specific extension syntax instructions
|
||||||
|
void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t count)
|
||||||
|
{
|
||||||
|
GLSLstd450 op = static_cast<GLSLstd450>(eop);
|
||||||
|
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case GLSLstd450Atan2:
|
||||||
|
emit_binary_func_op(result_type, id, args[0], args[1], "atan2");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Emit a structure declaration for the specified interface variable.
|
// Emit a structure declaration for the specified interface variable.
|
||||||
void CompilerMSL::emit_interface_block(uint32_t ib_var_id)
|
void CompilerMSL::emit_interface_block(uint32_t ib_var_id)
|
||||||
{
|
{
|
||||||
|
@ -96,6 +96,8 @@ public:
|
|||||||
std::string compile() override;
|
std::string compile() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void emit_instruction(const Instruction &instr) override;
|
||||||
|
void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args, uint32_t count) override;
|
||||||
void emit_header() override;
|
void emit_header() override;
|
||||||
void emit_function_prototype(SPIRFunction &func, uint64_t return_flags) override;
|
void emit_function_prototype(SPIRFunction &func, uint64_t return_flags) override;
|
||||||
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
||||||
@ -124,7 +126,6 @@ protected:
|
|||||||
void emit_interface_block(uint32_t ib_var_id);
|
void emit_interface_block(uint32_t ib_var_id);
|
||||||
void emit_function_prototype(SPIRFunction &func, bool is_decl);
|
void emit_function_prototype(SPIRFunction &func, bool is_decl);
|
||||||
void emit_function_declarations();
|
void emit_function_declarations();
|
||||||
void emit_msl_defines();
|
|
||||||
|
|
||||||
std::string func_type_decl(SPIRType &type);
|
std::string func_type_decl(SPIRType &type);
|
||||||
std::string clean_func_name(std::string func_name);
|
std::string clean_func_name(std::string func_name);
|
||||||
|
Loading…
Reference in New Issue
Block a user