diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index b3be9b75..1caa600e 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -5909,6 +5909,34 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) BFOP(mod); break; + case OpFRem: + { + if (is_legacy()) + SPIRV_CROSS_THROW("OpFRem requires trunc() and is only supported on non-legacy targets. A workaround is needed for legacy."); + + uint32_t result_type = ops[0]; + uint32_t result_id = ops[1]; + uint32_t op0 = ops[2]; + uint32_t op1 = ops[3]; + + // Needs special handling. + bool forward = should_forward(op0) && should_forward(op1); + auto expr = join(to_enclosed_expression(op0), + " - ", + to_enclosed_expression(op1), + " * ", + "trunc(", + to_enclosed_expression(op0), + " / ", + to_enclosed_expression(op1), + ")"); + + emit_op(result_type, result_id, expr, forward); + inherit_expression_dependencies(result_id, op0); + inherit_expression_dependencies(result_id, op1); + break; + } + // Relational case OpAny: UFOP(any); diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index a7ccf59b..5444df5c 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -3224,6 +3224,10 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) break; } + case OpFRem: + emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], "fmod"); + break; + case OpImage: { uint32_t result_type = ops[0]; diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 3b8a19bc..5585db1d 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -1486,6 +1486,10 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) UFOP(popcount); break; + case OpFRem: + BFOP(fmod); + break; + // Atomics case OpAtomicExchange: {