Merge pull request #77536 from clayjohn/GLES3-render-info
Add RENDERING_INFO parameters to GL Compatibility renderer
This commit is contained in:
commit
908610174d
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