diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/egl/egl_manager.cpp | 89 | ||||
-rw-r--r-- | drivers/egl/egl_manager.h | 2 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 3 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.h | 6 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_gles3.cpp | 9 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_gles3.h | 2 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 15 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 2 | ||||
-rw-r--r-- | drivers/gles3/shader_gles3.cpp | 5 | ||||
-rw-r--r-- | drivers/gles3/shader_gles3.h | 2 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 3 | ||||
-rw-r--r-- | drivers/gles3/storage/config.cpp | 44 | ||||
-rw-r--r-- | drivers/gles3/storage/config.h | 15 | ||||
-rw-r--r-- | drivers/gles3/storage/material_storage.cpp | 9 | ||||
-rw-r--r-- | drivers/gles3/storage/particles_storage.cpp | 4 | ||||
-rw-r--r-- | drivers/gles3/storage/particles_storage.h | 3 | ||||
-rw-r--r-- | drivers/gles3/storage/render_scene_buffers_gles3.cpp | 18 | ||||
-rw-r--r-- | drivers/gles3/storage/render_scene_buffers_gles3.h | 5 | ||||
-rw-r--r-- | drivers/gles3/storage/utilities.cpp | 5 |
19 files changed, 165 insertions, 76 deletions
diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp index 6073856747..9c1d08331d 100644 --- a/drivers/egl/egl_manager.cpp +++ b/drivers/egl/egl_manager.cpp @@ -33,10 +33,22 @@ #ifdef EGL_ENABLED #if defined(EGL_STATIC) -#define KHRONOS_STATIC 1 + #define GLAD_EGL_VERSION_1_5 true + +#ifdef EGL_EXT_platform_base +#define GLAD_EGL_EXT_platform_base 1 +#endif + +#define KHRONOS_STATIC 1 extern "C" EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +extern "C" EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list); #undef KHRONOS_STATIC + +#endif // defined(EGL_STATIC) + +#ifndef EGL_EXT_platform_base +#define GLAD_EGL_EXT_platform_base 0 #endif // Creates and caches a GLDisplay. Returns -1 on error. @@ -56,10 +68,23 @@ int EGLManager::_get_gldisplay_id(void *p_display) { if (GLAD_EGL_VERSION_1_5) { Vector<EGLAttrib> attribs = _get_platform_display_attributes(); new_gldisplay.egl_display = eglGetPlatformDisplay(_get_platform_extension_enum(), new_gldisplay.display, (attribs.size() > 0) ? attribs.ptr() : nullptr); + } else if (GLAD_EGL_EXT_platform_base) { +#ifdef EGL_EXT_platform_base + // eglGetPlatformDisplayEXT wants its attributes as EGLint, so we'll truncate + // what we already have. It's a bit naughty but I'm really not sure what else + // we could do here. + Vector<EGLint> attribs; + for (const EGLAttrib &attrib : _get_platform_display_attributes()) { + attribs.push_back((EGLint)attrib); + } + + new_gldisplay.egl_display = eglGetPlatformDisplayEXT(_get_platform_extension_enum(), new_gldisplay.display, (attribs.size() > 0) ? attribs.ptr() : nullptr); +#endif // EGL_EXT_platform_base } else { NativeDisplayType *native_display_type = (NativeDisplayType *)new_gldisplay.display; new_gldisplay.egl_display = eglGetDisplay(*native_display_type); } + ERR_FAIL_COND_V(eglGetError() != EGL_SUCCESS, -1); ERR_FAIL_COND_V_MSG(new_gldisplay.egl_display == EGL_NO_DISPLAY, -1, "Can't create an EGL display."); @@ -326,30 +351,51 @@ EGLContext EGLManager::get_context(DisplayServer::WindowID p_window_id) { return display.egl_context; } -Error EGLManager::initialize() { +Error EGLManager::initialize(void *p_native_display) { #if defined(GLAD_ENABLED) && !defined(EGL_STATIC) - // Passing a null display loads just the bare minimum to create one. We'll have - // to create a temporary test display and reload EGL with it to get a good idea - // of what version is supported on this machine. Currently we're looking for - // 1.5, the latest at the time of writing, which is actually pretty old. - if (!gladLoaderLoadEGL(nullptr)) { + // Loading EGL with a new display gets us just the bare minimum API. We'll then + // have to temporarily get a proper display and reload EGL once again to + // initialize everything else. + if (!gladLoaderLoadEGL(EGL_NO_DISPLAY)) { ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't load EGL."); } - // NOTE: EGL_DEFAULT_DISPLAY returns whatever the O.S. deems suitable. I have - // no idea if this may cause problems with multiple display servers and if we - // should handle different EGL contexts in another way. - EGLDisplay tmp_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - ERR_FAIL_COND_V(tmp_display == EGL_NO_DISPLAY, ERR_UNAVAILABLE); + EGLDisplay tmp_display = EGL_NO_DISPLAY; + + if (GLAD_EGL_EXT_platform_base) { +#ifdef EGL_EXT_platform_base + // eglGetPlatformDisplayEXT wants its attributes as EGLint. + Vector<EGLint> attribs; + for (const EGLAttrib &attrib : _get_platform_display_attributes()) { + attribs.push_back((EGLint)attrib); + } + tmp_display = eglGetPlatformDisplayEXT(_get_platform_extension_enum(), p_native_display, attribs.ptr()); +#endif // EGL_EXT_platform_base + } else { + WARN_PRINT("EGL: EGL_EXT_platform_base not found during init, using default platform."); + EGLNativeDisplayType *native_display_type = (EGLNativeDisplayType *)p_native_display; + tmp_display = eglGetDisplay(*native_display_type); + } + + if (tmp_display == EGL_NO_DISPLAY) { + eglTerminate(tmp_display); + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't get a valid initial EGL display."); + } eglInitialize(tmp_display, nullptr, nullptr); int version = gladLoaderLoadEGL(tmp_display); + if (!version) { + eglTerminate(tmp_display); + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't load EGL."); + } + + int major = GLAD_VERSION_MAJOR(version); + int minor = GLAD_VERSION_MINOR(version); - ERR_FAIL_COND_V_MSG(!version, ERR_UNAVAILABLE, "Can't load EGL."); - print_verbose(vformat("Loaded EGL %d.%d", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version))); + print_verbose(vformat("Loaded EGL %d.%d", major, minor)); - ERR_FAIL_COND_V_MSG(!GLAD_EGL_VERSION_1_4, ERR_UNAVAILABLE, "EGL version is too old!"); + ERR_FAIL_COND_V_MSG(!GLAD_EGL_VERSION_1_4, ERR_UNAVAILABLE, vformat("EGL version is too old! %d.%d < 1.4", major, minor)); eglTerminate(tmp_display); #endif @@ -378,13 +424,14 @@ Error EGLManager::initialize() { } #endif - String extensions_string = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - // The above method should always work. If it doesn't, something's very wrong. - ERR_FAIL_COND_V(eglGetError() != EGL_SUCCESS, ERR_BUG); + String client_extensions_string = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - const char *platform = _get_platform_extension_name(); - if (!extensions_string.split(" ").has(platform)) { - ERR_FAIL_V_MSG(ERR_UNAVAILABLE, vformat("EGL platform extension \"%s\" not found.", platform)); + // If the above method fails, we don't support client extensions, so there's nothing to check. + if (eglGetError() == EGL_SUCCESS) { + const char *platform = _get_platform_extension_name(); + if (!client_extensions_string.split(" ").has(platform)) { + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, vformat("EGL platform extension \"%s\" not found.", platform)); + } } return OK; diff --git a/drivers/egl/egl_manager.h b/drivers/egl/egl_manager.h index 83779349f0..a4502c0687 100644 --- a/drivers/egl/egl_manager.h +++ b/drivers/egl/egl_manager.h @@ -107,7 +107,7 @@ public: EGLContext get_context(DisplayServer::WindowID p_window_id); - Error initialize(); + Error initialize(void *p_native_display = nullptr); EGLManager(); virtual ~EGLManager(); diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 5fabeb94f5..941b1a1b28 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -2742,8 +2742,7 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - int uniform_max_size = config->max_uniform_buffer_size; - if (uniform_max_size < 65536) { + if (config->max_uniform_buffer_size < 65536) { data.max_lights_per_render = 64; } else { data.max_lights_per_render = 256; diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index a3762e828e..7fc9992c3d 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -157,6 +157,8 @@ class RasterizerCanvasGLES3 : public RendererCanvasRender { float atlas_rect[4]; }; + static_assert(sizeof(LightUniform) % 16 == 0, "2D light UBO size must be a multiple of 16 bytes"); + public: enum { BASE_UNIFORM_LOCATION = 0, @@ -186,6 +188,8 @@ public: uint32_t pad2; }; + static_assert(sizeof(StateBuffer) % 16 == 0, "2D state UBO size must be a multiple of 16 bytes"); + struct PolygonBuffers { GLuint vertex_buffer = 0; GLuint vertex_array = 0; @@ -230,6 +234,8 @@ public: uint32_t lights[4]; }; + static_assert(sizeof(InstanceData) == 128, "2D instance data struct size must be 128 bytes"); + struct Data { GLuint canvas_quad_vertices; GLuint canvas_quad_array; diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 993197e371..ae39c86d44 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -195,9 +195,9 @@ void RasterizerGLES3::initialize() { Engine::get_singleton()->print_header(vformat("OpenGL API %s - Compatibility - Using Device: %s - %s", RS::get_singleton()->get_video_adapter_api_version(), RS::get_singleton()->get_video_adapter_vendor(), RS::get_singleton()->get_video_adapter_name())); // FLIP XY Bug: Are more devices affected? - // Confirmed so far: all Adreno 3xx + // Confirmed so far: all Adreno 3xx with old driver (until 2018) // ok on some tested Adreno devices: 4xx, 5xx and 6xx - flip_xy_bugfix = GLES3::Config::get_singleton()->adreno_3xx_compatibility; + flip_xy_workaround = GLES3::Config::get_singleton()->flip_xy_workaround; } void RasterizerGLES3::finalize() { @@ -398,8 +398,7 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display // Viewport doesn't cover entire window so clear window to black before blitting. // Querying the actual window size from the DisplayServer would deadlock in separate render thread mode, // so let's set the biggest viewport the implementation supports, to be sure the window is fully covered. - GLsizei max_vp[2] = {}; - glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_vp); + Size2i max_vp = GLES3::Utilities::get_singleton()->get_maximum_viewport_size(); glViewport(0, 0, max_vp[0], max_vp[1]); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); @@ -411,7 +410,7 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display // Adreno (TM) 3xx devices have a bug that create wrong Landscape rotation of 180 degree // Reversing both the X and Y axis is equivalent to rotating 180 degrees bool flip_x = false; - if (flip_xy_bugfix && screen_rect_end.x > screen_rect_end.y) { + if (flip_xy_workaround && screen_rect_end.x > screen_rect_end.y) { flip_y = !flip_y; flip_x = !flip_x; } diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index 09d3c7bd52..0d0c26016d 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -56,7 +56,7 @@ private: float delta = 0; double time_total = 0.0; - bool flip_xy_bugfix = false; + bool flip_xy_workaround = false; static bool gles_over_gl; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 6a51ce6b70..9ea030bbd4 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2245,9 +2245,9 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ } bool glow_enabled = false; - if (p_environment.is_valid() && rb.is_valid()) { + if (p_environment.is_valid()) { glow_enabled = environment_get_glow_enabled(p_environment); - rb->set_glow_enabled(glow_enabled); // ensure our intermediate buffer is available if glow is enabled + rb->ensure_internal_buffers(); // Ensure our intermediate buffer is available if glow is enabled if (glow_enabled) { // If glow is enabled, we apply tonemapping etc. in post, so disable it during rendering apply_color_adjustments_in_post = true; @@ -2339,6 +2339,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ if (render_data.environment.is_valid()) { bool use_bcs = environment_get_adjustments_enabled(render_data.environment); if (use_bcs) { + rb->ensure_internal_buffers(); apply_color_adjustments_in_post = true; } @@ -2397,6 +2398,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ float bg_energy_multiplier = environment_get_bg_energy_multiplier(render_data.environment); bg_energy_multiplier *= environment_get_bg_intensity(render_data.environment); RS::EnvironmentReflectionSource reflection_source = environment_get_reflection_source(render_data.environment); + RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(render_data.environment); if (render_data.camera_attributes.is_valid()) { bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(render_data.camera_attributes); @@ -2437,8 +2439,13 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ } } + bool sky_reflections = reflection_source == RS::ENV_REFLECTION_SOURCE_SKY; + sky_reflections |= reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY; + bool sky_ambient = ambient_source == RS::ENV_AMBIENT_SOURCE_SKY; + sky_ambient |= ambient_source == RS::ENV_AMBIENT_SOURCE_BG && bg_mode == RS::ENV_BG_SKY; + // setup sky if used for ambient, reflections, or background - if (draw_sky || draw_sky_fog_only || (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY) { + if (draw_sky || draw_sky_fog_only || sky_reflections || sky_ambient) { RENDER_TIMESTAMP("Setup Sky"); Projection projection = render_data.cam_projection; if (is_reflection_probe) { @@ -2452,7 +2459,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ _setup_sky(&render_data, *render_data.lights, projection, render_data.cam_transform, screen_size); if (environment_get_sky(render_data.environment).is_valid()) { - if (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY || (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_BG && environment_get_background(render_data.environment) == RS::ENV_BG_SKY)) { + if (sky_reflections || sky_ambient) { _update_sky_radiance(render_data.environment, projection, render_data.cam_transform, sky_energy_multiplier); } } else { diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index b6c7a0c5a5..4c70c43244 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -428,6 +428,7 @@ private: bool pancake_shadows; }; static_assert(sizeof(UBO) % 16 == 0, "Scene UBO size must be a multiple of 16 bytes"); + static_assert(sizeof(UBO) < 16384, "Scene UBO size must be 16384 bytes or smaller"); struct MultiviewUBO { float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; @@ -435,6 +436,7 @@ private: float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4]; }; static_assert(sizeof(MultiviewUBO) % 16 == 0, "Multiview UBO size must be a multiple of 16 bytes"); + static_assert(sizeof(MultiviewUBO) < 16384, "MultiviewUBO size must be 16384 bytes or smaller"); struct TonemapUBO { float exposure = 1.0; diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 876309d22c..4a15ed827a 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -37,6 +37,7 @@ #include "core/io/file_access.h" #include "drivers/gles3/rasterizer_gles3.h" +#include "drivers/gles3/storage/config.h" static String _mkid(const String &p_id) { String id = "m_" + p_id.replace("__", "_dus_"); @@ -801,7 +802,9 @@ void ShaderGLES3::initialize(const String &p_general_defines, int p_base_texture print_verbose("Shader '" + name + "' SHA256: " + base_sha256); } - glGetInteger64v(GL_MAX_TEXTURE_IMAGE_UNITS, &max_image_units); + GLES3::Config *config = GLES3::Config::get_singleton(); + ERR_FAIL_NULL(config); + max_image_units = config->max_texture_image_units; } void ShaderGLES3::set_shader_cache_dir(const String &p_dir) { diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index 8968e76c12..9ee939e343 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -148,7 +148,7 @@ private: static bool shader_cache_save_debug; bool shader_cache_dir_valid = false; - int64_t max_image_units = 0; + GLint max_image_units = 0; enum StageType { STAGE_TYPE_VERTEX, diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 2b372cb88d..be7a6aba57 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1523,6 +1523,9 @@ void main() { #CODE : FRAGMENT } + // Keep albedo values in positive number range as negative values "wraparound" into positive numbers resulting in wrong colors + albedo = max(albedo, vec3(0.0)); + #ifdef LIGHT_VERTEX_USED vertex = light_vertex; #ifdef USE_MULTIVIEW diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index 6b5e227782..1a14902c7c 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -45,9 +45,9 @@ Config::Config() { singleton = this; { - int64_t max_extensions = 0; - glGetInteger64v(GL_NUM_EXTENSIONS, &max_extensions); - for (int64_t i = 0; i < max_extensions; i++) { + GLint max_extensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &max_extensions); + for (int i = 0; i < max_extensions; i++) { const GLubyte *s = glGetStringi(GL_EXTENSIONS, i); if (!s) { break; @@ -80,11 +80,14 @@ Config::Config() { rgtc_supported = extensions.has("GL_EXT_texture_compression_rgtc") || extensions.has("GL_ARB_texture_compression_rgtc") || extensions.has("EXT_texture_compression_rgtc"); } - glGetInteger64v(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &max_vertex_texture_image_units); - glGetInteger64v(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_image_units); - glGetInteger64v(GL_MAX_TEXTURE_SIZE, &max_texture_size); + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &max_vertex_texture_image_units); + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_image_units); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size); glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_buffer_size); - glGetInteger64v(GL_MAX_VIEWPORT_DIMS, max_viewport_size); + + // sanity clamp buffer size to 16K..1MB + max_uniform_buffer_size = CLAMP(max_uniform_buffer_size, 16384, 1048576); support_anisotropic_filter = extensions.has("GL_EXT_texture_filter_anisotropic"); if (support_anisotropic_filter) { @@ -169,8 +172,31 @@ Config::Config() { //Adreno 3xx Compatibility const String rendering_device_name = String::utf8((const char *)glGetString(GL_RENDERER)); - //TODO: Check the number between 300 and 399(?) - adreno_3xx_compatibility = (rendering_device_name.left(13) == "Adreno (TM) 3"); + if (rendering_device_name.left(13) == "Adreno (TM) 3") { + flip_xy_workaround = true; + disable_particles_workaround = true; + + // ignore driver version 331+ + const String gl_version = String::utf8((const char *)glGetString(GL_VERSION)); + // Adreno 3xx examples (https://opengles.gpuinfo.org/listreports.php): + // =========================================================================== + // OpenGL ES 3.0 V@84.0 AU@ (CL@) + // OpenGL ES 3.0 V@127.0 AU@ (GIT@I96aee987eb) + // OpenGL ES 3.0 V@140.0 AU@ (GIT@Ifd751822f5) + // OpenGL ES 3.0 V@251.0 AU@08.00.00.312.030 (GIT@Ie4790512f3) + // OpenGL ES 3.0 V@269.0 AU@ (GIT@I109c45a694) + // OpenGL ES 3.0 V@331.0 (GIT@35e467f, Ice9844a736) (Date:04/15/19) + // OpenGL ES 3.0 V@415.0 (GIT@d39f783, I79de86aa2c, 1591296226) (Date:06/04/20) + // OpenGL ES 3.0 V@0502.0 (GIT@09fef447e8, I1fe547a144, 1661493934) (Date:08/25/22) + String driver_version = gl_version.get_slice("V@", 1).get_slice(" ", 0); + if (driver_version.is_valid_float() && driver_version.to_float() >= 331.0) { + flip_xy_workaround = false; + + //TODO: also 'GPUParticles'? + //https://github.com/godotengine/godot/issues/92662#issuecomment-2161199477 + //disable_particles_workaround = false; + } + } } Config::~Config() { diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index c3ab65f0bc..0c9f9bc275 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -57,11 +57,12 @@ public: bool use_nearest_mip_filter = false; bool use_depth_prepass = true; - int64_t max_vertex_texture_image_units = 0; - int64_t max_texture_image_units = 0; - int64_t max_texture_size = 0; - int64_t max_viewport_size[2] = { 0, 0 }; - int64_t max_uniform_buffer_size = 0; + GLint max_vertex_texture_image_units = 0; + GLint max_texture_image_units = 0; + GLint max_texture_size = 0; + GLint max_viewport_size[2] = { 0, 0 }; + GLint64 max_uniform_buffer_size = 0; + int64_t max_renderable_elements = 0; int64_t max_renderable_lights = 0; int64_t max_lights_per_object = 0; @@ -91,7 +92,9 @@ public: bool rt_msaa_multiview_supported = false; bool multiview_supported = false; - bool adreno_3xx_compatibility = false; + // Adreno 3XX compatibility + bool disable_particles_workaround = false; // set to 'true' to disable 'GPUParticles' + bool flip_xy_workaround = false; #ifdef ANDROID_ENABLED PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC eglFramebufferTextureMultiviewOVR = nullptr; diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 996c205042..bacf607c66 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -1055,6 +1055,7 @@ void MaterialData::update_parameters_internal(const HashMap<StringName, Variant> ubo_data.resize(p_ubo_size); if (ubo_data.size()) { + ERR_FAIL_COND(p_ubo_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)); memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear } } @@ -1108,10 +1109,10 @@ MaterialStorage::MaterialStorage() { static_assert(sizeof(GlobalShaderUniforms::Value) == 16); - global_shader_uniforms.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); - if (global_shader_uniforms.buffer_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) { - global_shader_uniforms.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size); - WARN_PRINT("Project setting \"rendering/limits/global_shader_variables/buffer_size\" exceeds maximum uniform buffer size of: " + itos(Config::get_singleton()->max_uniform_buffer_size)); + global_shader_uniforms.buffer_size = MAX(16, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); + if (global_shader_uniforms.buffer_size * sizeof(GlobalShaderUniforms::Value) > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) { + global_shader_uniforms.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size) / sizeof(GlobalShaderUniforms::Value); + WARN_PRINT("Project setting \"rendering/limits/global_shader_variables/buffer_size\" exceeds maximum uniform buffer size of: " + itos(Config::get_singleton()->max_uniform_buffer_size / sizeof(GlobalShaderUniforms::Value)) + ". Falling back on maximum buffer size."); } global_shader_uniforms.buffer_values = memnew_arr(GlobalShaderUniforms::Value, global_shader_uniforms.buffer_size); diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp index fee90599e0..b600681280 100644 --- a/drivers/gles3/storage/particles_storage.cpp +++ b/drivers/gles3/storage/particles_storage.cpp @@ -122,7 +122,7 @@ void ParticlesStorage::particles_set_mode(RID p_particles, RS::ParticlesMode p_m } void ParticlesStorage::particles_set_emitting(RID p_particles, bool p_emitting) { - ERR_FAIL_COND_MSG(GLES3::Config::get_singleton()->adreno_3xx_compatibility, "Due to driver bugs, GPUParticles are not supported on Adreno 3XX devices. Please use CPUParticles instead."); + ERR_FAIL_COND_MSG(GLES3::Config::get_singleton()->disable_particles_workaround, "Due to driver bugs, GPUParticles are not supported on Adreno 3XX devices. Please use CPUParticles instead."); Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_NULL(particles); @@ -131,7 +131,7 @@ void ParticlesStorage::particles_set_emitting(RID p_particles, bool p_emitting) } bool ParticlesStorage::particles_get_emitting(RID p_particles) { - if (GLES3::Config::get_singleton()->adreno_3xx_compatibility) { + if (GLES3::Config::get_singleton()->disable_particles_workaround) { return false; } diff --git a/drivers/gles3/storage/particles_storage.h b/drivers/gles3/storage/particles_storage.h index ca347ed070..086f5f7936 100644 --- a/drivers/gles3/storage/particles_storage.h +++ b/drivers/gles3/storage/particles_storage.h @@ -145,6 +145,9 @@ private: Collider colliders[MAX_COLLIDERS]; }; + static_assert(sizeof(ParticlesFrameParams) % 16 == 0, "ParticlesFrameParams size must be a multiple of 16 bytes"); + static_assert(sizeof(ParticlesFrameParams) < 16384, "ParticlesFrameParams must be 16384 bytes or smaller"); + struct Particles { RS::ParticlesMode mode = RS::PARTICLES_MODE_3D; bool inactive = true; diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.cpp b/drivers/gles3/storage/render_scene_buffers_gles3.cpp index cb194933ed..e4f1a01f68 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.cpp +++ b/drivers/gles3/storage/render_scene_buffers_gles3.cpp @@ -194,7 +194,7 @@ void RenderSceneBuffersGLES3::_check_render_buffers() { ERR_FAIL_COND(view_count == 0); - bool use_internal_buffer = scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF || glow.glow_enabled; + bool use_internal_buffer = scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF || needs_internal_buffers; uint32_t depth_format_size = 3; bool use_multiview = view_count > 1; @@ -203,7 +203,7 @@ void RenderSceneBuffersGLES3::_check_render_buffers() { return; } - if (use_internal_buffer) { + if (use_internal_buffer && internal3d.color == 0) { // Setup our internal buffer. GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; @@ -261,14 +261,14 @@ void RenderSceneBuffersGLES3::_check_render_buffers() { GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { _clear_intermediate_buffers(); - WARN_PRINT("Could not create 3D buffers, status: " + texture_storage->get_framebuffer_error(status)); + WARN_PRINT("Could not create 3D internal buffers, status: " + texture_storage->get_framebuffer_error(status)); } glBindTexture(texture_target, 0); glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); } - if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED) { + if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && msaa3d.color == 0) { // Setup MSAA. const GLsizei samples[] = { 1, 2, 4, 8 }; msaa3d.samples = samples[msaa3d.mode]; @@ -558,14 +558,8 @@ void RenderSceneBuffersGLES3::_clear_back_buffers() { } } -void RenderSceneBuffersGLES3::set_glow_enabled(bool p_glow_enabled) { - if (glow.glow_enabled != p_glow_enabled) { - glow.glow_enabled = p_glow_enabled; - - // Clear our main buffers, this can impact them. - _clear_msaa3d_buffers(); - _clear_intermediate_buffers(); - } +void RenderSceneBuffersGLES3::ensure_internal_buffers() { + needs_internal_buffers = true; } void RenderSceneBuffersGLES3::check_glow_buffers() { diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.h b/drivers/gles3/storage/render_scene_buffers_gles3.h index 04b9113b91..8273c18b8e 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.h +++ b/drivers/gles3/storage/render_scene_buffers_gles3.h @@ -50,6 +50,7 @@ public: //bool use_taa = false; //bool use_debanding = false; uint32_t view_count = 1; + bool needs_internal_buffers = false; RID render_target; @@ -83,7 +84,6 @@ public: // Buffers for our glow implementation struct GLOW { - bool glow_enabled = false; GLES3::Glow::GLOWLEVEL levels[4]; } glow; @@ -111,6 +111,7 @@ public: void check_backbuffer(bool p_need_color, bool p_need_depth); // Check if we need to initialize our backbuffer. void check_glow_buffers(); // Check if we need to initialize our glow buffers. + void ensure_internal_buffers(); GLuint get_render_fbo(); GLuint get_msaa3d_fbo() { @@ -145,8 +146,6 @@ public: GLuint get_backbuffer() const { return backbuffer3d.color; } GLuint get_backbuffer_depth() const { return backbuffer3d.depth; } - bool get_glow_enabled() const { return glow.glow_enabled; } - void set_glow_enabled(bool p_glow_enabled); const GLES3::Glow::GLOWLEVEL *get_glow_buffers() const { return &glow.levels[0]; } // Getters diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp index 356dc06733..7f0be36466 100644 --- a/drivers/gles3/storage/utilities.cpp +++ b/drivers/gles3/storage/utilities.cpp @@ -463,10 +463,7 @@ String Utilities::get_video_adapter_api_version() const { Size2i Utilities::get_maximum_viewport_size() const { Config *config = Config::get_singleton(); - if (!config) { - return Size2i(); - } - + ERR_FAIL_NULL_V(config, Size2i()); return Size2i(config->max_viewport_size[0], config->max_viewport_size[1]); } |