You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
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.
This commit is contained in:
committed by
Rémi Verschelde
parent
9c41c4ecb6
commit
36a005fafc
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user