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 
testSetUp()31     void testSetUp() override
32     {
33         constexpr char kVS[] = R"(precision highp float;
34 attribute vec4 position;
35 varying vec2 texcoord;
36 
37 void main()
38 {
39     gl_Position = vec4(position.xy, 0.0, 1.0);
40     texcoord = (position.xy * 0.5) + 0.5;
41 })";
42 
43         constexpr char kFS[] = R"(precision highp float;
44 uniform sampler2D tex;
45 varying vec2 texcoord;
46 
47 void main()
48 {
49     gl_FragColor = texture2D(tex, texcoord);
50 })";
51 
52         m2DProgram                = CompileProgram(kVS, kFS);
53         mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");
54     }
55 
testTearDown()56     void testTearDown() override { glDeleteProgram(m2DProgram); }
57 
58     // Uses ColorStructType::writeColor to populate initial data for a texture, pass it to
59     // glTexImage2D, then render with it. The resulting colors should match the colors passed into
60     // ::writeColor.
61     template <typename ColorStructType>
runTest(GLenum tex2DFormat,GLenum tex2DType)62     void runTest(GLenum tex2DFormat, GLenum tex2DType)
63     {
64         gl::ColorF srcColorF[4];
65         ColorStructType pixels[4];
66 
67         GLuint tex = 0;
68         GLuint fbo = 0;
69         glGenTextures(1, &tex);
70         glGenFramebuffers(1, &fbo);
71         EXPECT_GL_NO_ERROR();
72 
73         srcColorF[0].red   = 1.0f;
74         srcColorF[0].green = 0.0f;
75         srcColorF[0].blue  = 0.0f;
76         srcColorF[0].alpha = 1.0f;  // Red
77         srcColorF[1].red   = 0.0f;
78         srcColorF[1].green = 1.0f;
79         srcColorF[1].blue  = 0.0f;
80         srcColorF[1].alpha = 1.0f;  // Green
81         srcColorF[2].red   = 0.0f;
82         srcColorF[2].green = 0.0f;
83         srcColorF[2].blue  = 1.0f;
84         srcColorF[2].alpha = 1.0f;  // Blue
85         srcColorF[3].red   = 1.0f;
86         srcColorF[3].green = 1.0f;
87         srcColorF[3].blue  = 0.0f;
88         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     runTest<R4G4B4A4>(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
130 }
131 
132 // Validation test for rx::R5G5B5A1's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR5G5B5A1)133 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR5G5B5A1)
134 {
135     runTest<R5G5B5A1>(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
136 }
137 
138 // Validation test for rx::R5G6B5's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR5G6B5)139 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR5G6B5)
140 {
141     runTest<R5G6B5>(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
142 }
143 
144 // Validation test for rx::R8G8B8A8's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR8G8B8A8)145 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR8G8B8A8)
146 {
147     runTest<R8G8B8A8>(GL_RGBA, GL_UNSIGNED_BYTE);
148 }
149 
150 // Validation test for rx::R8G8B8's writeColor functions
TEST_P(D3DImageFormatConversionTest,WriteColorFunctionR8G8B8)151 TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR8G8B8)
152 {
153     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
154     runTest<R8G8B8>(GL_RGB, GL_UNSIGNED_BYTE);
155 }
156 
157 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
158 // tests should be run against. Even though this test is only run on Windows (since it includes
159 // imageformats.h from the D3D renderer), we can still run the test against OpenGL. This is
160 // valuable, since it provides extra validation using a renderer that doesn't use imageformats.h
161 // itself.
162 ANGLE_INSTANTIATE_TEST_ES2(D3DImageFormatConversionTest);
163 
164 }  // namespace
165