From b86bd0a2653e67722ab1dbf33e51977baa35c6eb Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Mon, 11 Jun 2018 10:48:12 +0200 Subject: [PATCH] Unpack expressions when used in functions on MSL. OSX 10.14 broke (?) how overload resolution works, so overloading e.g. dot(float3, packed_float3) no longer works. Fix this by unpacking expressions before various func ops. This fix might need to be applied elsewhere, but do so later if needed. --- .../binary-func-unpack-pack-arguments.frag | 28 +++++++++++++++ .../binary-func-unpack-pack-arguments.frag | 28 +++++++++++++++ .../binary-func-unpack-pack-arguments.frag | 15 ++++++++ spirv_glsl.cpp | 34 ++++++++++++++----- spirv_glsl.hpp | 2 ++ 5 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 reference/opt/shaders-msl/frag/binary-func-unpack-pack-arguments.frag create mode 100644 reference/shaders-msl/frag/binary-func-unpack-pack-arguments.frag create mode 100644 shaders-msl/frag/binary-func-unpack-pack-arguments.frag diff --git a/reference/opt/shaders-msl/frag/binary-func-unpack-pack-arguments.frag b/reference/opt/shaders-msl/frag/binary-func-unpack-pack-arguments.frag new file mode 100644 index 0000000..0e66e1f --- /dev/null +++ b/reference/opt/shaders-msl/frag/binary-func-unpack-pack-arguments.frag @@ -0,0 +1,28 @@ +#include +#include + +using namespace metal; + +struct UBO +{ + packed_float3 color; + float v; +}; + +struct main0_in +{ + float3 vIn [[user(locn0)]]; +}; + +struct main0_out +{ + float FragColor [[color(0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], constant UBO& _15 [[buffer(0)]]) +{ + main0_out out = {}; + out.FragColor = dot(in.vIn, float3(_15.color)); + return out; +} + diff --git a/reference/shaders-msl/frag/binary-func-unpack-pack-arguments.frag b/reference/shaders-msl/frag/binary-func-unpack-pack-arguments.frag new file mode 100644 index 0000000..0e66e1f --- /dev/null +++ b/reference/shaders-msl/frag/binary-func-unpack-pack-arguments.frag @@ -0,0 +1,28 @@ +#include +#include + +using namespace metal; + +struct UBO +{ + packed_float3 color; + float v; +}; + +struct main0_in +{ + float3 vIn [[user(locn0)]]; +}; + +struct main0_out +{ + float FragColor [[color(0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], constant UBO& _15 [[buffer(0)]]) +{ + main0_out out = {}; + out.FragColor = dot(in.vIn, float3(_15.color)); + return out; +} + diff --git a/shaders-msl/frag/binary-func-unpack-pack-arguments.frag b/shaders-msl/frag/binary-func-unpack-pack-arguments.frag new file mode 100644 index 0000000..c0e5dab --- /dev/null +++ b/shaders-msl/frag/binary-func-unpack-pack-arguments.frag @@ -0,0 +1,15 @@ +#version 450 +layout(location = 0) out float FragColor; + +layout(binding = 0, std140) uniform UBO +{ + vec3 color; + float v; +}; + +layout(location = 0) in vec3 vIn; + +void main() +{ + FragColor = dot(vIn, color); +} diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 3487331..1e5e7e1 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -2373,6 +2373,22 @@ string CompilerGLSL::to_enclosed_expression(uint32_t id) return enclose_expression(to_expression(id)); } +string CompilerGLSL::to_unpacked_expression(uint32_t id) +{ + if (has_decoration(id, DecorationCPacked)) + return unpack_expression_type(to_expression(id), expression_type(id)); + else + return to_expression(id); +} + +string CompilerGLSL::to_enclosed_unpacked_expression(uint32_t id) +{ + if (has_decoration(id, DecorationCPacked)) + return unpack_expression_type(to_expression(id), expression_type(id)); + else + return to_enclosed_expression(id); +} + string CompilerGLSL::to_extract_component_expression(uint32_t id, uint32_t index) { auto expr = to_enclosed_expression(id); @@ -3390,7 +3406,7 @@ void CompilerGLSL::emit_binary_op_cast(uint32_t result_type, uint32_t result_id, void CompilerGLSL::emit_unary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op) { bool forward = should_forward(op0); - emit_op(result_type, result_id, join(op, "(", to_expression(op0), ")"), forward); + emit_op(result_type, result_id, join(op, "(", to_unpacked_expression(op0), ")"), forward); inherit_expression_dependencies(result_id, op0); } @@ -3398,7 +3414,8 @@ void CompilerGLSL::emit_binary_func_op(uint32_t result_type, uint32_t result_id, const char *op) { bool forward = should_forward(op0) && should_forward(op1); - emit_op(result_type, result_id, join(op, "(", to_expression(op0), ", ", to_expression(op1), ")"), forward); + emit_op(result_type, result_id, join(op, "(", to_unpacked_expression(op0), ", ", to_unpacked_expression(op1), ")"), + forward); inherit_expression_dependencies(result_id, op0); inherit_expression_dependencies(result_id, op1); } @@ -3435,7 +3452,9 @@ void CompilerGLSL::emit_trinary_func_op(uint32_t result_type, uint32_t result_id { bool forward = should_forward(op0) && should_forward(op1) && should_forward(op2); emit_op(result_type, result_id, - join(op, "(", to_expression(op0), ", ", to_expression(op1), ", ", to_expression(op2), ")"), forward); + join(op, "(", to_unpacked_expression(op0), ", ", to_unpacked_expression(op1), ", ", + to_unpacked_expression(op2), ")"), + forward); inherit_expression_dependencies(result_id, op0); inherit_expression_dependencies(result_id, op1); @@ -3447,8 +3466,8 @@ void CompilerGLSL::emit_quaternary_func_op(uint32_t result_type, uint32_t result { bool forward = should_forward(op0) && should_forward(op1) && should_forward(op2) && should_forward(op3); emit_op(result_type, result_id, - join(op, "(", to_expression(op0), ", ", to_expression(op1), ", ", to_expression(op2), ", ", - to_expression(op3), ")"), + join(op, "(", to_unpacked_expression(op0), ", ", to_unpacked_expression(op1), ", ", + to_unpacked_expression(op2), ", ", to_unpacked_expression(op3), ")"), forward); inherit_expression_dependencies(result_id, op0); @@ -6572,10 +6591,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) // We only source from first vector, so can use swizzle. // If the vector is packed, unpack it before applying a swizzle (needed for MSL) - expr += to_enclosed_expression(vec0); - if (has_decoration(vec0, DecorationCPacked)) - expr = unpack_expression_type(expr, expression_type(vec0)); - + expr += to_enclosed_unpacked_expression(vec0); expr += "."; for (uint32_t i = 0; i < length; i++) expr += index_to_swizzle(elems[i]); diff --git a/spirv_glsl.hpp b/spirv_glsl.hpp index 5421726..e02ef34 100644 --- a/spirv_glsl.hpp +++ b/spirv_glsl.hpp @@ -436,6 +436,8 @@ protected: void append_global_func_args(const SPIRFunction &func, uint32_t index, std::vector &arglist); std::string to_expression(uint32_t id); std::string to_enclosed_expression(uint32_t id); + std::string to_unpacked_expression(uint32_t id); + std::string to_enclosed_unpacked_expression(uint32_t id); std::string to_extract_component_expression(uint32_t id, uint32_t index); std::string enclose_expression(const std::string &expr); void strip_enclosed_expression(std::string &expr);