summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--doc/classes/RenderingServer.xml8
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp59
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp122
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h1
-rw-r--r--drivers/gles3/storage/light_storage.cpp100
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp46
-rw-r--r--drivers/gles3/storage/particles_storage.cpp44
-rw-r--r--drivers/gles3/storage/texture_storage.cpp76
-rw-r--r--drivers/gles3/storage/texture_storage.h4
-rw-r--r--drivers/gles3/storage/utilities.cpp38
-rw-r--r--drivers/gles3/storage/utilities.h64
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp2
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp4
-rw-r--r--servers/rendering/renderer_viewport.cpp2
-rw-r--r--servers/rendering/renderer_viewport.h2
-rw-r--r--servers/rendering/rendering_server_default.cpp2
17 files changed, 336 insertions, 242 deletions
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 6b65302a7d..0f2a6d649f 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -4575,7 +4575,7 @@
Number of objects drawn in a single frame.
</constant>
<constant name="VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME" value="1" enum="ViewportRenderInfo">
- Number of vertices drawn in a single frame.
+ Number of points, lines, or triangles drawn in a single frame.
</constant>
<constant name="VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME" value="2" enum="ViewportRenderInfo">
Number of draw calls during this frame.
@@ -5201,7 +5201,7 @@
Number of objects rendered in the current 3D scene. This varies depending on camera position and rotation.
</constant>
<constant name="RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME" value="1" enum="RenderingInfo">
- Number of vertices/indices rendered in the current 3D scene. This varies depending on camera position and rotation.
+ Number of points, lines, or triangles rendered in the current 3D scene. This varies depending on camera position and rotation.
</constant>
<constant name="RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME" value="2" enum="RenderingInfo">
Number of draw calls performed to render in the current 3D scene. This varies depending on camera position and rotation.
@@ -5210,10 +5210,10 @@
Texture memory used (in bytes).
</constant>
<constant name="RENDERING_INFO_BUFFER_MEM_USED" value="4" enum="RenderingInfo">
- Buffer memory used (in bytes).
+ Buffer memory used (in bytes). This includes vertex data, uniform buffers, and many miscellaneous buffer types used internally.
</constant>
<constant name="RENDERING_INFO_VIDEO_MEM_USED" value="5" enum="RenderingInfo">
- Video memory used (in bytes). This is always greater than the sum of [constant RENDERING_INFO_TEXTURE_MEM_USED] and [constant RENDERING_INFO_BUFFER_MEM_USED], since there is miscellaneous data not accounted for by those two metrics.
+ Video memory used (in bytes). When using the Forward+ or mobile rendering backends, this is always greater than the sum of [constant RENDERING_INFO_TEXTURE_MEM_USED] and [constant RENDERING_INFO_BUFFER_MEM_USED], since there is miscellaneous data not accounted for by those two metrics. When using the GL Compatibility backend, this is equal to the sum of [constant RENDERING_INFO_TEXTURE_MEM_USED] and [constant RENDERING_INFO_BUFFER_MEM_USED].
</constant>
<constant name="FEATURE_SHADERS" value="0" enum="Features">
Hardware supports shaders. This enum is currently unused in Godot 3.x.
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 59a65b4538..86405fa3f0 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1790,6 +1790,7 @@ void RasterizerCanvasGLES3::_update_shadow_atlas() {
state.shadow_depth_buffer = 0;
WARN_PRINT("Could not create CanvasItem shadow atlas, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
}
+ GLES3::Utilities::get_singleton()->texture_allocated_data(state.shadow_texture, state.shadow_texture_size * data.max_lights_per_render * 2 * 4, "2D shadow atlas texture");
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
}
}
@@ -1894,8 +1895,8 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
if (oc->line_point_count != lines.size() && oc->vertex_array != 0) {
glDeleteVertexArrays(1, &oc->vertex_array);
- glDeleteBuffers(1, &oc->vertex_buffer);
- glDeleteBuffers(1, &oc->index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(oc->vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(oc->index_buffer);
oc->vertex_array = 0;
oc->vertex_buffer = 0;
@@ -1954,13 +1955,15 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
glGenBuffers(1, &oc->vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, oc->vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(float), geometry.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, oc->vertex_buffer, lc * 6 * sizeof(float), geometry.ptr(), GL_STATIC_DRAW, "Occluder polygon vertex buffer");
+
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
glVertexAttribPointer(RS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glGenBuffers(1, &oc->index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oc->index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * lc * sizeof(uint16_t), indices.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, oc->index_buffer, 3 * lc * sizeof(uint16_t), indices.ptr(), GL_STATIC_DRAW, "Occluder polygon index buffer");
+
glBindVertexArray(0);
} else {
glBindBuffer(GL_ARRAY_BUFFER, oc->vertex_buffer);
@@ -1995,8 +1998,8 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
if (oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size() && oc->sdf_vertex_array != 0) {
glDeleteVertexArrays(1, &oc->sdf_vertex_array);
- glDeleteBuffers(1, &oc->sdf_vertex_buffer);
- glDeleteBuffers(1, &oc->sdf_index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(oc->sdf_vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(oc->sdf_index_buffer);
oc->sdf_vertex_array = 0;
oc->sdf_vertex_buffer = 0;
@@ -2015,13 +2018,15 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
glGenBuffers(1, &oc->sdf_vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, p_points.size() * 2 * sizeof(float), p_points.to_byte_array().ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer, oc->sdf_point_count * 2 * sizeof(float), p_points.to_byte_array().ptr(), GL_STATIC_DRAW, "Occluder polygon SDF vertex buffer");
+
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr);
glGenBuffers(1, &oc->sdf_index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oc->sdf_index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sdf_indices.size() * sizeof(uint32_t), sdf_indices.to_byte_array().ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, oc->sdf_index_buffer, oc->sdf_index_count * sizeof(uint32_t), sdf_indices.to_byte_array().ptr(), GL_STATIC_DRAW, "Occluder polygon SDF index buffer");
+
glBindVertexArray(0);
} else {
glBindBuffer(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer);
@@ -2410,7 +2415,7 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec
}
ERR_FAIL_COND_V(base_offset != stride, 0);
- glBufferData(GL_ARRAY_BUFFER, vertex_count * stride * sizeof(float), polygon_buffer.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, pb.vertex_buffer, vertex_count * stride * sizeof(float), polygon_buffer.ptr(), GL_STATIC_DRAW, "Polygon 2D vertex buffer");
}
if (p_indices.size()) {
@@ -2423,7 +2428,7 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec
}
glGenBuffers(1, &pb.index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_indices.size() * 4, index_buffer.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer, p_indices.size() * 4, index_buffer.ptr(), GL_STATIC_DRAW, "Polygon 2D index buffer");
pb.count = p_indices.size();
}
@@ -2444,11 +2449,11 @@ void RasterizerCanvasGLES3::free_polygon(PolygonID p_polygon) {
PolygonBuffers &pb = *pb_ptr;
if (pb.index_buffer != 0) {
- glDeleteBuffers(1, &pb.index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(pb.index_buffer);
}
glDeleteVertexArrays(1, &pb.vertex_array);
- glDeleteBuffers(1, &pb.vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(pb.vertex_buffer);
polygon_buffers.polygons.erase(p_polygon);
}
@@ -2462,13 +2467,13 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() {
glGenBuffers(3, new_buffers);
// Batch UBO.
glBindBuffer(GL_ARRAY_BUFFER, new_buffers[0]);
- glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffers[0], data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "2D Batch UBO[" + itos(state.current_data_buffer_index) + "][0]");
// Light uniform buffer.
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[1]);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[1], sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW, "2D Lights UBO[" + itos(state.current_data_buffer_index) + "]");
// State buffer.
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[2], sizeof(StateBuffer), nullptr, GL_STREAM_DRAW, "2D State UBO[" + itos(state.current_data_buffer_index) + "]");
state.current_data_buffer_index = (state.current_data_buffer_index + 1);
DataBuffer db;
@@ -2493,7 +2498,7 @@ void RasterizerCanvasGLES3::_allocate_instance_buffer() {
glGenBuffers(1, &new_buffer);
glBindBuffer(GL_ARRAY_BUFFER, new_buffer);
- glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffer, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "Batch UBO[" + itos(state.current_data_buffer_index) + "][" + itos(state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.size()) + "]");
state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.push_back(new_buffer);
@@ -2656,13 +2661,13 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
glGenBuffers(3, new_buffers);
// Batch UBO.
glBindBuffer(GL_ARRAY_BUFFER, new_buffers[0]);
- glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffers[0], data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "Batch UBO[0][0]");
// Light uniform buffer.
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[1]);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[1], sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW, "2D lights UBO[0]");
// State buffer.
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[2], sizeof(StateBuffer), nullptr, GL_STREAM_DRAW, "2D state UBO[0]");
DataBuffer db;
db.instance_buffers.push_back(new_buffers[0]);
db.light_ubo = new_buffers[1];
@@ -2779,12 +2784,26 @@ RasterizerCanvasGLES3::~RasterizerCanvasGLES3() {
if (state.shadow_fb != 0) {
glDeleteFramebuffers(1, &state.shadow_fb);
- glDeleteTextures(1, &state.shadow_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(state.shadow_texture);
glDeleteRenderbuffers(1, &state.shadow_depth_buffer);
state.shadow_fb = 0;
state.shadow_texture = 0;
state.shadow_depth_buffer = 0;
}
+
+ for (uint32_t i = 0; i < state.canvas_instance_data_buffers.size(); i++) {
+ for (int j = 0; j < state.canvas_instance_data_buffers[i].instance_buffers.size(); j++) {
+ if (state.canvas_instance_data_buffers[i].instance_buffers[j]) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].instance_buffers[j]);
+ }
+ }
+ if (state.canvas_instance_data_buffers[i].light_ubo) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].light_ubo);
+ }
+ if (state.canvas_instance_data_buffers[i].state_ubo) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].state_ubo);
+ }
+ }
}
#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 3d8f7924a7..6ed5b3b2f8 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -443,8 +443,10 @@ void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_g
void RasterizerSceneGLES3::_free_sky_data(Sky *p_sky) {
if (p_sky->radiance != 0) {
- glDeleteTextures(1, &p_sky->radiance);
+ GLES3::Utilities::get_singleton()->texture_free_data(p_sky->radiance);
p_sky->radiance = 0;
+ GLES3::Utilities::get_singleton()->texture_free_data(p_sky->raw_radiance);
+ p_sky->raw_radiance = 0;
glDeleteFramebuffers(1, &p_sky->radiance_framebuffer);
p_sky->radiance_framebuffer = 0;
}
@@ -546,6 +548,8 @@ void RasterizerSceneGLES3::_update_dirty_skys() {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count - 1);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(sky->radiance, Image::get_image_data_size(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8, true), "Sky radiance map");
+
glGenTextures(1, &sky->raw_radiance);
glBindTexture(GL_TEXTURE_CUBE_MAP, sky->raw_radiance);
@@ -568,6 +572,7 @@ void RasterizerSceneGLES3::_update_dirty_skys() {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count - 1);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(sky->raw_radiance, Image::get_image_data_size(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8, true), "Sky raw radiance map");
}
sky->reflection_dirty = true;
@@ -1154,6 +1159,11 @@ void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_inst
void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) {
}
+_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
+ static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
+ static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 };
+ return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];
+}
void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append) {
GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();
@@ -1258,7 +1268,8 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
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->index_count = indices;
+
if (p_render_data->render_info) {
indices = _indices_to_primitives(surf->primitive, indices);
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
@@ -1267,21 +1278,20 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;
}
}
- */
+
} else {
surf->lod_index = 0;
- /*
+
if (p_render_data->render_info) {
uint32_t to_draw = mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
to_draw = _indices_to_primitives(surf->primitive, to_draw);
- to_draw *= inst->instance_count;
+ to_draw *= inst->instance_count > 0 ? inst->instance_count : 1;
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
}
}
- */
}
// ADD Element
@@ -1451,17 +1461,26 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
if (scene_state.ubo_buffer == 0) {
glGenBuffers(1, &scene_state.ubo_buffer);
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.ubo_buffer, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW, "Scene state UBO");
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ } else {
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW);
}
- glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW);
+
glBindBuffer(GL_UNIFORM_BUFFER, 0);
if (p_render_data->view_count > 1) {
if (scene_state.multiview_buffer == 0) {
glGenBuffers(1, &scene_state.multiview_buffer);
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.multiview_buffer, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW, "Multiview UBO");
+ } else {
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW);
}
- glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW);
+
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
}
@@ -1792,9 +1811,14 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
if (scene_state.tonemap_buffer == 0) {
// Only create if using 3D
glGenBuffers(1, &scene_state.tonemap_buffer);
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.tonemap_buffer, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW, "Tonemap UBO");
+ } else {
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW);
}
- glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW);
+
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization.
@@ -2086,6 +2110,12 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}
bool should_request_redraw = false;
+ if constexpr (p_pass_mode != PASS_MODE_DEPTH) {
+ // Don't count elements during depth pre-pass to match the RD renderers.
+ if (p_render_data->render_info) {
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += p_to_element - p_from_element;
+ }
+ }
for (uint32_t i = p_from_element; i < p_to_element; i++) {
const GeometryInstanceSurface *surf = p_params->elements[i];
@@ -2326,6 +2356,21 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant, spec_constants);
+
+ // Can be index count or vertex count
+ uint32_t count = 0;
+ if (surf->lod_index > 0) {
+ count = surf->index_count;
+ } else {
+ count = mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface);
+ }
+ if constexpr (p_pass_mode != PASS_MODE_DEPTH) {
+ // Don't count draw calls during depth pre-pass to match the RD renderers.
+ if (p_render_data->render_info) {
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
+ }
+ }
+
if (inst->instance_count > 0) {
// Using MultiMesh or Particles.
// Bind instance buffers.
@@ -2366,16 +2411,16 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
glVertexAttribDivisor(15, 1);
}
if (use_index_buffer) {
- glDrawElementsInstanced(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), mesh_storage->mesh_surface_get_index_type(mesh_surface), 0, inst->instance_count);
+ glDrawElementsInstanced(primitive_gl, count, mesh_storage->mesh_surface_get_index_type(mesh_surface), 0, inst->instance_count);
} else {
- glDrawArraysInstanced(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), inst->instance_count);
+ glDrawArraysInstanced(primitive_gl, 0, count, inst->instance_count);
}
} else {
// Using regular Mesh.
if (use_index_buffer) {
- glDrawElements(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), mesh_storage->mesh_surface_get_index_type(mesh_surface), 0);
+ glDrawElements(primitive_gl, count, mesh_storage->mesh_surface_get_index_type(mesh_surface), 0);
} else {
- glDrawArrays(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface));
+ glDrawArrays(primitive_gl, 0, count);
}
}
if (inst->instance_count > 0) {
@@ -2579,19 +2624,20 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
scene_state.omni_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);
glGenBuffers(1, &scene_state.omni_light_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer);
- glBufferData(GL_UNIFORM_BUFFER, light_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer, light_buffer_size, nullptr, GL_STREAM_DRAW, "OmniLight UBO");
scene_state.spot_lights = memnew_arr(LightData, config->max_renderable_lights);
scene_state.spot_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);
glGenBuffers(1, &scene_state.spot_light_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer);
- glBufferData(GL_UNIFORM_BUFFER, light_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer, light_buffer_size, nullptr, GL_STREAM_DRAW, "SpotLight UBO");
uint32_t directional_light_buffer_size = MAX_DIRECTIONAL_LIGHTS * sizeof(DirectionalLightData);
scene_state.directional_lights = memnew_arr(DirectionalLightData, MAX_DIRECTIONAL_LIGHTS);
glGenBuffers(1, &scene_state.directional_light_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, scene_state.directional_light_buffer);
- glBufferData(GL_UNIFORM_BUFFER, directional_light_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.directional_light_buffer, directional_light_buffer_size, nullptr, GL_STREAM_DRAW, "DirectionalLight UBO");
+
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
@@ -2603,7 +2649,8 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
sky_globals.last_frame_directional_light_count = sky_globals.max_directional_lights + 1;
glGenBuffers(1, &sky_globals.directional_light_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, sky_globals.directional_light_buffer);
- glBufferData(GL_UNIFORM_BUFFER, directional_light_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, sky_globals.directional_light_buffer, directional_light_buffer_size, nullptr, GL_STREAM_DRAW, "Sky DirectionalLight UBO");
+
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
@@ -2702,6 +2749,8 @@ void sky() {
}
{
+ glGenVertexArrays(1, &sky_globals.screen_triangle_array);
+ glBindVertexArray(sky_globals.screen_triangle_array);
glGenBuffers(1, &sky_globals.screen_triangle);
glBindBuffer(GL_ARRAY_BUFFER, sky_globals.screen_triangle);
@@ -2714,12 +2763,8 @@ void sky() {
3.0f,
};
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6, qv, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, sky_globals.screen_triangle, sizeof(float) * 6, qv, GL_STATIC_DRAW, "Screen triangle vertex buffer");
- glGenVertexArrays(1, &sky_globals.screen_triangle_array);
- glBindVertexArray(sky_globals.screen_triangle_array);
- glBindBuffer(GL_ARRAY_BUFFER, sky_globals.screen_triangle);
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
glBindVertexArray(0);
@@ -2735,9 +2780,9 @@ void sky() {
}
RasterizerSceneGLES3::~RasterizerSceneGLES3() {
- glDeleteBuffers(1, &scene_state.directional_light_buffer);
- glDeleteBuffers(1, &scene_state.omni_light_buffer);
- glDeleteBuffers(1, &scene_state.spot_light_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.directional_light_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.omni_light_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.spot_light_buffer);
memdelete_arr(scene_state.directional_lights);
memdelete_arr(scene_state.omni_lights);
memdelete_arr(scene_state.spot_lights);
@@ -2756,13 +2801,26 @@ RasterizerSceneGLES3::~RasterizerSceneGLES3() {
RSG::material_storage->shader_free(sky_globals.default_shader);
RSG::material_storage->material_free(sky_globals.fog_material);
RSG::material_storage->shader_free(sky_globals.fog_shader);
- glDeleteBuffers(1, &sky_globals.screen_triangle);
+ GLES3::Utilities::get_singleton()->buffer_free_data(sky_globals.screen_triangle);
glDeleteVertexArrays(1, &sky_globals.screen_triangle_array);
glDeleteTextures(1, &sky_globals.radical_inverse_vdc_cache_tex);
- glDeleteBuffers(1, &sky_globals.directional_light_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(sky_globals.directional_light_buffer);
memdelete_arr(sky_globals.directional_lights);
memdelete_arr(sky_globals.last_frame_directional_lights);
+ // UBOs
+ if (scene_state.ubo_buffer != 0) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.ubo_buffer);
+ }
+
+ if (scene_state.multiview_buffer != 0) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.multiview_buffer);
+ }
+
+ if (scene_state.tonemap_buffer != 0) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.tonemap_buffer);
+ }
+
singleton = nullptr;
}
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index b4e787ad85..9709d6be2a 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -220,6 +220,7 @@ private:
uint32_t flags = 0;
uint32_t surface_index = 0;
uint32_t lod_index = 0;
+ uint32_t index_count = 0;
void *surface = nullptr;
GLES3::SceneShaderData *shader = nullptr;
diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp
index 8da5e657cd..5aab91e8ae 100644
--- a/drivers/gles3/storage/light_storage.cpp
+++ b/drivers/gles3/storage/light_storage.cpp
@@ -595,106 +595,6 @@ void LightStorage::lightmap_instance_free(RID p_lightmap) {
void LightStorage::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) {
}
-/* LIGHT SHADOW MAPPING */
-/*
-
-RID LightStorage::canvas_light_occluder_create() {
- CanvasOccluder *co = memnew(CanvasOccluder);
- co->index_id = 0;
- co->vertex_id = 0;
- co->len = 0;
-
- return canvas_occluder_owner.make_rid(co);
-}
-
-void LightStorage::canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) {
- CanvasOccluder *co = canvas_occluder_owner.get(p_occluder);
- ERR_FAIL_COND(!co);
-
- co->lines = p_lines;
-
- if (p_lines.size() != co->len) {
- if (co->index_id) {
- glDeleteBuffers(1, &co->index_id);
- } if (co->vertex_id) {
- glDeleteBuffers(1, &co->vertex_id);
- }
-
- co->index_id = 0;
- co->vertex_id = 0;
- co->len = 0;
- }
-
- if (p_lines.size()) {
- PoolVector<float> geometry;
- PoolVector<uint16_t> indices;
- int lc = p_lines.size();
-
- geometry.resize(lc * 6);
- indices.resize(lc * 3);
-
- PoolVector<float>::Write vw = geometry.write();
- PoolVector<uint16_t>::Write iw = indices.write();
-
- PoolVector<Vector2>::Read lr = p_lines.read();
-
- const int POLY_HEIGHT = 16384;
-
- for (int i = 0; i < lc / 2; i++) {
- vw[i * 12 + 0] = lr[i * 2 + 0].x;
- vw[i * 12 + 1] = lr[i * 2 + 0].y;
- vw[i * 12 + 2] = POLY_HEIGHT;
-
- vw[i * 12 + 3] = lr[i * 2 + 1].x;
- vw[i * 12 + 4] = lr[i * 2 + 1].y;
- vw[i * 12 + 5] = POLY_HEIGHT;
-
- vw[i * 12 + 6] = lr[i * 2 + 1].x;
- vw[i * 12 + 7] = lr[i * 2 + 1].y;
- vw[i * 12 + 8] = -POLY_HEIGHT;
-
- vw[i * 12 + 9] = lr[i * 2 + 0].x;
- vw[i * 12 + 10] = lr[i * 2 + 0].y;
- vw[i * 12 + 11] = -POLY_HEIGHT;
-
- iw[i * 6 + 0] = i * 4 + 0;
- iw[i * 6 + 1] = i * 4 + 1;
- iw[i * 6 + 2] = i * 4 + 2;
-
- iw[i * 6 + 3] = i * 4 + 2;
- iw[i * 6 + 4] = i * 4 + 3;
- iw[i * 6 + 5] = i * 4 + 0;
- }
-
- //if same buffer len is being set, just use BufferSubData to avoid a pipeline flush
-
- if (!co->vertex_id) {
- glGenBuffers(1, &co->vertex_id);
- glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
- } else {
- glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferSubData(GL_ARRAY_BUFFER, 0, lc * 6 * sizeof(real_t), vw.ptr());
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
-
- if (!co->index_id) {
- glGenBuffers(1, &co->index_id);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW);
- } else {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, lc * 3 * sizeof(uint16_t), iw.ptr());
- }
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
-
- co->len = lc;
- }
-}
-*/
-
/* SHADOW ATLAS API */
RID LightStorage::shadow_atlas_create() {
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
index 585ed5ff96..8a027aad1c 100644
--- a/drivers/gles3/storage/mesh_storage.cpp
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -193,26 +193,26 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
if (p_surface.vertex_data.size()) {
glGenBuffers(1, &s->vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, p_surface.vertex_data.size(), p_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, p_surface.vertex_data.size(), p_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 = p_surface.vertex_data.size();
}
if (p_surface.attribute_data.size()) {
glGenBuffers(1, &s->attribute_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);
- glBufferData(GL_ARRAY_BUFFER, p_surface.attribute_data.size(), p_surface.attribute_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->attribute_buffer, p_surface.attribute_data.size(), p_surface.attribute_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh attribute buffer");
s->attribute_buffer_size = p_surface.attribute_data.size();
}
+
if (p_surface.skin_data.size()) {
glGenBuffers(1, &s->skin_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->skin_buffer);
- glBufferData(GL_ARRAY_BUFFER, p_surface.skin_data.size(), p_surface.skin_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->skin_buffer, p_surface.skin_data.size(), p_surface.skin_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh skin buffer");
s->skin_buffer_size = p_surface.skin_data.size();
}
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
s->vertex_count = p_surface.vertex_count;
if (p_surface.format & RS::ARRAY_FORMAT_BONES) {
@@ -223,7 +223,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
bool is_index_16 = p_surface.vertex_count <= 65536 && p_surface.vertex_count > 0;
glGenBuffers(1, &s->index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_surface.index_data.size(), p_surface.index_data.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, s->index_buffer, p_surface.index_data.size(), p_surface.index_data.ptr(), GL_STATIC_DRAW, "Mesh index buffer");
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
s->index_count = p_surface.index_count;
s->index_buffer_size = p_surface.index_data.size();
@@ -235,7 +235,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
for (int i = 0; i < p_surface.lods.size(); i++) {
glGenBuffers(1, &s->lods[i].index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->lods[i].index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_surface.lods[i].index_data.size(), p_surface.lods[i].index_data.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, s->lods[i].index_buffer, p_surface.lods[i].index_data.size(), p_surface.lods[i].index_data.ptr(), GL_STATIC_DRAW, "Mesh index buffer LOD[" + itos(i) + "]");
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
s->lods[i].edge_length = p_surface.lods[i].edge_length;
s->lods[i].index_count = p_surface.lods[i].index_data.size() / (is_index_16 ? 2 : 4);
@@ -282,7 +282,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
glBindVertexArray(s->blend_shapes[i].vertex_array);
glGenBuffers(1, &s->blend_shapes[i].vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->blend_shapes[i].vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, size, p_surface.blend_shape_data.ptr() + i * size, (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->blend_shapes[i].vertex_buffer, size, p_surface.blend_shape_data.ptr() + i * size, (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh blend shape buffer");
if ((p_surface.format & (1 << RS::ARRAY_VERTEX))) {
glEnableVertexAttribArray(RS::ARRAY_VERTEX + 3);
@@ -637,7 +637,7 @@ void MeshStorage::mesh_clear(RID p_mesh) {
Mesh::Surface &s = *mesh->surfaces[i];
if (s.vertex_buffer != 0) {
- glDeleteBuffers(1, &s.vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.vertex_buffer);
s.vertex_buffer = 0;
}
@@ -649,17 +649,17 @@ void MeshStorage::mesh_clear(RID p_mesh) {
}
if (s.attribute_buffer != 0) {
- glDeleteBuffers(1, &s.attribute_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.attribute_buffer);
s.attribute_buffer = 0;
}
if (s.skin_buffer != 0) {
- glDeleteBuffers(1, &s.skin_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.skin_buffer);
s.skin_buffer = 0;
}
if (s.index_buffer != 0) {
- glDeleteBuffers(1, &s.index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.index_buffer);
s.index_buffer = 0;
}
@@ -670,7 +670,7 @@ void MeshStorage::mesh_clear(RID p_mesh) {
if (s.lod_count) {
for (uint32_t j = 0; j < s.lod_count; j++) {
if (s.lods[j].index_buffer != 0) {
- glDeleteBuffers(1, &s.lods[j].index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.lods[j].index_buffer);
s.lods[j].index_buffer = 0;
}
}
@@ -680,7 +680,7 @@ void MeshStorage::mesh_clear(RID p_mesh) {
if (mesh->blend_shape_count) {
for (uint32_t j = 0; j < mesh->blend_shape_count; j++) {
if (s.blend_shapes[j].vertex_buffer != 0) {
- glDeleteBuffers(1, &s.blend_shapes[j].vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.blend_shapes[j].vertex_buffer);
s.blend_shapes[j].vertex_buffer = 0;
}
if (s.blend_shapes[j].vertex_array != 0) {
@@ -916,13 +916,14 @@ void MeshStorage::_mesh_instance_clear(MeshInstance *mi) {
}
if (mi->surfaces[i].vertex_buffers[0] != 0) {
- glDeleteBuffers(2, mi->surfaces[i].vertex_buffers);
+ GLES3::Utilities::get_singleton()->buffer_free_data(mi->surfaces[i].vertex_buffers[0]);
+ GLES3::Utilities::get_singleton()->buffer_free_data(mi->surfaces[i].vertex_buffers[1]);
mi->surfaces[i].vertex_buffers[0] = 0;
mi->surfaces[i].vertex_buffers[1] = 0;
}
if (mi->surfaces[i].vertex_buffer != 0) {
- glDeleteBuffers(1, &mi->surfaces[i].vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(mi->surfaces[i].vertex_buffer);
mi->surfaces[i].vertex_buffer = 0;
}
}
@@ -963,13 +964,13 @@ void MeshStorage::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint3
// Buffer to be used for rendering. Final output of skeleton and blend shapes.
glGenBuffers(1, &s.vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count, nullptr, GL_DYNAMIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count, nullptr, GL_DYNAMIC_DRAW, "MeshInstance vertex buffer");
if (mesh->blend_shape_count > 0) {
// Ping-Pong buffers for processing blendshapes.
glGenBuffers(2, s.vertex_buffers);
for (uint32_t i = 0; i < 2; i++) {
glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffers[i]);
- glBufferData(GL_ARRAY_BUFFER, s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count, nullptr, GL_DYNAMIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s.vertex_buffers[i], s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count, nullptr, GL_DYNAMIC_DRAW, "MeshInstance process buffer[" + itos(i) + "]");
}
}
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
@@ -1271,7 +1272,7 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
}
if (multimesh->buffer) {
- glDeleteBuffers(1, &multimesh->buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(multimesh->buffer);
multimesh->buffer = 0;
}
@@ -1298,7 +1299,7 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
if (multimesh->instances) {
glGenBuffers(1, &multimesh->buffer);
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
- glBufferData(GL_ARRAY_BUFFER, multimesh->instances * multimesh->stride_cache * sizeof(float), nullptr, GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float), nullptr, GL_STATIC_DRAW, "MultiMesh buffer");
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
@@ -1958,7 +1959,7 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_
}
if (skeleton->transforms_texture != 0) {
- glDeleteTextures(1, &skeleton->transforms_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(skeleton->transforms_texture);
skeleton->transforms_texture = 0;
skeleton->data.clear();
}
@@ -1973,6 +1974,7 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(skeleton->transforms_texture, skeleton->data.size() * sizeof(float), "Skeleton transforms texture");
memset(skeleton->data.ptrw(), 0, skeleton->data.size() * sizeof(float));
diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp
index 4b64e2aec1..dbd86451d2 100644
--- a/drivers/gles3/storage/particles_storage.cpp
+++ b/drivers/gles3/storage/particles_storage.cpp
@@ -141,23 +141,23 @@ void ParticlesStorage::_particles_free_data(Particles *particles) {
if (particles->front_process_buffer != 0) {
glDeleteVertexArrays(1, &particles->front_vertex_array);
- glDeleteBuffers(1, &particles->front_process_buffer);
- glDeleteBuffers(1, &particles->front_instance_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->front_process_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->front_instance_buffer);
particles->front_vertex_array = 0;
particles->front_process_buffer = 0;
particles->front_instance_buffer = 0;
glDeleteVertexArrays(1, &particles->back_vertex_array);
- glDeleteBuffers(1, &particles->back_process_buffer);
- glDeleteBuffers(1, &particles->back_instance_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->back_process_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->back_instance_buffer);
particles->back_vertex_array = 0;
particles->back_process_buffer = 0;
particles->back_instance_buffer = 0;
}
if (particles->sort_buffer != 0) {
- glDeleteBuffers(1, &particles->last_frame_buffer);
- glDeleteBuffers(1, &particles->sort_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->last_frame_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->sort_buffer);
particles->last_frame_buffer = 0;
particles->sort_buffer = 0;
particles->sort_buffer_filled = false;
@@ -165,7 +165,7 @@ void ParticlesStorage::_particles_free_data(Particles *particles) {
}
if (particles->frame_params_ubo != 0) {
- glDeleteBuffers(1, &particles->frame_params_ubo);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->frame_params_ubo);
particles->frame_params_ubo = 0;
}
}
@@ -680,10 +680,13 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
if (p_particles->frame_params_ubo == 0) {
glGenBuffers(1, &p_particles->frame_params_ubo);
+ glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, p_particles->frame_params_ubo, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW, "Particle Frame UBO");
+ } else {
+ // Update per-frame UBO.
+ glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW);
}
- // Update per-frame UBO.
- glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW);
// Get shader and set shader uniforms;
ParticleProcessMaterialData *m = static_cast<ParticleProcessMaterialData *>(material_storage->material_get_data(p_particles->process_material, RS::SHADER_PARTICLES));
@@ -831,7 +834,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
glGenBuffers(1, &particles->front_instance_buffer);
glBindBuffer(GL_ARRAY_BUFFER, particles->front_process_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->process_buffer_stride_cache * total_amount, data, GL_DYNAMIC_COPY);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->front_process_buffer, particles->process_buffer_stride_cache * total_amount, data, GL_DYNAMIC_COPY, "Particles front process buffer");
for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
glEnableVertexAttribArray(j);
@@ -840,7 +843,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, particles->front_instance_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_COPY);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->front_instance_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_COPY, "Particles front instance buffer");
}
{
@@ -850,7 +853,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
glGenBuffers(1, &particles->back_instance_buffer);
glBindBuffer(GL_ARRAY_BUFFER, particles->back_process_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->process_buffer_stride_cache * total_amount, data, GL_DYNAMIC_COPY);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->back_process_buffer, particles->process_buffer_stride_cache * total_amount, data, GL_DYNAMIC_COPY, "Particles back process buffer");
for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
glEnableVertexAttribArray(j);
@@ -859,7 +862,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, particles->back_instance_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_COPY);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->back_instance_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_COPY, "Particles back instance buffer");
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -871,11 +874,12 @@ void ParticlesStorage::_particles_allocate_history_buffers(Particles *particles)
if (particles->sort_buffer == 0) {
glGenBuffers(1, &particles->last_frame_buffer);
glBindBuffer(GL_ARRAY_BUFFER, particles->last_frame_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->last_frame_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ, "Particles last frame buffer");
glGenBuffers(1, &particles->sort_buffer);
glBindBuffer(GL_ARRAY_BUFFER, particles->sort_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->sort_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ, "Particles sort buffer");
+
particles->sort_buffer_filled = false;
particles->last_frame_buffer_filled = false;
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -1179,7 +1183,7 @@ void ParticlesStorage::particles_collision_free(RID p_rid) {
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_rid);
if (particles_collision->heightfield_texture != 0) {
- glDeleteTextures(1, &particles_collision->heightfield_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
particles_collision->heightfield_texture = 0;
glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
particles_collision->heightfield_fb = 0;
@@ -1226,6 +1230,8 @@ GLuint ParticlesStorage::particles_collision_get_heightfield_framebuffer(RID p_p
WARN_PRINT("Could create heightmap texture status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
}
#endif
+ GLES3::Utilities::get_singleton()->texture_allocated_data(particles_collision->heightfield_texture, size.x * size.y * 4, "Particles collision heightfield texture");
+
particles_collision->heightfield_fb_size = size;
glBindTexture(GL_TEXTURE_2D, 0);
@@ -1244,7 +1250,7 @@ void ParticlesStorage::particles_collision_set_collision_type(RID p_particles_co
}
if (particles_collision->heightfield_texture != 0) {
- glDeleteTextures(1, &particles_collision->heightfield_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
particles_collision->heightfield_texture = 0;
glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
particles_collision->heightfield_fb = 0;
@@ -1319,7 +1325,7 @@ void ParticlesStorage::particles_collision_set_height_field_resolution(RID p_par
particles_collision->heightfield_resolution = p_resolution;
if (particles_collision->heightfield_texture != 0) {
- glDeleteTextures(1, &particles_collision->heightfield_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
particles_collision->heightfield_texture = 0;
glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
particles_collision->heightfield_fb = 0;
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;
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 2b939aa7fa..7aa69d48be 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -542,16 +542,12 @@ public:
virtual uint64_t texture_get_native_handle(RID p_texture, bool p_srgb = false) const override;
void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer = 0);
- void 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 = 0);
- //Ref<Image> texture_get_data(RID p_texture, int p_layer = 0) const;
- void texture_set_sampler(RID p_texture, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat);
Image::Format texture_get_format(RID p_texture) const;
uint32_t texture_get_texid(RID p_texture) const;
uint32_t texture_get_width(RID p_texture) const;
uint32_t texture_get_height(RID p_texture) const;
uint32_t texture_get_depth(RID p_texture) const;
void texture_bind(RID p_texture, uint32_t p_texture_no);
- RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const;
/* TEXTURE ATLAS API */
diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp
index 5f21d8f70a..3e6e72edad 100644
--- a/drivers/gles3/storage/utilities.cpp
+++ b/drivers/gles3/storage/utilities.cpp
@@ -67,6 +67,37 @@ Utilities::~Utilities() {
for (int i = 0; i < FRAME_COUNT; i++) {
glDeleteQueries(max_timestamp_query_elements, frames[i].queries);
}
+
+ if (texture_mem_cache) {
+ uint32_t leaked_data_size = 0;
+ for (const KeyValue<GLuint, ResourceAllocation> &E : texture_allocs_cache) {
+#ifdef DEV_ENABLED
+ ERR_PRINT(E.value.name + ": leaked " + itos(E.value.size) + " bytes.");
+#else
+ ERR_PRINT("Texture with GL ID of " + itos(E.key) + ": leaked " + itos(E.value.size) + " bytes.");
+#endif
+ leaked_data_size += E.value.size;
+ }
+ if (leaked_data_size < texture_mem_cache) {
+ ERR_PRINT("Texture cache is not empty. There may be an additional texture leak of " + itos(texture_mem_cache - leaked_data_size) + " bytes.");
+ }
+ }
+
+ if (buffer_mem_cache) {
+ uint32_t leaked_data_size = 0;
+
+ for (const KeyValue<GLuint, ResourceAllocation> &E : buffer_allocs_cache) {
+#ifdef DEV_ENABLED
+ ERR_PRINT(E.value.name + ": leaked " + itos(E.value.size) + " bytes.");
+#else
+ ERR_PRINT("Buffer with GL ID of " + itos(E.key) + ": leaked " + itos(E.value.size) + " bytes.");
+#endif
+ leaked_data_size += E.value.size;
+ }
+ if (leaked_data_size < buffer_mem_cache) {
+ ERR_PRINT("Buffer cache is not empty. There may be an additional buffer leak of " + itos(buffer_mem_cache - leaked_data_size) + " bytes.");
+ }
+ }
}
Vector<uint8_t> Utilities::buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size) {
@@ -324,6 +355,13 @@ void Utilities::update_memory_info() {
}
uint64_t Utilities::get_rendering_info(RS::RenderingInfo p_info) {
+ if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) {
+ return texture_mem_cache;
+ } else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) {
+ return buffer_mem_cache;
+ } else if (p_info == RS::RENDERING_INFO_VIDEO_MEM_USED) {
+ return texture_mem_cache + buffer_mem_cache;
+ }
return 0;
}
diff --git a/drivers/gles3/storage/utilities.h b/drivers/gles3/storage/utilities.h
index 92131aff8c..243342014b 100644
--- a/drivers/gles3/storage/utilities.h
+++ b/drivers/gles3/storage/utilities.h
@@ -48,6 +48,18 @@ class Utilities : public RendererUtilities {
private:
static Utilities *singleton;
+ struct ResourceAllocation {
+#ifdef DEV_ENABLED
+ String name;
+#endif
+ uint32_t size = 0;
+ };
+ HashMap<GLuint, ResourceAllocation> buffer_allocs_cache;
+ HashMap<GLuint, ResourceAllocation> texture_allocs_cache;
+
+ uint64_t buffer_mem_cache = 0;
+ uint64_t texture_mem_cache = 0;
+
public:
static Utilities *get_singleton() { return singleton; }
@@ -57,6 +69,58 @@ public:
// Buffer size is specified in bytes
static Vector<uint8_t> buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size);
+ // Allocate memory with glBufferData. Does not handle resizing.
+ _FORCE_INLINE_ void buffer_allocate_data(GLenum p_target, GLuint p_id, uint32_t p_size, const void *p_data, GLenum p_usage, String p_name = "") {
+ glBufferData(p_target, p_size, p_data, p_usage);
+ buffer_mem_cache += p_size;
+
+#ifdef DEV_ENABLED
+ ERR_FAIL_COND_MSG(buffer_allocs_cache.has(p_id), "trying to allocate buffer with name " + p_name + " but ID already used by " + buffer_allocs_cache[p_id].name);
+#endif
+
+ ResourceAllocation resource_allocation;
+ resource_allocation.size = p_size;
+#ifdef DEV_ENABLED
+ resource_allocation.name = p_name + ": " + itos((uint64_t)p_id);
+#endif
+ buffer_allocs_cache[p_id] = resource_allocation;
+ }
+
+ _FORCE_INLINE_ void buffer_free_data(GLuint p_id) {
+ ERR_FAIL_COND(!buffer_allocs_cache.has(p_id));
+ glDeleteBuffers(1, &p_id);
+ buffer_mem_cache -= buffer_allocs_cache[p_id].size;
+ buffer_allocs_cache.erase(p_id);
+ }
+
+ // Records that data was allocated for state tracking purposes.
+ _FORCE_INLINE_ void texture_allocated_data(GLuint p_id, uint32_t p_size, String p_name = "") {
+ texture_mem_cache += p_size;
+#ifdef DEV_ENABLED
+ ERR_FAIL_COND_MSG(texture_allocs_cache.has(p_id), "trying to allocate texture with name " + p_name + " but ID already used by " + texture_allocs_cache[p_id].name);
+#endif
+ ResourceAllocation resource_allocation;
+ resource_allocation.size = p_size;
+#ifdef DEV_ENABLED
+ resource_allocation.name = p_name + ": " + itos((uint64_t)p_id);
+#endif
+ texture_allocs_cache[p_id] = resource_allocation;
+ }
+
+ _FORCE_INLINE_ void texture_free_data(GLuint p_id) {
+ ERR_FAIL_COND(!texture_allocs_cache.has(p_id));
+ glDeleteTextures(1, &p_id);
+ texture_mem_cache -= texture_allocs_cache[p_id].size;
+ texture_allocs_cache.erase(p_id);
+ }
+
+ _FORCE_INLINE_ void texture_resize_data(GLuint p_id, uint32_t p_size) {
+ ERR_FAIL_COND(!texture_allocs_cache.has(p_id));
+ texture_mem_cache -= texture_allocs_cache[p_id].size;
+ texture_mem_cache += p_size;
+ texture_allocs_cache[p_id].size = p_size;
+ }
+
/* INSTANCES */
virtual RS::InstanceType get_base_type(RID p_rid) const override;
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index c3e011b812..7fad4061b1 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -2817,7 +2817,7 @@ void Node3DEditorViewport::_notification(int p_what) {
text += "\n";
text += vformat(TTR("Objects: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_OBJECTS_IN_FRAME));
- text += vformat(TTR("Primitive Indices: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME));
+ text += vformat(TTR("Primitives: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME));
text += vformat(TTR("Draw Calls: %d"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME));
info_label->set_text(text);
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index eea891792a..4f47a80c13 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -984,9 +984,9 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
to_draw = _indices_to_primitives(surf->primitive, to_draw);
to_draw *= inst->instance_count;
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
}
}
}
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 0b4157c5d6..77dd39b8d9 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -1884,9 +1884,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
to_draw = _indices_to_primitives(surf->primitive, to_draw);
to_draw *= inst->instance_count;
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
}
}
}
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 8813c2e651..71f6a28671 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -1403,7 +1403,7 @@ void RendererViewport::call_set_vsync_mode(DisplayServer::VSyncMode p_mode, Disp
int RendererViewport::get_total_objects_drawn() const {
return total_objects_drawn;
}
-int RendererViewport::get_total_vertices_drawn() const {
+int RendererViewport::get_total_primitives_drawn() const {
return total_vertices_drawn;
}
int RendererViewport::get_total_draw_calls_used() const {
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index 2f9537a47c..c004d05b23 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -297,7 +297,7 @@ public:
bool free(RID p_rid);
int get_total_objects_drawn() const;
- int get_total_vertices_drawn() const;
+ int get_total_primitives_drawn() const;
int get_total_draw_calls_used() const;
// Workaround for setting this on thread.
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index 5f14245307..65bdb94c9f 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -251,7 +251,7 @@ uint64_t RenderingServerDefault::get_rendering_info(RenderingInfo p_info) {
if (p_info == RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME) {
return RSG::viewport->get_total_objects_drawn();
} else if (p_info == RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME) {
- return RSG::viewport->get_total_vertices_drawn();
+ return RSG::viewport->get_total_primitives_drawn();
} else if (p_info == RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME) {
return RSG::viewport->get_total_draw_calls_used();
}