• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
7 #include "test_utils/ANGLETest.h"
8 
9 #include <vector>
10 #include "test_utils/gl_raii.h"
11 
12 using namespace angle;
13 
14 class IncompleteTextureTest : public ANGLETest
15 {
16   protected:
IncompleteTextureTest()17     IncompleteTextureTest()
18     {
19         setWindowWidth(128);
20         setWindowHeight(128);
21         setConfigRedBits(8);
22         setConfigGreenBits(8);
23         setConfigBlueBits(8);
24         setConfigAlphaBits(8);
25     }
26 
testSetUp()27     void testSetUp() override
28     {
29         constexpr char kVS[] = R"(precision highp float;
30 attribute vec4 position;
31 varying vec2 texcoord;
32 
33 void main()
34 {
35     gl_Position = position;
36     texcoord = (position.xy * 0.5) + 0.5;
37 })";
38 
39         constexpr char kFS[] = R"(precision highp float;
40 uniform sampler2D tex;
41 varying vec2 texcoord;
42 
43 void main()
44 {
45     gl_FragColor = texture2D(tex, texcoord);
46 })";
47 
48         mProgram = CompileProgram(kVS, kFS);
49         if (mProgram == 0)
50         {
51             FAIL() << "shader compilation failed.";
52         }
53 
54         mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
55     }
56 
testTearDown()57     void testTearDown() override { glDeleteProgram(mProgram); }
58 
59     GLuint mProgram;
60     GLint mTextureUniformLocation;
61 };
62 
63 class IncompleteTextureTestES3 : public ANGLETest
64 {
65   protected:
IncompleteTextureTestES3()66     IncompleteTextureTestES3()
67     {
68         setWindowWidth(128);
69         setWindowHeight(128);
70         setConfigRedBits(8);
71         setConfigGreenBits(8);
72         setConfigBlueBits(8);
73         setConfigAlphaBits(8);
74     }
75 };
76 
77 class IncompleteTextureTestES31 : public ANGLETest
78 {
79   protected:
IncompleteTextureTestES31()80     IncompleteTextureTestES31()
81     {
82         setWindowWidth(128);
83         setWindowHeight(128);
84         setConfigRedBits(8);
85         setConfigGreenBits(8);
86         setConfigBlueBits(8);
87         setConfigAlphaBits(8);
88     }
89 };
90 
91 // Test rendering with an incomplete texture.
TEST_P(IncompleteTextureTest,IncompleteTexture2D)92 TEST_P(IncompleteTextureTest, IncompleteTexture2D)
93 {
94     GLTexture tex;
95     glActiveTexture(GL_TEXTURE0);
96     glBindTexture(GL_TEXTURE_2D, tex);
97 
98     glUseProgram(mProgram);
99     glUniform1i(mTextureUniformLocation, 0);
100 
101     constexpr GLsizei kTextureSize = 2;
102     std::vector<GLColor> textureData(kTextureSize * kTextureSize, GLColor::red);
103 
104     // Make a complete texture.
105     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
106                  GL_UNSIGNED_BYTE, textureData.data());
107     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
108 
109     // Should be complete - expect red.
110     drawQuad(mProgram, "position", 0.5f);
111     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "complete texture should be red";
112 
113     // Make texture incomplete.
114     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
115 
116     // Should be incomplete - expect black.
117     drawQuad(mProgram, "position", 0.5f);
118     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black) << "incomplete texture should be black";
119 
120     // Make texture complete by defining the second mip.
121     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTextureSize >> 1, kTextureSize >> 1, 0, GL_RGBA,
122                  GL_UNSIGNED_BYTE, textureData.data());
123 
124     // Should be complete - expect red.
125     drawQuad(mProgram, "position", 0.5f);
126     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "mip-complete texture should be red";
127 }
128 
129 // Tests redefining a texture with half the size works as expected.
TEST_P(IncompleteTextureTest,UpdateTexture)130 TEST_P(IncompleteTextureTest, UpdateTexture)
131 {
132     GLTexture tex;
133     glActiveTexture(GL_TEXTURE0);
134     glBindTexture(GL_TEXTURE_2D, tex);
135 
136     glUseProgram(mProgram);
137     glUniform1i(mTextureUniformLocation, 0);
138 
139     constexpr GLsizei redTextureSize = 64;
140     std::vector<GLColor> redTextureData(redTextureSize * redTextureSize, GLColor::red);
141     for (GLint mip = 0; mip < 7; ++mip)
142     {
143         const GLsizei mipSize = redTextureSize >> mip;
144 
145         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, mipSize, mipSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
146                      redTextureData.data());
147     }
148 
149     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
150     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
151 
152     drawQuad(mProgram, "position", 0.5f);
153     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
154 
155     constexpr GLsizei greenTextureSize = 32;
156     std::vector<GLColor> greenTextureData(greenTextureSize * greenTextureSize, GLColor::green);
157 
158     for (GLint mip = 0; mip < 6; ++mip)
159     {
160         const GLsizei mipSize = greenTextureSize >> mip;
161 
162         glTexSubImage2D(GL_TEXTURE_2D, mip, mipSize, mipSize, mipSize, mipSize, GL_RGBA,
163                         GL_UNSIGNED_BYTE, greenTextureData.data());
164     }
165 
166     drawQuad(mProgram, "position", 0.5f);
167     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - greenTextureSize, getWindowHeight() - greenTextureSize,
168                           GLColor::green);
169 }
170 
171 // Tests that incomplete textures don't get initialized with the unpack buffer contents.
TEST_P(IncompleteTextureTestES3,UnpackBufferBound)172 TEST_P(IncompleteTextureTestES3, UnpackBufferBound)
173 {
174     // http://anglebug.com/4092
175     ANGLE_SKIP_TEST_IF(IsVulkan());
176     std::vector<GLColor> red(16, GLColor::red);
177 
178     GLBuffer unpackBuffer;
179     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
180     glBufferData(GL_PIXEL_UNPACK_BUFFER, red.size() * sizeof(GLColor), red.data(), GL_STATIC_DRAW);
181 
182     draw2DTexturedQuad(0.5f, 1.0f, true);
183     ASSERT_GL_NO_ERROR();
184 
185     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
186 }
187 
188 // Tests that the incomplete multisample texture has the correct alpha value.
TEST_P(IncompleteTextureTestES31,MultisampleTexture)189 TEST_P(IncompleteTextureTestES31, MultisampleTexture)
190 {
191     // http://anglebug.com/4092
192     ANGLE_SKIP_TEST_IF(IsVulkan());
193     constexpr char kVS[] = R"(#version 310 es
194 in vec2 position;
195 out vec2 texCoord;
196 void main()
197 {
198     gl_Position = vec4(position, 0, 1);
199     texCoord = (position * 0.5) + 0.5;
200 })";
201 
202     constexpr char kFS[] = R"(#version 310 es
203 precision mediump float;
204 in vec2 texCoord;
205 out vec4 color;
206 uniform mediump sampler2DMS tex;
207 void main()
208 {
209     ivec2 texSize = textureSize(tex);
210     ivec2 texel = ivec2(vec2(texSize) * texCoord);
211     color = texelFetch(tex, texel, 0);
212 })";
213 
214     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
215     glClear(GL_COLOR_BUFFER_BIT);
216     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
217 
218     // The zero texture will be incomplete by default.
219     ANGLE_GL_PROGRAM(program, kVS, kFS);
220     drawQuad(program, "position", 0.5f);
221     ASSERT_GL_NO_ERROR();
222 
223     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
224 }
225 
226 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
227 // tests should be run against.
228 ANGLE_INSTANTIATE_TEST_ES2(IncompleteTextureTest);
229 ANGLE_INSTANTIATE_TEST_ES3(IncompleteTextureTestES3);
230 ANGLE_INSTANTIATE_TEST_ES31(IncompleteTextureTestES31);
231