Commit 6ba5d4dd by Jamie Madill

Fix GetUniform rounding in D3D. Also add a test.

The test will help cover a bug that I found when doing the refactor of gl::Program. BUG=angleproject:1123 Change-Id: Id353ffaffef83ad1538580ad01668c915bf9853f Reviewed-on: https://chromium-review.googlesource.com/297031Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 6026538a
......@@ -1833,7 +1833,7 @@ void ProgramD3D::getUniformv(GLint location, T *params, GLenum uniformType)
for (unsigned int i = 0; i < size; i++)
{
params[i] = static_cast<T>(floatParams[i]);
params[i] = static_cast<T>(roundf(floatParams[i]));
}
}
break;
......
......@@ -15,6 +15,10 @@ class UniformTest : public ANGLETest
{
protected:
UniformTest()
: mProgram(0),
mUniformFLocation(-1),
mUniformILocation(-1),
mUniformBLocation(-1)
{
setWindowWidth(128);
setWindowHeight(128);
......@@ -33,7 +37,8 @@ class UniformTest : public ANGLETest
"precision mediump float;\n"
"uniform float uniF;\n"
"uniform int uniI;\n"
"void main() { gl_FragColor = vec4(uniF + float(uniI)); }";
"uniform bool uniB;\n"
"void main() { gl_FragColor = vec4(uniF + float(uniI) + (uniB ? 1.0 : 0.0)); }";
mProgram = CompileProgram(vertexShader, fragShader);
ASSERT_NE(mProgram, 0u);
......@@ -44,6 +49,9 @@ class UniformTest : public ANGLETest
mUniformILocation = glGetUniformLocation(mProgram, "uniI");
ASSERT_NE(mUniformILocation, -1);
mUniformBLocation = glGetUniformLocation(mProgram, "uniB");
ASSERT_NE(mUniformBLocation, -1);
ASSERT_GL_NO_ERROR();
}
......@@ -56,6 +64,7 @@ class UniformTest : public ANGLETest
GLuint mProgram;
GLint mUniformFLocation;
GLint mUniformILocation;
GLint mUniformBLocation;
};
TEST_P(UniformTest, GetUniformNoCurrentProgram)
......@@ -155,6 +164,149 @@ TEST_P(UniformTest, UniformArrayLocations)
glDeleteProgram(program);
}
// Test that float to integer GetUniform rounds values correctly.
TEST_P(UniformTest, FloatUniformStateQuery)
{
std::vector<GLfloat> inValues;
std::vector<GLfloat> expectedFValues;
std::vector<GLint> expectedIValues;
GLfloat intMaxF = static_cast<GLfloat>(std::numeric_limits<GLint>::max());
GLfloat intMinF = static_cast<GLfloat>(std::numeric_limits<GLint>::min());
// TODO(jmadill): Investigate rounding of .5
inValues.push_back(-1.0f);
inValues.push_back(-0.6f);
// inValues.push_back(-0.5f); // undefined behaviour?
inValues.push_back(-0.4f);
inValues.push_back(0.0f);
inValues.push_back(0.4f);
// inValues.push_back(0.5f); // undefined behaviour?
inValues.push_back(0.6f);
inValues.push_back(1.0f);
inValues.push_back(999999.2f);
inValues.push_back(intMaxF * 2.0f);
inValues.push_back(intMaxF + 1.0f);
inValues.push_back(intMinF * 2.0f);
inValues.push_back(intMinF - 1.0f);
for (GLfloat value : inValues)
{
expectedFValues.push_back(value);
GLfloat clampedValue = std::max(intMinF, std::min(intMaxF, value));
GLfloat rounded = roundf(clampedValue);
expectedIValues.push_back(static_cast<GLint>(rounded));
}
glUseProgram(mProgram);
ASSERT_GL_NO_ERROR();
for (size_t index = 0; index < inValues.size(); ++index)
{
GLfloat inValue = inValues[index];
GLfloat expectedValue = expectedFValues[index];
glUniform1f(mUniformFLocation, inValue);
GLfloat testValue;
glGetUniformfv(mProgram, mUniformFLocation, &testValue);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(expectedValue, testValue);
}
for (size_t index = 0; index < inValues.size(); ++index)
{
GLfloat inValue = inValues[index];
GLint expectedValue = expectedIValues[index];
glUniform1f(mUniformFLocation, inValue);
GLint testValue;
glGetUniformiv(mProgram, mUniformFLocation, &testValue);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(expectedValue, testValue);
}
}
// Test that integer to float GetUniform rounds values correctly.
TEST_P(UniformTest, IntUniformStateQuery)
{
std::vector<GLint> inValues;
std::vector<GLint> expectedIValues;
std::vector<GLfloat> expectedFValues;
GLint intMax = std::numeric_limits<GLint>::max();
GLint intMin = std::numeric_limits<GLint>::min();
inValues.push_back(-1);
inValues.push_back(0);
inValues.push_back(1);
inValues.push_back(999999);
inValues.push_back(intMax);
inValues.push_back(intMax - 1);
inValues.push_back(intMin);
inValues.push_back(intMin + 1);
for (GLint value : inValues)
{
expectedIValues.push_back(value);
expectedFValues.push_back(static_cast<GLfloat>(value));
}
glUseProgram(mProgram);
ASSERT_GL_NO_ERROR();
for (size_t index = 0; index < inValues.size(); ++index)
{
GLint inValue = inValues[index];
GLint expectedValue = expectedIValues[index];
glUniform1i(mUniformILocation, inValue);
GLint testValue;
glGetUniformiv(mProgram, mUniformILocation, &testValue);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(expectedValue, testValue);
}
for (size_t index = 0; index < inValues.size(); ++index)
{
GLint inValue = inValues[index];
GLfloat expectedValue = expectedFValues[index];
glUniform1i(mUniformILocation, inValue);
GLfloat testValue;
glGetUniformfv(mProgram, mUniformILocation, &testValue);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(expectedValue, testValue);
}
}
// Test that queries of boolean uniforms round correctly.
TEST_P(UniformTest, BooleanUniformStateQuery)
{
glUseProgram(mProgram);
GLint intValue = 0;
GLfloat floatValue = 0.0f;
glUniform1i(mUniformBLocation, GL_FALSE);
glGetUniformiv(mProgram, mUniformBLocation, &intValue);
EXPECT_EQ(0, intValue);
glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
EXPECT_EQ(0.0f, floatValue);
glUniform1i(mUniformBLocation, GL_TRUE);
glGetUniformiv(mProgram, mUniformBLocation, &intValue);
EXPECT_EQ(1, intValue);
glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
EXPECT_EQ(1.0f, floatValue);
ASSERT_GL_NO_ERROR();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(UniformTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
......
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