From 9e6e5d273833930af0751e94c630c16a1083d960 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 6 Nov 2020 17:34:38 +0100 Subject: [PATCH] GLSL: Fix round/roundEven for legacy GLSL. --- reference/opt/shaders/frag/round-even.frag | 12 ++++++++++ reference/opt/shaders/frag/round.frag | 12 ++++++++++ .../shaders/legacy/fragment/round.legacy.frag | 13 +++++++++++ reference/shaders/frag/round-even.frag | 12 ++++++++++ reference/shaders/frag/round.frag | 12 ++++++++++ .../shaders/legacy/fragment/round.legacy.frag | 13 +++++++++++ shaders/frag/round-even.frag | 11 ++++++++++ shaders/frag/round.frag | 11 ++++++++++ shaders/legacy/fragment/round.legacy.frag | 11 ++++++++++ spirv_glsl.cpp | 22 ++++++++++++++++--- 10 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 reference/opt/shaders/frag/round-even.frag create mode 100644 reference/opt/shaders/frag/round.frag create mode 100644 reference/opt/shaders/legacy/fragment/round.legacy.frag create mode 100644 reference/shaders/frag/round-even.frag create mode 100644 reference/shaders/frag/round.frag create mode 100644 reference/shaders/legacy/fragment/round.legacy.frag create mode 100644 shaders/frag/round-even.frag create mode 100644 shaders/frag/round.frag create mode 100644 shaders/legacy/fragment/round.legacy.frag diff --git a/reference/opt/shaders/frag/round-even.frag b/reference/opt/shaders/frag/round-even.frag new file mode 100644 index 00000000..ab6f37ad --- /dev/null +++ b/reference/opt/shaders/frag/round-even.frag @@ -0,0 +1,12 @@ +#version 450 + +layout(location = 0) out vec4 FragColor; +layout(location = 0) in vec4 vA; +layout(location = 1) in float vB; + +void main() +{ + FragColor = roundEven(vA); + FragColor *= roundEven(vB); +} + diff --git a/reference/opt/shaders/frag/round.frag b/reference/opt/shaders/frag/round.frag new file mode 100644 index 00000000..0f1fc0db --- /dev/null +++ b/reference/opt/shaders/frag/round.frag @@ -0,0 +1,12 @@ +#version 450 + +layout(location = 0) out vec4 FragColor; +layout(location = 0) in vec4 vA; +layout(location = 1) in float vB; + +void main() +{ + FragColor = round(vA); + FragColor *= round(vB); +} + diff --git a/reference/opt/shaders/legacy/fragment/round.legacy.frag b/reference/opt/shaders/legacy/fragment/round.legacy.frag new file mode 100644 index 00000000..9033bc3c --- /dev/null +++ b/reference/opt/shaders/legacy/fragment/round.legacy.frag @@ -0,0 +1,13 @@ +#version 100 +precision mediump float; +precision highp int; + +varying highp vec4 vA; +varying highp float vB; + +void main() +{ + gl_FragData[0] = floor(vA + vec4(0.5)); + gl_FragData[0] *= floor(vB + float(0.5)); +} + diff --git a/reference/shaders/frag/round-even.frag b/reference/shaders/frag/round-even.frag new file mode 100644 index 00000000..ab6f37ad --- /dev/null +++ b/reference/shaders/frag/round-even.frag @@ -0,0 +1,12 @@ +#version 450 + +layout(location = 0) out vec4 FragColor; +layout(location = 0) in vec4 vA; +layout(location = 1) in float vB; + +void main() +{ + FragColor = roundEven(vA); + FragColor *= roundEven(vB); +} + diff --git a/reference/shaders/frag/round.frag b/reference/shaders/frag/round.frag new file mode 100644 index 00000000..0f1fc0db --- /dev/null +++ b/reference/shaders/frag/round.frag @@ -0,0 +1,12 @@ +#version 450 + +layout(location = 0) out vec4 FragColor; +layout(location = 0) in vec4 vA; +layout(location = 1) in float vB; + +void main() +{ + FragColor = round(vA); + FragColor *= round(vB); +} + diff --git a/reference/shaders/legacy/fragment/round.legacy.frag b/reference/shaders/legacy/fragment/round.legacy.frag new file mode 100644 index 00000000..9033bc3c --- /dev/null +++ b/reference/shaders/legacy/fragment/round.legacy.frag @@ -0,0 +1,13 @@ +#version 100 +precision mediump float; +precision highp int; + +varying highp vec4 vA; +varying highp float vB; + +void main() +{ + gl_FragData[0] = floor(vA + vec4(0.5)); + gl_FragData[0] *= floor(vB + float(0.5)); +} + diff --git a/shaders/frag/round-even.frag b/shaders/frag/round-even.frag new file mode 100644 index 00000000..594ac162 --- /dev/null +++ b/shaders/frag/round-even.frag @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec4 vA; +layout(location = 1) in float vB; +layout(location = 0) out vec4 FragColor; + +void main() +{ + FragColor = roundEven(vA); + FragColor *= roundEven(vB); +} diff --git a/shaders/frag/round.frag b/shaders/frag/round.frag new file mode 100644 index 00000000..c87b0abb --- /dev/null +++ b/shaders/frag/round.frag @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec4 vA; +layout(location = 1) in float vB; +layout(location = 0) out vec4 FragColor; + +void main() +{ + FragColor = round(vA); + FragColor *= round(vB); +} diff --git a/shaders/legacy/fragment/round.legacy.frag b/shaders/legacy/fragment/round.legacy.frag new file mode 100644 index 00000000..c87b0abb --- /dev/null +++ b/shaders/legacy/fragment/round.legacy.frag @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec4 vA; +layout(location = 1) in float vB; +layout(location = 0) out vec4 FragColor; + +void main() +{ + FragColor = round(vA); + FragColor *= round(vB); +} diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 712f5e5c..8a3908e8 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -6725,14 +6725,30 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, { // FP fiddling case GLSLstd450Round: - emit_unary_func_op(result_type, id, args[0], "round"); + if (!is_legacy()) + emit_unary_func_op(result_type, id, args[0], "round"); + else + { + auto op0 = to_enclosed_expression(args[0]); + auto &op0_type = expression_type(args[0]); + auto expr = join("floor(", op0, " + ", type_to_glsl_constructor(op0_type), "(0.5))"); + bool forward = should_forward(args[0]); + emit_op(result_type, id, expr, forward); + inherit_expression_dependencies(id, args[0]); + } break; case GLSLstd450RoundEven: - if ((options.es && options.version >= 300) || (!options.es && options.version >= 130)) + if (!is_legacy()) emit_unary_func_op(result_type, id, args[0], "roundEven"); + else if (!options.es) + { + // This extension provides round() with round-to-even semantics. + require_extension_internal("GL_EXT_gpu_shader4"); + emit_unary_func_op(result_type, id, args[0], "round"); + } else - SPIRV_CROSS_THROW("roundEven supported only in ESSL 300 and GLSL 130 and up."); + SPIRV_CROSS_THROW("roundEven supported only in ESSL 300."); break; case GLSLstd450Trunc: