Merge pull request #103794 from clayjohn/mobile-allocations
Significantly reduce per-frame memory allocations from the heap in the Mobile renderer
This commit is contained in:
@ -35,6 +35,7 @@
|
||||
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
||||
@ -404,7 +405,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
// default render buffer and scene state uniform set
|
||||
// loaded into set 1
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
thread_local LocalVector<RD::Uniform> uniforms;
|
||||
uniforms.clear();
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
@ -481,9 +483,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
|
||||
/* we have limited ability to keep textures like this so we're moving this to a set we change before drawing geometry and just pushing the needed texture in */
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 6;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
Vector<RID> textures;
|
||||
textures.resize(scene_state.max_lightmaps * 2);
|
||||
|
||||
RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
|
||||
for (uint32_t i = 0; i < scene_state.max_lightmaps * 2; i++) {
|
||||
@ -503,14 +504,14 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
|
||||
if (texture.is_valid()) {
|
||||
RID rd_texture = texture_storage->texture_get_rd_texture(texture);
|
||||
u.append_id(rd_texture);
|
||||
textures.write[i] = rd_texture;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
u.append_id(default_tex);
|
||||
textures.write[i] = default_tex;
|
||||
}
|
||||
|
||||
RD::Uniform u(RD::UNIFORM_TYPE_TEXTURE, 6, textures);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
@ -630,15 +631,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
|
||||
p_samplers.append_uniforms(uniforms, 13);
|
||||
|
||||
if (p_index >= (int)render_pass_uniform_sets.size()) {
|
||||
render_pass_uniform_sets.resize(p_index + 1);
|
||||
}
|
||||
|
||||
if (render_pass_uniform_sets[p_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[p_index])) {
|
||||
RD::get_singleton()->free(render_pass_uniform_sets[p_index]);
|
||||
}
|
||||
render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET, true);
|
||||
return render_pass_uniform_sets[p_index];
|
||||
return UniformSetCacheRD::get_singleton()->get_cache_vec(scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET, uniforms);
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) {
|
||||
@ -1703,16 +1696,15 @@ void RenderForwardMobile::base_uniforms_changed() {
|
||||
void RenderForwardMobile::_update_render_base_uniform_set() {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
|
||||
// We must always recreate the uniform set every frame if we're using linear pools (since we requested it on creation).
|
||||
// This pays off as long as we often get inside the if() block (i.e. the settings end up changing often).
|
||||
if (RD::get_singleton()->uniform_sets_have_linear_pools() || render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != light_storage->lightmap_array_get_version())) {
|
||||
if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != light_storage->lightmap_array_get_version())) {
|
||||
if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
|
||||
RD::get_singleton()->free(render_base_uniform_set);
|
||||
}
|
||||
|
||||
lightmap_texture_array_version = light_storage->lightmap_array_get_version();
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
thread_local LocalVector<RD::Uniform> uniforms;
|
||||
uniforms.clear();
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
@ -1806,7 +1798,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET, true);
|
||||
render_base_uniform_set = UniformSetCacheRD::get_singleton()->get_cache_vec(scene_shader.default_shader_rd, SCENE_UNIFORM_SET, uniforms);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3271,13 +3263,6 @@ RenderForwardMobile::RenderForwardMobile() {
|
||||
RenderForwardMobile::~RenderForwardMobile() {
|
||||
RSG::light_storage->directional_shadow_atlas_set_size(0);
|
||||
|
||||
//clear base uniform set if still valid
|
||||
for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) {
|
||||
if (render_pass_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[i])) {
|
||||
RD::get_singleton()->free(render_pass_uniform_sets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (const RID &rid : scene_state.uniform_buffers) {
|
||||
RD::get_singleton()->free(rid);
|
||||
|
||||
@ -173,7 +173,6 @@ private:
|
||||
void _setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform);
|
||||
|
||||
RID render_base_uniform_set;
|
||||
LocalVector<RID> render_pass_uniform_sets;
|
||||
|
||||
/* Light map */
|
||||
|
||||
|
||||
@ -379,7 +379,8 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
|
||||
//re create canvas state
|
||||
Vector<RD::Uniform> uniforms;
|
||||
thread_local LocalVector<RD::Uniform> uniforms;
|
||||
uniforms.clear();
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
|
||||
@ -765,7 +765,8 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
|
||||
MaterialStorage *material_storage = MaterialStorage::get_singleton();
|
||||
|
||||
if (p_particles->particles_material_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_particles->particles_material_uniform_set)) {
|
||||
Vector<RD::Uniform> uniforms;
|
||||
thread_local LocalVector<RD::Uniform> uniforms;
|
||||
uniforms.clear();
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
@ -1071,7 +1072,8 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
|
||||
RD::get_singleton()->free(p_particles->collision_textures_uniform_set);
|
||||
}
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
thread_local LocalVector<RD::Uniform> uniforms;
|
||||
uniforms.clear();
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
|
||||
@ -3416,15 +3416,10 @@ void RenderingDevice::_uniform_set_update_shared(UniformSet *p_uniform_set) {
|
||||
}
|
||||
}
|
||||
|
||||
template RID RenderingDevice::uniform_set_create(const LocalVector<RD::Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool);
|
||||
|
||||
template RID RenderingDevice::uniform_set_create(const Vector<RD::Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool);
|
||||
|
||||
template <typename Collection>
|
||||
RID RenderingDevice::uniform_set_create(const Collection &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool) {
|
||||
RID RenderingDevice::uniform_set_create(const VectorView<RD::Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
ERR_FAIL_COND_V(p_uniforms.is_empty(), RID());
|
||||
ERR_FAIL_COND_V(p_uniforms.size() == 0, RID());
|
||||
|
||||
Shader *shader = shader_owner.get_or_null(p_shader);
|
||||
ERR_FAIL_NULL_V(shader, RID());
|
||||
@ -8208,12 +8203,12 @@ RID RenderingDevice::_shader_create_from_spirv(const Ref<RDShaderSPIRV> &p_spirv
|
||||
}
|
||||
|
||||
RID RenderingDevice::_uniform_set_create(const TypedArray<RDUniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) {
|
||||
Vector<Uniform> uniforms;
|
||||
LocalVector<Uniform> uniforms;
|
||||
uniforms.resize(p_uniforms.size());
|
||||
for (int i = 0; i < p_uniforms.size(); i++) {
|
||||
Ref<RDUniform> uniform = p_uniforms[i];
|
||||
ERR_FAIL_COND_V(uniform.is_null(), RID());
|
||||
uniforms.write[i] = uniform->base;
|
||||
uniforms[i] = uniform->base;
|
||||
}
|
||||
return uniform_set_create(uniforms, p_shader, p_shader_set);
|
||||
}
|
||||
|
||||
@ -1067,8 +1067,7 @@ public:
|
||||
* If you plan on keeping the return value around for more than one frame (e.g. Sets that are created once and reused forever) you MUST set it to false.
|
||||
* @return Baked descriptor set.
|
||||
*/
|
||||
template <typename Collection>
|
||||
RID uniform_set_create(const Collection &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool = false);
|
||||
RID uniform_set_create(const VectorView<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool = false);
|
||||
bool uniform_set_is_valid(RID p_uniform_set);
|
||||
void uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user