diff options
Diffstat (limited to 'drivers')
22 files changed, 233 insertions, 86 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 8b6d3e3268..65749323fd 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -933,7 +933,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p int max_processing_layer = sky->mipmap_count; // Update radiance cubemap - if (sky->reflection_dirty && (sky->processing_layer > max_processing_layer || update_single_frame)) { + if (sky->reflection_dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) { static const Vector3 view_normals[6] = { Vector3(+1, 0, 0), Vector3(-1, 0, 0), @@ -1363,38 +1363,25 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const GeometryInstanceSurface *surf = inst->surface_caches; + float lod_distance = 0.0; + + if (p_render_data->cam_orthogonal) { + lod_distance = 1.0; + } else { + Vector3 aabb_min = inst->transformed_aabb.position; + Vector3 aabb_max = inst->transformed_aabb.position + inst->transformed_aabb.size; + Vector3 camera_position = p_render_data->main_cam_transform.origin; + Vector3 surface_distance = Vector3(0.0, 0.0, 0.0).max(aabb_min - camera_position).max(camera_position - aabb_max); + + lod_distance = surface_distance.length(); + } + while (surf) { // LOD if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { - float distance = 0.0; - - // Check if camera is NOT inside the mesh AABB. - if (!inst->transformed_aabb.has_point(p_render_data->main_cam_transform.origin)) { - // Get the LOD support points on the mesh AABB. - Vector3 lod_support_min = inst->transformed_aabb.get_support(p_render_data->main_cam_transform.basis.get_column(Vector3::AXIS_Z)); - Vector3 lod_support_max = inst->transformed_aabb.get_support(-p_render_data->main_cam_transform.basis.get_column(Vector3::AXIS_Z)); - - // Get the distances to those points on the AABB from the camera origin. - float distance_min = (float)p_render_data->main_cam_transform.origin.distance_to(lod_support_min); - float distance_max = (float)p_render_data->main_cam_transform.origin.distance_to(lod_support_max); - - if (distance_min * distance_max < 0.0) { - //crossing plane - distance = 0.0; - } else if (distance_min >= 0.0) { - distance = distance_min; - } else if (distance_max <= 0.0) { - distance = -distance_max; - } - } - - if (p_render_data->cam_orthogonal) { - distance = 1.0; - } - uint32_t indices = 0; - surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, indices); + surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, lod_distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, indices); surf->index_count = indices; if (p_render_data->render_info) { @@ -2565,6 +2552,9 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ glBindTexture(rt->view_count > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D, rt->color); copy_effects->copy_screen(render_data.luminance_multiplier); + + scene_state.enable_gl_depth_test(true); + scene_state.enable_gl_depth_draw(true); } RENDER_TIMESTAMP("Render Opaque Pass"); diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 5a0f394db0..b73debf04a 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -189,6 +189,14 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant } builder.append("\n"); //make sure defines begin at newline + // Optional support for external textures. + if (GLES3::Config::get_singleton()->external_texture_supported) { + builder.append("#extension GL_OES_EGL_image_external : enable\n"); + builder.append("#extension GL_OES_EGL_image_external_essl3 : enable\n"); + } else { + builder.append("#define samplerExternalOES sampler2D\n"); + } + // Insert multiview extension loading, because it needs to appear before // any non-preprocessor code (like the "precision highp..." lines below). builder.append("#ifdef USE_MULTIVIEW\n"); diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index e358230747..76881c8032 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -262,6 +262,8 @@ void main() { color_interp = color; + vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy; + if (use_pixel_snap) { vertex = floor(vertex + 0.5); // precision issue on some hardware creates artifacts within texture @@ -269,8 +271,6 @@ void main() { uv += 1e-5; } - vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy; - vertex_interp = vertex; uv_interp = uv; diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl index f734e4b355..186b630bc8 100644 --- a/drivers/gles3/shaders/sky.glsl +++ b/drivers/gles3/shaders/sky.glsl @@ -212,9 +212,7 @@ void main() { #endif { - #CODE : SKY - } color *= sky_energy_multiplier; diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index d6472c44c1..4947d5d4ce 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -138,6 +138,7 @@ Config::Config() { // These are GLES only rt_msaa_supported = extensions.has("GL_EXT_multisampled_render_to_texture"); rt_msaa_multiview_supported = extensions.has("GL_OVR_multiview_multisampled_render_to_texture"); + external_texture_supported = extensions.has("GL_OES_EGL_image_external_essl3"); if (multiview_supported) { eglFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)eglGetProcAddress("glFramebufferTextureMultiviewOVR"); @@ -166,6 +167,13 @@ Config::Config() { rt_msaa_multiview_supported = false; } } + + if (external_texture_supported) { + eglEGLImageTargetTexture2DOES = (PFNEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES"); + if (eglEGLImageTargetTexture2DOES == nullptr) { + external_texture_supported = false; + } + } #endif force_vertex_shading = false; //GLOBAL_GET("rendering/quality/shading/force_vertex_shading"); diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index ff72fc5b58..1de00094f0 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -45,6 +45,7 @@ typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)(GLenum, GLenum, GLuint, typedef void (*PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean); typedef void (*PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)(GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC)(GLenum, GLenum, GLuint, GLint, GLsizei, GLint, GLsizei); +typedef void (*PFNEGLIMAGETARGETTEXTURE2DOESPROC)(GLenum, void *); #endif namespace GLES3 { @@ -91,6 +92,7 @@ public: bool rt_msaa_supported = false; bool rt_msaa_multiview_supported = false; bool multiview_supported = false; + bool external_texture_supported = false; // Adreno 3XX compatibility bool disable_particles_workaround = false; // set to 'true' to disable 'GPUParticles' @@ -104,6 +106,7 @@ public: PFNGLTEXSTORAGE3DMULTISAMPLEPROC eglTexStorage3DMultisample = nullptr; PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC eglFramebufferTexture2DMultisampleEXT = nullptr; PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC eglFramebufferTextureMultisampleMultiviewOVR = nullptr; + PFNEGLIMAGETARGETTEXTURE2DOESPROC eglEGLImageTargetTexture2DOES = nullptr; #endif static Config *get_singleton() { return singleton; }; diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index aab1aadf02..9b976c2206 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -1521,6 +1521,11 @@ bool LightStorage::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_i uint64_t min_pass = 0; // Pass of the existing one, try to use the least recently used one (LRU fashion). for (int j = 0; j < sc; j++) { + if (sarr[j].owner_is_omni != is_omni) { + // Existing light instance type doesn't match new light instance type skip. + continue; + } + LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner); if (!sli) { // Found a released light instance. diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index a37eba3b15..c29c741c2a 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -348,7 +348,7 @@ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_ } } -_FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector<ShaderLanguage::ConstantNode::Value> &value, uint8_t *data) { +_FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector<ShaderLanguage::Scalar> &value, uint8_t *data) { switch (type) { case ShaderLanguage::TYPE_BOOL: { uint32_t *gui = (uint32_t *)data; @@ -572,7 +572,7 @@ void ShaderData::set_default_texture_parameter(const StringName &p_name, RID p_t Variant ShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; + Vector<ShaderLanguage::Scalar> default_value = uniform.default_value; return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); } return Variant(); @@ -675,6 +675,7 @@ static const GLenum target_from_type[ShaderLanguage::TYPE_MAX] = { GL_TEXTURE_3D, // TYPE_USAMPLER3D, GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBE, GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBEARRAY, + _GL_TEXTURE_EXTERNAL_OES, // TYPE_SAMPLEREXT GL_TEXTURE_2D, // TYPE_STRUCT }; @@ -946,6 +947,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { ERR_PRINT_ONCE("Type: SamplerCubeArray not supported in GL Compatibility rendering backend, please use another type."); } break; + case ShaderLanguage::TYPE_SAMPLEREXT: { + gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_EXT); + } break; case ShaderLanguage::TYPE_ISAMPLER3D: case ShaderLanguage::TYPE_USAMPLER3D: @@ -1949,6 +1953,7 @@ void MaterialStorage::global_shader_parameters_load_settings(bool p_load_texture "sampler2DArray", "sampler3D", "samplerCube", + "samplerExternalOES" }; RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX; @@ -2661,7 +2666,11 @@ static void bind_uniforms_generic(const Vector<RID> &p_textures, const Vector<Sh const ShaderCompiler::GeneratedCode::Texture &texture_uniform = texture_uniforms[texture_uniform_index]; if (texture) { glActiveTexture(GL_TEXTURE0 + texture_offset + ti); - glBindTexture(target_from_type[texture_uniform.type], texture->tex_id); + GLenum target = target_from_type[texture_uniform.type]; + if (target == _GL_TEXTURE_EXTERNAL_OES && !GLES3::Config::get_singleton()->external_texture_supported) { + target = GL_TEXTURE_2D; + } + glBindTexture(target, texture->tex_id); if (texture->render_target) { texture->render_target->used_in_frame = true; } diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index de82d74aff..5058554659 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -1769,14 +1769,14 @@ AABB MeshStorage::_multimesh_get_custom_aabb(RID p_multimesh) const { return multimesh->custom_aabb; } -AABB MeshStorage::_multimesh_get_aabb(RID p_multimesh) const { +AABB MeshStorage::_multimesh_get_aabb(RID p_multimesh) { MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_NULL_V(multimesh, AABB()); if (multimesh->custom_aabb != AABB()) { return multimesh->custom_aabb; } if (multimesh->aabb_dirty) { - const_cast<MeshStorage *>(this)->_update_dirty_multimeshes(); + _update_dirty_multimeshes(); } return multimesh->aabb; } diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h index a2edbb9c48..31858cd372 100644 --- a/drivers/gles3/storage/mesh_storage.h +++ b/drivers/gles3/storage/mesh_storage.h @@ -510,7 +510,7 @@ public: virtual RID _multimesh_get_mesh(RID p_multimesh) const override; virtual void _multimesh_set_custom_aabb(RID p_multimesh, const AABB &p_aabb) override; virtual AABB _multimesh_get_custom_aabb(RID p_multimesh) const override; - virtual AABB _multimesh_get_aabb(RID p_multimesh) const override; + virtual AABB _multimesh_get_aabb(RID p_multimesh) override; virtual Transform3D _multimesh_instance_get_transform(RID p_multimesh, int p_index) const override; virtual Transform2D _multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const override; diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.h b/drivers/gles3/storage/render_scene_buffers_gles3.h index a7a676ad33..9a2912f978 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.h +++ b/drivers/gles3/storage/render_scene_buffers_gles3.h @@ -103,9 +103,9 @@ public: virtual void configure(const RenderSceneBuffersConfiguration *p_config) override; void configure_for_probe(Size2i p_size); - virtual void set_fsr_sharpness(float p_fsr_sharpness) override{}; - virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override{}; - virtual void set_use_debanding(bool p_use_debanding) override{}; + virtual void set_fsr_sharpness(float p_fsr_sharpness) override {} + virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override {} + virtual void set_use_debanding(bool p_use_debanding) override {} void set_apply_color_adjustments_in_post(bool p_apply_in_post); void free_render_buffer_data(); diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 36393dde86..27ba89aa5f 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -153,6 +153,11 @@ TextureStorage::TextureStorage() { } { + default_gl_textures[DEFAULT_GL_TEXTURE_EXT] = texture_allocate(); + texture_external_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_EXT], 1, 1, 0); + } + + { unsigned char pixel_data[4 * 4 * 4]; for (int i = 0; i < 16; i++) { pixel_data[i * 4 + 0] = 0; @@ -729,7 +734,7 @@ void TextureStorage::texture_free(RID p_texture) { } } } else { - must_free_data = t->tex_id != 0 && !t->is_external; + must_free_data = t->tex_id != 0 && !t->is_from_native_handle; } if (must_free_data) { GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id); @@ -769,6 +774,48 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im texture_set_data(p_texture, p_image); } +void TextureStorage::texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) { + Texture texture; + texture.active = true; + texture.alloc_width = texture.width = p_width; + texture.alloc_height = texture.height = p_height; + texture.real_format = texture.format = Image::FORMAT_RGB8; + texture.type = Texture::TYPE_2D; + + if (GLES3::Config::get_singleton()->external_texture_supported) { + texture.target = _GL_TEXTURE_EXTERNAL_OES; + } else { + texture.target = GL_TEXTURE_2D; + } + + glGenTextures(1, &texture.tex_id); + glBindTexture(texture.target, texture.tex_id); + +#ifdef ANDROID_ENABLED + if (texture.target == _GL_TEXTURE_EXTERNAL_OES) { + if (p_external_buffer) { + GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer)); + } + texture.total_data_size = 0; + } else +#endif + { + // If external textures aren't supported, allocate an empty 1x1 texture. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + texture.total_data_size = 3; + } + + glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture External"); + texture_owner.initialize_rid(p_texture, texture); + + glBindTexture(texture.target, 0); +} + void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { ERR_FAIL_COND(p_layers.is_empty()); @@ -874,26 +921,28 @@ void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) { texture_owner.initialize_rid(p_texture, proxy_tex); } -RID TextureStorage::texture_create_external(GLES3::Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) { +RID TextureStorage::texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) { Texture texture; texture.active = true; - texture.is_external = true; - texture.type = p_type; + texture.is_from_native_handle = true; switch (p_type) { - case Texture::TYPE_2D: { + case RS::TEXTURE_TYPE_2D: { + texture.type = Texture::TYPE_2D; texture.target = GL_TEXTURE_2D; } break; - case Texture::TYPE_3D: { + case RS::TEXTURE_TYPE_3D: { + texture.type = Texture::TYPE_3D; texture.target = GL_TEXTURE_3D; } break; - case Texture::TYPE_LAYERED: { + case RS::TEXTURE_TYPE_LAYERED: { + texture.type = Texture::TYPE_LAYERED; texture.target = GL_TEXTURE_2D_ARRAY; } break; } texture.real_format = texture.format = p_format; - texture.tex_id = p_image; + texture.tex_id = p_native_handle; texture.alloc_width = texture.width = p_width; texture.alloc_height = texture.height = p_height; texture.depth = p_depth; @@ -928,6 +977,22 @@ void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> & GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size); } +void TextureStorage::texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_NULL(tex); + + tex->alloc_width = tex->width = p_width; + tex->alloc_height = tex->height = p_height; + +#ifdef ANDROID_ENABLED + if (tex->target == _GL_TEXTURE_EXTERNAL_OES && p_external_buffer) { + glBindTexture(_GL_TEXTURE_EXTERNAL_OES, tex->tex_id); + GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer)); + glBindTexture(_GL_TEXTURE_EXTERNAL_OES, 0); + } +#endif +} + void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_NULL(tex); @@ -1039,7 +1104,7 @@ Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const { data.resize(data_size); ERR_FAIL_COND_V(data.is_empty(), Ref<Image>()); - image = Image::create_from_data(texture->width, texture->height, texture->mipmaps > 1, texture->real_format, data); + image = Image::create_from_data(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1, texture->real_format, data); ERR_FAIL_COND_V(image->is_empty(), Ref<Image>()); if (texture->format != texture->real_format) { image->convert(texture->format); @@ -1095,7 +1160,7 @@ Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const { data.resize(data_size); ERR_FAIL_COND_V(data.is_empty(), Ref<Image>()); - image = Image::create_from_data(texture->width, texture->height, false, Image::FORMAT_RGBA8, data); + image = Image::create_from_data(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data); ERR_FAIL_COND_V(image->is_empty(), Ref<Image>()); if (texture->format != Image::FORMAT_RGBA8) { diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 5569abcc73..2bf8546c0f 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -126,6 +126,7 @@ enum DefaultGLTexture { DEFAULT_GL_TEXTURE_3D_BLACK, DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE, DEFAULT_GL_TEXTURE_2D_UINT, + DEFAULT_GL_TEXTURE_EXT, DEFAULT_GL_TEXTURE_MAX }; @@ -146,7 +147,7 @@ struct Texture { RID self; bool is_proxy = false; - bool is_external = false; + bool is_from_native_handle = false; bool is_render_target = false; RID proxy_to; @@ -209,7 +210,7 @@ struct Texture { void copy_from(const Texture &o) { proxy_to = o.proxy_to; is_proxy = o.is_proxy; - is_external = o.is_external; + is_from_native_handle = o.is_from_native_handle; width = o.width; height = o.height; alloc_width = o.alloc_width; @@ -512,12 +513,14 @@ public: virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override; virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override; virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override; + virtual void texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override; virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent - RID texture_create_external(Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY); + virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) override; virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override; virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override; + virtual void texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override; virtual void texture_proxy_update(RID p_proxy, RID p_base) override; //these two APIs can be used together or in combination with the others. @@ -582,7 +585,7 @@ public: virtual RID decal_allocate() override; virtual void decal_initialize(RID p_rid) override; - virtual void decal_free(RID p_rid) override{}; + virtual void decal_free(RID p_rid) override {} virtual void decal_set_size(RID p_decal, const Vector3 &p_size) override; virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override; diff --git a/drivers/metal/metal_objects.h b/drivers/metal/metal_objects.h index 97f33bb1e8..030b353ee8 100644 --- a/drivers/metal/metal_objects.h +++ b/drivers/metal/metal_objects.h @@ -318,6 +318,13 @@ public: dirty.set_flag(DirtyFlag::DIRTY_UNIFORMS); } + _FORCE_INLINE_ void mark_blend_dirty() { + if (!blend_constants.has_value()) { + return; + } + dirty.set_flag(DirtyFlag::DIRTY_BLEND); + } + MTLScissorRect clip_to_render_area(MTLScissorRect p_rect) const { uint32_t raLeft = render_area.position.x; uint32_t raRight = raLeft + render_area.size.width; diff --git a/drivers/metal/metal_objects.mm b/drivers/metal/metal_objects.mm index abdcccf00c..1d08a10781 100644 --- a/drivers/metal/metal_objects.mm +++ b/drivers/metal/metal_objects.mm @@ -143,6 +143,9 @@ void MDCommandBuffer::bind_pipeline(RDD::PipelineID p_pipeline) { if (render.pipeline != nullptr && render.pipeline->depth_stencil != rp->depth_stencil) { render.dirty.set_flag(RenderState::DIRTY_DEPTH); } + if (rp->raster_state.blend.enabled) { + render.dirty.set_flag(RenderState::DIRTY_BLEND); + } render.pipeline = rp; } } else if (p->type == MDPipelineType::Compute) { @@ -301,6 +304,7 @@ void MDCommandBuffer::render_clear_attachments(VectorView<RDD::AttachmentClear> render.mark_viewport_dirty(); render.mark_scissors_dirty(); render.mark_vertex_dirty(); + render.mark_blend_dirty(); } void MDCommandBuffer::_render_set_dirty_state() { @@ -560,10 +564,10 @@ void MDCommandBuffer::_render_clear_render_area() { } } uint32_t ds_index = subpass.depth_stencil_reference.attachment; - MDAttachment const &attachment = pass.attachments[ds_index]; - bool shouldClearDepth = (ds_index != RDD::AttachmentReference::UNUSED && attachment.shouldClear(subpass, false)); - bool shouldClearStencil = (ds_index != RDD::AttachmentReference::UNUSED && attachment.shouldClear(subpass, true)); + bool shouldClearDepth = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, false)); + bool shouldClearStencil = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, true)); if (shouldClearDepth || shouldClearStencil) { + MDAttachment const &attachment = pass.attachments[ds_index]; BitField<RDD::TextureAspectBits> bits; if (shouldClearDepth && attachment.type & MDAttachmentType::Depth) { bits.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT); diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 489181a025..e4bad88083 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -419,6 +419,9 @@ Error DirAccessUnix::remove(String p_path) { } p_path = fix_path(p_path); + if (p_path.ends_with("/")) { + p_path = p_path.left(-1); + } struct stat flags = {}; if ((stat(p_path.utf8().get_data(), &flags) != 0)) { @@ -438,6 +441,9 @@ bool DirAccessUnix::is_link(String p_file) { } p_file = fix_path(p_file); + if (p_file.ends_with("/")) { + p_file = p_file.left(-1); + } struct stat flags = {}; if ((lstat(p_file.utf8().get_data(), &flags) != 0)) { @@ -453,6 +459,9 @@ String DirAccessUnix::read_link(String p_file) { } p_file = fix_path(p_file); + if (p_file.ends_with("/")) { + p_file = p_file.left(-1); + } char buf[256]; memset(buf, 0, 256); diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index 1e52b39be1..5caa33100e 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -67,6 +67,7 @@ #define SOCK_BUF(x) x #define SOCK_CBUF(x) x #define SOCK_IOCTL ioctl +#define SOCK_FIONREAD_LEN_TYPE int #define SOCK_CLOSE ::close #define SOCK_CONNECT(p_sock, p_addr, p_addr_len) ::connect(p_sock, p_addr, p_addr_len) @@ -81,6 +82,7 @@ #define SOCK_BUF(x) (char *)(x) #define SOCK_CBUF(x) (const char *)(x) #define SOCK_IOCTL ioctlsocket +#define SOCK_FIONREAD_LEN_TYPE unsigned long #define SOCK_CLOSE closesocket // connect is broken on windows under certain conditions, reasons unknown: // See https://github.com/godotengine/webrtc-native/issues/6 @@ -742,7 +744,7 @@ bool NetSocketPosix::is_open() const { int NetSocketPosix::get_available_bytes() const { ERR_FAIL_COND_V(!is_open(), -1); - unsigned long len; + SOCK_FIONREAD_LEN_TYPE len; int ret = SOCK_IOCTL(_sock, FIONREAD, &len); if (ret == -1) { _get_socket_error(); diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index 4ea46e8214..bd395f41e2 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -1772,16 +1772,17 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_from_extension(uint64 tex_info->vk_view = vk_image_view; tex_info->rd_format = p_format; tex_info->vk_view_create_info = image_view_create_info; - +#ifdef DEBUG_ENABLED + tex_info->created_from_extension = true; +#endif return TextureID(tex_info); } RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared(TextureID p_original_texture, const TextureView &p_view) { const TextureInfo *owner_tex_info = (const TextureInfo *)p_original_texture.id; #ifdef DEBUG_ENABLED - ERR_FAIL_COND_V(!owner_tex_info->allocation.handle, TextureID()); + ERR_FAIL_COND_V(!owner_tex_info->allocation.handle && !owner_tex_info->created_from_extension, TextureID()); #endif - VkImageViewCreateInfo image_view_create_info = owner_tex_info->vk_view_create_info; image_view_create_info.format = RD_TO_VK_FORMAT[p_view.format]; image_view_create_info.components.r = (VkComponentSwizzle)p_view.swizzle_r; @@ -1837,7 +1838,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared(TextureID p_or RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) { const TextureInfo *owner_tex_info = (const TextureInfo *)p_original_texture.id; #ifdef DEBUG_ENABLED - ERR_FAIL_COND_V(!owner_tex_info->allocation.handle, TextureID()); + ERR_FAIL_COND_V(!owner_tex_info->allocation.handle && !owner_tex_info->created_from_extension, TextureID()); #endif VkImageViewCreateInfo image_view_create_info = owner_tex_info->vk_view_create_info; diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h index 2615d9824d..81f4256941 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.h +++ b/drivers/vulkan/rendering_device_driver_vulkan.h @@ -213,6 +213,9 @@ public: VmaAllocation handle = nullptr; VmaAllocationInfo info = {}; } allocation; // All 0/null if just a view. +#ifdef DEBUG_ENABLED + bool created_from_extension = false; +#endif }; VkSampleCountFlagBits _ensure_supported_sample_count(TextureSamples p_requested_sample_count); diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index a349a66f75..4e7c9695a5 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -39,6 +39,9 @@ #include <functiondiscoverykeys.h> +#include <wrl/client.h> +using Microsoft::WRL::ComPtr; + // Define IAudioClient3 if not already defined by MinGW headers #if defined __MINGW32__ || defined __MINGW64__ @@ -107,6 +110,12 @@ const IID IID_IAudioClient3 = __uuidof(IAudioClient3); const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient); const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient); +#define SAFE_RELEASE(memory) \ + if ((memory) != nullptr) { \ + (memory)->Release(); \ + (memory) = nullptr; \ + } + #define REFTIMES_PER_SEC 10000000 #define REFTIMES_PER_MILLISEC 10000 @@ -302,7 +311,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i audioProps.bIsOffload = FALSE; audioProps.eCategory = AudioCategory_GameEffects; - hr = ((IAudioClient3 *)p_device->audio_client.Get())->SetClientProperties(&audioProps); + hr = ((IAudioClient3 *)p_device->audio_client)->SetClientProperties(&audioProps); ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: SetClientProperties failed with error 0x" + String::num_uint64(hr, 16) + "."); } @@ -385,7 +394,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i } } else { - IAudioClient3 *device_audio_client_3 = (IAudioClient3 *)p_device->audio_client.Get(); + IAudioClient3 *device_audio_client_3 = (IAudioClient3 *)p_device->audio_client; // AUDCLNT_STREAMFLAGS_RATEADJUST is an invalid flag with IAudioClient3, therefore we have to use // the closest supported mix rate supported by the audio driver. @@ -516,9 +525,9 @@ Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) { p_device->active.clear(); } - p_device->audio_client.Reset(); - p_device->render_client.Reset(); - p_device->capture_client.Reset(); + SAFE_RELEASE(p_device->audio_client) + SAFE_RELEASE(p_device->render_client) + SAFE_RELEASE(p_device->capture_client) return OK; } diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index d73cbf4a8a..367c30607a 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -40,18 +40,15 @@ #include <audioclient.h> #include <mmdeviceapi.h> -#include <wrl/client.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> -using Microsoft::WRL::ComPtr; - class AudioDriverWASAPI : public AudioDriver { class AudioDeviceWASAPI { public: - ComPtr<IAudioClient> audio_client = nullptr; - ComPtr<IAudioRenderClient> render_client = nullptr; // Output - ComPtr<IAudioCaptureClient> capture_client = nullptr; // Input + IAudioClient *audio_client = nullptr; + IAudioRenderClient *render_client = nullptr; // Output + IAudioCaptureClient *capture_client = nullptr; // Input SafeFlag active; WORD format_tag = 0; diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 0243d863f8..9d6aa13332 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -118,11 +118,12 @@ Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) { return ERR_INVALID_PARAMETER; } - struct _stat st; - if (_wstat((LPCWSTR)(path.utf16().get_data()), &st) == 0) { - if (!S_ISREG(st.st_mode)) { - return ERR_FILE_CANT_OPEN; - } + if (path.ends_with(":\\") || path.ends_with(":")) { + return ERR_FILE_CANT_OPEN; + } + DWORD file_attr = GetFileAttributesW((LPCWSTR)(path.utf16().get_data())); + if (file_attr != INVALID_FILE_ATTRIBUTES && (file_attr & FILE_ATTRIBUTE_DIRECTORY)) { + return ERR_FILE_CANT_OPEN; } #ifdef TOOLS_ENABLED @@ -412,15 +413,40 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) { file = file.substr(0, file.length() - 1); } - struct _stat st; - int rv = _wstat((LPCWSTR)(file.utf16().get_data()), &st); + HANDLE handle = CreateFileW((LPCWSTR)(file.utf16().get_data()), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); - if (rv == 0) { - return st.st_mtime; - } else { - print_verbose("Failed to get modified time for: " + p_file + ""); - return 0; + if (handle != INVALID_HANDLE_VALUE) { + FILETIME ft_create, ft_write; + + bool status = GetFileTime(handle, &ft_create, nullptr, &ft_write); + + CloseHandle(handle); + + if (status) { + uint64_t ret = 0; + + // If write time is invalid, fallback to creation time. + if (ft_write.dwHighDateTime == 0 && ft_write.dwLowDateTime == 0) { + ret = ft_create.dwHighDateTime; + ret <<= 32; + ret |= ft_create.dwLowDateTime; + } else { + ret = ft_write.dwHighDateTime; + ret <<= 32; + ret |= ft_write.dwLowDateTime; + } + + const uint64_t WINDOWS_TICKS_PER_SECOND = 10000000; + const uint64_t TICKS_TO_UNIX_EPOCH = 116444736000000000LL; + + if (ret >= TICKS_TO_UNIX_EPOCH) { + return (ret - TICKS_TO_UNIX_EPOCH) / WINDOWS_TICKS_PER_SECOND; + } + } } + + print_verbose("Failed to get modified time for: " + p_file); + return 0; } BitField<FileAccess::UnixPermissionFlags> FileAccessWindows::_get_unix_permissions(const String &p_file) { |
