blob: 93b93eccb1b70a531a7924d94c142afab8606889 [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);
James Darpinian0f56e9f32018-01-11 02:23:55420 if (type == GL_DEBUG_TYPE_ERROR && source == GL_DEBUG_SOURCE_API) {
421 error_logger->LogMessage(__FILE__, __LINE__,
422 " " + id_string + ": " + message);
423 } else {
424 error_logger->LogMessage(
425 __FILE__, __LINE__,
426 std::string("GL Driver Message (") + GetDebugSourceString(source) +
427 ", " + GetDebugTypeString(type) + ", " + id_string + ", " +
428 GetDebugSeverityString(severity) + "): " + message);
429 }
geofflang326c8512016-11-03 15:11:28430}
431
Geoff Langfdec674e2018-02-22 17:40:29432void InitializeGLDebugLogging(bool log_non_errors,
433 GLDEBUGPROC callback,
434 const void* user_param) {
geofflang326c8512016-11-03 15:11:28435 glEnable(GL_DEBUG_OUTPUT);
436 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
437
James Darpinian0f56e9f32018-01-11 02:23:55438 glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE,
439 0, nullptr, GL_TRUE);
geofflang326c8512016-11-03 15:11:28440
James Darpinian0f56e9f32018-01-11 02:23:55441 if (log_non_errors) {
442 // Enable logging of medium and high severity messages
443 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0,
444 nullptr, GL_TRUE);
445 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
446 0, nullptr, GL_TRUE);
447 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
448 nullptr, GL_FALSE);
449 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
450 GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
451 }
452
Geoff Langfdec674e2018-02-22 17:40:29453 glDebugMessageCallback(callback, user_param);
geofflang326c8512016-11-03 15:11:28454}
455
Geoff Langab3a2e82017-06-12 18:53:38456bool ValidContextLostReason(GLenum reason) {
457 switch (reason) {
458 case GL_NO_ERROR:
459 case GL_GUILTY_CONTEXT_RESET_ARB:
460 case GL_INNOCENT_CONTEXT_RESET_ARB:
461 case GL_UNKNOWN_CONTEXT_RESET_ARB:
462 return true;
463 default:
464 return false;
465 }
466}
467
Geoff Langf44323ed2017-06-07 18:10:15468error::ContextLostReason GetContextLostReasonFromResetStatus(
469 GLenum reset_status) {
470 switch (reset_status) {
471 case GL_NO_ERROR:
472 // TODO(kbr): improve the precision of the error code in this case.
473 // Consider delegating to context for error code if MakeCurrent fails.
474 return error::kUnknown;
475 case GL_GUILTY_CONTEXT_RESET_ARB:
476 return error::kGuilty;
477 case GL_INNOCENT_CONTEXT_RESET_ARB:
478 return error::kInnocent;
479 case GL_UNKNOWN_CONTEXT_RESET_ARB:
480 return error::kUnknown;
481 }
482
Peter BostrΓΆma11556e2024-10-31 04:49:10483 NOTREACHED();
Geoff Langf44323ed2017-06-07 18:10:15484}
485
Jonathan Backerc26060e2018-03-29 15:06:29486bool GetCompressedTexSizeInBytes(const char* function_name,
487 GLsizei width,
488 GLsizei height,
489 GLsizei depth,
490 GLenum format,
491 GLsizei* size_in_bytes,
492 ErrorState* error_state) {
493 base::CheckedNumeric<GLsizei> bytes_required(0);
494
495 switch (format) {
496 case GL_ATC_RGB_AMD:
497 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
498 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
499 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
500 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
501 case GL_ETC1_RGB8_OES:
502 bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
503 bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
504 bytes_required *= kS3TCDXT1BlockSize;
505 break;
506 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
507 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
508 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
509 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
510 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
511 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
512 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
513 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
514 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
515 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
516 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
517 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
518 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
519 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
520 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
521 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
522 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
523 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
524 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
525 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
526 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
527 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
528 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
529 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
530 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
531 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
532 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
533 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
534 const int index =
535 (format < GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
536 ? static_cast<int>(format - GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
537 : static_cast<int>(format -
538 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
539
540 const int kBlockWidth = kASTCBlockArray[index].blockWidth;
541 const int kBlockHeight = kASTCBlockArray[index].blockHeight;
542
543 bytes_required = (width + kBlockWidth - 1) / kBlockWidth;
544 bytes_required *= (height + kBlockHeight - 1) / kBlockHeight;
545
546 bytes_required *= kASTCBlockSize;
547 break;
548 }
549 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
550 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
551 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
552 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
553 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
554 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
555 bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
556 bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
557 bytes_required *= kS3TCDXT3AndDXT5BlockSize;
558 break;
559 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
560 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
561 bytes_required = std::max(width, 8);
562 bytes_required *= std::max(height, 8);
563 bytes_required *= 4;
564 bytes_required += 7;
565 bytes_required /= 8;
566 break;
567 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
568 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
569 bytes_required = std::max(width, 16);
570 bytes_required *= std::max(height, 8);
571 bytes_required *= 2;
572 bytes_required += 7;
573 bytes_required /= 8;
574 break;
575
576 // ES3 formats.
577 case GL_COMPRESSED_R11_EAC:
578 case GL_COMPRESSED_SIGNED_R11_EAC:
579 case GL_COMPRESSED_RGB8_ETC2:
580 case GL_COMPRESSED_SRGB8_ETC2:
581 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
582 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
583 bytes_required =
584 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
585 bytes_required *=
586 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
587 bytes_required *= 8;
588 bytes_required *= depth;
589 break;
590 case GL_COMPRESSED_RG11_EAC:
591 case GL_COMPRESSED_SIGNED_RG11_EAC:
592 case GL_COMPRESSED_RGBA8_ETC2_EAC:
593 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
594 bytes_required =
595 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
596 bytes_required *=
597 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
598 bytes_required *= 16;
599 bytes_required *= depth;
600 break;
shrekshaode2f6f32020-02-07 02:39:44601 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
602 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
603 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
604 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
605 bytes_required = (width + kBPTCBlockWidth - 1) / kBPTCBlockWidth;
606 bytes_required *= (height + kBPTCBlockHeight - 1) / kBPTCBlockHeight;
607 bytes_required *= 16;
608 bytes_required *= depth;
609 break;
shrekshao3c058332020-02-11 00:00:12610 case GL_COMPRESSED_RED_RGTC1_EXT:
611 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
shrekshaoeae7c512020-02-11 22:06:27612 bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
613 bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
614 bytes_required *= 8;
615 bytes_required *= depth;
616 break;
shrekshao3c058332020-02-11 00:00:12617 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
618 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
619 bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
620 bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
shrekshaoeae7c512020-02-11 22:06:27621 bytes_required *= 16;
shrekshao3c058332020-02-11 00:00:12622 bytes_required *= depth;
623 break;
Jonathan Backerc26060e2018-03-29 15:06:29624 default:
Geoff Lang72fe4762018-10-19 15:11:36625 if (function_name && error_state) {
626 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name, format,
627 "format");
628 }
Jonathan Backerc26060e2018-03-29 15:06:29629 return false;
630 }
631
632 if (!bytes_required.IsValid()) {
Geoff Lang72fe4762018-10-19 15:11:36633 if (function_name && error_state) {
634 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
635 "invalid size");
636 }
Jonathan Backerc26060e2018-03-29 15:06:29637 return false;
638 }
639
640 *size_in_bytes = bytes_required.ValueOrDefault(0);
641 return true;
642}
643
shrekshaofb226c242020-02-19 00:37:12644bool ValidateCompressedFormatTarget(GLenum target, GLenum format) {
645 if (target == GL_TEXTURE_3D) {
646 // Formats not supporting 3D Tex
647 switch (format) {
648 // ES 3.1, Section 8.7, page 169.
649 case GL_COMPRESSED_R11_EAC:
650 case GL_COMPRESSED_SIGNED_R11_EAC:
651 case GL_COMPRESSED_RG11_EAC:
652 case GL_COMPRESSED_SIGNED_RG11_EAC:
653 case GL_COMPRESSED_RGB8_ETC2:
654 case GL_COMPRESSED_SRGB8_ETC2:
655 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
656 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
657 case GL_COMPRESSED_RGBA8_ETC2_EAC:
658 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
shrekshaofb226c242020-02-19 00:37:12659 // GL_EXT_texture_compression_s3tc
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
663 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
664 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
665 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
666 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
667 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
668 // GL_EXT_texture_compression_rgtc
669 case GL_COMPRESSED_RED_RGTC1_EXT:
670 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
671 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
672 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
673 return false;
shrekshaoad4525482020-03-12 00:30:55674 // GL_KHR_texture_compression_astc_hdr, TEXTURE_3D is not supported
675 // without HDR profile. This is guaranteed to be validated beforehand
676 // in GLES2DecoderImpl::TexStorageImpl before calling this.
shrekshaofb226c242020-02-19 00:37:12677 default:
678 break;
679 }
680 }
681
682 return true;
683}
684
Daniel Bratell60acbb592018-07-26 09:13:14685bool ValidateCompressedTexSubDimensions(GLenum target,
686 GLint level,
687 GLint xoffset,
688 GLint yoffset,
689 GLint zoffset,
690 GLsizei width,
691 GLsizei height,
692 GLsizei depth,
693 GLenum format,
694 Texture* texture,
Daniel Bratell60acbb592018-07-26 09:13:14695 const char** error_message) {
shrekshaofb226c242020-02-19 00:37:12696 if (!ValidateCompressedFormatTarget(target, format)) {
697 *error_message = "target invalid for format";
698 return false;
699 }
700
Daniel Bratell60acbb592018-07-26 09:13:14701 if (xoffset < 0 || yoffset < 0 || zoffset < 0) {
702 *error_message = "x/y/z offset < 0";
703 return false;
704 }
705
706 switch (format) {
707 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
708 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
709 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
710 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
711 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
712 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
713 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
714 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: {
715 const int kBlockWidth = 4;
716 const int kBlockHeight = 4;
717 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
718 *error_message = "xoffset or yoffset not multiple of 4";
719 return false;
720 }
721 GLsizei tex_width = 0;
722 GLsizei tex_height = 0;
723 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
724 nullptr) ||
725 width - xoffset > tex_width || height - yoffset > tex_height) {
726 *error_message = "dimensions out of range";
727 return false;
728 }
729 if ((((width % kBlockWidth) != 0) && (width + xoffset != tex_width)) ||
730 (((height % kBlockHeight) != 0) &&
731 (height + yoffset != tex_height))) {
732 *error_message = "dimensions do not align to a block boundary";
733 return false;
734 }
735 return true;
736 }
737 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
738 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
739 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
740 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
741 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
742 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
743 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
744 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
745 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
746 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
747 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
748 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
749 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
750 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
751 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
752 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
753 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
754 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
755 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
756 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
757 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
758 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
759 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
760 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
761 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
762 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
763 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
764 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
765 const int index =
766 (format < GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
767 ? static_cast<int>(format - GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
768 : static_cast<int>(format -
769 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
770
771 const int kBlockWidth = kASTCBlockArray[index].blockWidth;
772 const int kBlockHeight = kASTCBlockArray[index].blockHeight;
773
774 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
775 *error_message = "xoffset or yoffset not multiple of 4";
776 return false;
777 }
778 GLsizei tex_width = 0;
779 GLsizei tex_height = 0;
780 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
781 nullptr) ||
782 width - xoffset > tex_width || height - yoffset > tex_height) {
783 *error_message = "dimensions out of range";
784 return false;
785 }
786 if ((((width % kBlockWidth) != 0) && (width + xoffset != tex_width)) ||
787 (((height % kBlockHeight) != 0) &&
788 (height + yoffset != tex_height))) {
789 *error_message = "dimensions do not align to a block boundary";
790 return false;
791 }
792 return true;
793 }
794 case GL_ATC_RGB_AMD:
795 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
796 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
797 *error_message = "not supported for ATC textures";
798 return false;
799 }
800 case GL_ETC1_RGB8_OES: {
801 *error_message = "not supported for ECT1_RGB8_OES textures";
802 return false;
803 }
804 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
805 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
806 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
807 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
808 if ((xoffset != 0) || (yoffset != 0)) {
809 *error_message = "xoffset and yoffset must be zero";
810 return false;
811 }
812 GLsizei tex_width = 0;
813 GLsizei tex_height = 0;
814 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
815 nullptr) ||
816 width != tex_width || height != tex_height) {
817 *error_message =
818 "dimensions must match existing texture level dimensions";
819 return false;
820 }
821 return ValidateCompressedTexDimensions(target, level, width, height, 1,
Geoff Lang1cabc702019-04-26 01:30:18822 format, error_message);
Daniel Bratell60acbb592018-07-26 09:13:14823 }
824
825 // ES3 formats
826 case GL_COMPRESSED_R11_EAC:
827 case GL_COMPRESSED_SIGNED_R11_EAC:
828 case GL_COMPRESSED_RG11_EAC:
829 case GL_COMPRESSED_SIGNED_RG11_EAC:
830 case GL_COMPRESSED_RGB8_ETC2:
831 case GL_COMPRESSED_SRGB8_ETC2:
832 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
833 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
834 case GL_COMPRESSED_RGBA8_ETC2_EAC:
shrekshao41abf0c2020-02-19 02:09:42835 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
shrekshao41abf0c2020-02-19 02:09:42836 case GL_COMPRESSED_RED_RGTC1_EXT:
837 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
838 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
839 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: {
shrekshaob70dfea2020-07-08 23:17:09840 if (target == GL_TEXTURE_3D) {
841 *error_message = "target == GL_TEXTURE_3D is not allowed";
842 return false;
843 }
Roland Bock445b8152022-01-05 08:17:25844 [[fallthrough]];
shrekshaob70dfea2020-07-08 23:17:09845 }
846 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
847 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
848 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
849 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: {
Daniel Bratell60acbb592018-07-26 09:13:14850 const int kBlockSize = 4;
851 GLsizei tex_width, tex_height;
shrekshaob70dfea2020-07-08 23:17:09852 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
Daniel Bratell60acbb592018-07-26 09:13:14853 nullptr) ||
854 (xoffset % kBlockSize) || (yoffset % kBlockSize) ||
855 ((width % kBlockSize) && xoffset + width != tex_width) ||
856 ((height % kBlockSize) && yoffset + height != tex_height)) {
857 *error_message =
858 "dimensions must match existing texture level dimensions";
859 return false;
860 }
861 return true;
862 }
863 default:
864 *error_message = "unknown compressed texture format";
865 return false;
866 }
867}
868
869bool ValidateCompressedTexDimensions(GLenum target,
870 GLint level,
871 GLsizei width,
872 GLsizei height,
873 GLsizei depth,
874 GLenum format,
Daniel Bratell60acbb592018-07-26 09:13:14875 const char** error_message) {
shrekshaofb226c242020-02-19 00:37:12876 if (!ValidateCompressedFormatTarget(target, format)) {
877 *error_message = "target invalid for format";
878 return false;
879 }
Daniel Bratell60acbb592018-07-26 09:13:14880 switch (format) {
881 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
882 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
883 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
884 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
885 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
886 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
887 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
888 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
Geoff Lang1cabc702019-04-26 01:30:18889 if (!IsValidS3TCSizeForWebGLAndANGLE(level, width) ||
890 !IsValidS3TCSizeForWebGLAndANGLE(level, height)) {
Daniel Bratell60acbb592018-07-26 09:13:14891 *error_message = "width or height invalid for level";
892 return false;
893 }
894 return true;
895 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
896 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
897 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
898 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
899 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
900 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
901 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
902 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
903 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
904 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
905 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
906 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
907 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
908 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
909 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
910 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
911 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
912 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
913 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
914 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
915 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
916 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
917 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
918 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
919 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
920 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
921 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
922 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
923 case GL_ATC_RGB_AMD:
924 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
925 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
926 case GL_ETC1_RGB8_OES:
Daniel Bratell60acbb592018-07-26 09:13:14927 if (width <= 0 || height <= 0) {
928 *error_message = "width or height invalid for level";
929 return false;
930 }
931 return true;
932 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
933 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
934 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
935 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
Daniel Bratell60acbb592018-07-26 09:13:14936 if (!IsValidPVRTCSize(level, width) || !IsValidPVRTCSize(level, height)) {
937 *error_message = "width or height invalid for level";
938 return false;
939 }
940 return true;
941
942 // ES3 formats.
943 case GL_COMPRESSED_R11_EAC:
944 case GL_COMPRESSED_SIGNED_R11_EAC:
945 case GL_COMPRESSED_RG11_EAC:
946 case GL_COMPRESSED_SIGNED_RG11_EAC:
947 case GL_COMPRESSED_RGB8_ETC2:
948 case GL_COMPRESSED_SRGB8_ETC2:
949 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
950 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
951 case GL_COMPRESSED_RGBA8_ETC2_EAC:
952 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
953 if (width < 0 || height < 0 || depth < 0) {
954 *error_message = "width, height, or depth invalid";
955 return false;
956 }
Daniel Bratell60acbb592018-07-26 09:13:14957 return true;
shrekshaode2f6f32020-02-07 02:39:44958 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
959 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
960 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
961 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
962 if (width < 0 || height < 0 || depth < 0) {
963 *error_message = "width, height, or depth invalid";
964 return false;
965 }
shrekshaob70dfea2020-07-08 23:17:09966 if (level == 0 &&
967 !(width % kBPTCBlockWidth == 0 && height % kBPTCBlockHeight == 0)) {
shrekshaode2f6f32020-02-07 02:39:44968 *error_message = "width or height is not a multiple of four";
969 return false;
970 }
971 return true;
shrekshao3c058332020-02-11 00:00:12972 case GL_COMPRESSED_RED_RGTC1_EXT:
973 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
974 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
975 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
976 if (width < 0 || height < 0 || depth < 0) {
977 *error_message = "width, height, or depth invalid";
978 return false;
979 }
shrekshaob70dfea2020-07-08 23:17:09980 if (level == 0 &&
981 !(width % kRGTCBlockWidth == 0 && height % kRGTCBlockHeight == 0)) {
shrekshao3c058332020-02-11 00:00:12982 *error_message = "width or height is not a multiple of four";
983 return false;
984 }
985 return true;
Daniel Bratell60acbb592018-07-26 09:13:14986 default:
987 return false;
988 }
989}
990
Jonathan Backer8629c392018-04-04 23:01:03991bool ValidateCopyTexFormatHelper(const FeatureInfo* feature_info,
992 GLenum internal_format,
993 GLenum read_format,
994 GLenum read_type,
995 std::string* output_error_msg) {
996 DCHECK(output_error_msg);
997 if (read_format == 0) {
998 *output_error_msg = std::string("no valid color image");
999 return false;
1000 }
1001 // Check we have compatible formats.
1002 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format);
1003 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
1004 if (!channels_needed ||
1005 (channels_needed & channels_exist) != channels_needed) {
1006 *output_error_msg = std::string("incompatible format");
1007 return false;
1008 }
Jiajia Qin252a8132018-07-19 01:03:221009 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
Jonathan Backer8629c392018-04-04 23:01:031010 GLint color_encoding =
1011 GLES2Util::GetColorEncodingFromInternalFormat(read_format);
1012 bool float_mismatch = feature_info->ext_color_buffer_float_available()
1013 ? (GLES2Util::IsIntegerFormat(internal_format) !=
1014 GLES2Util::IsIntegerFormat(read_format))
1015 : GLES2Util::IsFloatFormat(internal_format);
1016 if (color_encoding !=
1017 GLES2Util::GetColorEncodingFromInternalFormat(internal_format) ||
1018 float_mismatch ||
1019 (GLES2Util::IsSignedIntegerFormat(internal_format) !=
1020 GLES2Util::IsSignedIntegerFormat(read_format)) ||
1021 (GLES2Util::IsUnsignedIntegerFormat(internal_format) !=
1022 GLES2Util::IsUnsignedIntegerFormat(read_format))) {
1023 *output_error_msg = std::string("incompatible format");
1024 return false;
1025 }
1026 }
1027 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
1028 *output_error_msg =
1029 std::string("can not be used with depth or stencil textures");
1030 return false;
1031 }
Jiajia Qin252a8132018-07-19 01:03:221032 if (feature_info->IsWebGL2OrES3OrHigherContext() ||
Jonathan Backer8629c392018-04-04 23:01:031033 (feature_info->feature_flags().chromium_color_buffer_float_rgb &&
1034 internal_format == GL_RGB32F) ||
1035 (feature_info->feature_flags().chromium_color_buffer_float_rgba &&
1036 internal_format == GL_RGBA32F)) {
1037 if (GLES2Util::IsSizedColorFormat(internal_format)) {
1038 int sr, sg, sb, sa;
1039 GLES2Util::GetColorFormatComponentSizes(read_format, read_type, &sr, &sg,
1040 &sb, &sa);
1041 DCHECK(sr > 0 || sg > 0 || sb > 0 || sa > 0);
1042 int dr, dg, db, da;
1043 GLES2Util::GetColorFormatComponentSizes(internal_format, 0, &dr, &dg, &db,
1044 &da);
1045 DCHECK(dr > 0 || dg > 0 || db > 0 || da > 0);
1046 if ((dr > 0 && sr != dr) || (dg > 0 && sg != dg) ||
1047 (db > 0 && sb != db) || (da > 0 && sa != da)) {
1048 *output_error_msg = std::string("incompatible color component sizes");
1049 return false;
1050 }
1051 }
1052 }
1053 return true;
1054}
1055
1056CopyTextureMethod GetCopyTextureCHROMIUMMethod(const FeatureInfo* feature_info,
1057 GLenum source_target,
1058 GLint source_level,
1059 GLenum source_internal_format,
1060 GLenum source_type,
1061 GLenum dest_target,
1062 GLint dest_level,
1063 GLenum dest_internal_format,
1064 bool flip_y,
1065 bool premultiply_alpha,
Corentin Wallezcacc4172021-12-03 14:40:221066 bool unpremultiply_alpha) {
Jonathan Backer8629c392018-04-04 23:01:031067 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
1068 bool source_format_color_renderable =
1069 Texture::ColorRenderable(feature_info, source_internal_format, false);
1070 bool dest_format_color_renderable =
1071 Texture::ColorRenderable(feature_info, dest_internal_format, false);
1072 std::string output_error_msg;
1073
1074 switch (dest_internal_format) {
Xiaohan Wangfa22d3e2022-01-15 02:02:431075#if BUILDFLAG(IS_MAC)
Jonathan Backer8629c392018-04-04 23:01:031076 // RGB5_A1 is not color-renderable on NVIDIA Mac, see
1077 // https://crbug.com/676209.
1078 case GL_RGB5_A1:
1079 return CopyTextureMethod::DRAW_AND_READBACK;
1080#endif
1081 // RGB9_E5 isn't accepted by glCopyTexImage2D if underlying context is ES.
1082 case GL_RGB9_E5:
Zhenyao Mo12d741f2024-07-09 19:12:381083 return CopyTextureMethod::DRAW_AND_READBACK;
Jonathan Backer8629c392018-04-04 23:01:031084 // SRGB format has color-space conversion issue. WebGL spec doesn't define
1085 // clearly if linear-to-srgb color space conversion is required or not when
1086 // uploading DOM elements to SRGB textures. WebGL conformance test expects
1087 // no linear-to-srgb conversion, while current GPU path for
1088 // CopyTextureCHROMIUM does the conversion. Do a fallback path before the
1089 // issue is resolved. see https://github.com/KhronosGroup/WebGL/issues/2165.
1090 // TODO(qiankun.miao@intel.com): revisit this once the above issue is
1091 // resolved.
1092 case GL_SRGB_EXT:
1093 case GL_SRGB_ALPHA_EXT:
1094 case GL_SRGB8:
1095 case GL_SRGB8_ALPHA8:
1096 if (feature_info->IsWebGLContext())
1097 return CopyTextureMethod::DRAW_AND_READBACK;
1098 break;
1099 default:
1100 break;
1101 }
1102
1103 // CopyTexImage* should not allow internalformat of GL_BGRA_EXT and
1104 // GL_BGRA8_EXT. https://crbug.com/663086.
1105 bool copy_tex_image_format_valid =
1106 source_internal_format != GL_BGRA_EXT &&
1107 dest_internal_format != GL_BGRA_EXT &&
1108 source_internal_format != GL_BGRA8_EXT &&
1109 dest_internal_format != GL_BGRA8_EXT &&
1110 ValidateCopyTexFormatHelper(feature_info, dest_internal_format,
1111 source_internal_format, source_type,
1112 &output_error_msg);
1113
Antoine Labour4885296a2019-05-09 02:38:391114 // The ES3 spec is vague about whether or not glCopyTexImage2D from a
1115 // GL_RGB10_A2 attachment to an unsized internal format is valid. Most drivers
1116 // interpreted the explicit call out as not valid (and dEQP actually checks
1117 // this), so avoid DIRECT_COPY in that case.
Zhenyao Mo12d741f2024-07-09 19:12:381118 if (source_internal_format == GL_RGB10_A2 &&
1119 dest_internal_format != source_internal_format) {
Antoine Labour4885296a2019-05-09 02:38:391120 copy_tex_image_format_valid = false;
Zhenyao Mo12d741f2024-07-09 19:12:381121 }
Antoine Labour4885296a2019-05-09 02:38:391122
Jonathan Backer8629c392018-04-04 23:01:031123 // TODO(qiankun.miao@intel.com): for WebGL 2.0 or OpenGL ES 3.0, both
1124 // DIRECT_DRAW path for dest_level > 0 and DIRECT_COPY path for source_level >
1125 // 0 are not available due to a framebuffer completeness bug:
1126 // https://crbug.com/678526. Once the bug is fixed, the limitation for WebGL
1127 // 2.0 and OpenGL ES 3.0 can be lifted. For WebGL 1.0 or OpenGL ES 2.0,
1128 // DIRECT_DRAW path isn't available for dest_level > 0 due to level > 0 isn't
1129 // supported by glFramebufferTexture2D in ES2 context. DIRECT_DRAW path isn't
1130 // available for cube map dest texture either due to it may be cube map
1131 // incomplete. Go to DRAW_AND_COPY path in these cases.
1132 if (source_target == GL_TEXTURE_2D &&
1133 (dest_target == GL_TEXTURE_2D || dest_target == GL_TEXTURE_CUBE_MAP) &&
1134 source_format_color_renderable && copy_tex_image_format_valid &&
Corentin Wallezcacc4172021-12-03 14:40:221135 source_level == 0 && !flip_y && !premultiply_alpha_change) {
shrekshaob437fb192020-01-30 07:39:571136 auto source_texture_type = GLES2Util::GetGLReadPixelsImplementationType(
1137 source_internal_format, source_target);
1138 auto dest_texture_type = GLES2Util::GetGLReadPixelsImplementationType(
1139 dest_internal_format, dest_target);
1140 if (source_texture_type != GL_UNSIGNED_SHORT ||
1141 source_texture_type == dest_texture_type) {
1142 // https://crbug.com/1042239. As it is stated in the latest OpenGL ES 3.2
1143 // spec (Oct 22, 2019) it is optional for implementation to support
1144 // conversion between unmatched source and dest effective internal format.
1145 // R16 to R16F direct copy failure is seen on Android Nvidia shield
1146 // devices. So we won't use DIRECT_COPY for this format.
1147 return CopyTextureMethod::DIRECT_COPY;
1148 }
1149 }
Jonathan Backer8629c392018-04-04 23:01:031150 if (dest_format_color_renderable && dest_level == 0 &&
1151 dest_target != GL_TEXTURE_CUBE_MAP)
1152 return CopyTextureMethod::DIRECT_DRAW;
1153
1154 // Draw to a fbo attaching level 0 of an intermediate texture,
1155 // then copy from the fbo to dest texture level with glCopyTexImage2D.
1156 return CopyTextureMethod::DRAW_AND_COPY;
1157}
1158
Jonathan Backer4cb165c82018-07-03 20:25:331159bool ValidateCopyTextureCHROMIUMInternalFormats(const FeatureInfo* feature_info,
1160 GLenum source_internal_format,
1161 GLenum dest_internal_format,
1162 std::string* output_error_msg) {
1163 bool valid_dest_format = false;
1164 // TODO(qiankun.miao@intel.com): ALPHA, LUMINANCE and LUMINANCE_ALPHA formats
1165 // are not supported on GL core profile. See https://crbug.com/577144. Enable
1166 // the workaround for glCopyTexImage and glCopyTexSubImage in
1167 // gles2_cmd_copy_tex_image.cc for glCopyTextureCHROMIUM implementation.
1168 switch (dest_internal_format) {
1169 case GL_RGB:
1170 case GL_RGBA:
1171 case GL_RGB8:
1172 case GL_RGBA8:
1173 valid_dest_format = true;
1174 break;
1175 case GL_BGRA_EXT:
1176 case GL_BGRA8_EXT:
1177 valid_dest_format =
1178 feature_info->feature_flags().ext_texture_format_bgra8888;
1179 break;
1180 case GL_SRGB_EXT:
1181 case GL_SRGB_ALPHA_EXT:
1182 valid_dest_format = feature_info->feature_flags().ext_srgb;
1183 break;
1184 case GL_R8:
1185 case GL_R8UI:
1186 case GL_RG8:
1187 case GL_RG8UI:
1188 case GL_SRGB8:
1189 case GL_RGB565:
1190 case GL_RGB8UI:
1191 case GL_SRGB8_ALPHA8:
1192 case GL_RGB5_A1:
1193 case GL_RGBA4:
1194 case GL_RGBA8UI:
1195 case GL_RGB10_A2:
Jiajia Qin252a8132018-07-19 01:03:221196 valid_dest_format = feature_info->IsWebGL2OrES3OrHigherContext();
Jonathan Backer4cb165c82018-07-03 20:25:331197 break;
1198 case GL_RGB9_E5:
1199 case GL_R16F:
1200 case GL_R32F:
1201 case GL_RG16F:
1202 case GL_RG32F:
1203 case GL_RGB16F:
1204 case GL_RGBA16F:
1205 case GL_R11F_G11F_B10F:
1206 valid_dest_format = feature_info->ext_color_buffer_float_available();
1207 break;
1208 case GL_RGB32F:
1209 valid_dest_format =
1210 feature_info->ext_color_buffer_float_available() ||
1211 feature_info->feature_flags().chromium_color_buffer_float_rgb;
1212 break;
1213 case GL_RGBA32F:
1214 valid_dest_format =
1215 feature_info->ext_color_buffer_float_available() ||
1216 feature_info->feature_flags().chromium_color_buffer_float_rgba;
1217 break;
1218 case GL_ALPHA:
1219 case GL_LUMINANCE:
1220 case GL_LUMINANCE_ALPHA:
1221 valid_dest_format = true;
1222 break;
1223 default:
1224 valid_dest_format = false;
1225 break;
1226 }
1227
1228 // TODO(aleksandar.stojiljkovic): Use sized internal formats:
1229 // https://crbug.com/628064
1230 bool valid_source_format =
1231 source_internal_format == GL_RED || source_internal_format == GL_ALPHA ||
1232 source_internal_format == GL_RGB || source_internal_format == GL_RGBA ||
1233 source_internal_format == GL_RGB8 || source_internal_format == GL_RGBA8 ||
1234 source_internal_format == GL_LUMINANCE ||
1235 source_internal_format == GL_LUMINANCE_ALPHA ||
1236 source_internal_format == GL_BGRA_EXT ||
1237 source_internal_format == GL_BGRA8_EXT ||
Miguel Casas94f82b22019-01-31 21:20:571238 source_internal_format == GL_R16_EXT ||
shrekshaob437fb192020-01-30 07:39:571239 source_internal_format == GL_RG16_EXT ||
1240 source_internal_format == GL_RGBA16_EXT ||
Miguel Casas94f82b22019-01-31 21:20:571241 source_internal_format == GL_RGB10_A2;
Jonathan Backer4cb165c82018-07-03 20:25:331242 if (!valid_source_format) {
1243 *output_error_msg = "invalid source internal format " +
1244 GLES2Util::GetStringEnum(source_internal_format);
1245 return false;
1246 }
1247 if (!valid_dest_format) {
1248 *output_error_msg = "invalid dest internal format " +
1249 GLES2Util::GetStringEnum(dest_internal_format);
1250 return false;
1251 }
1252
1253 return true;
1254}
1255
Geoff Lang18c8f3d82019-07-08 23:20:331256GLenum GetTextureBindingQuery(GLenum texture_type) {
1257 switch (texture_type) {
1258 case GL_TEXTURE_2D:
1259 return GL_TEXTURE_BINDING_2D;
1260 case GL_TEXTURE_2D_ARRAY:
1261 return GL_TEXTURE_BINDING_2D_ARRAY;
1262 case GL_TEXTURE_2D_MULTISAMPLE:
1263 return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
1264 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1265 return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
1266 case GL_TEXTURE_3D:
1267 return GL_TEXTURE_BINDING_3D;
1268 case GL_TEXTURE_EXTERNAL_OES:
1269 return GL_TEXTURE_BINDING_EXTERNAL_OES;
1270 case GL_TEXTURE_RECTANGLE:
1271 return GL_TEXTURE_BINDING_RECTANGLE;
1272 case GL_TEXTURE_CUBE_MAP:
1273 return GL_TEXTURE_BINDING_CUBE_MAP;
1274 default:
Peter BostrΓΆma11556e2024-10-31 04:49:101275 NOTREACHED();
Geoff Lang18c8f3d82019-07-08 23:20:331276 }
1277}
1278
shrekshaoad4525482020-03-12 00:30:551279bool IsASTCFormat(GLenum internal_format) {
1280 switch (internal_format) {
1281 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
1282 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
1283 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
1284 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
1285 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
1286 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1287 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
1288 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
1289 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
1290 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
1291 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
1292 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
1293 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
1294 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
1295 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
1296 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
1297 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
1298 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
1299 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
1300 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
1301 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
1302 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
1303 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
1304 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
1305 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
1306 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
1307 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
1308 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
1309 return true;
1310 default:
1311 break;
1312 }
1313 return false;
1314}
1315
1316// This is only called in Texture::SetLevelInfo in texture_manager.cc
1317// where there is no direct access to decoder->IsCompressedTextureFormat
1318// or feature_info->validators()->compressed_texture_format.IsValid
1319bool IsCompressedTextureFormat(GLenum internal_format) {
1320 switch (internal_format) {
1321 // S3TC
1322 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1323 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1324 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1325 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1326 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1327 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1328 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1329 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1330 // ASTC
1331 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
1332 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
1333 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
1334 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
1335 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
1336 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1337 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
1338 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
1339 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
1340 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
1341 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
1342 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
1343 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
1344 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
1345 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
1346 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
1347 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
1348 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
1349 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
1350 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
1351 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
1352 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
1353 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
1354 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
1355 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
1356 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
1357 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
1358 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
1359 // BPTC
1360 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
1361 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
1362 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
1363 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
1364 // RGTC
1365 case GL_COMPRESSED_RED_RGTC1_EXT:
1366 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
1367 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
1368 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
1369 // ETC2/EAC
1370 case GL_COMPRESSED_R11_EAC:
1371 case GL_COMPRESSED_SIGNED_R11_EAC:
1372 case GL_COMPRESSED_RGB8_ETC2:
1373 case GL_COMPRESSED_SRGB8_ETC2:
1374 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1375 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1376 case GL_COMPRESSED_RG11_EAC:
1377 case GL_COMPRESSED_SIGNED_RG11_EAC:
1378 case GL_COMPRESSED_RGBA8_ETC2_EAC:
1379 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1380 // ETC1
1381 case GL_ETC1_RGB8_OES:
1382 // PVRTC
1383 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
1384 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
1385 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
1386 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
1387 // ATC
1388 case GL_ATC_RGB_AMD:
1389 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
1390 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
1391 return true;
1392 default:
1393 break;
1394 }
1395 return false;
1396}
1397
Saifuddin Hitawala151bf3bf2022-07-19 19:03:141398Texture* CreateGLES2TextureWithLightRef(GLuint service_id, GLenum target) {
1399 Texture* texture = new Texture(service_id);
1400 texture->SetLightweightRef();
1401 texture->SetTarget(target, 1 /*max_levels=*/);
1402 texture->set_min_filter(GL_LINEAR);
1403 texture->set_mag_filter(GL_LINEAR);
1404 texture->set_wrap_t(GL_CLAMP_TO_EDGE);
1405 texture->set_wrap_s(GL_CLAMP_TO_EDGE);
1406 return texture;
1407}
1408
junov0cad1f42016-01-07 21:48:511409} // namespace gles2
1410} // namespace gpu