diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/egl/egl_manager.cpp | 20 | ||||
| -rw-r--r-- | drivers/gles3/environment/gi.cpp | 3 | ||||
| -rw-r--r-- | drivers/gles3/environment/gi.h | 2 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 17 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 4 | ||||
| -rw-r--r-- | drivers/gles3/storage/mesh_storage.cpp | 24 | ||||
| -rw-r--r-- | drivers/gles3/storage/texture_storage.cpp | 22 |
7 files changed, 66 insertions, 26 deletions
diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp index 0faae8cf6f..c92cfea9af 100644 --- a/drivers/egl/egl_manager.cpp +++ b/drivers/egl/egl_manager.cpp @@ -34,6 +34,7 @@ #if defined(EGL_STATIC) #define KHRONOS_STATIC 1 +#define GLAD_EGL_VERSION_1_5 true extern "C" EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); #undef KHRONOS_STATIC #endif @@ -52,9 +53,13 @@ int EGLManager::_get_gldisplay_id(void *p_display) { GLDisplay new_gldisplay; new_gldisplay.display = p_display; - 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); + 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 { + 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."); @@ -198,7 +203,12 @@ Error EGLManager::window_create(DisplayServer::WindowID p_window_id, void *p_dis GLWindow &glwindow = windows[p_window_id]; glwindow.gldisplay_id = gldisplay_id; - glwindow.egl_surface = eglCreatePlatformWindowSurface(gldisplay.egl_display, gldisplay.egl_config, p_native_window, nullptr); + if (GLAD_EGL_VERSION_1_5) { + glwindow.egl_surface = eglCreatePlatformWindowSurface(gldisplay.egl_display, gldisplay.egl_config, p_native_window, nullptr); + } else { + EGLNativeWindowType *native_window_type = (EGLNativeWindowType *)p_native_window; + glwindow.egl_surface = eglCreateWindowSurface(gldisplay.egl_display, gldisplay.egl_config, *native_window_type, nullptr); + } if (glwindow.egl_surface == EGL_NO_SURFACE) { return ERR_CANT_CREATE; @@ -345,7 +355,7 @@ Error EGLManager::initialize() { 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))); - ERR_FAIL_COND_V_MSG(!GLAD_EGL_VERSION_1_5, ERR_UNAVAILABLE, "EGL version is too old!"); + ERR_FAIL_COND_V_MSG(!GLAD_EGL_VERSION_1_4, ERR_UNAVAILABLE, "EGL version is too old!"); eglTerminate(tmp_display); #endif diff --git a/drivers/gles3/environment/gi.cpp b/drivers/gles3/environment/gi.cpp index 8beee25c64..6b33e0aa22 100644 --- a/drivers/gles3/environment/gi.cpp +++ b/drivers/gles3/environment/gi.cpp @@ -137,4 +137,7 @@ uint32_t GI::voxel_gi_get_version(RID p_voxel_gi) const { return 0; } +void GI::sdfgi_reset() { +} + #endif // GLES3_ENABLED diff --git a/drivers/gles3/environment/gi.h b/drivers/gles3/environment/gi.h index 41958e43e6..3eaa687f4f 100644 --- a/drivers/gles3/environment/gi.h +++ b/drivers/gles3/environment/gi.h @@ -85,6 +85,8 @@ public: virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override; virtual uint32_t voxel_gi_get_version(RID p_voxel_gi) const override; + + virtual void sdfgi_reset() override; }; }; // namespace GLES3 diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 1f10f4b353..21e14c1ec9 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1906,7 +1906,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b } // Render shadows -void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data) { +void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data, const Size2i &p_viewport_size) { GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton(); LocalVector<int> cube_shadows; @@ -1942,20 +1942,20 @@ void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data) // Render cubemap shadows. for (const int &index : cube_shadows) { - _render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info); + _render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size); } // Render directional shadows. for (uint32_t i = 0; i < directional_shadows.size(); i++) { - _render_shadow_pass(p_render_data->render_shadows[directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[directional_shadows[i]].pass, p_render_data->render_shadows[directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info); + _render_shadow_pass(p_render_data->render_shadows[directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[directional_shadows[i]].pass, p_render_data->render_shadows[directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size); } // Render positional shadows (Spotlight and Omnilight with dual-paraboloid). for (uint32_t i = 0; i < shadows.size(); i++) { - _render_shadow_pass(p_render_data->render_shadows[shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[shadows[i]].pass, p_render_data->render_shadows[shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info); + _render_shadow_pass(p_render_data->render_shadows[shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[shadows[i]].pass, p_render_data->render_shadows[shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size); } } } -void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, RenderingMethod::RenderInfo *p_render_info) { +void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size) { GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton(); ERR_FAIL_COND(!light_storage->owns_light_instance(p_light)); @@ -2093,7 +2093,7 @@ void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas, render_data.instances = &p_instances; render_data.render_info = p_render_info; - _setup_environment(&render_data, true, Vector2(1, 1), false, Color(), use_pancake, shadow_bias); + _setup_environment(&render_data, true, p_viewport_size, false, Color(), use_pancake, shadow_bias); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { render_data.screen_mesh_lod_threshold = 0.0; @@ -2271,7 +2271,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ // If we're rendering right-side up, then we need to change the winding order. glFrontFace(GL_CW); } - _render_shadows(&render_data); + _render_shadows(&render_data, screen_size); _setup_lights(&render_data, true, render_data.directional_light_count, render_data.omni_light_count, render_data.spot_light_count, render_data.directional_shadow_count); _setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, flip_y, clear_color, false); @@ -3289,6 +3289,9 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { // Quality settings. use_physical_light_units = GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units"); + positional_soft_shadow_filter_set_quality((RS::ShadowQuality)(int)GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/soft_shadow_filter_quality")); + directional_soft_shadow_filter_set_quality((RS::ShadowQuality)(int)GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality")); + { // Setup Lights diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index da60d571bf..7d3c8896da 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -516,8 +516,8 @@ private: void _setup_lights(const RenderDataGLES3 *p_render_data, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_omni_light_count, uint32_t &r_spot_light_count, uint32_t &r_directional_shadow_count); void _setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows, float p_shadow_bias = 0.0); void _fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append = false); - void _render_shadows(const RenderDataGLES3 *p_render_data); - void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, RenderingMethod::RenderInfo *p_render_info = nullptr); + void _render_shadows(const RenderDataGLES3 *p_render_data, const Size2i &p_viewport_size = Size2i(1, 1)); + void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1)); template <PassMode p_pass_mode> _FORCE_INLINE_ void _render_list_template(RenderListParameters *p_params, const RenderDataGLES3 *p_render_data, uint32_t p_from_element, uint32_t p_to_element, bool p_alpha_pass = false); diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index 3213fa3775..88ee749ed6 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -217,8 +217,23 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) if (new_surface.vertex_data.size()) { glGenBuffers(1, &s->vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer); - GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_surface.vertex_data.size(), new_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer"); - s->vertex_buffer_size = new_surface.vertex_data.size(); + // If we have an uncompressed surface that contains normals, but not tangents, we need to differentiate the array + // from a compressed array in the shader. To do so, we allow the the normal to read 4 components out of the buffer + // But only give it 2 components per normal. So essentially, each vertex reads the next normal in normal.zw. + // This allows us to avoid adding a shader permutation, and avoid passing dummy tangents. Since the stride is kept small + // this should still be a net win for bandwidth. + // If we do this, then the last normal will read past the end of the array. So we need to pad the array with dummy data. + if (!(new_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (new_surface.format & RS::ARRAY_FORMAT_NORMAL) && !(new_surface.format & RS::ARRAY_FORMAT_TANGENT)) { + // Unfortunately, we need to copy the buffer, which is fine as doing a resize triggers a CoW anyway. + Vector<uint8_t> new_vertex_data; + new_vertex_data.resize_zeroed(new_surface.vertex_data.size() + sizeof(uint16_t) * 2); + memcpy(new_vertex_data.ptrw(), new_surface.vertex_data.ptr(), new_surface.vertex_data.size()); + GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_vertex_data.size(), new_vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer"); + s->vertex_buffer_size = new_vertex_data.size(); + } else { + GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_surface.vertex_data.size(), new_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer"); + s->vertex_buffer_size = new_surface.vertex_data.size(); + } } if (new_surface.attribute_data.size()) { @@ -461,6 +476,11 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const { sd.format = s.format; if (s.vertex_buffer != 0) { sd.vertex_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size); + + // When using an uncompressed buffer with normals, but without tangents, we have to trim the padding. + if (!(s.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (s.format & RS::ARRAY_FORMAT_NORMAL) && !(s.format & RS::ARRAY_FORMAT_TANGENT)) { + sd.vertex_data.resize(sd.vertex_data.size() - sizeof(uint16_t) * 2); + } } if (s.attribute_buffer != 0) { diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index b7b62d78a0..fcc1dee3e2 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -713,18 +713,20 @@ void TextureStorage::texture_free(RID p_texture) { memdelete(t->canvas_texture); } - if (t->tex_id != 0) { - if (!t->is_external) { - GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id); + bool must_free_data = false; + if (t->is_proxy) { + if (t->proxy_to.is_valid()) { + Texture *proxy_to = texture_owner.get_or_null(t->proxy_to); + if (proxy_to) { + proxy_to->proxies.erase(p_texture); + } } - t->tex_id = 0; + } else { + must_free_data = t->tex_id != 0 && !t->is_external; } - - if (t->is_proxy && t->proxy_to.is_valid()) { - Texture *proxy_to = texture_owner.get_or_null(t->proxy_to); - if (proxy_to) { - proxy_to->proxies.erase(p_texture); - } + if (must_free_data) { + GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id); + t->tex_id = 0; } texture_atlas_remove_texture(p_texture); |
