1#include "CapabilitiesGLES30.h"
9#include "CommonGLES30.h"
10#include "FormatsGLES30.h"
12#include "Foundation/Logging/Logger.h"
15#include <emscripten.h>
22 void toUpper(std::string &
string)
24 std::transform(
string.begin(),
string.end(),
string.begin(), [](
const char & c) {
return (
char)::toupper(c); });
28void Cogs::CapabilitiesGLES30::initialize(
bool isFullGL,
bool useClipControl)
32 std::string vendor((
const char *)glGetString(GL_VENDOR));
33 std::string renderer((
const char *)glGetString(GL_RENDERER));
36 LOG_DEBUG(logger,
"GL_VERSION: %s", glGetString(GL_VERSION));
37 LOG_DEBUG(logger,
"GL_VENDOR: %s", vendor.c_str());
38 LOG_DEBUG(logger,
"GL_RENDERER: %s", renderer.c_str());
39 LOG_DEBUG(logger,
"GL_SHADING_LANGUAGE_VERSION: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
43 const auto extensionsString = std::string((
const char *)glGetString(GL_EXTENSIONS));
45 std::istringstream sstream(extensionsString);
46 extensions = std::unordered_set<std::string>(std::istream_iterator<std::string>(sstream), std::istream_iterator<std::string>());
50 std::istringstream sstream(extensionsString);
52 while(sstream >> ext){
53 LOG_DEBUG(logger,
"Extension: %s", ext.c_str());
57 std::string unmaskedVendor;
58 std::string unmaskedRenderer;
59 if (isSupported(
"GL_WEBGL_debug_renderer_info")) {
60 unmaskedVendor = std::string((
const char*)glGetString(0x9245));
61 unmaskedRenderer = std::string((
const char*)glGetString(0x9246));
62 LOG_DEBUG(logger,
"GL_UNMASKED_VENDOR_WEBGL: %s", unmaskedRenderer.c_str());
63 LOG_DEBUG(logger,
"GL_UNMASKED_RENDERER_WEBGL: %s", unmaskedRenderer.c_str());
65 ::toUpper(unmaskedVendor);
66 ::toUpper(unmaskedRenderer);
71 if (vendor.find(
"NVIDIA") != vendor.npos) {
74 if (renderer.find(
"QUADRO FX") != std::string::npos) series =
Series::QuadroFX;
75 else if (renderer.find(
"QUADRO") != std::string::npos) series =
Series::Quadro;
76 else if (renderer.find(
"GEFORCE") != std::string::npos) series =
Series::geForce;
78 auto modelString = renderer.substr(0, renderer.find_first_of(
'/'));
80 if (modelString.size()) {
81 std::regex numbers(
"\\d.*");
84 if (std::regex_search(modelString, results, numbers)) {
85 model = std::stoi(results[0].str());
88 }
else if (vendor.find(
"AMD") != vendor.npos || vendor.find(
"ATI") != vendor.npos) {
91 if (renderer.find(
"FIREGL") != std::string::npos) series =
Series::FireGL;
92 }
else if (vendor.find(
"INTEL") != vendor.npos) {
98 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &deviceCapabilities.MaxTextureSlots);
99 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &deviceCapabilities.MaxVertexInputElements);
101 if (isSupported(
"GL_EXT_texture_filter_anisotropic")) {
102 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &deviceCapabilities.MaxAnisotropy);
103 LOG_DEBUG(logger,
"GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: %f", deviceCapabilities.MaxAnisotropy);
107 glGetIntegerv(GL_MAX_SAMPLES, &samples);
108 deviceCapabilities.MaxSamples = std::max(1, samples);
111 if (renderer.find(
"MALI-G72") != std::string::npos || unmaskedRenderer.find(
"MALI-G72") != std::string::npos) {
112 LOG_DEBUG(logger,
"Mali-G72 detected disabling multisampling");
113 deviceCapabilities.MaxSamples = 1;
116 GLint maxTextureSize = 0;
117 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
120 GLint max3DTextureSize = 0;
121 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
124 GLint maxCubeTextureSize = 0;
125 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
128 GLint maxArrayTextureLayers = 0;
129 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
132 LOG_DEBUG(logger,
"Texture limits: 2D=%u 3D=%u Cube=%u Array=%u",
138 GLint uniformBufferOffsetAlignment = 0;
139 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniformBufferOffsetAlignment);
140 if (uniformBufferOffsetAlignment) {
145 if (isSupported(
"GL_OCULUS_multiview")) {
146 deviceCapabilities.MultiSampleMultiView =
true;
147 deviceCapabilities.MultiView =
true;
149 else if (isSupported(
"GL_OVR_multiview_multisampled_render_to_texture")) {
150 deviceCapabilities.MultiSampleMultiView =
true;
151 deviceCapabilities.MultiView =
true;
153 else if (isSupported(
"GL_OVR_multiview2")) {
154 deviceCapabilities.MultiView =
true;
156 else if (isSupported(
"GL_OVR_multiview")) {
157 deviceCapabilities.MultiView =
true;
161 if (!deviceCapabilities.MultiView) {
163 for (
const item of Object.values(Module.GL.contexts)) {
164 if (item && item.hasOwnProperty(
'GLctx')) {
165 const ext = item.GLctx.getExtension(
"OVR_multiview2");
166 return ext !== null ? 1 : 0;
171 LOG_DEBUG(logger,
"Browser supports OVR_multiview2 even though emscripten doesn't, enabling regardless");
172 deviceCapabilities.MultiView =
true;
176 if (!deviceCapabilities.MultiSampleMultiView) {
178 for (
const item of Object.values(Module.GL.contexts)) {
179 if (item && item.hasOwnProperty(
'GLctx')) {
180 const ext = item.GLctx.getExtension(
"OCULUS_multiview");
181 return ext !== null ? 1 : 0;
186 LOG_DEBUG(logger,
"Browser supports OCULUS_multiview even though emscripten doesn't, enabling regardless");
187 deviceCapabilities.MultiSampleMultiView =
true;
188 deviceCapabilities.MultiView =
true;
194 deviceCapabilities.DefaultColorTargetHasLinearEncoding =
false;
196 GLint param = GL_INVALID_ENUM;
197 glBindFramebuffer(GL_FRAMEBUFFER, 0);
198 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, ¶m);
201 LOG_DEBUG(logger,
"Default render target has LINEAR encoding");
202 deviceCapabilities.DefaultColorTargetHasLinearEncoding =
true;
205 LOG_DEBUG(logger,
"Default render target has SRGB encoding");
208 LOG_ERROR(logger,
"glGetFramebufferAttachmentParameter returned unrecognized enum: #%04x", param);
213 if (deviceCapabilities.MultiView) {
215 glGetIntegerv(GL_MAX_VIEWS_OVR, &maxViews);
216 deviceCapabilities.MaxMultiViews = std::max(0, maxViews);
217 LOG_DEBUG(logger,
"MultiView rendering available, maxViews=%d, maxSamples=%d",
219 deviceCapabilities.MultiSampleMultiView ? deviceCapabilities.MaxSamples : 1);
226 deviceCapabilities.VertexAndIndexDataInSharedBuffers =
false;
229 deviceCapabilities.SyncObjects =
true;
230 deviceCapabilities.UnsignedIntIndexes =
true;
231 deviceCapabilities.FloatTextures =
true;
232 deviceCapabilities.FragDepth =
true;
233 deviceCapabilities.SupportsHlsl =
false;
234 deviceCapabilities.StartInstance =
false;
235 deviceCapabilities.IndependentSamplerState =
false;
236 deviceCapabilities.SupportsMultipleThreads =
false;
237 deviceCapabilities.TextureCubeArrays =
false;
238 deviceCapabilities.VertexArrayObjects =
true;
239 deviceCapabilities.OriginOnTop =
false;
240 deviceCapabilities.DepthNegativeOneToOne = !useClipControl;
242 if (isSupported(
"GL_EXT_depth_clamp")) {
249 if (isSupported(
"GL_EXT_texture_compression_s3tc") ||
250 isSupported(
"GL_WEBGL_compressed_texture_s3tc")) {
251 deviceCapabilities.TextureCompressionS3TC =
true;
253 if (isSupported(
"GL_ARB_texture_compression_rgtc") ||
254 isSupported(
"GL_EXT_texture_compression_rgtc")) {
255 deviceCapabilities.TextureCompressionRGTC =
true;
257 if (isSupported(
"GL_ARB_texture_compression_bptc") ||
258 isSupported(
"GL_EXT_texture_compression_bptc")) {
259 deviceCapabilities.TextureCompressionBPTC =
true;
261 if (isSupported(
"WEBGL_compressed_texture_etc") ||
262 isSupported(
"GL_OES_compressed_ETC1_RGB8_texture")) {
263 deviceCapabilities.TextureCompressionETC =
true;
265 if (isSupported(
"WEBGL_compressed_texture_pvrtc") ||
266 isSupported(
"GL_IMG_texture_compression_pvrtc")) {
267 deviceCapabilities.TextureCompressionPVRTC =
true;
269 if (isSupported(
"WEBGL_compressed_texture_astc") ||
270 isSupported(
"GL_OES_texture_compression_astc") || (
271 isSupported(
"GL_KHR_texture_compression_astc_hdr") &&
272 isSupported(
"GL_KHR_texture_compression_astc_ldr"))) {
273 deviceCapabilities.TextureCompressionASTC =
true;
276 OpenGLES30::enableExtensionFormats(
this);
279bool Cogs::CapabilitiesGLES30::isSupported(
const StringView & extension)
const
281 return extensions.find(std::string(extension)) != extensions.end();
Log implementation class.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
uint32_t MaxTexture3DSize
Using D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION as default.
uint32_t MaxTexture2DSize
Using D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION as default.
uint32_t MaxTextureCubeSize
Using D3D11_REQ_TEXTURECUBE_DIMENSION as default.
uint32_t MaxTextureArrayLayers
Using D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION as default.
unsigned ConstantBufferOffsetAlignment
Minimum offset alignment when binding constant buffers.
bool ConstantBufferRange
supports binding a range of a constant buffer.
@ QuadroFX
nVidia Quadro FX professional graphics adapters.
@ FireGL
AMD FireGL series.
@ geForce
nVidia geForce consumer adapters.
@ Quadro
nVidia Quadro professional graphics adapters.
@ nVidia
nVidia Corporation.
@ Unknown
Unknown device vendor.