18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#include "device_gles.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <algorithm> 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ci#include <base/containers/string.h> 218bf80f4bSopenharmony_ci#include <base/math/vector.h> 228bf80f4bSopenharmony_ci#include <base/util/compile_time_hashes.h> 238bf80f4bSopenharmony_ci#include <render/namespace.h> 248bf80f4bSopenharmony_ci 258bf80f4bSopenharmony_ci#include "device/gpu_program_util.h" 268bf80f4bSopenharmony_ci#include "device/gpu_resource_manager.h" 278bf80f4bSopenharmony_ci#include "device/shader_manager.h" 288bf80f4bSopenharmony_ci#include "device/shader_module.h" 298bf80f4bSopenharmony_ci#include "gles/gl_functions.h" 308bf80f4bSopenharmony_ci#include "gles/gpu_buffer_gles.h" 318bf80f4bSopenharmony_ci#include "gles/gpu_image_gles.h" 328bf80f4bSopenharmony_ci#include "gles/gpu_program_gles.h" 338bf80f4bSopenharmony_ci#include "gles/gpu_sampler_gles.h" 348bf80f4bSopenharmony_ci#include "gles/gpu_semaphore_gles.h" 358bf80f4bSopenharmony_ci#include "gles/node_context_descriptor_set_manager_gles.h" 368bf80f4bSopenharmony_ci#include "gles/node_context_pool_manager_gles.h" 378bf80f4bSopenharmony_ci#include "gles/pipeline_state_object_gles.h" 388bf80f4bSopenharmony_ci#include "gles/render_backend_gles.h" 398bf80f4bSopenharmony_ci#include "gles/render_frame_sync_gles.h" 408bf80f4bSopenharmony_ci#include "gles/shader_module_gles.h" 418bf80f4bSopenharmony_ci#include "gles/swapchain_gles.h" 428bf80f4bSopenharmony_ci#include "util/log.h" 438bf80f4bSopenharmony_ci 448bf80f4bSopenharmony_ciusing namespace BASE_NS; 458bf80f4bSopenharmony_ci 468bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE() 478bf80f4bSopenharmony_cinamespace { 488bf80f4bSopenharmony_ci// Make all temporary binds to unit GL_TEXTURE15. (should use the last available unit, so as to least affect actual 498bf80f4bSopenharmony_ci// usage) "The number of texture units is implementation-dependent, but must be at least 32. texture must be one of 508bf80f4bSopenharmony_ci// GL_TEXTUREi, where i ranges from zero to the value of GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS minus one." Currently our 518bf80f4bSopenharmony_ci// there is an implementation limit in our resource caching which limits it to 16... (this is why we use 16 instead of 528bf80f4bSopenharmony_ci// 32) 538bf80f4bSopenharmony_ciconstexpr const uint32_t TEMP_BIND_UNIT = 15; 548bf80f4bSopenharmony_ciconstexpr const string_view EXT_BUFFER_STORAGE = "GL_EXT_buffer_storage"; 558bf80f4bSopenharmony_ci#if RENDER_GL_DEBUG 568bf80f4bSopenharmony_ci#define DUMP(a) \ 578bf80f4bSopenharmony_ci { \ 588bf80f4bSopenharmony_ci GLint val; \ 598bf80f4bSopenharmony_ci glGetIntegerv(a, &val); \ 608bf80f4bSopenharmony_ci PLUGIN_LOG_V(#a ": %d", val); \ 618bf80f4bSopenharmony_ci } 628bf80f4bSopenharmony_ci 638bf80f4bSopenharmony_ci#define DUMP_INDEX(a, index) \ 648bf80f4bSopenharmony_ci { \ 658bf80f4bSopenharmony_ci GLint val; \ 668bf80f4bSopenharmony_ci glGetIntegeri_v(a, index, &val); \ 678bf80f4bSopenharmony_ci PLUGIN_LOG_V(#a "[%d]: %d", index, val); \ 688bf80f4bSopenharmony_ci } 698bf80f4bSopenharmony_ci 708bf80f4bSopenharmony_cistatic bool (*filterErrorFunc)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, 718bf80f4bSopenharmony_ci const string_view message, const void* userParam) noexcept = nullptr; 728bf80f4bSopenharmony_ci 738bf80f4bSopenharmony_cistatic auto SourceName(GLenum source) 748bf80f4bSopenharmony_ci{ 758bf80f4bSopenharmony_ci switch (source) { 768bf80f4bSopenharmony_ci case GL_DEBUG_SOURCE_API: 778bf80f4bSopenharmony_ci return "GL_DEBUG_SOURCE_API"; 788bf80f4bSopenharmony_ci case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 798bf80f4bSopenharmony_ci return "GL_DEBUG_SOURCE_WINDOW_SYSTEM"; 808bf80f4bSopenharmony_ci case GL_DEBUG_SOURCE_SHADER_COMPILER: 818bf80f4bSopenharmony_ci return "GL_DEBUG_SOURCE_SHADER_COMPILER"; 828bf80f4bSopenharmony_ci case GL_DEBUG_SOURCE_THIRD_PARTY: 838bf80f4bSopenharmony_ci return "GL_DEBUG_SOURCE_THIRD_PARTY"; 848bf80f4bSopenharmony_ci case GL_DEBUG_SOURCE_APPLICATION: 858bf80f4bSopenharmony_ci return "GL_DEBUG_SOURCE_APPLICATION"; 868bf80f4bSopenharmony_ci case GL_DEBUG_SOURCE_OTHER: 878bf80f4bSopenharmony_ci return "GL_DEBUG_SOURCE_OTHER"; 888bf80f4bSopenharmony_ci 898bf80f4bSopenharmony_ci default: 908bf80f4bSopenharmony_ci break; 918bf80f4bSopenharmony_ci } 928bf80f4bSopenharmony_ci return "UNKNOWN"; 938bf80f4bSopenharmony_ci} 948bf80f4bSopenharmony_ci 958bf80f4bSopenharmony_cistatic auto TypeName(GLenum type) 968bf80f4bSopenharmony_ci{ 978bf80f4bSopenharmony_ci switch (type) { 988bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_ERROR: 998bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_ERROR"; 1008bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 1018bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR"; 1028bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 1038bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR"; 1048bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_PORTABILITY: 1058bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_PORTABILITY"; 1068bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_PERFORMANCE: 1078bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_PERFORMANCE"; 1088bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_MARKER: 1098bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_MARKER"; 1108bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_PUSH_GROUP: 1118bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_PUSH_GROUP"; 1128bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_POP_GROUP: 1138bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_POP_GROUP"; 1148bf80f4bSopenharmony_ci case GL_DEBUG_TYPE_OTHER: 1158bf80f4bSopenharmony_ci return "GL_DEBUG_TYPE_OTHER"; 1168bf80f4bSopenharmony_ci 1178bf80f4bSopenharmony_ci default: 1188bf80f4bSopenharmony_ci break; 1198bf80f4bSopenharmony_ci } 1208bf80f4bSopenharmony_ci return "UNKNOWN"; 1218bf80f4bSopenharmony_ci} 1228bf80f4bSopenharmony_ci 1238bf80f4bSopenharmony_cistatic auto SeverityName(GLenum severity) 1248bf80f4bSopenharmony_ci{ 1258bf80f4bSopenharmony_ci switch (severity) { 1268bf80f4bSopenharmony_ci case GL_DEBUG_SEVERITY_LOW: 1278bf80f4bSopenharmony_ci return "GL_DEBUG_SEVERITY_LOW"; 1288bf80f4bSopenharmony_ci case GL_DEBUG_SEVERITY_MEDIUM: 1298bf80f4bSopenharmony_ci return "GL_DEBUG_SEVERITY_MEDIUM"; 1308bf80f4bSopenharmony_ci case GL_DEBUG_SEVERITY_HIGH: 1318bf80f4bSopenharmony_ci return "GL_DEBUG_SEVERITY_HIGH"; 1328bf80f4bSopenharmony_ci case GL_DEBUG_SEVERITY_NOTIFICATION: 1338bf80f4bSopenharmony_ci return "GL_DEBUG_SEVERITY_NOTIFICATION"; 1348bf80f4bSopenharmony_ci 1358bf80f4bSopenharmony_ci default: 1368bf80f4bSopenharmony_ci break; 1378bf80f4bSopenharmony_ci } 1388bf80f4bSopenharmony_ci return "UNKNOWN"; 1398bf80f4bSopenharmony_ci} 1408bf80f4bSopenharmony_ci 1418bf80f4bSopenharmony_ci#ifndef APIENTRY 1428bf80f4bSopenharmony_ci#define APIENTRY 1438bf80f4bSopenharmony_ci#endif 1448bf80f4bSopenharmony_cistatic void APIENTRY OnGlError(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, 1458bf80f4bSopenharmony_ci const GLchar* message, const void* userParam) noexcept 1468bf80f4bSopenharmony_ci{ 1478bf80f4bSopenharmony_ci if (type == GL_DEBUG_TYPE_PUSH_GROUP) { 1488bf80f4bSopenharmony_ci return; 1498bf80f4bSopenharmony_ci } else if (type == GL_DEBUG_TYPE_POP_GROUP) { 1508bf80f4bSopenharmony_ci return; 1518bf80f4bSopenharmony_ci } else if ((filterErrorFunc) && (filterErrorFunc(source, type, id, severity, length, message, userParam))) { 1528bf80f4bSopenharmony_ci return; 1538bf80f4bSopenharmony_ci } else if (type == GL_DEBUG_TYPE_ERROR) { 1548bf80f4bSopenharmony_ci PLUGIN_LOG_E("---------------------opengl-callback-start------------\n" 1558bf80f4bSopenharmony_ci "source: %s\n" 1568bf80f4bSopenharmony_ci "type: %s\n" 1578bf80f4bSopenharmony_ci "id: %u\n" 1588bf80f4bSopenharmony_ci "severity: %s\n" 1598bf80f4bSopenharmony_ci "message: %s\n" 1608bf80f4bSopenharmony_ci "---------------------opengl-callback-end--------------\n", 1618bf80f4bSopenharmony_ci SourceName(source), TypeName(type), id, SeverityName(severity), message); 1628bf80f4bSopenharmony_ci } else { 1638bf80f4bSopenharmony_ci PLUGIN_LOG_D("---------------------opengl-callback-start------------\n" 1648bf80f4bSopenharmony_ci "source: %s\n" 1658bf80f4bSopenharmony_ci "type: %s\n" 1668bf80f4bSopenharmony_ci "id: %u\n" 1678bf80f4bSopenharmony_ci "severity: %s\n" 1688bf80f4bSopenharmony_ci "message: %s\n" 1698bf80f4bSopenharmony_ci "---------------------opengl-callback-end--------------\n", 1708bf80f4bSopenharmony_ci SourceName(source), TypeName(type), id, SeverityName(severity), message); 1718bf80f4bSopenharmony_ci } 1728bf80f4bSopenharmony_ci} 1738bf80f4bSopenharmony_ci#else 1748bf80f4bSopenharmony_ci#define DUMP(a) 1758bf80f4bSopenharmony_ci#define DUMP_INDEX(a, index) 1768bf80f4bSopenharmony_ci#endif 1778bf80f4bSopenharmony_ci 1788bf80f4bSopenharmony_cistruct FormatFeatures { 1798bf80f4bSopenharmony_ci GLenum internalFormat; 1808bf80f4bSopenharmony_ci FormatFeatureFlags flags; 1818bf80f4bSopenharmony_ci}; 1828bf80f4bSopenharmony_ci 1838bf80f4bSopenharmony_ci// image store and atomic operations seem to go hand in hand 1848bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags ATOMIC_STORE = 1858bf80f4bSopenharmony_ci CORE_FORMAT_FEATURE_STORAGE_IMAGE_BIT | CORE_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT; 1868bf80f4bSopenharmony_ci// no writable texture buffers in gl? 1878bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags TEXEL_BUF = CORE_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; 1888bf80f4bSopenharmony_ci// color renderable 1898bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags CR = CORE_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; 1908bf80f4bSopenharmony_ci// texture filterable 1918bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags TF = CORE_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 1928bf80f4bSopenharmony_ci// required texture formats. assume can be sampled, and transfered to/from 1938bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags TEX = 1948bf80f4bSopenharmony_ci CORE_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | CORE_FORMAT_FEATURE_TRANSFER_SRC_BIT | CORE_FORMAT_FEATURE_TRANSFER_SRC_BIT; 1958bf80f4bSopenharmony_ci// required depth format 1968bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags DS = CORE_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | TEX | TF; 1978bf80f4bSopenharmony_ci 1988bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags TF_TEX = TF | TEX; 1998bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND 2008bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags CR_TEX = CR | TEX; // color renderable, texture format 2018bf80f4bSopenharmony_ci#endif 2028bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags CR_REND_TEX = CR | TEX; // color renderable, renderbuffer, texture format 2038bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 2048bf80f4bSopenharmony_cistatic constexpr const FormatFeatureFlags CR_TF_REND_TEX = CR | TF | TEX; 2058bf80f4bSopenharmony_ci#endif 2068bf80f4bSopenharmony_ci 2078bf80f4bSopenharmony_cistatic constexpr const FormatFeatures IMAGE_FORMAT_FEATURES[] = { 2088bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND 2098bf80f4bSopenharmony_ci { GL_R8, CR_TEX | ATOMIC_STORE | TEXEL_BUF }, 2108bf80f4bSopenharmony_ci { GL_R8_SNORM, CR_TEX | ATOMIC_STORE }, 2118bf80f4bSopenharmony_ci { GL_R16, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2128bf80f4bSopenharmony_ci { GL_R16_SNORM, CR_TEX | ATOMIC_STORE }, 2138bf80f4bSopenharmony_ci { GL_RG8, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2148bf80f4bSopenharmony_ci { GL_RG8_SNORM, CR_TEX | ATOMIC_STORE }, 2158bf80f4bSopenharmony_ci { GL_RG16, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2168bf80f4bSopenharmony_ci { GL_RG16_SNORM, CR_TEX | ATOMIC_STORE }, 2178bf80f4bSopenharmony_ci // R3_G3_B2 not in base format 2188bf80f4bSopenharmony_ci { GL_RGB4, CR_TEX }, 2198bf80f4bSopenharmony_ci // RGB5 not in base format 2208bf80f4bSopenharmony_ci { GL_RGB565, CR_REND_TEX }, 2218bf80f4bSopenharmony_ci { GL_RGB8, CR_TEX }, 2228bf80f4bSopenharmony_ci { GL_RGB8_SNORM, CR_TEX }, 2238bf80f4bSopenharmony_ci { GL_RGB10, CR_TEX }, 2248bf80f4bSopenharmony_ci { GL_RGB12, CR_TEX }, 2258bf80f4bSopenharmony_ci { GL_RGB16, CR_TEX }, 2268bf80f4bSopenharmony_ci { GL_RGB16_SNORM, CR_TEX }, 2278bf80f4bSopenharmony_ci // RGBA2 not in base format 2288bf80f4bSopenharmony_ci { GL_RGBA4, CR_REND_TEX }, 2298bf80f4bSopenharmony_ci { GL_RGB5_A1, CR_REND_TEX }, 2308bf80f4bSopenharmony_ci { GL_RGBA8, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2318bf80f4bSopenharmony_ci { GL_RGBA8_SNORM, CR_TEX | ATOMIC_STORE }, 2328bf80f4bSopenharmony_ci { GL_RGB10_A2, CR_REND_TEX | ATOMIC_STORE }, 2338bf80f4bSopenharmony_ci { GL_RGB10_A2UI, CR_REND_TEX | ATOMIC_STORE }, 2348bf80f4bSopenharmony_ci { GL_RGBA12, CR_TEX }, 2358bf80f4bSopenharmony_ci { GL_RGBA16, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2368bf80f4bSopenharmony_ci { GL_RGBA16_SNORM, CR_TEX | ATOMIC_STORE }, 2378bf80f4bSopenharmony_ci { GL_SRGB8, CR_TEX }, 2388bf80f4bSopenharmony_ci { GL_SRGB8_ALPHA8, CR_REND_TEX }, 2398bf80f4bSopenharmony_ci { GL_R16F, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2408bf80f4bSopenharmony_ci { GL_RG16F, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2418bf80f4bSopenharmony_ci { GL_RGB16F, CR_TEX }, 2428bf80f4bSopenharmony_ci { GL_RGBA16F, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2438bf80f4bSopenharmony_ci { GL_R32F, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2448bf80f4bSopenharmony_ci { GL_RG32F, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2458bf80f4bSopenharmony_ci { GL_RGB32F, CR_TEX | TEXEL_BUF | TEXEL_BUF }, 2468bf80f4bSopenharmony_ci { GL_RGBA32F, CR_REND_TEX | ATOMIC_STORE }, 2478bf80f4bSopenharmony_ci { GL_R11F_G11F_B10F, CR_REND_TEX | ATOMIC_STORE }, 2488bf80f4bSopenharmony_ci { GL_RGB9_E5, TEX }, 2498bf80f4bSopenharmony_ci { GL_R8I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2508bf80f4bSopenharmony_ci { GL_R8UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2518bf80f4bSopenharmony_ci { GL_R16I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2528bf80f4bSopenharmony_ci { GL_R16UI, CR_REND_TEX | TEXEL_BUF }, 2538bf80f4bSopenharmony_ci { GL_R32I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2548bf80f4bSopenharmony_ci { GL_R32UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2558bf80f4bSopenharmony_ci { GL_RG8I, CR_REND_TEX | TEXEL_BUF }, 2568bf80f4bSopenharmony_ci { GL_RG8UI, CR_REND_TEX | TEXEL_BUF }, 2578bf80f4bSopenharmony_ci { GL_RG16I, CR_REND_TEX | TEXEL_BUF }, 2588bf80f4bSopenharmony_ci { GL_RG16UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2598bf80f4bSopenharmony_ci { GL_RG32I, CR_REND_TEX | TEXEL_BUF }, 2608bf80f4bSopenharmony_ci { GL_RG32UI, CR_REND_TEX | TEXEL_BUF }, 2618bf80f4bSopenharmony_ci { GL_RGB8I, CR_TEX }, 2628bf80f4bSopenharmony_ci { GL_RGB8UI, CR_TEX }, 2638bf80f4bSopenharmony_ci { GL_RGB16I, CR_TEX }, 2648bf80f4bSopenharmony_ci { GL_RGB16UI, CR_TEX }, 2658bf80f4bSopenharmony_ci { GL_RGB32I, CR_TEX | TEXEL_BUF }, 2668bf80f4bSopenharmony_ci { GL_RGB32UI, CR_TEX | ATOMIC_STORE | TEXEL_BUF }, 2678bf80f4bSopenharmony_ci { GL_RGBA8I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2688bf80f4bSopenharmony_ci { GL_RGBA8UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2698bf80f4bSopenharmony_ci { GL_RGBA16I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2708bf80f4bSopenharmony_ci { GL_RGBA16UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2718bf80f4bSopenharmony_ci { GL_RGBA32I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2728bf80f4bSopenharmony_ci { GL_RGBA32UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2738bf80f4bSopenharmony_ci#elif RENDER_HAS_GLES_BACKEND 2748bf80f4bSopenharmony_ci { GL_R8, CR_TF_REND_TEX | TEXEL_BUF }, 2758bf80f4bSopenharmony_ci { GL_R8_SNORM, TF_TEX }, 2768bf80f4bSopenharmony_ci { GL_RG8, CR_TF_REND_TEX | TEXEL_BUF }, 2778bf80f4bSopenharmony_ci { GL_RG8_SNORM, TF_TEX }, 2788bf80f4bSopenharmony_ci { GL_RGB8, CR_TF_REND_TEX }, 2798bf80f4bSopenharmony_ci { GL_RGB8_SNORM, TF_TEX }, 2808bf80f4bSopenharmony_ci { GL_RGB565, CR_TF_REND_TEX }, 2818bf80f4bSopenharmony_ci { GL_RGBA4, CR_TF_REND_TEX }, 2828bf80f4bSopenharmony_ci { GL_RGB5_A1, CR_TF_REND_TEX }, 2838bf80f4bSopenharmony_ci { GL_RGBA8, CR_TF_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2848bf80f4bSopenharmony_ci { GL_RGBA8_SNORM, TF_TEX | ATOMIC_STORE }, 2858bf80f4bSopenharmony_ci { GL_RGB10_A2, CR_TF_REND_TEX }, 2868bf80f4bSopenharmony_ci { GL_RGB10_A2UI, CR_REND_TEX }, 2878bf80f4bSopenharmony_ci { GL_SRGB8, TF_TEX }, 2888bf80f4bSopenharmony_ci { GL_SRGB8_ALPHA8, CR_TF_REND_TEX }, 2898bf80f4bSopenharmony_ci { GL_R16F, CR_TF_REND_TEX | TEXEL_BUF }, 2908bf80f4bSopenharmony_ci { GL_RG16F, CR_TF_REND_TEX | TEXEL_BUF }, 2918bf80f4bSopenharmony_ci { GL_RGB16F, TF_TEX }, 2928bf80f4bSopenharmony_ci { GL_RGBA16F, CR_TF_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2938bf80f4bSopenharmony_ci { GL_R32F, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2948bf80f4bSopenharmony_ci { GL_RG32F, CR_REND_TEX | TEXEL_BUF }, 2958bf80f4bSopenharmony_ci { GL_RGB32F, TEX | TEXEL_BUF }, 2968bf80f4bSopenharmony_ci { GL_RGBA32F, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 2978bf80f4bSopenharmony_ci { GL_R11F_G11F_B10F, CR_TF_REND_TEX }, 2988bf80f4bSopenharmony_ci { GL_RGB9_E5, TF_TEX }, 2998bf80f4bSopenharmony_ci { GL_R8I, CR_REND_TEX | TEXEL_BUF }, 3008bf80f4bSopenharmony_ci { GL_R8UI, CR_REND_TEX | TEXEL_BUF }, 3018bf80f4bSopenharmony_ci { GL_R16I, CR_REND_TEX | TEXEL_BUF }, 3028bf80f4bSopenharmony_ci { GL_R16UI, CR_REND_TEX | TEXEL_BUF }, 3038bf80f4bSopenharmony_ci { GL_R32I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 3048bf80f4bSopenharmony_ci { GL_R32UI, CR_REND_TEX | TEXEL_BUF }, 3058bf80f4bSopenharmony_ci { GL_RG8I, CR_REND_TEX | TEXEL_BUF }, 3068bf80f4bSopenharmony_ci { GL_RG8UI, CR_REND_TEX | TEXEL_BUF }, 3078bf80f4bSopenharmony_ci { GL_RG16I, CR_REND_TEX | TEXEL_BUF }, 3088bf80f4bSopenharmony_ci { GL_RG16UI, CR_REND_TEX | TEXEL_BUF }, 3098bf80f4bSopenharmony_ci { GL_RG32I, CR_REND_TEX | TEXEL_BUF }, 3108bf80f4bSopenharmony_ci { GL_RG32UI, CR_REND_TEX | TEXEL_BUF }, 3118bf80f4bSopenharmony_ci { GL_RGB8I, TEX }, 3128bf80f4bSopenharmony_ci { GL_RGB8UI, TEX }, 3138bf80f4bSopenharmony_ci { GL_RGB16I, TEX }, 3148bf80f4bSopenharmony_ci { GL_RGB16UI, TEX }, 3158bf80f4bSopenharmony_ci { GL_RGB32I, TEX | TEXEL_BUF }, 3168bf80f4bSopenharmony_ci { GL_RGB32UI, TEX | TEXEL_BUF }, 3178bf80f4bSopenharmony_ci { GL_RGBA8I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 3188bf80f4bSopenharmony_ci { GL_RGBA8UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 3198bf80f4bSopenharmony_ci { GL_RGBA16I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 3208bf80f4bSopenharmony_ci { GL_RGBA16UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 3218bf80f4bSopenharmony_ci { GL_RGBA32I, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 3228bf80f4bSopenharmony_ci { GL_RGBA32UI, CR_REND_TEX | ATOMIC_STORE | TEXEL_BUF }, 3238bf80f4bSopenharmony_ci#endif 3248bf80f4bSopenharmony_ci { GL_DEPTH_COMPONENT16, DS }, 3258bf80f4bSopenharmony_ci { GL_DEPTH_COMPONENT24, DS }, 3268bf80f4bSopenharmony_ci { GL_DEPTH_COMPONENT32F, DS }, 3278bf80f4bSopenharmony_ci { GL_DEPTH24_STENCIL8, DS }, 3288bf80f4bSopenharmony_ci { GL_DEPTH32F_STENCIL8, DS }, 3298bf80f4bSopenharmony_ci { GL_STENCIL_INDEX8, DS }, 3308bf80f4bSopenharmony_ci 3318bf80f4bSopenharmony_ci#if (defined(GL_EXT_texture_sRGB_R8) && (GL_EXT_texture_sRGB_R8)) 3328bf80f4bSopenharmony_ci { GL_SR8_EXT, TF_TEX }, 3338bf80f4bSopenharmony_ci#endif 3348bf80f4bSopenharmony_ci 3358bf80f4bSopenharmony_ci#if (defined(GL_EXT_texture_sRGB_RG8) && (GL_EXT_texture_sRGB_RG8)) 3368bf80f4bSopenharmony_ci { GL_SRG8_EXT, TF_TEX }, 3378bf80f4bSopenharmony_ci#endif 3388bf80f4bSopenharmony_ci 3398bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_format_BGRA8888) && (GL_EXT_texture_format_BGRA8888) 3408bf80f4bSopenharmony_ci { GL_BGRA_EXT, CR_REND_TEX }, 3418bf80f4bSopenharmony_ci#endif 3428bf80f4bSopenharmony_ci 3438bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_norm16) && (GL_EXT_texture_norm16) 3448bf80f4bSopenharmony_ci { GL_R16_EXT, CR_TF_REND_TEX }, 3458bf80f4bSopenharmony_ci { GL_RG16_EXT, CR_TF_REND_TEX }, 3468bf80f4bSopenharmony_ci { GL_RGB16_EXT, TF_TEX }, 3478bf80f4bSopenharmony_ci { GL_RGBA16_EXT, CR_TF_REND_TEX }, 3488bf80f4bSopenharmony_ci { GL_R16_SNORM_EXT, TF_TEX }, 3498bf80f4bSopenharmony_ci { GL_RG16_SNORM_EXT, TF_TEX }, 3508bf80f4bSopenharmony_ci { GL_RGB16_SNORM_EXT, TF_TEX }, 3518bf80f4bSopenharmony_ci { GL_RGBA16_SNORM_EXT, TF_TEX }, 3528bf80f4bSopenharmony_ci#endif 3538bf80f4bSopenharmony_ci 3548bf80f4bSopenharmony_ci { GL_COMPRESSED_R11_EAC, TF_TEX }, 3558bf80f4bSopenharmony_ci { GL_COMPRESSED_SIGNED_R11_EAC, TF_TEX }, 3568bf80f4bSopenharmony_ci { GL_COMPRESSED_RG11_EAC, TF_TEX }, 3578bf80f4bSopenharmony_ci { GL_COMPRESSED_SIGNED_RG11_EAC, TF_TEX }, 3588bf80f4bSopenharmony_ci { GL_COMPRESSED_RGB8_ETC2, TF_TEX }, 3598bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ETC2, TF_TEX }, 3608bf80f4bSopenharmony_ci { GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, TF_TEX }, 3618bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, TF_TEX }, 3628bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA8_ETC2_EAC, TF_TEX }, 3638bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, TF_TEX }, 3648bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 3658bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_4x4, TF_TEX }, 3668bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_5x4, TF_TEX }, 3678bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_5x5, TF_TEX }, 3688bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_6x5, TF_TEX }, 3698bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_6x6, TF_TEX }, 3708bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_8x5, TF_TEX }, 3718bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_8x6, TF_TEX }, 3728bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_8x8, TF_TEX }, 3738bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_10x5, TF_TEX }, 3748bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_10x6, TF_TEX }, 3758bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_10x8, TF_TEX }, 3768bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_10x10, TF_TEX }, 3778bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_12x10, TF_TEX }, 3788bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_ASTC_12x12, TF_TEX }, 3798bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4, TF_TEX }, 3808bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4, TF_TEX }, 3818bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5, TF_TEX }, 3828bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5, TF_TEX }, 3838bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6, TF_TEX }, 3848bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5, TF_TEX }, 3858bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6, TF_TEX }, 3868bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8, TF_TEX }, 3878bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5, TF_TEX }, 3888bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6, TF_TEX }, 3898bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8, TF_TEX }, 3908bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10, TF_TEX }, 3918bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10, TF_TEX }, 3928bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12, TF_TEX }, 3938bf80f4bSopenharmony_ci#endif 3948bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_compression_s3tc) && (GL_EXT_texture_compression_s3tc) 3958bf80f4bSopenharmony_ci { GL_COMPRESSED_RGB_S3TC_DXT1_EXT, TF_TEX }, 3968bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, TF_TEX }, 3978bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, TF_TEX }, 3988bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, TF_TEX }, 3998bf80f4bSopenharmony_ci#endif 4008bf80f4bSopenharmony_ci#if defined(GL_ARB_texture_compression_bptc) && (GL_ARB_texture_compression_bptc) 4018bf80f4bSopenharmony_ci { GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, TF_TEX }, 4028bf80f4bSopenharmony_ci { GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, TF_TEX }, 4038bf80f4bSopenharmony_ci { GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, TF_TEX }, 4048bf80f4bSopenharmony_ci { GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, TF_TEX }, 4058bf80f4bSopenharmony_ci#endif 4068bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_compression_rgtc) && (GL_EXT_texture_compression_rgtc) 4078bf80f4bSopenharmony_ci { GL_COMPRESSED_RED_RGTC1_EXT, TF_TEX }, 4088bf80f4bSopenharmony_ci { GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, TF_TEX }, 4098bf80f4bSopenharmony_ci { GL_COMPRESSED_RED_GREEN_RGTC2_EXT, TF_TEX }, 4108bf80f4bSopenharmony_ci { GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, TF_TEX }, 4118bf80f4bSopenharmony_ci#endif 4128bf80f4bSopenharmony_ci}; 4138bf80f4bSopenharmony_ci 4148bf80f4bSopenharmony_ci// Dont allow SRGB_R8 and SRGB_R8G8 internal formats, instead use the GL_SRGB8 with swizzle as workaround. 4158bf80f4bSopenharmony_ci#define USE_EXTENSION_FORMATS 4168bf80f4bSopenharmony_ci 4178bf80f4bSopenharmony_ci#define BLOCK_BITS_8 1 4188bf80f4bSopenharmony_ci#define BLOCK_BITS_16 2 4198bf80f4bSopenharmony_ci#define BLOCK_BITS_32 4 4208bf80f4bSopenharmony_ci#define BLOCK_BITS_64 8 4218bf80f4bSopenharmony_ci#define BLOCK_BITS_128 16 4228bf80f4bSopenharmony_ci 4238bf80f4bSopenharmony_ci// GL_EXT_texture_sRGB_R8 extension 4248bf80f4bSopenharmony_ci#if (defined(GL_EXT_texture_sRGB_R8) && (GL_EXT_texture_sRGB_R8)) 4258bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_EXT_SRGB_R8[] = { 4268bf80f4bSopenharmony_ci { BASE_FORMAT_R8_SRGB, GL_RED, GL_SR8_EXT, GL_UNSIGNED_BYTE, 1, { false, 0, 0, 0 }, 4278bf80f4bSopenharmony_ci { GL_RED, GL_ZERO, GL_ZERO, GL_ONE } }, 4288bf80f4bSopenharmony_ci}; 4298bf80f4bSopenharmony_ci#endif 4308bf80f4bSopenharmony_ci 4318bf80f4bSopenharmony_ci// GL_EXT_texture_sRGB_RG8 extension 4328bf80f4bSopenharmony_ci#if (defined(GL_EXT_texture_sRGB_RG8) && (GL_EXT_texture_sRGB_RG8)) 4338bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_EXT_SRGB_RG8[] = { 4348bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8_SRGB, GL_RG, GL_SRG8_EXT, GL_UNSIGNED_BYTE, 1, { false, 0, 0, 0 }, 4358bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_ZERO, GL_ONE } }, 4368bf80f4bSopenharmony_ci}; 4378bf80f4bSopenharmony_ci#endif 4388bf80f4bSopenharmony_ci 4398bf80f4bSopenharmony_ci// GL_EXT_texture_sRGB extension 4408bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_sRGB) && (GL_EXT_texture_sRGB) 4418bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_EXT_SRGB[] = { 4428bf80f4bSopenharmony_ci { BASE_FORMAT_BC1_RGB_SRGB_BLOCK, GL_RGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, 0, 4438bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4448bf80f4bSopenharmony_ci { BASE_FORMAT_BC1_RGBA_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, 0, 4458bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4468bf80f4bSopenharmony_ci { BASE_FORMAT_BC2_SRGB_BLOCK, GL_RGB, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_UNSIGNED_BYTE, 0, 4478bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4488bf80f4bSopenharmony_ci { BASE_FORMAT_BC3_SRGB_BLOCK, GL_RGB, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_UNSIGNED_BYTE, 0, 4498bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4508bf80f4bSopenharmony_ci}; 4518bf80f4bSopenharmony_ci#endif 4528bf80f4bSopenharmony_ci 4538bf80f4bSopenharmony_ci// GL_EXT_texture_format_BGRA8888 extension 4548bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_format_BGRA8888) && (GL_EXT_texture_format_BGRA8888) 4558bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_EXT_BGRA[] = { 4568bf80f4bSopenharmony_ci { BASE_FORMAT_B8G8R8A8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 4, { false, 0, 0, 0 }, 4578bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4588bf80f4bSopenharmony_ci}; 4598bf80f4bSopenharmony_ci#endif 4608bf80f4bSopenharmony_ci 4618bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_norm16) && (GL_EXT_texture_norm16) 4628bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_EXT_NORM16[] = { 4638bf80f4bSopenharmony_ci { BASE_FORMAT_R16_UNORM, GL_RED, GL_R16_EXT, GL_UNSIGNED_SHORT, 2, { false, 0, 0, 0 }, 4648bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4658bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16_UNORM, GL_RG, GL_RG16_EXT, GL_UNSIGNED_SHORT, 4, { false, 0, 0, 0 }, 4668bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4678bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16_UNORM, GL_RGB, GL_RGB16_EXT, GL_UNSIGNED_SHORT, 6, { false, 0, 0, 0 }, 4688bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4698bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16A16_UNORM, GL_RGBA, GL_RGBA16_EXT, GL_UNSIGNED_SHORT, 8, { false, 0, 0, 0 }, 4708bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4718bf80f4bSopenharmony_ci { BASE_FORMAT_R16_SNORM, GL_RED, GL_R16_SNORM_EXT, GL_SHORT, 2, { false, 0, 0, 0 }, 4728bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4738bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16_SNORM, GL_RG, GL_RG16_SNORM_EXT, GL_SHORT, 4, { false, 0, 0, 0 }, 4748bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4758bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16_SNORM, GL_RGB, GL_RGB16_SNORM_EXT, GL_SHORT, 6, { false, 0, 0, 0 }, 4768bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4778bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16A16_SNORM, GL_RGBA, GL_RGBA16_SNORM_EXT, GL_SHORT, 8, { false, 0, 0, 0 }, 4788bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4798bf80f4bSopenharmony_ci}; 4808bf80f4bSopenharmony_ci#endif 4818bf80f4bSopenharmony_ci 4828bf80f4bSopenharmony_ci// GL_EXT_texture_compression_s3tc extension 4838bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_compression_s3tc) && (GL_EXT_texture_compression_s3tc) 4848bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_EXT_S3TC[] = { 4858bf80f4bSopenharmony_ci { BASE_FORMAT_BC1_RGB_UNORM_BLOCK, GL_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, 0, 4868bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4878bf80f4bSopenharmony_ci { BASE_FORMAT_BC1_RGBA_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, 0, 4888bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4898bf80f4bSopenharmony_ci { BASE_FORMAT_BC2_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_UNSIGNED_BYTE, 0, 4908bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4918bf80f4bSopenharmony_ci { BASE_FORMAT_BC3_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_UNSIGNED_BYTE, 0, 4928bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 4938bf80f4bSopenharmony_ci}; 4948bf80f4bSopenharmony_ci#endif 4958bf80f4bSopenharmony_ci 4968bf80f4bSopenharmony_ci// GL_ARB_texture_compression_bptc extension 4978bf80f4bSopenharmony_ci#if defined(GL_ARB_texture_compression_bptc) && (GL_ARB_texture_compression_bptc) 4988bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_EXT_BPTC[] = { 4998bf80f4bSopenharmony_ci { BASE_FORMAT_BC7_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_UNSIGNED_BYTE, 0, 5008bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5018bf80f4bSopenharmony_ci { BASE_FORMAT_BC7_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, GL_UNSIGNED_BYTE, 0, 5028bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5038bf80f4bSopenharmony_ci { BASE_FORMAT_BC6H_SFLOAT_BLOCK, GL_RGB, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_FLOAT, 0, 5048bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5058bf80f4bSopenharmony_ci { BASE_FORMAT_BC6H_UFLOAT_BLOCK, GL_RGB, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, GL_FLOAT, 0, 5068bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5078bf80f4bSopenharmony_ci}; 5088bf80f4bSopenharmony_ci#endif 5098bf80f4bSopenharmony_ci 5108bf80f4bSopenharmony_ci// GL_EXT_texture_norm16 extension 5118bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_compression_rgtc) && (GL_EXT_texture_compression_rgtc) 5128bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_EXT_RGTC[] = { 5138bf80f4bSopenharmony_ci { BASE_FORMAT_BC4_UNORM_BLOCK, GL_RED, GL_COMPRESSED_RED_RGTC1_EXT, GL_UNSIGNED_BYTE, 0, 5148bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5158bf80f4bSopenharmony_ci { BASE_FORMAT_BC4_SNORM_BLOCK, GL_RED, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, GL_UNSIGNED_BYTE, 0, 5168bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5178bf80f4bSopenharmony_ci { BASE_FORMAT_BC5_UNORM_BLOCK, GL_RG, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_UNSIGNED_BYTE, 0, 5188bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5198bf80f4bSopenharmony_ci { BASE_FORMAT_BC5_SNORM_BLOCK, GL_RG, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, GL_UNSIGNED_BYTE, 0, 5208bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5218bf80f4bSopenharmony_ci}; 5228bf80f4bSopenharmony_ci#endif 5238bf80f4bSopenharmony_ci 5248bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS_FALLBACK[] = { 5258bf80f4bSopenharmony_ci { BASE_FORMAT_R4G4_UNORM_PACK8, GL_RG, GL_RGBA4, GL_UNSIGNED_BYTE, 1, { false, 0, 0, 0 }, 5268bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_ZERO, GL_ONE } }, 5278bf80f4bSopenharmony_ci { BASE_FORMAT_B4G4R4A4_UNORM_PACK16, GL_RGBA, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, 2, { false, 0, 0, 0 }, 5288bf80f4bSopenharmony_ci { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA } }, 5298bf80f4bSopenharmony_ci { BASE_FORMAT_B5G6R5_UNORM_PACK16, GL_RGB, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, 2, { false, 0, 0, 0 }, 5308bf80f4bSopenharmony_ci { GL_BLUE, GL_GREEN, GL_RED, GL_ONE } }, 5318bf80f4bSopenharmony_ci { BASE_FORMAT_B5G5R5A1_UNORM_PACK16, GL_RGBA, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, 2, { false, 0, 0, 0 }, 5328bf80f4bSopenharmony_ci { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA } }, 5338bf80f4bSopenharmony_ci { BASE_FORMAT_A1R5G5B5_UNORM_PACK16, GL_RGBA, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, 2, { false, 0, 0, 0 }, 5348bf80f4bSopenharmony_ci { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA } }, 5358bf80f4bSopenharmony_ci 5368bf80f4bSopenharmony_ci // not available in desktop, available as an extension in opengles. "GL_EXT_texture_sRGB_RG8" 5378bf80f4bSopenharmony_ci { BASE_FORMAT_R8_SRGB, GL_RED, GL_SRGB8, GL_UNSIGNED_BYTE, 1, { false, 0, 0, 0 }, 5388bf80f4bSopenharmony_ci { GL_RED, GL_ZERO, GL_ZERO, GL_ONE } }, 5398bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8_SRGB, GL_RG, GL_SRGB8, GL_UNSIGNED_BYTE, 1, { false, 0, 0, 0 }, 5408bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_ZERO, GL_ONE } }, 5418bf80f4bSopenharmony_ci 5428bf80f4bSopenharmony_ci { BASE_FORMAT_A2R10G10B10_UNORM_PACK32, GL_RGBA, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, 4, { false, 0, 0, 0 }, 5438bf80f4bSopenharmony_ci { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA } }, 5448bf80f4bSopenharmony_ci { BASE_FORMAT_A2R10G10B10_UINT_PACK32, GL_RGBA, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, 4, 5458bf80f4bSopenharmony_ci { false, 0, 0, 0 }, { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA } }, 5468bf80f4bSopenharmony_ci 5478bf80f4bSopenharmony_ci // available as an extension in opengles. "GL_EXT_texture_norm16" -> fallback to half float 5488bf80f4bSopenharmony_ci { BASE_FORMAT_R16_UNORM, GL_RED, GL_R16F, GL_HALF_FLOAT, 2, { false, 0, 0, 0 }, 5498bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5508bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16_UNORM, GL_RG, GL_RG16F, GL_HALF_FLOAT, 4, { false, 0, 0, 0 }, 5518bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5528bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16_UNORM, GL_RGB, GL_RGB16F, GL_HALF_FLOAT, 6, { false, 0, 0, 0 }, 5538bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5548bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16A16_UNORM, GL_RGBA, GL_RGBA16F, GL_HALF_FLOAT, 8, { false, 0, 0, 0 }, 5558bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5568bf80f4bSopenharmony_ci}; 5578bf80f4bSopenharmony_ci 5588bf80f4bSopenharmony_ci// NOTE: verify this table. add missing formats. 5598bf80f4bSopenharmony_cistatic constexpr DeviceGLES::ImageFormat IMAGE_FORMATS[] = { 5608bf80f4bSopenharmony_ci { BASE_FORMAT_UNDEFINED, GL_NONE, GL_NONE, GL_NONE, 0, { false, 0, 0, 0 }, 5618bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5628bf80f4bSopenharmony_ci // These are required in GL and GLES 5638bf80f4bSopenharmony_ci { BASE_FORMAT_R8_UNORM, GL_RED, GL_R8, GL_UNSIGNED_BYTE, 1, { false, 0, 0, 0 }, 5648bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5658bf80f4bSopenharmony_ci { BASE_FORMAT_R8_SNORM, GL_RED, GL_R8_SNORM, GL_BYTE, 1, { false, 0, 0, 0 }, 5668bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5678bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8_UNORM, GL_RG, GL_RG8, GL_UNSIGNED_BYTE, 2, { false, 0, 0, 0 }, 5688bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5698bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8_SNORM, GL_RG, GL_RG8, GL_BYTE, 2, { false, 0, 0, 0 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5708bf80f4bSopenharmony_ci { BASE_FORMAT_R5G6B5_UNORM_PACK16, GL_RGB, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, 2, { false, 0, 0, 0 }, 5718bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5728bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8_UNORM, GL_RGB, GL_RGB8, GL_UNSIGNED_BYTE, 3, { false, 0, 0, 0 }, 5738bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5748bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8_SNORM, GL_RGB, GL_RGB8, GL_BYTE, 3, { false, 0, 0, 0 }, 5758bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5768bf80f4bSopenharmony_ci { BASE_FORMAT_R4G4B4A4_UNORM_PACK16, GL_RGBA, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, 2, { false, 0, 0, 0 }, 5778bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5788bf80f4bSopenharmony_ci { BASE_FORMAT_R5G5B5A1_UNORM_PACK16, GL_RGBA, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, 2, { false, 0, 0, 0 }, 5798bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5808bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8A8_UNORM, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, 4, { false, 0, 0, 0 }, 5818bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5828bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8A8_SNORM, GL_RGBA, GL_RGBA8, GL_BYTE, 4, { false, 0, 0, 0 }, 5838bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5848bf80f4bSopenharmony_ci { BASE_FORMAT_A2B10G10R10_UNORM_PACK32, GL_RGBA, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, 4, { false, 0, 0, 0 }, 5858bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5868bf80f4bSopenharmony_ci { BASE_FORMAT_A2B10G10R10_UINT_PACK32, GL_RGBA, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, 4, 5878bf80f4bSopenharmony_ci { false, 0, 0, 0 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5888bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8_SRGB, GL_RGB, GL_SRGB8, GL_UNSIGNED_BYTE, 3, { false, 0, 0, 0 }, 5898bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5908bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8A8_SRGB, GL_RGBA, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE, 4, { false, 0, 0, 0 }, 5918bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5928bf80f4bSopenharmony_ci { BASE_FORMAT_R16_SFLOAT, GL_RED, GL_R16F, GL_HALF_FLOAT, 2, { false, 0, 0, 0 }, 5938bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5948bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16_SFLOAT, GL_RG, GL_RG16F, GL_HALF_FLOAT, 4, { false, 0, 0, 0 }, 5958bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5968bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16_SFLOAT, GL_RGB, GL_RGB16F, GL_HALF_FLOAT, 6, { false, 0, 0, 0 }, 5978bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 5988bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16A16_SFLOAT, GL_RGBA, GL_RGBA16F, GL_HALF_FLOAT, 8, { false, 0, 0, 0 }, 5998bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6008bf80f4bSopenharmony_ci { BASE_FORMAT_R32_SFLOAT, GL_RED, GL_R32F, GL_FLOAT, 4, { false, 0, 0, 0 }, 6018bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6028bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32_SFLOAT, GL_RG, GL_RG32F, GL_FLOAT, 8, { false, 0, 0, 0 }, 6038bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6048bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32B32_SFLOAT, GL_RGB, GL_RGB32F, GL_FLOAT, 12, { false, 0, 0, 0 }, 6058bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6068bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32B32A32_SFLOAT, GL_RGBA, GL_RGBA32F, GL_FLOAT, 16, { false, 0, 0, 0 }, 6078bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6088bf80f4bSopenharmony_ci // Special R11 G11 B10 float format. This format does not work with compute on GLES, but works as a texture. (this 6098bf80f4bSopenharmony_ci // is handled elsewhere) 6108bf80f4bSopenharmony_ci { BASE_FORMAT_B10G11R11_UFLOAT_PACK32, GL_RGB, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV, 4, 6118bf80f4bSopenharmony_ci { false, 0, 0, 0 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6128bf80f4bSopenharmony_ci { BASE_FORMAT_E5B9G9R9_UFLOAT_PACK32, GL_RGB, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV, 4, { false, 0, 0, 0 }, 6138bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6148bf80f4bSopenharmony_ci { BASE_FORMAT_R8_SINT, GL_RED_INTEGER, GL_R8I, GL_BYTE, 1, { false, 0, 0, 0 }, 6158bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6168bf80f4bSopenharmony_ci { BASE_FORMAT_R8_UINT, GL_RED_INTEGER, GL_R8UI, GL_UNSIGNED_BYTE, 1, { false, 0, 0, 0 }, 6178bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6188bf80f4bSopenharmony_ci { BASE_FORMAT_R16_SINT, GL_RED_INTEGER, GL_R16I, GL_SHORT, 2, { false, 0, 0, 0 }, 6198bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6208bf80f4bSopenharmony_ci { BASE_FORMAT_R16_UINT, GL_RED_INTEGER, GL_R16UI, GL_UNSIGNED_SHORT, 2, { false, 0, 0, 0 }, 6218bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6228bf80f4bSopenharmony_ci { BASE_FORMAT_R32_SINT, GL_RED_INTEGER, GL_R32I, GL_INT, 4, { false, 0, 0, 0 }, 6238bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6248bf80f4bSopenharmony_ci { BASE_FORMAT_R32_UINT, GL_RED_INTEGER, GL_R32UI, GL_UNSIGNED_INT, 4, { false, 0, 0, 0 }, 6258bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6268bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8_SINT, GL_RG_INTEGER, GL_RG8I, GL_BYTE, 2, { false, 0, 0, 0 }, 6278bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6288bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8_UINT, GL_RG_INTEGER, GL_R8UI, GL_UNSIGNED_BYTE, 2, { false, 0, 0, 0 }, 6298bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6308bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16_SINT, GL_RG_INTEGER, GL_RG16I, GL_SHORT, 4, { false, 0, 0, 0 }, 6318bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6328bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16_UINT, GL_RG_INTEGER, GL_RG16UI, GL_UNSIGNED_SHORT, 4, { false, 0, 0, 0 }, 6338bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6348bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32_SINT, GL_RG_INTEGER, GL_RG32I, GL_INT, 8, { false, 0, 0, 0 }, 6358bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6368bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32_UINT, GL_RG_INTEGER, GL_RG32UI, GL_UNSIGNED_INT, 8, { false, 0, 0, 0 }, 6378bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6388bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8_SINT, GL_RGB_INTEGER, GL_RGB8I, GL_BYTE, 3, { false, 0, 0, 0 }, 6398bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6408bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8_UINT, GL_RGB_INTEGER, GL_RGB8UI, GL_UNSIGNED_BYTE, 3, { false, 0, 0, 0 }, 6418bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6428bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16_SINT, GL_RGB_INTEGER, GL_RGB16I, GL_SHORT, 6, { false, 0, 0, 0 }, 6438bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6448bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16_UINT, GL_RGB_INTEGER, GL_RGB16UI, GL_UNSIGNED_SHORT, 6, { false, 0, 0, 0 }, 6458bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6468bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32B32_SINT, GL_RGB_INTEGER, GL_RGB32I, GL_INT, 12, { false, 0, 0, 0 }, 6478bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6488bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32B32_UINT, GL_RGB_INTEGER, GL_RGB32UI, GL_UNSIGNED_INT, 12, { false, 0, 0, 0 }, 6498bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6508bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8A8_SINT, GL_RGBA_INTEGER, GL_RGBA8I, GL_BYTE, 4, { false, 0, 0, 0 }, 6518bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6528bf80f4bSopenharmony_ci { BASE_FORMAT_R8G8B8A8_UINT, GL_RGBA_INTEGER, GL_RGBA8UI, GL_UNSIGNED_BYTE, 4, { false, 0, 0, 0 }, 6538bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6548bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16A16_SINT, GL_RGBA_INTEGER, GL_RGBA16I, GL_SHORT, 8, { false, 0, 0, 0 }, 6558bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6568bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16A16_UINT, GL_RGBA_INTEGER, GL_RGBA16UI, GL_UNSIGNED_SHORT, 8, { false, 0, 0, 0 }, 6578bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6588bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32B32A32_SINT, GL_RGBA_INTEGER, GL_RGBA32I, GL_INT, 16, { false, 0, 0, 0 }, 6598bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6608bf80f4bSopenharmony_ci { BASE_FORMAT_R32G32B32A32_UINT, GL_RGBA_INTEGER, GL_RGBA32UI, GL_UNSIGNED_INT, 16, { false, 0, 0, 0 }, 6618bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6628bf80f4bSopenharmony_ci { BASE_FORMAT_D16_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT, 2, { false, 0, 0, 0 }, 6638bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6648bf80f4bSopenharmony_ci { BASE_FORMAT_X8_D24_UNORM_PACK32, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT, 4, { false, 0, 0, 0 }, 6658bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6668bf80f4bSopenharmony_ci { BASE_FORMAT_D32_SFLOAT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32F, GL_FLOAT, 4, { false, 0, 0, 0 }, 6678bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6688bf80f4bSopenharmony_ci { BASE_FORMAT_S8_UINT, GL_STENCIL_INDEX, GL_STENCIL_INDEX8, GL_UNSIGNED_BYTE, 1, { false, 0, 0, 0 }, 6698bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6708bf80f4bSopenharmony_ci { BASE_FORMAT_D24_UNORM_S8_UINT, GL_DEPTH_STENCIL, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, 4, { false, 0, 0, 0 }, 6718bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6728bf80f4bSopenharmony_ci { BASE_FORMAT_D32_SFLOAT_S8_UINT, GL_DEPTH_STENCIL, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, 6738bf80f4bSopenharmony_ci { false, 0, 0, 0 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6748bf80f4bSopenharmony_ci // EAC 6758bf80f4bSopenharmony_ci { BASE_FORMAT_EAC_R11_UNORM_BLOCK, GL_RED, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, 0, 6768bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6778bf80f4bSopenharmony_ci { BASE_FORMAT_EAC_R11_SNORM_BLOCK, GL_RED, GL_COMPRESSED_SIGNED_R11_EAC, GL_BYTE, 0, { true, 4, 4, BLOCK_BITS_64 }, 6788bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6798bf80f4bSopenharmony_ci { BASE_FORMAT_EAC_R11G11_UNORM_BLOCK, GL_RG, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, 0, 6808bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6818bf80f4bSopenharmony_ci { BASE_FORMAT_EAC_R11G11_SNORM_BLOCK, GL_RG, GL_COMPRESSED_SIGNED_RG11_EAC, GL_BYTE, 0, 6828bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6838bf80f4bSopenharmony_ci // ETC 6848bf80f4bSopenharmony_ci { BASE_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, GL_RGB, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, 0, 6858bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6868bf80f4bSopenharmony_ci { BASE_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, GL_RGB, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, 0, 6878bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6888bf80f4bSopenharmony_ci { BASE_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, 0, 6898bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6908bf80f4bSopenharmony_ci { BASE_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, 0, 6918bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_64 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6928bf80f4bSopenharmony_ci { BASE_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, 0, 6938bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6948bf80f4bSopenharmony_ci { BASE_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, 0, 6958bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 6968bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND 6978bf80f4bSopenharmony_ci // required by GL 6988bf80f4bSopenharmony_ci { BASE_FORMAT_R16_UNORM, GL_RED, GL_R16, GL_UNSIGNED_SHORT, 2, { false, 0, 0, 0 }, 6998bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7008bf80f4bSopenharmony_ci { BASE_FORMAT_R16_SNORM, GL_RED, GL_R16, GL_SHORT, 2, { false, 0, 0, 0 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7018bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16_UNORM, GL_RG, GL_RG16, GL_UNSIGNED_SHORT, 4, { false, 0, 0, 0 }, 7028bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7038bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16_SNORM, GL_RG, GL_RG16, GL_SHORT, 4, { false, 0, 0, 0 }, 7048bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7058bf80f4bSopenharmony_ci // GL_R3_G3_B2, RGB4, RGB5, RGB10, RGB12 not in base formats 7068bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16_UNORM, GL_RGB, GL_RGB16, GL_UNSIGNED_SHORT, 6, { false, 0, 0, 0 }, 7078bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7088bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16_SNORM, GL_RGB, GL_RGB16, GL_SHORT, 6, { false, 0, 0, 0 }, 7098bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7108bf80f4bSopenharmony_ci // RGBA2, RGBA12 not in base formats 7118bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16A16_UNORM, GL_RGBA, GL_RGBA16, GL_UNSIGNED_SHORT, 8, { false, 0, 0, 0 }, 7128bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7138bf80f4bSopenharmony_ci { BASE_FORMAT_R16G16B16A16_SNORM, GL_RGBA, GL_RGBA16, GL_SHORT, 8, { false, 0, 0, 0 }, 7148bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7158bf80f4bSopenharmony_ci // STENCIL_INDEX1, STENCIL_INDEX4, STENCIL_INDEX16 not in base formats 7168bf80f4bSopenharmony_ci { BASE_FORMAT_B4G4R4A4_UNORM_PACK16, GL_BGRA, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, { false, 0, 0, 0 }, 7178bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7188bf80f4bSopenharmony_ci { BASE_FORMAT_A1R5G5B5_UNORM_PACK16, GL_BGRA, GL_RGB5_A1, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, { false, 0, 0, 0 }, 7198bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7208bf80f4bSopenharmony_ci { BASE_FORMAT_B5G6R5_UNORM_PACK16, GL_BGR, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5_REV, 2, { false, 0, 0, 0 }, 7218bf80f4bSopenharmony_ci { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7228bf80f4bSopenharmony_ci#elif RENDER_HAS_GLES_BACKEND 7238bf80f4bSopenharmony_ci // required by GLES 7248bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_4x4_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_UNSIGNED_BYTE, 0, 7258bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7268bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_5x4_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_UNSIGNED_BYTE, 0, 7278bf80f4bSopenharmony_ci { true, 5, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7288bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_5x5_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_UNSIGNED_BYTE, 0, 7298bf80f4bSopenharmony_ci { true, 5, 5, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7308bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_6x5_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_UNSIGNED_BYTE, 0, 7318bf80f4bSopenharmony_ci { true, 6, 5, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7328bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_6x6_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_UNSIGNED_BYTE, 0, 7338bf80f4bSopenharmony_ci { true, 6, 6, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7348bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_8x5_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_UNSIGNED_BYTE, 0, 7358bf80f4bSopenharmony_ci { true, 8, 5, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7368bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_8x6_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_UNSIGNED_BYTE, 0, 7378bf80f4bSopenharmony_ci { true, 8, 6, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7388bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_8x8_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_UNSIGNED_BYTE, 0, 7398bf80f4bSopenharmony_ci { true, 8, 8, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7408bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_10x5_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_UNSIGNED_BYTE, 0, 7418bf80f4bSopenharmony_ci { true, 10, 5, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7428bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_10x6_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_UNSIGNED_BYTE, 0, 7438bf80f4bSopenharmony_ci { true, 10, 6, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7448bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_10x8_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_UNSIGNED_BYTE, 0, 7458bf80f4bSopenharmony_ci { true, 10, 8, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7468bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_10x10_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_UNSIGNED_BYTE, 0, 7478bf80f4bSopenharmony_ci { true, 10, 10, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7488bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_12x10_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_UNSIGNED_BYTE, 0, 7498bf80f4bSopenharmony_ci { true, 12, 10, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7508bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_12x12_UNORM_BLOCK, GL_RGBA, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_UNSIGNED_BYTE, 0, 7518bf80f4bSopenharmony_ci { true, 12, 12, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7528bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_4x4_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_UNSIGNED_BYTE, 0, 7538bf80f4bSopenharmony_ci { true, 4, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7548bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_5x4_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_UNSIGNED_BYTE, 0, 7558bf80f4bSopenharmony_ci { true, 5, 4, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7568bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_5x5_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_UNSIGNED_BYTE, 0, 7578bf80f4bSopenharmony_ci { true, 5, 5, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7588bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_6x5_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_UNSIGNED_BYTE, 0, 7598bf80f4bSopenharmony_ci { true, 6, 5, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7608bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_6x6_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_UNSIGNED_BYTE, 0, 7618bf80f4bSopenharmony_ci { true, 6, 6, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7628bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_8x5_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_UNSIGNED_BYTE, 0, 7638bf80f4bSopenharmony_ci { true, 8, 5, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7648bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_8x6_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_UNSIGNED_BYTE, 0, 7658bf80f4bSopenharmony_ci { true, 8, 6, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7668bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_8x8_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_UNSIGNED_BYTE, 0, 7678bf80f4bSopenharmony_ci { true, 8, 8, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7688bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_10x5_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_UNSIGNED_BYTE, 0, 7698bf80f4bSopenharmony_ci { true, 10, 5, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7708bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_10x6_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_UNSIGNED_BYTE, 0, 7718bf80f4bSopenharmony_ci { true, 10, 6, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7728bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_10x8_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_UNSIGNED_BYTE, 0, 7738bf80f4bSopenharmony_ci { true, 10, 8, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7748bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_10x10_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_UNSIGNED_BYTE, 0, 7758bf80f4bSopenharmony_ci { true, 10, 10, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7768bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_12x10_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_UNSIGNED_BYTE, 0, 7778bf80f4bSopenharmony_ci { true, 12, 10, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7788bf80f4bSopenharmony_ci { BASE_FORMAT_ASTC_12x12_SRGB_BLOCK, GL_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_UNSIGNED_BYTE, 0, 7798bf80f4bSopenharmony_ci { true, 12, 12, BLOCK_BITS_128 }, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, 7808bf80f4bSopenharmony_ci#endif 7818bf80f4bSopenharmony_ci}; 7828bf80f4bSopenharmony_ci 7838bf80f4bSopenharmony_civoid FillExtensionFormats(const DeviceGLES& device, BASE_NS::vector<DeviceGLES::ImageFormat>& sf) 7848bf80f4bSopenharmony_ci{ 7858bf80f4bSopenharmony_ci#if (defined(GL_EXT_texture_sRGB_R8) && (GL_EXT_texture_sRGB_R8)) 7868bf80f4bSopenharmony_ci if (device.HasExtension("GL_EXT_texture_sRGB_R8")) { 7878bf80f4bSopenharmony_ci sf.insert(sf.end(), std::begin(IMAGE_FORMATS_EXT_SRGB_R8), std::end(IMAGE_FORMATS_EXT_SRGB_R8)); 7888bf80f4bSopenharmony_ci } 7898bf80f4bSopenharmony_ci#endif 7908bf80f4bSopenharmony_ci 7918bf80f4bSopenharmony_ci#if (defined(GL_EXT_texture_sRGB_RG8) && (GL_EXT_texture_sRGB_RG8)) 7928bf80f4bSopenharmony_ci if (device.HasExtension("GL_EXT_texture_sRGB_RG8")) { 7938bf80f4bSopenharmony_ci sf.insert(sf.end(), std::begin(IMAGE_FORMATS_EXT_SRGB_RG8), std::end(IMAGE_FORMATS_EXT_SRGB_RG8)); 7948bf80f4bSopenharmony_ci } 7958bf80f4bSopenharmony_ci#endif 7968bf80f4bSopenharmony_ci 7978bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_sRGB) && (GL_EXT_texture_sRGB) 7988bf80f4bSopenharmony_ci if (device.HasExtension("GL_EXT_texture_sRGB")) { 7998bf80f4bSopenharmony_ci sf.insert(sf.end(), std::begin(IMAGE_FORMATS_EXT_SRGB), std::end(IMAGE_FORMATS_EXT_SRGB)); 8008bf80f4bSopenharmony_ci } 8018bf80f4bSopenharmony_ci#endif 8028bf80f4bSopenharmony_ci 8038bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_format_BGRA8888) && (GL_EXT_texture_format_BGRA8888) 8048bf80f4bSopenharmony_ci if (device.HasExtension("GL_EXT_texture_format_BGRA8888")) { 8058bf80f4bSopenharmony_ci sf.insert(sf.end(), std::begin(IMAGE_FORMATS_EXT_BGRA), std::end(IMAGE_FORMATS_EXT_BGRA)); 8068bf80f4bSopenharmony_ci } 8078bf80f4bSopenharmony_ci#endif 8088bf80f4bSopenharmony_ci 8098bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_norm16) && (GL_EXT_texture_norm16) 8108bf80f4bSopenharmony_ci if (device.HasExtension("GL_EXT_texture_norm16")) { 8118bf80f4bSopenharmony_ci sf.insert(sf.end(), std::begin(IMAGE_FORMATS_EXT_NORM16), std::end(IMAGE_FORMATS_EXT_NORM16)); 8128bf80f4bSopenharmony_ci } 8138bf80f4bSopenharmony_ci#endif 8148bf80f4bSopenharmony_ci 8158bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_compression_s3tc) && (GL_EXT_texture_compression_s3tc) 8168bf80f4bSopenharmony_ci if (device.HasExtension("GL_EXT_texture_compression_s3tc")) { 8178bf80f4bSopenharmony_ci sf.insert(sf.end(), std::begin(IMAGE_FORMATS_EXT_S3TC), std::end(IMAGE_FORMATS_EXT_S3TC)); 8188bf80f4bSopenharmony_ci } 8198bf80f4bSopenharmony_ci#endif 8208bf80f4bSopenharmony_ci 8218bf80f4bSopenharmony_ci#if defined(GL_ARB_texture_compression_bptc) && (GL_ARB_texture_compression_bptc) 8228bf80f4bSopenharmony_ci if (device.HasExtension("GL_ARB_texture_compression_bptc")) { 8238bf80f4bSopenharmony_ci sf.insert(sf.end(), std::begin(IMAGE_FORMATS_EXT_BPTC), std::end(IMAGE_FORMATS_EXT_BPTC)); 8248bf80f4bSopenharmony_ci } 8258bf80f4bSopenharmony_ci#endif 8268bf80f4bSopenharmony_ci 8278bf80f4bSopenharmony_ci#if defined(GL_EXT_texture_compression_rgtc) && (GL_EXT_texture_compression_rgtc) 8288bf80f4bSopenharmony_ci if (device.HasExtension("GL_EXT_texture_compression_rgtc")) { 8298bf80f4bSopenharmony_ci sf.insert(sf.end(), std::begin(IMAGE_FORMATS_EXT_RGTC), std::end(IMAGE_FORMATS_EXT_RGTC)); 8308bf80f4bSopenharmony_ci } 8318bf80f4bSopenharmony_ci#endif 8328bf80f4bSopenharmony_ci} 8338bf80f4bSopenharmony_ci} // namespace 8348bf80f4bSopenharmony_ci 8358bf80f4bSopenharmony_ci// Some OpenGL/ES features are supported and using them will lead to an assertion unless 8368bf80f4bSopenharmony_ci// the following define is added locally or as part of the build command: #define HANDLE_UNSUPPORTED_ENUMS 8378bf80f4bSopenharmony_ciinline uint32_t DeviceGLES::TargetToBinding(uint32_t target) 8388bf80f4bSopenharmony_ci{ 8398bf80f4bSopenharmony_ci if (target == GL_UNIFORM_BUFFER) { 8408bf80f4bSopenharmony_ci return GL_UNIFORM_BUFFER_BINDING; 8418bf80f4bSopenharmony_ci } else if (target == GL_SHADER_STORAGE_BUFFER) { 8428bf80f4bSopenharmony_ci return GL_SHADER_STORAGE_BUFFER_BINDING; 8438bf80f4bSopenharmony_ci } else if (target == GL_PIXEL_UNPACK_BUFFER) { 8448bf80f4bSopenharmony_ci return GL_PIXEL_UNPACK_BUFFER_BINDING; 8458bf80f4bSopenharmony_ci } else if (target == GL_COPY_READ_BUFFER) { 8468bf80f4bSopenharmony_ci return GL_COPY_READ_BUFFER_BINDING; 8478bf80f4bSopenharmony_ci } else if (target == GL_COPY_WRITE_BUFFER) { 8488bf80f4bSopenharmony_ci return GL_COPY_WRITE_BUFFER_BINDING; 8498bf80f4bSopenharmony_ci#ifdef HANDLE_UNSUPPORTED_ENUMS 8508bf80f4bSopenharmony_ci } else if (target == GL_ATOMIC_COUNTER_BUFFER) { 8518bf80f4bSopenharmony_ci return GL_ATOMIC_COUNTER_BUFFER_BINDING; 8528bf80f4bSopenharmony_ci } else if (target == GL_TRANSFORM_FEEDBACK_BUFFER) { 8538bf80f4bSopenharmony_ci return GL_TRANSFORM_FEEDBACK_BUFFER_BINDING; 8548bf80f4bSopenharmony_ci } else if (target == GL_PIXEL_PACK_BUFFER) { 8558bf80f4bSopenharmony_ci return GL_PIXEL_PACK_BUFFER_BINDING; 8568bf80f4bSopenharmony_ci } else if (target == GL_QUERY_BUFFER) { 8578bf80f4bSopenharmony_ci return GL_QUERY_BUFFER_BINDING; 8588bf80f4bSopenharmony_ci } else if (target == GL_ARRAY_BUFFER) { 8598bf80f4bSopenharmony_ci return GL_ARRAY_BUFFER_BINDING; 8608bf80f4bSopenharmony_ci } else if (target == GL_DISPATCH_INDIRECT_BUFFER) { 8618bf80f4bSopenharmony_ci return GL_DISPATCH_INDIRECT_BUFFER_BINDING; 8628bf80f4bSopenharmony_ci } else if (target == GL_DRAW_INDIRECT_BUFFER) { 8638bf80f4bSopenharmony_ci return GL_DRAW_INDIRECT_BUFFER_BINDING; 8648bf80f4bSopenharmony_ci } else if (target == GL_ELEMENT_ARRAY_BUFFER) { // stored in VAO state... 8658bf80f4bSopenharmony_ci return GL_ELEMENT_ARRAY_BUFFER_BINDING; 8668bf80f4bSopenharmony_ci } else if (target == GL_TEXTURE_BUFFER) { 8678bf80f4bSopenharmony_ci return GL_TEXTURE_BUFFER_BINDING; 8688bf80f4bSopenharmony_ci#endif 8698bf80f4bSopenharmony_ci } 8708bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "UNHANDLED BUFFER BIND TARGET UNIT"); 8718bf80f4bSopenharmony_ci return GL_NONE; 8728bf80f4bSopenharmony_ci} 8738bf80f4bSopenharmony_ci 8748bf80f4bSopenharmony_ciinline DeviceGLES::BufferBindId DeviceGLES::IndexedTargetToTargetId(uint32_t target) 8758bf80f4bSopenharmony_ci{ 8768bf80f4bSopenharmony_ci if (target == GL_UNIFORM_BUFFER) { 8778bf80f4bSopenharmony_ci return BufferBindId::UNIFORM_BUFFER_BIND; 8788bf80f4bSopenharmony_ci } else if (target == GL_SHADER_STORAGE_BUFFER) { 8798bf80f4bSopenharmony_ci return BufferBindId::SHADER_STORAGE_BUFFER_BIND; 8808bf80f4bSopenharmony_ci#ifdef HANDLE_UNSUPPORTED_ENUMS 8818bf80f4bSopenharmony_ci } else if (target == GL_ATOMIC_COUNTER_BUFFER) { 8828bf80f4bSopenharmony_ci return BufferBindId::ATOMIC_COUNTER_BUFFER; 8838bf80f4bSopenharmony_ci } else if (target == GL_TRANSFORM_FEEDBACK_BUFFER) { 8848bf80f4bSopenharmony_ci return BufferBindId::TRANSFORM_FEEDBACK_BUFFER; 8858bf80f4bSopenharmony_ci#endif 8868bf80f4bSopenharmony_ci } 8878bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "UNHANDLED BUFFER BIND TARGET UNIT"); 8888bf80f4bSopenharmony_ci return BufferBindId::MAX_BUFFER_BIND_ID; 8898bf80f4bSopenharmony_ci} 8908bf80f4bSopenharmony_ci 8918bf80f4bSopenharmony_ciinline uint32_t DeviceGLES::IndexedTargetIdToTarget(DeviceGLES::BufferBindId target) 8928bf80f4bSopenharmony_ci{ 8938bf80f4bSopenharmony_ci if (target == BufferBindId::UNIFORM_BUFFER_BIND) { 8948bf80f4bSopenharmony_ci return GL_UNIFORM_BUFFER; 8958bf80f4bSopenharmony_ci } else if (target == BufferBindId::SHADER_STORAGE_BUFFER_BIND) { 8968bf80f4bSopenharmony_ci return GL_SHADER_STORAGE_BUFFER; 8978bf80f4bSopenharmony_ci#ifdef HANDLE_UNSUPPORTED_ENUMS 8988bf80f4bSopenharmony_ci } else if (target == BufferBindId::ATOMIC_COUNTER_BUFFER_BIND) { 8998bf80f4bSopenharmony_ci return GL_ATOMIC_COUNTER_BUFFER; 9008bf80f4bSopenharmony_ci } else if (target == BufferBindId::TRANSFORM_FEEDBACK_BUFFER_BIND) { 9018bf80f4bSopenharmony_ci return GL_TRANSFORM_FEEDBACK_BUFFER; 9028bf80f4bSopenharmony_ci#endif 9038bf80f4bSopenharmony_ci } 9048bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "UNHANDLED BUFFER BIND TARGET UNIT"); 9058bf80f4bSopenharmony_ci return 0; 9068bf80f4bSopenharmony_ci} 9078bf80f4bSopenharmony_ci 9088bf80f4bSopenharmony_ciinline DeviceGLES::BufferTargetId DeviceGLES::GenericTargetToTargetId(uint32_t target) 9098bf80f4bSopenharmony_ci{ 9108bf80f4bSopenharmony_ci if (target == GL_PIXEL_UNPACK_BUFFER) { 9118bf80f4bSopenharmony_ci return BufferTargetId::PIXEL_UNPACK_BUFFER; 9128bf80f4bSopenharmony_ci } else if (target == GL_PIXEL_PACK_BUFFER) { 9138bf80f4bSopenharmony_ci return BufferTargetId::PIXEL_PACK_BUFFER; 9148bf80f4bSopenharmony_ci } else if (target == GL_COPY_READ_BUFFER) { 9158bf80f4bSopenharmony_ci return BufferTargetId::COPY_READ_BUFFER; 9168bf80f4bSopenharmony_ci } else if (target == GL_COPY_WRITE_BUFFER) { 9178bf80f4bSopenharmony_ci return BufferTargetId::COPY_WRITE_BUFFER; 9188bf80f4bSopenharmony_ci } else if (target == GL_UNIFORM_BUFFER) { 9198bf80f4bSopenharmony_ci return BufferTargetId::UNIFORM_BUFFER; 9208bf80f4bSopenharmony_ci } else if (target == GL_SHADER_STORAGE_BUFFER) { 9218bf80f4bSopenharmony_ci return BufferTargetId::SHADER_STORAGE_BUFFER; 9228bf80f4bSopenharmony_ci } else if (target == GL_DISPATCH_INDIRECT_BUFFER) { 9238bf80f4bSopenharmony_ci return BufferTargetId::DISPATCH_INDIRECT_BUFFER; 9248bf80f4bSopenharmony_ci } else if (target == GL_DRAW_INDIRECT_BUFFER) { 9258bf80f4bSopenharmony_ci return BufferTargetId::DRAW_INDIRECT_BUFFER; 9268bf80f4bSopenharmony_ci#ifdef HANDLE_UNSUPPORTED_ENUMS 9278bf80f4bSopenharmony_ci } else if (target == GL_ATOMIC_COUNTER_BUFFER) { 9288bf80f4bSopenharmony_ci return BufferTargetId::ATOMIC_COUNTER_BUFFER; 9298bf80f4bSopenharmony_ci } else if (target == GL_QUERY_BUFFER) { 9308bf80f4bSopenharmony_ci return BufferTargetId::QUERY_BUFFER; 9318bf80f4bSopenharmony_ci } else if (target == GL_TRANSFORM_FEEDBACK_BUFFER) { 9328bf80f4bSopenharmony_ci return BufferTargetId::TRANSFORM_FEEDBACK_BUFFER; 9338bf80f4bSopenharmony_ci } else if (target == GL_ARRAY_BUFFER) { 9348bf80f4bSopenharmony_ci return BufferTargetId::ARRAY_BUFFER; 9358bf80f4bSopenharmony_ci } else if (target == GL_ELEMENT_ARRAY_BUFFER) { // stored in VAO state... 9368bf80f4bSopenharmony_ci return BufferTargetId::ELEMENT_ARRAY_BUFFER; 9378bf80f4bSopenharmony_ci } else if (target == GL_TEXTURE_BUFFER) { 9388bf80f4bSopenharmony_ci return BufferTargetId::TEXTURE_BUFFER; 9398bf80f4bSopenharmony_ci#endif 9408bf80f4bSopenharmony_ci } 9418bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "UNHANDLED BUFFER BIND TARGET"); 9428bf80f4bSopenharmony_ci return BufferTargetId::MAX_BUFFER_TARGET_ID; 9438bf80f4bSopenharmony_ci} 9448bf80f4bSopenharmony_ci 9458bf80f4bSopenharmony_ciinline uint32_t DeviceGLES::GenericTargetIdToTarget(BufferTargetId target) 9468bf80f4bSopenharmony_ci{ 9478bf80f4bSopenharmony_ci if (target == BufferTargetId::PIXEL_UNPACK_BUFFER) { 9488bf80f4bSopenharmony_ci return GL_PIXEL_UNPACK_BUFFER; 9498bf80f4bSopenharmony_ci } else if (target == BufferTargetId::PIXEL_PACK_BUFFER) { 9508bf80f4bSopenharmony_ci return GL_PIXEL_PACK_BUFFER; 9518bf80f4bSopenharmony_ci } else if (target == BufferTargetId::COPY_READ_BUFFER) { 9528bf80f4bSopenharmony_ci return GL_COPY_READ_BUFFER; 9538bf80f4bSopenharmony_ci } else if (target == BufferTargetId::COPY_WRITE_BUFFER) { 9548bf80f4bSopenharmony_ci return GL_COPY_WRITE_BUFFER; 9558bf80f4bSopenharmony_ci } else if (target == BufferTargetId::UNIFORM_BUFFER) { 9568bf80f4bSopenharmony_ci return GL_UNIFORM_BUFFER; 9578bf80f4bSopenharmony_ci } else if (target == BufferTargetId::SHADER_STORAGE_BUFFER) { 9588bf80f4bSopenharmony_ci return GL_SHADER_STORAGE_BUFFER; 9598bf80f4bSopenharmony_ci } else if (target == BufferTargetId::DISPATCH_INDIRECT_BUFFER) { 9608bf80f4bSopenharmony_ci return GL_DISPATCH_INDIRECT_BUFFER; 9618bf80f4bSopenharmony_ci } else if (target == BufferTargetId::DRAW_INDIRECT_BUFFER) { 9628bf80f4bSopenharmony_ci return GL_DRAW_INDIRECT_BUFFER; 9638bf80f4bSopenharmony_ci#ifdef HANDLE_UNSUPPORTED_ENUMS 9648bf80f4bSopenharmony_ci } else if (target == BufferTargetId::ATOMIC_COUNTER_BUFFER) { 9658bf80f4bSopenharmony_ci return GL_ATOMIC_COUNTER_BUFFER; 9668bf80f4bSopenharmony_ci } else if (target == BufferTargetId::QUERY_BUFFER) { 9678bf80f4bSopenharmony_ci return GL_QUERY_BUFFER; 9688bf80f4bSopenharmony_ci } else if (target == BufferTargetId::TRANSFORM_FEEDBACK_BUFFER) { 9698bf80f4bSopenharmony_ci return GL_TRANSFORM_FEEDBACK_BUFFER; 9708bf80f4bSopenharmony_ci } else if (target == BufferTargetId::ARRAY_BUFFER) { 9718bf80f4bSopenharmony_ci return GL_ARRAY_BUFFER; 9728bf80f4bSopenharmony_ci } else if (target == BufferTargetId::ELEMENT_ARRAY_BUFFER) { // stored in VAO state... 9738bf80f4bSopenharmony_ci return GL_ELEMENT_ARRAY_BUFFER; 9748bf80f4bSopenharmony_ci } else if (target == BufferTargetId::TEXTURE_BUFFER) { 9758bf80f4bSopenharmony_ci return GL_TEXTURE_BUFFER; 9768bf80f4bSopenharmony_ci#endif 9778bf80f4bSopenharmony_ci } 9788bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "UNHANDLED BUFFER BIND TARGET"); 9798bf80f4bSopenharmony_ci return 0; 9808bf80f4bSopenharmony_ci} 9818bf80f4bSopenharmony_ci 9828bf80f4bSopenharmony_ciinline DeviceGLES::TextureTargetId DeviceGLES::TextureTargetToTargetId(uint32_t target) 9838bf80f4bSopenharmony_ci{ 9848bf80f4bSopenharmony_ci if (target == GL_TEXTURE_2D) { 9858bf80f4bSopenharmony_ci return TextureTargetId::TEXTURE_2D; 9868bf80f4bSopenharmony_ci } else if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X) || (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X) || 9878bf80f4bSopenharmony_ci (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y) || (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) || 9888bf80f4bSopenharmony_ci (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z) || (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) || 9898bf80f4bSopenharmony_ci (target == GL_TEXTURE_CUBE_MAP)) { 9908bf80f4bSopenharmony_ci return TextureTargetId::TEXTURE_CUBE_MAP; 9918bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 9928bf80f4bSopenharmony_ci } else if (target == GL_TEXTURE_EXTERNAL_OES) { 9938bf80f4bSopenharmony_ci return TextureTargetId::TEXTURE_EXTERNAL_OES; 9948bf80f4bSopenharmony_ci#endif 9958bf80f4bSopenharmony_ci } else if (target == GL_TEXTURE_2D_MULTISAMPLE) { 9968bf80f4bSopenharmony_ci return TextureTargetId::TEXTURE_2D_MULTISAMPLE; 9978bf80f4bSopenharmony_ci } else if (target == GL_TEXTURE_2D_ARRAY) { 9988bf80f4bSopenharmony_ci return TextureTargetId::TEXTURE_2D_ARRAY; 9998bf80f4bSopenharmony_ci } else if (target == GL_TEXTURE_3D) { 10008bf80f4bSopenharmony_ci return TextureTargetId::TEXTURE_3D; 10018bf80f4bSopenharmony_ci } 10028bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "UNHANDLED TEXTURE TARGET UNIT"); 10038bf80f4bSopenharmony_ci return TextureTargetId::MAX_TEXTURE_TARGET_ID; 10048bf80f4bSopenharmony_ci} 10058bf80f4bSopenharmony_ci 10068bf80f4bSopenharmony_ciinline uint32_t DeviceGLES::TextureTargetIdToTarget(DeviceGLES::TextureTargetId target) 10078bf80f4bSopenharmony_ci{ 10088bf80f4bSopenharmony_ci if (target == TextureTargetId::TEXTURE_2D) { 10098bf80f4bSopenharmony_ci return GL_TEXTURE_2D; 10108bf80f4bSopenharmony_ci } else if (target == TextureTargetId::TEXTURE_CUBE_MAP) { 10118bf80f4bSopenharmony_ci return GL_TEXTURE_CUBE_MAP; 10128bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 10138bf80f4bSopenharmony_ci } else if (target == TextureTargetId::TEXTURE_EXTERNAL_OES) { 10148bf80f4bSopenharmony_ci return GL_TEXTURE_EXTERNAL_OES; 10158bf80f4bSopenharmony_ci#endif 10168bf80f4bSopenharmony_ci } else if (target == TextureTargetId::TEXTURE_2D_MULTISAMPLE) { 10178bf80f4bSopenharmony_ci return GL_TEXTURE_2D_MULTISAMPLE; 10188bf80f4bSopenharmony_ci } else if (target == TextureTargetId::TEXTURE_2D_ARRAY) { 10198bf80f4bSopenharmony_ci return GL_TEXTURE_2D_ARRAY; 10208bf80f4bSopenharmony_ci } else if (target == TextureTargetId::TEXTURE_3D) { 10218bf80f4bSopenharmony_ci return GL_TEXTURE_3D; 10228bf80f4bSopenharmony_ci } 10238bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "UNHANDLED TEXTURE TARGET UNIT"); 10248bf80f4bSopenharmony_ci return 0; 10258bf80f4bSopenharmony_ci} 10268bf80f4bSopenharmony_ci 10278bf80f4bSopenharmony_civoid DeviceGLES::Activate(RenderHandle swapchain) 10288bf80f4bSopenharmony_ci{ 10298bf80f4bSopenharmony_ci if (HasSwapchain()) { 10308bf80f4bSopenharmony_ci eglState_.SetContext(static_cast<const SwapchainGLES*>(GetSwapchain(swapchain))); 10318bf80f4bSopenharmony_ci } else { 10328bf80f4bSopenharmony_ci // bind the dummy surface as there is no swapchain. 10338bf80f4bSopenharmony_ci eglState_.SetContext(nullptr); 10348bf80f4bSopenharmony_ci } 10358bf80f4bSopenharmony_ci} 10368bf80f4bSopenharmony_ci 10378bf80f4bSopenharmony_civoid DeviceGLES::SwapBuffers(const SwapchainGLES& swapchain) 10388bf80f4bSopenharmony_ci{ 10398bf80f4bSopenharmony_ci eglState_.SwapBuffers(swapchain); 10408bf80f4bSopenharmony_ci} 10418bf80f4bSopenharmony_ci 10428bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND 10438bf80f4bSopenharmony_ciconst WGLHelpers::WGLState& DeviceGLES::GetEglState() 10448bf80f4bSopenharmony_ci#endif 10458bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 10468bf80f4bSopenharmony_ci const EGLHelpers::EGLState& DeviceGLES::GetEglState() 10478bf80f4bSopenharmony_ci#endif 10488bf80f4bSopenharmony_ci{ 10498bf80f4bSopenharmony_ci return eglState_; 10508bf80f4bSopenharmony_ci} 10518bf80f4bSopenharmony_ci 10528bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 10538bf80f4bSopenharmony_cibool DeviceGLES::IsDepthResolveSupported() const 10548bf80f4bSopenharmony_ci{ 10558bf80f4bSopenharmony_ci return backendConfig_.allowDepthResolve; 10568bf80f4bSopenharmony_ci} 10578bf80f4bSopenharmony_ci#endif 10588bf80f4bSopenharmony_ci 10598bf80f4bSopenharmony_ciDeviceGLES::DeviceGLES(RenderContext& renderContext, DeviceCreateInfo const& createInfo) 10608bf80f4bSopenharmony_ci : Device(renderContext, createInfo) 10618bf80f4bSopenharmony_ci{ 10628bf80f4bSopenharmony_ci eglState_.CreateContext(createInfo); 10638bf80f4bSopenharmony_ci if (!eglState_.IsValid()) { 10648bf80f4bSopenharmony_ci PLUGIN_LOG_F("Failed to create a context"); 10658bf80f4bSopenharmony_ci return; 10668bf80f4bSopenharmony_ci } 10678bf80f4bSopenharmony_ci eglState_.GlInitialize(); 10688bf80f4bSopenharmony_ci#if RENDER_GL_DEBUG 10698bf80f4bSopenharmony_ci filterErrorFunc = (decltype(filterErrorFunc))eglState_.ErrorFilter(); 10708bf80f4bSopenharmony_ci glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); 10718bf80f4bSopenharmony_ci glDebugMessageCallback(OnGlError, NULL); 10728bf80f4bSopenharmony_ci GLuint unusedIds = 0; 10738bf80f4bSopenharmony_ci glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, &unusedIds, true); 10748bf80f4bSopenharmony_ci#endif 10758bf80f4bSopenharmony_ci PLUGIN_LOG_I("GL_VENDOR: %s", glGetString(GL_VENDOR)); 10768bf80f4bSopenharmony_ci PLUGIN_LOG_I("GL_RENDERER: %s", glGetString(GL_RENDERER)); 10778bf80f4bSopenharmony_ci PLUGIN_LOG_I("GL_VERSION: %s", glGetString(GL_VERSION)); 10788bf80f4bSopenharmony_ci PLUGIN_LOG_I("GL_SHADING_LANGUAGE_VERSION: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); 10798bf80f4bSopenharmony_ci GLint n = 0; 10808bf80f4bSopenharmony_ci glGetIntegerv(GL_NUM_EXTENSIONS, &n); 10818bf80f4bSopenharmony_ci extensions_.reserve(n + 1U); 10828bf80f4bSopenharmony_ci for (GLuint i = 0U; i < static_cast<GLuint>(n); ++i) { 10838bf80f4bSopenharmony_ci const auto ext = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i)); 10848bf80f4bSopenharmony_ci PLUGIN_LOG_V(" GL_EXTENSION: %s", ext); 10858bf80f4bSopenharmony_ci extensions_.emplace_back(ext); 10868bf80f4bSopenharmony_ci } 10878bf80f4bSopenharmony_ci std::sort(extensions_.begin(), extensions_.end(), 10888bf80f4bSopenharmony_ci [](const string_view& lhs, const string_view& rhs) { return lhs < rhs; }); 10898bf80f4bSopenharmony_ci 10908bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND 10918bf80f4bSopenharmony_ci // Extension in OpenGL ES, but part of core in OpenGL. 10928bf80f4bSopenharmony_ci if (const auto pos = std::lower_bound(extensions_.cbegin(), extensions_.cend(), EXT_BUFFER_STORAGE, 10938bf80f4bSopenharmony_ci [](const string_view& element, const string_view& value) { return element < value; }); 10948bf80f4bSopenharmony_ci (pos == extensions_.cend()) || (*pos != EXT_BUFFER_STORAGE)) { 10958bf80f4bSopenharmony_ci extensions_.insert(pos, EXT_BUFFER_STORAGE); 10968bf80f4bSopenharmony_ci } 10978bf80f4bSopenharmony_ci // Seamless cubemaps are always on in vulkan and gles 3.0.. 10988bf80f4bSopenharmony_ci // (3.0 made it required, not supported prior to 3.0 es) 10998bf80f4bSopenharmony_ci // on desktop gl, it's optional. 11008bf80f4bSopenharmony_ci // (but must be supported since 3.2) 11018bf80f4bSopenharmony_ci // So just enable it always, so that desktop GL works as vulkan and GLES. 11028bf80f4bSopenharmony_ci glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); 11038bf80f4bSopenharmony_ci#endif 11048bf80f4bSopenharmony_ci#if RENDER_GL_DEBUG 11058bf80f4bSopenharmony_ci // Dump interesting constants. 11068bf80f4bSopenharmony_ci DUMP(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS); 11078bf80f4bSopenharmony_ci DUMP(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS); 11088bf80f4bSopenharmony_ci DUMP(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS); 11098bf80f4bSopenharmony_ci DUMP(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS); 11108bf80f4bSopenharmony_ci DUMP(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS); 11118bf80f4bSopenharmony_ci DUMP(GL_MAX_SHADER_STORAGE_BLOCK_SIZE); 11128bf80f4bSopenharmony_ci#endif 11138bf80f4bSopenharmony_ci boundReadFbo_ = boundWriteFbo_ = 0; 11148bf80f4bSopenharmony_ci eglState_.RestoreContext(); 11158bf80f4bSopenharmony_ci#ifdef RENDER_OPTIMIZE_FOR_INTEGRATED_GPU 11168bf80f4bSopenharmony_ci // NOTE: we expect e.g. mobile devices to have integrated memory, where we can bypass staging and write directly to 11178bf80f4bSopenharmony_ci // linear gpu buffers without additional copies and performance decrease 11188bf80f4bSopenharmony_ci deviceSharedMemoryPropertyFlags_ = CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 11198bf80f4bSopenharmony_ci#endif 11208bf80f4bSopenharmony_ci SetDeviceStatus(true); 11218bf80f4bSopenharmony_ci 11228bf80f4bSopenharmony_ci // First dump required formats and then add based on supported extensions 11238bf80f4bSopenharmony_ci supportedFormats_.insert(supportedFormats_.end(), std::begin(IMAGE_FORMATS), std::end(IMAGE_FORMATS)); 11248bf80f4bSopenharmony_ci 11258bf80f4bSopenharmony_ci FillExtensionFormats(*this, supportedFormats_); 11268bf80f4bSopenharmony_ci 11278bf80f4bSopenharmony_ci // Keep the list sorted for faster lookup 11288bf80f4bSopenharmony_ci std::sort(supportedFormats_.begin(), supportedFormats_.end(), 11298bf80f4bSopenharmony_ci [](const ImageFormat& lhs, const ImageFormat& rhs) { return lhs.coreFormat < rhs.coreFormat; }); 11308bf80f4bSopenharmony_ci 11318bf80f4bSopenharmony_ci const GpuResourceManager::CreateInfo grmCreateInfo { 11328bf80f4bSopenharmony_ci GpuResourceManager::GPU_RESOURCE_MANAGER_OPTIMIZE_STAGING_MEMORY, 11338bf80f4bSopenharmony_ci }; 11348bf80f4bSopenharmony_ci gpuResourceMgr_ = make_unique<GpuResourceManager>(*this, grmCreateInfo); 11358bf80f4bSopenharmony_ci shaderMgr_ = make_unique<ShaderManager>(*this); 11368bf80f4bSopenharmony_ci 11378bf80f4bSopenharmony_ci lowLevelDevice_ = make_unique<LowLevelDeviceGLES>(*this); 11388bf80f4bSopenharmony_ci} 11398bf80f4bSopenharmony_ci 11408bf80f4bSopenharmony_ciDeviceGLES::~DeviceGLES() 11418bf80f4bSopenharmony_ci{ 11428bf80f4bSopenharmony_ci if (eglState_.IsValid()) { 11438bf80f4bSopenharmony_ci Activate(); // make sure we are active during teardown.. 11448bf80f4bSopenharmony_ci WaitForIdle(); 11458bf80f4bSopenharmony_ci 11468bf80f4bSopenharmony_ci // must release handles before taking down gpu resource manager. 11478bf80f4bSopenharmony_ci swapchains_.clear(); 11488bf80f4bSopenharmony_ci 11498bf80f4bSopenharmony_ci gpuResourceMgr_.reset(); 11508bf80f4bSopenharmony_ci shaderMgr_.reset(); 11518bf80f4bSopenharmony_ci eglState_.DestroyContext(); 11528bf80f4bSopenharmony_ci Deactivate(); // make sure the previous context is still active.. 11538bf80f4bSopenharmony_ci } 11548bf80f4bSopenharmony_ci} 11558bf80f4bSopenharmony_ci 11568bf80f4bSopenharmony_cibool DeviceGLES::HasExtension(const string_view extension) const 11578bf80f4bSopenharmony_ci{ 11588bf80f4bSopenharmony_ci return std::binary_search(extensions_.begin(), extensions_.end(), extension, 11598bf80f4bSopenharmony_ci [](const string_view& element, const string_view value) { return element < value; }); 11608bf80f4bSopenharmony_ci} 11618bf80f4bSopenharmony_ci 11628bf80f4bSopenharmony_ciDeviceBackendType DeviceGLES::GetBackendType() const 11638bf80f4bSopenharmony_ci{ 11648bf80f4bSopenharmony_ci return backendType_; 11658bf80f4bSopenharmony_ci} 11668bf80f4bSopenharmony_ci 11678bf80f4bSopenharmony_ciconst DevicePlatformData& DeviceGLES::GetPlatformData() const 11688bf80f4bSopenharmony_ci{ 11698bf80f4bSopenharmony_ci return eglState_.GetPlatformData(); 11708bf80f4bSopenharmony_ci} 11718bf80f4bSopenharmony_ci 11728bf80f4bSopenharmony_ciILowLevelDevice& DeviceGLES::GetLowLevelDevice() const 11738bf80f4bSopenharmony_ci{ 11748bf80f4bSopenharmony_ci return *lowLevelDevice_; 11758bf80f4bSopenharmony_ci} 11768bf80f4bSopenharmony_ci 11778bf80f4bSopenharmony_ciFormatProperties DeviceGLES::GetFormatProperties(const Format format) const 11788bf80f4bSopenharmony_ci{ 11798bf80f4bSopenharmony_ci FormatProperties properties; 11808bf80f4bSopenharmony_ci auto& glFormat = GetGlImageFormat(format); 11818bf80f4bSopenharmony_ci if (glFormat.internalFormat != GL_NONE) { 11828bf80f4bSopenharmony_ci if (auto pos = std::find_if(std::begin(IMAGE_FORMAT_FEATURES), std::end(IMAGE_FORMAT_FEATURES), 11838bf80f4bSopenharmony_ci [internalFormat = glFormat.internalFormat]( 11848bf80f4bSopenharmony_ci const FormatFeatures& features) { return features.internalFormat == internalFormat; }); 11858bf80f4bSopenharmony_ci pos != std::end(IMAGE_FORMAT_FEATURES)) { 11868bf80f4bSopenharmony_ci // split texel buffer support to bufferFeatures 11878bf80f4bSopenharmony_ci properties.linearTilingFeatures = properties.optimalTilingFeatures = 11888bf80f4bSopenharmony_ci pos->flags & ~CORE_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; 11898bf80f4bSopenharmony_ci // assume if the format can be sampled it can be used as a vertex buffer. 11908bf80f4bSopenharmony_ci properties.bufferFeatures = 11918bf80f4bSopenharmony_ci ((pos->flags & CORE_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? CORE_FORMAT_FEATURE_VERTEX_BUFFER_BIT : 0U) | 11928bf80f4bSopenharmony_ci (pos->flags & CORE_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT); 11938bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND 11948bf80f4bSopenharmony_ci // desktop GL can filter anything 11958bf80f4bSopenharmony_ci properties.linearTilingFeatures |= TF; 11968bf80f4bSopenharmony_ci properties.optimalTilingFeatures |= TF; 11978bf80f4bSopenharmony_ci#endif 11988bf80f4bSopenharmony_ci // can probably blit if not compressed 11998bf80f4bSopenharmony_ci if (!glFormat.compression.compressed) { 12008bf80f4bSopenharmony_ci properties.linearTilingFeatures |= CORE_FORMAT_FEATURE_BLIT_DST_BIT | CORE_FORMAT_FEATURE_BLIT_SRC_BIT; 12018bf80f4bSopenharmony_ci properties.optimalTilingFeatures |= CORE_FORMAT_FEATURE_BLIT_DST_BIT | CORE_FORMAT_FEATURE_BLIT_SRC_BIT; 12028bf80f4bSopenharmony_ci } 12038bf80f4bSopenharmony_ci properties.bytesPerPixel = glFormat.bytesperpixel; 12048bf80f4bSopenharmony_ci } 12058bf80f4bSopenharmony_ci } 12068bf80f4bSopenharmony_ci return properties; 12078bf80f4bSopenharmony_ci} 12088bf80f4bSopenharmony_ci 12098bf80f4bSopenharmony_ciAccelerationStructureBuildSizes DeviceGLES::GetAccelerationStructureBuildSizes( 12108bf80f4bSopenharmony_ci const AccelerationStructureBuildGeometryInfo& geometry, 12118bf80f4bSopenharmony_ci BASE_NS::array_view<const AccelerationStructureGeometryTrianglesInfo> triangles, 12128bf80f4bSopenharmony_ci BASE_NS::array_view<const AccelerationStructureGeometryAabbsInfo> aabbs, 12138bf80f4bSopenharmony_ci BASE_NS::array_view<const AccelerationStructureGeometryInstancesInfo> instances) const 12148bf80f4bSopenharmony_ci{ 12158bf80f4bSopenharmony_ci return {}; 12168bf80f4bSopenharmony_ci} 12178bf80f4bSopenharmony_ci 12188bf80f4bSopenharmony_ciPlatformGpuMemoryAllocator* DeviceGLES::GetPlatformGpuMemoryAllocator() 12198bf80f4bSopenharmony_ci{ 12208bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "DeviceGLES::GetPlatformGpuMemoryAllocator called!"); 12218bf80f4bSopenharmony_ci return nullptr; 12228bf80f4bSopenharmony_ci} 12238bf80f4bSopenharmony_ci 12248bf80f4bSopenharmony_ci// (re-)create swapchain 12258bf80f4bSopenharmony_ciunique_ptr<Swapchain> DeviceGLES::CreateDeviceSwapchain(const SwapchainCreateInfo& swapchainCreateInfo) 12268bf80f4bSopenharmony_ci{ 12278bf80f4bSopenharmony_ci PLUGIN_ASSERT(IsActive()); 12288bf80f4bSopenharmony_ci auto swapchain = make_unique<SwapchainGLES>(*this, swapchainCreateInfo); 12298bf80f4bSopenharmony_ci // Switch to the new swapchain. 12308bf80f4bSopenharmony_ci eglState_.SetContext(swapchain.get()); 12318bf80f4bSopenharmony_ci return swapchain; 12328bf80f4bSopenharmony_ci} 12338bf80f4bSopenharmony_ci 12348bf80f4bSopenharmony_civoid DeviceGLES::DestroyDeviceSwapchain() 12358bf80f4bSopenharmony_ci{ 12368bf80f4bSopenharmony_ci PLUGIN_ASSERT(IsActive()); 12378bf80f4bSopenharmony_ci // TODO: 12388bf80f4bSopenharmony_ci // Drop to dummycontext (ie. 1x1 surface etc...) 12398bf80f4bSopenharmony_ci eglState_.SetContext(nullptr); 12408bf80f4bSopenharmony_ci} 12418bf80f4bSopenharmony_ci 12428bf80f4bSopenharmony_cibool DeviceGLES::IsActive() const 12438bf80f4bSopenharmony_ci{ 12448bf80f4bSopenharmony_ci return isActive_ > 0; 12458bf80f4bSopenharmony_ci} 12468bf80f4bSopenharmony_ci 12478bf80f4bSopenharmony_civoid DeviceGLES::Activate() 12488bf80f4bSopenharmony_ci{ 12498bf80f4bSopenharmony_ci activeMutex_.lock(); 12508bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(isActive_ == 0, "Activate called while already inactive"); 12518bf80f4bSopenharmony_ci if (isActive_ == 0) { 12528bf80f4bSopenharmony_ci eglState_.SaveContext(); 12538bf80f4bSopenharmony_ci 12548bf80f4bSopenharmony_ci constexpr RenderHandle defaultSwapchain {}; 12558bf80f4bSopenharmony_ci Activate(defaultSwapchain); 12568bf80f4bSopenharmony_ci } 12578bf80f4bSopenharmony_ci isActive_++; 12588bf80f4bSopenharmony_ci} 12598bf80f4bSopenharmony_ci 12608bf80f4bSopenharmony_civoid DeviceGLES::Deactivate() 12618bf80f4bSopenharmony_ci{ 12628bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(isActive_ > 0, "Deactivate called while already inactive"); 12638bf80f4bSopenharmony_ci if (isActive_ > 0) { 12648bf80f4bSopenharmony_ci isActive_--; 12658bf80f4bSopenharmony_ci } 12668bf80f4bSopenharmony_ci if (isActive_ == 0) { 12678bf80f4bSopenharmony_ci eglState_.RestoreContext(); 12688bf80f4bSopenharmony_ci isActive_ = false; 12698bf80f4bSopenharmony_ci } 12708bf80f4bSopenharmony_ci activeMutex_.unlock(); 12718bf80f4bSopenharmony_ci} 12728bf80f4bSopenharmony_ci 12738bf80f4bSopenharmony_ciGpuQueue DeviceGLES::GetValidGpuQueue(const GpuQueue& gpuQueue) const 12748bf80f4bSopenharmony_ci{ 12758bf80f4bSopenharmony_ci return { GpuQueue::QueueType::GRAPHICS, 0 }; // no queues -> graphics 12768bf80f4bSopenharmony_ci} 12778bf80f4bSopenharmony_ci 12788bf80f4bSopenharmony_ciuint32_t DeviceGLES::GetGpuQueueCount() const 12798bf80f4bSopenharmony_ci{ 12808bf80f4bSopenharmony_ci return 1; 12818bf80f4bSopenharmony_ci} 12828bf80f4bSopenharmony_ci 12838bf80f4bSopenharmony_civoid DeviceGLES::InitializePipelineCache(array_view<const uint8_t> initialData) 12848bf80f4bSopenharmony_ci{ 12858bf80f4bSopenharmony_ci // NOTE: not implemented. 12868bf80f4bSopenharmony_ci} 12878bf80f4bSopenharmony_ci 12888bf80f4bSopenharmony_civector<uint8_t> DeviceGLES::GetPipelineCache() const 12898bf80f4bSopenharmony_ci{ 12908bf80f4bSopenharmony_ci // NOTE: not implemented. could probably be done by gathering glGetProgramBinary results together. 12918bf80f4bSopenharmony_ci return {}; 12928bf80f4bSopenharmony_ci} 12938bf80f4bSopenharmony_ci 12948bf80f4bSopenharmony_civoid DeviceGLES::WaitForIdle() 12958bf80f4bSopenharmony_ci{ 12968bf80f4bSopenharmony_ci const bool activeState = IsActive(); 12978bf80f4bSopenharmony_ci if (!activeState) { 12988bf80f4bSopenharmony_ci Activate(); 12998bf80f4bSopenharmony_ci } 13008bf80f4bSopenharmony_ci if (!isRenderbackendRunning_) { 13018bf80f4bSopenharmony_ci PLUGIN_LOG_D("Device - WaitForIdle"); 13028bf80f4bSopenharmony_ci glFinish(); 13038bf80f4bSopenharmony_ci } else { 13048bf80f4bSopenharmony_ci PLUGIN_LOG_E("Device WaitForIdle can only called when render backend is not running"); 13058bf80f4bSopenharmony_ci } 13068bf80f4bSopenharmony_ci if (!activeState) { 13078bf80f4bSopenharmony_ci Deactivate(); 13088bf80f4bSopenharmony_ci } 13098bf80f4bSopenharmony_ci} 13108bf80f4bSopenharmony_ci 13118bf80f4bSopenharmony_ci#if (RENDER_HAS_GL_BACKEND) 13128bf80f4bSopenharmony_ciunique_ptr<Device> CreateDeviceGL(RenderContext& renderContext, DeviceCreateInfo const& createInfo) 13138bf80f4bSopenharmony_ci{ 13148bf80f4bSopenharmony_ci if (auto device = make_unique<DeviceGLES>(renderContext, createInfo); device) { 13158bf80f4bSopenharmony_ci const auto& plat = static_cast<const DevicePlatformDataGL&>(device->GetPlatformData()); 13168bf80f4bSopenharmony_ci if (plat.context != nullptr) { 13178bf80f4bSopenharmony_ci return device; 13188bf80f4bSopenharmony_ci } 13198bf80f4bSopenharmony_ci } 13208bf80f4bSopenharmony_ci return nullptr; 13218bf80f4bSopenharmony_ci} 13228bf80f4bSopenharmony_ci#endif 13238bf80f4bSopenharmony_ci#if (RENDER_HAS_GLES_BACKEND) 13248bf80f4bSopenharmony_ciunique_ptr<Device> CreateDeviceGLES(RenderContext& renderContext, DeviceCreateInfo const& createInfo) 13258bf80f4bSopenharmony_ci{ 13268bf80f4bSopenharmony_ci if (auto device = make_unique<DeviceGLES>(renderContext, createInfo); device) { 13278bf80f4bSopenharmony_ci const auto& plat = static_cast<const DevicePlatformDataGLES&>(device->GetPlatformData()); 13288bf80f4bSopenharmony_ci if (plat.context != EGL_NO_CONTEXT) { 13298bf80f4bSopenharmony_ci return device; 13308bf80f4bSopenharmony_ci } 13318bf80f4bSopenharmony_ci } 13328bf80f4bSopenharmony_ci return nullptr; 13338bf80f4bSopenharmony_ci} 13348bf80f4bSopenharmony_ci#endif 13358bf80f4bSopenharmony_ci 13368bf80f4bSopenharmony_civoid DeviceGLES::ReleaseShader(uint32_t type, uint32_t shader) 13378bf80f4bSopenharmony_ci{ 13388bf80f4bSopenharmony_ci vector<ShaderCache::Entry>* cache = nullptr; 13398bf80f4bSopenharmony_ci if (type == GL_FRAGMENT_SHADER) { 13408bf80f4bSopenharmony_ci cache = &caches[DeviceGLES::FRAGMENT_CACHE].cache; 13418bf80f4bSopenharmony_ci } else if (type == GL_VERTEX_SHADER) { 13428bf80f4bSopenharmony_ci cache = &caches[DeviceGLES::VERTEX_CACHE].cache; 13438bf80f4bSopenharmony_ci } else if (type == GL_COMPUTE_SHADER) { 13448bf80f4bSopenharmony_ci cache = &caches[DeviceGLES::COMPUTE_CACHE].cache; 13458bf80f4bSopenharmony_ci } else { 13468bf80f4bSopenharmony_ci return; 13478bf80f4bSopenharmony_ci } 13488bf80f4bSopenharmony_ci 13498bf80f4bSopenharmony_ci const auto pos = std::find_if( 13508bf80f4bSopenharmony_ci cache->begin(), cache->end(), [shader](const ShaderCache::Entry& entry) { return entry.shader == shader; }); 13518bf80f4bSopenharmony_ci if (pos != cache->end()) { 13528bf80f4bSopenharmony_ci ShaderCache::Entry& entry = *pos; 13538bf80f4bSopenharmony_ci entry.refCount--; 13548bf80f4bSopenharmony_ci if (entry.refCount == 0) { 13558bf80f4bSopenharmony_ci glDeleteShader(entry.shader); 13568bf80f4bSopenharmony_ci cache->erase(pos); 13578bf80f4bSopenharmony_ci } 13588bf80f4bSopenharmony_ci return; 13598bf80f4bSopenharmony_ci } 13608bf80f4bSopenharmony_ci 13618bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "Tried to release a non-existant shader?"); 13628bf80f4bSopenharmony_ci} 13638bf80f4bSopenharmony_ci 13648bf80f4bSopenharmony_civoid DeviceGLES::ReleaseProgram(uint32_t program) 13658bf80f4bSopenharmony_ci{ 13668bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(isActive_, "Device not active when releasing shaders"); 13678bf80f4bSopenharmony_ci for (auto it = programs_.begin(); it != programs_.end(); it++) { 13688bf80f4bSopenharmony_ci auto& t = *it; 13698bf80f4bSopenharmony_ci if (t.program == program) { 13708bf80f4bSopenharmony_ci t.refCount--; 13718bf80f4bSopenharmony_ci if (t.refCount == 0) { 13728bf80f4bSopenharmony_ci if (t.fragShader) { 13738bf80f4bSopenharmony_ci ReleaseShader(GL_FRAGMENT_SHADER, t.fragShader); 13748bf80f4bSopenharmony_ci } 13758bf80f4bSopenharmony_ci if (t.vertShader) { 13768bf80f4bSopenharmony_ci ReleaseShader(GL_VERTEX_SHADER, t.vertShader); 13778bf80f4bSopenharmony_ci } 13788bf80f4bSopenharmony_ci if (t.compShader) { 13798bf80f4bSopenharmony_ci ReleaseShader(GL_COMPUTE_SHADER, t.compShader); 13808bf80f4bSopenharmony_ci } 13818bf80f4bSopenharmony_ci glDeleteProgram(t.program); 13828bf80f4bSopenharmony_ci programs_.erase(it); 13838bf80f4bSopenharmony_ci } 13848bf80f4bSopenharmony_ci return; 13858bf80f4bSopenharmony_ci } 13868bf80f4bSopenharmony_ci } 13878bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(false, "Tried to release a non-existant program?"); 13888bf80f4bSopenharmony_ci} 13898bf80f4bSopenharmony_ci 13908bf80f4bSopenharmony_ciconst DeviceGLES::ShaderCache::Entry& DeviceGLES::CacheShader(int type, const string_view source) 13918bf80f4bSopenharmony_ci{ 13928bf80f4bSopenharmony_ci PLUGIN_ASSERT(type < MAX_CACHES); 13938bf80f4bSopenharmony_ci if (source.empty()) { 13948bf80f4bSopenharmony_ci static constexpr DeviceGLES::ShaderCache::Entry invalid {}; 13958bf80f4bSopenharmony_ci return invalid; 13968bf80f4bSopenharmony_ci } 13978bf80f4bSopenharmony_ci constexpr GLenum types[] = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_COMPUTE_SHADER }; 13988bf80f4bSopenharmony_ci // NOTE: check other hash functions, also i guess verify (strcmp) on collision would be prudent. 13998bf80f4bSopenharmony_ci const uint64_t hash = FNV1aHash(source.data(), source.size()); 14008bf80f4bSopenharmony_ci PLUGIN_ASSERT(hash != 0); 14018bf80f4bSopenharmony_ci for (auto& t : caches[type].cache) { 14028bf80f4bSopenharmony_ci if (t.hash == hash) { 14038bf80f4bSopenharmony_ci caches[type].hit++; 14048bf80f4bSopenharmony_ci t.refCount++; 14058bf80f4bSopenharmony_ci return t; 14068bf80f4bSopenharmony_ci } 14078bf80f4bSopenharmony_ci } 14088bf80f4bSopenharmony_ci caches[type].miss++; 14098bf80f4bSopenharmony_ci DeviceGLES::ShaderCache::Entry entry; 14108bf80f4bSopenharmony_ci entry.hash = hash; 14118bf80f4bSopenharmony_ci entry.shader = glCreateShader(types[type]); 14128bf80f4bSopenharmony_ci entry.refCount = 1; 14138bf80f4bSopenharmony_ci const GLint len = static_cast<GLint>(source.length()); 14148bf80f4bSopenharmony_ci const auto data = source.data(); 14158bf80f4bSopenharmony_ci glShaderSource(entry.shader, 1, &data, &len); 14168bf80f4bSopenharmony_ci glCompileShader(entry.shader); 14178bf80f4bSopenharmony_ci GLint result = GL_FALSE; 14188bf80f4bSopenharmony_ci glGetShaderiv(entry.shader, GL_COMPILE_STATUS, &result); 14198bf80f4bSopenharmony_ci if (result == GL_FALSE) { 14208bf80f4bSopenharmony_ci GLint logLength = 0; 14218bf80f4bSopenharmony_ci glGetShaderiv(entry.shader, GL_INFO_LOG_LENGTH, &logLength); 14228bf80f4bSopenharmony_ci string messages; 14238bf80f4bSopenharmony_ci messages.resize(static_cast<size_t>(logLength)); 14248bf80f4bSopenharmony_ci glGetShaderInfoLog(entry.shader, logLength, 0, messages.data()); 14258bf80f4bSopenharmony_ci PLUGIN_LOG_F("Shader compilation error: %s", messages.c_str()); 14268bf80f4bSopenharmony_ci glDeleteShader(entry.shader); 14278bf80f4bSopenharmony_ci entry.shader = 0U; 14288bf80f4bSopenharmony_ci } 14298bf80f4bSopenharmony_ci caches[type].cache.push_back(entry); 14308bf80f4bSopenharmony_ci return caches[type].cache.back(); 14318bf80f4bSopenharmony_ci} 14328bf80f4bSopenharmony_ci 14338bf80f4bSopenharmony_ciuint32_t DeviceGLES::CacheProgram( 14348bf80f4bSopenharmony_ci const string_view vertSource, const string_view fragSource, const string_view compSource) 14358bf80f4bSopenharmony_ci{ 14368bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(isActive_, "Device not active when building shaders"); 14378bf80f4bSopenharmony_ci // Hash and cache shader sources. 14388bf80f4bSopenharmony_ci const auto& vEntry = CacheShader(DeviceGLES::VERTEX_CACHE, vertSource); 14398bf80f4bSopenharmony_ci const auto& fEntry = CacheShader(DeviceGLES::FRAGMENT_CACHE, fragSource); 14408bf80f4bSopenharmony_ci const auto& cEntry = CacheShader(DeviceGLES::COMPUTE_CACHE, compSource); 14418bf80f4bSopenharmony_ci // Then check if we have the program already cached (ie. matching shaders linked) 14428bf80f4bSopenharmony_ci for (ProgramCache& t : programs_) { 14438bf80f4bSopenharmony_ci if ((t.hashVert != vEntry.hash) || (t.hashFrag != fEntry.hash) || (t.hashComp != cEntry.hash)) { 14448bf80f4bSopenharmony_ci continue; 14458bf80f4bSopenharmony_ci } 14468bf80f4bSopenharmony_ci pCacheHit_++; 14478bf80f4bSopenharmony_ci t.refCount++; 14488bf80f4bSopenharmony_ci return t.program; 14498bf80f4bSopenharmony_ci } 14508bf80f4bSopenharmony_ci // Create new program 14518bf80f4bSopenharmony_ci pCacheMiss_++; 14528bf80f4bSopenharmony_ci const GLuint program = glCreateProgram(); 14538bf80f4bSopenharmony_ci#if defined(CORE_USE_SEPARATE_SHADER_OBJECTS) && (CORE_USE_SEPARATE_SHADER_OBJECTS == 1) 14548bf80f4bSopenharmony_ci // enable separable programs. 14558bf80f4bSopenharmony_ci glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE); 14568bf80f4bSopenharmony_ci#endif 14578bf80f4bSopenharmony_ci // Attach and link 14588bf80f4bSopenharmony_ci if (vEntry.shader) { 14598bf80f4bSopenharmony_ci glAttachShader(program, vEntry.shader); 14608bf80f4bSopenharmony_ci } 14618bf80f4bSopenharmony_ci if (fEntry.shader) { 14628bf80f4bSopenharmony_ci glAttachShader(program, fEntry.shader); 14638bf80f4bSopenharmony_ci } 14648bf80f4bSopenharmony_ci if (cEntry.shader) { 14658bf80f4bSopenharmony_ci glAttachShader(program, cEntry.shader); 14668bf80f4bSopenharmony_ci } 14678bf80f4bSopenharmony_ci glLinkProgram(program); 14688bf80f4bSopenharmony_ci GLint result = GL_FALSE; 14698bf80f4bSopenharmony_ci glGetProgramiv(program, GL_LINK_STATUS, &result); 14708bf80f4bSopenharmony_ci if (result == GL_FALSE) { 14718bf80f4bSopenharmony_ci GLint logLength = 0; 14728bf80f4bSopenharmony_ci glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 14738bf80f4bSopenharmony_ci string messages; 14748bf80f4bSopenharmony_ci messages.resize(static_cast<size_t>(logLength)); 14758bf80f4bSopenharmony_ci glGetProgramInfoLog(program, logLength, 0, messages.data()); 14768bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1) 14778bf80f4bSopenharmony_ci PLUGIN_LOG_ONCE_E("gl_shader_linking_error_" + to_string(program), 14788bf80f4bSopenharmony_ci "RENDER_VALIDATION: Shader linking error: %s", messages.c_str()); 14798bf80f4bSopenharmony_ci#endif 14808bf80f4bSopenharmony_ci glDeleteProgram(program); 14818bf80f4bSopenharmony_ci return 0U; 14828bf80f4bSopenharmony_ci } 14838bf80f4bSopenharmony_ci // Add the program to cache 14848bf80f4bSopenharmony_ci programs_.push_back( 14858bf80f4bSopenharmony_ci { program, vEntry.shader, fEntry.shader, cEntry.shader, vEntry.hash, fEntry.hash, cEntry.hash, 1 }); 14868bf80f4bSopenharmony_ci return program; 14878bf80f4bSopenharmony_ci} 14888bf80f4bSopenharmony_ci 14898bf80f4bSopenharmony_civoid DeviceGLES::UseProgram(uint32_t program) 14908bf80f4bSopenharmony_ci{ 14918bf80f4bSopenharmony_ci if (boundProgram_ != program) { 14928bf80f4bSopenharmony_ci boundProgram_ = program; 14938bf80f4bSopenharmony_ci glUseProgram(static_cast<GLuint>(program)); 14948bf80f4bSopenharmony_ci } 14958bf80f4bSopenharmony_ci} 14968bf80f4bSopenharmony_ci 14978bf80f4bSopenharmony_civoid DeviceGLES::BindBuffer(uint32_t target, uint32_t buffer) 14988bf80f4bSopenharmony_ci{ 14998bf80f4bSopenharmony_ci const uint32_t targetId = GenericTargetToTargetId(target); 15008bf80f4bSopenharmony_ci auto& state = bufferBound_[targetId]; 15018bf80f4bSopenharmony_ci if ((!state.bound) || (state.buffer != buffer)) { 15028bf80f4bSopenharmony_ci state.bound = true; 15038bf80f4bSopenharmony_ci state.buffer = buffer; 15048bf80f4bSopenharmony_ci glBindBuffer(target, static_cast<GLuint>(buffer)); 15058bf80f4bSopenharmony_ci } 15068bf80f4bSopenharmony_ci} 15078bf80f4bSopenharmony_ci 15088bf80f4bSopenharmony_civoid DeviceGLES::BindBufferRange(uint32_t target, uint32_t binding, uint32_t buffer, uint64_t offset, uint64_t size) 15098bf80f4bSopenharmony_ci{ 15108bf80f4bSopenharmony_ci const uint32_t targetId = IndexedTargetToTargetId(target); 15118bf80f4bSopenharmony_ci auto& slot = boundBuffers_[targetId][binding]; 15128bf80f4bSopenharmony_ci 15138bf80f4bSopenharmony_ci if ((slot.cached == false) || (slot.buffer != buffer) || (slot.offset != offset) || (slot.size != size)) { 15148bf80f4bSopenharmony_ci slot.cached = true; 15158bf80f4bSopenharmony_ci slot.buffer = buffer; 15168bf80f4bSopenharmony_ci slot.offset = offset; 15178bf80f4bSopenharmony_ci slot.size = size; 15188bf80f4bSopenharmony_ci glBindBufferRange(target, binding, buffer, static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size)); 15198bf80f4bSopenharmony_ci // BindBufferRange sets the "generic" binding too. so make sure cache state is correct. 15208bf80f4bSopenharmony_ci const uint32_t targetId2 = GenericTargetToTargetId(target); 15218bf80f4bSopenharmony_ci auto& state = bufferBound_[targetId2]; 15228bf80f4bSopenharmony_ci state.bound = true; 15238bf80f4bSopenharmony_ci state.buffer = buffer; 15248bf80f4bSopenharmony_ci } 15258bf80f4bSopenharmony_ci // NOTE: we are not forcing the generic bind point here. use BindBuffer to set the generic one if needed! 15268bf80f4bSopenharmony_ci} 15278bf80f4bSopenharmony_ci 15288bf80f4bSopenharmony_civoid DeviceGLES::BindSampler(uint32_t textureUnit, uint32_t sampler) 15298bf80f4bSopenharmony_ci{ 15308bf80f4bSopenharmony_ci if ((sampler + 1) != boundSampler_[textureUnit]) { 15318bf80f4bSopenharmony_ci boundSampler_[textureUnit] = sampler + 1; 15328bf80f4bSopenharmony_ci glBindSampler(textureUnit, sampler); 15338bf80f4bSopenharmony_ci } 15348bf80f4bSopenharmony_ci} 15358bf80f4bSopenharmony_ci 15368bf80f4bSopenharmony_ciuint32_t DeviceGLES::BoundReadFrameBuffer() const 15378bf80f4bSopenharmony_ci{ 15388bf80f4bSopenharmony_ci return boundReadFbo_; 15398bf80f4bSopenharmony_ci} 15408bf80f4bSopenharmony_ci 15418bf80f4bSopenharmony_ciuint32_t DeviceGLES::BoundWriteFrameBuffer() const 15428bf80f4bSopenharmony_ci{ 15438bf80f4bSopenharmony_ci return boundWriteFbo_; 15448bf80f4bSopenharmony_ci} 15458bf80f4bSopenharmony_ci 15468bf80f4bSopenharmony_ciuint32_t DeviceGLES::BoundProgram() const 15478bf80f4bSopenharmony_ci{ 15488bf80f4bSopenharmony_ci return boundProgram_; 15498bf80f4bSopenharmony_ci} 15508bf80f4bSopenharmony_ci 15518bf80f4bSopenharmony_ciuint32_t DeviceGLES::BoundBuffer(uint32_t target) const 15528bf80f4bSopenharmony_ci{ 15538bf80f4bSopenharmony_ci const uint32_t targetId = GenericTargetToTargetId(target); 15548bf80f4bSopenharmony_ci if (targetId >= MAX_BUFFER_BIND_ID) { 15558bf80f4bSopenharmony_ci return 0; 15568bf80f4bSopenharmony_ci } 15578bf80f4bSopenharmony_ci const auto& slot = bufferBound_[targetId]; 15588bf80f4bSopenharmony_ci if (!slot.bound) { 15598bf80f4bSopenharmony_ci return 0; 15608bf80f4bSopenharmony_ci } 15618bf80f4bSopenharmony_ci return slot.buffer; 15628bf80f4bSopenharmony_ci} 15638bf80f4bSopenharmony_ci 15648bf80f4bSopenharmony_ciuint32_t DeviceGLES::BoundBuffer(uint32_t target, uint32_t binding) const 15658bf80f4bSopenharmony_ci{ 15668bf80f4bSopenharmony_ci const uint32_t targetId = IndexedTargetToTargetId(target); 15678bf80f4bSopenharmony_ci if (targetId >= MAX_BUFFER_BIND_ID || binding >= MAX_BINDING_VALUE) { 15688bf80f4bSopenharmony_ci return 0; 15698bf80f4bSopenharmony_ci } 15708bf80f4bSopenharmony_ci const auto& slot = boundBuffers_[targetId][binding]; 15718bf80f4bSopenharmony_ci if (!slot.cached) { 15728bf80f4bSopenharmony_ci return 0; 15738bf80f4bSopenharmony_ci } 15748bf80f4bSopenharmony_ci return slot.buffer; 15758bf80f4bSopenharmony_ci} 15768bf80f4bSopenharmony_ci 15778bf80f4bSopenharmony_ciuint32_t DeviceGLES::BoundSampler(uint32_t textureUnit) const 15788bf80f4bSopenharmony_ci{ 15798bf80f4bSopenharmony_ci if (textureUnit >= MAX_SAMPLERS) { 15808bf80f4bSopenharmony_ci return 0; 15818bf80f4bSopenharmony_ci } 15828bf80f4bSopenharmony_ci const uint32_t bound = boundSampler_[textureUnit]; 15838bf80f4bSopenharmony_ci return bound ? (bound - 1) : bound; 15848bf80f4bSopenharmony_ci} 15858bf80f4bSopenharmony_ci 15868bf80f4bSopenharmony_ciuint32_t DeviceGLES::BoundTexture(uint32_t textureUnit, uint32_t target) const 15878bf80f4bSopenharmony_ci{ 15888bf80f4bSopenharmony_ci const uint32_t targetId = TextureTargetToTargetId(target); 15898bf80f4bSopenharmony_ci if (textureUnit >= MAX_TEXTURE_UNITS || targetId >= MAX_TEXTURE_TARGET_ID) { 15908bf80f4bSopenharmony_ci return 0; 15918bf80f4bSopenharmony_ci } 15928bf80f4bSopenharmony_ci const uint32_t bound = boundTexture_[textureUnit][targetId]; 15938bf80f4bSopenharmony_ci if (bound == 0) { 15948bf80f4bSopenharmony_ci return 0; // bound 0 == nothing has been bound via cache yet. 15958bf80f4bSopenharmony_ci } 15968bf80f4bSopenharmony_ci return bound - 1; 15978bf80f4bSopenharmony_ci} 15988bf80f4bSopenharmony_ci 15998bf80f4bSopenharmony_civoid DeviceGLES::BindImageTexture( 16008bf80f4bSopenharmony_ci uint32_t unit, uint32_t texture, uint32_t level, bool layered, uint32_t layer, uint32_t access, uint32_t format) 16018bf80f4bSopenharmony_ci{ 16028bf80f4bSopenharmony_ci auto& image = boundImage_[unit]; 16038bf80f4bSopenharmony_ci if ((!image.bound) || (image.texture != texture) || (image.level != level) || (image.layered != layered) || 16048bf80f4bSopenharmony_ci (image.access != access) || (image.format != format)) { 16058bf80f4bSopenharmony_ci image.bound = true; 16068bf80f4bSopenharmony_ci image.texture = texture; 16078bf80f4bSopenharmony_ci image.level = level; 16088bf80f4bSopenharmony_ci image.layered = layered; 16098bf80f4bSopenharmony_ci image.access = access; 16108bf80f4bSopenharmony_ci image.format = format; 16118bf80f4bSopenharmony_ci glBindImageTexture(static_cast<GLuint>(unit), static_cast<GLuint>(texture), static_cast<GLint>(level), 16128bf80f4bSopenharmony_ci static_cast<GLboolean>(layered), static_cast<GLint>(layer), static_cast<GLenum>(access), 16138bf80f4bSopenharmony_ci static_cast<GLenum>(format)); 16148bf80f4bSopenharmony_ci } 16158bf80f4bSopenharmony_ci} 16168bf80f4bSopenharmony_ci 16178bf80f4bSopenharmony_civoid DeviceGLES::SetActiveTextureUnit(uint32_t textureUnit) 16188bf80f4bSopenharmony_ci{ 16198bf80f4bSopenharmony_ci if ((textureUnit + 1) != activeTextureUnit_) { 16208bf80f4bSopenharmony_ci activeTextureUnit_ = textureUnit + 1; 16218bf80f4bSopenharmony_ci glActiveTexture(GL_TEXTURE0 + textureUnit); 16228bf80f4bSopenharmony_ci } 16238bf80f4bSopenharmony_ci} 16248bf80f4bSopenharmony_ci 16258bf80f4bSopenharmony_civoid DeviceGLES::BindTexture(uint32_t textureUnit, uint32_t target, uint32_t texture) 16268bf80f4bSopenharmony_ci{ 16278bf80f4bSopenharmony_ci const uint32_t targetId = TextureTargetToTargetId(target); 16288bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 16298bf80f4bSopenharmony_ci if (target == GL_TEXTURE_EXTERNAL_OES) { 16308bf80f4bSopenharmony_ci // Work around for oes textures needing a bind to zero to update. 16318bf80f4bSopenharmony_ci SetActiveTextureUnit(textureUnit); 16328bf80f4bSopenharmony_ci glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); 16338bf80f4bSopenharmony_ci boundTexture_[textureUnit][targetId] = 0; 16348bf80f4bSopenharmony_ci // Force the default sampler for OES textures. 16358bf80f4bSopenharmony_ci BindSampler(textureUnit, 0); 16368bf80f4bSopenharmony_ci } 16378bf80f4bSopenharmony_ci#endif 16388bf80f4bSopenharmony_ci if ((texture + 1) != boundTexture_[textureUnit][targetId]) { 16398bf80f4bSopenharmony_ci SetActiveTextureUnit(textureUnit); 16408bf80f4bSopenharmony_ci boundTexture_[textureUnit][targetId] = texture + 1; 16418bf80f4bSopenharmony_ci // remap the cubemap layer ids... 16428bf80f4bSopenharmony_ci switch (target) { 16438bf80f4bSopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 16448bf80f4bSopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 16458bf80f4bSopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 16468bf80f4bSopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 16478bf80f4bSopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 16488bf80f4bSopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 16498bf80f4bSopenharmony_ci glBindTexture(GL_TEXTURE_CUBE_MAP, texture); 16508bf80f4bSopenharmony_ci break; 16518bf80f4bSopenharmony_ci default: 16528bf80f4bSopenharmony_ci glBindTexture(target, texture); 16538bf80f4bSopenharmony_ci break; 16548bf80f4bSopenharmony_ci } 16558bf80f4bSopenharmony_ci } 16568bf80f4bSopenharmony_ci} 16578bf80f4bSopenharmony_ci 16588bf80f4bSopenharmony_civoid DeviceGLES::TexSwizzle(uint32_t image, uint32_t target, const Math::UVec4& swizzle) 16598bf80f4bSopenharmony_ci{ 16608bf80f4bSopenharmony_ci // set only if not default.. 16618bf80f4bSopenharmony_ci if ((swizzle.x != GL_RED) || (swizzle.y != GL_GREEN) || (swizzle.z != GL_BLUE) || (swizzle.w != GL_ALPHA)) { 16628bf80f4bSopenharmony_ci SetActiveTextureUnit(TEMP_BIND_UNIT); 16638bf80f4bSopenharmony_ci BindTexture(TEMP_BIND_UNIT, target, image); 16648bf80f4bSopenharmony_ci glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_SWIZZLE_R, static_cast<GLint>(swizzle.x)); 16658bf80f4bSopenharmony_ci glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_SWIZZLE_G, static_cast<GLint>(swizzle.y)); 16668bf80f4bSopenharmony_ci glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_SWIZZLE_B, static_cast<GLint>(swizzle.z)); 16678bf80f4bSopenharmony_ci glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_SWIZZLE_A, static_cast<GLint>(swizzle.w)); 16688bf80f4bSopenharmony_ci } 16698bf80f4bSopenharmony_ci} 16708bf80f4bSopenharmony_ci 16718bf80f4bSopenharmony_civoid DeviceGLES::TexStorage2D( 16728bf80f4bSopenharmony_ci uint32_t image, uint32_t target, uint32_t levels, uint32_t internalformat, const Math::UVec2& extent) 16738bf80f4bSopenharmony_ci{ 16748bf80f4bSopenharmony_ci SetActiveTextureUnit(TEMP_BIND_UNIT); 16758bf80f4bSopenharmony_ci BindTexture(TEMP_BIND_UNIT, target, image); 16768bf80f4bSopenharmony_ci glTexStorage2D(static_cast<GLenum>(target), static_cast<GLsizei>(levels), static_cast<GLenum>(internalformat), 16778bf80f4bSopenharmony_ci static_cast<GLsizei>(extent.x), static_cast<GLsizei>(extent.y)); 16788bf80f4bSopenharmony_ci} 16798bf80f4bSopenharmony_ci 16808bf80f4bSopenharmony_civoid DeviceGLES::TexStorage2DMultisample(uint32_t image, uint32_t target, uint32_t samples, uint32_t internalformat, 16818bf80f4bSopenharmony_ci const Math::UVec2& extent, bool fixedsamplelocations) 16828bf80f4bSopenharmony_ci{ 16838bf80f4bSopenharmony_ci SetActiveTextureUnit(TEMP_BIND_UNIT); 16848bf80f4bSopenharmony_ci BindTexture(TEMP_BIND_UNIT, target, image); 16858bf80f4bSopenharmony_ci glTexStorage2DMultisample(static_cast<GLenum>(target), static_cast<GLsizei>(samples), 16868bf80f4bSopenharmony_ci static_cast<GLenum>(internalformat), static_cast<GLsizei>(extent.x), static_cast<GLsizei>(extent.y), 16878bf80f4bSopenharmony_ci fixedsamplelocations); 16888bf80f4bSopenharmony_ci} 16898bf80f4bSopenharmony_ci 16908bf80f4bSopenharmony_civoid DeviceGLES::TexStorage3D( 16918bf80f4bSopenharmony_ci uint32_t image, uint32_t target, uint32_t levels, uint32_t internalformat, const Math::UVec3& extent) 16928bf80f4bSopenharmony_ci{ 16938bf80f4bSopenharmony_ci SetActiveTextureUnit(TEMP_BIND_UNIT); 16948bf80f4bSopenharmony_ci BindTexture(TEMP_BIND_UNIT, target, image); 16958bf80f4bSopenharmony_ci glTexStorage3D((GLenum)target, (GLsizei)levels, (GLenum)internalformat, (GLsizei)extent.x, (GLsizei)extent.y, 16968bf80f4bSopenharmony_ci (GLsizei)extent.z); 16978bf80f4bSopenharmony_ci} 16988bf80f4bSopenharmony_ci 16998bf80f4bSopenharmony_civoid DeviceGLES::TexSubImage2D(uint32_t image, uint32_t target, uint32_t level, const Math::UVec2& offset, 17008bf80f4bSopenharmony_ci const Math::UVec2& extent, uint32_t format, uint32_t type, const void* pixels) 17018bf80f4bSopenharmony_ci{ 17028bf80f4bSopenharmony_ci SetActiveTextureUnit(TEMP_BIND_UNIT); 17038bf80f4bSopenharmony_ci BindTexture(TEMP_BIND_UNIT, target, image); 17048bf80f4bSopenharmony_ci glTexSubImage2D((GLenum)target, (GLint)level, (GLint)offset.x, (GLint)offset.y, (GLsizei)extent.x, 17058bf80f4bSopenharmony_ci (GLsizei)extent.y, (GLenum)format, (GLenum)type, pixels); 17068bf80f4bSopenharmony_ci} 17078bf80f4bSopenharmony_ci 17088bf80f4bSopenharmony_civoid DeviceGLES::TexSubImage3D(uint32_t image, uint32_t target, uint32_t level, const Math::UVec3& offset, 17098bf80f4bSopenharmony_ci const Math::UVec3& extent, uint32_t format, uint32_t type, const void* pixels) 17108bf80f4bSopenharmony_ci{ 17118bf80f4bSopenharmony_ci SetActiveTextureUnit(TEMP_BIND_UNIT); 17128bf80f4bSopenharmony_ci BindTexture(TEMP_BIND_UNIT, target, image); 17138bf80f4bSopenharmony_ci glTexSubImage3D((GLenum)target, (GLint)level, (GLint)offset.x, (GLint)offset.y, (GLint)offset.z, (GLsizei)extent.x, 17148bf80f4bSopenharmony_ci (GLsizei)extent.y, (GLsizei)extent.z, (GLenum)format, (GLenum)type, pixels); 17158bf80f4bSopenharmony_ci} 17168bf80f4bSopenharmony_ci 17178bf80f4bSopenharmony_civoid DeviceGLES::CompressedTexSubImage2D(uint32_t image, uint32_t target, uint32_t level, const Math::UVec2& offset, 17188bf80f4bSopenharmony_ci const Math::UVec2& extent, uint32_t format, uint32_t imageSize, const void* data) 17198bf80f4bSopenharmony_ci{ 17208bf80f4bSopenharmony_ci SetActiveTextureUnit(TEMP_BIND_UNIT); 17218bf80f4bSopenharmony_ci BindTexture(TEMP_BIND_UNIT, target, image); 17228bf80f4bSopenharmony_ci glCompressedTexSubImage2D((GLenum)target, (GLint)level, (GLint)offset.x, (GLint)offset.y, (GLsizei)extent.x, 17238bf80f4bSopenharmony_ci (GLsizei)extent.y, (GLenum)format, (GLint)imageSize, data); 17248bf80f4bSopenharmony_ci} 17258bf80f4bSopenharmony_ci 17268bf80f4bSopenharmony_civoid DeviceGLES::CompressedTexSubImage3D(uint32_t image, uint32_t target, uint32_t level, const Math::UVec3& offset, 17278bf80f4bSopenharmony_ci const Math::UVec3& extent, uint32_t format, uint32_t imageSize, const void* data) 17288bf80f4bSopenharmony_ci{ 17298bf80f4bSopenharmony_ci SetActiveTextureUnit(TEMP_BIND_UNIT); 17308bf80f4bSopenharmony_ci BindTexture(TEMP_BIND_UNIT, target, image); 17318bf80f4bSopenharmony_ci glCompressedTexSubImage3D((GLenum)target, (GLint)level, (GLint)offset.x, (GLint)offset.y, (GLint)offset.z, 17328bf80f4bSopenharmony_ci (GLsizei)extent.x, (GLsizei)extent.y, (GLsizei)extent.z, (GLenum)format, (GLint)imageSize, data); 17338bf80f4bSopenharmony_ci} 17348bf80f4bSopenharmony_ci 17358bf80f4bSopenharmony_ciconst DeviceGLES::ImageFormat& DeviceGLES::GetGlImageFormat(const Format format) const 17368bf80f4bSopenharmony_ci{ 17378bf80f4bSopenharmony_ci if (const auto pos = std::lower_bound(supportedFormats_.begin(), supportedFormats_.end(), format, 17388bf80f4bSopenharmony_ci [](const ImageFormat& element, const Format value) { return element.coreFormat < value; }); 17398bf80f4bSopenharmony_ci (pos != supportedFormats_.end()) && (pos->coreFormat == format)) { 17408bf80f4bSopenharmony_ci return *pos; 17418bf80f4bSopenharmony_ci } 17428bf80f4bSopenharmony_ci if (const auto pos = std::lower_bound(std::begin(IMAGE_FORMATS_FALLBACK), std::end(IMAGE_FORMATS_FALLBACK), format, 17438bf80f4bSopenharmony_ci [](const ImageFormat& element, const Format value) { return element.coreFormat < value; }); 17448bf80f4bSopenharmony_ci (pos != std::end(IMAGE_FORMATS_FALLBACK)) && (pos->coreFormat == format)) { 17458bf80f4bSopenharmony_ci PLUGIN_LOG_I("using fallback for format %u", format); 17468bf80f4bSopenharmony_ci return *pos; 17478bf80f4bSopenharmony_ci } 17488bf80f4bSopenharmony_ci PLUGIN_LOG_I("asking for unsupported format %u", format); 17498bf80f4bSopenharmony_ci return supportedFormats_[0]; 17508bf80f4bSopenharmony_ci} 17518bf80f4bSopenharmony_ci 17528bf80f4bSopenharmony_civoid DeviceGLES::DeleteTexture(uint32_t texture) 17538bf80f4bSopenharmony_ci{ 17548bf80f4bSopenharmony_ci UnBindTexture(texture); 17558bf80f4bSopenharmony_ci glDeleteTextures(1, &texture); 17568bf80f4bSopenharmony_ci} 17578bf80f4bSopenharmony_ci 17588bf80f4bSopenharmony_civoid DeviceGLES::DeleteBuffer(uint32_t buffer) 17598bf80f4bSopenharmony_ci{ 17608bf80f4bSopenharmony_ci UnBindBuffer(buffer); 17618bf80f4bSopenharmony_ci glDeleteBuffers(1, &buffer); 17628bf80f4bSopenharmony_ci} 17638bf80f4bSopenharmony_ci 17648bf80f4bSopenharmony_civoid DeviceGLES::DeleteSampler(uint32_t sampler) 17658bf80f4bSopenharmony_ci{ 17668bf80f4bSopenharmony_ci UnBindSampler(sampler); 17678bf80f4bSopenharmony_ci glDeleteSamplers(1, &sampler); 17688bf80f4bSopenharmony_ci} 17698bf80f4bSopenharmony_ci 17708bf80f4bSopenharmony_ciuint32_t DeviceGLES::CreateVertexArray() 17718bf80f4bSopenharmony_ci{ 17728bf80f4bSopenharmony_ci GLuint vao; 17738bf80f4bSopenharmony_ci glGenVertexArrays(1, &vao); 17748bf80f4bSopenharmony_ci if (vaoStatesInUse_ == vaoStates_.size()) { 17758bf80f4bSopenharmony_ci for (auto it = vaoStates_.begin(); it != vaoStates_.end(); it++) { 17768bf80f4bSopenharmony_ci if (it->vao == 0) { 17778bf80f4bSopenharmony_ci // re-use old "object" 17788bf80f4bSopenharmony_ci it->vao = vao; 17798bf80f4bSopenharmony_ci vaoStatesInUse_++; 17808bf80f4bSopenharmony_ci return static_cast<uint32_t>(1 + (it - vaoStates_.begin())); 17818bf80f4bSopenharmony_ci } 17828bf80f4bSopenharmony_ci } 17838bf80f4bSopenharmony_ci } 17848bf80f4bSopenharmony_ci VAOState v; 17858bf80f4bSopenharmony_ci v.vao = vao; 17868bf80f4bSopenharmony_ci vaoStates_.push_back(v); 17878bf80f4bSopenharmony_ci vaoStatesInUse_++; 17888bf80f4bSopenharmony_ci return static_cast<uint32_t>(vaoStates_.size()); 17898bf80f4bSopenharmony_ci} 17908bf80f4bSopenharmony_ci 17918bf80f4bSopenharmony_civoid DeviceGLES::DeleteVertexArray(uint32_t vao) 17928bf80f4bSopenharmony_ci{ 17938bf80f4bSopenharmony_ci PLUGIN_ASSERT(!vaoStates_.empty()); 17948bf80f4bSopenharmony_ci if (vao > 0) { 17958bf80f4bSopenharmony_ci UnBindVertexArray(vao); 17968bf80f4bSopenharmony_ci auto& state = vaoStates_[vao - 1]; 17978bf80f4bSopenharmony_ci glDeleteVertexArrays(1, &state.vao); 17988bf80f4bSopenharmony_ci state = {}; // clear the object. 17998bf80f4bSopenharmony_ci vaoStatesInUse_--; 18008bf80f4bSopenharmony_ci } 18018bf80f4bSopenharmony_ci} 18028bf80f4bSopenharmony_ci 18038bf80f4bSopenharmony_civoid DeviceGLES::DeleteFrameBuffer(uint32_t fbo) 18048bf80f4bSopenharmony_ci{ 18058bf80f4bSopenharmony_ci PLUGIN_ASSERT(IsActive()); 18068bf80f4bSopenharmony_ci UnBindFrameBuffer(fbo); 18078bf80f4bSopenharmony_ci glDeleteFramebuffers(1, &fbo); 18088bf80f4bSopenharmony_ci#if (RENDER_DEBUG_GPU_RESOURCE_IDS == 1) 18098bf80f4bSopenharmony_ci PLUGIN_LOG_D("fbo id <: %u", fbo); 18108bf80f4bSopenharmony_ci#endif 18118bf80f4bSopenharmony_ci} 18128bf80f4bSopenharmony_ci 18138bf80f4bSopenharmony_civoid DeviceGLES::UnBindTexture(uint32_t texture) 18148bf80f4bSopenharmony_ci{ 18158bf80f4bSopenharmony_ci uint32_t unit = 0; 18168bf80f4bSopenharmony_ci for (auto& textureUnit : boundTexture_) { 18178bf80f4bSopenharmony_ci uint32_t targetId = 0; 18188bf80f4bSopenharmony_ci for (uint32_t& typeBinding : textureUnit) { 18198bf80f4bSopenharmony_ci if (typeBinding == texture + 1) { 18208bf80f4bSopenharmony_ci SetActiveTextureUnit(unit); 18218bf80f4bSopenharmony_ci const uint32_t target = TextureTargetIdToTarget(TextureTargetId { targetId }); 18228bf80f4bSopenharmony_ci glBindTexture(target, 0); 18238bf80f4bSopenharmony_ci typeBinding = 0; 18248bf80f4bSopenharmony_ci } 18258bf80f4bSopenharmony_ci targetId++; 18268bf80f4bSopenharmony_ci } 18278bf80f4bSopenharmony_ci unit++; 18288bf80f4bSopenharmony_ci } 18298bf80f4bSopenharmony_ci 18308bf80f4bSopenharmony_ci unit = 0; 18318bf80f4bSopenharmony_ci for (auto& image : boundImage_) { 18328bf80f4bSopenharmony_ci if ((image.bound) && (image.texture == texture)) { 18338bf80f4bSopenharmony_ci glBindImageTexture(static_cast<GLuint>(unit), 0, 0, false, 0, GL_READ_ONLY, GL_R32UI); 18348bf80f4bSopenharmony_ci // set default state... 18358bf80f4bSopenharmony_ci image.bound = false; 18368bf80f4bSopenharmony_ci image.texture = 0; 18378bf80f4bSopenharmony_ci image.level = 0; 18388bf80f4bSopenharmony_ci image.layered = false; 18398bf80f4bSopenharmony_ci image.access = GL_READ_ONLY; 18408bf80f4bSopenharmony_ci image.format = GL_R32UI; 18418bf80f4bSopenharmony_ci } 18428bf80f4bSopenharmony_ci unit++; 18438bf80f4bSopenharmony_ci } 18448bf80f4bSopenharmony_ci} 18458bf80f4bSopenharmony_ci 18468bf80f4bSopenharmony_civoid DeviceGLES::UnBindBuffer(uint32_t buffer) 18478bf80f4bSopenharmony_ci{ 18488bf80f4bSopenharmony_ci uint32_t tid = 0; 18498bf80f4bSopenharmony_ci for (auto& buffers : boundBuffers_) { 18508bf80f4bSopenharmony_ci const uint32_t targetId = IndexedTargetIdToTarget(BufferBindId { tid }); 18518bf80f4bSopenharmony_ci uint32_t bid = 0; 18528bf80f4bSopenharmony_ci for (auto& slot : buffers) { 18538bf80f4bSopenharmony_ci if (slot.buffer == buffer) { 18548bf80f4bSopenharmony_ci glBindBufferRange(targetId, bid, 0, 0, 0); 18558bf80f4bSopenharmony_ci // nothing bound 18568bf80f4bSopenharmony_ci slot.cached = false; 18578bf80f4bSopenharmony_ci slot.buffer = 0; 18588bf80f4bSopenharmony_ci slot.offset = 0; 18598bf80f4bSopenharmony_ci slot.size = 0; 18608bf80f4bSopenharmony_ci } 18618bf80f4bSopenharmony_ci bid++; 18628bf80f4bSopenharmony_ci } 18638bf80f4bSopenharmony_ci tid++; 18648bf80f4bSopenharmony_ci } 18658bf80f4bSopenharmony_ci 18668bf80f4bSopenharmony_ci tid = 0; 18678bf80f4bSopenharmony_ci for (auto& slot : bufferBound_) { 18688bf80f4bSopenharmony_ci if (slot.buffer == buffer) { 18698bf80f4bSopenharmony_ci const uint32_t targetId = GenericTargetIdToTarget(BufferTargetId { tid }); 18708bf80f4bSopenharmony_ci glBindBuffer(targetId, 0); 18718bf80f4bSopenharmony_ci // nothing bound 18728bf80f4bSopenharmony_ci slot.bound = false; 18738bf80f4bSopenharmony_ci slot.buffer = 0; 18748bf80f4bSopenharmony_ci } 18758bf80f4bSopenharmony_ci tid++; 18768bf80f4bSopenharmony_ci } 18778bf80f4bSopenharmony_ci 18788bf80f4bSopenharmony_ci // scan VAOs also.. 18798bf80f4bSopenharmony_ci UnBindBufferFromVertexArray(buffer); 18808bf80f4bSopenharmony_ci} 18818bf80f4bSopenharmony_ci 18828bf80f4bSopenharmony_civoid DeviceGLES::UnBindBufferFromVertexArray(uint32_t buffer) 18838bf80f4bSopenharmony_ci{ 18848bf80f4bSopenharmony_ci uint32_t vao = 1; 18858bf80f4bSopenharmony_ci uint32_t wasbound = BoundVertexArray(); 18868bf80f4bSopenharmony_ci for (auto& state : vaoStates_) { 18878bf80f4bSopenharmony_ci if (state.vao > 0) { 18888bf80f4bSopenharmony_ci auto& elementBuffer = state.elementBuffer; 18898bf80f4bSopenharmony_ci auto& vertexBufferBinds = state.vertexBufferBinds; 18908bf80f4bSopenharmony_ci int slot = 0; 18918bf80f4bSopenharmony_ci for (auto& t : vertexBufferBinds) { 18928bf80f4bSopenharmony_ci if ((t.bound) && (t.buffer == buffer)) { 18938bf80f4bSopenharmony_ci // detach the buffer from vao. 18948bf80f4bSopenharmony_ci BindVertexArray(vao); 18958bf80f4bSopenharmony_ci glBindVertexBuffer((GLuint)slot, 0, 0, 0); 18968bf80f4bSopenharmony_ci t.bound = false; 18978bf80f4bSopenharmony_ci t.buffer = 0; 18988bf80f4bSopenharmony_ci t.offset = 0; 18998bf80f4bSopenharmony_ci t.stride = 0; 19008bf80f4bSopenharmony_ci } 19018bf80f4bSopenharmony_ci slot++; 19028bf80f4bSopenharmony_ci } 19038bf80f4bSopenharmony_ci if ((elementBuffer.bound) && (elementBuffer.buffer == buffer)) { 19048bf80f4bSopenharmony_ci // detach the buffer from vao. 19058bf80f4bSopenharmony_ci BindVertexArray(vao); 19068bf80f4bSopenharmony_ci glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 19078bf80f4bSopenharmony_ci elementBuffer.bound = false; 19088bf80f4bSopenharmony_ci elementBuffer.buffer = 0; 19098bf80f4bSopenharmony_ci } 19108bf80f4bSopenharmony_ci } 19118bf80f4bSopenharmony_ci vao++; 19128bf80f4bSopenharmony_ci } 19138bf80f4bSopenharmony_ci BindVertexArray(wasbound); 19148bf80f4bSopenharmony_ci} 19158bf80f4bSopenharmony_ci 19168bf80f4bSopenharmony_civoid DeviceGLES::UnBindSampler(uint32_t sampler) 19178bf80f4bSopenharmony_ci{ 19188bf80f4bSopenharmony_ci for (uint32_t& boundSampler : boundSampler_) { 19198bf80f4bSopenharmony_ci if ((sampler + 1) == boundSampler) { 19208bf80f4bSopenharmony_ci glBindSampler((sampler + 1), 0); 19218bf80f4bSopenharmony_ci boundSampler = 0; 19228bf80f4bSopenharmony_ci } 19238bf80f4bSopenharmony_ci } 19248bf80f4bSopenharmony_ci} 19258bf80f4bSopenharmony_ci 19268bf80f4bSopenharmony_civoid DeviceGLES::UnBindVertexArray(uint32_t vao) 19278bf80f4bSopenharmony_ci{ 19288bf80f4bSopenharmony_ci if (boundVao_ == vao) { 19298bf80f4bSopenharmony_ci glBindVertexArray(0); 19308bf80f4bSopenharmony_ci boundVao_ = 0; 19318bf80f4bSopenharmony_ci } 19328bf80f4bSopenharmony_ci} 19338bf80f4bSopenharmony_ci 19348bf80f4bSopenharmony_civoid DeviceGLES::UnBindFrameBuffer(uint32_t fbo) 19358bf80f4bSopenharmony_ci{ 19368bf80f4bSopenharmony_ci if ((fbo == boundReadFbo_) && (fbo == boundWriteFbo_)) { 19378bf80f4bSopenharmony_ci boundReadFbo_ = 0; 19388bf80f4bSopenharmony_ci boundWriteFbo_ = 0; 19398bf80f4bSopenharmony_ci glBindFramebuffer(GL_FRAMEBUFFER, 0); 19408bf80f4bSopenharmony_ci } else if (boundWriteFbo_ == fbo) { 19418bf80f4bSopenharmony_ci boundWriteFbo_ = 0; 19428bf80f4bSopenharmony_ci glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 19438bf80f4bSopenharmony_ci } else if (boundReadFbo_ == fbo) { 19448bf80f4bSopenharmony_ci boundReadFbo_ = 0; 19458bf80f4bSopenharmony_ci glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); 19468bf80f4bSopenharmony_ci } 19478bf80f4bSopenharmony_ci} 19488bf80f4bSopenharmony_ci 19498bf80f4bSopenharmony_ciuint32_t DeviceGLES::BoundVertexArray() const 19508bf80f4bSopenharmony_ci{ 19518bf80f4bSopenharmony_ci return boundVao_; 19528bf80f4bSopenharmony_ci} 19538bf80f4bSopenharmony_ci 19548bf80f4bSopenharmony_civoid DeviceGLES::BindFrameBuffer(uint32_t fbo) 19558bf80f4bSopenharmony_ci{ 19568bf80f4bSopenharmony_ci if ((boundReadFbo_ != fbo) && (boundWriteFbo_ != fbo)) { 19578bf80f4bSopenharmony_ci glBindFramebuffer(GL_FRAMEBUFFER, fbo); 19588bf80f4bSopenharmony_ci boundReadFbo_ = boundWriteFbo_ = fbo; 19598bf80f4bSopenharmony_ci } else if (boundWriteFbo_ != fbo) { 19608bf80f4bSopenharmony_ci glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); 19618bf80f4bSopenharmony_ci boundWriteFbo_ = fbo; 19628bf80f4bSopenharmony_ci } else if (boundReadFbo_ != fbo) { 19638bf80f4bSopenharmony_ci glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); 19648bf80f4bSopenharmony_ci boundReadFbo_ = fbo; 19658bf80f4bSopenharmony_ci } 19668bf80f4bSopenharmony_ci} 19678bf80f4bSopenharmony_ci 19688bf80f4bSopenharmony_civoid DeviceGLES::BindReadFrameBuffer(uint32_t fbo) 19698bf80f4bSopenharmony_ci{ 19708bf80f4bSopenharmony_ci if (boundReadFbo_ != fbo) { 19718bf80f4bSopenharmony_ci glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); 19728bf80f4bSopenharmony_ci boundReadFbo_ = fbo; 19738bf80f4bSopenharmony_ci } 19748bf80f4bSopenharmony_ci} 19758bf80f4bSopenharmony_ci 19768bf80f4bSopenharmony_civoid DeviceGLES::BindWriteFrameBuffer(uint32_t fbo) 19778bf80f4bSopenharmony_ci{ 19788bf80f4bSopenharmony_ci if (boundWriteFbo_ != fbo) { 19798bf80f4bSopenharmony_ci glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); 19808bf80f4bSopenharmony_ci boundWriteFbo_ = fbo; 19818bf80f4bSopenharmony_ci } 19828bf80f4bSopenharmony_ci} 19838bf80f4bSopenharmony_ci 19848bf80f4bSopenharmony_civoid DeviceGLES::BindVertexArray(uint32_t vao) 19858bf80f4bSopenharmony_ci{ 19868bf80f4bSopenharmony_ci if (boundVao_ != vao) { 19878bf80f4bSopenharmony_ci PLUGIN_ASSERT(vao <= vaoStates_.size()); 19888bf80f4bSopenharmony_ci if (vao > 0) { 19898bf80f4bSopenharmony_ci glBindVertexArray(vaoStates_[vao - 1].vao); 19908bf80f4bSopenharmony_ci } else { 19918bf80f4bSopenharmony_ci glBindVertexArray(0); 19928bf80f4bSopenharmony_ci } 19938bf80f4bSopenharmony_ci boundVao_ = vao; 19948bf80f4bSopenharmony_ci } 19958bf80f4bSopenharmony_ci} 19968bf80f4bSopenharmony_ci 19978bf80f4bSopenharmony_civoid DeviceGLES::BindVertexBuffer(uint32_t slot, uint32_t buffer, intptr_t offset, intptr_t stride) 19988bf80f4bSopenharmony_ci{ 19998bf80f4bSopenharmony_ci PLUGIN_ASSERT(boundVao_ > 0); 20008bf80f4bSopenharmony_ci PLUGIN_ASSERT(boundVao_ <= vaoStates_.size()); 20018bf80f4bSopenharmony_ci auto& vertexBufferBinds = vaoStates_[boundVao_ - 1].vertexBufferBinds; 20028bf80f4bSopenharmony_ci bool bind = true; 20038bf80f4bSopenharmony_ci if (vertexBufferBinds[slot].bound) { 20048bf80f4bSopenharmony_ci bind = (vertexBufferBinds[slot].buffer != buffer) || (vertexBufferBinds[slot].offset != offset) || 20058bf80f4bSopenharmony_ci (vertexBufferBinds[slot].stride != stride); 20068bf80f4bSopenharmony_ci } 20078bf80f4bSopenharmony_ci if (bind) { 20088bf80f4bSopenharmony_ci vertexBufferBinds[slot].bound = true; 20098bf80f4bSopenharmony_ci vertexBufferBinds[slot].buffer = buffer; 20108bf80f4bSopenharmony_ci vertexBufferBinds[slot].offset = offset; 20118bf80f4bSopenharmony_ci vertexBufferBinds[slot].stride = stride; 20128bf80f4bSopenharmony_ci glBindVertexBuffer((GLuint)slot, (GLuint)buffer, (GLintptr)offset, (GLsizei)stride); 20138bf80f4bSopenharmony_ci } 20148bf80f4bSopenharmony_ci} 20158bf80f4bSopenharmony_ci 20168bf80f4bSopenharmony_civoid DeviceGLES::VertexBindingDivisor(uint32_t slot, uint32_t divisor) 20178bf80f4bSopenharmony_ci{ 20188bf80f4bSopenharmony_ci PLUGIN_ASSERT(boundVao_ > 0); 20198bf80f4bSopenharmony_ci PLUGIN_ASSERT(boundVao_ <= vaoStates_.size()); 20208bf80f4bSopenharmony_ci auto& vertexBufferBinds = vaoStates_[boundVao_ - 1].vertexBufferBinds; 20218bf80f4bSopenharmony_ci if (vertexBufferBinds[slot].divisor != divisor) { 20228bf80f4bSopenharmony_ci vertexBufferBinds[slot].divisor = divisor; 20238bf80f4bSopenharmony_ci glVertexBindingDivisor(slot, divisor); 20248bf80f4bSopenharmony_ci } 20258bf80f4bSopenharmony_ci} 20268bf80f4bSopenharmony_ci 20278bf80f4bSopenharmony_civoid DeviceGLES::BindElementBuffer(uint32_t buffer) 20288bf80f4bSopenharmony_ci{ 20298bf80f4bSopenharmony_ci PLUGIN_ASSERT(boundVao_ > 0); 20308bf80f4bSopenharmony_ci PLUGIN_ASSERT(boundVao_ <= vaoStates_.size()); 20318bf80f4bSopenharmony_ci auto& elementBuffer = vaoStates_[boundVao_ - 1].elementBuffer; 20328bf80f4bSopenharmony_ci bool bind = true; 20338bf80f4bSopenharmony_ci if (elementBuffer.bound) { 20348bf80f4bSopenharmony_ci bind = (buffer != elementBuffer.buffer); 20358bf80f4bSopenharmony_ci } 20368bf80f4bSopenharmony_ci if (bind) { 20378bf80f4bSopenharmony_ci elementBuffer.bound = true; 20388bf80f4bSopenharmony_ci elementBuffer.buffer = buffer; 20398bf80f4bSopenharmony_ci glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); 20408bf80f4bSopenharmony_ci } 20418bf80f4bSopenharmony_ci} 20428bf80f4bSopenharmony_ci 20438bf80f4bSopenharmony_cibool DeviceGLES::AllowThreadedProcessing() const 20448bf80f4bSopenharmony_ci{ 20458bf80f4bSopenharmony_ci return HasExtension(EXT_BUFFER_STORAGE); 20468bf80f4bSopenharmony_ci} 20478bf80f4bSopenharmony_ci 20488bf80f4bSopenharmony_ciunique_ptr<GpuBuffer> DeviceGLES::CreateGpuBuffer(const GpuBufferDesc& desc) 20498bf80f4bSopenharmony_ci{ 20508bf80f4bSopenharmony_ci return make_unique<GpuBufferGLES>(*this, desc); 20518bf80f4bSopenharmony_ci} 20528bf80f4bSopenharmony_ci 20538bf80f4bSopenharmony_ciunique_ptr<GpuBuffer> DeviceGLES::CreateGpuBuffer(const GpuAccelerationStructureDesc& desc) 20548bf80f4bSopenharmony_ci{ 20558bf80f4bSopenharmony_ci return make_unique<GpuBufferGLES>(*this, desc.bufferDesc); 20568bf80f4bSopenharmony_ci} 20578bf80f4bSopenharmony_ci 20588bf80f4bSopenharmony_ciunique_ptr<GpuImage> DeviceGLES::CreateGpuImage(const GpuImageDesc& desc) 20598bf80f4bSopenharmony_ci{ 20608bf80f4bSopenharmony_ci return make_unique<GpuImageGLES>(*this, desc); 20618bf80f4bSopenharmony_ci} 20628bf80f4bSopenharmony_ci 20638bf80f4bSopenharmony_ciunique_ptr<GpuImage> DeviceGLES::CreateGpuImageView(const GpuImageDesc& desc, const GpuImagePlatformData& platformData) 20648bf80f4bSopenharmony_ci{ 20658bf80f4bSopenharmony_ci PLUGIN_ASSERT(IsActive()); 20668bf80f4bSopenharmony_ci return make_unique<GpuImageGLES>(*this, desc, platformData); 20678bf80f4bSopenharmony_ci} 20688bf80f4bSopenharmony_ci 20698bf80f4bSopenharmony_civector<unique_ptr<GpuImage>> DeviceGLES::CreateGpuImageViews(const Swapchain& platformSwapchain) 20708bf80f4bSopenharmony_ci{ 20718bf80f4bSopenharmony_ci vector<unique_ptr<GpuImage>> gpuImages; 20728bf80f4bSopenharmony_ci const SwapchainGLES& swapchain = (const SwapchainGLES&)platformSwapchain; 20738bf80f4bSopenharmony_ci const GpuImageDesc& desc = swapchain.GetDesc(); 20748bf80f4bSopenharmony_ci const auto& swapchainPlat = swapchain.GetPlatformData(); 20758bf80f4bSopenharmony_ci 20768bf80f4bSopenharmony_ci gpuImages.resize(swapchainPlat.swapchainImages.images.size()); 20778bf80f4bSopenharmony_ci 20788bf80f4bSopenharmony_ci PLUGIN_ASSERT(IsActive()); 20798bf80f4bSopenharmony_ci for (size_t idx = 0; idx < gpuImages.size(); ++idx) { 20808bf80f4bSopenharmony_ci GpuImagePlatformDataGL gpuImagePlat {}; 20818bf80f4bSopenharmony_ci gpuImagePlat.image = swapchainPlat.swapchainImages.images[idx]; 20828bf80f4bSopenharmony_ci gpuImagePlat.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; 20838bf80f4bSopenharmony_ci gpuImages[idx] = CreateGpuImageView(desc, gpuImagePlat); 20848bf80f4bSopenharmony_ci } 20858bf80f4bSopenharmony_ci return gpuImages; 20868bf80f4bSopenharmony_ci} 20878bf80f4bSopenharmony_ci 20888bf80f4bSopenharmony_ciunique_ptr<GpuSampler> DeviceGLES::CreateGpuSampler(const GpuSamplerDesc& desc) 20898bf80f4bSopenharmony_ci{ 20908bf80f4bSopenharmony_ci return make_unique<GpuSamplerGLES>(*this, desc); 20918bf80f4bSopenharmony_ci} 20928bf80f4bSopenharmony_ci 20938bf80f4bSopenharmony_ciunique_ptr<RenderFrameSync> DeviceGLES::CreateRenderFrameSync() 20948bf80f4bSopenharmony_ci{ 20958bf80f4bSopenharmony_ci return make_unique<RenderFrameSyncGLES>(*this); 20968bf80f4bSopenharmony_ci} 20978bf80f4bSopenharmony_ci 20988bf80f4bSopenharmony_ciunique_ptr<RenderBackend> DeviceGLES::CreateRenderBackend( 20998bf80f4bSopenharmony_ci GpuResourceManager& gpuResourceMgr, const CORE_NS::IParallelTaskQueue::Ptr&) 21008bf80f4bSopenharmony_ci{ 21018bf80f4bSopenharmony_ci return make_unique<RenderBackendGLES>(*this, gpuResourceMgr); 21028bf80f4bSopenharmony_ci} 21038bf80f4bSopenharmony_ci 21048bf80f4bSopenharmony_ciunique_ptr<ShaderModule> DeviceGLES::CreateShaderModule(const ShaderModuleCreateInfo& data) 21058bf80f4bSopenharmony_ci{ 21068bf80f4bSopenharmony_ci return make_unique<ShaderModuleGLES>(*this, data); 21078bf80f4bSopenharmony_ci} 21088bf80f4bSopenharmony_ci 21098bf80f4bSopenharmony_ciunique_ptr<ShaderModule> DeviceGLES::CreateComputeShaderModule(const ShaderModuleCreateInfo& data) 21108bf80f4bSopenharmony_ci{ 21118bf80f4bSopenharmony_ci return make_unique<ShaderModuleGLES>(*this, data); 21128bf80f4bSopenharmony_ci} 21138bf80f4bSopenharmony_ci 21148bf80f4bSopenharmony_ciunique_ptr<GpuShaderProgram> DeviceGLES::CreateGpuShaderProgram(const GpuShaderProgramCreateData& data) 21158bf80f4bSopenharmony_ci{ 21168bf80f4bSopenharmony_ci return make_unique<GpuShaderProgramGLES>(*this, data); 21178bf80f4bSopenharmony_ci} 21188bf80f4bSopenharmony_ci 21198bf80f4bSopenharmony_ciunique_ptr<GpuComputeProgram> DeviceGLES::CreateGpuComputeProgram(const GpuComputeProgramCreateData& data) 21208bf80f4bSopenharmony_ci{ 21218bf80f4bSopenharmony_ci return make_unique<GpuComputeProgramGLES>(*this, data); 21228bf80f4bSopenharmony_ci} 21238bf80f4bSopenharmony_ci 21248bf80f4bSopenharmony_ciunique_ptr<NodeContextDescriptorSetManager> DeviceGLES::CreateNodeContextDescriptorSetManager() 21258bf80f4bSopenharmony_ci{ 21268bf80f4bSopenharmony_ci return make_unique<NodeContextDescriptorSetManagerGLES>(*this); 21278bf80f4bSopenharmony_ci} 21288bf80f4bSopenharmony_ci 21298bf80f4bSopenharmony_ciunique_ptr<NodeContextPoolManager> DeviceGLES::CreateNodeContextPoolManager( 21308bf80f4bSopenharmony_ci GpuResourceManager& gpuResourceMgr, const GpuQueue& gpuQueue) 21318bf80f4bSopenharmony_ci{ 21328bf80f4bSopenharmony_ci return make_unique<NodeContextPoolManagerGLES>(*this, gpuResourceMgr); 21338bf80f4bSopenharmony_ci} 21348bf80f4bSopenharmony_ci 21358bf80f4bSopenharmony_ciunique_ptr<GraphicsPipelineStateObject> DeviceGLES::CreateGraphicsPipelineStateObject( 21368bf80f4bSopenharmony_ci const GpuShaderProgram& gpuProgram, const GraphicsState& graphicsState, const PipelineLayout& pipelineLayout, 21378bf80f4bSopenharmony_ci const VertexInputDeclarationView& vertexInputDeclaration, 21388bf80f4bSopenharmony_ci const ShaderSpecializationConstantDataView& specializationConstants, 21398bf80f4bSopenharmony_ci const array_view<const DynamicStateEnum> dynamicStates, const RenderPassDesc& renderPassDesc, 21408bf80f4bSopenharmony_ci const array_view<const RenderPassSubpassDesc>& renderPassSubpassDescs, const uint32_t subpassIndex, 21418bf80f4bSopenharmony_ci const LowLevelRenderPassData* renderPassData, const LowLevelPipelineLayoutData* pipelineLayoutData) 21428bf80f4bSopenharmony_ci{ 21438bf80f4bSopenharmony_ci PLUGIN_ASSERT(!renderPassData); 21448bf80f4bSopenharmony_ci PLUGIN_ASSERT(!pipelineLayoutData); 21458bf80f4bSopenharmony_ci auto pipeline = make_unique<GraphicsPipelineStateObjectGLES>(*this, gpuProgram, graphicsState, pipelineLayout, 21468bf80f4bSopenharmony_ci vertexInputDeclaration, specializationConstants, dynamicStates, renderPassDesc, renderPassSubpassDescs, 21478bf80f4bSopenharmony_ci subpassIndex); 21488bf80f4bSopenharmony_ci return unique_ptr<GraphicsPipelineStateObject> { pipeline->GetPlatformData().graphicsShader ? pipeline.release() 21498bf80f4bSopenharmony_ci : nullptr }; 21508bf80f4bSopenharmony_ci} 21518bf80f4bSopenharmony_ci 21528bf80f4bSopenharmony_ciunique_ptr<ComputePipelineStateObject> DeviceGLES::CreateComputePipelineStateObject(const GpuComputeProgram& gpuProgram, 21538bf80f4bSopenharmony_ci const PipelineLayout& pipelineLayout, const ShaderSpecializationConstantDataView& specializationConstants, 21548bf80f4bSopenharmony_ci const LowLevelPipelineLayoutData* pipelineLayoutData) 21558bf80f4bSopenharmony_ci{ 21568bf80f4bSopenharmony_ci PLUGIN_ASSERT(!pipelineLayoutData); 21578bf80f4bSopenharmony_ci auto pipeline = 21588bf80f4bSopenharmony_ci make_unique<ComputePipelineStateObjectGLES>(*this, gpuProgram, pipelineLayout, specializationConstants); 21598bf80f4bSopenharmony_ci return unique_ptr<ComputePipelineStateObject> { pipeline->GetPlatformData().computeShader ? pipeline.release() 21608bf80f4bSopenharmony_ci : nullptr }; 21618bf80f4bSopenharmony_ci} 21628bf80f4bSopenharmony_ci 21638bf80f4bSopenharmony_ciunique_ptr<GpuSemaphore> DeviceGLES::CreateGpuSemaphore() 21648bf80f4bSopenharmony_ci{ 21658bf80f4bSopenharmony_ci return make_unique<GpuSemaphoreGles>(*this); 21668bf80f4bSopenharmony_ci} 21678bf80f4bSopenharmony_ci 21688bf80f4bSopenharmony_ciunique_ptr<GpuSemaphore> DeviceGLES::CreateGpuSemaphoreView(const uint64_t handle) 21698bf80f4bSopenharmony_ci{ 21708bf80f4bSopenharmony_ci return make_unique<GpuSemaphoreGles>(*this, handle); 21718bf80f4bSopenharmony_ci} 21728bf80f4bSopenharmony_ci 21738bf80f4bSopenharmony_civoid DeviceGLES::SetBackendConfig(const BackendConfig& config) 21748bf80f4bSopenharmony_ci{ 21758bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND 21768bf80f4bSopenharmony_ci backendConfig_.allowDepthResolve = static_cast<const BackendConfigGLES&>(config).allowDepthResolve && 21778bf80f4bSopenharmony_ci HasExtension("GL_EXT_multisampled_render_to_texture2"); 21788bf80f4bSopenharmony_ci#endif 21798bf80f4bSopenharmony_ci} 21808bf80f4bSopenharmony_ci 21818bf80f4bSopenharmony_ciLowLevelDeviceGLES::LowLevelDeviceGLES(DeviceGLES& deviceGLES) 21828bf80f4bSopenharmony_ci : deviceGLES_(deviceGLES), gpuResourceMgr_(static_cast<GpuResourceManager&>(deviceGLES.GetGpuResourceManager())) 21838bf80f4bSopenharmony_ci{} 21848bf80f4bSopenharmony_ci 21858bf80f4bSopenharmony_ciDeviceBackendType LowLevelDeviceGLES::GetBackendType() const 21868bf80f4bSopenharmony_ci{ 21878bf80f4bSopenharmony_ci return deviceGLES_.GetBackendType(); 21888bf80f4bSopenharmony_ci} 21898bf80f4bSopenharmony_ci 21908bf80f4bSopenharmony_ci#if RENDER_HAS_EXPERIMENTAL 21918bf80f4bSopenharmony_civoid LowLevelDeviceGLES::Activate() 21928bf80f4bSopenharmony_ci{ 21938bf80f4bSopenharmony_ci deviceGLES_.Activate(); 21948bf80f4bSopenharmony_ci} 21958bf80f4bSopenharmony_ci 21968bf80f4bSopenharmony_civoid LowLevelDeviceGLES::Deactivate() 21978bf80f4bSopenharmony_ci{ 21988bf80f4bSopenharmony_ci deviceGLES_.Deactivate(); 21998bf80f4bSopenharmony_ci} 22008bf80f4bSopenharmony_ci 22018bf80f4bSopenharmony_civoid LowLevelDeviceGLES::SwapBuffers() 22028bf80f4bSopenharmony_ci{ 22038bf80f4bSopenharmony_ci if (deviceGLES_.IsActive() && deviceGLES_.HasSwapchain()) { 22048bf80f4bSopenharmony_ci RenderHandle defaultSwapChain {}; 22058bf80f4bSopenharmony_ci auto sc = static_cast<const SwapchainGLES*>(deviceGLES_.GetSwapchain(defaultSwapChain)); 22068bf80f4bSopenharmony_ci deviceGLES_.SwapBuffers(*sc); 22078bf80f4bSopenharmony_ci } 22088bf80f4bSopenharmony_ci} 22098bf80f4bSopenharmony_ci#endif 22108bf80f4bSopenharmony_ci 22118bf80f4bSopenharmony_ciRENDER_END_NAMESPACE() 2212