gl_texture_storage_unittest.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // Copyright 2014 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 <stdint.h>
  7. #include "gpu/GLES2/gl2extchromium.h"
  8. #include "gpu/command_buffer/tests/gl_manager.h"
  9. #include "gpu/command_buffer/tests/gl_test_utils.h"
  10. #include "gpu/command_buffer/tests/texture_image_factory.h"
  11. #include "testing/gmock/include/gmock/gmock.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. namespace gpu {
  14. namespace {
  15. // Blits texture bound to active texture unit to currently bound framebuffer.
  16. // Viewport must be set by caller.
  17. void BlitTexture() {
  18. const GLuint kVertexPositionAttrib = 0;
  19. const GLfloat kQuadVertices[] = {-1.0f, -1.0f, 1.0f, -1.0f,
  20. 1.0f, 1.0f, -1.0f, 1.0f};
  21. GLuint buffer_id = 0;
  22. glGenBuffers(1, &buffer_id);
  23. glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
  24. glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices,
  25. GL_STATIC_DRAW);
  26. glEnableVertexAttribArray(kVertexPositionAttrib);
  27. glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
  28. GLuint shader_program = glCreateProgram();
  29. static const char* kBlitTextureVertexShader =
  30. "precision mediump float;\n"
  31. "attribute vec2 a_position;\n"
  32. "varying mediump vec2 v_uv;\n"
  33. "void main(void) {\n"
  34. " gl_Position = vec4(a_position, 0, 1);\n"
  35. " v_uv = 0.5 * (a_position + vec2(1, 1));\n"
  36. "}\n";
  37. GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
  38. glShaderSource(vertex_shader, 1, &kBlitTextureVertexShader, 0);
  39. glCompileShader(vertex_shader);
  40. glAttachShader(shader_program, vertex_shader);
  41. static const char* kBlitTextureFragmentShader =
  42. "uniform sampler2D u_sampler;\n"
  43. "varying mediump vec2 v_uv;\n"
  44. "void main(void) {\n"
  45. " gl_FragColor = texture2D(u_sampler, v_uv);\n"
  46. "}\n";
  47. GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
  48. glShaderSource(fragment_shader, 1, &kBlitTextureFragmentShader, 0);
  49. glCompileShader(fragment_shader);
  50. glAttachShader(shader_program, fragment_shader);
  51. glBindAttribLocation(shader_program, kVertexPositionAttrib, "a_position");
  52. glLinkProgram(shader_program);
  53. glUseProgram(shader_program);
  54. GLuint sampler_handle = glGetUniformLocation(shader_program, "u_sampler");
  55. glUniform1i(sampler_handle, 0);
  56. glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  57. ASSERT_TRUE(glGetError() == GL_NONE);
  58. }
  59. } // namespace
  60. class TextureStorageTest : public testing::Test {
  61. protected:
  62. static const GLsizei kResolution = 64;
  63. void SetUp() override {
  64. GLManager::Options options;
  65. image_factory_.SetRequiredTextureType(GL_TEXTURE_2D);
  66. options.size = gfx::Size(kResolution, kResolution);
  67. options.image_factory = &image_factory_;
  68. gl_.Initialize(options);
  69. gl_.MakeCurrent();
  70. glGenTextures(1, &tex_);
  71. glBindTexture(GL_TEXTURE_2D, tex_);
  72. glGenFramebuffers(1, &fbo_);
  73. glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
  74. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  75. tex_, 0);
  76. const GLubyte* extensions = glGetString(GL_EXTENSIONS);
  77. ext_texture_storage_available_ = strstr(
  78. reinterpret_cast<const char*>(extensions), "GL_EXT_texture_storage");
  79. }
  80. void TearDown() override { gl_.Destroy(); }
  81. TextureImageFactory image_factory_;
  82. GLManager gl_;
  83. GLuint tex_ = 0;
  84. GLuint fbo_ = 0;
  85. bool ext_texture_storage_available_ = false;
  86. };
  87. TEST_F(TextureStorageTest, CorrectPixels) {
  88. if (!ext_texture_storage_available_)
  89. return;
  90. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 2, 2);
  91. // Mesa drivers crash without rebinding to FBO. It's why
  92. // DISABLE_TEXTURE_STORAGE workaround is introduced. crbug.com/521904
  93. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  94. tex_, 0);
  95. uint8_t source_pixels[16] = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
  96. glTexSubImage2D(GL_TEXTURE_2D,
  97. 0,
  98. 0, 0,
  99. 2, 2,
  100. GL_RGBA, GL_UNSIGNED_BYTE,
  101. source_pixels);
  102. EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 2, 2, 0, source_pixels, nullptr));
  103. }
  104. TEST_F(TextureStorageTest, IsImmutable) {
  105. if (!ext_texture_storage_available_)
  106. return;
  107. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 4, 4);
  108. GLint param = 0;
  109. glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_FORMAT_EXT, &param);
  110. EXPECT_TRUE(param);
  111. }
  112. TEST_F(TextureStorageTest, OneLevel) {
  113. if (!ext_texture_storage_available_)
  114. return;
  115. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 4, 4);
  116. uint8_t source_pixels[64] = {0};
  117. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  118. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4,
  119. GL_RGBA, GL_UNSIGNED_BYTE, source_pixels);
  120. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  121. glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 2, 2,
  122. GL_RGBA, GL_UNSIGNED_BYTE, source_pixels);
  123. EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
  124. }
  125. TEST_F(TextureStorageTest, MultipleLevels) {
  126. if (!ext_texture_storage_available_)
  127. return;
  128. glTexStorage2DEXT(GL_TEXTURE_2D, 2, GL_RGBA8_OES, 2, 2);
  129. uint8_t source_pixels[16] = {0};
  130. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  131. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2,
  132. GL_RGBA, GL_UNSIGNED_BYTE, source_pixels);
  133. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  134. glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 1, 1,
  135. GL_RGBA, GL_UNSIGNED_BYTE, source_pixels);
  136. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  137. glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, 1, 1,
  138. GL_RGBA, GL_UNSIGNED_BYTE, source_pixels);
  139. EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
  140. }
  141. TEST_F(TextureStorageTest, BadTarget) {
  142. if (!ext_texture_storage_available_)
  143. return;
  144. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  145. glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8_OES, 4, 4);
  146. EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError());
  147. }
  148. TEST_F(TextureStorageTest, InvalidId) {
  149. if (!ext_texture_storage_available_)
  150. return;
  151. glDeleteTextures(1, &tex_);
  152. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  153. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 4, 4);
  154. EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
  155. }
  156. TEST_F(TextureStorageTest, CannotRedefine) {
  157. if (!ext_texture_storage_available_)
  158. return;
  159. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 4, 4);
  160. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  161. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 4, 4);
  162. EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
  163. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  164. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  165. nullptr);
  166. EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
  167. }
  168. TEST_F(TextureStorageTest, InternalFormatBleedingToTexImage) {
  169. if (!ext_texture_storage_available_)
  170. return;
  171. EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  172. // The context is ES2 context.
  173. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_OES, 4, 4, 0, GL_RGBA,
  174. GL_UNSIGNED_BYTE, nullptr);
  175. EXPECT_NE(static_cast<GLenum>(GL_NO_ERROR), glGetError());
  176. }
  177. TEST_F(TextureStorageTest, LuminanceEmulation) {
  178. if (!ext_texture_storage_available_)
  179. return;
  180. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 2, 2);
  181. // Mesa drivers crash without rebinding to FBO. It's why
  182. // DISABLE_TEXTURE_STORAGE workaround is introduced. crbug.com/521904
  183. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  184. tex_, 0);
  185. ASSERT_TRUE(glGetError() == GL_NONE);
  186. GLuint luminance_tex = 0;
  187. glGenTextures(1, &luminance_tex);
  188. glBindTexture(GL_TEXTURE_2D, luminance_tex);
  189. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  190. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  191. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  192. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  193. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_LUMINANCE8_EXT, 2, 2);
  194. ASSERT_TRUE(glGetError() == GL_NONE);
  195. const uint8_t source_data[4] = {1, 1, 1, 1};
  196. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  197. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
  198. source_data);
  199. ASSERT_TRUE(glGetError() == GL_NONE);
  200. BlitTexture();
  201. const uint8_t swizzled_pixel[4] = {1, 1, 1, 255};
  202. EXPECT_TRUE(
  203. GLTestHelper::CheckPixels(0, 0, 2, 2, 0, swizzled_pixel, nullptr));
  204. }
  205. TEST_F(TextureStorageTest, AlphaEmulation) {
  206. if (!ext_texture_storage_available_)
  207. return;
  208. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 2, 2);
  209. // Mesa drivers crash without rebinding to FBO. It's why
  210. // DISABLE_TEXTURE_STORAGE workaround is introduced. crbug.com/521904
  211. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  212. tex_, 0);
  213. ASSERT_TRUE(glGetError() == GL_NONE);
  214. GLuint alpha_tex = 0;
  215. glGenTextures(1, &alpha_tex);
  216. glBindTexture(GL_TEXTURE_2D, alpha_tex);
  217. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  218. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  219. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  220. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  221. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ALPHA8_EXT, 2, 2);
  222. ASSERT_TRUE(glGetError() == GL_NONE);
  223. const uint8_t source_data[4] = {1, 1, 1, 1};
  224. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  225. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_ALPHA, GL_UNSIGNED_BYTE,
  226. source_data);
  227. ASSERT_TRUE(glGetError() == GL_NONE);
  228. BlitTexture();
  229. const uint8_t swizzled_pixel[4] = {0, 0, 0, 1};
  230. EXPECT_TRUE(
  231. GLTestHelper::CheckPixels(0, 0, 2, 2, 0, swizzled_pixel, nullptr));
  232. }
  233. TEST_F(TextureStorageTest, LuminanceAlphaEmulation) {
  234. if (!ext_texture_storage_available_)
  235. return;
  236. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 2, 2);
  237. // Mesa drivers crash without rebinding to FBO. It's why
  238. // DISABLE_TEXTURE_STORAGE workaround is introduced. crbug.com/521904
  239. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  240. tex_, 0);
  241. ASSERT_TRUE(glGetError() == GL_NONE);
  242. GLuint luminance_alpha_tex = 0;
  243. glGenTextures(1, &luminance_alpha_tex);
  244. glBindTexture(GL_TEXTURE_2D, luminance_alpha_tex);
  245. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  246. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  247. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  248. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  249. glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_LUMINANCE8_ALPHA8_EXT, 2, 2);
  250. ASSERT_TRUE(glGetError() == GL_NONE);
  251. const uint8_t source_data[8] = {1, 2, 1, 2, 1, 2, 1, 2};
  252. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  253. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_LUMINANCE_ALPHA,
  254. GL_UNSIGNED_BYTE, source_data);
  255. ASSERT_TRUE(glGetError() == GL_NONE);
  256. BlitTexture();
  257. const uint8_t swizzled_pixel[4] = {1, 1, 1, 2};
  258. EXPECT_TRUE(
  259. GLTestHelper::CheckPixels(0, 0, 2, 2, 0, swizzled_pixel, nullptr));
  260. }
  261. } // namespace gpu