Commit 596f653f by Alexis Hetu Committed by Alexis Hétu

Fixed atan corner case

atan(0, <negative>) was returning 0 instead of PI. Did a simple fix in the arctan() function and added an associated unit test. Change-Id: Idbbdaf099b5104e3aaa2868ca8fd806c6c735981 Reviewed-on: https://swiftshader-review.googlesource.com/18868Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent e475674e
...@@ -402,14 +402,13 @@ namespace sw ...@@ -402,14 +402,13 @@ namespace sw
Float4 y0 = Abs(y); Float4 y0 = Abs(y);
// Rotate to right quadrant when in left quadrant // Rotate to right quadrant when in left quadrant
Int4 non_zero_y = CmpNEQ(y0, Float4(0.0f)); Int4 Q = CmpLT(x0, Float4(0.0f));
Int4 Q = CmpLT(x0, Float4(0.0f)) & non_zero_y;
theta += As<Float4>(Q & As<Int4>(half_pi)); theta += As<Float4>(Q & As<Int4>(half_pi));
Float4 x1 = As<Float4>((Q & As<Int4>(y0)) | (~Q & As<Int4>(x0))); // FIXME: Vector select Float4 x1 = As<Float4>((Q & As<Int4>(y0)) | (~Q & As<Int4>(x0))); // FIXME: Vector select
Float4 y1 = As<Float4>((Q & As<Int4>(-x0)) | (~Q & As<Int4>(y0))); // FIXME: Vector select Float4 y1 = As<Float4>((Q & As<Int4>(-x0)) | (~Q & As<Int4>(y0))); // FIXME: Vector select
// Mirror to first octant when in second octant // Mirror to first octant when in second octant
Int4 O = CmpNLT(y1, x1) & non_zero_y; Int4 O = CmpNLT(y1, x1);
Float4 x2 = As<Float4>((O & As<Int4>(y1)) | (~O & As<Int4>(x1))); // FIXME: Vector select Float4 x2 = As<Float4>((O & As<Int4>(y1)) | (~O & As<Int4>(x1))); // FIXME: Vector select
Float4 y2 = As<Float4>((O & As<Int4>(x1)) | (~O & As<Int4>(y1))); // FIXME: Vector select Float4 y2 = As<Float4>((O & As<Int4>(x1)) | (~O & As<Int4>(y1))); // FIXME: Vector select
...@@ -417,7 +416,7 @@ namespace sw ...@@ -417,7 +416,7 @@ namespace sw
Int4 zero_x = CmpEQ(x2, Float4(0.0f)); Int4 zero_x = CmpEQ(x2, Float4(0.0f));
Int4 inf_y = IsInf(y2); // Since x2 >= y2, this means x2 == y2 == inf, so we use 45 degrees or pi/4 Int4 inf_y = IsInf(y2); // Since x2 >= y2, this means x2 == y2 == inf, so we use 45 degrees or pi/4
Float4 atan2_theta = arctan_01(y2 / x2, pp); Float4 atan2_theta = arctan_01(y2 / x2, pp);
theta += As<Float4>((~zero_x & ~inf_y & non_zero_y & ((O & As<Int4>(half_pi - atan2_theta)) | (~O & (As<Int4>(atan2_theta))))) | // FIXME: Vector select theta += As<Float4>((~zero_x & ~inf_y & ((O & As<Int4>(half_pi - atan2_theta)) | (~O & (As<Int4>(atan2_theta))))) | // FIXME: Vector select
(inf_y & As<Int4>(quarter_pi))); (inf_y & As<Int4>(quarter_pi)));
// Recover loss of precision for tiny theta angles // Recover loss of precision for tiny theta angles
......
...@@ -258,9 +258,12 @@ protected: ...@@ -258,9 +258,12 @@ protected:
GLint posLoc = glGetAttribLocation(program, "position"); GLint posLoc = glGetAttribLocation(program, "position");
EXPECT_GLENUM_EQ(GL_NONE, glGetError()); EXPECT_GLENUM_EQ(GL_NONE, glGetError());
GLint location = glGetUniformLocation(program, textureName); if(textureName)
ASSERT_NE(-1, location); {
glUniform1i(location, 0); GLint location = glGetUniformLocation(program, textureName);
ASSERT_NE(-1, location);
glUniform1i(location, 0);
}
float vertices[18] = { -1.0f, 1.0f, 0.5f, float vertices[18] = { -1.0f, 1.0f, 0.5f,
-1.0f, -1.0f, 0.5f, -1.0f, -1.0f, 0.5f,
...@@ -368,6 +371,60 @@ TEST_F(SwiftShaderTest, SamplerArrayInStructArrayAsFunctionArg) ...@@ -368,6 +371,60 @@ TEST_F(SwiftShaderTest, SamplerArrayInStructArrayAsFunctionArg)
Uninitialize(); Uninitialize();
} }
// Test sampling from a sampler in a struct as a function argument
TEST_F(SwiftShaderTest, AtanCornerCases)
{
Initialize(3, false);
const std::string vs =
"#version 300 es\n"
"in vec4 position;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position.xy, 0.0, 1.0);\n"
"}\n";
const std::string fs =
"#version 300 es\n"
"precision mediump float;\n"
"const float kPI = 3.14159265358979323846;"
"uniform float positive_value;\n"
"uniform float negative_value;\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
" // Should yield vec4(0, pi, pi/2, -pi/2)\n"
" vec4 result = atan(vec4(0.0, 0.0, positive_value, negative_value),\n"
" vec4(positive_value, negative_value, 0.0, 0.0));\n"
" fragColor = (result / vec4(kPI)) + vec4(0.5, -0.5, 0.0, 1.0) + vec4(0.5 / 255.0);\n"
"}\n";
const ProgramHandles ph = createProgram(vs, fs);
glUseProgram(ph.program);
GLint positive_value = glGetUniformLocation(ph.program, "positive_value");
ASSERT_NE(-1, positive_value);
GLint negative_value = glGetUniformLocation(ph.program, "negative_value");
ASSERT_NE(-1, negative_value);
glUniform1f(positive_value, 1.0);
glUniform1f(negative_value, -1.0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_GLENUM_EQ(GL_NONE, glGetError());
drawQuad(ph.program, nullptr);
deleteProgram(ph);
unsigned char grey[4] = { 128, 128, 128, 128 };
compareColor(grey);
EXPECT_GLENUM_EQ(GL_NONE, glGetError());
Uninitialize();
}
// Note: GL_ARB_texture_rectangle is part of gl2extchromium.h in the Chromium repo // Note: GL_ARB_texture_rectangle is part of gl2extchromium.h in the Chromium repo
// GL_ARB_texture_rectangle // GL_ARB_texture_rectangle
#ifndef GL_ARB_texture_rectangle #ifndef GL_ARB_texture_rectangle
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment