gl_depth_texture_unittest.cc 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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.
  4. #include <GLES2/gl2.h>
  5. #include <GLES2/gl2ext.h>
  6. #include <stddef.h>
  7. #include <stdint.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"
  12. #define SHADER(Src) #Src
  13. namespace gpu {
  14. class DepthTextureTest : public testing::Test {
  15. protected:
  16. static const GLsizei kResolution = 64;
  17. void SetUp() override {
  18. GLManager::Options options;
  19. options.size = gfx::Size(kResolution, kResolution);
  20. gl_.Initialize(options);
  21. }
  22. void TearDown() override { gl_.Destroy(); }
  23. GLuint SetupUnitQuad(GLint position_location);
  24. GLManager gl_;
  25. };
  26. GLuint DepthTextureTest::SetupUnitQuad(GLint position_location) {
  27. GLuint vbo = 0;
  28. glGenBuffers(1, &vbo);
  29. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  30. static float vertices[] = {
  31. 1.0f, 1.0f, 1.0f,
  32. -1.0f, 1.0f, 0.0f,
  33. -1.0f, -1.0f, -1.0f,
  34. 1.0f, 1.0f, 1.0f,
  35. -1.0f, -1.0f, -1.0f,
  36. 1.0f, -1.0f, 0.0f,
  37. };
  38. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  39. glEnableVertexAttribArray(position_location);
  40. glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
  41. return vbo;
  42. }
  43. namespace {
  44. struct FormatType {
  45. GLenum format;
  46. GLenum type;
  47. };
  48. } // anonymous namespace
  49. TEST_F(DepthTextureTest, RenderTo) {
  50. if (!GLTestHelper::HasExtension("GL_CHROMIUM_depth_texture")) {
  51. return;
  52. }
  53. bool have_depth_stencil = GLTestHelper::HasExtension(
  54. "GL_OES_packed_depth_stencil");
  55. static const char* v_shader_str = SHADER(
  56. attribute vec4 v_position;
  57. void main()
  58. {
  59. gl_Position = v_position;
  60. }
  61. );
  62. static const char* f_shader_str = SHADER(
  63. precision mediump float;
  64. uniform sampler2D u_texture;
  65. uniform vec2 u_resolution;
  66. void main()
  67. {
  68. vec2 texcoord = gl_FragCoord.xy / u_resolution;
  69. gl_FragColor = texture2D(u_texture, texcoord);
  70. }
  71. );
  72. GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
  73. GLint position_loc = glGetAttribLocation(program, "v_position");
  74. GLint resolution_loc = glGetUniformLocation(program, "u_resolution");
  75. SetupUnitQuad(position_loc);
  76. // Depth test needs to be on for the depth buffer to be updated.
  77. glEnable(GL_DEPTH_TEST);
  78. // create an fbo
  79. GLuint fbo = 0;
  80. glGenFramebuffers(1, &fbo);
  81. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  82. // create a depth texture.
  83. GLuint color_texture = 0;
  84. GLuint depth_texture = 0;
  85. glGenTextures(1, &color_texture);
  86. glBindTexture(GL_TEXTURE_2D, color_texture);
  87. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolution, kResolution, 0, GL_RGBA,
  88. GL_UNSIGNED_BYTE, nullptr);
  89. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  90. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  91. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  92. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  93. glFramebufferTexture2D(
  94. GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0);
  95. glGenTextures(1, &depth_texture);
  96. glBindTexture(GL_TEXTURE_2D, depth_texture);
  97. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  98. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  99. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  100. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  101. glFramebufferTexture2D(
  102. GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
  103. glUseProgram(program);
  104. glUniform2f(resolution_loc, kResolution, kResolution);
  105. static const FormatType format_types[] = {
  106. { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT },
  107. { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT },
  108. { GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES },
  109. };
  110. for (size_t ii = 0; ii < std::size(format_types); ++ii) {
  111. const FormatType& format_type = format_types[ii];
  112. GLenum format = format_type.format;
  113. GLenum type = format_type.type;
  114. if (format == GL_DEPTH_STENCIL_OES && !have_depth_stencil) {
  115. continue;
  116. }
  117. glBindTexture(GL_TEXTURE_2D, depth_texture);
  118. glTexImage2D(GL_TEXTURE_2D, 0, format, kResolution, kResolution, 0, format,
  119. type, nullptr);
  120. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  121. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  122. EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), status)
  123. << "iteration: " << ii;
  124. if (status != GL_FRAMEBUFFER_COMPLETE) {
  125. continue;
  126. }
  127. if (!GLTestHelper::CheckGLError("no errors after setup", __LINE__)) {
  128. continue;
  129. }
  130. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  131. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  132. // Disconnect the texture so we'll render with the default texture.
  133. glBindTexture(GL_TEXTURE_2D, 0);
  134. // Render to the fbo.
  135. glDrawArrays(GL_TRIANGLES, 0, 6);
  136. if (!GLTestHelper::CheckGLError("no errors after depth draw", __LINE__)) {
  137. continue;
  138. }
  139. // Render with the depth texture.
  140. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  141. glBindTexture(GL_TEXTURE_2D, depth_texture);
  142. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  143. glDrawArrays(GL_TRIANGLES, 0, 6);
  144. if (!GLTestHelper::CheckGLError("no errors after texture draw", __LINE__)) {
  145. continue;
  146. }
  147. uint8_t actual_pixels[kResolution * kResolution * 4] = {
  148. 0,
  149. };
  150. glReadPixels(
  151. 0, 0, kResolution, kResolution, GL_RGBA, GL_UNSIGNED_BYTE,
  152. actual_pixels);
  153. if (!GLTestHelper::CheckGLError("no errors after readpixels", __LINE__)) {
  154. continue;
  155. }
  156. // Check that each pixel's red value is less than the previous pixel in
  157. // either direction. Basically verify we have a gradient. No assumption is
  158. // made about the other channels green, blue and alpha since, according to
  159. // the GL_CHROMIUM_depth_texture spec, they have undefined values for
  160. // depth textures.
  161. int bad_count = 0; // used to not spam the log with too many messages.
  162. for (GLint yy = 0; bad_count < 16 && yy < kResolution; ++yy) {
  163. for (GLint xx = 0; bad_count < 16 && xx < kResolution; ++xx) {
  164. const uint8_t* actual = &actual_pixels[(yy * kResolution + xx) * 4];
  165. const uint8_t* left = actual - 4;
  166. const uint8_t* down = actual - kResolution * 4;
  167. // NOTE: Qualcomm on Nexus 4 the right most column has the same
  168. // values as the next to right most column. (bad interpolator?)
  169. if (xx > 0 && xx < kResolution - 1) {
  170. EXPECT_GT(actual[0], left[0])
  171. << "pixel at " << xx << ", " << yy
  172. << " actual[0] =" << static_cast<unsigned>(actual[0])
  173. << " left[0] =" << static_cast<unsigned>(left[0])
  174. << " actual =" << reinterpret_cast<const void*>(actual)
  175. << " left =" << reinterpret_cast<const void*>(left);
  176. bad_count += (actual[0] > left[0] ? 0 : 1);
  177. }
  178. if (yy > 0 && yy < kResolution - 1) {
  179. EXPECT_GT(actual[0], down[0]) << "pixel at " << xx << ", " << yy;
  180. bad_count += (actual[0] > down[0] ? 0 : 1);
  181. }
  182. }
  183. }
  184. // Check that bottom left corner is vastly different thatn top right.
  185. EXPECT_GT(
  186. actual_pixels[(kResolution * kResolution - 1) * 4] - actual_pixels[0],
  187. 0xC0);
  188. GLTestHelper::CheckGLError("no errors after everything", __LINE__);
  189. }
  190. }
  191. } // namespace gpu