allocator optimizations

This commit is contained in:
Mikulas Florek 2022-02-11 02:02:54 +01:00
parent 019fa3fc1e
commit db4b769652
9 changed files with 96 additions and 128 deletions

View file

@ -23,19 +23,7 @@ static const ComponentType POINT_LIGHT_TYPE = reflection::getComponentType("poin
static const ComponentType TERRAIN_TYPE = reflection::getComponentType("terrain");
enum class IconType
{
PHYSICAL_CONTROLLER,
CAMERA,
LIGHT,
TERRAIN,
ENTITY,
COUNT
};
const char* ICONS[(int)IconType::COUNT] =
const char* ICONS[(int)EditorIcons::IconType::COUNT] =
{
"phy_controller_icon",
"camera_icon",
@ -50,14 +38,6 @@ static const float ORTHO_SIZE_SCALE = 1 / 20.0f;
struct EditorIconsImpl final : EditorIcons
{
struct Icon
{
EntityRef entity;
IconType type;
float scale;
};
explicit EditorIconsImpl(WorldEditor& editor, RenderScene& scene)
: m_editor(editor)
, m_icons(editor.getAllocator())
@ -205,8 +185,24 @@ struct EditorIconsImpl final : EditorIcons
return ret;
}
void computeScales() override {
Matrix getIconMatrix(const Icon& icon, const Matrix& camera_matrix, const DVec3& vp_pos, bool is_ortho, float ortho_size) const
static const float MIN_SCALE_FACTOR = 10;
static const float MAX_SCALE_FACTOR = 60;
const Universe& universe = *m_editor.getUniverse();
const Viewport& vp = m_editor.getView().getViewport();
for(auto& icon : m_icons) {
const DVec3 position = universe.getPosition(icon.entity);
const float distance = (float)length(position - vp.pos);
float scale_factor = MIN_SCALE_FACTOR + distance;
scale_factor = clamp(scale_factor, MIN_SCALE_FACTOR, MAX_SCALE_FACTOR);
icon.scale = tanf(vp.fov * 0.5f) * distance / scale_factor;
}
}
Matrix getIconMatrix(const Icon& icon, const Matrix& camera_matrix, const DVec3& vp_pos, bool is_ortho, float ortho_size) const override
{
Matrix ret;
if (m_is_3d[(int)icon.type])
@ -228,29 +224,10 @@ struct EditorIconsImpl final : EditorIcons
}
return ret;
}
const Model* getModel(IconType type) const override { return m_models[(i32)type]; }
void getRenderData(Array<RenderData>* data) override
{
static const float MIN_SCALE_FACTOR = 10;
static const float MAX_SCALE_FACTOR = 60;
const Universe& universe = *m_editor.getUniverse();
const Viewport& vp = m_editor.getView().getViewport();
Matrix camera_mtx({0, 0, 0}, vp.rot);
data->reserve(m_icons.size());
for(auto& icon : m_icons) {
const DVec3 position = universe.getPosition(icon.entity);
const float distance = (float)length(position - vp.pos);
float scale_factor = MIN_SCALE_FACTOR + distance;
scale_factor = clamp(scale_factor, MIN_SCALE_FACTOR, MAX_SCALE_FACTOR);
icon.scale = tanf(vp.fov * 0.5f) * distance / scale_factor;
Matrix icon_mtx = getIconMatrix(icon, camera_mtx, vp.pos, vp.is_ortho, vp.ortho_size);
data->push({icon_mtx, m_models[(int)icon.type]});
}
}
const HashMap<EntityRef, Icon>& getIcons() const override { return m_icons; }
HashMap<EntityRef, Icon> m_icons;
Model* m_models[(int)IconType::COUNT];

View file

@ -1,6 +1,7 @@
#pragma once
#include "engine/hash_map.h"
#include "engine/math.h"
@ -12,15 +13,25 @@ template <typename T> struct UniquePtr;
struct EditorIcons
{
struct Hit
{
EntityPtr entity;
float t;
enum class IconType {
PHYSICAL_CONTROLLER,
CAMERA,
LIGHT,
TERRAIN,
ENTITY,
COUNT
};
struct RenderData {
Matrix mtx;
struct Model* model;
struct Icon {
EntityRef entity;
IconType type;
float scale;
};
struct Hit {
EntityPtr entity;
float t;
};
static UniquePtr<EditorIcons> create(struct WorldEditor& editor, struct RenderScene& scene);
@ -28,7 +39,10 @@ struct EditorIcons
virtual ~EditorIcons() {}
virtual void getRenderData(Array<RenderData>* data) = 0;
virtual void computeScales() = 0;
virtual Matrix getIconMatrix(const Icon& icon, const Matrix& camera_matrix, const DVec3& vp_pos, bool is_ortho, float ortho_size) const = 0;
virtual const struct Model* getModel(IconType type) const = 0;
virtual const HashMap<EntityRef, Icon>& getIcons() const = 0;
virtual Hit raycast(const DVec3& origin, const Vec3& dir) = 0;
virtual void refresh() = 0;
};

View file

@ -17,6 +17,7 @@
#include "editor/studio_app.h"
#include "editor/utils.h"
#include "editor/world_editor.h"
#include "engine/allocators.h"
#include "engine/associative_array.h"
#include "engine/crc32.h"
#include "engine/engine.h"
@ -4223,11 +4224,11 @@ struct RenderInterfaceImpl final : RenderInterface
struct EditorUIRenderPlugin final : StudioApp::GUIPlugin
{
struct RenderCommand : Renderer::RenderJob
struct RenderJob : Renderer::RenderJob
{
struct CmdList
{
CmdList(IAllocator& allocator) : commands(allocator) {}
CmdList(LinearAllocator& allocator) : commands(allocator) {}
Renderer::TransientSlice idx_buffer;
Renderer::TransientSlice vtx_buffer;
@ -4236,7 +4237,7 @@ struct EditorUIRenderPlugin final : StudioApp::GUIPlugin
};
struct WindowDrawData {
WindowDrawData(IAllocator& allocator) : cmd_lists(allocator) {}
WindowDrawData(LinearAllocator& allocator) : cmd_lists(allocator) {}
gpu::ProgramHandle program;
os::WindowHandle window;
@ -4246,7 +4247,7 @@ struct EditorUIRenderPlugin final : StudioApp::GUIPlugin
Array<CmdList> cmd_lists;
};
RenderCommand(IAllocator& allocator)
RenderJob(LinearAllocator& allocator)
: allocator(allocator)
, window_draw_data(allocator)
{
@ -4417,13 +4418,13 @@ struct EditorUIRenderPlugin final : StudioApp::GUIPlugin
renderer->endProfileBlock();
}
LinearAllocator& allocator;
Renderer* renderer;
const gpu::TextureHandle* default_texture;
Array<WindowDrawData> window_draw_data;
gpu::BufferHandle ub;
u32 ib_offset;
u32 vb_offset;
IAllocator& allocator;
EditorUIRenderPlugin* plugin;
};
@ -4488,7 +4489,7 @@ struct EditorUIRenderPlugin final : StudioApp::GUIPlugin
void guiEndFrame() override
{
Renderer* renderer = static_cast<Renderer*>(m_engine.getPluginManager().getPlugin("renderer"));
RenderCommand& cmd = renderer->createJob<RenderCommand>(renderer->getAllocator());
RenderJob& cmd = renderer->createJob<RenderJob>(renderer->getCurrentFrameAllocator());
cmd.plugin = this;
cmd.ub = m_ub;

View file

@ -10,6 +10,7 @@
#include "editor/settings.h"
#include "editor/studio_app.h"
#include "editor/utils.h"
#include "engine/allocators.h"
#include "engine/crc32.h"
#include "engine/delegate_list.h"
#include "engine/engine.h"
@ -789,21 +790,26 @@ void SceneView::renderIcons()
{
struct RenderJob : Renderer::RenderJob
{
RenderJob(Renderer& renderer, IAllocator& allocator)
: m_allocator(allocator)
, m_renderer(renderer)
RenderJob(Renderer& renderer, LinearAllocator& allocator)
: m_renderer(renderer)
, m_items(allocator)
{}
void setup() override
{
PROFILE_FUNCTION();
Array<EditorIcons::RenderData> data(m_allocator);
m_ui->m_view->m_icons->getRenderData(&data);
m_items.reserve(data.size());
EditorIcons* icon_manager = m_ui->m_view->m_icons.get();
const HashMap<EntityRef, EditorIcons::Icon>& icons = icon_manager->getIcons();
m_items.reserve(icons.size());
for (EditorIcons::RenderData& rd : data) {
const Model* model = rd.model;
const Viewport& vp = m_ui->m_view->getViewport();
Matrix camera_mtx({0, 0, 0}, vp.rot);
icon_manager->computeScales();
for (const EditorIcons::Icon& icon : icons) {
const Model* model = icon_manager->getModel(icon.type);
if (!model || !model->isReady()) continue;
for (int i = 0; i <= model->getLODIndices()[0].to; ++i) {
@ -813,7 +819,8 @@ void SceneView::renderIcons()
item.material = mesh.material->getRenderData();
item.program = mesh.material->getShader()->getProgram(mesh.vertex_decl, item.material->define_mask);
item.ub = m_renderer.allocUniform(sizeof(Matrix));
memcpy(item.ub.ptr, &rd.mtx, sizeof(rd.mtx));
const Matrix mtx = icon_manager->getIconMatrix(icon, camera_mtx, vp.pos, vp.is_ortho, vp.ortho_size);
memcpy(item.ub.ptr, &mtx, sizeof(mtx));
}
}
}
@ -844,7 +851,6 @@ void SceneView::renderIcons()
Renderer::TransientSlice ub;
};
IAllocator& m_allocator;
Renderer& m_renderer;
Array<Item> m_items;
SceneView* m_ui;
@ -853,8 +859,7 @@ void SceneView::renderIcons()
Engine& engine = m_app.getEngine();
Renderer* renderer = static_cast<Renderer*>(engine.getPluginManager().getPlugin("renderer"));
IAllocator& allocator = renderer->getAllocator();
RenderJob& cmd = renderer->createJob<RenderJob>(*renderer, allocator);
RenderJob& cmd = renderer->createJob<RenderJob>(*renderer, renderer->getCurrentFrameAllocator());
cmd.m_ui = this;
renderer->queue(cmd, 0);
}

View file

@ -1,8 +1,8 @@
#include "gpu/gpu.h"
#include "engine/crt.h"
#include "engine/allocators.h"
#include "engine/associative_array.h"
#include "engine/crc32.h"
#include "engine/crt.h"
#include "engine/engine.h"
#include "engine/file_system.h"
#include "engine/geometry.h"
@ -4072,7 +4072,8 @@ struct PipelineImpl final : Pipeline
}
PageAllocator& page_allocator = m_renderer.getEngine().getPageAllocator();
Array<CmdPage*> pages(m_allocator);
StackAllocator<sizeof(CmdPage*) * 64, alignof(CmdPage*)> pages_allocator(m_allocator);
Array<CmdPage*> pages(pages_allocator);
pages.resize(steps);
jobs::forEach(size, STEP, [&](i32 from, i32 to){
@ -4280,7 +4281,8 @@ struct PipelineImpl final : Pipeline
{
RenderGrassCommand(IAllocator& allocator)
: m_allocator(allocator)
, m_grass(allocator)
, m_grass_allocator(allocator)
, m_grass(m_grass_allocator)
{
}
@ -4476,6 +4478,7 @@ struct PipelineImpl final : Pipeline
IAllocator& m_allocator;
gpu::ProgramHandle m_compute_shader;
StackAllocator<sizeof(Grass) * 32, alignof(Grass)> m_grass_allocator;
Array<Grass> m_grass;
PipelineImpl* m_pipeline;
CameraParams m_camera_params;
@ -4495,23 +4498,26 @@ struct PipelineImpl final : Pipeline
void setup() override
{
PROFILE_FUNCTION();
Array<TerrainInfo> infos(m_allocator);
m_pipeline->m_scene->getTerrainInfos(infos);
if(infos.empty()) return;
const HashMap<EntityRef, Terrain*>& terrains = m_pipeline->m_scene->getTerrains();
if(terrains.empty()) return;
m_instances.reserve(infos.size());
for (TerrainInfo& info : infos) {
if (!info.terrain->m_heightmap) continue;
if (!info.terrain->m_heightmap->isReady()) continue;
Universe& universe = m_pipeline->m_scene->getUniverse();
m_instances.reserve(terrains.size());
for (const Terrain* terrain : terrains) {
if (!terrain->m_heightmap) continue;
if (!terrain->m_heightmap->isReady()) continue;
if (!terrain->m_material || !terrain->m_material->isReady()) continue;
const Transform& tr = universe.getTransform(terrain->m_entity);
Instance& inst = m_instances.emplace(m_allocator);
inst.pos = Vec3(info.position - m_camera_params.pos);
inst.ref_pos = Vec3(info.position - m_pipeline->m_viewport.pos);
inst.rot = info.rot;
inst.scale = info.terrain->getScale();
inst.hm_size = info.terrain->getSize();
inst.program = info.shader->getProgram(gpu::VertexDecl(), m_define_mask);
inst.material = info.terrain->m_material->getRenderData();
inst.pos = Vec3(tr.pos- m_camera_params.pos);
inst.ref_pos = Vec3(tr.pos - m_pipeline->m_viewport.pos);
inst.rot = tr.rot;
inst.scale = terrain->getScale();
inst.hm_size = terrain->getSize();
Shader* shader = terrain->m_material->getShader();
inst.program = shader->getProgram(gpu::VertexDecl(), m_define_mask);
inst.material = terrain->m_material->getRenderData();
if (isinf(inst.pos.x) || isinf(inst.pos.y) || isinf(inst.pos.z)) {
m_instances.pop();
continue;
@ -4612,7 +4618,10 @@ struct PipelineImpl final : Pipeline
}
struct Instance {
Instance(IAllocator& allocator) : quads(allocator) {}
Instance(IAllocator& allocator)
: quads_allocator(allocator)
, quads(quads_allocator)
{}
struct Quad {
Renderer::TransientSlice buf;
@ -4626,6 +4635,7 @@ struct PipelineImpl final : Pipeline
Vec3 scale;
gpu::ProgramHandle program;
Material::RenderData* material;
StackAllocator<sizeof(Quad) * 32, alignof(Quad)> quads_allocator;
Array<Quad> quads;
};

View file

@ -1799,17 +1799,6 @@ struct RenderSceneImpl final : RenderScene {
}
void getTerrainInfos(Array<TerrainInfo>& infos) override
{
PROFILE_FUNCTION();
infos.reserve(m_terrains.size());
for (auto* terrain : m_terrains) {
const TerrainInfo info = terrain->getInfo();
if (info.terrain) infos.push(info);
}
}
static int LUA_castCameraRay(lua_State* L)
{
auto* scene = LuaWrapper::checkArg<RenderSceneImpl*>(L, 1);

View file

@ -75,16 +75,6 @@ struct CurveDecal {
Vec2 bezier_p2;
};
struct TerrainInfo
{
DVec3 position;
Quat rot;
Shader* shader;
Terrain* terrain;
Vec3 min;
int index;
};
struct Environment
{
enum Flags : u32 {
@ -370,7 +360,6 @@ struct LUMIX_RENDERER_API RenderScene : IScene
virtual Terrain* getTerrain(EntityRef entity) = 0;
virtual const HashMap<EntityRef, Terrain*>& getTerrains() = 0;
virtual void getTerrainInfos(Array<TerrainInfo>& infos) = 0;
virtual float getTerrainHeightAt(EntityRef entity, float x, float z) = 0;
virtual Vec3 getTerrainNormalAt(EntityRef entity, float x, float z) = 0;
virtual void setTerrainMaterialPath(EntityRef entity, const Path& path) = 0;

View file

@ -264,20 +264,6 @@ void Terrain::serialize(OutputMemoryStream& serializer)
}
}
TerrainInfo Terrain::getInfo()
{
if (!m_material || !m_material->isReady()) return {};
TerrainInfo info;
info.shader = m_material->getShader();
info.position = m_scene.getUniverse().getPosition(m_entity);
info.rot = m_scene.getUniverse().getRotation(m_entity);
info.terrain = this;
return info;
}
Vec3 Terrain::getNormal(float x, float z)
{
int int_x = (int)(x / m_scale.x);

View file

@ -23,7 +23,6 @@ struct Renderer;
struct RenderScene;
struct ShiftedFrustum;
struct TerrainQuad;
struct TerrainInfo;
struct Texture;
struct Universe;
@ -92,8 +91,6 @@ struct Terrain
void setGrassTypeRotationMode(int index, GrassType::RotationMode mode);
void setMaterial(Material* material);
TerrainInfo getInfo();
RayCastModelHit castRay(const DVec3& origin, const Vec3& dir);
void serialize(OutputMemoryStream& serializer);
void deserialize(EntityRef entity, InputMemoryStream& serializer, Universe& universe, RenderScene& scene);