diff --git a/drivers/gles3/effects/copy_effects.cpp b/drivers/gles3/effects/copy_effects.cpp index 47ca832bd7ab..257b17a717d5 100644 --- a/drivers/gles3/effects/copy_effects.cpp +++ b/drivers/gles3/effects/copy_effects.cpp @@ -241,7 +241,6 @@ void CopyEffects::gaussian_blur(GLuint p_source_texture, int p_mipmap_count, con base_size.x >>= 1; base_size.y >>= 1; - glBindTexture(GL_TEXTURE_2D, p_source_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, i - 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i - 1); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_source_texture, i); @@ -275,10 +274,11 @@ void CopyEffects::gaussian_blur(GLuint p_source_texture, int p_mipmap_count, con glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); glDeleteFramebuffers(1, &framebuffer); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, p_mipmap_count - 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glViewport(0, 0, p_size.x, p_size.y); diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index b9206f310e8b..dbf8f94844d7 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1847,6 +1847,9 @@ void RasterizerCanvasGLES3::_update_shadow_atlas() { glGenTextures(1, &state.shadow_texture); glBindTexture(GL_TEXTURE_2D, state.shadow_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + if (config->float_texture_supported) { glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, state.shadow_texture_size, data.max_lights_per_render * 2, 0, GL_RED, GL_FLOAT, nullptr); } else { @@ -1857,8 +1860,6 @@ void RasterizerCanvasGLES3::_update_shadow_atlas() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, state.shadow_texture, 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 3ed8042f3f77..3aa9fac81b2d 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -556,6 +556,9 @@ GLuint _init_radiance_texture(int p_size, int p_mipmaps, String p_name) { glGenTextures(1, &radiance_id); glBindTexture(GL_TEXTURE_CUBE_MAP, radiance_id); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, p_mipmaps - 1); + #ifdef GL_API_ENABLED if (RasterizerGLES3::is_gles_over_gl()) { //TODO, on low-end compare this to allocating each face of each mip individually @@ -576,8 +579,6 @@ GLuint _init_radiance_texture(int p_size, int p_mipmaps, String p_name) { glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, p_mipmaps - 1); GLES3::Utilities::get_singleton()->texture_allocated_data(radiance_id, Image::get_image_data_size(p_size, p_size, Image::FORMAT_RGBA8, true), p_name); return radiance_id; @@ -588,7 +589,8 @@ void RasterizerSceneGLES3::_update_dirty_skys() { while (sky) { if (sky->radiance == 0) { - sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) - 1; + // Limit mipmaps so smallest is 4x4 for optimization + sky->mipmap_count = MAX(1, Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) - 1); // Left uninitialized, will attach a texture at render time glGenFramebuffers(1, &sky->radiance_framebuffer); sky->radiance = _init_radiance_texture(sky->radiance_size, sky->mipmap_count, "Sky radiance texture"); @@ -1023,6 +1025,9 @@ Ref RasterizerSceneGLES3::sky_bake_panorama(RID p_sky, float p_energy, bo GLuint rad_tex = 0; glGenTextures(1, &rad_tex); glBindTexture(GL_TEXTURE_2D, rad_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + if (config->float_texture_supported) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_size.width, p_size.height, 0, GL_RGBA, GL_FLOAT, nullptr); GLES3::Utilities::get_singleton()->texture_allocated_data(rad_tex, p_size.width * p_size.height * 16, "Temp sky panorama"); @@ -3885,19 +3890,27 @@ TypedArray RasterizerSceneGLES3::bake_render_uv2(RID p_base, const TypedA glGenTextures(1, &depth_tex); glBindTexture(GL_TEXTURE_2D, albedo_alpha_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); GLES3::Utilities::get_singleton()->texture_allocated_data(albedo_alpha_tex, p_image_size.width * p_image_size.height * 4, "Lightmap albedo texture"); glBindTexture(GL_TEXTURE_2D, normal_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); GLES3::Utilities::get_singleton()->texture_allocated_data(normal_tex, p_image_size.width * p_image_size.height * 4, "Lightmap normal texture"); glBindTexture(GL_TEXTURE_2D, orm_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); GLES3::Utilities::get_singleton()->texture_allocated_data(orm_tex, p_image_size.width * p_image_size.height * 4, "Lightmap ORM texture"); // Consider rendering to RGBA8 encoded as RGBE, then manually convert to RGBAH on CPU. glBindTexture(GL_TEXTURE_2D, emission_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); if (config->float_texture_supported) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_FLOAT, nullptr); GLES3::Utilities::get_singleton()->texture_allocated_data(emission_tex, p_image_size.width * p_image_size.height * 16, "Lightmap emission texture"); @@ -3908,6 +3921,8 @@ TypedArray RasterizerSceneGLES3::bake_render_uv2(RID p_base, const TypedA } glBindTexture(GL_TEXTURE_2D, depth_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, p_image_size.width, p_image_size.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); GLES3::Utilities::get_singleton()->texture_allocated_data(depth_tex, p_image_size.width * p_image_size.height * 3, "Lightmap depth texture"); diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index aab1aadf02d3..12c081d3d808 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -799,7 +799,8 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ if (atlas->depth == 0) { // We need to create our textures - atlas->mipmap_count = Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) - 1; + // Limit mipmaps so smallest is 4x4 for optimization + atlas->mipmap_count = MAX(1, Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) - 1); atlas->mipmap_count = MIN(atlas->mipmap_count, 8); // No more than 8 please.. glActiveTexture(GL_TEXTURE0); @@ -808,6 +809,8 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ // We create one set of 6 layers for depth, we can reuse this when rendering. glGenTextures(1, &atlas->depth); glBindTexture(GL_TEXTURE_2D_ARRAY, atlas->depth); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, atlas->size, atlas->size, 6, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); @@ -822,6 +825,8 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ GLuint color = 0; glGenTextures(1, &color); glBindTexture(GL_TEXTURE_CUBE_MAP, color); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, atlas->mipmap_count - 1); atlas->reflections.write[i].color = color; #ifdef GL_API_ENABLED @@ -842,8 +847,6 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, atlas->mipmap_count - 1); // Setup sizes and calculate how much memory we're using. int mipmap_size = atlas->size; @@ -860,6 +863,8 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ GLuint radiance = 0; glGenTextures(1, &radiance); glBindTexture(GL_TEXTURE_CUBE_MAP, radiance); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, atlas->mipmap_count - 1); atlas->reflections.write[i].radiance = radiance; #ifdef GL_API_ENABLED @@ -880,8 +885,6 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, atlas->mipmap_count - 1); // Same data size as our color buffer GLES3::Utilities::get_singleton()->texture_allocated_data(radiance, data_size, String("Reflection probe atlas (") + String::num_int64(i) + String(", radiance)")); @@ -1466,6 +1469,9 @@ bool LightStorage::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_i if (is_omni) { glBindTexture(GL_TEXTURE_CUBE_MAP, texture_id); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0); + for (int id = 0; id < 6; id++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + id, 0, format, size / 2, size / 2, 0, GL_DEPTH_COMPONENT, type, nullptr); } @@ -1491,6 +1497,8 @@ bool LightStorage::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_i glBindTexture(GL_TEXTURE_CUBE_MAP, 0); } else { glBindTexture(GL_TEXTURE_2D, texture_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, GL_DEPTH_COMPONENT, type, nullptr); @@ -1578,6 +1586,8 @@ void LightStorage::update_directional_shadow_atlas() { glGenTextures(1, &directional_shadow.depth); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, directional_shadow.depth); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); GLenum format = directional_shadow.use_16_bits ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24; GLenum type = directional_shadow.use_16_bits ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h index ed00dd235f36..675b10ecb4be 100644 --- a/drivers/gles3/storage/light_storage.h +++ b/drivers/gles3/storage/light_storage.h @@ -804,6 +804,8 @@ class LightStorage : public RendererLightStorage { glGenTextures(1, &atlas->debug_texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, atlas->debug_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, atlas->size, atlas->size, 0, GL_RED, GL_UNSIGNED_INT, nullptr); diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index de82d74aff3f..b408dcb7adb4 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -2193,7 +2193,11 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_ skeleton->data.resize(256 * skeleton->height * 4); glGenTextures(1, &skeleton->transforms_texture); glBindTexture(GL_TEXTURE_2D, skeleton->transforms_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, skeleton->height, 0, GL_RGBA, GL_FLOAT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -2324,6 +2328,8 @@ void MeshStorage::_update_dirty_skeletons() { if (skeleton->size) { glBindTexture(GL_TEXTURE_2D, skeleton->transforms_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, skeleton->height, 0, GL_RGBA, GL_FLOAT, skeleton->data.ptr()); glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp index b60068128091..2a9878edac4d 100644 --- a/drivers/gles3/storage/particles_storage.cpp +++ b/drivers/gles3/storage/particles_storage.cpp @@ -1249,12 +1249,13 @@ GLuint ParticlesStorage::particles_collision_get_heightfield_framebuffer(RID p_p glGenTextures(1, &particles_collision->heightfield_texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, particles_collision->heightfield_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.cpp b/drivers/gles3/storage/render_scene_buffers_gles3.cpp index c91547d2b166..d6c134da8823 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.cpp +++ b/drivers/gles3/storage/render_scene_buffers_gles3.cpp @@ -210,6 +210,8 @@ void RenderSceneBuffersGLES3::_check_render_buffers() { // Create our color buffer. glGenTextures(1, &internal3d.color); glBindTexture(texture_target, internal3d.color); + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, 0); if (use_multiview) { glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr); @@ -227,6 +229,8 @@ void RenderSceneBuffersGLES3::_check_render_buffers() { // Create our depth buffer. glGenTextures(1, &internal3d.depth); glBindTexture(texture_target, internal3d.depth); + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, 0); if (use_multiview) { glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); @@ -478,6 +482,8 @@ void RenderSceneBuffersGLES3::check_backbuffer(bool p_need_color, bool p_need_de if (backbuffer3d.color == 0 && p_need_color) { glGenTextures(1, &backbuffer3d.color); glBindTexture(texture_target, backbuffer3d.color); + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, 0); if (use_multiview) { glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr); @@ -506,6 +512,8 @@ void RenderSceneBuffersGLES3::check_backbuffer(bool p_need_color, bool p_need_de if (backbuffer3d.depth == 0 && p_need_depth) { glGenTextures(1, &backbuffer3d.depth); glBindTexture(texture_target, backbuffer3d.depth); + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, 0); if (use_multiview) { glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); @@ -579,6 +587,8 @@ void RenderSceneBuffersGLES3::check_glow_buffers() { glGenTextures(1, &glow.levels[i].color); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, glow.levels[i].color); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, level_size.x, level_size.y, 0, color_format, color_type, nullptr); @@ -587,9 +597,6 @@ void RenderSceneBuffersGLES3::check_glow_buffers() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - GLES3::Utilities::get_singleton()->texture_allocated_data(glow.levels[i].color, level_size.x * level_size.y * color_format_size, String("Glow buffer ") + String::num_int64(i)); // Create our FBO diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 36393dde8693..d06c99ce2723 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -171,8 +171,10 @@ TextureStorage::TextureStorage() { texture.active = true; glGenTextures(1, &texture.tex_id); texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT], texture); - glBindTexture(GL_TEXTURE_2D, texture.tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 4, 4, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixel_data); GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 4, "Default uint texture"); texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST); @@ -193,8 +195,10 @@ TextureStorage::TextureStorage() { texture.active = true; glGenTextures(1, &texture.tex_id); texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH], texture); - glBindTexture(GL_TEXTURE_2D, texture.tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 4, 4, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixel_data); GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 2, "Default depth texture"); texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST); @@ -214,6 +218,9 @@ TextureStorage::TextureStorage() { glGenTextures(1, &texture_atlas.texture); glBindTexture(GL_TEXTURE_2D, texture_atlas.texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data); GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, 4 * 4 * 4, "Texture atlas (Default)"); } @@ -1065,6 +1072,8 @@ Ref TextureStorage::texture_2d_get(RID p_texture) const { glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer); glBindTexture(GL_TEXTURE_2D, temp_color_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -1137,6 +1146,8 @@ Ref TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) cons glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer); glBindTexture(GL_TEXTURE_2D, temp_color_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -1246,6 +1257,8 @@ Vector> TextureStorage::texture_3d_get(RID p_texture) const { glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer); glBindTexture(GL_TEXTURE_2D, temp_color_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -1489,6 +1502,8 @@ void TextureStorage::_texture_set_data(RID p_texture, const Ref &p_image, _texture_set_swizzle(texture, real_format); int mipmaps = img->has_mipmaps() ? img->get_mipmap_count() + 1 : 1; + glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1); // Set filtering and repeat state to default. if (mipmaps > 1) { @@ -1620,6 +1635,8 @@ void TextureStorage::_texture_set_3d_data(RID p_texture, const Vector texture->total_data_size = all_data_size; texture->mipmaps = mipmap_level + 1; + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, texture->mipmaps - 1); #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) { @@ -1905,6 +1922,9 @@ void TextureStorage::update_texture_atlas() { glGenTextures(1, &texture_atlas.texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture_atlas.texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture_atlas.size.width, texture_atlas.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, texture_atlas.size.width * texture_atlas.size.height * 4, "Texture atlas"); @@ -1912,8 +1932,6 @@ void TextureStorage::update_texture_atlas() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glGenFramebuffers(1, &texture_atlas.framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, texture_atlas.framebuffer); @@ -2054,6 +2072,8 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { glGenTextures(1, &rt->color); glBindTexture(texture_target, rt->color); + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, 0); if (use_multiview) { glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr); @@ -2085,6 +2105,8 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { } else { glGenTextures(1, &rt->depth); glBindTexture(texture_target, rt->depth); + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, 0); if (use_multiview) { glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); @@ -2175,6 +2197,8 @@ void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) { glGenTextures(1, &rt->backbuffer); glBindTexture(GL_TEXTURE_2D, rt->backbuffer); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1); uint32_t texture_size_bytes = 0; for (int l = 0; l < count; l++) { @@ -2184,9 +2208,6 @@ void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) { height = MAX(1, (height / 2)); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1); - glGenFramebuffers(1, &rt->backbuffer_fbo); glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo); @@ -2230,16 +2251,21 @@ void GLES3::TextureStorage::check_backbuffer(RenderTarget *rt, const bool uses_s if (rt->backbuffer == 0 && uses_screen_texture) { glGenTextures(1, &rt->backbuffer); glBindTexture(texture_target, rt->backbuffer); + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, 0); + if (use_multiview) { glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr); } else { glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr); } GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, rt->size.x * rt->size.y * rt->view_count * rt->color_format_size, "Render target backbuffer color texture (3D)"); + glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + #ifndef IOS_ENABLED if (use_multiview) { glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->backbuffer, 0, 0, rt->view_count); @@ -2253,6 +2279,9 @@ void GLES3::TextureStorage::check_backbuffer(RenderTarget *rt, const bool uses_s if (rt->backbuffer_depth == 0 && uses_depth_texture) { glGenTextures(1, &rt->backbuffer_depth); glBindTexture(texture_target, rt->backbuffer_depth); + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, 0); + if (use_multiview) { glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); } else { @@ -2809,12 +2838,14 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) { glGenTextures(1, &rt->sdf_texture_write); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size.width, size.height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr); GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_write, size.width * size.height, "SDF texture"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -2844,35 +2875,42 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) { glGenTextures(2, rt->sdf_texture_process); glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr); + GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[0], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[0]"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[0], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[0]"); glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[1]); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr); + GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[1], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[1]"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[1], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[1]"); glGenTextures(1, &rt->sdf_texture_read); glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_read); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->process_size.width, rt->process_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_read, rt->process_size.width * rt->process_size.height * 4, "SDF texture (read)"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_read, rt->process_size.width * rt->process_size.height * 4, "SDF texture (read)"); } void TextureStorage::_render_target_clear_sdf(RenderTarget *rt) { diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 5569abcc7326..2b2bb40fc5bb 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -245,18 +245,15 @@ struct Texture { state_filter = p_filter; GLenum pmin = GL_NEAREST; GLenum pmag = GL_NEAREST; - GLint max_lod = 0; GLfloat anisotropy = 1.0f; switch (state_filter) { case RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST: { pmin = GL_NEAREST; pmag = GL_NEAREST; - max_lod = 0; } break; case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR: { pmin = GL_LINEAR; pmag = GL_LINEAR; - max_lod = 0; } break; case RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: { anisotropy = config->anisotropic_level; @@ -264,15 +261,10 @@ struct Texture { [[fallthrough]]; case RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: { pmag = GL_NEAREST; - if (mipmaps <= 1) { - pmin = GL_NEAREST; - max_lod = 0; - } else if (config->use_nearest_mip_filter) { + if (config->use_nearest_mip_filter) { pmin = GL_NEAREST_MIPMAP_NEAREST; - max_lod = 1000; } else { pmin = GL_NEAREST_MIPMAP_LINEAR; - max_lod = 1000; } } break; case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: { @@ -281,15 +273,10 @@ struct Texture { [[fallthrough]]; case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: { pmag = GL_LINEAR; - if (mipmaps <= 1) { - pmin = GL_LINEAR; - max_lod = 0; - } else if (config->use_nearest_mip_filter) { + if (config->use_nearest_mip_filter) { pmin = GL_LINEAR_MIPMAP_NEAREST; - max_lod = 1000; } else { pmin = GL_LINEAR_MIPMAP_LINEAR; - max_lod = 1000; } } break; default: { @@ -298,8 +285,6 @@ struct Texture { } glTexParameteri(target, GL_TEXTURE_MIN_FILTER, pmin); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, pmag); - glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, max_lod); if (config->support_anisotropic_filter) { glTexParameterf(target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); }