Skip to content

Commit

Permalink
gh-56: add new shader reflection and shader class builder
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorOrachyov committed Mar 21, 2024
1 parent a14122d commit 68017ee
Show file tree
Hide file tree
Showing 32 changed files with 1,698 additions and 152 deletions.
16 changes: 14 additions & 2 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,6 @@ add_library(wmoge STATIC
gfx/gfx_driver.hpp
gfx/gfx_dynamic_buffers.cpp
gfx/gfx_dynamic_buffers.hpp
gfx/gfx_pass.hpp
gfx/gfx_pass.cpp
gfx/gfx_pipeline_cache.cpp
gfx/gfx_pipeline_cache.hpp
gfx/gfx_pipeline.cpp
Expand Down Expand Up @@ -185,6 +183,20 @@ add_library(wmoge STATIC
gfx/vulkan/vk_vert_format.hpp
gfx/vulkan/vk_window.cpp
gfx/vulkan/vk_window.hpp
glsl/glsl_include_processor.cpp
glsl/glsl_include_processor.hpp
glsl/glsl_shader_compiler.cpp
glsl/glsl_shader_compiler.hpp
grc/grc_shader_class_builder.cpp
grc/grc_shader_class_builder.hpp
grc/grc_shader_class.cpp
grc/grc_shader_class.hpp
grc/grc_shader_manager.cpp
grc/grc_shader_manager.hpp
grc/grc_shader_reflection.cpp
grc/grc_shader_reflection.hpp
grc/grc_shader.cpp
grc/grc_shader.hpp
hgfx/hgfx_pass.cpp
hgfx/hgfx_pass.hpp
hgfx/hgfx_pass_base.cpp
Expand Down
7 changes: 7 additions & 0 deletions engine/core/async.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "core/async.hpp"

#include "async.hpp"
#include "debug/profiler.hpp"

namespace wmoge {
Expand Down Expand Up @@ -86,4 +87,10 @@ namespace wmoge {
return Async(std::move(state));
}

Async Async::completed() {
auto state = make_async_op<int>();
state->set_result(0);
return Async(state);
}

}// namespace wmoge
7 changes: 7 additions & 0 deletions engine/core/async.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,13 @@ namespace wmoge {
* @return New async signaled when all deps finished or failed if one failed
*/
static Async join(ArrayView<Async> dependencies);

/**
* @brief Make signaled (completed) async op
*
* @return Completed async
*/
static Async completed();
};

/**
Expand Down
38 changes: 27 additions & 11 deletions engine/ecs/ecs_registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#pragma once

#include "core/array_view.hpp"
#include "core/fast_map.hpp"
#include "core/fast_vector.hpp"
#include "core/string_id.hpp"
Expand All @@ -37,6 +38,7 @@
#include "memory/mem_pool.hpp"

#include <array>
#include <memory>
#include <mutex>

namespace wmoge {
Expand All @@ -52,22 +54,29 @@ namespace wmoge {
EcsRegistry(EcsRegistry&&) = delete;
~EcsRegistry() = default;

[[nodiscard]] int get_component_idx(const Strid& name);
[[nodiscard]] const EcsComponentInfo& get_component_info(const Strid& name);
[[nodiscard]] const EcsComponentInfo& get_component_info(int idx);
[[nodiscard]] MemPool& get_component_pool(int idx);
[[nodiscard]] MemPool& get_entity_pool();
[[nodiscard]] int get_chunk_size() const { return m_chunk_size; }
[[nodiscard]] int get_expand_size() const { return m_expand_size; }
[[nodiscard]] int get_component_idx(const Strid& name);
[[nodiscard]] const EcsComponentInfo& get_component_info(const Strid& name);
[[nodiscard]] const EcsComponentInfo& get_component_info(int idx);
[[nodiscard]] MemPool& get_component_pool(int idx);
[[nodiscard]] MemPool& get_entity_pool();
[[nodiscard]] int get_chunk_size() const { return m_chunk_size; }
[[nodiscard]] int get_expand_size() const { return m_expand_size; }
[[nodiscard]] ArrayView<const EcsSystemPtr> get_systems() const { return m_systems; }

template<typename Component>
void register_component();

template<typename System>
std::shared_ptr<System> register_system();

private:
std::array<EcsComponentInfo, EcsLimits::MAX_COMPONENTS> m_components_info; // type info of component, indexed by component id
std::array<std::unique_ptr<MemPool>, EcsLimits::MAX_COMPONENTS> m_components_pool; // pools to allocate components chunks
fast_map<Strid, int> m_components_name_to_idx;// resolve component name to its idx
std::unique_ptr<MemPool> m_entity_pool; // pool to allocate entities chunks
static const int MAX_CMP = EcsLimits::MAX_COMPONENTS;

std::array<EcsComponentInfo, MAX_CMP> m_components_info; // type info of component, indexed by component id
std::array<std::unique_ptr<MemPool>, MAX_CMP> m_components_pool; // pools to allocate components chunks
fast_map<Strid, int> m_components_name_to_idx;// resolve component name to its idx
std::unique_ptr<MemPool> m_entity_pool; // pool to allocate entities chunks
std::vector<EcsSystemPtr> m_systems; // registered global systems

int m_chunk_size = 16;// num of components of a single type sequentially allocate in one chunk
int m_expand_size = 2; // num of chunks in a single pooled allocation in head
Expand Down Expand Up @@ -108,4 +117,11 @@ namespace wmoge {
m_components_pool[component_info.idx] = std::make_unique<MemPool>(component_info.size * m_chunk_size, m_expand_size);
}

template<typename System>
inline std::shared_ptr<System> EcsRegistry::register_system() {
auto sys = std::make_shared<System>();
m_systems.emplace_back(sys);
return sys;
}

}// namespace wmoge
21 changes: 13 additions & 8 deletions engine/ecs/ecs_system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ namespace wmoge {
* @brief How system must be executed
*/
enum class EcsSystemExecMode {
OnMain, // On main (game) thread only without parallel speed up
OnWorkers// In task manager with multiple parallel tasks
SingleThread,// One thread only without parallel speed up
WorkerThreads// In task manager with multiple parallel tasks
};

/**
Expand Down Expand Up @@ -83,20 +83,25 @@ namespace wmoge {
virtual void process_batch(class EcsWorld& world, EcsArchStorage& storage, int start_entity, int count) = 0;

[[nodiscard]] virtual EcsSystemType get_type() const { return EcsSystemType::Update; }
[[nodiscard]] virtual EcsSystemExecMode get_exec_mode() const { return EcsSystemExecMode::OnMain; }
[[nodiscard]] virtual EcsSystemExecMode get_exec_mode() const { return EcsSystemExecMode::SingleThread; }
[[nodiscard]] virtual Strid get_name() const = 0;
[[nodiscard]] virtual EcsQuery get_query() const = 0;
};

/**
* @brief Shader pointer to a ecs system
*/
using EcsSystemPtr = std::shared_ptr<EcsSystem>;

/**
* @brief Holds system information for execution within a world
*/
struct EcsSystemInfo {
EcsQuery query; // system query, which archetypes its affects
EcsSystemType type; // system type (exec, deletion, etc.)
EcsSystemExecMode exec_mode; // execution mode
std::shared_ptr<EcsSystem> system; // cached system ptr
std::vector<int> filtered_arch;// pre-filtered arch idx to execute using this system
EcsQuery query; // system query, which archetypes its affects
EcsSystemType type; // system type (exec, deletion, etc.)
EcsSystemExecMode exec_mode; // execution mode
EcsSystemPtr system; // cached system ptr
std::vector<int> filtered_arch;// pre-filtered arch idx to execute using this system
};

/**
Expand Down
80 changes: 23 additions & 57 deletions engine/ecs/ecs_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include "core/log.hpp"
#include "core/task.hpp"
#include "core/task_manager.hpp"
#include "core/task_parallel_for.hpp"
#include "debug/profiler.hpp"
#include "ecs/ecs_registry.hpp"
Expand All @@ -39,6 +40,11 @@ namespace wmoge {

EcsWorld::EcsWorld() {
m_task_manager = Engine::instance()->task_manager();
m_ecs_registry = Engine::instance()->ecs_registry();

for (const EcsSystemPtr& system : m_ecs_registry->get_systems()) {
register_system(system);
}
}

EcsWorld::~EcsWorld() {
Expand Down Expand Up @@ -99,10 +105,8 @@ namespace wmoge {
const EcsArch right_arch = m_arch_by_idx[right_info.arch];
const EcsArch left_arch = m_arch_by_idx[left_info.arch];

EcsRegistry* ecs_registry = Engine::instance()->ecs_registry();

EcsArch(right_arch & left_arch).for_each_component([&](int idx) {
const EcsComponentInfo& info = ecs_registry->get_component_info(idx);
const EcsComponentInfo& info = m_ecs_registry->get_component_info(idx);
info.swap(right_storage->get_component(right_info.storage, idx), left_storage->get_component(left_info.storage, idx));
});
}
Expand Down Expand Up @@ -233,88 +237,50 @@ namespace wmoge {
}
}

void EcsWorld::execute_system(const std::shared_ptr<EcsSystem>& system) {
WG_AUTO_PROFILE_ECS("EcsWorld::execute_system");
Async EcsWorld::schedule_system(const std::shared_ptr<EcsSystem>& system, Async depends_on) {
WG_AUTO_PROFILE_ECS("EcsWorld::schedule_system");

assert(system);
assert(m_system_to_idx.find(system->get_name()) != m_system_to_idx.end());

EcsSystemInfo& system_info = m_systems[m_system_to_idx[system->get_name()]];

switch (system_info.exec_mode) {
case EcsSystemExecMode::OnMain: {
for (const int arch_idx : system_info.filtered_arch) {
EcsArchStorage& storage = *m_arch_storage[arch_idx];
const int size = storage.get_size();
const int start_entity = 0;
const int count = size;

system_info.system->process_batch(*this, storage, start_entity, count);
}

break;
}

case EcsSystemExecMode::OnWorkers: {
TaskParallelFor task(system->get_name(), [&](TaskContext&, int batch_id, int batch_count) {
case EcsSystemExecMode::SingleThread: {
Task task(system_info.system->get_name(), [&](TaskContext&) {
for (const int arch_idx : system_info.filtered_arch) {
EcsArchStorage& storage = *m_arch_storage[arch_idx];
const int size = storage.get_size();
const auto [start_entity, count] = Math::batch_start_count(size, batch_id, batch_count);
EcsArchStorage& storage = *m_arch_storage[arch_idx];
const int size = storage.get_size();
const int start_entity = 0;
const int count = size;

system_info.system->process_batch(*this, storage, start_entity, count);
}

return 0;
});

task.schedule(m_task_manager->get_num_workers(), 1).wait_completed();

break;
return task.schedule(depends_on).as_async();
}

default:
WG_LOG_ERROR("unknown system exec mode");
}
}

void EcsWorld::execute_system(EcsSystem& system) {
WG_AUTO_PROFILE_ECS("EcsWorld::execute_system");

const std::vector<int> filtered_arch = filter_arch_idx(system.get_query());

switch (system.get_exec_mode()) {
case EcsSystemExecMode::OnMain: {
for (const int arch_idx : filtered_arch) {
EcsArchStorage& storage = *m_arch_storage[arch_idx];
const int size = storage.get_size();
const int start_entity = 0;
const int count = size;

system.process_batch(*this, storage, start_entity, count);
}

break;
}

case EcsSystemExecMode::OnWorkers: {
TaskParallelFor task(system.get_name(), [&](TaskContext&, int batch_id, int batch_count) {
for (const int arch_idx : filtered_arch) {
case EcsSystemExecMode::WorkerThreads: {
TaskParallelFor task(system->get_name(), [&](TaskContext&, int batch_id, int batch_count) {
for (const int arch_idx : system_info.filtered_arch) {
EcsArchStorage& storage = *m_arch_storage[arch_idx];
const int size = storage.get_size();
const auto [start_entity, count] = Math::batch_start_count(size, batch_id, batch_count);

system.process_batch(*this, storage, start_entity, count);
system_info.system->process_batch(*this, storage, start_entity, count);
}
return 0;
});

task.schedule(m_task_manager->get_num_workers(), 1).wait_completed();

break;
return task.schedule(m_task_manager->get_num_workers(), 1, depends_on).as_async();
}

default:
WG_LOG_ERROR("unknown system exec mode");
return Async{};
}
}

Expand Down
14 changes: 6 additions & 8 deletions engine/ecs/ecs_world.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@

#pragma once

#include "core/async.hpp"
#include "core/callback_queue.hpp"
#include "core/fast_map.hpp"
#include "core/synchronization.hpp"
#include "core/task_manager.hpp"
#include "ecs/ecs_component.hpp"
#include "ecs/ecs_core.hpp"
#include "ecs/ecs_entity.hpp"
Expand Down Expand Up @@ -112,11 +112,8 @@ namespace wmoge {
/** @brief Registers system within a world */
void register_system(const std::shared_ptr<EcsSystem>& system);

/** @brief Manual trigger of system execution */
void execute_system(const std::shared_ptr<EcsSystem>& system);

/** @brief Manual trigger of system execution */
void execute_system(EcsSystem& system);
/** @brief Schedules system to be executed */
Async schedule_system(const std::shared_ptr<EcsSystem>& system, Async depends_on = Async{});

/** @brief Exec function for each entity matching query*/
void each(const EcsQuery& query, const std::function<void(EcsEntity)>& func);
Expand Down Expand Up @@ -150,8 +147,9 @@ namespace wmoge {

fast_vector<void*> m_attributes;// custom attributes to access context within world

CallbackQueue m_queue; // queue for async world operations, flushed on sync
TaskManager* m_task_manager;// manager for parallel system update
CallbackQueue m_queue; // queue for async world operations, flushed on sync
class TaskManager* m_task_manager;// manager for parallel system update
class EcsRegistry* m_ecs_registry;// registry of the ecs world

SpinMutex m_mutex;
};
Expand Down
6 changes: 5 additions & 1 deletion engine/engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
#include "gfx/gfx_desc_set.hpp"
#include "gfx/gfx_driver.hpp"
#include "gfx/gfx_dynamic_buffers.hpp"
#include "gfx/gfx_pass.hpp"
#include "gfx/gfx_pipeline.hpp"
#include "gfx/gfx_pipeline_cache.hpp"
#include "gfx/gfx_render_pass.hpp"
Expand All @@ -110,6 +109,11 @@
#include "gfx/gfx_vert_format.hpp"
#include "gfx/gfx_vert_format_cache.hpp"

#include "grc/grc_shader.hpp"
#include "grc/grc_shader_class.hpp"
#include "grc/grc_shader_class_builder.hpp"
#include "grc/grc_shader_reflection.hpp"

#include "hgfx/hgfx_pass.hpp"
#include "hgfx/hgfx_pass_base.hpp"
#include "hgfx/hgfx_pass_text.hpp"
Expand Down
8 changes: 3 additions & 5 deletions engine/gfx/gfx_defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
/* SOFTWARE. */
/**********************************************************************************/

#ifndef WMOGE_GFX_DEFS_HPP
#define WMOGE_GFX_DEFS_HPP
#pragma once

#include "core/data.hpp"
#include "core/mask.hpp"
Expand All @@ -35,6 +34,7 @@
#include "math/vec.hpp"

#include <array>
#include <bitset>
#include <cinttypes>

namespace wmoge {
Expand Down Expand Up @@ -500,6 +500,4 @@ namespace wmoge {
int uniform_block_offset_alignment = -1;
};

}// namespace wmoge

#endif//WMOGE_GFX_DEFS_HPP
}// namespace wmoge
Loading

0 comments on commit 68017ee

Please sign in to comment.