blob: 27cc85958ed57aa91e25bb48d73e27378a2e33ee [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
5#include "gpu/command_buffer/service/gl_utils.h"
6
Jonathan Backer4cb165c82018-07-03 20:25:337#include <algorithm>
brettw1ce49f62017-04-27 19:42:328#include <unordered_set>
9
Xiaohan Wangfa22d3e2022-01-15 02:02:4310#include "build/build_config.h"
geofflang124fd552016-09-08 20:02:5511#include "gpu/command_buffer/common/capabilities.h"
Jonathan Backerc26060e2018-03-29 15:06:2912#include "gpu/command_buffer/service/error_state.h"
geofflang124fd552016-09-08 20:02:5513#include "gpu/command_buffer/service/feature_info.h"
Jonathan Backer8629c392018-04-04 23:01:0314#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
James Darpinian0f56e9f32018-01-11 02:23:5515#include "gpu/command_buffer/service/logger.h"
Jonathan Backer8629c392018-04-04 23:01:0316#include "gpu/command_buffer/service/texture_manager.h"
geofflang124fd552016-09-08 20:02:5517#include "ui/gl/gl_version_info.h"
junov0cad1f42016-01-07 21:48:5118
Robert Mader16be7de2023-03-14 15:46:1819#if BUILDFLAG(IS_CHROMEOS_ASH)
Robert Mader36c50132022-10-21 15:38:5720#include "ui/gl/gl_surface_egl.h"
21#endif
22
junov0cad1f42016-01-07 21:48:5123namespace gpu {
24namespace gles2 {
25
geofflang326c8512016-11-03 15:11:2826namespace {
Jonathan Backerc26060e2018-03-29 15:06:2927
28const int kASTCBlockSize = 16;
29const int kS3TCBlockWidth = 4;
30const int kS3TCBlockHeight = 4;
31const int kS3TCDXT1BlockSize = 8;
32const int kS3TCDXT3AndDXT5BlockSize = 16;
33const int kEACAndETC2BlockSize = 4;
shrekshaode2f6f32020-02-07 02:39:4434const int kBPTCBlockWidth = 4;
35const int kBPTCBlockHeight = 4;
shrekshao3c058332020-02-11 00:00:1236const int kRGTCBlockWidth = 4;
37const int kRGTCBlockHeight = 4;
Jonathan Backerc26060e2018-03-29 15:06:2938
39typedef struct {
40 int blockWidth;
41 int blockHeight;
42} ASTCBlockArray;
43
44const ASTCBlockArray kASTCBlockArray[] = {
45 {4, 4}, /* GL_COMPRESSED_RGBA_ASTC_4x4_KHR */
46 {5, 4}, /* and GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR */
47 {5, 5}, {6, 5}, {6, 6}, {8, 5}, {8, 6}, {8, 8},
48 {10, 5}, {10, 6}, {10, 8}, {10, 10}, {12, 10}, {12, 12}};
49
Daniel Bratell60acbb592018-07-26 09:13:1450bool IsValidPVRTCSize(GLint level, GLsizei size) {
51 return GLES2Util::IsPOT(size);
52}
53
Geoff Lang1cabc702019-04-26 01:30:1854bool IsValidS3TCSizeForWebGLAndANGLE(GLint level, GLsizei size) {
Geoff Langf067e4c2020-09-18 17:51:5755 // WebGL and ANGLE only allow multiple-of-4 sizes for the base level. See
56 // WEBGL_compressed_texture_s3tc and ANGLE_compressed_texture_dxt*
57 return (level > 0) || (size % kS3TCBlockWidth == 0);
Daniel Bratell60acbb592018-07-26 09:13:1458}
59
geofflang326c8512016-11-03 15:11:2860const char* GetDebugSourceString(GLenum source) {
61 switch (source) {
62 case GL_DEBUG_SOURCE_API:
63 return "OpenGL";
64 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
65 return "Window System";
66 case GL_DEBUG_SOURCE_SHADER_COMPILER:
67 return "Shader Compiler";
68 case GL_DEBUG_SOURCE_THIRD_PARTY:
69 return "Third Party";
70 case GL_DEBUG_SOURCE_APPLICATION:
71 return "Application";
72 case GL_DEBUG_SOURCE_OTHER:
73 return "Other";
74 default:
75 return "UNKNOWN";
76 }
77}
78
79const char* GetDebugTypeString(GLenum type) {
80 switch (type) {
81 case GL_DEBUG_TYPE_ERROR:
82 return "Error";
83 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
84 return "Deprecated behavior";
85 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
86 return "Undefined behavior";
87 case GL_DEBUG_TYPE_PORTABILITY:
88 return "Portability";
89 case GL_DEBUG_TYPE_PERFORMANCE:
90 return "Performance";
91 case GL_DEBUG_TYPE_OTHER:
92 return "Other";
93 case GL_DEBUG_TYPE_MARKER:
94 return "Marker";
95 default:
96 return "UNKNOWN";
97 }
98}
99
100const char* GetDebugSeverityString(GLenum severity) {
101 switch (severity) {
102 case GL_DEBUG_SEVERITY_HIGH:
103 return "High";
104 case GL_DEBUG_SEVERITY_MEDIUM:
105 return "Medium";
106 case GL_DEBUG_SEVERITY_LOW:
107 return "Low";
108 case GL_DEBUG_SEVERITY_NOTIFICATION:
109 return "Notification";
110 default:
111 return "UNKNOWN";
112 }
113}
James Darpinian0f56e9f32018-01-11 02:23:55114} // namespace
geofflang326c8512016-11-03 15:11:28115
geofflang124fd552016-09-08 20:02:55116bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
117 GLint rangeMax,
118 GLint precision) {
119 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
120}
121
122void QueryShaderPrecisionFormat(const gl::GLVersionInfo& gl_version_info,
123 GLenum shader_type,
124 GLenum precision_type,
125 GLint* range,
126 GLint* precision) {
127 switch (precision_type) {
128 case GL_LOW_INT:
129 case GL_MEDIUM_INT:
130 case GL_HIGH_INT:
131 // These values are for a 32-bit twos-complement integer format.
132 range[0] = 31;
133 range[1] = 30;
134 *precision = 0;
135 break;
136 case GL_LOW_FLOAT:
137 case GL_MEDIUM_FLOAT:
138 case GL_HIGH_FLOAT:
139 // These values are for an IEEE single-precision floating-point format.
140 range[0] = 127;
141 range[1] = 127;
142 *precision = 23;
143 break;
144 default:
145 NOTREACHED();
146 break;
147 }
148
149 if (gl_version_info.is_es) {
150 // This function is sometimes defined even though it's really just
151 // a stub, so we need to set range and precision as if it weren't
152 // defined before calling it.
153 // On Mac OS with some GPUs, calling this generates a
154 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
155 // platforms.
156 glGetShaderPrecisionFormat(shader_type, precision_type, range, precision);
157
158 // TODO(brianderson): Make the following official workarounds.
159
160 // Some drivers have bugs where they report the ranges as a negative number.
161 // Taking the absolute value here shouldn't hurt because negative numbers
162 // aren't expected anyway.
163 range[0] = abs(range[0]);
164 range[1] = abs(range[1]);
165
166 // If the driver reports a precision for highp float that isn't actually
167 // highp, don't pretend like it's supported because shader compilation will
168 // fail anyway.
169 if (precision_type == GL_HIGH_FLOAT &&
170 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
171 range[0] = 0;
172 range[1] = 0;
173 *precision = 0;
174 }
175 }
176}
177
178void PopulateNumericCapabilities(Capabilities* caps,
179 const FeatureInfo* feature_info) {
180 DCHECK(caps != nullptr);
181
182 const gl::GLVersionInfo& version_info = feature_info->gl_version_info();
183 caps->VisitPrecisions([&version_info](
James Darpinian0f56e9f32018-01-11 02:23:55184 GLenum shader, GLenum type,
185 Capabilities::ShaderPrecision* shader_precision) {
geofflang124fd552016-09-08 20:02:55186 GLint range[2] = {0, 0};
187 GLint precision = 0;
188 QueryShaderPrecisionFormat(version_info, shader, type, range, &precision);
189 shader_precision->min_range = range[0];
190 shader_precision->max_range = range[1];
191 shader_precision->precision = precision;
192 });
193
194 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
195 &caps->max_combined_texture_image_units);
196 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps->max_cube_map_texture_size);
197 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
198 &caps->max_fragment_uniform_vectors);
199 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps->max_renderbuffer_size);
200 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps->max_texture_image_units);
201 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps->max_texture_size);
202 glGetIntegerv(GL_MAX_VARYING_VECTORS, &caps->max_varying_vectors);
203 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps->max_vertex_attribs);
204 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
205 &caps->max_vertex_texture_image_units);
206 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
207 &caps->max_vertex_uniform_vectors);
zmoc95386fb2016-12-09 23:48:55208 {
209 GLint dims[2] = {0, 0};
210 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
211 caps->max_viewport_width = dims[0];
212 caps->max_viewport_height = dims[1];
213 }
geofflang124fd552016-09-08 20:02:55214 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
215 &caps->num_compressed_texture_formats);
216 glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps->num_shader_binary_formats);
217
Jiajia Qin252a8132018-07-19 01:03:22218 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
geofflang124fd552016-09-08 20:02:55219 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps->max_3d_texture_size);
220 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps->max_array_texture_layers);
221 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps->max_color_attachments);
222 glGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
223 &caps->max_combined_fragment_uniform_components);
224 glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
225 &caps->max_combined_uniform_blocks);
226 glGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
227 &caps->max_combined_vertex_uniform_components);
228 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps->max_draw_buffers);
229 glGetInteger64v(GL_MAX_ELEMENT_INDEX, &caps->max_element_index);
230 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps->max_elements_indices);
231 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps->max_elements_vertices);
232 glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
233 &caps->max_fragment_input_components);
234 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
235 &caps->max_fragment_uniform_blocks);
236 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
237 &caps->max_fragment_uniform_components);
238 glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->max_program_texel_offset);
239 glGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &caps->max_server_wait_timeout);
240 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->max_texture_lod_bias);
241 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
242 &caps->max_transform_feedback_interleaved_components);
243 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
244 &caps->max_transform_feedback_separate_attribs);
245 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
246 &caps->max_transform_feedback_separate_components);
247 glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &caps->max_uniform_block_size);
248 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
249 &caps->max_uniform_buffer_bindings);
250 glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps->max_varying_components);
251 glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
252 &caps->max_vertex_output_components);
253 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS,
254 &caps->max_vertex_uniform_blocks);
255 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
256 &caps->max_vertex_uniform_components);
257 glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->min_program_texel_offset);
258 glGetIntegerv(GL_NUM_EXTENSIONS, &caps->num_extensions);
259 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
260 &caps->num_program_binary_formats);
261 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
262 &caps->uniform_buffer_offset_alignment);
263 caps->major_version = 3;
Geoff Langd0c755c2021-01-18 21:58:16264 if (feature_info->IsES31ForTestingContext()) {
Jiajia Qinbf31bed2018-08-23 03:54:50265 glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,
266 &caps->max_atomic_counter_buffer_bindings);
267 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
268 &caps->max_shader_storage_buffer_bindings);
269 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT,
270 &caps->shader_storage_buffer_offset_alignment);
Jiajia Qin252a8132018-07-19 01:03:22271 caps->minor_version = 1;
272 } else {
273 caps->minor_version = 0;
274 }
geofflang124fd552016-09-08 20:02:55275 }
276 if (feature_info->feature_flags().multisampled_render_to_texture ||
277 feature_info->feature_flags().chromium_framebuffer_multisample ||
Jiajia Qin252a8132018-07-19 01:03:22278 feature_info->IsWebGL2OrES3OrHigherContext()) {
geofflang124fd552016-09-08 20:02:55279 glGetIntegerv(GL_MAX_SAMPLES, &caps->max_samples);
280 }
281}
282
Robert Mader16be7de2023-03-14 15:46:18283#if BUILDFLAG(IS_CHROMEOS_ASH)
Robert Mader36c50132022-10-21 15:38:57284void PopulateDRMCapabilities(Capabilities* caps,
285 const FeatureInfo* feature_info) {
286 DCHECK(caps != nullptr);
287
288 if (!gl::GLSurfaceEGL::GetGLDisplayEGL() ||
289 !gl::GLSurfaceEGL::GetGLDisplayEGL()->IsInitialized() ||
290 !gl::GLSurfaceEGL::GetGLDisplayEGL()
291 ->ext->b_EGL_EXT_image_dma_buf_import_modifiers ||
292 feature_info->workarounds()
293 .disable_egl_ext_image_dma_buf_import_modifiers ||
294 !gl::g_driver_egl.client_ext.b_EGL_EXT_device_query) {
295 return;
296 }
297
298 EGLDisplay egl_display = gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay();
299 DCHECK(egl_display != nullptr);
300
301 EGLDeviceEXT egl_device;
302 if (!eglQueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT,
303 (EGLAttrib*)&egl_device)) {
304 return;
305 }
306
307 gfx::ExtensionSet device_extension_set;
308 const char* device_extensions =
309 eglQueryDeviceStringEXT(egl_device, EGL_EXTENSIONS);
310 if (device_extensions) {
311 device_extension_set = gfx::MakeExtensionSet(device_extensions);
312 } else {
313 device_extension_set = gfx::ExtensionSet();
314 }
315
316 if (gfx::HasExtension(device_extension_set,
317 "EGL_EXT_device_drm_render_node")) {
318 const char* path =
319 eglQueryDeviceStringEXT(egl_device, EGL_DRM_RENDER_NODE_FILE_EXT);
Kramer Gecfec01662022-12-05 22:54:24320 if (path)
321 caps->drm_render_node = std::string(path);
Robert Mader36c50132022-10-21 15:38:57322 }
323 if (caps->drm_render_node.empty() &&
324 gfx::HasExtension(device_extension_set, "EGL_EXT_device_drm")) {
325 const char* path =
326 eglQueryDeviceStringEXT(egl_device, EGL_DRM_DEVICE_FILE_EXT);
Kramer Gecfec01662022-12-05 22:54:24327 if (path)
328 caps->drm_render_node = std::string(path);
Robert Mader36c50132022-10-21 15:38:57329 }
330
331 EGLint num_formats = 0;
332 if (eglQueryDmaBufFormatsEXT(egl_display, 0, nullptr, &num_formats) &&
333 num_formats > 0) {
334 std::vector<EGLint> formats_array(num_formats);
335 bool res = eglQueryDmaBufFormatsEXT(egl_display, num_formats,
336 formats_array.data(), &num_formats);
337 DCHECK(res);
338
339 for (EGLint format : formats_array) {
340 std::vector<uint64_t> modifiers;
341 EGLint num_modifiers = 0;
342 if (eglQueryDmaBufModifiersEXT(egl_display, format, 0, nullptr, nullptr,
343 &num_modifiers) &&
344 num_modifiers > 0) {
345 std::vector<EGLuint64KHR> modifiers_array(num_modifiers);
346 res = eglQueryDmaBufModifiersEXT(egl_display, format, num_modifiers,
347 modifiers_array.data(), nullptr,
348 &num_modifiers);
349 DCHECK(res);
350
351 for (uint64_t modifier : modifiers_array) {
352 modifiers.push_back(modifier);
353 }
354 }
355
356 caps->drm_formats_and_modifiers.emplace(format, modifiers);
357 }
358 }
359}
360#endif
361
geofflang851a4812016-09-14 19:20:29362bool CheckUniqueAndNonNullIds(GLsizei n, const GLuint* client_ids) {
363 if (n <= 0)
364 return true;
365 std::unordered_set<uint32_t> unique_ids(client_ids, client_ids + n);
366 return (unique_ids.size() == static_cast<size_t>(n)) &&
367 (unique_ids.find(0) == unique_ids.end());
368}
369
geofflang67c1fca2016-11-15 21:18:09370const char* GetServiceVersionString(const FeatureInfo* feature_info) {
371 if (feature_info->IsWebGL2OrES3Context())
372 return "OpenGL ES 3.0 Chromium";
Geoff Langd0c755c2021-01-18 21:58:16373 else if (feature_info->IsES31ForTestingContext()) {
Jiajia Qin252a8132018-07-19 01:03:22374 return "OpenGL ES 3.1 Chromium";
375 } else
geofflang67c1fca2016-11-15 21:18:09376 return "OpenGL ES 2.0 Chromium";
377}
378
379const char* GetServiceShadingLanguageVersionString(
380 const FeatureInfo* feature_info) {
381 if (feature_info->IsWebGL2OrES3Context())
382 return "OpenGL ES GLSL ES 3.0 Chromium";
Geoff Langd0c755c2021-01-18 21:58:16383 else if (feature_info->IsES31ForTestingContext()) {
Jiajia Qin252a8132018-07-19 01:03:22384 return "OpenGL ES GLSL ES 3.1 Chromium";
385 } else
geofflang67c1fca2016-11-15 21:18:09386 return "OpenGL ES GLSL ES 1.0 Chromium";
387}
388
Geoff Langfdec674e2018-02-22 17:40:29389void LogGLDebugMessage(GLenum source,
390 GLenum type,
391 GLuint id,
392 GLenum severity,
393 GLsizei length,
394 const GLchar* message,
395 Logger* error_logger) {
James Darpinian0f56e9f32018-01-11 02:23:55396 std::string id_string = GLES2Util::GetStringEnum(id);
James Darpinian0f56e9f32018-01-11 02:23:55397 if (type == GL_DEBUG_TYPE_ERROR && source == GL_DEBUG_SOURCE_API) {
398 error_logger->LogMessage(__FILE__, __LINE__,
399 " " + id_string + ": " + message);
400 } else {
401 error_logger->LogMessage(
402 __FILE__, __LINE__,
403 std::string("GL Driver Message (") + GetDebugSourceString(source) +
404 ", " + GetDebugTypeString(type) + ", " + id_string + ", " +
405 GetDebugSeverityString(severity) + "): " + message);
406 }
geofflang326c8512016-11-03 15:11:28407}
408
Geoff Langfdec674e2018-02-22 17:40:29409void InitializeGLDebugLogging(bool log_non_errors,
410 GLDEBUGPROC callback,
411 const void* user_param) {
geofflang326c8512016-11-03 15:11:28412 glEnable(GL_DEBUG_OUTPUT);
413 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
414
James Darpinian0f56e9f32018-01-11 02:23:55415 glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE,
416 0, nullptr, GL_TRUE);
geofflang326c8512016-11-03 15:11:28417
James Darpinian0f56e9f32018-01-11 02:23:55418 if (log_non_errors) {
419 // Enable logging of medium and high severity messages
420 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0,
421 nullptr, GL_TRUE);
422 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
423 0, nullptr, GL_TRUE);
424 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
425 nullptr, GL_FALSE);
426 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
427 GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
428 }
429
Geoff Langfdec674e2018-02-22 17:40:29430 glDebugMessageCallback(callback, user_param);
geofflang326c8512016-11-03 15:11:28431}
432
Geoff Langab3a2e82017-06-12 18:53:38433bool ValidContextLostReason(GLenum reason) {
434 switch (reason) {
435 case GL_NO_ERROR:
436 case GL_GUILTY_CONTEXT_RESET_ARB:
437 case GL_INNOCENT_CONTEXT_RESET_ARB:
438 case GL_UNKNOWN_CONTEXT_RESET_ARB:
439 return true;
440 default:
441 return false;
442 }
443}
444
Geoff Langf44323ed2017-06-07 18:10:15445error::ContextLostReason GetContextLostReasonFromResetStatus(
446 GLenum reset_status) {
447 switch (reset_status) {
448 case GL_NO_ERROR:
449 // TODO(kbr): improve the precision of the error code in this case.
450 // Consider delegating to context for error code if MakeCurrent fails.
451 return error::kUnknown;
452 case GL_GUILTY_CONTEXT_RESET_ARB:
453 return error::kGuilty;
454 case GL_INNOCENT_CONTEXT_RESET_ARB:
455 return error::kInnocent;
456 case GL_UNKNOWN_CONTEXT_RESET_ARB:
457 return error::kUnknown;
458 }
459
460 NOTREACHED();
461 return error::kUnknown;
462}
463
Jonathan Backerc26060e2018-03-29 15:06:29464bool GetCompressedTexSizeInBytes(const char* function_name,
465 GLsizei width,
466 GLsizei height,
467 GLsizei depth,
468 GLenum format,
469 GLsizei* size_in_bytes,
470 ErrorState* error_state) {
471 base::CheckedNumeric<GLsizei> bytes_required(0);
472
473 switch (format) {
474 case GL_ATC_RGB_AMD:
475 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
476 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
477 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
478 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
479 case GL_ETC1_RGB8_OES:
480 bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
481 bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
482 bytes_required *= kS3TCDXT1BlockSize;
483 break;
484 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
485 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
486 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
487 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
488 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
489 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
490 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
491 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
492 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
493 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
494 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
495 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
496 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
497 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
498 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
499 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
500 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
501 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
502 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
503 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
504 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
505 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
506 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
507 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
508 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
509 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
510 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
511 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
512 const int index =
513 (format < GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
514 ? static_cast<int>(format - GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
515 : static_cast<int>(format -
516 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
517
518 const int kBlockWidth = kASTCBlockArray[index].blockWidth;
519 const int kBlockHeight = kASTCBlockArray[index].blockHeight;
520
521 bytes_required = (width + kBlockWidth - 1) / kBlockWidth;
522 bytes_required *= (height + kBlockHeight - 1) / kBlockHeight;
523
524 bytes_required *= kASTCBlockSize;
525 break;
526 }
527 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
528 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
529 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
530 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
531 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
532 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
533 bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
534 bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
535 bytes_required *= kS3TCDXT3AndDXT5BlockSize;
536 break;
537 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
538 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
539 bytes_required = std::max(width, 8);
540 bytes_required *= std::max(height, 8);
541 bytes_required *= 4;
542 bytes_required += 7;
543 bytes_required /= 8;
544 break;
545 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
546 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
547 bytes_required = std::max(width, 16);
548 bytes_required *= std::max(height, 8);
549 bytes_required *= 2;
550 bytes_required += 7;
551 bytes_required /= 8;
552 break;
553
554 // ES3 formats.
555 case GL_COMPRESSED_R11_EAC:
556 case GL_COMPRESSED_SIGNED_R11_EAC:
557 case GL_COMPRESSED_RGB8_ETC2:
558 case GL_COMPRESSED_SRGB8_ETC2:
559 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
560 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
561 bytes_required =
562 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
563 bytes_required *=
564 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
565 bytes_required *= 8;
566 bytes_required *= depth;
567 break;
568 case GL_COMPRESSED_RG11_EAC:
569 case GL_COMPRESSED_SIGNED_RG11_EAC:
570 case GL_COMPRESSED_RGBA8_ETC2_EAC:
571 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
572 bytes_required =
573 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
574 bytes_required *=
575 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
576 bytes_required *= 16;
577 bytes_required *= depth;
578 break;
shrekshaode2f6f32020-02-07 02:39:44579 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
580 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
581 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
582 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
583 bytes_required = (width + kBPTCBlockWidth - 1) / kBPTCBlockWidth;
584 bytes_required *= (height + kBPTCBlockHeight - 1) / kBPTCBlockHeight;
585 bytes_required *= 16;
586 bytes_required *= depth;
587 break;
shrekshao3c058332020-02-11 00:00:12588 case GL_COMPRESSED_RED_RGTC1_EXT:
589 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
shrekshaoeae7c512020-02-11 22:06:27590 bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
591 bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
592 bytes_required *= 8;
593 bytes_required *= depth;
594 break;
shrekshao3c058332020-02-11 00:00:12595 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
596 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
597 bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
598 bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
shrekshaoeae7c512020-02-11 22:06:27599 bytes_required *= 16;
shrekshao3c058332020-02-11 00:00:12600 bytes_required *= depth;
601 break;
Jonathan Backerc26060e2018-03-29 15:06:29602 default:
Geoff Lang72fe4762018-10-19 15:11:36603 if (function_name && error_state) {
604 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name, format,
605 "format");
606 }
Jonathan Backerc26060e2018-03-29 15:06:29607 return false;
608 }
609
610 if (!bytes_required.IsValid()) {
Geoff Lang72fe4762018-10-19 15:11:36611 if (function_name && error_state) {
612 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
613 "invalid size");
614 }
Jonathan Backerc26060e2018-03-29 15:06:29615 return false;
616 }
617
618 *size_in_bytes = bytes_required.ValueOrDefault(0);
619 return true;
620}
621
shrekshaofb226c242020-02-19 00:37:12622bool ValidateCompressedFormatTarget(GLenum target, GLenum format) {
623 if (target == GL_TEXTURE_3D) {
624 // Formats not supporting 3D Tex
625 switch (format) {
626 // ES 3.1, Section 8.7, page 169.
627 case GL_COMPRESSED_R11_EAC:
628 case GL_COMPRESSED_SIGNED_R11_EAC:
629 case GL_COMPRESSED_RG11_EAC:
630 case GL_COMPRESSED_SIGNED_RG11_EAC:
631 case GL_COMPRESSED_RGB8_ETC2:
632 case GL_COMPRESSED_SRGB8_ETC2:
633 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
634 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
635 case GL_COMPRESSED_RGBA8_ETC2_EAC:
636 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
shrekshaofb226c242020-02-19 00:37:12637 // GL_EXT_texture_compression_s3tc
638 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
639 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
640 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
641 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
642 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
643 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
644 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
645 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
646 // GL_EXT_texture_compression_rgtc
647 case GL_COMPRESSED_RED_RGTC1_EXT:
648 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
649 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
650 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
651 return false;
shrekshaoad4525482020-03-12 00:30:55652 // GL_KHR_texture_compression_astc_hdr, TEXTURE_3D is not supported
653 // without HDR profile. This is guaranteed to be validated beforehand
654 // in GLES2DecoderImpl::TexStorageImpl before calling this.
shrekshaofb226c242020-02-19 00:37:12655 default:
656 break;
657 }
658 }
659
660 return true;
661}
662
Daniel Bratell60acbb592018-07-26 09:13:14663bool ValidateCompressedTexSubDimensions(GLenum target,
664 GLint level,
665 GLint xoffset,
666 GLint yoffset,
667 GLint zoffset,
668 GLsizei width,
669 GLsizei height,
670 GLsizei depth,
671 GLenum format,
672 Texture* texture,
Daniel Bratell60acbb592018-07-26 09:13:14673 const char** error_message) {
shrekshaofb226c242020-02-19 00:37:12674 if (!ValidateCompressedFormatTarget(target, format)) {
675 *error_message = "target invalid for format";
676 return false;
677 }
678
Daniel Bratell60acbb592018-07-26 09:13:14679 if (xoffset < 0 || yoffset < 0 || zoffset < 0) {
680 *error_message = "x/y/z offset < 0";
681 return false;
682 }
683
684 switch (format) {
685 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
686 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
687 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
688 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
689 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
690 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
691 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
692 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: {
693 const int kBlockWidth = 4;
694 const int kBlockHeight = 4;
695 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
696 *error_message = "xoffset or yoffset not multiple of 4";
697 return false;
698 }
699 GLsizei tex_width = 0;
700 GLsizei tex_height = 0;
701 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
702 nullptr) ||
703 width - xoffset > tex_width || height - yoffset > tex_height) {
704 *error_message = "dimensions out of range";
705 return false;
706 }
707 if ((((width % kBlockWidth) != 0) && (width + xoffset != tex_width)) ||
708 (((height % kBlockHeight) != 0) &&
709 (height + yoffset != tex_height))) {
710 *error_message = "dimensions do not align to a block boundary";
711 return false;
712 }
713 return true;
714 }
715 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
716 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
717 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
718 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
719 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
720 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
721 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
722 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
723 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
724 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
725 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
726 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
727 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
728 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
729 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
730 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
731 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
732 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
733 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
734 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
735 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
736 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
737 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
738 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
739 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
740 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
741 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
742 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
743 const int index =
744 (format < GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
745 ? static_cast<int>(format - GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
746 : static_cast<int>(format -
747 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
748
749 const int kBlockWidth = kASTCBlockArray[index].blockWidth;
750 const int kBlockHeight = kASTCBlockArray[index].blockHeight;
751
752 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
753 *error_message = "xoffset or yoffset not multiple of 4";
754 return false;
755 }
756 GLsizei tex_width = 0;
757 GLsizei tex_height = 0;
758 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
759 nullptr) ||
760 width - xoffset > tex_width || height - yoffset > tex_height) {
761 *error_message = "dimensions out of range";
762 return false;
763 }
764 if ((((width % kBlockWidth) != 0) && (width + xoffset != tex_width)) ||
765 (((height % kBlockHeight) != 0) &&
766 (height + yoffset != tex_height))) {
767 *error_message = "dimensions do not align to a block boundary";
768 return false;
769 }
770 return true;
771 }
772 case GL_ATC_RGB_AMD:
773 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
774 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
775 *error_message = "not supported for ATC textures";
776 return false;
777 }
778 case GL_ETC1_RGB8_OES: {
779 *error_message = "not supported for ECT1_RGB8_OES textures";
780 return false;
781 }
782 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
783 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
784 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
785 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
786 if ((xoffset != 0) || (yoffset != 0)) {
787 *error_message = "xoffset and yoffset must be zero";
788 return false;
789 }
790 GLsizei tex_width = 0;
791 GLsizei tex_height = 0;
792 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
793 nullptr) ||
794 width != tex_width || height != tex_height) {
795 *error_message =
796 "dimensions must match existing texture level dimensions";
797 return false;
798 }
799 return ValidateCompressedTexDimensions(target, level, width, height, 1,
Geoff Lang1cabc702019-04-26 01:30:18800 format, error_message);
Daniel Bratell60acbb592018-07-26 09:13:14801 }
802
803 // ES3 formats
804 case GL_COMPRESSED_R11_EAC:
805 case GL_COMPRESSED_SIGNED_R11_EAC:
806 case GL_COMPRESSED_RG11_EAC:
807 case GL_COMPRESSED_SIGNED_RG11_EAC:
808 case GL_COMPRESSED_RGB8_ETC2:
809 case GL_COMPRESSED_SRGB8_ETC2:
810 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
811 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
812 case GL_COMPRESSED_RGBA8_ETC2_EAC:
shrekshao41abf0c2020-02-19 02:09:42813 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
shrekshao41abf0c2020-02-19 02:09:42814 case GL_COMPRESSED_RED_RGTC1_EXT:
815 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
816 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
817 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: {
shrekshaob70dfea2020-07-08 23:17:09818 if (target == GL_TEXTURE_3D) {
819 *error_message = "target == GL_TEXTURE_3D is not allowed";
820 return false;
821 }
Roland Bock445b8152022-01-05 08:17:25822 [[fallthrough]];
shrekshaob70dfea2020-07-08 23:17:09823 }
824 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
825 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
826 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
827 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: {
Daniel Bratell60acbb592018-07-26 09:13:14828 const int kBlockSize = 4;
829 GLsizei tex_width, tex_height;
shrekshaob70dfea2020-07-08 23:17:09830 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
Daniel Bratell60acbb592018-07-26 09:13:14831 nullptr) ||
832 (xoffset % kBlockSize) || (yoffset % kBlockSize) ||
833 ((width % kBlockSize) && xoffset + width != tex_width) ||
834 ((height % kBlockSize) && yoffset + height != tex_height)) {
835 *error_message =
836 "dimensions must match existing texture level dimensions";
837 return false;
838 }
839 return true;
840 }
841 default:
842 *error_message = "unknown compressed texture format";
843 return false;
844 }
845}
846
847bool ValidateCompressedTexDimensions(GLenum target,
848 GLint level,
849 GLsizei width,
850 GLsizei height,
851 GLsizei depth,
852 GLenum format,
Daniel Bratell60acbb592018-07-26 09:13:14853 const char** error_message) {
shrekshaofb226c242020-02-19 00:37:12854 if (!ValidateCompressedFormatTarget(target, format)) {
855 *error_message = "target invalid for format";
856 return false;
857 }
Daniel Bratell60acbb592018-07-26 09:13:14858 switch (format) {
859 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
860 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
861 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
862 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
863 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
864 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
865 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
866 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
Geoff Lang1cabc702019-04-26 01:30:18867 if (!IsValidS3TCSizeForWebGLAndANGLE(level, width) ||
868 !IsValidS3TCSizeForWebGLAndANGLE(level, height)) {
Daniel Bratell60acbb592018-07-26 09:13:14869 *error_message = "width or height invalid for level";
870 return false;
871 }
872 return true;
873 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
874 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
875 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
876 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
877 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
878 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
879 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
880 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
881 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
882 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
883 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
884 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
885 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
886 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
887 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
888 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
889 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
890 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
891 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
892 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
893 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
894 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
895 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
896 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
897 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
898 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
899 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
900 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
901 case GL_ATC_RGB_AMD:
902 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
903 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
904 case GL_ETC1_RGB8_OES:
Daniel Bratell60acbb592018-07-26 09:13:14905 if (width <= 0 || height <= 0) {
906 *error_message = "width or height invalid for level";
907 return false;
908 }
909 return true;
910 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
911 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
912 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
913 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
Daniel Bratell60acbb592018-07-26 09:13:14914 if (!IsValidPVRTCSize(level, width) || !IsValidPVRTCSize(level, height)) {
915 *error_message = "width or height invalid for level";
916 return false;
917 }
918 return true;
919
920 // ES3 formats.
921 case GL_COMPRESSED_R11_EAC:
922 case GL_COMPRESSED_SIGNED_R11_EAC:
923 case GL_COMPRESSED_RG11_EAC:
924 case GL_COMPRESSED_SIGNED_RG11_EAC:
925 case GL_COMPRESSED_RGB8_ETC2:
926 case GL_COMPRESSED_SRGB8_ETC2:
927 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
928 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
929 case GL_COMPRESSED_RGBA8_ETC2_EAC:
930 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
931 if (width < 0 || height < 0 || depth < 0) {
932 *error_message = "width, height, or depth invalid";
933 return false;
934 }
Daniel Bratell60acbb592018-07-26 09:13:14935 return true;
shrekshaode2f6f32020-02-07 02:39:44936 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
937 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
938 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
939 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
940 if (width < 0 || height < 0 || depth < 0) {
941 *error_message = "width, height, or depth invalid";
942 return false;
943 }
shrekshaob70dfea2020-07-08 23:17:09944 if (level == 0 &&
945 !(width % kBPTCBlockWidth == 0 && height % kBPTCBlockHeight == 0)) {
shrekshaode2f6f32020-02-07 02:39:44946 *error_message = "width or height is not a multiple of four";
947 return false;
948 }
949 return true;
shrekshao3c058332020-02-11 00:00:12950 case GL_COMPRESSED_RED_RGTC1_EXT:
951 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
952 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
953 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
954 if (width < 0 || height < 0 || depth < 0) {
955 *error_message = "width, height, or depth invalid";
956 return false;
957 }
shrekshaob70dfea2020-07-08 23:17:09958 if (level == 0 &&
959 !(width % kRGTCBlockWidth == 0 && height % kRGTCBlockHeight == 0)) {
shrekshao3c058332020-02-11 00:00:12960 *error_message = "width or height is not a multiple of four";
961 return false;
962 }
963 return true;
Daniel Bratell60acbb592018-07-26 09:13:14964 default:
965 return false;
966 }
967}
968
Jonathan Backer8629c392018-04-04 23:01:03969bool ValidateCopyTexFormatHelper(const FeatureInfo* feature_info,
970 GLenum internal_format,
971 GLenum read_format,
972 GLenum read_type,
973 std::string* output_error_msg) {
974 DCHECK(output_error_msg);
975 if (read_format == 0) {
976 *output_error_msg = std::string("no valid color image");
977 return false;
978 }
Albert Chaulka8b2ab52020-07-22 18:47:14979 // YUV formats are not valid for CopyTex[Sub]Image.
980 if (internal_format == GL_RGB_YCRCB_420_CHROMIUM ||
981 internal_format == GL_RGB_YCBCR_420V_CHROMIUM ||
Christopher Cameron56f47c4a2020-12-02 23:17:50982 internal_format == GL_RGB_YCBCR_P010_CHROMIUM ||
Albert Chaulka8b2ab52020-07-22 18:47:14983 read_format == GL_RGB_YCRCB_420_CHROMIUM ||
Christopher Cameron56f47c4a2020-12-02 23:17:50984 read_format == GL_RGB_YCBCR_420V_CHROMIUM ||
985 read_format == GL_RGB_YCBCR_P010_CHROMIUM) {
Albert Chaulka8b2ab52020-07-22 18:47:14986 return false;
987 }
Jonathan Backer8629c392018-04-04 23:01:03988 // Check we have compatible formats.
989 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format);
990 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
991 if (!channels_needed ||
992 (channels_needed & channels_exist) != channels_needed) {
993 *output_error_msg = std::string("incompatible format");
994 return false;
995 }
Jiajia Qin252a8132018-07-19 01:03:22996 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
Jonathan Backer8629c392018-04-04 23:01:03997 GLint color_encoding =
998 GLES2Util::GetColorEncodingFromInternalFormat(read_format);
999 bool float_mismatch = feature_info->ext_color_buffer_float_available()
1000 ? (GLES2Util::IsIntegerFormat(internal_format) !=
1001 GLES2Util::IsIntegerFormat(read_format))
1002 : GLES2Util::IsFloatFormat(internal_format);
1003 if (color_encoding !=
1004 GLES2Util::GetColorEncodingFromInternalFormat(internal_format) ||
1005 float_mismatch ||
1006 (GLES2Util::IsSignedIntegerFormat(internal_format) !=
1007 GLES2Util::IsSignedIntegerFormat(read_format)) ||
1008 (GLES2Util::IsUnsignedIntegerFormat(internal_format) !=
1009 GLES2Util::IsUnsignedIntegerFormat(read_format))) {
1010 *output_error_msg = std::string("incompatible format");
1011 return false;
1012 }
1013 }
1014 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
1015 *output_error_msg =
1016 std::string("can not be used with depth or stencil textures");
1017 return false;
1018 }
Jiajia Qin252a8132018-07-19 01:03:221019 if (feature_info->IsWebGL2OrES3OrHigherContext() ||
Jonathan Backer8629c392018-04-04 23:01:031020 (feature_info->feature_flags().chromium_color_buffer_float_rgb &&
1021 internal_format == GL_RGB32F) ||
1022 (feature_info->feature_flags().chromium_color_buffer_float_rgba &&
1023 internal_format == GL_RGBA32F)) {
1024 if (GLES2Util::IsSizedColorFormat(internal_format)) {
1025 int sr, sg, sb, sa;
1026 GLES2Util::GetColorFormatComponentSizes(read_format, read_type, &sr, &sg,
1027 &sb, &sa);
1028 DCHECK(sr > 0 || sg > 0 || sb > 0 || sa > 0);
1029 int dr, dg, db, da;
1030 GLES2Util::GetColorFormatComponentSizes(internal_format, 0, &dr, &dg, &db,
1031 &da);
1032 DCHECK(dr > 0 || dg > 0 || db > 0 || da > 0);
1033 if ((dr > 0 && sr != dr) || (dg > 0 && sg != dg) ||
1034 (db > 0 && sb != db) || (da > 0 && sa != da)) {
1035 *output_error_msg = std::string("incompatible color component sizes");
1036 return false;
1037 }
1038 }
1039 }
1040 return true;
1041}
1042
1043CopyTextureMethod GetCopyTextureCHROMIUMMethod(const FeatureInfo* feature_info,
1044 GLenum source_target,
1045 GLint source_level,
1046 GLenum source_internal_format,
1047 GLenum source_type,
1048 GLenum dest_target,
1049 GLint dest_level,
1050 GLenum dest_internal_format,
1051 bool flip_y,
1052 bool premultiply_alpha,
Corentin Wallezcacc4172021-12-03 14:40:221053 bool unpremultiply_alpha) {
Jonathan Backer8629c392018-04-04 23:01:031054 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
1055 bool source_format_color_renderable =
1056 Texture::ColorRenderable(feature_info, source_internal_format, false);
1057 bool dest_format_color_renderable =
1058 Texture::ColorRenderable(feature_info, dest_internal_format, false);
1059 std::string output_error_msg;
1060
1061 switch (dest_internal_format) {
Xiaohan Wangfa22d3e2022-01-15 02:02:431062#if BUILDFLAG(IS_MAC)
Jonathan Backer8629c392018-04-04 23:01:031063 // RGB5_A1 is not color-renderable on NVIDIA Mac, see
1064 // https://crbug.com/676209.
1065 case GL_RGB5_A1:
1066 return CopyTextureMethod::DRAW_AND_READBACK;
1067#endif
1068 // RGB9_E5 isn't accepted by glCopyTexImage2D if underlying context is ES.
1069 case GL_RGB9_E5:
1070 if (feature_info->gl_version_info().is_es)
1071 return CopyTextureMethod::DRAW_AND_READBACK;
1072 break;
1073 // SRGB format has color-space conversion issue. WebGL spec doesn't define
1074 // clearly if linear-to-srgb color space conversion is required or not when
1075 // uploading DOM elements to SRGB textures. WebGL conformance test expects
1076 // no linear-to-srgb conversion, while current GPU path for
1077 // CopyTextureCHROMIUM does the conversion. Do a fallback path before the
1078 // issue is resolved. see https://github.com/KhronosGroup/WebGL/issues/2165.
1079 // TODO(qiankun.miao@intel.com): revisit this once the above issue is
1080 // resolved.
1081 case GL_SRGB_EXT:
1082 case GL_SRGB_ALPHA_EXT:
1083 case GL_SRGB8:
1084 case GL_SRGB8_ALPHA8:
1085 if (feature_info->IsWebGLContext())
1086 return CopyTextureMethod::DRAW_AND_READBACK;
1087 break;
1088 default:
1089 break;
1090 }
1091
1092 // CopyTexImage* should not allow internalformat of GL_BGRA_EXT and
1093 // GL_BGRA8_EXT. https://crbug.com/663086.
1094 bool copy_tex_image_format_valid =
1095 source_internal_format != GL_BGRA_EXT &&
1096 dest_internal_format != GL_BGRA_EXT &&
1097 source_internal_format != GL_BGRA8_EXT &&
1098 dest_internal_format != GL_BGRA8_EXT &&
1099 ValidateCopyTexFormatHelper(feature_info, dest_internal_format,
1100 source_internal_format, source_type,
1101 &output_error_msg);
1102
Antoine Labour4885296a2019-05-09 02:38:391103 // The ES3 spec is vague about whether or not glCopyTexImage2D from a
1104 // GL_RGB10_A2 attachment to an unsized internal format is valid. Most drivers
1105 // interpreted the explicit call out as not valid (and dEQP actually checks
1106 // this), so avoid DIRECT_COPY in that case.
1107 if (feature_info->gl_version_info().is_es &&
1108 source_internal_format == GL_RGB10_A2 &&
1109 dest_internal_format != source_internal_format)
1110 copy_tex_image_format_valid = false;
1111
Jonathan Backer8629c392018-04-04 23:01:031112 // TODO(qiankun.miao@intel.com): for WebGL 2.0 or OpenGL ES 3.0, both
1113 // DIRECT_DRAW path for dest_level > 0 and DIRECT_COPY path for source_level >
1114 // 0 are not available due to a framebuffer completeness bug:
1115 // https://crbug.com/678526. Once the bug is fixed, the limitation for WebGL
1116 // 2.0 and OpenGL ES 3.0 can be lifted. For WebGL 1.0 or OpenGL ES 2.0,
1117 // DIRECT_DRAW path isn't available for dest_level > 0 due to level > 0 isn't
1118 // supported by glFramebufferTexture2D in ES2 context. DIRECT_DRAW path isn't
1119 // available for cube map dest texture either due to it may be cube map
1120 // incomplete. Go to DRAW_AND_COPY path in these cases.
1121 if (source_target == GL_TEXTURE_2D &&
1122 (dest_target == GL_TEXTURE_2D || dest_target == GL_TEXTURE_CUBE_MAP) &&
1123 source_format_color_renderable && copy_tex_image_format_valid &&
Corentin Wallezcacc4172021-12-03 14:40:221124 source_level == 0 && !flip_y && !premultiply_alpha_change) {
shrekshaob437fb192020-01-30 07:39:571125 auto source_texture_type = GLES2Util::GetGLReadPixelsImplementationType(
1126 source_internal_format, source_target);
1127 auto dest_texture_type = GLES2Util::GetGLReadPixelsImplementationType(
1128 dest_internal_format, dest_target);
1129 if (source_texture_type != GL_UNSIGNED_SHORT ||
1130 source_texture_type == dest_texture_type) {
1131 // https://crbug.com/1042239. As it is stated in the latest OpenGL ES 3.2
1132 // spec (Oct 22, 2019) it is optional for implementation to support
1133 // conversion between unmatched source and dest effective internal format.
1134 // R16 to R16F direct copy failure is seen on Android Nvidia shield
1135 // devices. So we won't use DIRECT_COPY for this format.
1136 return CopyTextureMethod::DIRECT_COPY;
1137 }
1138 }
Jonathan Backer8629c392018-04-04 23:01:031139 if (dest_format_color_renderable && dest_level == 0 &&
1140 dest_target != GL_TEXTURE_CUBE_MAP)
1141 return CopyTextureMethod::DIRECT_DRAW;
1142
1143 // Draw to a fbo attaching level 0 of an intermediate texture,
1144 // then copy from the fbo to dest texture level with glCopyTexImage2D.
1145 return CopyTextureMethod::DRAW_AND_COPY;
1146}
1147
Jonathan Backer4cb165c82018-07-03 20:25:331148bool ValidateCopyTextureCHROMIUMInternalFormats(const FeatureInfo* feature_info,
1149 GLenum source_internal_format,
1150 GLenum dest_internal_format,
1151 std::string* output_error_msg) {
1152 bool valid_dest_format = false;
1153 // TODO(qiankun.miao@intel.com): ALPHA, LUMINANCE and LUMINANCE_ALPHA formats
1154 // are not supported on GL core profile. See https://crbug.com/577144. Enable
1155 // the workaround for glCopyTexImage and glCopyTexSubImage in
1156 // gles2_cmd_copy_tex_image.cc for glCopyTextureCHROMIUM implementation.
1157 switch (dest_internal_format) {
1158 case GL_RGB:
1159 case GL_RGBA:
1160 case GL_RGB8:
1161 case GL_RGBA8:
1162 valid_dest_format = true;
1163 break;
1164 case GL_BGRA_EXT:
1165 case GL_BGRA8_EXT:
1166 valid_dest_format =
1167 feature_info->feature_flags().ext_texture_format_bgra8888;
1168 break;
1169 case GL_SRGB_EXT:
1170 case GL_SRGB_ALPHA_EXT:
1171 valid_dest_format = feature_info->feature_flags().ext_srgb;
1172 break;
1173 case GL_R8:
1174 case GL_R8UI:
1175 case GL_RG8:
1176 case GL_RG8UI:
1177 case GL_SRGB8:
1178 case GL_RGB565:
1179 case GL_RGB8UI:
1180 case GL_SRGB8_ALPHA8:
1181 case GL_RGB5_A1:
1182 case GL_RGBA4:
1183 case GL_RGBA8UI:
1184 case GL_RGB10_A2:
Jiajia Qin252a8132018-07-19 01:03:221185 valid_dest_format = feature_info->IsWebGL2OrES3OrHigherContext();
Jonathan Backer4cb165c82018-07-03 20:25:331186 break;
1187 case GL_RGB9_E5:
1188 case GL_R16F:
1189 case GL_R32F:
1190 case GL_RG16F:
1191 case GL_RG32F:
1192 case GL_RGB16F:
1193 case GL_RGBA16F:
1194 case GL_R11F_G11F_B10F:
1195 valid_dest_format = feature_info->ext_color_buffer_float_available();
1196 break;
1197 case GL_RGB32F:
1198 valid_dest_format =
1199 feature_info->ext_color_buffer_float_available() ||
1200 feature_info->feature_flags().chromium_color_buffer_float_rgb;
1201 break;
1202 case GL_RGBA32F:
1203 valid_dest_format =
1204 feature_info->ext_color_buffer_float_available() ||
1205 feature_info->feature_flags().chromium_color_buffer_float_rgba;
1206 break;
1207 case GL_ALPHA:
1208 case GL_LUMINANCE:
1209 case GL_LUMINANCE_ALPHA:
1210 valid_dest_format = true;
1211 break;
1212 default:
1213 valid_dest_format = false;
1214 break;
1215 }
1216
1217 // TODO(aleksandar.stojiljkovic): Use sized internal formats:
1218 // https://crbug.com/628064
1219 bool valid_source_format =
1220 source_internal_format == GL_RED || source_internal_format == GL_ALPHA ||
1221 source_internal_format == GL_RGB || source_internal_format == GL_RGBA ||
1222 source_internal_format == GL_RGB8 || source_internal_format == GL_RGBA8 ||
1223 source_internal_format == GL_LUMINANCE ||
1224 source_internal_format == GL_LUMINANCE_ALPHA ||
1225 source_internal_format == GL_BGRA_EXT ||
1226 source_internal_format == GL_BGRA8_EXT ||
Andres Calderon Jaramillo2b20c872022-11-23 17:03:261227 source_internal_format == GL_RGB_YCRCB_420_CHROMIUM ||
Jonathan Backer4cb165c82018-07-03 20:25:331228 source_internal_format == GL_RGB_YCBCR_420V_CHROMIUM ||
1229 source_internal_format == GL_RGB_YCBCR_422_CHROMIUM ||
Miguel Casas1deef582019-06-12 22:36:371230 source_internal_format == GL_RGB_YCBCR_P010_CHROMIUM ||
Miguel Casas94f82b22019-01-31 21:20:571231 source_internal_format == GL_R16_EXT ||
shrekshaob437fb192020-01-30 07:39:571232 source_internal_format == GL_RG16_EXT ||
1233 source_internal_format == GL_RGBA16_EXT ||
Miguel Casas94f82b22019-01-31 21:20:571234 source_internal_format == GL_RGB10_A2;
Jonathan Backer4cb165c82018-07-03 20:25:331235 if (!valid_source_format) {
1236 *output_error_msg = "invalid source internal format " +
1237 GLES2Util::GetStringEnum(source_internal_format);
1238 return false;
1239 }
1240 if (!valid_dest_format) {
1241 *output_error_msg = "invalid dest internal format " +
1242 GLES2Util::GetStringEnum(dest_internal_format);
1243 return false;
1244 }
1245
1246 return true;
1247}
1248
Geoff Lang18c8f3d82019-07-08 23:20:331249GLenum GetTextureBindingQuery(GLenum texture_type) {
1250 switch (texture_type) {
1251 case GL_TEXTURE_2D:
1252 return GL_TEXTURE_BINDING_2D;
1253 case GL_TEXTURE_2D_ARRAY:
1254 return GL_TEXTURE_BINDING_2D_ARRAY;
1255 case GL_TEXTURE_2D_MULTISAMPLE:
1256 return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
1257 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1258 return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
1259 case GL_TEXTURE_3D:
1260 return GL_TEXTURE_BINDING_3D;
1261 case GL_TEXTURE_EXTERNAL_OES:
1262 return GL_TEXTURE_BINDING_EXTERNAL_OES;
1263 case GL_TEXTURE_RECTANGLE:
1264 return GL_TEXTURE_BINDING_RECTANGLE;
1265 case GL_TEXTURE_CUBE_MAP:
1266 return GL_TEXTURE_BINDING_CUBE_MAP;
1267 default:
1268 NOTREACHED();
1269 return 0;
1270 }
1271}
1272
Geoff Lang657134d12019-07-18 18:56:471273bool GetGFXBufferFormat(GLenum internal_format, gfx::BufferFormat* out_format) {
1274 switch (internal_format) {
1275 case GL_RGBA8_OES:
1276 *out_format = gfx::BufferFormat::RGBA_8888;
1277 return true;
1278 case GL_BGRA8_EXT:
1279 *out_format = gfx::BufferFormat::BGRA_8888;
1280 return true;
1281 case GL_RGBA16F_EXT:
1282 *out_format = gfx::BufferFormat::RGBA_F16;
1283 return true;
1284 case GL_R8_EXT:
1285 *out_format = gfx::BufferFormat::R_8;
1286 return true;
1287 default:
1288 return false;
1289 }
1290}
1291
shrekshaoad4525482020-03-12 00:30:551292bool IsASTCFormat(GLenum internal_format) {
1293 switch (internal_format) {
1294 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
1295 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
1296 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
1297 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
1298 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
1299 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1300 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
1301 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
1302 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
1303 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
1304 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
1305 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
1306 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
1307 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
1308 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
1309 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
1310 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
1311 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
1312 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
1313 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
1314 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
1315 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
1316 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
1317 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
1318 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
1319 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
1320 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
1321 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
1322 return true;
1323 default:
1324 break;
1325 }
1326 return false;
1327}
1328
1329// This is only called in Texture::SetLevelInfo in texture_manager.cc
1330// where there is no direct access to decoder->IsCompressedTextureFormat
1331// or feature_info->validators()->compressed_texture_format.IsValid
1332bool IsCompressedTextureFormat(GLenum internal_format) {
1333 switch (internal_format) {
1334 // S3TC
1335 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1336 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1337 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1338 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1339 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1340 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1341 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1342 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1343 // ASTC
1344 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
1345 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
1346 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
1347 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
1348 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
1349 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1350 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
1351 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
1352 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
1353 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
1354 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
1355 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
1356 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
1357 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
1358 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
1359 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
1360 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
1361 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
1362 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
1363 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
1364 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
1365 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
1366 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
1367 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
1368 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
1369 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
1370 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
1371 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
1372 // BPTC
1373 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
1374 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
1375 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
1376 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
1377 // RGTC
1378 case GL_COMPRESSED_RED_RGTC1_EXT:
1379 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
1380 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
1381 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
1382 // ETC2/EAC
1383 case GL_COMPRESSED_R11_EAC:
1384 case GL_COMPRESSED_SIGNED_R11_EAC:
1385 case GL_COMPRESSED_RGB8_ETC2:
1386 case GL_COMPRESSED_SRGB8_ETC2:
1387 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1388 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1389 case GL_COMPRESSED_RG11_EAC:
1390 case GL_COMPRESSED_SIGNED_RG11_EAC:
1391 case GL_COMPRESSED_RGBA8_ETC2_EAC:
1392 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1393 // ETC1
1394 case GL_ETC1_RGB8_OES:
1395 // PVRTC
1396 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
1397 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
1398 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
1399 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
1400 // ATC
1401 case GL_ATC_RGB_AMD:
1402 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
1403 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
1404 return true;
1405 default:
1406 break;
1407 }
1408 return false;
1409}
1410
Saifuddin Hitawala151bf3bf2022-07-19 19:03:141411Texture* CreateGLES2TextureWithLightRef(GLuint service_id, GLenum target) {
1412 Texture* texture = new Texture(service_id);
1413 texture->SetLightweightRef();
1414 texture->SetTarget(target, 1 /*max_levels=*/);
1415 texture->set_min_filter(GL_LINEAR);
1416 texture->set_mag_filter(GL_LINEAR);
1417 texture->set_wrap_t(GL_CLAMP_TO_EDGE);
1418 texture->set_wrap_s(GL_CLAMP_TO_EDGE);
1419 return texture;
1420}
1421
junov0cad1f42016-01-07 21:48:511422} // namespace gles2
1423} // namespace gpu