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:
parent
9c41c4ecb6
commit
36a005fafc
17 changed files with 336 additions and 242 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue