diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 62845585c..2f099a272 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -13,8 +13,7 @@ Here are some guidelines on contributing. You can submit a pull request with you
- prefer having braces on their own line when writing loops, branches, functions or whatever
- unit of time should be seconds
- use std::string to store strings
-- avoid using c++ stl containers if possible (std::vector is acceptable, or unordered_map, but use them sparingly)
-- avoid new and malloc and allocating on general purpose heap wherever you can. Especially avoid it in frequently called code! Note that by default, c++ std:: lib will allocate on heap.
+- avoid new and malloc and allocating on general purpose heap wherever you can. Especially avoid it in frequently called code
- you can use auto keyword, but aim for as small scope as possible
- using auto keyword for iterators is encouraged
- aim to write const-correct code
diff --git a/Documentation/WickedEngine-Documentation.md b/Documentation/WickedEngine-Documentation.md
index dcb79222c..cb8140b59 100644
--- a/Documentation/WickedEngine-Documentation.md
+++ b/Documentation/WickedEngine-Documentation.md
@@ -42,7 +42,7 @@ Order of execution:
- Implements a compute shader based path tracing solution. In a static scene, the rendering will converge to ground truth.
## System
-You can find out more about the Entity-Component system under ENGINE/System filter in the solution.
+You can find out more about the Entity-Component system and other engine-level systems under ENGINE/System filter in the solution.
- wiECS
- This is the core entity-component relationship handler class: ComponentManager
@@ -51,7 +51,16 @@ You can find out more about the Entity-Component system under ENGINE/System filt
- wiSceneSystem
- This contains Scene, a class that is responsible of holding and managing everything in the world
- - There are also all of the Component types, like TransformComponent, MeshCOmponent, etc.
+ - There are also all of the Component types, like TransformComponent, MeshComponent, etc.
+
+- wiJobSystem
+ - Manages the execution of concurrent tasks
+
+- wiInitializer
+ - Initializes all engine systems
+
+- wiWindowRegistration
+ - This is a platform specific utility to manage the native display window
## Physics
You can find the physics system related functionality under ENGINE/Physics filter in the solution.
@@ -84,3 +93,40 @@ You can see a quickstart guide on the following picture regarding the most commo

