summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/UniformTest.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/angle/src/tests/gl_tests/UniformTest.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/UniformTest.cpp')
-rwxr-xr-xgfx/angle/src/tests/gl_tests/UniformTest.cpp682
1 files changed, 682 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/UniformTest.cpp b/gfx/angle/src/tests/gl_tests/UniformTest.cpp
new file mode 100755
index 000000000..4dd2738ef
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/UniformTest.cpp
@@ -0,0 +1,682 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "test_utils/ANGLETest.h"
+
+#include <array>
+#include <cmath>
+
+using namespace angle;
+
+namespace
+{
+
+class UniformTest : public ANGLETest
+{
+ protected:
+ UniformTest() : mProgram(0), mUniformFLocation(-1), mUniformILocation(-1), mUniformBLocation(-1)
+ {
+ setWindowWidth(128);
+ setWindowHeight(128);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ }
+
+ void SetUp() override
+ {
+ ANGLETest::SetUp();
+
+ const std::string &vertexShader = "void main() { gl_Position = vec4(1); }";
+ const std::string &fragShader =
+ "precision mediump float;\n"
+ "uniform float uniF;\n"
+ "uniform int uniI;\n"
+ "uniform bool uniB;\n"
+ "uniform bool uniBArr[4];\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(uniF + float(uniI));\n"
+ " gl_FragColor += vec4(uniB ? 1.0 : 0.0);\n"
+ " gl_FragColor += vec4(uniBArr[0] ? 1.0 : 0.0);\n"
+ "}";
+
+ mProgram = CompileProgram(vertexShader, fragShader);
+ ASSERT_NE(mProgram, 0u);
+
+ mUniformFLocation = glGetUniformLocation(mProgram, "uniF");
+ ASSERT_NE(mUniformFLocation, -1);
+
+ mUniformILocation = glGetUniformLocation(mProgram, "uniI");
+ ASSERT_NE(mUniformILocation, -1);
+
+ mUniformBLocation = glGetUniformLocation(mProgram, "uniB");
+ ASSERT_NE(mUniformBLocation, -1);
+
+ ASSERT_GL_NO_ERROR();
+ }
+
+ void TearDown() override
+ {
+ glDeleteProgram(mProgram);
+ ANGLETest::TearDown();
+ }
+
+ GLuint mProgram;
+ GLint mUniformFLocation;
+ GLint mUniformILocation;
+ GLint mUniformBLocation;
+};
+
+TEST_P(UniformTest, GetUniformNoCurrentProgram)
+{
+ glUseProgram(mProgram);
+ glUniform1f(mUniformFLocation, 1.0f);
+ glUniform1i(mUniformILocation, 1);
+ glUseProgram(0);
+
+ GLfloat f;
+ glGetnUniformfvEXT(mProgram, mUniformFLocation, 4, &f);
+ ASSERT_GL_NO_ERROR();
+ EXPECT_EQ(1.0f, f);
+
+ glGetUniformfv(mProgram, mUniformFLocation, &f);
+ ASSERT_GL_NO_ERROR();
+ EXPECT_EQ(1.0f, f);
+
+ GLint i;
+ glGetnUniformivEXT(mProgram, mUniformILocation, 4, &i);
+ ASSERT_GL_NO_ERROR();
+ EXPECT_EQ(1, i);
+
+ glGetUniformiv(mProgram, mUniformILocation, &i);
+ ASSERT_GL_NO_ERROR();
+ EXPECT_EQ(1, i);
+}
+
+TEST_P(UniformTest, UniformArrayLocations)
+{
+ // TODO(geofflang): Figure out why this is broken on Intel OpenGL
+ if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
+ {
+ std::cout << "Test skipped on Intel OpenGL." << std::endl;
+ return;
+ }
+
+ const std::string vertexShader = SHADER_SOURCE
+ (
+ precision mediump float;
+ uniform float uPosition[4];
+ void main(void)
+ {
+ gl_Position = vec4(uPosition[0], uPosition[1], uPosition[2], uPosition[3]);
+ }
+ );
+
+ const std::string fragShader = SHADER_SOURCE
+ (
+ precision mediump float;
+ uniform float uColor[4];
+ void main(void)
+ {
+ gl_FragColor = vec4(uColor[0], uColor[1], uColor[2], uColor[3]);
+ }
+ );
+
+ GLuint program = CompileProgram(vertexShader, fragShader);
+ ASSERT_NE(program, 0u);
+
+ // Array index zero should be equivalent to the un-indexed uniform
+ EXPECT_NE(-1, glGetUniformLocation(program, "uPosition"));
+ EXPECT_EQ(glGetUniformLocation(program, "uPosition"), glGetUniformLocation(program, "uPosition[0]"));
+
+ EXPECT_NE(-1, glGetUniformLocation(program, "uColor"));
+ EXPECT_EQ(glGetUniformLocation(program, "uColor"), glGetUniformLocation(program, "uColor[0]"));
+
+ // All array uniform locations should be unique
+ GLint positionLocations[4] =
+ {
+ glGetUniformLocation(program, "uPosition[0]"),
+ glGetUniformLocation(program, "uPosition[1]"),
+ glGetUniformLocation(program, "uPosition[2]"),
+ glGetUniformLocation(program, "uPosition[3]"),
+ };
+
+ GLint colorLocations[4] =
+ {
+ glGetUniformLocation(program, "uColor[0]"),
+ glGetUniformLocation(program, "uColor[1]"),
+ glGetUniformLocation(program, "uColor[2]"),
+ glGetUniformLocation(program, "uColor[3]"),
+ };
+
+ for (size_t i = 0; i < 4; i++)
+ {
+ EXPECT_NE(-1, positionLocations[i]);
+ EXPECT_NE(-1, colorLocations[i]);
+
+ for (size_t j = i + 1; j < 4; j++)
+ {
+ EXPECT_NE(positionLocations[i], positionLocations[j]);
+ EXPECT_NE(colorLocations[i], colorLocations[j]);
+ }
+ }
+
+ glDeleteProgram(program);
+}
+
+// Test that float to integer GetUniform rounds values correctly.
+TEST_P(UniformTest, FloatUniformStateQuery)
+{
+ std::vector<double> inValues;
+ std::vector<GLfloat> expectedFValues;
+ std::vector<GLint> expectedIValues;
+
+ double intMaxD = static_cast<double>(std::numeric_limits<GLint>::max());
+ double intMinD = static_cast<double>(std::numeric_limits<GLint>::min());
+
+ // TODO(jmadill): Investigate rounding of .5
+ inValues.push_back(-1.0);
+ inValues.push_back(-0.6);
+ // inValues.push_back(-0.5); // undefined behaviour?
+ inValues.push_back(-0.4);
+ inValues.push_back(0.0);
+ inValues.push_back(0.4);
+ // inValues.push_back(0.5); // undefined behaviour?
+ inValues.push_back(0.6);
+ inValues.push_back(1.0);
+ inValues.push_back(999999.2);
+ inValues.push_back(intMaxD * 2.0);
+ inValues.push_back(intMaxD + 1.0);
+ inValues.push_back(intMinD * 2.0);
+ inValues.push_back(intMinD - 1.0);
+
+ for (double value : inValues)
+ {
+ expectedFValues.push_back(static_cast<GLfloat>(value));
+
+ double clampedValue = std::max(intMinD, std::min(intMaxD, value));
+ double rounded = round(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 = static_cast<GLfloat>(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 = static_cast<GLfloat>(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;
+
+ // Calling Uniform1i
+ 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);
+
+ // Calling Uniform1f
+ glUniform1f(mUniformBLocation, 0.0f);
+
+ glGetUniformiv(mProgram, mUniformBLocation, &intValue);
+ EXPECT_EQ(0, intValue);
+
+ glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
+ EXPECT_EQ(0.0f, floatValue);
+
+ glUniform1f(mUniformBLocation, 1.0f);
+
+ glGetUniformiv(mProgram, mUniformBLocation, &intValue);
+ EXPECT_EQ(1, intValue);
+
+ glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
+ EXPECT_EQ(1.0f, floatValue);
+
+ ASSERT_GL_NO_ERROR();
+}
+
+// Test queries for arrays of boolean uniforms.
+TEST_P(UniformTest, BooleanArrayUniformStateQuery)
+{
+ glUseProgram(mProgram);
+ GLint boolValuesi[4] = {0, 1, 0, 1};
+ GLfloat boolValuesf[4] = {0, 1, 0, 1};
+
+ GLint locations[4] = {
+ glGetUniformLocation(mProgram, "uniBArr"),
+ glGetUniformLocation(mProgram, "uniBArr[1]"),
+ glGetUniformLocation(mProgram, "uniBArr[2]"),
+ glGetUniformLocation(mProgram, "uniBArr[3]"),
+ };
+
+ // Calling Uniform1iv
+ glUniform1iv(locations[0], 4, boolValuesi);
+
+ for (unsigned int idx = 0; idx < 4; ++idx)
+ {
+ int value = -1;
+ glGetUniformiv(mProgram, locations[idx], &value);
+ EXPECT_EQ(boolValuesi[idx], value);
+ }
+
+ for (unsigned int idx = 0; idx < 4; ++idx)
+ {
+ float value = -1.0f;
+ glGetUniformfv(mProgram, locations[idx], &value);
+ EXPECT_EQ(boolValuesf[idx], value);
+ }
+
+ // Calling Uniform1fv
+ glUniform1fv(locations[0], 4, boolValuesf);
+
+ for (unsigned int idx = 0; idx < 4; ++idx)
+ {
+ int value = -1;
+ glGetUniformiv(mProgram, locations[idx], &value);
+ EXPECT_EQ(boolValuesi[idx], value);
+ }
+
+ for (unsigned int idx = 0; idx < 4; ++idx)
+ {
+ float value = -1.0f;
+ glGetUniformfv(mProgram, locations[idx], &value);
+ EXPECT_EQ(boolValuesf[idx], value);
+ }
+
+ ASSERT_GL_NO_ERROR();
+}
+
+class UniformTestES3 : public ANGLETest
+{
+ protected:
+ UniformTestES3() : mProgram(0) {}
+
+ void SetUp() override
+ {
+ ANGLETest::SetUp();
+ }
+
+ void TearDown() override
+ {
+ if (mProgram != 0)
+ {
+ glDeleteProgram(mProgram);
+ mProgram = 0;
+ }
+ }
+
+ GLuint mProgram;
+};
+
+// Test queries for transposed arrays of non-square matrix uniforms.
+TEST_P(UniformTestES3, TranposedMatrixArrayUniformStateQuery)
+{
+ const std::string &vertexShader =
+ "#version 300 es\n"
+ "void main() { gl_Position = vec4(1); }";
+ const std::string &fragShader =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "uniform mat3x2 uniMat3x2[5];\n"
+ "out vec4 color;\n"
+ "void main() {\n"
+ " color = vec4(uniMat3x2[0][0][0]);\n"
+ "}";
+
+ mProgram = CompileProgram(vertexShader, fragShader);
+ ASSERT_NE(mProgram, 0u);
+
+ glUseProgram(mProgram);
+
+ std::vector<GLfloat> transposedValues;
+
+ for (size_t arrayElement = 0; arrayElement < 5; ++arrayElement)
+ {
+ transposedValues.push_back(1.0f + arrayElement);
+ transposedValues.push_back(3.0f + arrayElement);
+ transposedValues.push_back(5.0f + arrayElement);
+ transposedValues.push_back(2.0f + arrayElement);
+ transposedValues.push_back(4.0f + arrayElement);
+ transposedValues.push_back(6.0f + arrayElement);
+ }
+
+ // Setting as a clump
+ GLint baseLocation = glGetUniformLocation(mProgram, "uniMat3x2");
+ ASSERT_NE(-1, baseLocation);
+
+ glUniformMatrix3x2fv(baseLocation, 5, GL_TRUE, &transposedValues[0]);
+
+ for (size_t arrayElement = 0; arrayElement < 5; ++arrayElement)
+ {
+ std::stringstream nameStr;
+ nameStr << "uniMat3x2[" << arrayElement << "]";
+ std::string name = nameStr.str();
+ GLint location = glGetUniformLocation(mProgram, name.c_str());
+ ASSERT_NE(-1, location);
+
+ std::vector<GLfloat> sequentialValues(6, 0);
+ glGetUniformfv(mProgram, location, &sequentialValues[0]);
+
+ ASSERT_GL_NO_ERROR();
+
+ for (size_t comp = 0; comp < 6; ++comp)
+ {
+ EXPECT_EQ(static_cast<GLfloat>(comp + 1 + arrayElement), sequentialValues[comp]);
+ }
+ }
+}
+
+// Check that trying setting too many elements of an array doesn't overflow
+TEST_P(UniformTestES3, OverflowArray)
+{
+ const std::string &vertexShader =
+ "#version 300 es\n"
+ "void main() { gl_Position = vec4(1); }";
+ const std::string &fragShader =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "uniform float uniF[5];\n"
+ "uniform mat3x2 uniMat3x2[5];\n"
+ "out vec4 color;\n"
+ "void main() {\n"
+ " color = vec4(uniMat3x2[0][0][0] + uniF[0]);\n"
+ "}";
+
+ mProgram = CompileProgram(vertexShader, fragShader);
+ ASSERT_NE(mProgram, 0u);
+
+ glUseProgram(mProgram);
+
+ const size_t kOverflowSize = 10000;
+ std::vector<GLfloat> values(10000 * 6);
+
+ // Setting as a clump
+ GLint floatLocation = glGetUniformLocation(mProgram, "uniF");
+ ASSERT_NE(-1, floatLocation);
+ GLint matLocation = glGetUniformLocation(mProgram, "uniMat3x2");
+ ASSERT_NE(-1, matLocation);
+
+ // Set too many float uniforms
+ glUniform1fv(floatLocation, kOverflowSize, &values[0]);
+
+ // Set too many matrix uniforms, transposed or not
+ glUniformMatrix3x2fv(matLocation, kOverflowSize, GL_FALSE, &values[0]);
+ glUniformMatrix3x2fv(matLocation, kOverflowSize, GL_TRUE, &values[0]);
+
+ // Same checks but with offsets
+ GLint floatLocationOffset = glGetUniformLocation(mProgram, "uniF[3]");
+ ASSERT_NE(-1, floatLocationOffset);
+ GLint matLocationOffset = glGetUniformLocation(mProgram, "uniMat3x2[3]");
+ ASSERT_NE(-1, matLocationOffset);
+
+ glUniform1fv(floatLocationOffset, kOverflowSize, &values[0]);
+ glUniformMatrix3x2fv(matLocationOffset, kOverflowSize, GL_FALSE, &values[0]);
+ glUniformMatrix3x2fv(matLocationOffset, kOverflowSize, GL_TRUE, &values[0]);
+}
+
+// Check that sampler uniforms only show up one time in the list
+TEST_P(UniformTest, SamplerUniformsAppearOnce)
+{
+ int maxVertexTextureImageUnits = 0;
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits);
+
+ if (maxVertexTextureImageUnits == 0)
+ {
+ std::cout << "Renderer doesn't support vertex texture fetch, skipping test" << std::endl;
+ return;
+ }
+
+ const std::string &vertShader =
+ "attribute vec2 position;\n"
+ "uniform sampler2D tex2D;\n"
+ "varying vec4 color;\n"
+ "void main() {\n"
+ " gl_Position = vec4(position, 0, 1);\n"
+ " color = texture2D(tex2D, vec2(0));\n"
+ "}";
+
+ const std::string &fragShader =
+ "precision mediump float;\n"
+ "varying vec4 color;\n"
+ "uniform sampler2D tex2D;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(tex2D, vec2(0)) + color;\n"
+ "}";
+
+ GLuint program = CompileProgram(vertShader, fragShader);
+ ASSERT_NE(0u, program);
+
+ GLint activeUniformsCount = 0;
+ glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniformsCount);
+ ASSERT_EQ(1, activeUniformsCount);
+
+ GLint size = 0;
+ GLenum type = GL_NONE;
+ GLchar name[120] = {0};
+ glGetActiveUniform(program, 0, 100, nullptr, &size, &type, name);
+ EXPECT_EQ(1, size);
+ EXPECT_GLENUM_EQ(GL_SAMPLER_2D, type);
+ EXPECT_STREQ("tex2D", name);
+
+ EXPECT_GL_NO_ERROR();
+
+ glDeleteProgram(program);
+}
+
+template <typename T, typename GetUniformV>
+void CheckOneElement(GetUniformV getUniformv,
+ GLuint program,
+ const std::string &name,
+ int components,
+ T canary)
+{
+ // The buffer getting the results has three chunks
+ // - A chunk to see underflows
+ // - A chunk that will hold the result
+ // - A chunk to see overflows for when components = kChunkSize
+ static const size_t kChunkSize = 4;
+ std::array<T, 3 * kChunkSize> buffer;
+ buffer.fill(canary);
+
+ GLint location = glGetUniformLocation(program, name.c_str());
+ ASSERT_NE(location, -1);
+
+ getUniformv(program, location, &buffer[kChunkSize]);
+ for (size_t i = 0; i < kChunkSize; i++)
+ {
+ ASSERT_EQ(canary, buffer[i]);
+ }
+ for (size_t i = kChunkSize + components; i < buffer.size(); i++)
+ {
+ ASSERT_EQ(canary, buffer[i]);
+ }
+}
+
+// Check that getting an element array doesn't return the whole array.
+TEST_P(UniformTestES3, ReturnsOnlyOneArrayElement)
+{
+ static const size_t kArraySize = 4;
+ struct UniformArrayInfo
+ {
+ UniformArrayInfo(std::string type, std::string name, int components)
+ : type(type), name(name), components(components)
+ {
+ }
+ std::string type;
+ std::string name;
+ int components;
+ };
+
+ // Check for various number of components and types
+ std::vector<UniformArrayInfo> uniformArrays;
+ uniformArrays.emplace_back("bool", "uBool", 1);
+ uniformArrays.emplace_back("vec2", "uFloat", 2);
+ uniformArrays.emplace_back("ivec3", "uInt", 3);
+ uniformArrays.emplace_back("uvec4", "uUint", 4);
+
+ std::ostringstream uniformStream;
+ std::ostringstream additionStream;
+ for (const auto &array : uniformArrays)
+ {
+ uniformStream << "uniform " << array.type << " " << array.name << "["
+ << ToString(kArraySize) << "];\n";
+
+ // We need to make use of the uniforms or they get compiled out.
+ for (int i = 0; i < 4; i++)
+ {
+ if (array.components == 1)
+ {
+ additionStream << " + float(" << array.name << "[" << i << "])";
+ }
+ else
+ {
+ for (int component = 0; component < array.components; component++)
+ {
+ additionStream << " + float(" << array.name << "[" << i << "][" << component
+ << "])";
+ }
+ }
+ }
+ }
+
+ const std::string &vertexShader =
+ "#version 300 es\n" +
+ uniformStream.str() +
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(1.0" + additionStream.str() + ");\n"
+ "}";
+
+ const std::string &fragmentShader =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "out vec4 color;\n"
+ "void main ()\n"
+ "{\n"
+ " color = vec4(1, 0, 0, 1);\n"
+ "}";
+
+ mProgram = CompileProgram(vertexShader, fragmentShader);
+ ASSERT_NE(0u, mProgram);
+
+ glUseProgram(mProgram);
+
+ for (const auto &uniformArray : uniformArrays)
+ {
+ for (size_t index = 0; index < kArraySize; index++)
+ {
+ std::string strIndex = "[" + ToString(index) + "]";
+ // Check all the different glGetUniformv functions
+ CheckOneElement<float>(glGetUniformfv, mProgram, uniformArray.name + strIndex,
+ uniformArray.components, 42.4242f);
+ CheckOneElement<int>(glGetUniformiv, mProgram, uniformArray.name + strIndex,
+ uniformArray.components, 0x7BADBED5);
+ CheckOneElement<unsigned int>(glGetUniformuiv, mProgram, uniformArray.name + strIndex,
+ uniformArray.components, 0xDEADBEEF);
+ }
+ }
+}
+
+// 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_D3D11_FL9_3(),
+ ES2_OPENGL(),
+ ES2_OPENGLES());
+ANGLE_INSTANTIATE_TEST(UniformTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
+
+} // namespace