blob: 7c0bc9108cdf7c030efc457bf44456fecdf0a554 [file] [log] [blame]
Avi Drissman05dfbc822022-09-13 21:25:341// Copyright 2016 The Chromium Authors
junov0cad1f42016-01-07 21:48:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Arthur Sonzogni720f1c952024-07-25 16:17:515#ifdef UNSAFE_BUFFERS_BUILD
6// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
7#pragma allow_unsafe_buffers
8#endif
9
junov0cad1f42016-01-07 21:48:5110#include "gpu/command_buffer/service/gl_utils.h"
11
Jonathan Backer4cb165c82018-07-03 20:25:3312#include <algorithm>
brettw1ce49f62017-04-27 19:42:3213#include <unordered_set>
14
Xiaohan Wangfa22d3e2022-01-15 02:02:4315#include "build/build_config.h"
geofflang124fd552016-09-08 20:02:5516#include "gpu/command_buffer/common/capabilities.h"
Jonathan Backerc26060e2018-03-29 15:06:2917#include "gpu/command_buffer/service/error_state.h"
geofflang124fd552016-09-08 20:02:5518#include "gpu/command_buffer/service/feature_info.h"
Jonathan Backer8629c392018-04-04 23:01:0319#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
James Darpinian0f56e9f32018-01-11 02:23:5520#include "gpu/command_buffer/service/logger.h"
Jonathan Backer8629c392018-04-04 23:01:0321#include "gpu/command_buffer/service/texture_manager.h"
geofflang124fd552016-09-08 20:02:5522#include "ui/gl/gl_version_info.h"
junov0cad1f42016-01-07 21:48:5123
Robert Mader16be7de2023-03-14 15:46:1824#if BUILDFLAG(IS_CHROMEOS_ASH)
Chia-I Wu4cff4be62023-12-08 03:21:2725#include <sys/stat.h>
Robert Mader36c50132022-10-21 15:38:5726#include "ui/gl/gl_surface_egl.h"
27#endif
28
junov0cad1f42016-01-07 21:48:5129namespace gpu {
30namespace gles2 {
31
geofflang326c8512016-11-03 15:11:2832namespace {
Jonathan Backerc26060e2018-03-29 15:06:2933
34const int kASTCBlockSize = 16;
35const int kS3TCBlockWidth = 4;
36const int kS3TCBlockHeight = 4;
37const int kS3TCDXT1BlockSize = 8;
38const int kS3TCDXT3AndDXT5BlockSize = 16;
39const int kEACAndETC2BlockSize = 4;
shrekshaode2f6f32020-02-07 02:39:4440const int kBPTCBlockWidth = 4;
41const int kBPTCBlockHeight = 4;
shrekshao3c058332020-02-11 00:00:1242const int kRGTCBlockWidth = 4;
43const int kRGTCBlockHeight = 4;
Jonathan Backerc26060e2018-03-29 15:06:2944
45typedef struct {
46 int blockWidth;
47 int blockHeight;
48} ASTCBlockArray;
49
50const ASTCBlockArray kASTCBlockArray[] = {
51 {4, 4}, /* GL_COMPRESSED_RGBA_ASTC_4x4_KHR */
52 {5, 4}, /* and GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR */
53 {5, 5}, {6, 5}, {6, 6}, {8, 5}, {8, 6}, {8, 8},
54 {10, 5}, {10, 6}, {10, 8}, {10, 10}, {12, 10}, {12, 12}};
55
Daniel Bratell60acbb592018-07-26 09:13:1456bool IsValidPVRTCSize(GLint level, GLsizei size) {
57 return GLES2Util::IsPOT(size);
58}
59
Geoff Lang1cabc702019-04-26 01:30:1860bool IsValidS3TCSizeForWebGLAndANGLE(GLint level, GLsizei size) {
Geoff Langf067e4c2020-09-18 17:51:5761 // WebGL and ANGLE only allow multiple-of-4 sizes for the base level. See
62 // WEBGL_compressed_texture_s3tc and ANGLE_compressed_texture_dxt*
63 return (level > 0) || (size % kS3TCBlockWidth == 0);
Daniel Bratell60acbb592018-07-26 09:13:1464}
65
geofflang326c8512016-11-03 15:11:2866const char* GetDebugSourceString(GLenum source) {
67 switch (source) {
68 case GL_DEBUG_SOURCE_API:
69 return "OpenGL";
70 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
71 return "Window System";
72 case GL_DEBUG_SOURCE_SHADER_COMPILER:
73 return "Shader Compiler";
74 case GL_DEBUG_SOURCE_THIRD_PARTY:
75 return "Third Party";
76 case GL_DEBUG_SOURCE_APPLICATION:
77 return "Application";
78 case GL_DEBUG_SOURCE_OTHER:
79 return "Other";
80 default:
81 return "UNKNOWN";
82 }
83}
84
85const char* GetDebugTypeString(GLenum type) {
86 switch (type) {
87 case GL_DEBUG_TYPE_ERROR:
88 return "Error";
89 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
90 return "Deprecated behavior";
91 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
92 return "Undefined behavior";
93 case GL_DEBUG_TYPE_PORTABILITY:
94 return "Portability";
95 case GL_DEBUG_TYPE_PERFORMANCE:
96 return "Performance";
97 case GL_DEBUG_TYPE_OTHER:
98 return "Other";
99 case GL_DEBUG_TYPE_MARKER:
100 return "Marker";
101 default:
102 return "UNKNOWN";
103 }
104}
105
106const char* GetDebugSeverityString(GLenum severity) {
107 switch (severity) {
108 case GL_DEBUG_SEVERITY_HIGH:
109 return "High";
110 case GL_DEBUG_SEVERITY_MEDIUM:
111 return "Medium";
112 case GL_DEBUG_SEVERITY_LOW:
113 return "Low";
114 case GL_DEBUG_SEVERITY_NOTIFICATION:
115 return "Notification";
116 default:
117 return "UNKNOWN";
118 }
119}
James Darpinian0f56e9f32018-01-11 02:23:55120} // namespace
geofflang326c8512016-11-03 15:11:28121
geofflang124fd552016-09-08 20:02:55122bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
123 GLint rangeMax,
124 GLint precision) {
125 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
126}
127
Zhenyao Mo12d741f2024-07-09 19:12:38128void QueryShaderPrecisionFormat(GLenum shader_type,
geofflang124fd552016-09-08 20:02:55129 GLenum precision_type,
130 GLint* range,
131 GLint* precision) {
132 switch (precision_type) {
133 case GL_LOW_INT:
134 case GL_MEDIUM_INT:
135 case GL_HIGH_INT:
136 // These values are for a 32-bit twos-complement integer format.
137 range[0] = 31;
138 range[1] = 30;
139 *precision = 0;
140 break;
141 case GL_LOW_FLOAT:
142 case GL_MEDIUM_FLOAT:
143 case GL_HIGH_FLOAT:
144 // These values are for an IEEE single-precision floating-point format.
145 range[0] = 127;
146 range[1] = 127;
147 *precision = 23;
148 break;
149 default:
Peter BostrΓΆma11556e2024-10-31 04:49:10150 NOTREACHED();
geofflang124fd552016-09-08 20:02:55151 }
152
Zhenyao Mo12d741f2024-07-09 19:12:38153 // This function is sometimes defined even though it's really just
154 // a stub, so we need to set range and precision as if it weren't
155 // defined before calling it.
156 // On Mac OS with some GPUs, calling this generates a
157 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
158 // platforms.
159 glGetShaderPrecisionFormat(shader_type, precision_type, range, precision);
geofflang124fd552016-09-08 20:02:55160
Zhenyao Mo12d741f2024-07-09 19:12:38161 // TODO(brianderson): Make the following official workarounds.
geofflang124fd552016-09-08 20:02:55162
Zhenyao Mo12d741f2024-07-09 19:12:38163 // Some drivers have bugs where they report the ranges as a negative number.
164 // Taking the absolute value here shouldn't hurt because negative numbers
165 // aren't expected anyway.
166 range[0] = abs(range[0]);
167 range[1] = abs(range[1]);
geofflang124fd552016-09-08 20:02:55168
Zhenyao Mo12d741f2024-07-09 19:12:38169 // If the driver reports a precision for highp float that isn't actually
170 // highp, don't pretend like it's supported because shader compilation will
171 // fail anyway.
172 if (precision_type == GL_HIGH_FLOAT &&
173 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
174 range[0] = 0;
175 range[1] = 0;
176 *precision = 0;
geofflang124fd552016-09-08 20:02:55177 }
178}
179
180void PopulateNumericCapabilities(Capabilities* caps,
181 const FeatureInfo* feature_info) {
182 DCHECK(caps != nullptr);
Saifuddin Hitawalaa589c352023-10-05 21:42:22183 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps->max_texture_size);
Saifuddin Hitawalaa589c352023-10-05 21:42:22184}
185
186void PopulateGLCapabilities(GLCapabilities* caps,
187 const FeatureInfo* feature_info) {
188 CHECK(caps);
Saifuddin Hitawalad3ec84c32023-10-11 13:52:52189
Zhenyao Mo12d741f2024-07-09 19:12:38190 caps->VisitPrecisions([](GLenum shader, GLenum type,
191 GLCapabilities::ShaderPrecision* shader_precision) {
Saifuddin Hitawalad3ec84c32023-10-11 13:52:52192 GLint range[2] = {0, 0};
193 GLint precision = 0;
Zhenyao Mo12d741f2024-07-09 19:12:38194 QueryShaderPrecisionFormat(shader, type, range, &precision);
Saifuddin Hitawalad3ec84c32023-10-11 13:52:52195 shader_precision->min_range = range[0];
196 shader_precision->max_range = range[1];
197 shader_precision->precision = precision;
198 });
199
Saifuddin Hitawala8deded82024-08-14 21:26:30200 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps->max_texture_size);
201
Saifuddin Hitawalaa589c352023-10-05 21:42:22202 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
203 &caps->max_combined_texture_image_units);
Saifuddin Hitawala9f187482023-10-11 22:43:09204 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps->max_cube_map_texture_size);
geofflang124fd552016-09-08 20:02:55205 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
206 &caps->max_fragment_uniform_vectors);
207 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps->max_renderbuffer_size);
208 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps->max_texture_image_units);
geofflang124fd552016-09-08 20:02:55209 glGetIntegerv(GL_MAX_VARYING_VECTORS, &caps->max_varying_vectors);
210 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps->max_vertex_attribs);
211 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
212 &caps->max_vertex_texture_image_units);
213 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
214 &caps->max_vertex_uniform_vectors);
zmoc95386fb2016-12-09 23:48:55215 {
216 GLint dims[2] = {0, 0};
217 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
218 caps->max_viewport_width = dims[0];
219 caps->max_viewport_height = dims[1];
220 }
geofflang124fd552016-09-08 20:02:55221 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
222 &caps->num_compressed_texture_formats);
223 glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps->num_shader_binary_formats);
Saifuddin Hitawalaa589c352023-10-05 21:42:22224 glGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
225 &caps->bind_generates_resource_chromium);
Jiajia Qin252a8132018-07-19 01:03:22226 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
geofflang124fd552016-09-08 20:02:55227 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps->max_3d_texture_size);
228 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps->max_array_texture_layers);
229 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps->max_color_attachments);
230 glGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
231 &caps->max_combined_fragment_uniform_components);
232 glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
233 &caps->max_combined_uniform_blocks);
234 glGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
235 &caps->max_combined_vertex_uniform_components);
236 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps->max_draw_buffers);
237 glGetInteger64v(GL_MAX_ELEMENT_INDEX, &caps->max_element_index);
238 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps->max_elements_indices);
239 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps->max_elements_vertices);
240 glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
241 &caps->max_fragment_input_components);
242 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
243 &caps->max_fragment_uniform_blocks);
244 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
245 &caps->max_fragment_uniform_components);
246 glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->max_program_texel_offset);
247 glGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &caps->max_server_wait_timeout);
248 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->max_texture_lod_bias);
249 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
250 &caps->max_transform_feedback_interleaved_components);
251 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
252 &caps->max_transform_feedback_separate_attribs);
253 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
254 &caps->max_transform_feedback_separate_components);
255 glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &caps->max_uniform_block_size);
256 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
257 &caps->max_uniform_buffer_bindings);
258 glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps->max_varying_components);
259 glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
260 &caps->max_vertex_output_components);
261 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS,
262 &caps->max_vertex_uniform_blocks);
263 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
264 &caps->max_vertex_uniform_components);
265 glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->min_program_texel_offset);
geofflang124fd552016-09-08 20:02:55266 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
267 &caps->num_program_binary_formats);
268 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
269 &caps->uniform_buffer_offset_alignment);
Geoff Langd0c755c2021-01-18 21:58:16270 if (feature_info->IsES31ForTestingContext()) {
Jiajia Qinbf31bed2018-08-23 03:54:50271 glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,
272 &caps->max_atomic_counter_buffer_bindings);
273 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
274 &caps->max_shader_storage_buffer_bindings);
275 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT,
276 &caps->shader_storage_buffer_offset_alignment);
Jiajia Qin252a8132018-07-19 01:03:22277 }
geofflang124fd552016-09-08 20:02:55278 }
Saifuddin Hitawala9f187482023-10-11 22:43:09279 if (feature_info->feature_flags().multisampled_render_to_texture ||
280 feature_info->feature_flags().chromium_framebuffer_multisample ||
281 feature_info->IsWebGL2OrES3OrHigherContext()) {
282 glGetIntegerv(GL_MAX_SAMPLES, &caps->max_samples);
283 }
Saifuddin Hitawala4908ef62024-08-13 22:02:30284
285 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
286 caps->major_version = 3;
287 if (feature_info->IsES31ForTestingContext()) {
288 caps->minor_version = 1;
289 } else {
290 caps->minor_version = 0;
291 }
292 }
Saifuddin Hitawalab2da4f02023-10-04 15:36:46293}
294
Robert Mader16be7de2023-03-14 15:46:18295#if BUILDFLAG(IS_CHROMEOS_ASH)
Robert Mader36c50132022-10-21 15:38:57296void PopulateDRMCapabilities(Capabilities* caps,
297 const FeatureInfo* feature_info) {
298 DCHECK(caps != nullptr);
299
300 if (!gl::GLSurfaceEGL::GetGLDisplayEGL() ||
301 !gl::GLSurfaceEGL::GetGLDisplayEGL()->IsInitialized() ||
302 !gl::GLSurfaceEGL::GetGLDisplayEGL()
303 ->ext->b_EGL_EXT_image_dma_buf_import_modifiers ||
304 feature_info->workarounds()
305 .disable_egl_ext_image_dma_buf_import_modifiers ||
306 !gl::g_driver_egl.client_ext.b_EGL_EXT_device_query) {
307 return;
308 }
309
310 EGLDisplay egl_display = gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay();
311 DCHECK(egl_display != nullptr);
312
313 EGLDeviceEXT egl_device;
314 if (!eglQueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT,
315 (EGLAttrib*)&egl_device)) {
316 return;
317 }
318
319 gfx::ExtensionSet device_extension_set;
320 const char* device_extensions =
321 eglQueryDeviceStringEXT(egl_device, EGL_EXTENSIONS);
322 if (device_extensions) {
323 device_extension_set = gfx::MakeExtensionSet(device_extensions);
324 } else {
325 device_extension_set = gfx::ExtensionSet();
326 }
327
Chia-I Wu4cff4be62023-12-08 03:21:27328 std::string drm_render_node;
Robert Mader36c50132022-10-21 15:38:57329 if (gfx::HasExtension(device_extension_set,
330 "EGL_EXT_device_drm_render_node")) {
331 const char* path =
332 eglQueryDeviceStringEXT(egl_device, EGL_DRM_RENDER_NODE_FILE_EXT);
Kramer Gecfec01662022-12-05 22:54:24333 if (path)
Chia-I Wu4cff4be62023-12-08 03:21:27334 drm_render_node = std::string(path);
Robert Mader36c50132022-10-21 15:38:57335 }
Chia-I Wu4cff4be62023-12-08 03:21:27336 if (drm_render_node.empty() &&
Robert Mader36c50132022-10-21 15:38:57337 gfx::HasExtension(device_extension_set, "EGL_EXT_device_drm")) {
338 const char* path =
339 eglQueryDeviceStringEXT(egl_device, EGL_DRM_DEVICE_FILE_EXT);
Kramer Gecfec01662022-12-05 22:54:24340 if (path)
Chia-I Wu4cff4be62023-12-08 03:21:27341 drm_render_node = std::string(path);
342 }
343
344 if (!drm_render_node.empty()) {
345 struct stat dev_stat;
346 if (stat(drm_render_node.c_str(), &dev_stat) == 0) {
347 static_assert(sizeof(dev_t) <= sizeof(caps->drm_device_id),
348 "unexpected dev_t size");
349 DCHECK(dev_stat.st_rdev);
350 caps->drm_device_id = dev_stat.st_rdev;
351 }
Robert Mader36c50132022-10-21 15:38:57352 }
353
354 EGLint num_formats = 0;
355 if (eglQueryDmaBufFormatsEXT(egl_display, 0, nullptr, &num_formats) &&
356 num_formats > 0) {
357 std::vector<EGLint> formats_array(num_formats);
358 bool res = eglQueryDmaBufFormatsEXT(egl_display, num_formats,
359 formats_array.data(), &num_formats);
360 DCHECK(res);
361
362 for (EGLint format : formats_array) {
363 std::vector<uint64_t> modifiers;
364 EGLint num_modifiers = 0;
365 if (eglQueryDmaBufModifiersEXT(egl_display, format, 0, nullptr, nullptr,
366 &num_modifiers) &&
367 num_modifiers > 0) {
368 std::vector<EGLuint64KHR> modifiers_array(num_modifiers);
369 res = eglQueryDmaBufModifiersEXT(egl_display, format, num_modifiers,
370 modifiers_array.data(), nullptr,
371 &num_modifiers);
372 DCHECK(res);
373
374 for (uint64_t modifier : modifiers_array) {
375 modifiers.push_back(modifier);
376 }
377 }
378
379 caps->drm_formats_and_modifiers.emplace(format, modifiers);
380 }
381 }
382}
383#endif
384
geofflang851a4812016-09-14 19:20:29385bool CheckUniqueAndNonNullIds(GLsizei n, const GLuint* client_ids) {
386 if (n <= 0)
387 return true;
388 std::unordered_set<uint32_t> unique_ids(client_ids, client_ids + n);
389 return (unique_ids.size() == static_cast<size_t>(n)) &&
390 (unique_ids.find(0) == unique_ids.end());
391}
392
geofflang67c1fca2016-11-15 21:18:09393const char* GetServiceVersionString(const FeatureInfo* feature_info) {
394 if (feature_info->IsWebGL2OrES3Context())
395 return "OpenGL ES 3.0 Chromium";
Geoff Langd0c755c2021-01-18 21:58:16396 else if (feature_info->IsES31ForTestingContext()) {
Jiajia Qin252a8132018-07-19 01:03:22397 return "OpenGL ES 3.1 Chromium";
398 } else
geofflang67c1fca2016-11-15 21:18:09399 return "OpenGL ES 2.0 Chromium";
400}
401
402const char* GetServiceShadingLanguageVersionString(
403 const FeatureInfo* feature_info) {
404 if (feature_info->IsWebGL2OrES3Context())
405 return "OpenGL ES GLSL ES 3.0 Chromium";
Geoff Langd0c755c2021-01-18 21:58:16406 else if (feature_info->IsES31ForTestingContext()) {
Jiajia Qin252a8132018-07-19 01:03:22407 return "OpenGL ES GLSL ES 3.1 Chromium";
408 } else
geofflang67c1fca2016-11-15 21:18:09409 return "OpenGL ES GLSL ES 1.0 Chromium";
410}
411
Geoff Langfdec674e2018-02-22 17:40:29412void LogGLDebugMessage(GLenum source,
413 GLenum type,
414 GLuint id,
415 GLenum severity,
416 GLsizei length,
417 const GLchar* message,
418 Logger* error_logger) {
James Darpinian0f56e9f32018-01-11 02:23:55419 std::string id_string = GLES2Util::GetStringEnum(id);
Saifuddin Hitawalae608efe62024-11-14 00:17:49420 // Suppresses GL_DEBUG_TYPE_PERFORMANCE log messages for web tests that can
421 // get sent to the JS console and cause unnecessary test failures due test
422 // output log expectation comparisons.
423 if (type == GL_DEBUG_TYPE_PERFORMANCE &&
424 error_logger->SuppressPerformanceLogs()) {
425 return;
426 } else if (type == GL_DEBUG_TYPE_ERROR && source == GL_DEBUG_SOURCE_API) {
James Darpinian0f56e9f32018-01-11 02:23:55427 error_logger->LogMessage(__FILE__, __LINE__,
428 " " + id_string + ": " + message);
429 } else {
430 error_logger->LogMessage(
431 __FILE__, __LINE__,
432 std::string("GL Driver Message (") + GetDebugSourceString(source) +
433 ", " + GetDebugTypeString(type) + ", " + id_string + ", " +
434 GetDebugSeverityString(severity) + "): " + message);
435 }
geofflang326c8512016-11-03 15:11:28436}
437
Geoff Langfdec674e2018-02-22 17:40:29438void InitializeGLDebugLogging(bool log_non_errors,
439 GLDEBUGPROC callback,
440 const void* user_param) {
geofflang326c8512016-11-03 15:11:28441 glEnable(GL_DEBUG_OUTPUT);
442 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
443
James Darpinian0f56e9f32018-01-11 02:23:55444 glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE,
445 0, nullptr, GL_TRUE);
geofflang326c8512016-11-03 15:11:28446
James Darpinian0f56e9f32018-01-11 02:23:55447 if (log_non_errors) {
448 // Enable logging of medium and high severity messages
449 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0,
450 nullptr, GL_TRUE);
451 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
452 0, nullptr, GL_TRUE);
453 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
454 nullptr, GL_FALSE);
455 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
456 GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
457 }
458
Geoff Langfdec674e2018-02-22 17:40:29459 glDebugMessageCallback(callback, user_param);
geofflang326c8512016-11-03 15:11:28460}
461
Geoff Langab3a2e82017-06-12 18:53:38462bool ValidContextLostReason(GLenum reason) {
463 switch (reason) {
464 case GL_NO_ERROR:
465 case GL_GUILTY_CONTEXT_RESET_ARB:
466 case GL_INNOCENT_CONTEXT_RESET_ARB:
467 case GL_UNKNOWN_CONTEXT_RESET_ARB:
468 return true;
469 default:
470 return false;
471 }
472}
473
Geoff Langf44323ed2017-06-07 18:10:15474error::ContextLostReason GetContextLostReasonFromResetStatus(
475 GLenum reset_status) {
476 switch (reset_status) {
477 case GL_NO_ERROR:
478 // TODO(kbr): improve the precision of the error code in this case.
479 // Consider delegating to context for error code if MakeCurrent fails.
480 return error::kUnknown;
481 case GL_GUILTY_CONTEXT_RESET_ARB:
482 return error::kGuilty;
483 case GL_INNOCENT_CONTEXT_RESET_ARB:
484 return error::kInnocent;
485 case GL_UNKNOWN_CONTEXT_RESET_ARB:
486 return error::kUnknown;
487 }
488
Peter BostrΓΆma11556e2024-10-31 04:49:10489 NOTREACHED();
Geoff Langf44323ed2017-06-07 18:10:15490}
491
Jonathan Backerc26060e2018-03-29 15:06:29492bool GetCompressedTexSizeInBytes(const char* function_name,
493 GLsizei width,
494 GLsizei height,
495 GLsizei depth,
496 GLenum format,
497 GLsizei* size_in_bytes,
498 ErrorState* error_state) {
499 base::CheckedNumeric<GLsizei> bytes_required(0);
500
501 switch (format) {
502 case GL_ATC_RGB_AMD:
503 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
504 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
505 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
506 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
507 case GL_ETC1_RGB8_OES:
508 bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
509 bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
510 bytes_required *= kS3TCDXT1BlockSize;
511 break;
512 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
513 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
514 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
515 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
516 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
517 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
518 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
519 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
520 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
521 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
522 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
523 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
524 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
525 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
526 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
527 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
528 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
529 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
530 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
531 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
532 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
533 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
534 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
535 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
536 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
537 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
538 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
539 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
540 const int index =
541 (format < GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
542 ? static_cast<int>(format - GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
543 : static_cast<int>(format -
544 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
545
546 const int kBlockWidth = kASTCBlockArray[index].blockWidth;
547 const int kBlockHeight = kASTCBlockArray[index].blockHeight;
548
549 bytes_required = (width + kBlockWidth - 1) / kBlockWidth;
550 bytes_required *= (height + kBlockHeight - 1) / kBlockHeight;
551
552 bytes_required *= kASTCBlockSize;
553 break;
554 }
555 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
556 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
557 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
558 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
559 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
560 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
561 bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
562 bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
563 bytes_required *= kS3TCDXT3AndDXT5BlockSize;
564 break;
565 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
566 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
567 bytes_required = std::max(width, 8);
568 bytes_required *= std::max(height, 8);
569 bytes_required *= 4;
570 bytes_required += 7;
571 bytes_required /= 8;
572 break;
573 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
574 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
575 bytes_required = std::max(width, 16);
576 bytes_required *= std::max(height, 8);
577 bytes_required *= 2;
578 bytes_required += 7;
579 bytes_required /= 8;
580 break;
581
582 // ES3 formats.
583 case GL_COMPRESSED_R11_EAC:
584 case GL_COMPRESSED_SIGNED_R11_EAC:
585 case GL_COMPRESSED_RGB8_ETC2:
586 case GL_COMPRESSED_SRGB8_ETC2:
587 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
588 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
589 bytes_required =
590 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
591 bytes_required *=
592 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
593 bytes_required *= 8;
594 bytes_required *= depth;
595 break;
596 case GL_COMPRESSED_RG11_EAC:
597 case GL_COMPRESSED_SIGNED_RG11_EAC:
598 case GL_COMPRESSED_RGBA8_ETC2_EAC:
599 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
600 bytes_required =
601 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
602 bytes_required *=
603 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
604 bytes_required *= 16;
605 bytes_required *= depth;
606 break;
shrekshaode2f6f32020-02-07 02:39:44607 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
608 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
609 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
610 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
611 bytes_required = (width + kBPTCBlockWidth - 1) / kBPTCBlockWidth;
612 bytes_required *= (height + kBPTCBlockHeight - 1) / kBPTCBlockHeight;
613 bytes_required *= 16;
614 bytes_required *= depth;
615 break;
shrekshao3c058332020-02-11 00:00:12616 case GL_COMPRESSED_RED_RGTC1_EXT:
617 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
shrekshaoeae7c512020-02-11 22:06:27618 bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
619 bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
620 bytes_required *= 8;
621 bytes_required *= depth;
622 break;
shrekshao3c058332020-02-11 00:00:12623 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
624 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
625 bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
626 bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
shrekshaoeae7c512020-02-11 22:06:27627 bytes_required *= 16;
shrekshao3c058332020-02-11 00:00:12628 bytes_required *= depth;
629 break;
Jonathan Backerc26060e2018-03-29 15:06:29630 default:
Geoff Lang72fe4762018-10-19 15:11:36631 if (function_name && error_state) {
632 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name, format,
633 "format");
634 }
Jonathan Backerc26060e2018-03-29 15:06:29635 return false;
636 }
637
638 if (!bytes_required.IsValid()) {
Geoff Lang72fe4762018-10-19 15:11:36639 if (function_name && error_state) {
640 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
641 "invalid size");
642 }
Jonathan Backerc26060e2018-03-29 15:06:29643 return false;
644 }
645
646 *size_in_bytes = bytes_required.ValueOrDefault(0);
647 return true;
648}
649
shrekshaofb226c242020-02-19 00:37:12650bool ValidateCompressedFormatTarget(GLenum target, GLenum format) {
651 if (target == GL_TEXTURE_3D) {
652 // Formats not supporting 3D Tex
653 switch (format) {
654 // ES 3.1, Section 8.7, page 169.
655 case GL_COMPRESSED_R11_EAC:
656 case GL_COMPRESSED_SIGNED_R11_EAC:
657 case GL_COMPRESSED_RG11_EAC:
658 case GL_COMPRESSED_SIGNED_RG11_EAC:
659 case GL_COMPRESSED_RGB8_ETC2:
660 case GL_COMPRESSED_SRGB8_ETC2:
661 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
662 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
663 case GL_COMPRESSED_RGBA8_ETC2_EAC:
664 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
shrekshaofb226c242020-02-19 00:37:12665 // GL_EXT_texture_compression_s3tc
666 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
667 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
668 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
669 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
670 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
671 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
672 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
673 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
674 // GL_EXT_texture_compression_rgtc
675 case GL_COMPRESSED_RED_RGTC1_EXT:
676 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
677 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
678 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
679 return false;
shrekshaoad4525482020-03-12 00:30:55680 // GL_KHR_texture_compression_astc_hdr, TEXTURE_3D is not supported
681 // without HDR profile. This is guaranteed to be validated beforehand
682 // in GLES2DecoderImpl::TexStorageImpl before calling this.
shrekshaofb226c242020-02-19 00:37:12683 default:
684 break;
685 }
686 }
687
688 return true;
689}
690
Daniel Bratell60acbb592018-07-26 09:13:14691bool ValidateCompressedTexSubDimensions(GLenum target,
692 GLint level,
693 GLint xoffset,
694 GLint yoffset,
695 GLint zoffset,
696 GLsizei width,
697 GLsizei height,
698 GLsizei depth,
699 GLenum format,
700 Texture* texture,
Daniel Bratell60acbb592018-07-26 09:13:14701 const char** error_message) {
shrekshaofb226c242020-02-19 00:37:12702 if (!ValidateCompressedFormatTarget(target, format)) {
703 *error_message = "target invalid for format";
704 return false;
705 }
706
Daniel Bratell60acbb592018-07-26 09:13:14707 if (xoffset < 0 || yoffset < 0 || zoffset < 0) {
708 *error_message = "x/y/z offset < 0";
709 return false;
710 }
711
712 switch (format) {
713 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
714 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
715 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
716 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
717 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
718 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
719 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
720 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: {
721 const int kBlockWidth = 4;
722 const int kBlockHeight = 4;
723 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
724 *error_message = "xoffset or yoffset not multiple of 4";
725 return false;
726 }
727 GLsizei tex_width = 0;
728 GLsizei tex_height = 0;
729 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
730 nullptr) ||
731 width - xoffset > tex_width || height - yoffset > tex_height) {
732 *error_message = "dimensions out of range";
733 return false;
734 }
735 if ((((width % kBlockWidth) != 0) && (width + xoffset != tex_width)) ||
736 (((height % kBlockHeight) != 0) &&
737 (height + yoffset != tex_height))) {
738 *error_message = "dimensions do not align to a block boundary";
739 return false;
740 }
741 return true;
742 }
743 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
744 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
745 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
746 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
747 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
748 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
749 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
750 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
751 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
752 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
753 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
754 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
755 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
756 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
757 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
758 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
759 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
760 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
761 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
762 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
763 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
764 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
765 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
766 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
767 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
768 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
769 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
770 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
771 const int index =
772 (format < GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
773 ? static_cast<int>(format - GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
774 : static_cast<int>(format -
775 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
776
777 const int kBlockWidth = kASTCBlockArray[index].blockWidth;
778 const int kBlockHeight = kASTCBlockArray[index].blockHeight;
779
780 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
781 *error_message = "xoffset or yoffset not multiple of 4";
782 return false;
783 }
784 GLsizei tex_width = 0;
785 GLsizei tex_height = 0;
786 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
787 nullptr) ||
788 width - xoffset > tex_width || height - yoffset > tex_height) {
789 *error_message = "dimensions out of range";
790 return false;
791 }
792 if ((((width % kBlockWidth) != 0) && (width + xoffset != tex_width)) ||
793 (((height % kBlockHeight) != 0) &&
794 (height + yoffset != tex_height))) {
795 *error_message = "dimensions do not align to a block boundary";
796 return false;
797 }
798 return true;
799 }
800 case GL_ATC_RGB_AMD:
801 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
802 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
803 *error_message = "not supported for ATC textures";
804 return false;
805 }
806 case GL_ETC1_RGB8_OES: {
807 *error_message = "not supported for ECT1_RGB8_OES textures";
808 return false;
809 }
810 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
811 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
812 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
813 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
814 if ((xoffset != 0) || (yoffset != 0)) {
815 *error_message = "xoffset and yoffset must be zero";
816 return false;
817 }
818 GLsizei tex_width = 0;
819 GLsizei tex_height = 0;
820 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
821 nullptr) ||
822 width != tex_width || height != tex_height) {
823 *error_message =
824 "dimensions must match existing texture level dimensions";
825 return false;
826 }
827 return ValidateCompressedTexDimensions(target, level, width, height, 1,
Geoff Lang1cabc702019-04-26 01:30:18828 format, error_message);
Daniel Bratell60acbb592018-07-26 09:13:14829 }
830
831 // ES3 formats
832 case GL_COMPRESSED_R11_EAC:
833 case GL_COMPRESSED_SIGNED_R11_EAC:
834 case GL_COMPRESSED_RG11_EAC:
835 case GL_COMPRESSED_SIGNED_RG11_EAC:
836 case GL_COMPRESSED_RGB8_ETC2:
837 case GL_COMPRESSED_SRGB8_ETC2:
838 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
839 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
840 case GL_COMPRESSED_RGBA8_ETC2_EAC:
shrekshao41abf0c2020-02-19 02:09:42841 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
shrekshao41abf0c2020-02-19 02:09:42842 case GL_COMPRESSED_RED_RGTC1_EXT:
843 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
844 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
845 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: {
shrekshaob70dfea2020-07-08 23:17:09846 if (target == GL_TEXTURE_3D) {
847 *error_message = "target == GL_TEXTURE_3D is not allowed";
848 return false;
849 }
Roland Bock445b8152022-01-05 08:17:25850 [[fallthrough]];
shrekshaob70dfea2020-07-08 23:17:09851 }
852 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
853 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
854 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
855 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: {
Daniel Bratell60acbb592018-07-26 09:13:14856 const int kBlockSize = 4;
857 GLsizei tex_width, tex_height;
shrekshaob70dfea2020-07-08 23:17:09858 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
Daniel Bratell60acbb592018-07-26 09:13:14859 nullptr) ||
860 (xoffset % kBlockSize) || (yoffset % kBlockSize) ||
861 ((width % kBlockSize) && xoffset + width != tex_width) ||
862 ((height % kBlockSize) && yoffset + height != tex_height)) {
863 *error_message =
864 "dimensions must match existing texture level dimensions";
865 return false;
866 }
867 return true;
868 }
869 default:
870 *error_message = "unknown compressed texture format";
871 return false;
872 }
873}
874
875bool ValidateCompressedTexDimensions(GLenum target,
876 GLint level,
877 GLsizei width,
878 GLsizei height,
879 GLsizei depth,
880 GLenum format,
Daniel Bratell60acbb592018-07-26 09:13:14881 const char** error_message) {
shrekshaofb226c242020-02-19 00:37:12882 if (!ValidateCompressedFormatTarget(target, format)) {
883 *error_message = "target invalid for format";
884 return false;
885 }
Daniel Bratell60acbb592018-07-26 09:13:14886 switch (format) {
887 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
888 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
889 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
890 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
891 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
892 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
893 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
894 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
Geoff Lang1cabc702019-04-26 01:30:18895 if (!IsValidS3TCSizeForWebGLAndANGLE(level, width) ||
896 !IsValidS3TCSizeForWebGLAndANGLE(level, height)) {
Daniel Bratell60acbb592018-07-26 09:13:14897 *error_message = "width or height invalid for level";
898 return false;
899 }
900 return true;
901 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
902 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
903 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
904 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
905 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
906 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
907 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
908 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
909 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
910 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
911 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
912 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
913 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
914 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
915 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
916 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
917 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
918 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
919 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
920 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
921 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
922 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
923 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
924 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
925 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
926 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
927 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
928 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
929 case GL_ATC_RGB_AMD:
930 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
931 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
932 case GL_ETC1_RGB8_OES:
Daniel Bratell60acbb592018-07-26 09:13:14933 if (width <= 0 || height <= 0) {
934 *error_message = "width or height invalid for level";
935 return false;
936 }
937 return true;
938 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
939 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
940 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
941 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
Daniel Bratell60acbb592018-07-26 09:13:14942 if (!IsValidPVRTCSize(level, width) || !IsValidPVRTCSize(level, height)) {
943 *error_message = "width or height invalid for level";
944 return false;
945 }
946 return true;
947
948 // ES3 formats.
949 case GL_COMPRESSED_R11_EAC:
950 case GL_COMPRESSED_SIGNED_R11_EAC:
951 case GL_COMPRESSED_RG11_EAC:
952 case GL_COMPRESSED_SIGNED_RG11_EAC:
953 case GL_COMPRESSED_RGB8_ETC2:
954 case GL_COMPRESSED_SRGB8_ETC2:
955 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
956 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
957 case GL_COMPRESSED_RGBA8_ETC2_EAC:
958 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
959 if (width < 0 || height < 0 || depth < 0) {
960 *error_message = "width, height, or depth invalid";
961 return false;
962 }
Daniel Bratell60acbb592018-07-26 09:13:14963 return true;
shrekshaode2f6f32020-02-07 02:39:44964 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
965 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
966 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
967 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
968 if (width < 0 || height < 0 || depth < 0) {
969 *error_message = "width, height, or depth invalid";
970 return false;
971 }
shrekshaob70dfea2020-07-08 23:17:09972 if (level == 0 &&
973 !(width % kBPTCBlockWidth == 0 && height % kBPTCBlockHeight == 0)) {
shrekshaode2f6f32020-02-07 02:39:44974 *error_message = "width or height is not a multiple of four";
975 return false;
976 }
977 return true;
shrekshao3c058332020-02-11 00:00:12978 case GL_COMPRESSED_RED_RGTC1_EXT:
979 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
980 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
981 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
982 if (width < 0 || height < 0 || depth < 0) {
983 *error_message = "width, height, or depth invalid";
984 return false;
985 }
shrekshaob70dfea2020-07-08 23:17:09986 if (level == 0 &&
987 !(width % kRGTCBlockWidth == 0 && height % kRGTCBlockHeight == 0)) {
shrekshao3c058332020-02-11 00:00:12988 *error_message = "width or height is not a multiple of four";
989 return false;
990 }
991 return true;
Daniel Bratell60acbb592018-07-26 09:13:14992 default:
993 return false;
994 }
995}
996
Jonathan Backer8629c392018-04-04 23:01:03997bool ValidateCopyTexFormatHelper(const FeatureInfo* feature_info,
998 GLenum internal_format,
999 GLenum read_format,
1000 GLenum read_type,
1001 std::string* output_error_msg) {
1002 DCHECK(output_error_msg);
1003 if (read_format == 0) {
1004 *output_error_msg = std::string("no valid color image");
1005 return false;
1006 }
1007 // Check we have compatible formats.
1008 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format);
1009 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
1010 if (!channels_needed ||
1011 (channels_needed & channels_exist) != channels_needed) {
1012 *output_error_msg = std::string("incompatible format");
1013 return false;
1014 }
Jiajia Qin252a8132018-07-19 01:03:221015 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
Jonathan Backer8629c392018-04-04 23:01:031016 GLint color_encoding =
1017 GLES2Util::GetColorEncodingFromInternalFormat(read_format);
1018 bool float_mismatch = feature_info->ext_color_buffer_float_available()
1019 ? (GLES2Util::IsIntegerFormat(internal_format) !=
1020 GLES2Util::IsIntegerFormat(read_format))
1021 : GLES2Util::IsFloatFormat(internal_format);
1022 if (color_encoding !=
1023 GLES2Util::GetColorEncodingFromInternalFormat(internal_format) ||
1024 float_mismatch ||
1025 (GLES2Util::IsSignedIntegerFormat(internal_format) !=
1026 GLES2Util::IsSignedIntegerFormat(read_format)) ||
1027 (GLES2Util::IsUnsignedIntegerFormat(internal_format) !=
1028 GLES2Util::IsUnsignedIntegerFormat(read_format))) {
1029 *output_error_msg = std::string("incompatible format");
1030 return false;
1031 }
1032 }
1033 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
1034 *output_error_msg =
1035 std::string("can not be used with depth or stencil textures");
1036 return false;
1037 }
Jiajia Qin252a8132018-07-19 01:03:221038 if (feature_info->IsWebGL2OrES3OrHigherContext() ||
Jonathan Backer8629c392018-04-04 23:01:031039 (feature_info->feature_flags().chromium_color_buffer_float_rgb &&
1040 internal_format == GL_RGB32F) ||
1041 (feature_info->feature_flags().chromium_color_buffer_float_rgba &&
1042 internal_format == GL_RGBA32F)) {
1043 if (GLES2Util::IsSizedColorFormat(internal_format)) {
1044 int sr, sg, sb, sa;
1045 GLES2Util::GetColorFormatComponentSizes(read_format, read_type, &sr, &sg,
1046 &sb, &sa);
1047 DCHECK(sr > 0 || sg > 0 || sb > 0 || sa > 0);
1048 int dr, dg, db, da;
1049 GLES2Util::GetColorFormatComponentSizes(internal_format, 0, &dr, &dg, &db,
1050 &da);
1051 DCHECK(dr > 0 || dg > 0 || db > 0 || da > 0);
1052 if ((dr > 0 && sr != dr) || (dg > 0 && sg != dg) ||
1053 (db > 0 && sb != db) || (da > 0 && sa != da)) {
1054 *output_error_msg = std::string("incompatible color component sizes");
1055 return false;
1056 }
1057 }
1058 }
1059 return true;
1060}
1061
1062CopyTextureMethod GetCopyTextureCHROMIUMMethod(const FeatureInfo* feature_info,
1063 GLenum source_target,
1064 GLint source_level,
1065 GLenum source_internal_format,
1066 GLenum source_type,
1067 GLenum dest_target,
1068 GLint dest_level,
1069 GLenum dest_internal_format,
1070 bool flip_y,
1071 bool premultiply_alpha,
Corentin Wallezcacc4172021-12-03 14:40:221072 bool unpremultiply_alpha) {
Jonathan Backer8629c392018-04-04 23:01:031073 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
1074 bool source_format_color_renderable =
1075 Texture::ColorRenderable(feature_info, source_internal_format, false);
1076 bool dest_format_color_renderable =
1077 Texture::ColorRenderable(feature_info, dest_internal_format, false);
1078 std::string output_error_msg;
1079
1080 switch (dest_internal_format) {
Xiaohan Wangfa22d3e2022-01-15 02:02:431081#if BUILDFLAG(IS_MAC)
Jonathan Backer8629c392018-04-04 23:01:031082 // RGB5_A1 is not color-renderable on NVIDIA Mac, see
1083 // https://crbug.com/676209.
1084 case GL_RGB5_A1:
1085 return CopyTextureMethod::DRAW_AND_READBACK;
1086#endif
1087 // RGB9_E5 isn't accepted by glCopyTexImage2D if underlying context is ES.
1088 case GL_RGB9_E5:
Zhenyao Mo12d741f2024-07-09 19:12:381089 return CopyTextureMethod::DRAW_AND_READBACK;
Jonathan Backer8629c392018-04-04 23:01:031090 // SRGB format has color-space conversion issue. WebGL spec doesn't define
1091 // clearly if linear-to-srgb color space conversion is required or not when
1092 // uploading DOM elements to SRGB textures. WebGL conformance test expects
1093 // no linear-to-srgb conversion, while current GPU path for
1094 // CopyTextureCHROMIUM does the conversion. Do a fallback path before the
1095 // issue is resolved. see https://github.com/KhronosGroup/WebGL/issues/2165.
1096 // TODO(qiankun.miao@intel.com): revisit this once the above issue is
1097 // resolved.
1098 case GL_SRGB_EXT:
1099 case GL_SRGB_ALPHA_EXT:
1100 case GL_SRGB8:
1101 case GL_SRGB8_ALPHA8:
1102 if (feature_info->IsWebGLContext())
1103 return CopyTextureMethod::DRAW_AND_READBACK;
1104 break;
1105 default:
1106 break;
1107 }
1108
1109 // CopyTexImage* should not allow internalformat of GL_BGRA_EXT and
1110 // GL_BGRA8_EXT. https://crbug.com/663086.
1111 bool copy_tex_image_format_valid =
1112 source_internal_format != GL_BGRA_EXT &&
1113 dest_internal_format != GL_BGRA_EXT &&
1114 source_internal_format != GL_BGRA8_EXT &&
1115 dest_internal_format != GL_BGRA8_EXT &&
1116 ValidateCopyTexFormatHelper(feature_info, dest_internal_format,
1117 source_internal_format, source_type,
1118 &output_error_msg);
1119
Antoine Labour4885296a2019-05-09 02:38:391120 // The ES3 spec is vague about whether or not glCopyTexImage2D from a
1121 // GL_RGB10_A2 attachment to an unsized internal format is valid. Most drivers
1122 // interpreted the explicit call out as not valid (and dEQP actually checks
1123 // this), so avoid DIRECT_COPY in that case.
Zhenyao Mo12d741f2024-07-09 19:12:381124 if (source_internal_format == GL_RGB10_A2 &&
1125 dest_internal_format != source_internal_format) {
Antoine Labour4885296a2019-05-09 02:38:391126 copy_tex_image_format_valid = false;
Zhenyao Mo12d741f2024-07-09 19:12:381127 }
Antoine Labour4885296a2019-05-09 02:38:391128
Jonathan Backer8629c392018-04-04 23:01:031129 // TODO(qiankun.miao@intel.com): for WebGL 2.0 or OpenGL ES 3.0, both
1130 // DIRECT_DRAW path for dest_level > 0 and DIRECT_COPY path for source_level >
1131 // 0 are not available due to a framebuffer completeness bug:
1132 // https://crbug.com/678526. Once the bug is fixed, the limitation for WebGL
1133 // 2.0 and OpenGL ES 3.0 can be lifted. For WebGL 1.0 or OpenGL ES 2.0,
1134 // DIRECT_DRAW path isn't available for dest_level > 0 due to level > 0 isn't
1135 // supported by glFramebufferTexture2D in ES2 context. DIRECT_DRAW path isn't
1136 // available for cube map dest texture either due to it may be cube map
1137 // incomplete. Go to DRAW_AND_COPY path in these cases.
1138 if (source_target == GL_TEXTURE_2D &&
1139 (dest_target == GL_TEXTURE_2D || dest_target == GL_TEXTURE_CUBE_MAP) &&
1140 source_format_color_renderable && copy_tex_image_format_valid &&
Corentin Wallezcacc4172021-12-03 14:40:221141 source_level == 0 && !flip_y && !premultiply_alpha_change) {
shrekshaob437fb192020-01-30 07:39:571142 auto source_texture_type = GLES2Util::GetGLReadPixelsImplementationType(
1143 source_internal_format, source_target);
1144 auto dest_texture_type = GLES2Util::GetGLReadPixelsImplementationType(
1145 dest_internal_format, dest_target);
1146 if (source_texture_type != GL_UNSIGNED_SHORT ||
1147 source_texture_type == dest_texture_type) {
1148 // https://crbug.com/1042239. As it is stated in the latest OpenGL ES 3.2
1149 // spec (Oct 22, 2019) it is optional for implementation to support
1150 // conversion between unmatched source and dest effective internal format.
1151 // R16 to R16F direct copy failure is seen on Android Nvidia shield
1152 // devices. So we won't use DIRECT_COPY for this format.
1153 return CopyTextureMethod::DIRECT_COPY;
1154 }
1155 }
Jonathan Backer8629c392018-04-04 23:01:031156 if (dest_format_color_renderable && dest_level == 0 &&
1157 dest_target != GL_TEXTURE_CUBE_MAP)
1158 return CopyTextureMethod::DIRECT_DRAW;
1159
1160 // Draw to a fbo attaching level 0 of an intermediate texture,
1161 // then copy from the fbo to dest texture level with glCopyTexImage2D.
1162 return CopyTextureMethod::DRAW_AND_COPY;
1163}
1164
Jonathan Backer4cb165c82018-07-03 20:25:331165bool ValidateCopyTextureCHROMIUMInternalFormats(const FeatureInfo* feature_info,
1166 GLenum source_internal_format,
1167 GLenum dest_internal_format,
1168 std::string* output_error_msg) {
1169 bool valid_dest_format = false;
1170 // TODO(qiankun.miao@intel.com): ALPHA, LUMINANCE and LUMINANCE_ALPHA formats
1171 // are not supported on GL core profile. See https://crbug.com/577144. Enable
1172 // the workaround for glCopyTexImage and glCopyTexSubImage in
1173 // gles2_cmd_copy_tex_image.cc for glCopyTextureCHROMIUM implementation.
1174 switch (dest_internal_format) {
1175 case GL_RGB:
1176 case GL_RGBA:
1177 case GL_RGB8:
1178 case GL_RGBA8:
1179 valid_dest_format = true;
1180 break;
1181 case GL_BGRA_EXT:
1182 case GL_BGRA8_EXT:
1183 valid_dest_format =
1184 feature_info->feature_flags().ext_texture_format_bgra8888;
1185 break;
1186 case GL_SRGB_EXT:
1187 case GL_SRGB_ALPHA_EXT:
1188 valid_dest_format = feature_info->feature_flags().ext_srgb;
1189 break;
1190 case GL_R8:
1191 case GL_R8UI:
1192 case GL_RG8:
1193 case GL_RG8UI:
1194 case GL_SRGB8:
1195 case GL_RGB565:
1196 case GL_RGB8UI:
1197 case GL_SRGB8_ALPHA8:
1198 case GL_RGB5_A1:
1199 case GL_RGBA4:
1200 case GL_RGBA8UI:
1201 case GL_RGB10_A2:
Jiajia Qin252a8132018-07-19 01:03:221202 valid_dest_format = feature_info->IsWebGL2OrES3OrHigherContext();
Jonathan Backer4cb165c82018-07-03 20:25:331203 break;
1204 case GL_RGB9_E5:
1205 case GL_R16F:
1206 case GL_R32F:
1207 case GL_RG16F:
1208 case GL_RG32F:
1209 case GL_RGB16F:
1210 case GL_RGBA16F:
1211 case GL_R11F_G11F_B10F:
1212 valid_dest_format = feature_info->ext_color_buffer_float_available();
1213 break;
1214 case GL_RGB32F:
1215 valid_dest_format =
1216 feature_info->ext_color_buffer_float_available() ||
1217 feature_info->feature_flags().chromium_color_buffer_float_rgb;
1218 break;
1219 case GL_RGBA32F:
1220 valid_dest_format =
1221 feature_info->ext_color_buffer_float_available() ||
1222 feature_info->feature_flags().chromium_color_buffer_float_rgba;
1223 break;
1224 case GL_ALPHA:
1225 case GL_LUMINANCE:
1226 case GL_LUMINANCE_ALPHA:
1227 valid_dest_format = true;
1228 break;
1229 default:
1230 valid_dest_format = false;
1231 break;
1232 }
1233
1234 // TODO(aleksandar.stojiljkovic): Use sized internal formats:
1235 // https://crbug.com/628064
1236 bool valid_source_format =
1237 source_internal_format == GL_RED || source_internal_format == GL_ALPHA ||
1238 source_internal_format == GL_RGB || source_internal_format == GL_RGBA ||
1239 source_internal_format == GL_RGB8 || source_internal_format == GL_RGBA8 ||
1240 source_internal_format == GL_LUMINANCE ||
1241 source_internal_format == GL_LUMINANCE_ALPHA ||
1242 source_internal_format == GL_BGRA_EXT ||
1243 source_internal_format == GL_BGRA8_EXT ||
Miguel Casas94f82b22019-01-31 21:20:571244 source_internal_format == GL_R16_EXT ||
shrekshaob437fb192020-01-30 07:39:571245 source_internal_format == GL_RG16_EXT ||
1246 source_internal_format == GL_RGBA16_EXT ||
Miguel Casas94f82b22019-01-31 21:20:571247 source_internal_format == GL_RGB10_A2;
Jonathan Backer4cb165c82018-07-03 20:25:331248 if (!valid_source_format) {
1249 *output_error_msg = "invalid source internal format " +
1250 GLES2Util::GetStringEnum(source_internal_format);
1251 return false;
1252 }
1253 if (!valid_dest_format) {
1254 *output_error_msg = "invalid dest internal format " +
1255 GLES2Util::GetStringEnum(dest_internal_format);
1256 return false;
1257 }
1258
1259 return true;
1260}
1261
Geoff Lang18c8f3d82019-07-08 23:20:331262GLenum GetTextureBindingQuery(GLenum texture_type) {
1263 switch (texture_type) {
1264 case GL_TEXTURE_2D:
1265 return GL_TEXTURE_BINDING_2D;
1266 case GL_TEXTURE_2D_ARRAY:
1267 return GL_TEXTURE_BINDING_2D_ARRAY;
1268 case GL_TEXTURE_2D_MULTISAMPLE:
1269 return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
1270 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1271 return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
1272 case GL_TEXTURE_3D:
1273 return GL_TEXTURE_BINDING_3D;
1274 case GL_TEXTURE_EXTERNAL_OES:
1275 return GL_TEXTURE_BINDING_EXTERNAL_OES;
1276 case GL_TEXTURE_RECTANGLE:
1277 return GL_TEXTURE_BINDING_RECTANGLE;
1278 case GL_TEXTURE_CUBE_MAP:
1279 return GL_TEXTURE_BINDING_CUBE_MAP;
1280 default:
Peter BostrΓΆma11556e2024-10-31 04:49:101281 NOTREACHED();
Geoff Lang18c8f3d82019-07-08 23:20:331282 }
1283}
1284
shrekshaoad4525482020-03-12 00:30:551285bool IsASTCFormat(GLenum internal_format) {
1286 switch (internal_format) {
1287 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
1288 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
1289 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
1290 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
1291 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
1292 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1293 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
1294 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
1295 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
1296 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
1297 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
1298 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
1299 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
1300 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
1301 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
1302 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
1303 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
1304 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
1305 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
1306 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
1307 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
1308 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
1309 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
1310 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
1311 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
1312 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
1313 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
1314 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
1315 return true;
1316 default:
1317 break;
1318 }
1319 return false;
1320}
1321
1322// This is only called in Texture::SetLevelInfo in texture_manager.cc
1323// where there is no direct access to decoder->IsCompressedTextureFormat
1324// or feature_info->validators()->compressed_texture_format.IsValid
1325bool IsCompressedTextureFormat(GLenum internal_format) {
1326 switch (internal_format) {
1327 // S3TC
1328 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1329 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1330 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1331 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1332 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1333 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1334 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1335 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1336 // ASTC
1337 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
1338 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
1339 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
1340 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
1341 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
1342 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1343 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
1344 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
1345 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
1346 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
1347 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
1348 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
1349 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
1350 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
1351 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
1352 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
1353 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
1354 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
1355 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
1356 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
1357 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
1358 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
1359 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
1360 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
1361 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
1362 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
1363 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
1364 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
1365 // BPTC
1366 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
1367 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
1368 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
1369 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
1370 // RGTC
1371 case GL_COMPRESSED_RED_RGTC1_EXT:
1372 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
1373 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
1374 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
1375 // ETC2/EAC
1376 case GL_COMPRESSED_R11_EAC:
1377 case GL_COMPRESSED_SIGNED_R11_EAC:
1378 case GL_COMPRESSED_RGB8_ETC2:
1379 case GL_COMPRESSED_SRGB8_ETC2:
1380 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1381 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1382 case GL_COMPRESSED_RG11_EAC:
1383 case GL_COMPRESSED_SIGNED_RG11_EAC:
1384 case GL_COMPRESSED_RGBA8_ETC2_EAC:
1385 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1386 // ETC1
1387 case GL_ETC1_RGB8_OES:
1388 // PVRTC
1389 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
1390 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
1391 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
1392 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
1393 // ATC
1394 case GL_ATC_RGB_AMD:
1395 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
1396 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
1397 return true;
1398 default:
1399 break;
1400 }
1401 return false;
1402}
1403
Saifuddin Hitawala151bf3bf2022-07-19 19:03:141404Texture* CreateGLES2TextureWithLightRef(GLuint service_id, GLenum target) {
1405 Texture* texture = new Texture(service_id);
1406 texture->SetLightweightRef();
1407 texture->SetTarget(target, 1 /*max_levels=*/);
1408 texture->set_min_filter(GL_LINEAR);
1409 texture->set_mag_filter(GL_LINEAR);
1410 texture->set_wrap_t(GL_CLAMP_TO_EDGE);
1411 texture->set_wrap_s(GL_CLAMP_TO_EDGE);
1412 return texture;
1413}
1414
junov0cad1f42016-01-07 21:48:511415} // namespace gles2
1416} // namespace gpu