Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2019-07-26 15:28:16 +0300
committerGitHub <noreply@github.com>2019-07-26 15:28:16 +0300
commit87513f9ac025981b33fac7629e29420900cf283d (patch)
treee898ff10aaf0f2feb195f32c34fe3d982e38e61b
parent0630a8533c110d9b271cd6420b6b48ff138f560d (diff)
parentabb345d0b3b781843912de74f26a7b6e6ac56f6b (diff)
Merge pull request #1102 from KhronosGroup/fix-1096
MSL: Deal with Modf/Frexp where output is access chain to scalar.
-rw-r--r--reference/shaders-msl-no-opt/asm/frag/modf-frexp-scalar-access-chain-output.asm.frag17
-rw-r--r--shaders-msl-no-opt/asm/frag/modf-frexp-scalar-access-chain-output.asm.frag36
-rw-r--r--spirv_msl.cpp26
3 files changed, 79 insertions, 0 deletions
diff --git a/reference/shaders-msl-no-opt/asm/frag/modf-frexp-scalar-access-chain-output.asm.frag b/reference/shaders-msl-no-opt/asm/frag/modf-frexp-scalar-access-chain-output.asm.frag
new file mode 100644
index 00000000..910c8fa7
--- /dev/null
+++ b/reference/shaders-msl-no-opt/asm/frag/modf-frexp-scalar-access-chain-output.asm.frag
@@ -0,0 +1,17 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+fragment void main0()
+{
+ float3 col;
+ int2 _18;
+ float _23;
+ float _21 = modf(0.1500000059604644775390625, _23);
+ col.x = _23;
+ int _24;
+ float _22 = frexp(0.1500000059604644775390625, _24);
+ _18.y = _24;
+}
+
diff --git a/shaders-msl-no-opt/asm/frag/modf-frexp-scalar-access-chain-output.asm.frag b/shaders-msl-no-opt/asm/frag/modf-frexp-scalar-access-chain-output.asm.frag
new file mode 100644
index 00000000..707fa550
--- /dev/null
+++ b/shaders-msl-no-opt/asm/frag/modf-frexp-scalar-access-chain-output.asm.frag
@@ -0,0 +1,36 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 17
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpSource ESSL 310
+ OpName %main "main"
+ OpName %col "col"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%float_0_150000006 = OpConstant %float 0.150000006
+ %v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %int_1 = OpConstant %int 1
+ %v2int = OpTypeVector %int 2
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+%_ptr_Function_int = OpTypePointer Function %int
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %col = OpVariable %_ptr_Function_v3float Function
+ %icol = OpVariable %_ptr_Function_v2int Function
+ %ptr_x = OpAccessChain %_ptr_Function_float %col %int_0
+ %ptr_y = OpAccessChain %_ptr_Function_int %icol %int_1
+ %16 = OpExtInst %float %1 Modf %float_0_150000006 %ptr_x
+ %17 = OpExtInst %float %1 Frexp %float_0_150000006 %ptr_y
+ OpReturn
+ OpFunctionEnd
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index 1805e12a..a4f911c3 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -5260,6 +5260,32 @@ void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
break;
+ case GLSLstd450Modf:
+ case GLSLstd450Frexp:
+ {
+ // Special case. If the variable is a scalar access chain, we cannot use it directly. We have to emit a temporary.
+ auto *ptr = maybe_get<SPIRExpression>(args[1]);
+ if (ptr && ptr->access_chain && is_scalar(expression_type(args[1])))
+ {
+ register_call_out_argument(args[1]);
+ forced_temporaries.insert(id);
+
+ // Need to create temporaries and copy over to access chain after.
+ // We cannot directly take the reference of a vector swizzle in MSL, even if it's scalar ...
+ uint32_t &tmp_id = extra_sub_expressions[id];
+ if (!tmp_id)
+ tmp_id = ir.increase_bound_by(1);
+
+ uint32_t tmp_type_id = get_pointee_type_id(ptr->expression_type);
+ emit_uninitialized_temporary_expression(tmp_type_id, tmp_id);
+ emit_binary_func_op(result_type, id, args[0], tmp_id, eop == GLSLstd450Modf ? "modf" : "frexp");
+ statement(to_expression(args[1]), " = ", to_expression(tmp_id), ";");
+ }
+ else
+ CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
+ break;
+ }
+
default:
CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
break;