+## Helpers
+A collection of engine-level helper classes
+
+- wiArchive
+ - This is used for serializing binary data
+- wiHelper
+ - Many helper utility functions, like screenshot, readfile, messagebox, splitpath, sleep, etc...
+- wiMath
+ - Math related helper functions, like lerp, triangleArea, HueToRGB, etc...
+- wiProfiler
+ - A timer utility that can measure CPU and GPU timings and used across the engine
+- wiRandom
+ - random number generator
+- ...
+
+## Input
+The input interface can be found here
+
+- wiInputManager
+ - This manages all inputs
+ - There are several functions, such as down(), press(), etc. to check button states.
+
+## Network
+TODO: Rewrite the networking systems
+
+## Scripting
+This is the place for the Lua scipt interface. The systems that are bound to Lua have the name of the system prefixed by _BindLua.
+
+- wiLua
+ - The Lua scripting interface
+
+## Tools
+This is the place for tools that use engine-level systems
+
+- wiBackLog
+ - Used to log any messages by any system, from any thread. It can draw itself to the screen. It can execute Lua scripts.
+
diff --git a/WickedEngine/MainComponent.cpp b/WickedEngine/MainComponent.cpp
index f17afeb33..a5189c307 100644
--- a/WickedEngine/MainComponent.cpp
+++ b/WickedEngine/MainComponent.cpp
@@ -284,10 +284,6 @@ void MainComponent::Compose()
#endif
ss << endl;
}
- if (infoDisplay.initstats)
- {
- ss << "System init time: " << wiInitializer::GetInitializationTimeInSeconds() << " sec" << endl;
- }
if (infoDisplay.resolution)
{
ss << "Resolution: " << wiRenderer::GetDevice()->GetScreenWidth() << " x " << wiRenderer::GetDevice()->GetScreenHeight() << endl;
diff --git a/WickedEngine/MainComponent.h b/WickedEngine/MainComponent.h
index 4d8472a2f..581eb680d 100644
--- a/WickedEngine/MainComponent.h
+++ b/WickedEngine/MainComponent.h
@@ -81,8 +81,6 @@ public:
bool cpuinfo = false;
// display resolution info
bool resolution = false;
- // display engine initialization time
- bool initstats = false;
// text size
int size = -1;
};
diff --git a/WickedEngine/WickedEngine.h b/WickedEngine/WickedEngine.h
index 91ebf5b20..fc900605b 100644
--- a/WickedEngine/WickedEngine.h
+++ b/WickedEngine/WickedEngine.h
@@ -8,6 +8,19 @@
#include "CommonInclude.h"
+// High-level interface:
+#include "RenderPath.h"
+#include "RenderPath2D.h"
+#include "RenderPath3D.h"
+#include "RenderPath3D_Forward.h"
+#include "RenderPath3D_Deferred.h"
+#include "RenderPath3D_TiledForward.h"
+#include "RenderPath3D_TiledDeferred.h"
+#include "RenderPath3D_PathTracing.h"
+#include "LoadingScreen.h"
+#include "MainComponent.h"
+
+// Engine-level systems
#include "wiVersion.h"
#include "wiRenderTarget.h"
#include "wiDepthTarget.h"
@@ -55,17 +68,7 @@
#include "wiStartupArguments.h"
#include "wiGPUBVH.h"
#include "wiGPUSortLib.h"
-
-#include "RenderPath.h"
-#include "RenderPath2D.h"
-#include "RenderPath3D.h"
-#include "RenderPath3D_Forward.h"
-#include "RenderPath3D_Deferred.h"
-#include "RenderPath3D_TiledForward.h"
-#include "RenderPath3D_TiledDeferred.h"
-#include "RenderPath3D_PathTracing.h"
-#include "LoadingScreen.h"
-#include "MainComponent.h"
+#include "wiJobSystem.h"
#ifdef _WIN32
diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems b/WickedEngine/WickedEngine_SHARED.vcxitems
index 0756021cd..521d979fb 100644
--- a/WickedEngine/WickedEngine_SHARED.vcxitems
+++ b/WickedEngine/WickedEngine_SHARED.vcxitems
@@ -340,6 +340,7 @@
+
@@ -680,6 +681,7 @@
+
diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems.filters b/WickedEngine/WickedEngine_SHARED.vcxitems.filters
index c6f6c06b6..abdc36fd3 100644
--- a/WickedEngine/WickedEngine_SHARED.vcxitems.filters
+++ b/WickedEngine/WickedEngine_SHARED.vcxitems.filters
@@ -903,9 +903,6 @@
ENGINE\Graphics
-
- ENGINE\Helpers
-
ENGINE\Helpers
@@ -951,9 +948,6 @@
ENGINE\Helpers
-
- ENGINE\Helpers
-
ENGINE\Input
@@ -1149,6 +1143,15 @@
ENGINE\High level interface
+
+ ENGINE\System
+
+
+ ENGINE\System
+
+
+ ENGINE\System
+
@@ -1814,9 +1817,6 @@
ENGINE\Helpers
-
- ENGINE\Helpers
-
ENGINE\Input
@@ -1892,9 +1892,6 @@
ENGINE\Graphics
-
- ENGINE\Helpers
-
ENGINE\Scripting\LuaBindings
@@ -1946,6 +1943,15 @@
ENGINE\High level interface
+
+ ENGINE\System
+
+
+ ENGINE\System
+
+
+ ENGINE\System
+
diff --git a/WickedEngine/wiInitializer.cpp b/WickedEngine/wiInitializer.cpp
index c7fc8d456..489e1709d 100644
--- a/WickedEngine/wiInitializer.cpp
+++ b/WickedEngine/wiInitializer.cpp
@@ -8,64 +8,40 @@ using namespace std;
namespace wiInitializer
{
- static bool finished = false;
- static float initializationTime = 0;
+ bool initializationStarted = false;
void InitializeComponentsImmediate()
{
- if (finished)
- {
- return;
- }
-
- wiTimer timer;
- timer.record();
-
- wiBackLog::post("\n[wiInitializer] Initializing Wicked Engine, please wait...\n");
-
- wiFont::Initialize();
- wiImage::Initialize();
- wiTextureHelper::Initialize();
- wiRenderer::Initialize();
- wiSceneSystem::wiHairParticle::Initialize();
- wiSceneSystem::wiEmittedParticle::Initialize();
- wiCpuInfo::Initialize();
- wiLensFlare::Initialize();
- wiOcean::Initialize();
- wiWidget::LoadShaders();
- wiGPUSortLib::LoadShaders();
- wiGPUBVH::LoadShaders();
- wiPhysicsEngine::Initialize();
- wiSoundEffect::Initialize();
- wiMusic::Initialize();
-
- initializationTime = (float)(timer.elapsed() / 1000.0);
-
- finished = true;
-
+ InitializeComponentsAsync();
+ wiJobSystem::Wait();
}
void InitializeComponentsAsync()
{
- if (finished)
- {
- return;
- }
+ initializationStarted = true;
- std::thread([] {
+ wiBackLog::post("\n[wiInitializer] Initializing Wicked Engine, please wait...\n");
- InitializeComponentsImmediate();
+ wiJobSystem::Initialize();
- }).detach();
+ wiJobSystem::Execute([] { wiFont::Initialize(); });
+ wiJobSystem::Execute([] { wiImage::Initialize(); });
+ wiJobSystem::Execute([] { wiRenderer::Initialize(); });
+ wiJobSystem::Execute([] { wiSoundEffect::Initialize(); wiMusic::Initialize(); });
+ wiJobSystem::Execute([] { wiCpuInfo::Initialize(); });
+ wiJobSystem::Execute([] { wiTextureHelper::Initialize(); });
+ wiJobSystem::Execute([] { wiSceneSystem::wiHairParticle::Initialize(); });
+ wiJobSystem::Execute([] { wiSceneSystem::wiEmittedParticle::Initialize(); });
+ wiJobSystem::Execute([] { wiLensFlare::Initialize(); });
+ wiJobSystem::Execute([] { wiOcean::Initialize(); });
+ wiJobSystem::Execute([] { wiWidget::LoadShaders(); });
+ wiJobSystem::Execute([] { wiGPUSortLib::LoadShaders(); });
+ wiJobSystem::Execute([] { wiGPUBVH::LoadShaders(); });
+ wiJobSystem::Execute([] { wiPhysicsEngine::Initialize(); });
}
bool IsInitializeFinished()
{
- return finished;
- }
-
- float GetInitializationTimeInSeconds()
- {
- return initializationTime;
+ return initializationStarted && !wiJobSystem::IsBusy();
}
}
\ No newline at end of file
diff --git a/WickedEngine/wiInitializer.h b/WickedEngine/wiInitializer.h
index 32c52736c..5e4f2a4c6 100644
--- a/WickedEngine/wiInitializer.h
+++ b/WickedEngine/wiInitializer.h
@@ -9,8 +9,6 @@ namespace wiInitializer
void InitializeComponentsAsync();
// Check if systems have been initialized or not
bool IsInitializeFinished();
- // Check the time it took to initialize systems
- float GetInitializationTimeInSeconds();
}
diff --git a/WickedEngine/wiJobSystem.cpp b/WickedEngine/wiJobSystem.cpp
new file mode 100644
index 000000000..60eca04e4
--- /dev/null
+++ b/WickedEngine/wiJobSystem.cpp
@@ -0,0 +1,87 @@
+#include "wiJobSystem.h"
+#include "wiSpinLock.h"
+#include "wiBackLog.h"
+
+#include
+#include
+#include
+#include
+
+namespace wiJobSystem
+{
+ struct Job
+ {
+ std::function func;
+
+ Job() {}
+ Job(const std::function& func) :func(func) {}
+ };
+ std::deque jobPool;
+ wiSpinLock jobLock;
+ std::atomic executionMask = 0;
+
+ void Initialize()
+ {
+ unsigned int numCores = std::thread::hardware_concurrency();
+ numCores = min(numCores, 64); // execution mask is 64 bits
+
+ for (unsigned int threadID = 0; threadID < numCores; ++threadID)
+ {
+ std::thread([threadID] {
+
+ while (true)
+ {
+ Job job;
+ bool working = false;
+ const uint64_t threadMask = 1ull << threadID;
+
+ jobLock.lock();
+ {
+ if (!jobPool.empty())
+ {
+ executionMask.fetch_or(threadMask); // mark this thread as working
+ working = true;
+ job = std::move(jobPool.front());
+ jobPool.pop_front();
+ }
+ }
+ jobLock.unlock();
+
+ if (working)
+ {
+ job.func(); // execute job
+ executionMask.fetch_and(~threadMask); // mark this thread as idle
+ }
+ else
+ {
+ std::this_thread::yield();
+ }
+ }
+
+ }).detach();
+ }
+
+ std::stringstream ss("");
+ ss << "wiJobSystem Initialized with " << numCores << " threads";
+ wiBackLog::post(ss.str().c_str());
+ }
+
+ void Execute(const std::function& func)
+ {
+ jobLock.lock();
+ jobPool.push_back(Job(std::move(func)));
+ jobLock.unlock();
+ }
+
+ bool IsBusy()
+ {
+ return executionMask.load() > 0;
+ }
+
+ void Wait()
+ {
+ jobLock.lock();
+ while (IsBusy()) {}
+ jobLock.unlock();
+ }
+}
diff --git a/WickedEngine/wiJobSystem.h b/WickedEngine/wiJobSystem.h
new file mode 100644
index 000000000..439584686
--- /dev/null
+++ b/WickedEngine/wiJobSystem.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include
+
+namespace wiJobSystem
+{
+ void Initialize();
+
+ // Add a job to execute asynchronously
+ void Execute(const std::function& func);
+
+ // Check if any threads are working currently or not
+ bool IsBusy();
+
+ // Wait until all threads become idle
+ void Wait();
+}
diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp
index f32f658c2..74f7dfcac 100644
--- a/WickedEngine/wiRenderer.cpp
+++ b/WickedEngine/wiRenderer.cpp
@@ -48,23 +48,23 @@ namespace wiRenderer
GraphicsDevice* graphicsDevice = nullptr;
-static Sampler *samplers[SSLOT_COUNT] = {};
-static VertexShader *vertexShaders[VSTYPE_LAST] = {};
-static PixelShader *pixelShaders[PSTYPE_LAST] = {};
-static GeometryShader *geometryShaders[GSTYPE_LAST] = {};
-static HullShader *hullShaders[HSTYPE_LAST] = {};
-static DomainShader *domainShaders[DSTYPE_LAST] = {};
-static ComputeShader *computeShaders[CSTYPE_LAST] = {};
-static VertexLayout *vertexLayouts[VLTYPE_LAST] = {};
-static RasterizerState *rasterizers[RSTYPE_LAST] = {};
-static DepthStencilState *depthStencils[DSSTYPE_LAST] = {};
-static BlendState *blendStates[BSTYPE_LAST] = {};
-static GPUBuffer *constantBuffers[CBTYPE_LAST] = {};
-static GPUBuffer *resourceBuffers[RBTYPE_LAST] = {};
-static Texture *textures[TEXTYPE_LAST] = {};
-static Sampler *customsamplers[SSTYPE_LAST] = {};
+Sampler *samplers[SSLOT_COUNT] = {};
+VertexShader *vertexShaders[VSTYPE_LAST] = {};
+PixelShader *pixelShaders[PSTYPE_LAST] = {};
+GeometryShader *geometryShaders[GSTYPE_LAST] = {};
+HullShader *hullShaders[HSTYPE_LAST] = {};
+DomainShader *domainShaders[DSTYPE_LAST] = {};
+ComputeShader *computeShaders[CSTYPE_LAST] = {};
+VertexLayout *vertexLayouts[VLTYPE_LAST] = {};
+RasterizerState *rasterizers[RSTYPE_LAST] = {};
+DepthStencilState *depthStencils[DSSTYPE_LAST] = {};
+BlendState *blendStates[BSTYPE_LAST] = {};
+GPUBuffer *constantBuffers[CBTYPE_LAST] = {};
+GPUBuffer *resourceBuffers[RBTYPE_LAST] = {};
+Texture *textures[TEXTYPE_LAST] = {};
+Sampler *customsamplers[SSTYPE_LAST] = {};
-static string SHADERPATH = "shaders/";
+string SHADERPATH = "shaders/";
LinearAllocator frameAllocators[GRAPHICSTHREAD_COUNT];
GPURingBuffer dynamicVertexBufferPools[GRAPHICSTHREAD_COUNT] = {};
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index 26498fddd..e080e1dd2 100644
--- a/WickedEngine/wiVersion.cpp
+++ b/WickedEngine/wiVersion.cpp
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 22;
// minor bug fixes, alterations, refactors, updates
- const int revision = 0;
+ const int revision = 1;
long GetVersion()