diff --git a/Template_Windows/Template_Windows.vcxproj b/Template_Windows/Template_Windows.vcxproj
index 256726128..b03e1aaf4 100644
--- a/Template_Windows/Template_Windows.vcxproj
+++ b/Template_Windows/Template_Windows.vcxproj
@@ -73,7 +73,7 @@
true
true
$(SolutionDir)BUILD\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)
- UseLinkTimeCodeGeneration
+ UseFastLinkTimeCodeGeneration
diff --git a/Tests/Tests.vcxproj b/Tests/Tests.vcxproj
index 22b6960de..ab232b5b4 100644
--- a/Tests/Tests.vcxproj
+++ b/Tests/Tests.vcxproj
@@ -76,7 +76,7 @@
true
true
$(SolutionDir)BUILD\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)
- UseLinkTimeCodeGeneration
+ UseFastLinkTimeCodeGeneration
diff --git a/WickedEngine/wiApplication.cpp b/WickedEngine/wiApplication.cpp
index f48e8a3f1..063f582de 100644
--- a/WickedEngine/wiApplication.cpp
+++ b/WickedEngine/wiApplication.cpp
@@ -52,6 +52,11 @@ namespace wi
wi::initializer::InitializeComponentsAsync();
alwaysactive = wi::arguments::HasArgument("alwaysactive");
+
+ // Note: lua is always initialized immediately on main thread by wi::initializer, so this is safe to do:
+ assert(wi::initializer::IsInitializeFinished(wi::initializer::INITIALIZED_SYSTEM_LUA));
+ Luna::push_global(wi::lua::GetLuaState(), "main", this);
+ Luna::push_global(wi::lua::GetLuaState(), "application", this);
}
void Application::ActivatePath(RenderPath* component, float fadeSeconds, wi::Color fadeColor)
@@ -114,8 +119,6 @@ namespace wi
if (!startup_script)
{
startup_script = true;
- Luna::push_global(wi::lua::GetLuaState(), "main", this);
- Luna::push_global(wi::lua::GetLuaState(), "application", this);
std::string startup_lua_filename = wi::helper::GetCurrentPath() + "/startup.lua";
if (wi::helper::FileExists(startup_lua_filename))
{
@@ -512,6 +515,10 @@ namespace wi
{
params.cursor = wi::font::Draw(std::to_string(wi::renderer::GetShaderErrorCount()) + " shader compilation errors! Check the backlog for more information!\n", params, cmd);
}
+ if (wi::backlog::GetUnseenLogLevelMax() >= wi::backlog::LogLevel::Error)
+ {
+ params.cursor = wi::font::Draw("Errors found, check the backlog for more information!", params, cmd);
+ }
if (infoDisplay.colorgrading_helper)
{
diff --git a/WickedEngine/wiInitializer.cpp b/WickedEngine/wiInitializer.cpp
index a1c0de84d..9787ae40d 100644
--- a/WickedEngine/wiInitializer.cpp
+++ b/WickedEngine/wiInitializer.cpp
@@ -7,24 +7,28 @@
namespace wi::initializer
{
- static bool initializationStarted = false;
+ static std::atomic_bool initializationStarted{ false };
static wi::jobsystem::context ctx;
static wi::Timer timer;
static std::atomic_bool systems[INITIALIZED_SYSTEM_COUNT]{};
void InitializeComponentsImmediate()
{
- if (!initializationStarted)
+ if (IsInitializeFinished())
+ return;
+ if (!initializationStarted.load())
{
InitializeComponentsAsync();
}
- wi::jobsystem::Wait(ctx);
+ WaitForInitializationsToFinish();
}
void InitializeComponentsAsync()
{
+ if (IsInitializeFinished())
+ return;
timer.record();
- initializationStarted = true;
+ initializationStarted.store(true);
std::string ss;
ss += "\n[wi::initializer] Initializing Wicked Engine, please wait...\n";
@@ -57,11 +61,11 @@ namespace wi::initializer
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { wi::gpusortlib::Initialize(); systems[INITIALIZED_SYSTEM_GPUSORTLIB].store(true); });
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { wi::GPUBVH::Initialize(); systems[INITIALIZED_SYSTEM_GPUBVH].store(true); });
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { wi::physics::Initialize(); systems[INITIALIZED_SYSTEM_PHYSICS].store(true); });
- wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { wi::audio::Initialize(); systems[INITIALIZED_SYSTEM_AUDIO].store(true); });
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { wi::TrailRenderer::Initialize(); systems[INITIALIZED_SYSTEM_TRAILRENDERER].store(true); });
- // Initialize this immediately:
+ // Initialize these immediately:
wi::lua::Initialize(); systems[INITIALIZED_SYSTEM_LUA].store(true);
+ wi::audio::Initialize(); systems[INITIALIZED_SYSTEM_AUDIO].store(true);
std::thread([] {
wi::jobsystem::Wait(ctx);
@@ -74,11 +78,16 @@ namespace wi::initializer
{
if (system == INITIALIZED_SYSTEM_COUNT)
{
- return initializationStarted && !wi::jobsystem::IsBusy(ctx);
+ return initializationStarted.load() && !wi::jobsystem::IsBusy(ctx);
}
else
{
return systems[system].load();
}
}
+
+ void WaitForInitializationsToFinish()
+ {
+ wi::jobsystem::Wait(ctx);
+ }
}
diff --git a/WickedEngine/wiInitializer.h b/WickedEngine/wiInitializer.h
index dadb42a92..7088bd8ce 100644
--- a/WickedEngine/wiInitializer.h
+++ b/WickedEngine/wiInitializer.h
@@ -29,4 +29,6 @@ namespace wi::initializer
// Check if systems have been initialized or not
// system : specify to check a specific system, or leave default to check all systems
bool IsInitializeFinished(INITIALIZED_SYSTEM system = INITIALIZED_SYSTEM_COUNT);
+ // Wait for all system initializations to finish
+ void WaitForInitializationsToFinish();
}
diff --git a/WickedEngine/wiJobSystem.cpp b/WickedEngine/wiJobSystem.cpp
index 773c19c98..f6fc13a51 100644
--- a/WickedEngine/wiJobSystem.cpp
+++ b/WickedEngine/wiJobSystem.cpp
@@ -30,6 +30,32 @@ namespace wi::jobsystem
uint32_t groupJobOffset;
uint32_t groupJobEnd;
uint32_t sharedmemory_size;
+ inline void execute()
+ {
+ JobArgs args;
+ args.groupID = groupID;
+ if (sharedmemory_size > 0)
+ {
+ thread_local static wi::vector shared_allocation_data;
+ shared_allocation_data.reserve(sharedmemory_size);
+ args.sharedmemory = shared_allocation_data.data();
+ }
+ else
+ {
+ args.sharedmemory = nullptr;
+ }
+
+ for (uint32_t j = groupJobOffset; j < groupJobEnd; ++j)
+ {
+ args.jobIndex = j;
+ args.groupIndex = j - groupJobOffset;
+ args.isFirstJobInGroup = (j == groupJobOffset);
+ args.isLastJobInGroup = (j == groupJobEnd - 1);
+ task(args);
+ }
+
+ ctx->counter.fetch_sub(1);
+ }
};
struct JobQueue
{
@@ -72,29 +98,7 @@ namespace wi::jobsystem
JobQueue& job_queue = jobQueuePerThread[startingQueue % numThreads];
while (job_queue.pop_front(job))
{
- JobArgs args;
- args.groupID = job.groupID;
- if (job.sharedmemory_size > 0)
- {
- thread_local static wi::vector shared_allocation_data;
- shared_allocation_data.reserve(job.sharedmemory_size);
- args.sharedmemory = shared_allocation_data.data();
- }
- else
- {
- args.sharedmemory = nullptr;
- }
-
- for (uint32_t j = job.groupJobOffset; j < job.groupJobEnd; ++j)
- {
- args.jobIndex = j;
- args.groupIndex = j - job.groupJobOffset;
- args.isFirstJobInGroup = (j == job.groupJobOffset);
- args.isLastJobInGroup = (j == job.groupJobEnd - 1);
- job.task(args);
- }
-
- job.ctx->counter.fetch_sub(1);
+ job.execute();
}
startingQueue++; // go to next queue
}
@@ -305,6 +309,8 @@ namespace wi::jobsystem
void Execute(context& ctx, const std::function& task)
{
+ PriorityResources& res = internal_state.resources[int(ctx.priority)];
+
// Context state is updated:
ctx.counter.fetch_add(1);
@@ -316,7 +322,13 @@ namespace wi::jobsystem
job.groupJobEnd = 1;
job.sharedmemory_size = 0;
- PriorityResources& res = internal_state.resources[int(ctx.priority)];
+ if (res.numThreads <= 1)
+ {
+ // If job system is not yet initialized, or only has one threads, job will be executed immediately here instead of thread:
+ job.execute();
+ return;
+ }
+
res.jobQueuePerThread[res.nextQueue.fetch_add(1) % res.numThreads].push_back(job);
res.wakeCondition.notify_one();
}
@@ -346,10 +358,21 @@ namespace wi::jobsystem
job.groupJobOffset = groupID * groupSize;
job.groupJobEnd = std::min(job.groupJobOffset + groupSize, jobCount);
- res.jobQueuePerThread[res.nextQueue.fetch_add(1) % res.numThreads].push_back(job);
+ if (res.numThreads <= 1)
+ {
+ // If job system is not yet initialized, or only has one threads, job will be executed immediately here instead of thread:
+ job.execute();
+ }
+ else
+ {
+ res.jobQueuePerThread[res.nextQueue.fetch_add(1) % res.numThreads].push_back(job);
+ }
}
- res.wakeCondition.notify_all();
+ if (res.numThreads > 1)
+ {
+ res.wakeCondition.notify_all();
+ }
}
uint32_t DispatchGroupCount(uint32_t jobCount, uint32_t groupSize)
diff --git a/WickedEngine/wiLua.cpp b/WickedEngine/wiLua.cpp
index 638147021..b9ebaf6fe 100644
--- a/WickedEngine/wiLua.cpp
+++ b/WickedEngine/wiLua.cpp
@@ -202,6 +202,9 @@ namespace wi::lua
void Initialize()
{
+ if (lua_internal().m_luaState != nullptr)
+ return; // already initialized
+
wi::Timer timer;
lua_internal().m_luaState = luaL_newstate();
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index f892c38ee..edf7c9d22 100644
--- a/WickedEngine/wiVersion.cpp
+++ b/WickedEngine/wiVersion.cpp
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
- const int revision = 520;
+ const int revision = 521;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);