blob: c7f7654be358d8acf68ce78d20a5b4b660daeba0 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
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
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Geoff Lang0ddab0c2013-10-23 13:24:41 -04008
9#include <vector>
Jamie Madill81c2e252017-09-09 23:32:46 -040010#include "test_utils/gl_raii.h"
Geoff Lang0ddab0c2013-10-23 13:24:41 -040011
Jamie Madillfa05f602015-05-07 13:47:11 -040012using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070013
Geoff Lang0ddab0c2013-10-23 13:24:41 -040014class IncompleteTextureTest : public ANGLETest
15{
Jamie Madillfa05f602015-05-07 13:47:11 -040016 protected:
17 IncompleteTextureTest()
Geoff Lang0ddab0c2013-10-23 13:24:41 -040018 {
19 setWindowWidth(128);
20 setWindowHeight(128);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 }
26
27 virtual void SetUp()
28 {
29 ANGLETest::SetUp();
30
Olli Etuahoa20af6d2017-09-18 13:32:29 +030031 const std::string vertexShaderSource =
32 R"(precision highp float;
Geoff Lang0ddab0c2013-10-23 13:24:41 -040033 attribute vec4 position;
34 varying vec2 texcoord;
35
36 void main()
37 {
38 gl_Position = position;
39 texcoord = (position.xy * 0.5) + 0.5;
Olli Etuahoa20af6d2017-09-18 13:32:29 +030040 })";
Geoff Lang0ddab0c2013-10-23 13:24:41 -040041
Olli Etuahoa20af6d2017-09-18 13:32:29 +030042 const std::string fragmentShaderSource =
43 R"(precision highp float;
Geoff Lang0ddab0c2013-10-23 13:24:41 -040044 uniform sampler2D tex;
45 varying vec2 texcoord;
46
47 void main()
48 {
49 gl_FragColor = texture2D(tex, texcoord);
Olli Etuahoa20af6d2017-09-18 13:32:29 +030050 })";
Geoff Lang0ddab0c2013-10-23 13:24:41 -040051
Jamie Madill5599c8f2014-08-26 13:16:39 -040052 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
Geoff Lang0ddab0c2013-10-23 13:24:41 -040053 if (mProgram == 0)
54 {
55 FAIL() << "shader compilation failed.";
56 }
57
58 mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
59 }
60
61 virtual void TearDown()
62 {
63 glDeleteProgram(mProgram);
64
65 ANGLETest::TearDown();
66 }
67
68 void fillTextureData(std::vector<GLubyte> &buffer, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
69 {
70 size_t count = buffer.size() / 4;
71 for (size_t i = 0; i < count; i++)
72 {
73 buffer[i * 4 + 0] = r;
74 buffer[i * 4 + 1] = g;
75 buffer[i * 4 + 2] = b;
76 buffer[i * 4 + 3] = a;
77 }
78 }
79
80 GLuint mProgram;
81 GLint mTextureUniformLocation;
82};
83
Jamie Madillfa05f602015-05-07 13:47:11 -040084TEST_P(IncompleteTextureTest, IncompleteTexture2D)
Geoff Lang0ddab0c2013-10-23 13:24:41 -040085{
Jamie Madill81c2e252017-09-09 23:32:46 -040086 GLTexture tex;
Geoff Lang0ddab0c2013-10-23 13:24:41 -040087 glActiveTexture(GL_TEXTURE0);
88 glBindTexture(GL_TEXTURE_2D, tex);
89
90 glUseProgram(mProgram);
91 glUniform1i(mTextureUniformLocation, 0);
92
Jamie Madill81c2e252017-09-09 23:32:46 -040093 constexpr GLsizei kTextureSize = 2;
94 std::vector<GLColor> textureData(kTextureSize * kTextureSize, GLColor::red);
Geoff Lang0ddab0c2013-10-23 13:24:41 -040095
Jamie Madill81c2e252017-09-09 23:32:46 -040096 // Make a complete texture.
97 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureSize, kTextureSize, 0, GL_RGBA,
98 GL_UNSIGNED_BYTE, textureData.data());
Geoff Lang0ddab0c2013-10-23 13:24:41 -040099 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
100
Jamie Madill81c2e252017-09-09 23:32:46 -0400101 // Should be complete - expect red.
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400102 drawQuad(mProgram, "position", 0.5f);
Jamie Madill81c2e252017-09-09 23:32:46 -0400103 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400104
Jamie Madill81c2e252017-09-09 23:32:46 -0400105 // Make texture incomplete.
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
107
Jamie Madill81c2e252017-09-09 23:32:46 -0400108 // Should be incomplete - expect black.
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400109 drawQuad(mProgram, "position", 0.5f);
Jamie Madill81c2e252017-09-09 23:32:46 -0400110 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400111
Jamie Madill81c2e252017-09-09 23:32:46 -0400112 // Make texture complete by defining the second mip.
113 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTextureSize >> 1, kTextureSize >> 1, 0, GL_RGBA,
114 GL_UNSIGNED_BYTE, textureData.data());
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400115
Jamie Madill81c2e252017-09-09 23:32:46 -0400116 // Should be complete - expect red.
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400117 drawQuad(mProgram, "position", 0.5f);
Jamie Madill81c2e252017-09-09 23:32:46 -0400118 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400119}
120
Jamie Madillfa05f602015-05-07 13:47:11 -0400121TEST_P(IncompleteTextureTest, UpdateTexture)
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400122{
Jamie Madill81c2e252017-09-09 23:32:46 -0400123 GLTexture tex;
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400124 glActiveTexture(GL_TEXTURE0);
125 glBindTexture(GL_TEXTURE_2D, tex);
126
127 glUseProgram(mProgram);
128 glUniform1i(mTextureUniformLocation, 0);
129
130 const GLsizei redTextureWidth = 64;
131 const GLsizei redTextureHeight = 64;
132 std::vector<GLubyte> redTextureData(redTextureWidth * redTextureHeight * 4);
133 fillTextureData(redTextureData, 255, 0, 0, 255);
134 for (size_t i = 0; i < 7; i++)
135 {
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700136 glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(i), GL_RGBA, redTextureWidth >> i,
137 redTextureHeight >> i, 0, GL_RGBA, GL_UNSIGNED_BYTE, &redTextureData[0]);
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400138 }
139
140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
142
143 drawQuad(mProgram, "position", 0.5f);
144 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
145
146 const GLsizei greenTextureWidth = 32;
147 const GLsizei greenTextureHeight = 32;
148 std::vector<GLubyte> greenTextureData(greenTextureWidth * greenTextureHeight * 4);
149 fillTextureData(greenTextureData, 0, 255, 0, 255);
150
151 for (size_t i = 0; i < 6; i++)
152 {
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700153 glTexSubImage2D(GL_TEXTURE_2D, static_cast<GLint>(i), greenTextureWidth >> i,
154 greenTextureHeight >> i, greenTextureWidth >> i, greenTextureHeight >> i,
155 GL_RGBA, GL_UNSIGNED_BYTE, &greenTextureData[0]);
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400156 }
157
158 drawQuad(mProgram, "position", 0.5f);
159 EXPECT_PIXEL_EQ(getWindowWidth() - greenTextureWidth, getWindowHeight() - greenTextureWidth, 0, 255, 0, 255);
Geoff Lang0ddab0c2013-10-23 13:24:41 -0400160}
Jamie Madillfa05f602015-05-07 13:47:11 -0400161
162// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500163ANGLE_INSTANTIATE_TEST(IncompleteTextureTest,
164 ES2_D3D9(),
165 ES2_D3D11(),
166 ES2_OPENGL(),
167 ES2_OPENGLES());