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:
Diffstat (limited to 'spirv_glsl.cpp')
-rw-r--r--spirv_glsl.cpp50
1 files changed, 46 insertions, 4 deletions
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index d04adae4..9d7939c5 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -4935,14 +4935,27 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
break;
case GLSLstd450NMin:
- emit_binary_func_op(result_type, id, args[0], args[1], "unsupported_glsl450_nmin");
- break;
case GLSLstd450NMax:
- emit_binary_func_op(result_type, id, args[0], args[1], "unsupported_glsl450_nmax");
+ {
+ emit_nminmax_op(result_type, id, args[0], args[1], op);
break;
+ }
+
case GLSLstd450NClamp:
- emit_binary_func_op(result_type, id, args[0], args[1], "unsupported_glsl450_nclamp");
+ {
+ // Make sure we have a unique ID here to avoid aliasing the extra sub-expressions between clamp and NMin sub-op.
+ // IDs cannot exceed 24 bits, so we can make use of the higher bits for some unique flags.
+ uint32_t &max_id = extra_sub_expressions[id | 0x80000000u];
+ if (!max_id)
+ max_id = ir.increase_bound_by(1);
+
+ // Inherit precision qualifiers.
+ ir.meta[max_id] = ir.meta[id];
+
+ emit_nminmax_op(result_type, max_id, args[0], args[1], GLSLstd450NMax);
+ emit_nminmax_op(result_type, id, max_id, args[2], GLSLstd450NMin);
break;
+ }
default:
statement("// unimplemented GLSL op ", eop);
@@ -4950,6 +4963,35 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
}
}
+void CompilerGLSL::emit_nminmax_op(uint32_t result_type, uint32_t id, uint32_t op0, uint32_t op1, GLSLstd450 op)
+{
+ // Need to emulate this call.
+ uint32_t &ids = extra_sub_expressions[id];
+ if (!ids)
+ {
+ ids = ir.increase_bound_by(5);
+ auto btype = get<SPIRType>(result_type);
+ btype.basetype = SPIRType::Boolean;
+ set<SPIRType>(ids, btype);
+ }
+
+ uint32_t btype_id = ids + 0;
+ uint32_t left_nan_id = ids + 1;
+ uint32_t right_nan_id = ids + 2;
+ uint32_t tmp_id = ids + 3;
+ uint32_t mixed_first_id = ids + 4;
+
+ // Inherit precision qualifiers.
+ ir.meta[tmp_id] = ir.meta[id];
+ ir.meta[mixed_first_id] = ir.meta[id];
+
+ emit_unary_func_op(btype_id, left_nan_id, op0, "isnan");
+ emit_unary_func_op(btype_id, right_nan_id, op1, "isnan");
+ emit_binary_func_op(result_type, tmp_id, op0, op1, op == GLSLstd450NMin ? "min" : "max");
+ emit_mix_op(result_type, mixed_first_id, tmp_id, op1, left_nan_id);
+ emit_mix_op(result_type, id, mixed_first_id, op0, right_nan_id);
+}
+
void CompilerGLSL::emit_spv_amd_shader_ballot_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args,
uint32_t)
{