1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // D3DImageFormatConversionTest:
7 //   Basic tests to validate code relating to D3D Image format conversions.
8 
9 #include "test_utils/ANGLETest.h"
10 
11 #include "image_util/imageformats.h"
12 
13 using namespace angle;
14 
15 namespace
16 {
17 
18 class D3DImageFormatConversionTest : public ANGLETest
19 {
20   protected:
D3DImageFormatConversionTest()21     D3DImageFormatConversionTest()
22     {
23         setWindowWidth(128);
24         setWindowHeight(128);
25         setConfigRedBits(8);
26         setConfigGreenBits(8);
27         setConfigBlueBits(8);
28         setConfigAlphaBits(8);
29     }
30 
SetUp()31     void SetUp() override
32     {
33         ANGLETest::SetUp();
34 
35         const std::string vertexShaderSource = SHADER_SOURCE
36         (
37             precision highp float;
38             attribute vec4 position;
39             varying vec2 texcoord;
40 
41             void main()
42             {
43                 gl_Position = vec4(position.xy, 0.0, 1.0);
44                 texcoord = (position.xy * 0.5) + 0.5;
45             }
46         );
47 
48         const std::string fragmentShaderSource2D = SHADER_SOURCE
49         (
50             precision highp float;
51             uniform sampler2D tex;
52             varying vec2 texcoord;
53 
54             void main()
55             {
56                 gl_FragColor = texture2D(tex, texcoord);
57             }
58         );
59 
60         m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D);
61         mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");
62     }
63 
TearDown()64     void TearDown() override
65     {
66         glDeleteProgram(m2DProgram);
67 
68         ANGLETest::TearDown();
69     }
70 
71     // Uses ColorStructType::writeColor to populate initial data for a texture, pass it to glTexImage2D, then render with it.
72     // The resulting colors should match the colors passed into ::writeColor.
73     template <typename ColorStructType>
runTest(GLenum tex2DFormat,GLenum tex2DType)74     void runTest(GLenum tex2DFormat, GLenum tex2DType)
75     {
76         gl::ColorF srcColorF[4];
77         ColorStructType pixels[4];
78 
79         GLuint tex = 0;
80         GLuint fbo = 0;
81         glGenTextures(1, &tex);
82         glGenFramebuffers(1, &fbo);
83         EXPECT_GL_NO_ERROR();
84 
85         srcColorF[0].red = 1.0f; srcColorF[0].green = 0.0f; srcColorF[0].blue = 0.0f; srcColorF[0].alpha = 1.0f; // Red
86         srcColorF[1].red = 0.0f; srcColorF[1].green = 1.0f; srcColorF[1].blue = 0.0f; srcColorF[1].alpha = 1.0f; // Green
87         srcColorF[2].red = 0.0f; srcColorF[2].green = 0.0f; srcColorF[2].blue = 1.0f; srcColorF[2].alpha = 1.0f; // Blue
88         srcColorF[3].red = 1.0f; srcColorF[3].green = 1.0f; srcColorF[3].blue = 0.0f; srcColorF[3].alpha = 1.0f; // Red + Green (Yellow)
89 
90         // Convert the ColorF into the pixels that will be fed to glTexImage2D
91         for (unsigned int i = 0; i < 4; i++)
92         {
93             ColorStructType::writeColor(&(pixels[i]), &(srcColorF[i]));
94         }
95 
96         // Generate the texture
97         glBindTexture(GL_TEXTURE_2D, tex);
98         glTexImage2D(GL_TEXTURE_2D, 0, tex2DFormat, 2, 2, 0, tex2DFormat, tex2DType, pixels);
99         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
100         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
101         EXPECT_GL_NO_ERROR();
102 
103         // Draw a quad using the texture
104         glClearColor(0, 0, 0, 0);
105         glClear(GL_COLOR_BUFFER_BIT);
106         glUseProgram(m2DProgram);
107         glUniform1i(mTexture2DUniformLocation, 0);
108         drawQuad(m2DProgram, "position", 0.5f);
109         EXPECT_GL_NO_ERROR();
110 
111         // Check that the pixel colors match srcColorF
112         EXPECT_PIXEL_EQ(                    0,                    0, 255,   0,   0, 255);
113         EXPECT_PIXEL_EQ(getWindowHeight() - 1,                    0,   0, 255,   0, 255);
114         EXPECT_PIXEL_EQ(                    0, getWindowWidth() - 1,   0,   0, 255, 255);
115         EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255,   0, 255);
116         swapBuffers();
117 
118         glDeleteFramebuffers(1, &fbo);
119         glDeleteTextures(1, &tex);
120     }
121 
122     GLuint m2DProgram;
123     GLint mTexture2DUniformLocation;
124 };
125 
126 // Validation test for rx::R4G4B4A4's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR4G4B4A4)127 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR4G4B4A4)
128 {
129     // These tests fail on certain Intel machines running an un-updated version of Win7
130     // The tests pass after installing the latest updates from Windows Update.
131     // TODO: reenable these tests once the bots have been updated
132     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
133     {
134         std::cout << "Test skipped on Intel D3D11." << std::endl;
135         return;
136     }
137 
138     runTest<R4G4B4A4>(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
139 }
140 
141 // Validation test for rx::R5G5B5A1's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR5G5B5A1)142 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR5G5B5A1)
143 {
144     // These tests fail on certain Intel machines running an un-updated version of Win7
145     // The tests pass after installing the latest updates from Windows Update.
146     // TODO: reenable these tests once the bots have been updated
147     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
148     {
149         std::cout << "Test skipped on Intel D3D11." << std::endl;
150         return;
151     }
152 
153     runTest<R5G5B5A1>(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
154 }
155 
156 // Validation test for rx::R5G6B5's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR5G6B5)157 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR5G6B5)
158 {
159     // These tests fail on certain Intel machines running an un-updated version of Win7
160     // The tests pass after installing the latest updates from Windows Update.
161     // TODO: reenable these tests once the bots have been updated
162     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
163     {
164         std::cout << "Test skipped on Intel D3D11." << std::endl;
165         return;
166     }
167 
168     runTest<R5G6B5>(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
169 }
170 
171 // Validation test for rx::R8G8B8A8's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR8G8B8A8)172 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR8G8B8A8)
173 {
174     // These tests fail on certain Intel machines running an un-updated version of Win7
175     // The tests pass after installing the latest updates from Windows Update.
176     // TODO: reenable these tests once the bots have been updated
177     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
178     {
179         std::cout << "Test skipped on Intel D3D11." << std::endl;
180         return;
181     }
182 
183     runTest<R8G8B8A8>(GL_RGBA, GL_UNSIGNED_BYTE);
184 }
185 
186 // Validation test for rx::R8G8B8's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR8G8B8)187 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR8G8B8)
188 {
189     // These tests fail on certain Intel machines running an un-updated version of Win7
190     // The tests pass after installing the latest updates from Windows Update.
191     // TODO: reenable these tests once the bots have been updated
192     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
193     {
194         std::cout << "Test skipped on Intel D3D11." << std::endl;
195         return;
196     }
197 
198     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
199     runTest<R8G8B8>(GL_RGB, GL_UNSIGNED_BYTE);
200 }
201 
202 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
203 // Even though this test is only run on Windows (since it includes imageformats.h from the D3D renderer), we can still run the test
204 // against OpenGL. This is valuable, since it provides extra validation using a renderer that doesn't use imageformats.h itself.
205 ANGLE_INSTANTIATE_TEST(D3DImageFormatConversionTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL());
206 
207 } // namespace
208