From 8e851c1a0b9e923ceb77751b7ae7221d22833bcb Mon Sep 17 00:00:00 2001 From: Alexis Hetu Date: Thu, 4 Jun 2015 11:30:54 -0400 Subject: [PATCH] RoundEven implementation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Implementation for the roundEven glsl intrinsic function. All dEQP roundEven tests pass. Change-Id: I8b6f3704f03eea32b08a6c2dc318ecb99a01957d Reviewed-on: https://swiftshader-review.googlesource.com/3382 Tested-by: Alexis Hétu Reviewed-by: Nicolas Capens --- src/Shader/PixelRoutine.cpp | 1 + src/Shader/ShaderCore.cpp | 19 +++++++++++++++++++ src/Shader/ShaderCore.hpp | 1 + src/Shader/VertexProgram.cpp | 1 + 4 files changed, 22 insertions(+) diff --git a/src/Shader/PixelRoutine.cpp b/src/Shader/PixelRoutine.cpp index dded20296..d810f1bc6 100644 --- a/src/Shader/PixelRoutine.cpp +++ b/src/Shader/PixelRoutine.cpp @@ -3935,6 +3935,7 @@ namespace sw case Shader::OPCODE_TRUNC: trunc(d, s0); break; case Shader::OPCODE_FLOOR: floor(d, s0); break; case Shader::OPCODE_ROUND: round(d, s0); break; + case Shader::OPCODE_ROUNDEVEN: roundEven(d, s0); break; case Shader::OPCODE_CEIL: ceil(d, s0); break; case Shader::OPCODE_EXP2X: exp2x(d, s0, pp); break; case Shader::OPCODE_EXP2: exp2(d, s0, pp); break; diff --git a/src/Shader/ShaderCore.cpp b/src/Shader/ShaderCore.cpp index 516ec70fd..6d5b8565e 100644 --- a/src/Shader/ShaderCore.cpp +++ b/src/Shader/ShaderCore.cpp @@ -1001,6 +1001,25 @@ namespace sw dst.w = Round(src.w); } + void ShaderCore::roundEven(Vector4f &dst, Vector4f &src) + { + // dst = round(src) + ((round(src) < src) * 2 - 1) * (fract(src) == 0.5) * isOdd(round(src)); + // ex.: 1.5: 2 + (0 * 2 - 1) * 1 * 0 = 2 + // 2.5: 3 + (0 * 2 - 1) * 1 * 1 = 2 + // -1.5: -2 + (1 * 2 - 1) * 1 * 0 = -2 + // -2.5: -3 + (1 * 2 - 1) * 1 * 1 = -2 + // Even if the round implementation rounds the other way: + // 1.5: 1 + (1 * 2 - 1) * 1 * 1 = 2 + // 2.5: 2 + (1 * 2 - 1) * 1 * 0 = 2 + // -1.5: -1 + (0 * 2 - 1) * 1 * 1 = -2 + // -2.5: -2 + (0 * 2 - 1) * 1 * 0 = -2 + round(dst, src); + dst.x += ((Float4(CmpLT(dst.x, src.x) & Int4(1)) * Float4(2.0f)) - Float4(1.0f)) * Float4(CmpEQ(Frac(src.x), Float4(0.5f)) & Int4(1)) * Float4(Int4(dst.x) & Int4(1)); + dst.y += ((Float4(CmpLT(dst.y, src.y) & Int4(1)) * Float4(2.0f)) - Float4(1.0f)) * Float4(CmpEQ(Frac(src.y), Float4(0.5f)) & Int4(1)) * Float4(Int4(dst.y) & Int4(1)); + dst.z += ((Float4(CmpLT(dst.z, src.z) & Int4(1)) * Float4(2.0f)) - Float4(1.0f)) * Float4(CmpEQ(Frac(src.z), Float4(0.5f)) & Int4(1)) * Float4(Int4(dst.z) & Int4(1)); + dst.w += ((Float4(CmpLT(dst.w, src.w) & Int4(1)) * Float4(2.0f)) - Float4(1.0f)) * Float4(CmpEQ(Frac(src.w), Float4(0.5f)) & Int4(1)) * Float4(Int4(dst.w) & Int4(1)); + } + void ShaderCore::ceil(Vector4f &dst, Vector4f &src) { dst.x = Ceil(src.x); diff --git a/src/Shader/ShaderCore.hpp b/src/Shader/ShaderCore.hpp index 66ff2cdf1..bd18f5967 100644 --- a/src/Shader/ShaderCore.hpp +++ b/src/Shader/ShaderCore.hpp @@ -289,6 +289,7 @@ namespace sw void trunc(Vector4f &dst, Vector4f &src); void floor(Vector4f &dst, Vector4f &src); void round(Vector4f &dst, Vector4f &src); + void roundEven(Vector4f &dst, Vector4f &src); void ceil(Vector4f &dst, Vector4f &src); void powx(Vector4f &dst, Vector4f &src0, Vector4f &src1, bool pp = false); void pow(Vector4f &dst, Vector4f &src0, Vector4f &src1, bool pp = false); diff --git a/src/Shader/VertexProgram.cpp b/src/Shader/VertexProgram.cpp index acbdbcf69..14bd5f620 100644 --- a/src/Shader/VertexProgram.cpp +++ b/src/Shader/VertexProgram.cpp @@ -162,6 +162,7 @@ namespace sw case Shader::OPCODE_TRUNC: trunc(d, s0); break; case Shader::OPCODE_FLOOR: floor(d, s0); break; case Shader::OPCODE_ROUND: round(d, s0); break; + case Shader::OPCODE_ROUNDEVEN: roundEven(d, s0); break; case Shader::OPCODE_CEIL: ceil(d, s0); break; case Shader::OPCODE_LIT: lit(d, s0); break; case Shader::OPCODE_LOG2X: log2x(d, s0, pp); break; -- 2.11.0