blob: d46c736029e1c61cbf004d1813df74bb5b0cd86f [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 Lang95663912015-04-02 15:54:45 -04008
Jamie Madillfa05f602015-05-07 13:47:11 -04009using namespace angle;
Geoff Lang95663912015-04-02 15:54:45 -040010
Geoff Lang95663912015-04-02 15:54:45 -040011class FramebufferRenderMipmapTest : public ANGLETest
12{
Jamie Madillfa05f602015-05-07 13:47:11 -040013 protected:
14 FramebufferRenderMipmapTest()
Geoff Lang95663912015-04-02 15:54:45 -040015 {
16 setWindowWidth(256);
17 setWindowHeight(256);
18 setConfigRedBits(8);
19 setConfigGreenBits(8);
20 setConfigBlueBits(8);
21 setConfigAlphaBits(8);
22 }
23
24 virtual void SetUp()
25 {
26 ANGLETest::SetUp();
27
Olli Etuahoa20af6d2017-09-18 13:32:29 +030028 const std::string vsSource =
29 R"(attribute highp vec4 position;
Geoff Lang95663912015-04-02 15:54:45 -040030 void main(void)
31 {
32 gl_Position = position;
Olli Etuahoa20af6d2017-09-18 13:32:29 +030033 })";
Geoff Lang95663912015-04-02 15:54:45 -040034
Olli Etuahoa20af6d2017-09-18 13:32:29 +030035 const std::string fsSource =
36 R"(uniform highp vec4 color;
Geoff Lang95663912015-04-02 15:54:45 -040037 void main(void)
38 {
39 gl_FragColor = color;
Olli Etuahoa20af6d2017-09-18 13:32:29 +030040 })";
Geoff Lang95663912015-04-02 15:54:45 -040041
42 mProgram = CompileProgram(vsSource, fsSource);
43 if (mProgram == 0)
44 {
45 FAIL() << "shader compilation failed.";
46 }
47
48 mColorLocation = glGetUniformLocation(mProgram, "color");
49
50 glUseProgram(mProgram);
51
52 glClearColor(0, 0, 0, 0);
53 glClearDepthf(0.0);
54 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
55
56 glEnable(GL_BLEND);
57 glDisable(GL_DEPTH_TEST);
58
59 ASSERT_GL_NO_ERROR();
60 }
61
62 virtual void TearDown()
63 {
64 glDeleteProgram(mProgram);
65
66 ANGLETest::TearDown();
67 }
68
69 GLuint mProgram;
70 GLint mColorLocation;
71};
72
73// Validate that if we are in ES3 or GL_OES_fbo_render_mipmap exists, there are no validation errors
74// when using a non-zero level in glFramebufferTexture2D.
Jamie Madillfa05f602015-05-07 13:47:11 -040075TEST_P(FramebufferRenderMipmapTest, Validation)
Geoff Lang95663912015-04-02 15:54:45 -040076{
Martin Radev1be913c2016-07-11 17:59:16 +030077 bool renderToMipmapSupported =
78 extensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2;
Geoff Lang95663912015-04-02 15:54:45 -040079
80 GLuint tex = 0;
81 glGenTextures(1, &tex);
82 glBindTexture(GL_TEXTURE_2D, tex);
83
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -070084 const GLint levels = 5;
85 for (GLint i = 0; i < levels; i++)
Geoff Lang95663912015-04-02 15:54:45 -040086 {
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -070087 GLsizei size = 1 << ((levels - 1) - i);
Yunchao Hef81ce4a2017-04-24 10:49:17 +080088 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
Geoff Lang95663912015-04-02 15:54:45 -040089 }
90
91 EXPECT_GL_NO_ERROR();
92
93 GLuint fbo = 0;
94 glGenFramebuffers(1, &fbo);
95 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
96 EXPECT_GL_NO_ERROR();
97
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -070098 for (GLint i = 0; i < levels; i++)
Geoff Lang95663912015-04-02 15:54:45 -040099 {
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -0700100 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
Geoff Lang95663912015-04-02 15:54:45 -0400101
102 if (i > 0 && !renderToMipmapSupported)
103 {
104 EXPECT_GL_ERROR(GL_INVALID_VALUE);
105 }
106 else
107 {
108 EXPECT_GL_NO_ERROR();
109 EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GLenum(GL_FRAMEBUFFER_COMPLETE));
110 }
111 }
112
113 glDeleteFramebuffers(1, &fbo);
114 glDeleteTextures(1, &tex);
115}
116
117// Render to various levels of a texture and check that they have the correct color data via ReadPixels
Jamie Madillfa05f602015-05-07 13:47:11 -0400118TEST_P(FramebufferRenderMipmapTest, RenderToMipmap)
Geoff Lang95663912015-04-02 15:54:45 -0400119{
Geoff Lang1a0847c2015-04-08 13:49:31 -0400120 // TODO(geofflang): Figure out why this is broken on Intel OpenGL
Jamie Madill518b9fa2016-03-02 11:26:02 -0500121 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang1a0847c2015-04-08 13:49:31 -0400122 {
123 std::cout << "Test skipped on Intel OpenGL." << std::endl;
124 return;
125 }
126
Martin Radev1be913c2016-07-11 17:59:16 +0300127 bool renderToMipmapSupported =
128 extensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2;
Geoff Lang95663912015-04-02 15:54:45 -0400129 if (!renderToMipmapSupported)
130 {
131 std::cout << "Test skipped because GL_OES_fbo_render_mipmap or ES3 is not available." << std::endl;
132 return;
133 }
134
135 const GLfloat levelColors[] =
136 {
137 1.0f, 0.0f, 0.0f, 1.0f,
138 0.0f, 1.0f, 0.0f, 1.0f,
139 0.0f, 0.0f, 1.0f, 1.0f,
140 1.0f, 1.0f, 0.0f, 1.0f,
141 1.0f, 0.0f, 1.0f, 1.0f,
142 0.0f, 1.0f, 1.0f, 1.0f,
143 };
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -0700144 const GLint testLevels = static_cast<GLint>(ArraySize(levelColors) / 4);
Geoff Lang95663912015-04-02 15:54:45 -0400145
146 GLuint tex = 0;
147 glGenTextures(1, &tex);
148 glBindTexture(GL_TEXTURE_2D, tex);
149
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -0700150 for (GLint i = 0; i < testLevels; i++)
Geoff Lang95663912015-04-02 15:54:45 -0400151 {
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -0700152 GLsizei size = 1 << ((testLevels - 1) - i);
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800153 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
Geoff Lang95663912015-04-02 15:54:45 -0400154 }
155
156 EXPECT_GL_NO_ERROR();
157
158 GLuint fbo = 0;
159 glGenFramebuffers(1, &fbo);
160 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
161 EXPECT_GL_NO_ERROR();
162
163 // Render to the levels of the texture with different colors
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -0700164 for (GLint i = 0; i < testLevels; i++)
Geoff Lang95663912015-04-02 15:54:45 -0400165 {
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -0700166 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
Geoff Lang95663912015-04-02 15:54:45 -0400167 EXPECT_GL_NO_ERROR();
168
169 glUseProgram(mProgram);
170 glUniform4fv(mColorLocation, 1, levelColors + (i * 4));
171
172 drawQuad(mProgram, "position", 0.5f);
173 EXPECT_GL_NO_ERROR();
174 }
175
176 // Test that the levels of the texture are correct
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -0700177 for (GLint i = 0; i < testLevels; i++)
Geoff Lang95663912015-04-02 15:54:45 -0400178 {
Bruce Dawsone2fcf5c2016-03-30 11:27:12 -0700179 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
Geoff Lang95663912015-04-02 15:54:45 -0400180 EXPECT_GL_NO_ERROR();
181
182 const GLfloat *color = levelColors + (i * 4);
183 EXPECT_PIXEL_EQ(0, 0, color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255);
184 }
185
186 glDeleteFramebuffers(1, &fbo);
187 glDeleteTextures(1, &tex);
188
189 EXPECT_GL_NO_ERROR();
190}
Jamie Madillfa05f602015-05-07 13:47:11 -0400191
192// 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 -0500193ANGLE_INSTANTIATE_TEST(FramebufferRenderMipmapTest,
194 ES2_D3D9(),
195 ES2_D3D11(),
196 ES3_D3D11(),
197 ES2_OPENGL(),
198 ES3_OPENGL(),
199 ES2_OPENGLES(),
200 ES3_OPENGLES());