blob: fca56b668db3eb284e4d7482fadea93c8c714a57 [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>
Kalvin Lee9e2c2e82025-04-16 22:37:4213#include <array>
brettw1ce49f62017-04-27 19:42:3214#include <unordered_set>
15
Stephen Nuskof4e53402025-07-23 13:39:4416#include "base/containers/span.h"
Xiaohan Wangfa22d3e2022-01-15 02:02:4317#include "build/build_config.h"
geofflang124fd552016-09-08 20:02:5518#include "gpu/command_buffer/common/capabilities.h"
Jonathan Backerc26060e2018-03-29 15:06:2919#include "gpu/command_buffer/service/error_state.h"
geofflang124fd552016-09-08 20:02:5520#include "gpu/command_buffer/service/feature_info.h"
Jonathan Backer8629c392018-04-04 23:01:0321#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
James Darpinian0f56e9f32018-01-11 02:23:5522#include "gpu/command_buffer/service/logger.h"
Jonathan Backer8629c392018-04-04 23:01:0323#include "gpu/command_buffer/service/texture_manager.h"
Geoff Langc33679e2025-05-28 15:56:5824#include "ui/gl/gl_utils.h"
geofflang124fd552016-09-08 20:02:5525#include "ui/gl/gl_version_info.h"
junov0cad1f42016-01-07 21:48:5126
Georg Neis24b92cc42025-02-07 04:11:1027#if BUILDFLAG(IS_CHROMEOS)
Chia-I Wu4cff4be62023-12-08 03:21:2728#include <sys/stat.h>
Robert Mader36c50132022-10-21 15:38:5729#include "ui/gl/gl_surface_egl.h"
30#endif
31
junov0cad1f42016-01-07 21:48:5132namespace gpu {
33namespace gles2 {
34
geofflang326c8512016-11-03 15:11:2835namespace {
Jonathan Backerc26060e2018-03-29 15:06:2936
37const int kASTCBlockSize = 16;
38const int kS3TCBlockWidth = 4;
39const int kS3TCBlockHeight = 4;
40const int kS3TCDXT1BlockSize = 8;
41const int kS3TCDXT3AndDXT5BlockSize = 16;
42const int kEACAndETC2BlockSize = 4;
shrekshaode2f6f32020-02-07 02:39:4443const int kBPTCBlockWidth = 4;
44const int kBPTCBlockHeight = 4;
shrekshao3c058332020-02-11 00:00:1245const int kRGTCBlockWidth = 4;
46const int kRGTCBlockHeight = 4;
Jonathan Backerc26060e2018-03-29 15:06:2947
48typedef struct {
49 int blockWidth;
50 int blockHeight;
51} ASTCBlockArray;
52
Kalvin Lee9e2c2e82025-04-16 22:37:4253const auto kASTCBlockArray = std::to_array<ASTCBlockArray>({
Jonathan Backerc26060e2018-03-29 15:06:2954 {4, 4}, /* GL_COMPRESSED_RGBA_ASTC_4x4_KHR */
55 {5, 4}, /* and GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR */
Kalvin Lee9e2c2e82025-04-16 22:37:4256 {5, 5},
57 {6, 5},
58 {6, 6},
59 {8, 5},
60 {8, 6},
61 {8, 8},
62 {10, 5},
63 {10, 6},
64 {10, 8},
65 {10, 10},
66 {12, 10},
67 {12, 12},
68});
Jonathan Backerc26060e2018-03-29 15:06:2969
Daniel Bratell60acbb592018-07-26 09:13:1470bool IsValidPVRTCSize(GLint level, GLsizei size) {
71 return GLES2Util::IsPOT(size);
72}
73
Geoff Lang1cabc702019-04-26 01:30:1874bool IsValidS3TCSizeForWebGLAndANGLE(GLint level, GLsizei size) {
Geoff Langf067e4c2020-09-18 17:51:5775 // WebGL and ANGLE only allow multiple-of-4 sizes for the base level. See
76 // WEBGL_compressed_texture_s3tc and ANGLE_compressed_texture_dxt*
77 return (level > 0) || (size % kS3TCBlockWidth == 0);
Daniel Bratell60acbb592018-07-26 09:13:1478}
James Darpinian0f56e9f32018-01-11 02:23:5579} // namespace
geofflang326c8512016-11-03 15:11:2880
geofflang124fd552016-09-08 20:02:5581bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
82 GLint rangeMax,
83 GLint precision) {
84 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
85}
86
Zhenyao Mo12d741f2024-07-09 19:12:3887void QueryShaderPrecisionFormat(GLenum shader_type,
geofflang124fd552016-09-08 20:02:5588 GLenum precision_type,
Stephen Nuskof4e53402025-07-23 13:39:4489 base::span<GLint> range,
geofflang124fd552016-09-08 20:02:5590 GLint* precision) {
91 switch (precision_type) {
92 case GL_LOW_INT:
93 case GL_MEDIUM_INT:
94 case GL_HIGH_INT:
95 // These values are for a 32-bit twos-complement integer format.
96 range[0] = 31;
97 range[1] = 30;
98 *precision = 0;
99 break;
100 case GL_LOW_FLOAT:
101 case GL_MEDIUM_FLOAT:
102 case GL_HIGH_FLOAT:
103 // These values are for an IEEE single-precision floating-point format.
104 range[0] = 127;
105 range[1] = 127;
106 *precision = 23;
107 break;
108 default:
Peter BostrΓΆma11556e2024-10-31 04:49:10109 NOTREACHED();
geofflang124fd552016-09-08 20:02:55110 }
111
Zhenyao Mo12d741f2024-07-09 19:12:38112 // This function is sometimes defined even though it's really just
113 // a stub, so we need to set range and precision as if it weren't
114 // defined before calling it.
115 // On Mac OS with some GPUs, calling this generates a
116 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
117 // platforms.
Stephen Nuskof4e53402025-07-23 13:39:44118 glGetShaderPrecisionFormat(shader_type, precision_type, range.data(),
119 precision);
geofflang124fd552016-09-08 20:02:55120
Zhenyao Mo12d741f2024-07-09 19:12:38121 // TODO(brianderson): Make the following official workarounds.
geofflang124fd552016-09-08 20:02:55122
Zhenyao Mo12d741f2024-07-09 19:12:38123 // Some drivers have bugs where they report the ranges as a negative number.
124 // Taking the absolute value here shouldn't hurt because negative numbers
125 // aren't expected anyway.
126 range[0] = abs(range[0]);
127 range[1] = abs(range[1]);
geofflang124fd552016-09-08 20:02:55128
Zhenyao Mo12d741f2024-07-09 19:12:38129 // If the driver reports a precision for highp float that isn't actually
130 // highp, don't pretend like it's supported because shader compilation will
131 // fail anyway.
132 if (precision_type == GL_HIGH_FLOAT &&
133 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
134 range[0] = 0;
135 range[1] = 0;
136 *precision = 0;
geofflang124fd552016-09-08 20:02:55137 }
138}
139
140void PopulateNumericCapabilities(Capabilities* caps,
141 const FeatureInfo* feature_info) {
142 DCHECK(caps != nullptr);
Saifuddin Hitawalaa589c352023-10-05 21:42:22143 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps->max_texture_size);
Saifuddin Hitawalaa589c352023-10-05 21:42:22144}
145
146void PopulateGLCapabilities(GLCapabilities* caps,
147 const FeatureInfo* feature_info) {
148 CHECK(caps);
Saifuddin Hitawalad3ec84c32023-10-11 13:52:52149
Zhenyao Mo12d741f2024-07-09 19:12:38150 caps->VisitPrecisions([](GLenum shader, GLenum type,
151 GLCapabilities::ShaderPrecision* shader_precision) {
Saifuddin Hitawalad3ec84c32023-10-11 13:52:52152 GLint range[2] = {0, 0};
153 GLint precision = 0;
Zhenyao Mo12d741f2024-07-09 19:12:38154 QueryShaderPrecisionFormat(shader, type, range, &precision);
Saifuddin Hitawalad3ec84c32023-10-11 13:52:52155 shader_precision->min_range = range[0];
156 shader_precision->max_range = range[1];
157 shader_precision->precision = precision;
158 });
159
Saifuddin Hitawala8deded82024-08-14 21:26:30160 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps->max_texture_size);
161
Saifuddin Hitawalaa589c352023-10-05 21:42:22162 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
163 &caps->max_combined_texture_image_units);
Saifuddin Hitawala9f187482023-10-11 22:43:09164 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps->max_cube_map_texture_size);
geofflang124fd552016-09-08 20:02:55165 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
166 &caps->max_fragment_uniform_vectors);
167 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps->max_renderbuffer_size);
168 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps->max_texture_image_units);
geofflang124fd552016-09-08 20:02:55169 glGetIntegerv(GL_MAX_VARYING_VECTORS, &caps->max_varying_vectors);
170 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps->max_vertex_attribs);
171 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
172 &caps->max_vertex_texture_image_units);
173 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
174 &caps->max_vertex_uniform_vectors);
zmoc95386fb2016-12-09 23:48:55175 {
176 GLint dims[2] = {0, 0};
177 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
178 caps->max_viewport_width = dims[0];
179 caps->max_viewport_height = dims[1];
180 }
geofflang124fd552016-09-08 20:02:55181 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
182 &caps->num_compressed_texture_formats);
183 glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps->num_shader_binary_formats);
Jiajia Qin252a8132018-07-19 01:03:22184 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
geofflang124fd552016-09-08 20:02:55185 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps->max_3d_texture_size);
186 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps->max_array_texture_layers);
187 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps->max_color_attachments);
188 glGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
189 &caps->max_combined_fragment_uniform_components);
190 glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
191 &caps->max_combined_uniform_blocks);
192 glGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
193 &caps->max_combined_vertex_uniform_components);
194 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps->max_draw_buffers);
195 glGetInteger64v(GL_MAX_ELEMENT_INDEX, &caps->max_element_index);
196 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps->max_elements_indices);
197 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps->max_elements_vertices);
198 glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
199 &caps->max_fragment_input_components);
200 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
201 &caps->max_fragment_uniform_blocks);
202 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
203 &caps->max_fragment_uniform_components);
204 glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->max_program_texel_offset);
205 glGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &caps->max_server_wait_timeout);
206 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->max_texture_lod_bias);
207 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
208 &caps->max_transform_feedback_interleaved_components);
209 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
210 &caps->max_transform_feedback_separate_attribs);
211 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
212 &caps->max_transform_feedback_separate_components);
213 glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &caps->max_uniform_block_size);
214 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
215 &caps->max_uniform_buffer_bindings);
216 glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps->max_varying_components);
217 glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
218 &caps->max_vertex_output_components);
219 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS,
220 &caps->max_vertex_uniform_blocks);
221 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
222 &caps->max_vertex_uniform_components);
223 glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->min_program_texel_offset);
geofflang124fd552016-09-08 20:02:55224 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
225 &caps->num_program_binary_formats);
226 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
227 &caps->uniform_buffer_offset_alignment);
Geoff Langd0c755c2021-01-18 21:58:16228 if (feature_info->IsES31ForTestingContext()) {
Jiajia Qinbf31bed2018-08-23 03:54:50229 glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,
230 &caps->max_atomic_counter_buffer_bindings);
231 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
232 &caps->max_shader_storage_buffer_bindings);
233 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT,
234 &caps->shader_storage_buffer_offset_alignment);
Jiajia Qin252a8132018-07-19 01:03:22235 }
geofflang124fd552016-09-08 20:02:55236 }
Saifuddin Hitawala9f187482023-10-11 22:43:09237 if (feature_info->feature_flags().multisampled_render_to_texture ||
238 feature_info->feature_flags().chromium_framebuffer_multisample ||
239 feature_info->IsWebGL2OrES3OrHigherContext()) {
240 glGetIntegerv(GL_MAX_SAMPLES, &caps->max_samples);
241 }
Saifuddin Hitawala4908ef62024-08-13 22:02:30242
243 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
244 caps->major_version = 3;
245 if (feature_info->IsES31ForTestingContext()) {
246 caps->minor_version = 1;
247 } else {
248 caps->minor_version = 0;
249 }
250 }
Saifuddin Hitawalab2da4f02023-10-04 15:36:46251}
252
Georg Neis24b92cc42025-02-07 04:11:10253#if BUILDFLAG(IS_CHROMEOS)
Robert Mader36c50132022-10-21 15:38:57254void PopulateDRMCapabilities(Capabilities* caps,
255 const FeatureInfo* feature_info) {
256 DCHECK(caps != nullptr);
257
258 if (!gl::GLSurfaceEGL::GetGLDisplayEGL() ||
259 !gl::GLSurfaceEGL::GetGLDisplayEGL()->IsInitialized() ||
260 !gl::GLSurfaceEGL::GetGLDisplayEGL()
261 ->ext->b_EGL_EXT_image_dma_buf_import_modifiers ||
262 feature_info->workarounds()
263 .disable_egl_ext_image_dma_buf_import_modifiers ||
264 !gl::g_driver_egl.client_ext.b_EGL_EXT_device_query) {
265 return;
266 }
267
268 EGLDisplay egl_display = gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay();
269 DCHECK(egl_display != nullptr);
270
271 EGLDeviceEXT egl_device;
272 if (!eglQueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT,
273 (EGLAttrib*)&egl_device)) {
274 return;
275 }
276
277 gfx::ExtensionSet device_extension_set;
278 const char* device_extensions =
279 eglQueryDeviceStringEXT(egl_device, EGL_EXTENSIONS);
280 if (device_extensions) {
281 device_extension_set = gfx::MakeExtensionSet(device_extensions);
282 } else {
283 device_extension_set = gfx::ExtensionSet();
284 }
285
Chia-I Wu4cff4be62023-12-08 03:21:27286 std::string drm_render_node;
Robert Mader36c50132022-10-21 15:38:57287 if (gfx::HasExtension(device_extension_set,
288 "EGL_EXT_device_drm_render_node")) {
289 const char* path =
290 eglQueryDeviceStringEXT(egl_device, EGL_DRM_RENDER_NODE_FILE_EXT);
Kramer Gecfec01662022-12-05 22:54:24291 if (path)
Chia-I Wu4cff4be62023-12-08 03:21:27292 drm_render_node = std::string(path);
Robert Mader36c50132022-10-21 15:38:57293 }
Chia-I Wu4cff4be62023-12-08 03:21:27294 if (drm_render_node.empty() &&
Robert Mader36c50132022-10-21 15:38:57295 gfx::HasExtension(device_extension_set, "EGL_EXT_device_drm")) {
296 const char* path =
297 eglQueryDeviceStringEXT(egl_device, EGL_DRM_DEVICE_FILE_EXT);
Kramer Gecfec01662022-12-05 22:54:24298 if (path)
Chia-I Wu4cff4be62023-12-08 03:21:27299 drm_render_node = std::string(path);
300 }
301
302 if (!drm_render_node.empty()) {
303 struct stat dev_stat;
304 if (stat(drm_render_node.c_str(), &dev_stat) == 0) {
305 static_assert(sizeof(dev_t) <= sizeof(caps->drm_device_id),
306 "unexpected dev_t size");
307 DCHECK(dev_stat.st_rdev);
308 caps->drm_device_id = dev_stat.st_rdev;
309 }
Robert Mader36c50132022-10-21 15:38:57310 }
311
312 EGLint num_formats = 0;
313 if (eglQueryDmaBufFormatsEXT(egl_display, 0, nullptr, &num_formats) &&
314 num_formats > 0) {
315 std::vector<EGLint> formats_array(num_formats);
316 bool res = eglQueryDmaBufFormatsEXT(egl_display, num_formats,
317 formats_array.data(), &num_formats);
318 DCHECK(res);
319
320 for (EGLint format : formats_array) {
321 std::vector<uint64_t> modifiers;
322 EGLint num_modifiers = 0;
323 if (eglQueryDmaBufModifiersEXT(egl_display, format, 0, nullptr, nullptr,
324 &num_modifiers) &&
325 num_modifiers > 0) {
326 std::vector<EGLuint64KHR> modifiers_array(num_modifiers);
327 res = eglQueryDmaBufModifiersEXT(egl_display, format, num_modifiers,
328 modifiers_array.data(), nullptr,
329 &num_modifiers);
330 DCHECK(res);
331
332 for (uint64_t modifier : modifiers_array) {
333 modifiers.push_back(modifier);
334 }
335 }
336
337 caps->drm_formats_and_modifiers.emplace(format, modifiers);
338 }
339 }
340}
341#endif
342
geofflang851a4812016-09-14 19:20:29343bool CheckUniqueAndNonNullIds(GLsizei n, const GLuint* client_ids) {
344 if (n <= 0)
345 return true;
346 std::unordered_set<uint32_t> unique_ids(client_ids, client_ids + n);
347 return (unique_ids.size() == static_cast<size_t>(n)) &&
348 (unique_ids.find(0) == unique_ids.end());
349}
350
geofflang67c1fca2016-11-15 21:18:09351const char* GetServiceVersionString(const FeatureInfo* feature_info) {
352 if (feature_info->IsWebGL2OrES3Context())
353 return "OpenGL ES 3.0 Chromium";
Geoff Langd0c755c2021-01-18 21:58:16354 else if (feature_info->IsES31ForTestingContext()) {
Jiajia Qin252a8132018-07-19 01:03:22355 return "OpenGL ES 3.1 Chromium";
356 } else
geofflang67c1fca2016-11-15 21:18:09357 return "OpenGL ES 2.0 Chromium";
358}
359
360const char* GetServiceShadingLanguageVersionString(
361 const FeatureInfo* feature_info) {
362 if (feature_info->IsWebGL2OrES3Context())
363 return "OpenGL ES GLSL ES 3.0 Chromium";
Geoff Langd0c755c2021-01-18 21:58:16364 else if (feature_info->IsES31ForTestingContext()) {
Jiajia Qin252a8132018-07-19 01:03:22365 return "OpenGL ES GLSL ES 3.1 Chromium";
366 } else
geofflang67c1fca2016-11-15 21:18:09367 return "OpenGL ES GLSL ES 1.0 Chromium";
368}
369
Geoff Langfdec674e2018-02-22 17:40:29370void LogGLDebugMessage(GLenum source,
371 GLenum type,
372 GLuint id,
373 GLenum severity,
374 GLsizei length,
375 const GLchar* message,
376 Logger* error_logger) {
James Darpinian0f56e9f32018-01-11 02:23:55377 std::string id_string = GLES2Util::GetStringEnum(id);
Saifuddin Hitawalae608efe62024-11-14 00:17:49378 // Suppresses GL_DEBUG_TYPE_PERFORMANCE log messages for web tests that can
379 // get sent to the JS console and cause unnecessary test failures due test
380 // output log expectation comparisons.
381 if (type == GL_DEBUG_TYPE_PERFORMANCE &&
382 error_logger->SuppressPerformanceLogs()) {
383 return;
384 } else if (type == GL_DEBUG_TYPE_ERROR && source == GL_DEBUG_SOURCE_API) {
James Darpinian0f56e9f32018-01-11 02:23:55385 error_logger->LogMessage(__FILE__, __LINE__,
386 " " + id_string + ": " + message);
387 } else {
388 error_logger->LogMessage(
389 __FILE__, __LINE__,
Geoff Langc33679e2025-05-28 15:56:58390 std::string("GL Driver Message (") + gl::GetDebugSourceString(source) +
391 ", " + gl::GetDebugTypeString(type) + ", " + id_string + ", " +
392 gl::GetDebugSeverityString(severity) + "): " + message);
James Darpinian0f56e9f32018-01-11 02:23:55393 }
geofflang326c8512016-11-03 15:11:28394}
395
Geoff Langfdec674e2018-02-22 17:40:29396void InitializeGLDebugLogging(bool log_non_errors,
397 GLDEBUGPROC callback,
398 const void* user_param) {
geofflang326c8512016-11-03 15:11:28399 glEnable(GL_DEBUG_OUTPUT);
400 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
401
James Darpinian0f56e9f32018-01-11 02:23:55402 glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE,
403 0, nullptr, GL_TRUE);
geofflang326c8512016-11-03 15:11:28404
James Darpinian0f56e9f32018-01-11 02:23:55405 if (log_non_errors) {
406 // Enable logging of medium and high severity messages
407 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0,
408 nullptr, GL_TRUE);
409 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
410 0, nullptr, GL_TRUE);
411 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
412 nullptr, GL_FALSE);
413 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
414 GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
415 }
416
Geoff Langfdec674e2018-02-22 17:40:29417 glDebugMessageCallback(callback, user_param);
geofflang326c8512016-11-03 15:11:28418}
419
Geoff Langab3a2e82017-06-12 18:53:38420bool ValidContextLostReason(GLenum reason) {
421 switch (reason) {
422 case GL_NO_ERROR:
Geoff Lang8fc21cd2025-05-26 13:13:29423 case GL_GUILTY_CONTEXT_RESET:
424 case GL_INNOCENT_CONTEXT_RESET:
425 case GL_UNKNOWN_CONTEXT_RESET:
Geoff Langab3a2e82017-06-12 18:53:38426 return true;
427 default:
428 return false;
429 }
430}
431
Geoff Langf44323ed2017-06-07 18:10:15432error::ContextLostReason GetContextLostReasonFromResetStatus(
433 GLenum reset_status) {
434 switch (reset_status) {
435 case GL_NO_ERROR:
436 // TODO(kbr): improve the precision of the error code in this case.
437 // Consider delegating to context for error code if MakeCurrent fails.
438 return error::kUnknown;
Geoff Lang8fc21cd2025-05-26 13:13:29439 case GL_GUILTY_CONTEXT_RESET:
Geoff Langf44323ed2017-06-07 18:10:15440 return error::kGuilty;
Geoff Lang8fc21cd2025-05-26 13:13:29441 case GL_INNOCENT_CONTEXT_RESET:
Geoff Langf44323ed2017-06-07 18:10:15442 return error::kInnocent;
Geoff Lang8fc21cd2025-05-26 13:13:29443 case GL_UNKNOWN_CONTEXT_RESET:
Geoff Langf44323ed2017-06-07 18:10:15444 return error::kUnknown;
445 }
446
Peter BostrΓΆma11556e2024-10-31 04:49:10447 NOTREACHED();
Geoff Langf44323ed2017-06-07 18:10:15448}
449
Jonathan Backerc26060e2018-03-29 15:06:29450bool GetCompressedTexSizeInBytes(const char* function_name,
451 GLsizei width,
452 GLsizei height,
453 GLsizei depth,
454 GLenum format,
455 GLsizei* size_in_bytes,
456 ErrorState* error_state) {
457 base::CheckedNumeric<GLsizei> bytes_required(0);
458
459 switch (format) {
460 case GL_ATC_RGB_AMD:
461 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
462 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
463 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
464 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
465 case GL_ETC1_RGB8_OES:
466 bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
467 bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
468 bytes_required *= kS3TCDXT1BlockSize;
469 break;
470 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
471 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
472 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
473 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
474 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
475 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
476 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
477 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
478 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
479 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
480 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
481 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
482 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
483 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
484 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
485 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
486 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
487 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
488 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
489 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
490 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
491 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
492 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
493 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
494 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
495 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
496 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
497 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
498 const int index =
499 (format < GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
500 ? static_cast<int>(format - GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
501 : static_cast<int>(format -
502 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
503
504 const int kBlockWidth = kASTCBlockArray[index].blockWidth;
505 const int kBlockHeight = kASTCBlockArray[index].blockHeight;
506
507 bytes_required = (width + kBlockWidth - 1) / kBlockWidth;
508 bytes_required *= (height + kBlockHeight - 1) / kBlockHeight;
509
510 bytes_required *= kASTCBlockSize;
511 break;
512 }
513 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
514 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
515 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
516 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
517 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
518 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
519 bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
520 bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
521 bytes_required *= kS3TCDXT3AndDXT5BlockSize;
522 break;
523 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
524 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
525 bytes_required = std::max(width, 8);
526 bytes_required *= std::max(height, 8);
527 bytes_required *= 4;
528 bytes_required += 7;
529 bytes_required /= 8;
530 break;
531 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
532 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
533 bytes_required = std::max(width, 16);
534 bytes_required *= std::max(height, 8);
535 bytes_required *= 2;
536 bytes_required += 7;
537 bytes_required /= 8;
538 break;
539
540 // ES3 formats.
541 case GL_COMPRESSED_R11_EAC:
542 case GL_COMPRESSED_SIGNED_R11_EAC:
543 case GL_COMPRESSED_RGB8_ETC2:
544 case GL_COMPRESSED_SRGB8_ETC2:
545 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
546 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
547 bytes_required =
548 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
549 bytes_required *=
550 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
551 bytes_required *= 8;
552 bytes_required *= depth;
553 break;
554 case GL_COMPRESSED_RG11_EAC:
555 case GL_COMPRESSED_SIGNED_RG11_EAC:
556 case GL_COMPRESSED_RGBA8_ETC2_EAC:
557 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
558 bytes_required =
559 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
560 bytes_required *=
561 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
562 bytes_required *= 16;
563 bytes_required *= depth;
564 break;
shrekshaode2f6f32020-02-07 02:39:44565 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
566 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
567 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
568 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
569 bytes_required = (width + kBPTCBlockWidth - 1) / kBPTCBlockWidth;
570 bytes_required *= (height + kBPTCBlockHeight - 1) / kBPTCBlockHeight;
571 bytes_required *= 16;
572 bytes_required *= depth;
573 break;
shrekshao3c058332020-02-11 00:00:12574 case GL_COMPRESSED_RED_RGTC1_EXT:
575 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
shrekshaoeae7c512020-02-11 22:06:27576 bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
577 bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
578 bytes_required *= 8;
579 bytes_required *= depth;
580 break;
shrekshao3c058332020-02-11 00:00:12581 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
582 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
583 bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
584 bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
shrekshaoeae7c512020-02-11 22:06:27585 bytes_required *= 16;
shrekshao3c058332020-02-11 00:00:12586 bytes_required *= depth;
587 break;
Jonathan Backerc26060e2018-03-29 15:06:29588 default:
Geoff Lang72fe4762018-10-19 15:11:36589 if (function_name && error_state) {
590 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name, format,
591 "format");
592 }
Jonathan Backerc26060e2018-03-29 15:06:29593 return false;
594 }
595
596 if (!bytes_required.IsValid()) {
Geoff Lang72fe4762018-10-19 15:11:36597 if (function_name && error_state) {
598 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
599 "invalid size");
600 }
Jonathan Backerc26060e2018-03-29 15:06:29601 return false;
602 }
603
604 *size_in_bytes = bytes_required.ValueOrDefault(0);
605 return true;
606}
607
shrekshaofb226c242020-02-19 00:37:12608bool ValidateCompressedFormatTarget(GLenum target, GLenum format) {
609 if (target == GL_TEXTURE_3D) {
610 // Formats not supporting 3D Tex
611 switch (format) {
612 // ES 3.1, Section 8.7, page 169.
613 case GL_COMPRESSED_R11_EAC:
614 case GL_COMPRESSED_SIGNED_R11_EAC:
615 case GL_COMPRESSED_RG11_EAC:
616 case GL_COMPRESSED_SIGNED_RG11_EAC:
617 case GL_COMPRESSED_RGB8_ETC2:
618 case GL_COMPRESSED_SRGB8_ETC2:
619 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
620 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
621 case GL_COMPRESSED_RGBA8_ETC2_EAC:
622 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
shrekshaofb226c242020-02-19 00:37:12623 // GL_EXT_texture_compression_s3tc
624 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
625 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
626 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
627 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
628 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
629 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
630 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
631 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
632 // GL_EXT_texture_compression_rgtc
633 case GL_COMPRESSED_RED_RGTC1_EXT:
634 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
635 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
636 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
637 return false;
shrekshaoad4525482020-03-12 00:30:55638 // GL_KHR_texture_compression_astc_hdr, TEXTURE_3D is not supported
639 // without HDR profile. This is guaranteed to be validated beforehand
640 // in GLES2DecoderImpl::TexStorageImpl before calling this.
shrekshaofb226c242020-02-19 00:37:12641 default:
642 break;
643 }
644 }
645
646 return true;
647}
648
Daniel Bratell60acbb592018-07-26 09:13:14649bool ValidateCompressedTexSubDimensions(GLenum target,
650 GLint level,
651 GLint xoffset,
652 GLint yoffset,
653 GLint zoffset,
654 GLsizei width,
655 GLsizei height,
656 GLsizei depth,
657 GLenum format,
658 Texture* texture,
Daniel Bratell60acbb592018-07-26 09:13:14659 const char** error_message) {
shrekshaofb226c242020-02-19 00:37:12660 if (!ValidateCompressedFormatTarget(target, format)) {
661 *error_message = "target invalid for format";
662 return false;
663 }
664
Daniel Bratell60acbb592018-07-26 09:13:14665 if (xoffset < 0 || yoffset < 0 || zoffset < 0) {
666 *error_message = "x/y/z offset < 0";
667 return false;
668 }
669
670 switch (format) {
671 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
672 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
674 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
675 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
676 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
677 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
678 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: {
679 const int kBlockWidth = 4;
680 const int kBlockHeight = 4;
681 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
682 *error_message = "xoffset or yoffset not multiple of 4";
683 return false;
684 }
685 GLsizei tex_width = 0;
686 GLsizei tex_height = 0;
687 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
688 nullptr) ||
689 width - xoffset > tex_width || height - yoffset > tex_height) {
690 *error_message = "dimensions out of range";
691 return false;
692 }
693 if ((((width % kBlockWidth) != 0) && (width + xoffset != tex_width)) ||
694 (((height % kBlockHeight) != 0) &&
695 (height + yoffset != tex_height))) {
696 *error_message = "dimensions do not align to a block boundary";
697 return false;
698 }
699 return true;
700 }
701 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
702 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
703 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
704 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
705 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
706 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
707 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
708 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
709 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
710 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
711 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
712 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
713 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
714 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
715 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
716 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
717 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
718 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
719 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
720 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
721 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
722 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
723 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
724 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
725 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
726 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
727 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
728 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
729 const int index =
730 (format < GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
731 ? static_cast<int>(format - GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
732 : static_cast<int>(format -
733 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
734
735 const int kBlockWidth = kASTCBlockArray[index].blockWidth;
736 const int kBlockHeight = kASTCBlockArray[index].blockHeight;
737
738 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
739 *error_message = "xoffset or yoffset not multiple of 4";
740 return false;
741 }
742 GLsizei tex_width = 0;
743 GLsizei tex_height = 0;
744 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
745 nullptr) ||
746 width - xoffset > tex_width || height - yoffset > tex_height) {
747 *error_message = "dimensions out of range";
748 return false;
749 }
750 if ((((width % kBlockWidth) != 0) && (width + xoffset != tex_width)) ||
751 (((height % kBlockHeight) != 0) &&
752 (height + yoffset != tex_height))) {
753 *error_message = "dimensions do not align to a block boundary";
754 return false;
755 }
756 return true;
757 }
758 case GL_ATC_RGB_AMD:
759 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
760 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
761 *error_message = "not supported for ATC textures";
762 return false;
763 }
764 case GL_ETC1_RGB8_OES: {
765 *error_message = "not supported for ECT1_RGB8_OES textures";
766 return false;
767 }
768 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
769 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
770 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
771 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
772 if ((xoffset != 0) || (yoffset != 0)) {
773 *error_message = "xoffset and yoffset must be zero";
774 return false;
775 }
776 GLsizei tex_width = 0;
777 GLsizei tex_height = 0;
778 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
779 nullptr) ||
780 width != tex_width || height != tex_height) {
781 *error_message =
782 "dimensions must match existing texture level dimensions";
783 return false;
784 }
785 return ValidateCompressedTexDimensions(target, level, width, height, 1,
Geoff Lang1cabc702019-04-26 01:30:18786 format, error_message);
Daniel Bratell60acbb592018-07-26 09:13:14787 }
788
789 // ES3 formats
790 case GL_COMPRESSED_R11_EAC:
791 case GL_COMPRESSED_SIGNED_R11_EAC:
792 case GL_COMPRESSED_RG11_EAC:
793 case GL_COMPRESSED_SIGNED_RG11_EAC:
794 case GL_COMPRESSED_RGB8_ETC2:
795 case GL_COMPRESSED_SRGB8_ETC2:
796 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
797 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
798 case GL_COMPRESSED_RGBA8_ETC2_EAC:
shrekshao41abf0c2020-02-19 02:09:42799 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
shrekshao41abf0c2020-02-19 02:09:42800 case GL_COMPRESSED_RED_RGTC1_EXT:
801 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
802 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
803 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: {
shrekshaob70dfea2020-07-08 23:17:09804 if (target == GL_TEXTURE_3D) {
805 *error_message = "target == GL_TEXTURE_3D is not allowed";
806 return false;
807 }
Roland Bock445b8152022-01-05 08:17:25808 [[fallthrough]];
shrekshaob70dfea2020-07-08 23:17:09809 }
810 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
811 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
812 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
813 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: {
Daniel Bratell60acbb592018-07-26 09:13:14814 const int kBlockSize = 4;
815 GLsizei tex_width, tex_height;
shrekshaob70dfea2020-07-08 23:17:09816 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height,
Daniel Bratell60acbb592018-07-26 09:13:14817 nullptr) ||
818 (xoffset % kBlockSize) || (yoffset % kBlockSize) ||
819 ((width % kBlockSize) && xoffset + width != tex_width) ||
820 ((height % kBlockSize) && yoffset + height != tex_height)) {
821 *error_message =
822 "dimensions must match existing texture level dimensions";
823 return false;
824 }
825 return true;
826 }
827 default:
828 *error_message = "unknown compressed texture format";
829 return false;
830 }
831}
832
833bool ValidateCompressedTexDimensions(GLenum target,
834 GLint level,
835 GLsizei width,
836 GLsizei height,
837 GLsizei depth,
838 GLenum format,
Daniel Bratell60acbb592018-07-26 09:13:14839 const char** error_message) {
shrekshaofb226c242020-02-19 00:37:12840 if (!ValidateCompressedFormatTarget(target, format)) {
841 *error_message = "target invalid for format";
842 return false;
843 }
Daniel Bratell60acbb592018-07-26 09:13:14844 switch (format) {
845 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
846 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
847 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
848 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
849 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
850 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
851 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
852 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
Geoff Lang1cabc702019-04-26 01:30:18853 if (!IsValidS3TCSizeForWebGLAndANGLE(level, width) ||
854 !IsValidS3TCSizeForWebGLAndANGLE(level, height)) {
Daniel Bratell60acbb592018-07-26 09:13:14855 *error_message = "width or height invalid for level";
856 return false;
857 }
858 return true;
859 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
860 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
861 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
862 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
863 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
864 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
865 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
866 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
867 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
868 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
869 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
870 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
871 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
872 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
873 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
874 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
875 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
876 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
877 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
878 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
879 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
880 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
881 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
882 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
883 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
884 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
885 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
886 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
887 case GL_ATC_RGB_AMD:
888 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
889 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
890 case GL_ETC1_RGB8_OES:
Daniel Bratell60acbb592018-07-26 09:13:14891 if (width <= 0 || height <= 0) {
892 *error_message = "width or height invalid for level";
893 return false;
894 }
895 return true;
896 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
897 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
898 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
899 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
Daniel Bratell60acbb592018-07-26 09:13:14900 if (!IsValidPVRTCSize(level, width) || !IsValidPVRTCSize(level, height)) {
901 *error_message = "width or height invalid for level";
902 return false;
903 }
904 return true;
905
906 // ES3 formats.
907 case GL_COMPRESSED_R11_EAC:
908 case GL_COMPRESSED_SIGNED_R11_EAC:
909 case GL_COMPRESSED_RG11_EAC:
910 case GL_COMPRESSED_SIGNED_RG11_EAC:
911 case GL_COMPRESSED_RGB8_ETC2:
912 case GL_COMPRESSED_SRGB8_ETC2:
913 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
914 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
915 case GL_COMPRESSED_RGBA8_ETC2_EAC:
916 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
917 if (width < 0 || height < 0 || depth < 0) {
918 *error_message = "width, height, or depth invalid";
919 return false;
920 }
Daniel Bratell60acbb592018-07-26 09:13:14921 return true;
shrekshaode2f6f32020-02-07 02:39:44922 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
923 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
924 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
925 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
926 if (width < 0 || height < 0 || depth < 0) {
927 *error_message = "width, height, or depth invalid";
928 return false;
929 }
shrekshaob70dfea2020-07-08 23:17:09930 if (level == 0 &&
931 !(width % kBPTCBlockWidth == 0 && height % kBPTCBlockHeight == 0)) {
shrekshaode2f6f32020-02-07 02:39:44932 *error_message = "width or height is not a multiple of four";
933 return false;
934 }
935 return true;
shrekshao3c058332020-02-11 00:00:12936 case GL_COMPRESSED_RED_RGTC1_EXT:
937 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
938 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
939 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_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 % kRGTCBlockWidth == 0 && height % kRGTCBlockHeight == 0)) {
shrekshao3c058332020-02-11 00:00:12946 *error_message = "width or height is not a multiple of four";
947 return false;
948 }
949 return true;
Daniel Bratell60acbb592018-07-26 09:13:14950 default:
951 return false;
952 }
953}
954
Jonathan Backer8629c392018-04-04 23:01:03955bool ValidateCopyTexFormatHelper(const FeatureInfo* feature_info,
956 GLenum internal_format,
957 GLenum read_format,
958 GLenum read_type,
959 std::string* output_error_msg) {
960 DCHECK(output_error_msg);
961 if (read_format == 0) {
962 *output_error_msg = std::string("no valid color image");
963 return false;
964 }
965 // Check we have compatible formats.
966 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format);
967 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
968 if (!channels_needed ||
969 (channels_needed & channels_exist) != channels_needed) {
970 *output_error_msg = std::string("incompatible format");
971 return false;
972 }
Jiajia Qin252a8132018-07-19 01:03:22973 if (feature_info->IsWebGL2OrES3OrHigherContext()) {
Jonathan Backer8629c392018-04-04 23:01:03974 GLint color_encoding =
975 GLES2Util::GetColorEncodingFromInternalFormat(read_format);
976 bool float_mismatch = feature_info->ext_color_buffer_float_available()
977 ? (GLES2Util::IsIntegerFormat(internal_format) !=
978 GLES2Util::IsIntegerFormat(read_format))
979 : GLES2Util::IsFloatFormat(internal_format);
980 if (color_encoding !=
981 GLES2Util::GetColorEncodingFromInternalFormat(internal_format) ||
982 float_mismatch ||
983 (GLES2Util::IsSignedIntegerFormat(internal_format) !=
984 GLES2Util::IsSignedIntegerFormat(read_format)) ||
985 (GLES2Util::IsUnsignedIntegerFormat(internal_format) !=
986 GLES2Util::IsUnsignedIntegerFormat(read_format))) {
987 *output_error_msg = std::string("incompatible format");
988 return false;
989 }
990 }
991 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
992 *output_error_msg =
993 std::string("can not be used with depth or stencil textures");
994 return false;
995 }
Jiajia Qin252a8132018-07-19 01:03:22996 if (feature_info->IsWebGL2OrES3OrHigherContext() ||
Jonathan Backer8629c392018-04-04 23:01:03997 (feature_info->feature_flags().chromium_color_buffer_float_rgb &&
998 internal_format == GL_RGB32F) ||
999 (feature_info->feature_flags().chromium_color_buffer_float_rgba &&
1000 internal_format == GL_RGBA32F)) {
1001 if (GLES2Util::IsSizedColorFormat(internal_format)) {
1002 int sr, sg, sb, sa;
1003 GLES2Util::GetColorFormatComponentSizes(read_format, read_type, &sr, &sg,
1004 &sb, &sa);
1005 DCHECK(sr > 0 || sg > 0 || sb > 0 || sa > 0);
1006 int dr, dg, db, da;
1007 GLES2Util::GetColorFormatComponentSizes(internal_format, 0, &dr, &dg, &db,
1008 &da);
1009 DCHECK(dr > 0 || dg > 0 || db > 0 || da > 0);
1010 if ((dr > 0 && sr != dr) || (dg > 0 && sg != dg) ||
1011 (db > 0 && sb != db) || (da > 0 && sa != da)) {
1012 *output_error_msg = std::string("incompatible color component sizes");
1013 return false;
1014 }
1015 }
1016 }
1017 return true;
1018}
1019
1020CopyTextureMethod GetCopyTextureCHROMIUMMethod(const FeatureInfo* feature_info,
1021 GLenum source_target,
1022 GLint source_level,
1023 GLenum source_internal_format,
1024 GLenum source_type,
1025 GLenum dest_target,
1026 GLint dest_level,
1027 GLenum dest_internal_format,
1028 bool flip_y,
1029 bool premultiply_alpha,
Corentin Wallezcacc4172021-12-03 14:40:221030 bool unpremultiply_alpha) {
Jonathan Backer8629c392018-04-04 23:01:031031 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
1032 bool source_format_color_renderable =
1033 Texture::ColorRenderable(feature_info, source_internal_format, false);
1034 bool dest_format_color_renderable =
1035 Texture::ColorRenderable(feature_info, dest_internal_format, false);
1036 std::string output_error_msg;
1037
1038 switch (dest_internal_format) {
Xiaohan Wangfa22d3e2022-01-15 02:02:431039#if BUILDFLAG(IS_MAC)
Jonathan Backer8629c392018-04-04 23:01:031040 // RGB5_A1 is not color-renderable on NVIDIA Mac, see
1041 // https://crbug.com/676209.
1042 case GL_RGB5_A1:
1043 return CopyTextureMethod::DRAW_AND_READBACK;
1044#endif
1045 // RGB9_E5 isn't accepted by glCopyTexImage2D if underlying context is ES.
1046 case GL_RGB9_E5:
Zhenyao Mo12d741f2024-07-09 19:12:381047 return CopyTextureMethod::DRAW_AND_READBACK;
Jonathan Backer8629c392018-04-04 23:01:031048 // SRGB format has color-space conversion issue. WebGL spec doesn't define
1049 // clearly if linear-to-srgb color space conversion is required or not when
1050 // uploading DOM elements to SRGB textures. WebGL conformance test expects
1051 // no linear-to-srgb conversion, while current GPU path for
1052 // CopyTextureCHROMIUM does the conversion. Do a fallback path before the
1053 // issue is resolved. see https://github.com/KhronosGroup/WebGL/issues/2165.
1054 // TODO(qiankun.miao@intel.com): revisit this once the above issue is
1055 // resolved.
1056 case GL_SRGB_EXT:
1057 case GL_SRGB_ALPHA_EXT:
1058 case GL_SRGB8:
1059 case GL_SRGB8_ALPHA8:
1060 if (feature_info->IsWebGLContext())
1061 return CopyTextureMethod::DRAW_AND_READBACK;
1062 break;
1063 default:
1064 break;
1065 }
1066
1067 // CopyTexImage* should not allow internalformat of GL_BGRA_EXT and
1068 // GL_BGRA8_EXT. https://crbug.com/663086.
1069 bool copy_tex_image_format_valid =
1070 source_internal_format != GL_BGRA_EXT &&
1071 dest_internal_format != GL_BGRA_EXT &&
1072 source_internal_format != GL_BGRA8_EXT &&
1073 dest_internal_format != GL_BGRA8_EXT &&
1074 ValidateCopyTexFormatHelper(feature_info, dest_internal_format,
1075 source_internal_format, source_type,
1076 &output_error_msg);
1077
Antoine Labour4885296a2019-05-09 02:38:391078 // The ES3 spec is vague about whether or not glCopyTexImage2D from a
1079 // GL_RGB10_A2 attachment to an unsized internal format is valid. Most drivers
1080 // interpreted the explicit call out as not valid (and dEQP actually checks
1081 // this), so avoid DIRECT_COPY in that case.
Zhenyao Mo12d741f2024-07-09 19:12:381082 if (source_internal_format == GL_RGB10_A2 &&
1083 dest_internal_format != source_internal_format) {
Antoine Labour4885296a2019-05-09 02:38:391084 copy_tex_image_format_valid = false;
Zhenyao Mo12d741f2024-07-09 19:12:381085 }
Antoine Labour4885296a2019-05-09 02:38:391086
Jonathan Backer8629c392018-04-04 23:01:031087 // TODO(qiankun.miao@intel.com): for WebGL 2.0 or OpenGL ES 3.0, both
1088 // DIRECT_DRAW path for dest_level > 0 and DIRECT_COPY path for source_level >
1089 // 0 are not available due to a framebuffer completeness bug:
1090 // https://crbug.com/678526. Once the bug is fixed, the limitation for WebGL
1091 // 2.0 and OpenGL ES 3.0 can be lifted. For WebGL 1.0 or OpenGL ES 2.0,
1092 // DIRECT_DRAW path isn't available for dest_level > 0 due to level > 0 isn't
1093 // supported by glFramebufferTexture2D in ES2 context. DIRECT_DRAW path isn't
1094 // available for cube map dest texture either due to it may be cube map
1095 // incomplete. Go to DRAW_AND_COPY path in these cases.
1096 if (source_target == GL_TEXTURE_2D &&
1097 (dest_target == GL_TEXTURE_2D || dest_target == GL_TEXTURE_CUBE_MAP) &&
1098 source_format_color_renderable && copy_tex_image_format_valid &&
Corentin Wallezcacc4172021-12-03 14:40:221099 source_level == 0 && !flip_y && !premultiply_alpha_change) {
shrekshaob437fb192020-01-30 07:39:571100 auto source_texture_type = GLES2Util::GetGLReadPixelsImplementationType(
1101 source_internal_format, source_target);
1102 auto dest_texture_type = GLES2Util::GetGLReadPixelsImplementationType(
1103 dest_internal_format, dest_target);
1104 if (source_texture_type != GL_UNSIGNED_SHORT ||
1105 source_texture_type == dest_texture_type) {
1106 // https://crbug.com/1042239. As it is stated in the latest OpenGL ES 3.2
1107 // spec (Oct 22, 2019) it is optional for implementation to support
1108 // conversion between unmatched source and dest effective internal format.
1109 // R16 to R16F direct copy failure is seen on Android Nvidia shield
1110 // devices. So we won't use DIRECT_COPY for this format.
1111 return CopyTextureMethod::DIRECT_COPY;
1112 }
1113 }
Jonathan Backer8629c392018-04-04 23:01:031114 if (dest_format_color_renderable && dest_level == 0 &&
1115 dest_target != GL_TEXTURE_CUBE_MAP)
1116 return CopyTextureMethod::DIRECT_DRAW;
1117
1118 // Draw to a fbo attaching level 0 of an intermediate texture,
1119 // then copy from the fbo to dest texture level with glCopyTexImage2D.
1120 return CopyTextureMethod::DRAW_AND_COPY;
1121}
1122
Jonathan Backer4cb165c82018-07-03 20:25:331123bool ValidateCopyTextureCHROMIUMInternalFormats(const FeatureInfo* feature_info,
1124 GLenum source_internal_format,
1125 GLenum dest_internal_format,
1126 std::string* output_error_msg) {
1127 bool valid_dest_format = false;
1128 // TODO(qiankun.miao@intel.com): ALPHA, LUMINANCE and LUMINANCE_ALPHA formats
1129 // are not supported on GL core profile. See https://crbug.com/577144. Enable
1130 // the workaround for glCopyTexImage and glCopyTexSubImage in
1131 // gles2_cmd_copy_tex_image.cc for glCopyTextureCHROMIUM implementation.
1132 switch (dest_internal_format) {
1133 case GL_RGB:
1134 case GL_RGBA:
1135 case GL_RGB8:
1136 case GL_RGBA8:
1137 valid_dest_format = true;
1138 break;
1139 case GL_BGRA_EXT:
1140 case GL_BGRA8_EXT:
1141 valid_dest_format =
1142 feature_info->feature_flags().ext_texture_format_bgra8888;
1143 break;
1144 case GL_SRGB_EXT:
1145 case GL_SRGB_ALPHA_EXT:
1146 valid_dest_format = feature_info->feature_flags().ext_srgb;
1147 break;
1148 case GL_R8:
1149 case GL_R8UI:
1150 case GL_RG8:
1151 case GL_RG8UI:
1152 case GL_SRGB8:
1153 case GL_RGB565:
1154 case GL_RGB8UI:
1155 case GL_SRGB8_ALPHA8:
1156 case GL_RGB5_A1:
1157 case GL_RGBA4:
1158 case GL_RGBA8UI:
1159 case GL_RGB10_A2:
Jiajia Qin252a8132018-07-19 01:03:221160 valid_dest_format = feature_info->IsWebGL2OrES3OrHigherContext();
Jonathan Backer4cb165c82018-07-03 20:25:331161 break;
1162 case GL_RGB9_E5:
1163 case GL_R16F:
1164 case GL_R32F:
1165 case GL_RG16F:
1166 case GL_RG32F:
1167 case GL_RGB16F:
1168 case GL_RGBA16F:
1169 case GL_R11F_G11F_B10F:
1170 valid_dest_format = feature_info->ext_color_buffer_float_available();
1171 break;
1172 case GL_RGB32F:
1173 valid_dest_format =
1174 feature_info->ext_color_buffer_float_available() ||
1175 feature_info->feature_flags().chromium_color_buffer_float_rgb;
1176 break;
1177 case GL_RGBA32F:
1178 valid_dest_format =
1179 feature_info->ext_color_buffer_float_available() ||
1180 feature_info->feature_flags().chromium_color_buffer_float_rgba;
1181 break;
1182 case GL_ALPHA:
1183 case GL_LUMINANCE:
1184 case GL_LUMINANCE_ALPHA:
1185 valid_dest_format = true;
1186 break;
1187 default:
1188 valid_dest_format = false;
1189 break;
1190 }
1191
1192 // TODO(aleksandar.stojiljkovic): Use sized internal formats:
1193 // https://crbug.com/628064
1194 bool valid_source_format =
1195 source_internal_format == GL_RED || source_internal_format == GL_ALPHA ||
1196 source_internal_format == GL_RGB || source_internal_format == GL_RGBA ||
1197 source_internal_format == GL_RGB8 || source_internal_format == GL_RGBA8 ||
1198 source_internal_format == GL_LUMINANCE ||
1199 source_internal_format == GL_LUMINANCE_ALPHA ||
1200 source_internal_format == GL_BGRA_EXT ||
1201 source_internal_format == GL_BGRA8_EXT ||
Miguel Casas94f82b22019-01-31 21:20:571202 source_internal_format == GL_R16_EXT ||
shrekshaob437fb192020-01-30 07:39:571203 source_internal_format == GL_RG16_EXT ||
1204 source_internal_format == GL_RGBA16_EXT ||
Miguel Casas94f82b22019-01-31 21:20:571205 source_internal_format == GL_RGB10_A2;
Jonathan Backer4cb165c82018-07-03 20:25:331206 if (!valid_source_format) {
1207 *output_error_msg = "invalid source internal format " +
1208 GLES2Util::GetStringEnum(source_internal_format);
1209 return false;
1210 }
1211 if (!valid_dest_format) {
1212 *output_error_msg = "invalid dest internal format " +
1213 GLES2Util::GetStringEnum(dest_internal_format);
1214 return false;
1215 }
1216
1217 return true;
1218}
1219
Geoff Lang18c8f3d82019-07-08 23:20:331220GLenum GetTextureBindingQuery(GLenum texture_type) {
1221 switch (texture_type) {
1222 case GL_TEXTURE_2D:
1223 return GL_TEXTURE_BINDING_2D;
1224 case GL_TEXTURE_2D_ARRAY:
1225 return GL_TEXTURE_BINDING_2D_ARRAY;
1226 case GL_TEXTURE_2D_MULTISAMPLE:
1227 return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
1228 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1229 return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
1230 case GL_TEXTURE_3D:
1231 return GL_TEXTURE_BINDING_3D;
1232 case GL_TEXTURE_EXTERNAL_OES:
1233 return GL_TEXTURE_BINDING_EXTERNAL_OES;
Geoff Lang8fc21cd2025-05-26 13:13:291234 case GL_TEXTURE_RECTANGLE_ANGLE:
1235 return GL_TEXTURE_BINDING_RECTANGLE_ANGLE;
Geoff Lang18c8f3d82019-07-08 23:20:331236 case GL_TEXTURE_CUBE_MAP:
1237 return GL_TEXTURE_BINDING_CUBE_MAP;
1238 default:
Peter BostrΓΆma11556e2024-10-31 04:49:101239 NOTREACHED();
Geoff Lang18c8f3d82019-07-08 23:20:331240 }
1241}
1242
shrekshaoad4525482020-03-12 00:30:551243bool IsASTCFormat(GLenum internal_format) {
1244 switch (internal_format) {
1245 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
1246 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
1247 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
1248 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
1249 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
1250 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1251 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
1252 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
1253 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
1254 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
1255 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
1256 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
1257 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
1258 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
1259 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
1260 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
1261 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
1262 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
1263 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
1264 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
1265 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
1266 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
1267 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
1268 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
1269 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
1270 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
1271 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
1272 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
1273 return true;
1274 default:
1275 break;
1276 }
1277 return false;
1278}
1279
1280// This is only called in Texture::SetLevelInfo in texture_manager.cc
1281// where there is no direct access to decoder->IsCompressedTextureFormat
1282// or feature_info->validators()->compressed_texture_format.IsValid
1283bool IsCompressedTextureFormat(GLenum internal_format) {
1284 switch (internal_format) {
1285 // S3TC
1286 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1287 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1288 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1289 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1290 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1291 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1292 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1293 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1294 // ASTC
1295 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
1296 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
1297 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
1298 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
1299 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
1300 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1301 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
1302 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
1303 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
1304 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
1305 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
1306 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
1307 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
1308 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
1309 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
1310 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
1311 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
1312 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
1313 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
1314 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
1315 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
1316 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
1317 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
1318 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
1319 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
1320 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
1321 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
1322 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
1323 // BPTC
1324 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
1325 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
1326 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
1327 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
1328 // RGTC
1329 case GL_COMPRESSED_RED_RGTC1_EXT:
1330 case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
1331 case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
1332 case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
1333 // ETC2/EAC
1334 case GL_COMPRESSED_R11_EAC:
1335 case GL_COMPRESSED_SIGNED_R11_EAC:
1336 case GL_COMPRESSED_RGB8_ETC2:
1337 case GL_COMPRESSED_SRGB8_ETC2:
1338 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1339 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1340 case GL_COMPRESSED_RG11_EAC:
1341 case GL_COMPRESSED_SIGNED_RG11_EAC:
1342 case GL_COMPRESSED_RGBA8_ETC2_EAC:
1343 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1344 // ETC1
1345 case GL_ETC1_RGB8_OES:
1346 // PVRTC
1347 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
1348 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
1349 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
1350 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
1351 // ATC
1352 case GL_ATC_RGB_AMD:
1353 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
1354 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
1355 return true;
1356 default:
1357 break;
1358 }
1359 return false;
1360}
1361
Saifuddin Hitawala151bf3bf2022-07-19 19:03:141362Texture* CreateGLES2TextureWithLightRef(GLuint service_id, GLenum target) {
1363 Texture* texture = new Texture(service_id);
1364 texture->SetLightweightRef();
1365 texture->SetTarget(target, 1 /*max_levels=*/);
1366 texture->set_min_filter(GL_LINEAR);
1367 texture->set_mag_filter(GL_LINEAR);
1368 texture->set_wrap_t(GL_CLAMP_TO_EDGE);
1369 texture->set_wrap_s(GL_CLAMP_TO_EDGE);
1370 return texture;
1371}
1372
junov0cad1f42016-01-07 21:48:511373} // namespace gles2
1374} // namespace gpu