1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include <GLES2/gl2ext.h>
8 #include "gpu/command_buffer/tests/gl_manager.h"
9 #include "gpu/command_buffer/tests/gl_test_utils.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 #define SHADER(Src) #Src
17 class DepthTextureTest
: public testing::Test
{
19 static const GLsizei kResolution
= 64;
20 void SetUp() override
{
21 GLManager::Options options
;
22 options
.size
= gfx::Size(kResolution
, kResolution
);
23 gl_
.Initialize(options
);
26 void TearDown() override
{ gl_
.Destroy(); }
28 GLuint
SetupUnitQuad(GLint position_location
);
33 GLuint
DepthTextureTest::SetupUnitQuad(GLint position_location
) {
35 glGenBuffers(1, &vbo
);
36 glBindBuffer(GL_ARRAY_BUFFER
, vbo
);
37 static float vertices
[] = {
45 glBufferData(GL_ARRAY_BUFFER
, sizeof(vertices
), vertices
, GL_STATIC_DRAW
);
46 glEnableVertexAttribArray(position_location
);
47 glVertexAttribPointer(position_location
, 3, GL_FLOAT
, GL_FALSE
, 0, 0);
59 } // anonymous namespace
61 TEST_F(DepthTextureTest
, RenderTo
) {
62 if (!GLTestHelper::HasExtension("GL_CHROMIUM_depth_texture")) {
66 bool have_depth_stencil
= GLTestHelper::HasExtension(
67 "GL_OES_packed_depth_stencil");
69 static const char* v_shader_str
= SHADER(
70 attribute vec4 v_position
;
73 gl_Position
= v_position
;
76 static const char* f_shader_str
= SHADER(
77 precision mediump
float;
78 uniform sampler2D u_texture
;
79 uniform vec2 u_resolution
;
82 vec2 texcoord
= gl_FragCoord
.xy
/ u_resolution
;
83 gl_FragColor
= texture2D(u_texture
, texcoord
);
87 GLuint program
= GLTestHelper::LoadProgram(v_shader_str
, f_shader_str
);
89 GLint position_loc
= glGetAttribLocation(program
, "v_position");
90 GLint resolution_loc
= glGetUniformLocation(program
, "u_resolution");
92 SetupUnitQuad(position_loc
);
94 // Depth test needs to be on for the depth buffer to be updated.
95 glEnable(GL_DEPTH_TEST
);
99 glGenFramebuffers(1, &fbo
);
100 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
102 // create a depth texture.
103 GLuint color_texture
= 0;
104 GLuint depth_texture
= 0;
106 glGenTextures(1, &color_texture
);
107 glBindTexture(GL_TEXTURE_2D
, color_texture
);
109 GL_TEXTURE_2D
, 0, GL_RGBA
, kResolution
, kResolution
,
110 0, GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
111 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
112 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
113 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
114 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
115 glFramebufferTexture2D(
116 GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, color_texture
, 0);
118 glGenTextures(1, &depth_texture
);
119 glBindTexture(GL_TEXTURE_2D
, depth_texture
);
120 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
121 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
122 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
123 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
124 glFramebufferTexture2D(
125 GL_FRAMEBUFFER
, GL_DEPTH_ATTACHMENT
, GL_TEXTURE_2D
, depth_texture
, 0);
127 glUseProgram(program
);
128 glUniform2f(resolution_loc
, kResolution
, kResolution
);
130 static const FormatType format_types
[] = {
131 { GL_DEPTH_COMPONENT
, GL_UNSIGNED_SHORT
},
132 { GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
},
133 { GL_DEPTH_STENCIL_OES
, GL_UNSIGNED_INT_24_8_OES
},
135 for (size_t ii
= 0; ii
< arraysize(format_types
); ++ii
) {
136 const FormatType
& format_type
= format_types
[ii
];
137 GLenum format
= format_type
.format
;
138 GLenum type
= format_type
.type
;
140 if (format
== GL_DEPTH_STENCIL_OES
&& !have_depth_stencil
) {
144 glBindTexture(GL_TEXTURE_2D
, depth_texture
);
146 GL_TEXTURE_2D
, 0, format
, kResolution
, kResolution
,
147 0, format
, type
, NULL
);
149 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
150 GLenum status
= glCheckFramebufferStatus(GL_FRAMEBUFFER
);
151 EXPECT_EQ(static_cast<GLenum
>(GL_FRAMEBUFFER_COMPLETE
), status
)
152 << "iteration: " << ii
;
153 if (status
!= GL_FRAMEBUFFER_COMPLETE
) {
157 if (!GLTestHelper::CheckGLError("no errors after setup", __LINE__
)) {
161 glClearColor(1.0f
, 1.0f
, 1.0f
, 1.0f
);
162 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
164 // Disconnect the texture so we'll render with the default texture.
165 glBindTexture(GL_TEXTURE_2D
, 0);
167 // Render to the fbo.
168 glDrawArrays(GL_TRIANGLES
, 0, 6);
170 if (!GLTestHelper::CheckGLError("no errors after depth draw", __LINE__
)) {
174 // Render with the depth texture.
175 glBindFramebuffer(GL_FRAMEBUFFER
, 0);
176 glBindTexture(GL_TEXTURE_2D
, depth_texture
);
177 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
178 glDrawArrays(GL_TRIANGLES
, 0, 6);
180 if (!GLTestHelper::CheckGLError("no errors after texture draw", __LINE__
)) {
184 uint8 actual_pixels
[kResolution
* kResolution
* 4] = { 0, };
186 0, 0, kResolution
, kResolution
, GL_RGBA
, GL_UNSIGNED_BYTE
,
189 if (!GLTestHelper::CheckGLError("no errors after readpixels", __LINE__
)) {
193 // Check that each pixel's red value is less than the previous pixel in
194 // either direction. Basically verify we have a gradient. No assumption is
195 // made about the other channels green, blue and alpha since, according to
196 // the GL_CHROMIUM_depth_texture spec, they have undefined values for
198 int bad_count
= 0; // used to not spam the log with too many messages.
199 for (GLint yy
= 0; bad_count
< 16 && yy
< kResolution
; ++yy
) {
200 for (GLint xx
= 0; bad_count
< 16 && xx
< kResolution
; ++xx
) {
201 const uint8
* actual
= &actual_pixels
[(yy
* kResolution
+ xx
) * 4];
202 const uint8
* left
= actual
- 4;
203 const uint8
* down
= actual
- kResolution
* 4;
205 // NOTE: Qualcomm on Nexus 4 the right most column has the same
206 // values as the next to right most column. (bad interpolator?)
207 if (xx
> 0 && xx
< kResolution
- 1) {
208 EXPECT_GT(actual
[0], left
[0])
209 << "pixel at " << xx
<< ", " << yy
210 << " actual[0] =" << static_cast<unsigned>(actual
[0])
211 << " left[0] =" << static_cast<unsigned>(left
[0])
212 << " actual =" << reinterpret_cast<const void*>(actual
)
213 << " left =" << reinterpret_cast<const void*>(left
);
214 bad_count
+= (actual
[0] > left
[0] ? 0 : 1);
217 if (yy
> 0 && yy
< kResolution
- 1) {
218 EXPECT_GT(actual
[0], down
[0]) << "pixel at " << xx
<< ", " << yy
;
219 bad_count
+= (actual
[0] > down
[0] ? 0 : 1);
224 // Check that bottom left corner is vastly different thatn top right.
226 actual_pixels
[(kResolution
* kResolution
- 1) * 4] - actual_pixels
[0],
229 GLTestHelper::CheckGLError("no errors after everything", __LINE__
);