summaryrefslogtreecommitdiffstats
path: root/drivers/gles3/storage/texture_storage.cpp
diff options
context:
space:
mode:
authorclayjohn <claynjohn@gmail.com>2023-05-26 18:09:39 -0700
committerRémi Verschelde <rverschelde@gmail.com>2023-06-16 09:10:00 +0200
commit36a005fafcad7be0c22f6402b6475d7bd7024703 (patch)
tree629144fd66ad7d3a13999ea06b4364c10ea366a1 /drivers/gles3/storage/texture_storage.cpp
parent9c41c4ecb6d122792fae2060e2a411ecf6812add (diff)
downloadredot-engine-36a005fafcad7be0c22f6402b6475d7bd7024703.tar.gz
Add RENDERING_INFO parameters to GL Compatibility renderer
This also fixes RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME for the RD renderers as it was incorrectly reporting vertex/index count at times This also adds memory tracking to textures and buffers to catch memory leaks. This also cleans up some memory leaks that the new system caught.
Diffstat (limited to 'drivers/gles3/storage/texture_storage.cpp')
-rw-r--r--drivers/gles3/storage/texture_storage.cpp76
1 files changed, 43 insertions, 33 deletions
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index c4fef89cfd..05b4443963 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -33,6 +33,7 @@
#include "texture_storage.h"
#include "config.h"
#include "drivers/gles3/effects/copy_effects.h"
+#include "utilities.h"
#ifdef ANDROID_ENABLED
#define glFramebufferTextureMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultiviewOVR
@@ -164,6 +165,7 @@ TextureStorage::TextureStorage() {
glBindTexture(GL_TEXTURE_2D, texture.tex_id);
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);
}
{
@@ -185,6 +187,7 @@ TextureStorage::TextureStorage() {
glBindTexture(GL_TEXTURE_2D, texture.tex_id);
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);
}
}
@@ -203,6 +206,7 @@ TextureStorage::TextureStorage() {
glGenTextures(1, &texture_atlas.texture);
glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);
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)");
}
glBindTexture(GL_TEXTURE_2D, 0);
@@ -222,8 +226,9 @@ TextureStorage::~TextureStorage() {
for (int i = 0; i < DEFAULT_GL_TEXTURE_MAX; i++) {
texture_free(default_gl_textures[i]);
}
-
- glDeleteTextures(1, &texture_atlas.texture);
+ if (texture_atlas.texture != 0) {
+ GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
+ }
texture_atlas.texture = 0;
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
texture_atlas.framebuffer = 0;
@@ -706,7 +711,7 @@ void TextureStorage::texture_free(RID p_texture) {
if (t->tex_id != 0) {
if (!t->is_external) {
- glDeleteTextures(1, &t->tex_id);
+ GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);
}
t->tex_id = 0;
}
@@ -743,9 +748,10 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
texture.type = Texture::TYPE_2D;
texture.target = GL_TEXTURE_2D;
_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
- //texture.total_data_size = p_image->get_image_data_size(); // verify that this returns size in bytes
+ texture.total_data_size = p_image->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps);
texture.active = true;
glGenTextures(1, &texture.tex_id);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 2D");
texture_owner.initialize_rid(p_texture, texture);
texture_set_data(p_texture, p_image);
}
@@ -792,8 +798,10 @@ void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<R
texture.target = p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D_ARRAY;
texture.layers = p_layers.size();
_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
+ texture.total_data_size = p_layers[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.layers;
texture.active = true;
glGenTextures(1, &texture.tex_id);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture Layered");
texture_owner.initialize_rid(p_texture, texture);
for (int i = 0; i < p_layers.size(); i++) {
_texture_set_data(p_texture, p_layers[i], i, i == 0);
@@ -850,10 +858,12 @@ RID TextureStorage::texture_create_external(Texture::Type p_type, Image::Format
void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
texture_set_data(p_texture, p_image, p_layer);
-#ifdef TOOLS_ENABLED
+
Texture *tex = texture_owner.get_or_null(p_texture);
ERR_FAIL_COND(!tex);
+ GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);
+#ifdef TOOLS_ENABLED
tex->image_cache_2d.unref();
#endif
}
@@ -1063,7 +1073,7 @@ void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
}
if (tex_to->tex_id) {
- glDeleteTextures(1, &tex_to->tex_id);
+ GLES3::Utilities::get_singleton()->texture_free_data(tex_to->tex_id);
tex_to->tex_id = 0;
}
@@ -1213,15 +1223,11 @@ void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image,
ERR_FAIL_COND(!p_image->get_width());
ERR_FAIL_COND(!p_image->get_height());
- // ERR_FAIL_COND(texture->type == RS::TEXTURE_TYPE_EXTERNAL);
-
GLenum type;
GLenum format;
GLenum internal_format;
bool compressed = false;
- // print_line("texture_set_data width " + itos (p_image->get_width()) + " height " + itos(p_image->get_height()));
-
Image::Format real_format;
Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), real_format, format, internal_format, type, compressed, texture->resize_to_po2);
ERR_FAIL_COND(img.is_null());
@@ -1322,21 +1328,13 @@ void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image,
h = MAX(1, h >> 1);
}
- // info.texture_mem -= texture->total_data_size; // TODO make this work again!!
texture->total_data_size = tsize;
- // info.texture_mem += texture->total_data_size; // TODO make this work again!!
-
- // printf("texture: %i x %i - size: %i - total: %i\n", texture->width, texture->height, tsize, info.texture_mem);
texture->stored_cube_sides |= (1 << p_layer);
texture->mipmaps = mipmaps;
}
-void TextureStorage::texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer) {
- ERR_PRINT("Not implemented yet, sorry :(");
-}
-
Image::Format TextureStorage::texture_get_format(RID p_texture) const {
Texture *texture = texture_owner.get_or_null(p_texture);
@@ -1386,10 +1384,6 @@ void TextureStorage::texture_bind(RID p_texture, uint32_t p_texture_no) {
glBindTexture(texture->target, texture->tex_id);
}
-RID TextureStorage::texture_create_radiance_cubemap(RID p_source, int p_resolution) const {
- return RID();
-}
-
/* TEXTURE ATLAS API */
void TextureStorage::texture_add_to_texture_atlas(RID p_texture) {
@@ -1442,7 +1436,7 @@ void TextureStorage::update_texture_atlas() {
texture_atlas.dirty = false;
if (texture_atlas.texture != 0) {
- glDeleteTextures(1, &texture_atlas.texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
texture_atlas.texture = 0;
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
texture_atlas.framebuffer = 0;
@@ -1559,6 +1553,7 @@ void TextureStorage::update_texture_atlas() {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);
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");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -1576,7 +1571,7 @@ void TextureStorage::update_texture_atlas() {
if (status != GL_FRAMEBUFFER_COMPLETE) {
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
texture_atlas.framebuffer = 0;
- glDeleteTextures(1, &texture_atlas.texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
texture_atlas.texture = 0;
WARN_PRINT("Could not create texture atlas, status: " + get_framebuffer_error(status));
return;
@@ -1702,6 +1697,8 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
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);
+
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->color, rt->size.x * rt->size.y * rt->view_count * 4, "Render target color texture");
}
#ifndef IOS_ENABLED
if (use_multiview) {
@@ -1733,6 +1730,8 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
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);
+
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->depth, rt->size.x * rt->size.y * rt->view_count * 3, "Render target depth texture");
}
#ifndef IOS_ENABLED
if (use_multiview) {
@@ -1747,7 +1746,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
glDeleteFramebuffers(1, &rt->fbo);
- glDeleteTextures(1, &rt->color);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->color);
rt->fbo = 0;
rt->size.x = 0;
rt->size.y = 0;
@@ -1805,8 +1804,10 @@ void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
glGenTextures(1, &rt->backbuffer);
glBindTexture(GL_TEXTURE_2D, rt->backbuffer);
+ uint32_t texture_size_bytes = 0;
for (int l = 0; l < count; l++) {
+ texture_size_bytes += width * height * 4;
glTexImage2D(GL_TEXTURE_2D, l, rt->color_internal_format, width, height, 0, rt->color_format, rt->color_type, nullptr);
width = MAX(1, (width / 2));
height = MAX(1, (height / 2));
@@ -1826,6 +1827,7 @@ void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
return;
}
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, texture_size_bytes, "Render target backbuffer color texture");
// Initialize all levels to opaque Magenta.
for (int j = 0; j < count; j++) {
@@ -1862,7 +1864,7 @@ void GLES3::TextureStorage::copy_scene_to_backbuffer(RenderTarget *rt, const boo
} 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 * 4, "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);
@@ -1885,6 +1887,8 @@ void GLES3::TextureStorage::copy_scene_to_backbuffer(RenderTarget *rt, const boo
} else {
glTexImage2D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
}
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer_depth, rt->size.x * rt->size.y * rt->view_count * 3, "Render target backbuffer depth texture");
+
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);
@@ -1941,7 +1945,7 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
if (rt->overridden.color.is_valid()) {
rt->overridden.color = RID();
} else if (rt->color) {
- glDeleteTextures(1, &rt->color);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->color);
if (rt->texture.is_valid()) {
Texture *tex = get_texture(rt->texture);
tex->tex_id = 0;
@@ -1952,7 +1956,7 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
if (rt->overridden.depth.is_valid()) {
rt->overridden.depth = RID();
} else if (rt->depth) {
- glDeleteTextures(1, &rt->depth);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);
}
rt->depth = 0;
@@ -1961,12 +1965,12 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
if (rt->backbuffer_fbo != 0) {
glDeleteFramebuffers(1, &rt->backbuffer_fbo);
- glDeleteTextures(1, &rt->backbuffer);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer);
rt->backbuffer = 0;
rt->backbuffer_fbo = 0;
}
if (rt->backbuffer_depth != 0) {
- glDeleteTextures(1, &rt->backbuffer_depth);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer_depth);
rt->backbuffer_depth = 0;
}
_render_target_clear_sdf(rt);
@@ -2331,6 +2335,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);
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);
@@ -2371,6 +2376,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
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]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);
@@ -2380,6 +2386,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
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);
@@ -2390,13 +2397,16 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
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) {
if (rt->sdf_texture_write_fb != 0) {
- glDeleteTextures(1, &rt->sdf_texture_read);
- glDeleteTextures(1, &rt->sdf_texture_write);
- glDeleteTextures(2, rt->sdf_texture_process);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_read);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_write);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[0]);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[1]);
+
glDeleteFramebuffers(1, &rt->sdf_texture_write_fb);
rt->sdf_texture_read = 0;
rt->sdf_texture_write = 0;