1#include "ANGLETest.h"
2
3class VertexAttributeTest : public ANGLETest
4{
5protected:
6    VertexAttributeTest()
7    {
8        setWindowWidth(128);
9        setWindowHeight(128);
10        setConfigRedBits(8);
11        setConfigGreenBits(8);
12        setConfigBlueBits(8);
13        setConfigAlphaBits(8);
14        setConfigDepthBits(24);
15
16        mProgram = 0;
17        mTestAttrib = -1;
18        mExpectedAttrib = -1;
19    }
20
21    struct TestData
22    {
23        GLenum type;
24        GLboolean normalized;
25
26        const void *inputData;
27        const GLfloat *expectedData;
28    };
29
30    void runTest(const TestData& test)
31    {
32        GLint viewportSize[4];
33        glGetIntegerv(GL_VIEWPORT, viewportSize);
34
35        GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2;
36        GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2;
37
38        for (size_t i = 0; i < 4; i++)
39        {
40            glBindBuffer(GL_ARRAY_BUFFER, 0);
41            glVertexAttribPointer(mTestAttrib, i + 1, test.type, test.normalized, 0, test.inputData);
42            glVertexAttribPointer(mExpectedAttrib, i + 1, GL_FLOAT, GL_FALSE, 0, test.expectedData);
43
44            glEnableVertexAttribArray(mTestAttrib);
45            glEnableVertexAttribArray(mExpectedAttrib);
46
47            drawQuad(mProgram, "position", 0.5f);
48
49            glDisableVertexAttribArray(mTestAttrib);
50            glDisableVertexAttribArray(mExpectedAttrib);
51
52            // We need to offset our checks from triangle edges to ensure we don't fall on a single tri
53            // Avoid making assumptions of drawQuad with four checks to check the four possible tri regions
54            EXPECT_PIXEL_EQ((midPixelX + viewportSize[0]) / 2, midPixelY, 255, 255, 255, 255);
55            EXPECT_PIXEL_EQ((midPixelX + viewportSize[2]) / 2, midPixelY, 255, 255, 255, 255);
56            EXPECT_PIXEL_EQ(midPixelX, (midPixelY + viewportSize[1]) / 2, 255, 255, 255, 255);
57            EXPECT_PIXEL_EQ(midPixelX, (midPixelY + viewportSize[3]) / 2, 255, 255, 255, 255);
58        }
59    }
60
61    virtual void SetUp()
62    {
63        ANGLETest::SetUp();
64
65        const std::string testVertexShaderSource = SHADER_SOURCE
66        (
67            attribute highp vec4 position;
68            attribute highp vec4 test;
69            attribute highp vec4 expected;
70
71            varying highp vec4 color;
72
73            void main(void)
74            {
75                gl_Position = position;
76                color = vec4(lessThan(abs(test - expected), vec4(1.0 / 64.0)));
77            }
78        );
79
80        const std::string testFragmentShaderSource = SHADER_SOURCE
81        (
82            varying highp vec4 color;
83            void main(void)
84            {
85                gl_FragColor = color;
86            }
87        );
88
89        mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
90        if (mProgram == 0)
91        {
92            FAIL() << "shader compilation failed.";
93        }
94
95        mTestAttrib = glGetAttribLocation(mProgram, "test");
96        mExpectedAttrib = glGetAttribLocation(mProgram, "expected");
97
98        glUseProgram(mProgram);
99
100        glClearColor(0, 0, 0, 0);
101        glClearDepthf(0.0);
102        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
103
104        glDisable(GL_DEPTH_TEST);
105    }
106
107    virtual void TearDown()
108    {
109        glDeleteProgram(mProgram);
110
111        ANGLETest::TearDown();
112    }
113
114    static const size_t mVertexCount = 24;
115
116    GLuint mProgram;
117    GLint mTestAttrib;
118    GLint mExpectedAttrib;
119};
120
121TEST_F(VertexAttributeTest, UnsignedByteUnnormalized)
122{
123    GLubyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, 5, 6, 7, 125, 126, 127, 128, 129, 250, 251, 252, 253, 254, 255 };
124    GLfloat expectedData[mVertexCount];
125    for (size_t i = 0; i < mVertexCount; i++)
126    {
127        expectedData[i] = inputData[i];
128    }
129
130    TestData data = { GL_UNSIGNED_BYTE, GL_FALSE, inputData, expectedData };
131    runTest(data);
132}
133
134TEST_F(VertexAttributeTest, UnsignedByteNormalized)
135{
136    GLubyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, 5, 6, 7, 125, 126, 127, 128, 129, 250, 251, 252, 253, 254, 255 };
137    GLfloat expectedData[mVertexCount];
138    for (size_t i = 0; i < mVertexCount; i++)
139    {
140        expectedData[i] = inputData[i] / 255.0f;
141    }
142
143    TestData data = { GL_UNSIGNED_BYTE, GL_TRUE, inputData, expectedData };
144    runTest(data);
145}
146
147TEST_F(VertexAttributeTest, ByteUnnormalized)
148{
149    GLbyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, -1, -2, -3, -4, 125, 126, 127, -128, -127, -126 };
150    GLfloat expectedData[mVertexCount];
151    for (size_t i = 0; i < mVertexCount; i++)
152    {
153        expectedData[i] = inputData[i];
154    }
155
156    TestData data = { GL_BYTE, GL_FALSE, inputData, expectedData };
157    runTest(data);
158}
159
160TEST_F(VertexAttributeTest, ByteNormalized)
161{
162    GLbyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, -1, -2, -3, -4, 125, 126, 127, -128, -127, -126 };
163    GLfloat expectedData[mVertexCount];
164    for (size_t i = 0; i < mVertexCount; i++)
165    {
166        expectedData[i] = ((2.0f * inputData[i]) + 1.0f) / 255.0f;
167    }
168
169    TestData data = { GL_BYTE, GL_TRUE, inputData, expectedData };
170    runTest(data);
171}
172
173TEST_F(VertexAttributeTest, UnsignedShortUnnormalized)
174{
175    GLushort inputData[mVertexCount] = { 0, 1, 2, 3, 254, 255, 256, 32766, 32767, 32768, 65533, 65534, 65535 };
176    GLfloat expectedData[mVertexCount];
177    for (size_t i = 0; i < mVertexCount; i++)
178    {
179        expectedData[i] = inputData[i];
180    }
181
182    TestData data = { GL_UNSIGNED_SHORT, GL_FALSE, inputData, expectedData };
183    runTest(data);
184}
185
186TEST_F(VertexAttributeTest, UnsignedShortNormalized)
187{
188    GLushort inputData[mVertexCount] = { 0, 1, 2, 3, 254, 255, 256, 32766, 32767, 32768, 65533, 65534, 65535 };
189    GLfloat expectedData[mVertexCount];
190    for (size_t i = 0; i < mVertexCount; i++)
191    {
192        expectedData[i] = inputData[i] / 65535.0f;
193    }
194
195    TestData data = { GL_UNSIGNED_SHORT, GL_TRUE, inputData, expectedData };
196    runTest(data);
197}
198
199TEST_F(VertexAttributeTest, ShortUnnormalized)
200{
201    GLshort inputData[mVertexCount] = {  0, 1, 2, 3, -1, -2, -3, -4, 32766, 32767, -32768, -32767, -32766 };
202    GLfloat expectedData[mVertexCount];
203    for (size_t i = 0; i < mVertexCount; i++)
204    {
205        expectedData[i] = inputData[i];
206    }
207
208    TestData data = { GL_SHORT, GL_FALSE, inputData, expectedData };
209    runTest(data);
210}
211
212TEST_F(VertexAttributeTest, ShortNormalized)
213{
214    GLshort inputData[mVertexCount] = {  0, 1, 2, 3, -1, -2, -3, -4, 32766, 32767, -32768, -32767, -32766 };
215    GLfloat expectedData[mVertexCount];
216    for (size_t i = 0; i < mVertexCount; i++)
217    {
218        expectedData[i] = ((2.0f * inputData[i]) + 1.0f) / 65535.0f;
219    }
220
221    TestData data = { GL_SHORT, GL_TRUE, inputData, expectedData };
222    runTest(data);
223}
224