From c7f5c1a17ea5de604133ea729df125bd9d6780df Mon Sep 17 00:00:00 2001 From: Turanszki Janos Date: Sun, 31 May 2020 00:38:03 +0100 Subject: [PATCH] job system updates, cpu performance improvements --- Editor/Editor.cpp | 24 +- Editor/ObjectWindow.cpp | 2 +- Tests/Tests.cpp | 12 +- Tests/Tests.vcxproj | 3 - WickedEngine/LoadingScreen.cpp | 6 +- WickedEngine/LoadingScreen.h | 4 +- WickedEngine/RenderPath3D_Deferred.cpp | 15 +- WickedEngine/RenderPath3D_Forward.cpp | 15 +- WickedEngine/RenderPath3D_PathTracing.cpp | 5 +- WickedEngine/RenderPath3D_TiledDeferred.cpp | 15 +- WickedEngine/RenderPath3D_TiledForward.cpp | 15 +- WickedEngine/wiInitializer.cpp | 26 +- WickedEngine/wiJobSystem.cpp | 84 ++- WickedEngine/wiJobSystem.h | 23 +- WickedEngine/wiPhysicsEngine.h | 8 +- WickedEngine/wiPhysicsEngine_Bullet.cpp | 44 +- WickedEngine/wiRenderer.cpp | 769 +++++++++++--------- WickedEngine/wiScene.cpp | 451 +++++------- WickedEngine/wiScene.h | 137 +--- WickedEngine/wiVersion.cpp | 2 +- 20 files changed, 815 insertions(+), 845 deletions(-) diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 8b7440bc8..98236c250 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -444,17 +444,17 @@ void EditorComponent::Load() #endif // PLATFORM_UWP wiJobSystem::context ctx; - wiJobSystem::Execute(ctx, [this] { pointLightTex = wiResourceManager::Load("images/pointlight.dds"); }); - wiJobSystem::Execute(ctx, [this] { spotLightTex = wiResourceManager::Load("images/spotlight.dds"); }); - wiJobSystem::Execute(ctx, [this] { dirLightTex = wiResourceManager::Load("images/directional_light.dds"); }); - wiJobSystem::Execute(ctx, [this] { areaLightTex = wiResourceManager::Load("images/arealight.dds"); }); - wiJobSystem::Execute(ctx, [this] { decalTex = wiResourceManager::Load("images/decal.dds"); }); - wiJobSystem::Execute(ctx, [this] { forceFieldTex = wiResourceManager::Load("images/forcefield.dds"); }); - wiJobSystem::Execute(ctx, [this] { emitterTex = wiResourceManager::Load("images/emitter.dds"); }); - wiJobSystem::Execute(ctx, [this] { hairTex = wiResourceManager::Load("images/hair.dds"); }); - wiJobSystem::Execute(ctx, [this] { cameraTex = wiResourceManager::Load("images/camera.dds"); }); - wiJobSystem::Execute(ctx, [this] { armatureTex = wiResourceManager::Load("images/armature.dds"); }); - wiJobSystem::Execute(ctx, [this] { soundTex = wiResourceManager::Load("images/sound.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { pointLightTex = wiResourceManager::Load("images/pointlight.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { spotLightTex = wiResourceManager::Load("images/spotlight.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { dirLightTex = wiResourceManager::Load("images/directional_light.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { areaLightTex = wiResourceManager::Load("images/arealight.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { decalTex = wiResourceManager::Load("images/decal.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { forceFieldTex = wiResourceManager::Load("images/forcefield.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { emitterTex = wiResourceManager::Load("images/emitter.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { hairTex = wiResourceManager::Load("images/hair.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { cameraTex = wiResourceManager::Load("images/camera.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { armatureTex = wiResourceManager::Load("images/armature.dds"); }); + wiJobSystem::Execute(ctx, [this](wiJobArgs args) { soundTex = wiResourceManager::Load("images/sound.dds"); }); // wait for ctx is at the end of this function! translator.enabled = false; @@ -748,7 +748,7 @@ void EditorComponent::Load() params.extensions.push_back("glb"); wiHelper::FileDialog(params, [&](std::string fileName) { - main->loader->addLoadingFunction([=] { + main->loader->addLoadingFunction([=](wiJobArgs args) { string extension = wiHelper::toUpper(wiHelper::GetExtensionFromFileName(fileName)); if (!extension.compare("WISCENE")) // engine-serialized diff --git a/Editor/ObjectWindow.cpp b/Editor/ObjectWindow.cpp index 8842fecae..fc2bef51d 100644 --- a/Editor/ObjectWindow.cpp +++ b/Editor/ObjectWindow.cpp @@ -501,7 +501,7 @@ ObjectWindow::ObjectWindow(EditorComponent* editor) : editor(editor) } else if (gen_type == UV_GEN_GENERATE_ATLAS) { - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { it.second = GenerateMeshAtlas(mesh, (uint32_t)lightmapResolutionSlider->GetValue()); }); } diff --git a/Tests/Tests.cpp b/Tests/Tests.cpp index 28e585a33..e79d0051c 100644 --- a/Tests/Tests.cpp +++ b/Tests/Tests.cpp @@ -265,7 +265,7 @@ void TestsRenderer::Load() case 18: { wiScene::LoadModel("../models/suzanne.wiscene"); - //wiProfiler::SetEnabled(true); + wiProfiler::SetEnabled(true); Scene& scene = wiScene::GetScene(); scene.Entity_CreateLight("testlight", XMFLOAT3(0, 2, -4), XMFLOAT3(1, 1, 1), 4, 10); Entity suzanne = scene.Entity_FindByName("Suzanne"); @@ -367,10 +367,10 @@ void TestsRenderer::RunJobSystemTest() // Execute test { timer.record(); - wiJobSystem::Execute(ctx, []{ wiHelper::Spin(100); }); - wiJobSystem::Execute(ctx, []{ wiHelper::Spin(100); }); - wiJobSystem::Execute(ctx, []{ wiHelper::Spin(100); }); - wiJobSystem::Execute(ctx, []{ wiHelper::Spin(100); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args){ wiHelper::Spin(100); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args){ wiHelper::Spin(100); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args){ wiHelper::Spin(100); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args){ wiHelper::Spin(100); }); wiJobSystem::Wait(ctx); double time = timer.elapsed(); ss << "wiJobSystem::Execute() took " << time << " milliseconds" << std::endl; @@ -395,7 +395,7 @@ void TestsRenderer::RunJobSystemTest() { std::vector dataSet(itemCount); timer.record(); - wiJobSystem::Dispatch(ctx, itemCount, 1000, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, itemCount, 1000, [&](wiJobArgs args) { dataSet[args.jobIndex].UpdateCamera(); }); wiJobSystem::Wait(ctx); diff --git a/Tests/Tests.vcxproj b/Tests/Tests.vcxproj index 4ebb97815..ff0dcb7b5 100644 --- a/Tests/Tests.vcxproj +++ b/Tests/Tests.vcxproj @@ -193,9 +193,6 @@ - - {8c15dc72-70c8-4212-b046-0b166a688a7c} - {06163dcb-b183-4ed9-9c62-13ef1658e049} diff --git a/WickedEngine/LoadingScreen.cpp b/WickedEngine/LoadingScreen.cpp index 1b2d855f0..2f1514ffc 100644 --- a/WickedEngine/LoadingScreen.cpp +++ b/WickedEngine/LoadingScreen.cpp @@ -8,7 +8,7 @@ bool LoadingScreen::isActive() return wiJobSystem::IsBusy(ctx_main) || wiJobSystem::IsBusy(ctx_finish); } -void LoadingScreen::addLoadingFunction(function loadingFunction) +void LoadingScreen::addLoadingFunction(function loadingFunction) { if (loadingFunction != nullptr) { @@ -18,7 +18,7 @@ void LoadingScreen::addLoadingFunction(function loadingFunction) void LoadingScreen::addLoadingComponent(RenderPath* component, MainComponent* main, float fadeSeconds, wiColor fadeColor) { - addLoadingFunction([=] { + addLoadingFunction([=](wiJobArgs args) { component->Load(); }); onFinished([=] { @@ -43,7 +43,7 @@ void LoadingScreen::Start() { wiJobSystem::Execute(ctx_main, x); } - wiJobSystem::Execute(ctx_finish, [this] { + wiJobSystem::Execute(ctx_finish, [this](wiJobArgs args) { wiJobSystem::Wait(ctx_main); finish(); }); diff --git a/WickedEngine/LoadingScreen.h b/WickedEngine/LoadingScreen.h index 4ce618e73..b55749e4e 100644 --- a/WickedEngine/LoadingScreen.h +++ b/WickedEngine/LoadingScreen.h @@ -13,13 +13,13 @@ class LoadingScreen : private: wiJobSystem::context ctx_main; wiJobSystem::context ctx_finish; - std::vector> tasks; + std::vector> tasks; std::function finish; public: //Add a loading task which should be executed //use std::bind( YourFunctionPointer ) - void addLoadingFunction(std::function loadingFunction); + void addLoadingFunction(std::function loadingFunction); //Helper for loading a whole renderable component void addLoadingComponent(RenderPath* component, MainComponent* main, float fadeSeconds = 0, wiColor fadeColor = wiColor(0, 0, 0, 255)); //Set a function that should be called when the loading finishes diff --git a/WickedEngine/RenderPath3D_Deferred.cpp b/WickedEngine/RenderPath3D_Deferred.cpp index 88fe221f7..44980e201 100644 --- a/WickedEngine/RenderPath3D_Deferred.cpp +++ b/WickedEngine/RenderPath3D_Deferred.cpp @@ -136,16 +136,17 @@ void RenderPath3D_Deferred::Render() const CommandList cmd; cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderFrameSetUp(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderFrameSetUp(cmd); }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderShadows(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderShadows(cmd); }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderReflections(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderReflections(cmd); }); // Main scene: cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); device->Barrier(&GPUBarrier::Image(&depthBuffer, IMAGE_LAYOUT_DEPTHSTENCIL_READONLY, IMAGE_LAYOUT_DEPTHSTENCIL), 1, cmd); @@ -192,8 +193,9 @@ void RenderPath3D_Deferred::Render() const }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); wiRenderer::BindCommonResources(cmd); @@ -218,8 +220,9 @@ void RenderPath3D_Deferred::Render() const cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); wiRenderer::BindCommonResources(cmd); diff --git a/WickedEngine/RenderPath3D_Forward.cpp b/WickedEngine/RenderPath3D_Forward.cpp index 860c2c193..5b5a89e2e 100644 --- a/WickedEngine/RenderPath3D_Forward.cpp +++ b/WickedEngine/RenderPath3D_Forward.cpp @@ -89,16 +89,17 @@ void RenderPath3D_Forward::Render() const CommandList cmd; cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderFrameSetUp(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderFrameSetUp(cmd); }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderShadows(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderShadows(cmd); }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderReflections(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderReflections(cmd); }); // Main scene: cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); device->Barrier(&GPUBarrier::Image(&depthBuffer, IMAGE_LAYOUT_DEPTHSTENCIL_READONLY, IMAGE_LAYOUT_DEPTHSTENCIL), 1, cmd); @@ -154,8 +155,9 @@ void RenderPath3D_Forward::Render() const }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); // Opaque Scene: @@ -184,8 +186,9 @@ void RenderPath3D_Forward::Render() const }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); wiRenderer::BindCommonResources(cmd); diff --git a/WickedEngine/RenderPath3D_PathTracing.cpp b/WickedEngine/RenderPath3D_PathTracing.cpp index c00f8b25a..d4ff28341 100644 --- a/WickedEngine/RenderPath3D_PathTracing.cpp +++ b/WickedEngine/RenderPath3D_PathTracing.cpp @@ -114,7 +114,7 @@ void RenderPath3D_PathTracing::Render() const // Setup: cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { wiRenderer::UpdateRenderData(cmd); @@ -126,8 +126,9 @@ void RenderPath3D_PathTracing::Render() const // Main scene: cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::BindCommonResources(cmd); if (wiRenderer::GetRaytraceDebugBVHVisualizerEnabled()) diff --git a/WickedEngine/RenderPath3D_TiledDeferred.cpp b/WickedEngine/RenderPath3D_TiledDeferred.cpp index 7a7830f64..a6f5f909e 100644 --- a/WickedEngine/RenderPath3D_TiledDeferred.cpp +++ b/WickedEngine/RenderPath3D_TiledDeferred.cpp @@ -41,16 +41,17 @@ void RenderPath3D_TiledDeferred::Render() const CommandList cmd; cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderFrameSetUp(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderFrameSetUp(cmd); }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderShadows(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderShadows(cmd); }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderReflections(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderReflections(cmd); }); // Main scene: cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); device->Barrier(&GPUBarrier::Image(&depthBuffer, IMAGE_LAYOUT_DEPTHSTENCIL_READONLY, IMAGE_LAYOUT_DEPTHSTENCIL), 1, cmd); @@ -97,8 +98,9 @@ void RenderPath3D_TiledDeferred::Render() const }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); wiRenderer::BindCommonResources(cmd); @@ -147,8 +149,9 @@ void RenderPath3D_TiledDeferred::Render() const }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); wiRenderer::BindCommonResources(cmd); diff --git a/WickedEngine/RenderPath3D_TiledForward.cpp b/WickedEngine/RenderPath3D_TiledForward.cpp index bc164cc6d..06d4823f4 100644 --- a/WickedEngine/RenderPath3D_TiledForward.cpp +++ b/WickedEngine/RenderPath3D_TiledForward.cpp @@ -14,16 +14,17 @@ void RenderPath3D_TiledForward::Render() const CommandList cmd; cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderFrameSetUp(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderFrameSetUp(cmd); }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderShadows(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderShadows(cmd); }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, cmd] { RenderReflections(cmd); }); + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { RenderReflections(cmd); }); // Main scene: cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); device->Barrier(&GPUBarrier::Image(&depthBuffer, IMAGE_LAYOUT_DEPTHSTENCIL_READONLY, IMAGE_LAYOUT_DEPTHSTENCIL), 1, cmd); @@ -79,8 +80,9 @@ void RenderPath3D_TiledForward::Render() const }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::ComputeTiledLightCulling( depthBuffer_Copy, cmd @@ -114,8 +116,9 @@ void RenderPath3D_TiledForward::Render() const }); cmd = device->BeginCommandList(); - wiJobSystem::Execute(ctx, [this, device, cmd] { + wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) { + GraphicsDevice* device = wiRenderer::GetDevice(); wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), cmd); wiRenderer::BindCommonResources(cmd); diff --git a/WickedEngine/wiInitializer.cpp b/WickedEngine/wiInitializer.cpp index 66a15eb5b..23f72d025 100644 --- a/WickedEngine/wiInitializer.cpp +++ b/WickedEngine/wiInitializer.cpp @@ -24,19 +24,19 @@ namespace wiInitializer wiJobSystem::Initialize(); - wiJobSystem::Execute(ctx, [] { wiFont::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiImage::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiInput::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiRenderer::Initialize(); wiWidget::LoadShaders(); }); - wiJobSystem::Execute(ctx, [] { wiAudio::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiNetwork::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiTextureHelper::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiScene::wiHairParticle::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiScene::wiEmittedParticle::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiOcean::Initialize(); }); - wiJobSystem::Execute(ctx, [] { wiGPUSortLib::LoadShaders(); }); - wiJobSystem::Execute(ctx, [] { wiGPUBVH::LoadShaders(); }); - wiJobSystem::Execute(ctx, [] { wiPhysicsEngine::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiFont::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiImage::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiInput::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiRenderer::Initialize(); wiWidget::LoadShaders(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiAudio::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiNetwork::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiTextureHelper::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiScene::wiHairParticle::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiScene::wiEmittedParticle::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiOcean::Initialize(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiGPUSortLib::LoadShaders(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiGPUBVH::LoadShaders(); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { wiPhysicsEngine::Initialize(); }); } diff --git a/WickedEngine/wiJobSystem.cpp b/WickedEngine/wiJobSystem.cpp index bbb9d35a5..641d58e02 100644 --- a/WickedEngine/wiJobSystem.cpp +++ b/WickedEngine/wiJobSystem.cpp @@ -13,8 +13,12 @@ namespace wiJobSystem { struct Job { - std::function task; context* ctx; + std::function task; + uint32_t groupID; + uint32_t groupJobOffset; + uint32_t groupJobEnd; + uint32_t sharedmemory_size; }; uint32_t numThreads = 0; @@ -28,7 +32,26 @@ namespace wiJobSystem Job job; if (jobQueue.pop_front(job)) { - job.task(); // execute job + wiJobArgs args; + args.groupID = job.groupID; + if (job.sharedmemory_size > 0) + { + args.sharedmemory = alloca(job.sharedmemory_size); + } + else + { + args.sharedmemory = nullptr; + } + + for (uint32_t i = job.groupJobOffset; i < job.groupJobEnd; ++i) + { + args.jobIndex = i; + args.groupIndex = i - job.groupJobOffset; + args.isFirstJobInGroup = (i == job.groupJobOffset); + args.isLastJobInGroup = (i == job.groupJobEnd - 1); + job.task(args); + } + job.ctx->counter.fetch_sub(1); return true; } @@ -47,8 +70,6 @@ namespace wiJobSystem { std::thread worker([] { - std::function job; - while (true) { if (!work()) @@ -66,7 +87,7 @@ namespace wiJobSystem HANDLE handle = (HANDLE)worker.native_handle(); // Put each thread on to dedicated core: - DWORD_PTR affinityMask = 1ull << threadID; + DWORD_PTR affinityMask = 1ull << threadID; DWORD_PTR affinity_result = SetThreadAffinityMask(handle, affinityMask); assert(affinity_result > 0); @@ -80,7 +101,7 @@ namespace wiJobSystem HRESULT hr = SetThreadDescription(handle, wss.str().c_str()); assert(SUCCEEDED(hr)); #endif // _WIN32 - + worker.detach(); } @@ -94,59 +115,64 @@ namespace wiJobSystem return numThreads; } - void Execute(context& ctx, const std::function& job) + void Execute(context& ctx, const std::function& task) { // Context state is updated: ctx.counter.fetch_add(1); + Job job; + job.ctx = &ctx; + job.task = task; + job.groupID = 0; + job.groupJobOffset = 0; + job.groupJobEnd = 1; + job.sharedmemory_size = 0; + // Try to push a new job until it is pushed successfully: - while (!jobQueue.push_back({ job, &ctx })) { wakeCondition.notify_all(); } + while (!jobQueue.push_back(job)) { wakeCondition.notify_all(); } // Wake any one thread that might be sleeping: wakeCondition.notify_one(); } - void Dispatch(context& ctx, uint32_t jobCount, uint32_t groupSize, const std::function& job) + void Dispatch(context& ctx, uint32_t jobCount, uint32_t groupSize, const std::function& task, size_t sharedmemory_size) { if (jobCount == 0 || groupSize == 0) { return; } - // Calculate the amount of job groups to dispatch (overestimate, or "ceil"): - const uint32_t groupCount = (jobCount + groupSize - 1) / groupSize; + const uint32_t groupCount = DispatchGroupCount(jobCount, groupSize); // Context state is updated: ctx.counter.fetch_add(groupCount); - for (uint32_t groupIndex = 0; groupIndex < groupCount; ++groupIndex) + Job job; + job.ctx = &ctx; + job.task = task; + job.sharedmemory_size = (uint32_t)sharedmemory_size; + + for (uint32_t groupID = 0; groupID < groupCount; ++groupID) { // For each group, generate one real job: - const auto& jobGroup = [jobCount, groupSize, job, groupIndex]() { - - // Calculate the current group's offset into the jobs: - const uint32_t groupJobOffset = groupIndex * groupSize; - const uint32_t groupJobEnd = std::min(groupJobOffset + groupSize, jobCount); - - wiJobDispatchArgs args; - args.groupIndex = groupIndex; - - // Inside the group, loop through all job indices and execute job for each index: - for (uint32_t i = groupJobOffset; i < groupJobEnd; ++i) - { - args.jobIndex = i; - job(args); - } - }; + job.groupID = groupID; + job.groupJobOffset = groupID * groupSize; + job.groupJobEnd = std::min(job.groupJobOffset + groupSize, jobCount); // Try to push a new job until it is pushed successfully: - while (!jobQueue.push_back({ jobGroup, &ctx })) { wakeCondition.notify_all(); } + while (!jobQueue.push_back(job)) { wakeCondition.notify_all(); } } // Wake any threads that might be sleeping: wakeCondition.notify_all(); } + uint32_t DispatchGroupCount(uint32_t jobCount, uint32_t groupSize) + { + // Calculate the amount of job groups to dispatch (overestimate, or "ceil"): + return (jobCount + groupSize - 1) / groupSize; + } + bool IsBusy(const context& ctx) { // Whenever the context label is greater than zero, it means that there is still work that needs to be done diff --git a/WickedEngine/wiJobSystem.h b/WickedEngine/wiJobSystem.h index 31fc096fa..209c09214 100644 --- a/WickedEngine/wiJobSystem.h +++ b/WickedEngine/wiJobSystem.h @@ -3,10 +3,14 @@ #include #include -struct wiJobDispatchArgs +struct wiJobArgs { - uint32_t jobIndex; - uint32_t groupIndex; + uint32_t jobIndex; // job index relative to dispatch (like SV_DispatchThreadID in HLSL) + uint32_t groupID; // group index relative to dispatch (like SV_GroupID in HLSL) + uint32_t groupIndex; // job index relative to group (like SV_GroupIndex in HLSL) + bool isFirstJobInGroup; // is the current job the first one in the group? + bool isLastJobInGroup; // is the current job the last one in the group? + void* sharedmemory; // stack memory shared within the current group (jobs within a group execute serially) }; namespace wiJobSystem @@ -21,14 +25,17 @@ namespace wiJobSystem std::atomic counter{ 0 }; }; - // Add a job to execute asynchronously. Any idle thread will execute this job. - void Execute(context& ctx, const std::function& job); + // Add a task to execute asynchronously. Any idle thread will execute this. + void Execute(context& ctx, const std::function& task); - // Divide a job onto multiple jobs and execute in parallel. + // Divide a task onto multiple jobs and execute in parallel. // jobCount : how many jobs to generate for this task. // groupSize : how many jobs to execute per thread. Jobs inside a group execute serially. It might be worth to increase for small jobs - // func : receives a wiJobDispatchArgs as parameter - void Dispatch(context& ctx, uint32_t jobCount, uint32_t groupSize, const std::function& job); + // task : receives a wiJobArgs as parameter + void Dispatch(context& ctx, uint32_t jobCount, uint32_t groupSize, const std::function& task, size_t sharedmemory_size = 0); + + // Returns the amount of job groups that will be created for a set number of jobs and group size + uint32_t DispatchGroupCount(uint32_t jobCount, uint32_t groupSize); // Check if any threads are working currently or not bool IsBusy(const context& ctx); diff --git a/WickedEngine/wiPhysicsEngine.h b/WickedEngine/wiPhysicsEngine.h index 819d2e53f..9db7b3d51 100644 --- a/WickedEngine/wiPhysicsEngine.h +++ b/WickedEngine/wiPhysicsEngine.h @@ -12,13 +12,7 @@ namespace wiPhysicsEngine void RunPhysicsUpdateSystem( wiJobSystem::context& ctx, - const wiScene::WeatherComponent& weather, - const wiECS::ComponentManager& armatures, - wiECS::ComponentManager& transforms, - wiECS::ComponentManager& meshes, - wiECS::ComponentManager& objects, - wiECS::ComponentManager& rigidbodies, - wiECS::ComponentManager& softbodies, + wiScene::Scene& scene, float dt ); } diff --git a/WickedEngine/wiPhysicsEngine_Bullet.cpp b/WickedEngine/wiPhysicsEngine_Bullet.cpp index 69b6e2119..42de44c2d 100644 --- a/WickedEngine/wiPhysicsEngine_Bullet.cpp +++ b/WickedEngine/wiPhysicsEngine_Bullet.cpp @@ -285,13 +285,7 @@ namespace wiPhysicsEngine void RunPhysicsUpdateSystem( wiJobSystem::context& ctx, - const WeatherComponent& weather, - const ComponentManager& armatures, - ComponentManager& transforms, - ComponentManager& meshes, - ComponentManager& objects, - ComponentManager& rigidbodies, - ComponentManager& softbodies, + Scene& scene, float dt ) { @@ -300,23 +294,21 @@ namespace wiPhysicsEngine return; } - wiJobSystem::Wait(ctx); - auto range = wiProfiler::BeginRangeCPU("Physics"); - btVector3 wind = btVector3(weather.windDirection.x, weather.windDirection.y, weather.windDirection.z); + btVector3 wind = btVector3(scene.weather.windDirection.x, scene.weather.windDirection.y, scene.weather.windDirection.z); // System will register rigidbodies to objects, and update physics engine state for kinematics: - wiJobSystem::Dispatch(ctx, (uint32_t)rigidbodies.GetCount(), 256, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)scene.rigidbodies.GetCount(), 256, [&](wiJobArgs args) { - RigidBodyPhysicsComponent& physicscomponent = rigidbodies[args.jobIndex]; - Entity entity = rigidbodies.GetEntity(args.jobIndex); + RigidBodyPhysicsComponent& physicscomponent = scene.rigidbodies[args.jobIndex]; + Entity entity = scene.rigidbodies.GetEntity(args.jobIndex); if (physicscomponent.physicsobject == nullptr) { - TransformComponent& transform = *transforms.GetComponent(entity); - const ObjectComponent& object = *objects.GetComponent(entity); - const MeshComponent& mesh = *meshes.GetComponent(object.meshID); + TransformComponent& transform = *scene.transforms.GetComponent(entity); + const ObjectComponent& object = *scene.objects.GetComponent(entity); + const MeshComponent& mesh = *scene.meshes.GetComponent(object.meshID); physicsLock.lock(); AddRigidBody(entity, physicscomponent, mesh, transform); physicsLock.unlock(); @@ -340,7 +332,7 @@ namespace wiPhysicsEngine // For kinematic object, system updates physics state, else the physics updates system state: if (physicscomponent.IsKinematic()) { - TransformComponent& transform = *transforms.GetComponent(entity); + TransformComponent& transform = *scene.transforms.GetComponent(entity); btMotionState* motionState = rigidbody->getMotionState(); btTransform physicsTransform; @@ -357,12 +349,12 @@ namespace wiPhysicsEngine }); // System will register softbodies to meshes and update physics engine state: - wiJobSystem::Dispatch(ctx, (uint32_t)softbodies.GetCount(), 1, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)scene.softbodies.GetCount(), 1, [&](wiJobArgs args) { - SoftBodyPhysicsComponent& physicscomponent = softbodies[args.jobIndex]; - Entity entity = softbodies.GetEntity(args.jobIndex); - MeshComponent& mesh = *meshes.GetComponent(entity); - const ArmatureComponent* armature = mesh.IsSkinned() ? armatures.GetComponent(mesh.armatureID) : nullptr; + SoftBodyPhysicsComponent& physicscomponent = scene.softbodies[args.jobIndex]; + Entity entity = scene.softbodies.GetEntity(args.jobIndex); + MeshComponent& mesh = *scene.meshes.GetComponent(entity); + const ArmatureComponent* armature = mesh.IsSkinned() ? scene.armatures.GetComponent(mesh.armatureID) : nullptr; mesh.SetDynamic(true); if (physicscomponent._flags & SoftBodyPhysicsComponent::FORCE_RESET) @@ -423,7 +415,7 @@ namespace wiPhysicsEngine btRigidBody* rigidbody = btRigidBody::upcast(collisionobject); if (rigidbody != nullptr) { - RigidBodyPhysicsComponent* physicscomponent = rigidbodies.GetComponent(entity); + RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(entity); if (physicscomponent == nullptr) { dynamicsWorld->removeRigidBody(rigidbody); @@ -434,7 +426,7 @@ namespace wiPhysicsEngine // Feedback non-kinematic objects to system: if(!physicscomponent->IsKinematic()) { - TransformComponent& transform = *transforms.GetComponent(entity); + TransformComponent& transform = *scene.transforms.GetComponent(entity); btMotionState* motionState = rigidbody->getMotionState(); btTransform physicsTransform; @@ -454,7 +446,7 @@ namespace wiPhysicsEngine if (softbody != nullptr) { - SoftBodyPhysicsComponent* physicscomponent = softbodies.GetComponent(entity); + SoftBodyPhysicsComponent* physicscomponent = scene.softbodies.GetComponent(entity); if (physicscomponent == nullptr) { ((btSoftRigidDynamicsWorld*)dynamicsWorld.get())->removeSoftBody(softbody); @@ -462,7 +454,7 @@ namespace wiPhysicsEngine continue; } - MeshComponent& mesh = *meshes.GetComponent(entity); + MeshComponent& mesh = *scene.meshes.GetComponent(entity); // System mesh aabb will be queried from physics engine soft body: btVector3 aabb_min; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 94be8d6ee..fd8b42068 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -32,6 +32,7 @@ #include #include #include +#include using namespace std; using namespace wiGraphics; @@ -288,6 +289,10 @@ struct FrameCulling vector culledEmitters; vector culledHairs; + atomic object_counter; + atomic light_counter; + atomic decal_counter; + void Clear() { culledObjects.clear(); @@ -296,6 +301,10 @@ struct FrameCulling culledEnvProbes.clear(); culledEmitters.clear(); culledHairs.clear(); + + object_counter.store(0); + light_counter.store(0); + decal_counter.store(0); } }; unordered_map frameCullings; @@ -1042,7 +1051,7 @@ void LoadShaders() GraphicsDevice* device = GetDevice(); wiJobSystem::context ctx; - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1051,7 +1060,7 @@ void LoadShaders() device->CreateInputLayout(layout, arraysize(layout), &vertexShaders[VSTYPE_OBJECT_DEBUG], &inputLayouts[ILTYPE_OBJECT_DEBUG]); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1074,7 +1083,7 @@ void LoadShaders() device->CreateInputLayout(layout, arraysize(layout), &vertexShaders[VSTYPE_OBJECT_COMMON], &inputLayouts[ILTYPE_OBJECT_ALL]); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1089,7 +1098,7 @@ void LoadShaders() }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1106,7 +1115,7 @@ void LoadShaders() }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1121,7 +1130,7 @@ void LoadShaders() }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1139,7 +1148,7 @@ void LoadShaders() LoadShader(VS, vertexShaders[VSTYPE_SHADOW_TRANSPARENT], "shadowVS_transparent.cso"); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION", 0, FORMAT_R32G32B32A32_FLOAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1150,7 +1159,7 @@ void LoadShaders() }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION", 0, FORMAT_R32G32B32_FLOAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1161,7 +1170,7 @@ void LoadShaders() device->CreateInputLayout(layout, arraysize(layout), &vertexShaders[VSTYPE_TRAIL], &inputLayouts[ILTYPE_TRAIL]); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { InputLayoutDesc layout[] = { { "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, @@ -1175,236 +1184,236 @@ void LoadShaders() device->CreateInputLayout(layout, arraysize(layout), &vertexShaders[VSTYPE_RENDERLIGHTMAP], &inputLayouts[ILTYPE_RENDERLIGHTMAP]); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_OBJECT_COMMON_TESSELLATION], "objectVS_common_tessellation.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_OBJECT_SIMPLE_TESSELLATION], "objectVS_simple_tessellation.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_IMPOSTOR], "impostorVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_DIRLIGHT], "dirLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_POINTLIGHT], "pointLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_SPOTLIGHT], "spotLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_SPOTLIGHT], "vSpotLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_POINTLIGHT], "vPointLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_SPHERELIGHT], "vSphereLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_DISCLIGHT], "vDiscLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_RECTANGLELIGHT], "vRectangleLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_TUBELIGHT], "vTubeLightVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_DECAL], "decalVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_ENVMAP], "envMapVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_ENVMAP_SKY], "envMap_skyVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_SPHERE], "sphereVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_CUBE], "cubeVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_SHADOWCUBEMAPRENDER], "cubeShadowVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_SHADOWCUBEMAPRENDER_ALPHATEST], "cubeShadowVS_alphatest.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_SKY], "skyVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_VOXELIZER], "objectVS_voxelizer.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_VOXEL], "voxelVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_FORCEFIELDVISUALIZER_POINT], "forceFieldPointVisualizerVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_FORCEFIELDVISUALIZER_PLANE], "forceFieldPlaneVisualizerVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_RAYTRACE_SCREEN], "raytrace_screenVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_SCREEN], "screenVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(VS, vertexShaders[VSTYPE_LENSFLARE], "lensFlareVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_OBJECT_COMMON_TESSELLATION], "objectVS_common_tessellation.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_OBJECT_SIMPLE_TESSELLATION], "objectVS_simple_tessellation.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_IMPOSTOR], "impostorVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_DIRLIGHT], "dirLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_POINTLIGHT], "pointLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_SPOTLIGHT], "spotLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_SPOTLIGHT], "vSpotLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_POINTLIGHT], "vPointLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_SPHERELIGHT], "vSphereLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_DISCLIGHT], "vDiscLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_RECTANGLELIGHT], "vRectangleLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_LIGHTVISUALIZER_TUBELIGHT], "vTubeLightVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_DECAL], "decalVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_ENVMAP], "envMapVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_ENVMAP_SKY], "envMap_skyVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_SPHERE], "sphereVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_CUBE], "cubeVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_SHADOWCUBEMAPRENDER], "cubeShadowVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_SHADOWCUBEMAPRENDER_ALPHATEST], "cubeShadowVS_alphatest.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_SKY], "skyVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_VOXELIZER], "objectVS_voxelizer.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_VOXEL], "voxelVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_FORCEFIELDVISUALIZER_POINT], "forceFieldPointVisualizerVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_FORCEFIELDVISUALIZER_PLANE], "forceFieldPlaneVisualizerVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_RAYTRACE_SCREEN], "raytrace_screenVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_SCREEN], "screenVS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(VS, vertexShaders[VSTYPE_LENSFLARE], "lensFlareVS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED], "objectPS_deferred.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_NORMALMAP], "objectPS_deferred_normalmap.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_POM], "objectPS_deferred_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_PLANARREFLECTION], "objectPS_deferred_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_NORMALMAP_POM], "objectPS_deferred_normalmap_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_NORMALMAP_PLANARREFLECTION], "objectPS_deferred_normalmap_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_TERRAIN], "objectPS_deferred_terrain.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_DEFERRED], "impostorPS_deferred.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED], "objectPS_deferred.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_NORMALMAP], "objectPS_deferred_normalmap.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_POM], "objectPS_deferred_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_PLANARREFLECTION], "objectPS_deferred_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_NORMALMAP_POM], "objectPS_deferred_normalmap_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_NORMALMAP_PLANARREFLECTION], "objectPS_deferred_normalmap_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEFERRED_TERRAIN], "objectPS_deferred_terrain.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_DEFERRED], "impostorPS_deferred.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD], "objectPS_forward.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_NORMALMAP], "objectPS_forward_normalmap.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT], "objectPS_forward_transparent.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_NORMALMAP], "objectPS_forward_transparent_normalmap.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_PLANARREFLECTION], "objectPS_forward_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_NORMALMAP_PLANARREFLECTION], "objectPS_forward_normalmap_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_PLANARREFLECTION], "objectPS_forward_transparent_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_NORMALMAP_PLANARREFLECTION], "objectPS_forward_transparent_normalmap_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_POM], "objectPS_forward_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_NORMALMAP_POM], "objectPS_forward_normalmap_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_POM], "objectPS_forward_transparent_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_NORMALMAP_POM], "objectPS_forward_transparent_normalmap_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_WATER], "objectPS_forward_water.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TERRAIN], "objectPS_forward_terrain.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_FORWARD], "impostorPS_forward.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD], "objectPS_forward.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_NORMALMAP], "objectPS_forward_normalmap.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT], "objectPS_forward_transparent.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_NORMALMAP], "objectPS_forward_transparent_normalmap.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_PLANARREFLECTION], "objectPS_forward_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_NORMALMAP_PLANARREFLECTION], "objectPS_forward_normalmap_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_PLANARREFLECTION], "objectPS_forward_transparent_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_NORMALMAP_PLANARREFLECTION], "objectPS_forward_transparent_normalmap_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_POM], "objectPS_forward_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_NORMALMAP_POM], "objectPS_forward_normalmap_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_POM], "objectPS_forward_transparent_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TRANSPARENT_NORMALMAP_POM], "objectPS_forward_transparent_normalmap_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_WATER], "objectPS_forward_water.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_FORWARD_TERRAIN], "objectPS_forward_terrain.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_FORWARD], "impostorPS_forward.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD], "objectPS_tiledforward.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_NORMALMAP], "objectPS_tiledforward_normalmap.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT], "objectPS_tiledforward_transparent.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_NORMALMAP], "objectPS_tiledforward_transparent_normalmap.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_PLANARREFLECTION], "objectPS_tiledforward_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_NORMALMAP_PLANARREFLECTION], "objectPS_tiledforward_normalmap_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_PLANARREFLECTION], "objectPS_tiledforward_transparent_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_NORMALMAP_PLANARREFLECTION], "objectPS_tiledforward_transparent_normalmap_planarreflection.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_POM], "objectPS_tiledforward_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_NORMALMAP_POM], "objectPS_tiledforward_normalmap_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_POM], "objectPS_tiledforward_transparent_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_NORMALMAP_POM], "objectPS_tiledforward_transparent_normalmap_pom.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_WATER], "objectPS_tiledforward_water.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TERRAIN], "objectPS_tiledforward_terrain.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_TILEDFORWARD], "impostorPS_tiledforward.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD], "objectPS_tiledforward.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_NORMALMAP], "objectPS_tiledforward_normalmap.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT], "objectPS_tiledforward_transparent.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_NORMALMAP], "objectPS_tiledforward_transparent_normalmap.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_PLANARREFLECTION], "objectPS_tiledforward_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_NORMALMAP_PLANARREFLECTION], "objectPS_tiledforward_normalmap_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_PLANARREFLECTION], "objectPS_tiledforward_transparent_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_NORMALMAP_PLANARREFLECTION], "objectPS_tiledforward_transparent_normalmap_planarreflection.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_POM], "objectPS_tiledforward_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_NORMALMAP_POM], "objectPS_tiledforward_normalmap_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_POM], "objectPS_tiledforward_transparent_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TRANSPARENT_NORMALMAP_POM], "objectPS_tiledforward_transparent_normalmap_pom.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_WATER], "objectPS_tiledforward_water.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TILEDFORWARD_TERRAIN], "objectPS_tiledforward_terrain.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_TILEDFORWARD], "impostorPS_tiledforward.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_HOLOGRAM], "objectPS_hologram.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_HOLOGRAM], "objectPS_hologram.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEBUG], "objectPS_debug.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_PAINTRADIUS], "objectPS_paintradius.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_SIMPLEST], "objectPS_simplest.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_BLACKOUT], "objectPS_blackout.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TEXTUREONLY], "objectPS_textureonly.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_ALPHATESTONLY], "objectPS_alphatestonly.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_ALPHATESTONLY], "impostorPS_alphatestonly.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_SIMPLE], "impostorPS_simple.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_WIRE], "impostorPS_wire.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_ENVIRONMENTALLIGHT], "environmentalLightPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_DIRLIGHT], "dirLightPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_POINTLIGHT], "pointLightPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_SPOTLIGHT], "spotLightPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_SPHERELIGHT], "sphereLightPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_DISCLIGHT], "discLightPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_RECTANGLELIGHT], "rectangleLightPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_TUBELIGHT], "tubeLightPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_LIGHTVISUALIZER], "lightVisualizerPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_VOLUMETRICLIGHT_DIRECTIONAL], "volumetricLight_DirectionalPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_VOLUMETRICLIGHT_POINT], "volumetricLight_PointPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_VOLUMETRICLIGHT_SPOT], "volumetricLight_SpotPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_DECAL], "decalPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_ENVMAP], "envMapPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_ENVMAP_TERRAIN], "envMapPS_terrain.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_ENVMAP_SKY_STATIC], "envMap_skyPS_static.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_ENVMAP_SKY_DYNAMIC], "envMap_skyPS_dynamic.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_CAPTUREIMPOSTOR_ALBEDO], "captureImpostorPS_albedo.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_CAPTUREIMPOSTOR_NORMAL], "captureImpostorPS_normal.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_CAPTUREIMPOSTOR_SURFACE], "captureImpostorPS_surface.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_CUBEMAP], "cubemapPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_VERTEXCOLOR], "vertexcolorPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_SKY_STATIC], "skyPS_static.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_SKY_DYNAMIC], "skyPS_dynamic.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_SUN], "sunPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_SHADOW_ALPHATEST], "shadowPS_alphatest.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_SHADOW_TRANSPARENT], "shadowPS_transparent.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_SHADOW_WATER], "shadowPS_water.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_TRAIL], "trailPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_VOXELIZER], "objectPS_voxelizer.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_VOXELIZER_TERRAIN], "objectPS_voxelizer_terrain.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_VOXEL], "voxelPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_FORCEFIELDVISUALIZER], "forceFieldVisualizerPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_RENDERLIGHTMAP], "renderlightmapPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_RAYTRACE_DEBUGBVH], "raytrace_debugbvhPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_DOWNSAMPLEDEPTHBUFFER], "downsampleDepthBuffer4xPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_DEFERREDCOMPOSITION], "deferredPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_POSTPROCESS_SSS], "sssPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL], "upsample_bilateralPS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_POSTPROCESS_OUTLINE], "outlinePS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(PS, pixelShaders[PSTYPE_LENSFLARE], "lensFlarePS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_DEBUG], "objectPS_debug.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_PAINTRADIUS], "objectPS_paintradius.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_SIMPLEST], "objectPS_simplest.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_BLACKOUT], "objectPS_blackout.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_TEXTUREONLY], "objectPS_textureonly.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_OBJECT_ALPHATESTONLY], "objectPS_alphatestonly.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_ALPHATESTONLY], "impostorPS_alphatestonly.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_SIMPLE], "impostorPS_simple.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_IMPOSTOR_WIRE], "impostorPS_wire.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_ENVIRONMENTALLIGHT], "environmentalLightPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_DIRLIGHT], "dirLightPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_POINTLIGHT], "pointLightPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_SPOTLIGHT], "spotLightPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_SPHERELIGHT], "sphereLightPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_DISCLIGHT], "discLightPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_RECTANGLELIGHT], "rectangleLightPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_TUBELIGHT], "tubeLightPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_LIGHTVISUALIZER], "lightVisualizerPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_VOLUMETRICLIGHT_DIRECTIONAL], "volumetricLight_DirectionalPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_VOLUMETRICLIGHT_POINT], "volumetricLight_PointPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_VOLUMETRICLIGHT_SPOT], "volumetricLight_SpotPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_DECAL], "decalPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_ENVMAP], "envMapPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_ENVMAP_TERRAIN], "envMapPS_terrain.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_ENVMAP_SKY_STATIC], "envMap_skyPS_static.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_ENVMAP_SKY_DYNAMIC], "envMap_skyPS_dynamic.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_CAPTUREIMPOSTOR_ALBEDO], "captureImpostorPS_albedo.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_CAPTUREIMPOSTOR_NORMAL], "captureImpostorPS_normal.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_CAPTUREIMPOSTOR_SURFACE], "captureImpostorPS_surface.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_CUBEMAP], "cubemapPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_VERTEXCOLOR], "vertexcolorPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_SKY_STATIC], "skyPS_static.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_SKY_DYNAMIC], "skyPS_dynamic.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_SUN], "sunPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_SHADOW_ALPHATEST], "shadowPS_alphatest.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_SHADOW_TRANSPARENT], "shadowPS_transparent.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_SHADOW_WATER], "shadowPS_water.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_TRAIL], "trailPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_VOXELIZER], "objectPS_voxelizer.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_VOXELIZER_TERRAIN], "objectPS_voxelizer_terrain.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_VOXEL], "voxelPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_FORCEFIELDVISUALIZER], "forceFieldVisualizerPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_RENDERLIGHTMAP], "renderlightmapPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_RAYTRACE_DEBUGBVH], "raytrace_debugbvhPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_DOWNSAMPLEDEPTHBUFFER], "downsampleDepthBuffer4xPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_DEFERREDCOMPOSITION], "deferredPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_POSTPROCESS_SSS], "sssPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL], "upsample_bilateralPS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_POSTPROCESS_OUTLINE], "outlinePS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, pixelShaders[PSTYPE_LENSFLARE], "lensFlarePS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(GS, geometryShaders[GSTYPE_VOXELIZER], "objectGS_voxelizer.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(GS, geometryShaders[GSTYPE_VOXEL], "voxelGS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(GS, geometryShaders[GSTYPE_LENSFLARE], "lensFlareGS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(GS, geometryShaders[GSTYPE_VOXELIZER], "objectGS_voxelizer.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(GS, geometryShaders[GSTYPE_VOXEL], "voxelGS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(GS, geometryShaders[GSTYPE_LENSFLARE], "lensFlareGS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_LUMINANCE_PASS1], "luminancePass1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_LUMINANCE_PASS2], "luminancePass2CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_TILEFRUSTUMS], "tileFrustumsCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_RESOLVEMSAADEPTHSTENCIL], "resolveMSAADepthStencilCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_VOXELSCENECOPYCLEAR], "voxelSceneCopyClearCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_VOXELSCENECOPYCLEAR_TEMPORALSMOOTHING], "voxelSceneCopyClearCS_TemporalSmoothing.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_VOXELRADIANCESECONDARYBOUNCE], "voxelRadianceSecondaryBounceCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_VOXELCLEARONLYNORMAL], "voxelClearOnlyNormalCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAIN2D_UNORM4], "generateMIPChain2DCS_unorm4.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAIN2D_FLOAT4], "generateMIPChain2DCS_float4.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAIN3D_UNORM4], "generateMIPChain3DCS_unorm4.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAIN3D_FLOAT4], "generateMIPChain3DCS_float4.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAINCUBE_UNORM4], "generateMIPChainCubeCS_unorm4.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAINCUBE_FLOAT4], "generateMIPChainCubeCS_float4.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAINCUBEARRAY_UNORM4], "generateMIPChainCubeArrayCS_unorm4.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAINCUBEARRAY_FLOAT4], "generateMIPChainCubeArrayCS_float4.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_FILTERENVMAP], "filterEnvMapCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_COPYTEXTURE2D_UNORM4], "copytexture2D_unorm4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_COPYTEXTURE2D_FLOAT4], "copytexture2D_float4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_COPYTEXTURE2D_UNORM4_BORDEREXPAND], "copytexture2D_unorm4_borderexpandCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_COPYTEXTURE2D_FLOAT4_BORDEREXPAND], "copytexture2D_float4_borderexpandCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_SKINNING], "skinningCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_SKINNING_LDS], "skinningCS_LDS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_LAUNCH], "raytrace_launchCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_KICKJOBS], "raytrace_kickjobsCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_CLOSESTHIT], "raytrace_closesthitCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_SHADE], "raytrace_shadeCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_TILESORT], "raytrace_tilesortCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_LUMINANCE_PASS1], "luminancePass1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_LUMINANCE_PASS2], "luminancePass2CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_TILEFRUSTUMS], "tileFrustumsCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_RESOLVEMSAADEPTHSTENCIL], "resolveMSAADepthStencilCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_VOXELSCENECOPYCLEAR], "voxelSceneCopyClearCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_VOXELSCENECOPYCLEAR_TEMPORALSMOOTHING], "voxelSceneCopyClearCS_TemporalSmoothing.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_VOXELRADIANCESECONDARYBOUNCE], "voxelRadianceSecondaryBounceCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_VOXELCLEARONLYNORMAL], "voxelClearOnlyNormalCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAIN2D_UNORM4], "generateMIPChain2DCS_unorm4.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAIN2D_FLOAT4], "generateMIPChain2DCS_float4.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAIN3D_UNORM4], "generateMIPChain3DCS_unorm4.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAIN3D_FLOAT4], "generateMIPChain3DCS_float4.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAINCUBE_UNORM4], "generateMIPChainCubeCS_unorm4.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAINCUBE_FLOAT4], "generateMIPChainCubeCS_float4.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAINCUBEARRAY_UNORM4], "generateMIPChainCubeArrayCS_unorm4.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_GENERATEMIPCHAINCUBEARRAY_FLOAT4], "generateMIPChainCubeArrayCS_float4.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_FILTERENVMAP], "filterEnvMapCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_COPYTEXTURE2D_UNORM4], "copytexture2D_unorm4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_COPYTEXTURE2D_FLOAT4], "copytexture2D_float4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_COPYTEXTURE2D_UNORM4_BORDEREXPAND], "copytexture2D_unorm4_borderexpandCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_COPYTEXTURE2D_FLOAT4_BORDEREXPAND], "copytexture2D_float4_borderexpandCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_SKINNING], "skinningCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_SKINNING_LDS], "skinningCS_LDS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_LAUNCH], "raytrace_launchCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_KICKJOBS], "raytrace_kickjobsCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_CLOSESTHIT], "raytrace_closesthitCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_SHADE], "raytrace_shadeCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_TILESORT], "raytrace_tilesortCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_PAINT_TEXTURE], "paint_textureCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_PAINT_TEXTURE], "paint_textureCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT1], "blur_gaussian_float1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT3], "blur_gaussian_float3CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT4], "blur_gaussian_float4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM1], "blur_gaussian_unorm1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM4], "blur_gaussian_unorm4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT1], "blur_gaussian_wide_float1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT3], "blur_gaussian_wide_float3CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT4], "blur_gaussian_wide_float4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM1], "blur_gaussian_wide_unorm1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM4], "blur_gaussian_wide_unorm4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT1], "blur_bilateral_float1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT3], "blur_bilateral_float3CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT4], "blur_bilateral_float4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM1], "blur_bilateral_unorm1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM4], "blur_bilateral_unorm4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT1], "blur_bilateral_wide_float1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT3], "blur_bilateral_wide_float3CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT4], "blur_bilateral_wide_float4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM1], "blur_bilateral_wide_unorm1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM4], "blur_bilateral_wide_unorm4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSAO], "ssaoCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_HBAO], "hbaoCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_PREPAREDEPTHBUFFERS1], "msao_preparedepthbuffers1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_PREPAREDEPTHBUFFERS2], "msao_preparedepthbuffers2CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_INTERLEAVE], "msao_interleaveCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO], "msaoCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE], "msao_blurupsampleCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE_BLENDOUT], "msao_blurupsampleCS_blendout.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE_PREMIN], "msao_blurupsampleCS_premin.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE_PREMIN_BLENDOUT], "msao_blurupsampleCS_premin_blendout.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_RAYTRACE], "ssr_raytraceCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_RESOLVE], "ssr_resolveCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_TEMPORAL], "ssr_temporalCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_MEDIAN], "ssr_medianCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_LIGHTSHAFTS], "lightshaftsCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_TILEMAXCOC_HORIZONTAL], "depthoffield_tileMaxCOC_horizontalCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_TILEMAXCOC_VERTICAL], "depthoffield_tileMaxCOC_verticalCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_NEIGHBORHOODMAXCOC], "depthoffield_neighborhoodMaxCOCCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_KICKJOBS], "depthoffield_kickjobsCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_PREPASS], "depthoffield_prepassCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_PREPASS_EARLYEXIT], "depthoffield_prepassCS_earlyexit.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN], "depthoffield_mainCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN_EARLYEXIT], "depthoffield_mainCS_earlyexit.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN_CHEAP], "depthoffield_mainCS_cheap.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_POSTFILTER], "depthoffield_postfilterCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_UPSAMPLE], "depthoffield_upsampleCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_TILEMAXVELOCITY_HORIZONTAL], "motionblur_tileMaxVelocity_horizontalCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_TILEMAXVELOCITY_VERTICAL], "motionblur_tileMaxVelocity_verticalCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_NEIGHBORHOODMAXVELOCITY], "motionblur_neighborhoodMaxVelocityCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_KICKJOBS], "motionblur_kickjobsCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR], "motionblurCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_EARLYEXIT], "motionblurCS_earlyexit.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_CHEAP], "motionblurCS_cheap.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLOOMSEPARATE], "bloomseparateCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLOOMCOMBINE], "bloomcombineCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_FXAA], "fxaaCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_TEMPORALAA], "temporalaaCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_LINEARDEPTH], "lineardepthCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SHARPEN], "sharpenCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_TONEMAP], "tonemapCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_CHROMATIC_ABERRATION], "chromatic_aberrationCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_FLOAT1], "upsample_bilateral_float1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_UNORM1], "upsample_bilateral_unorm1CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_FLOAT4], "upsample_bilateral_float4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_UNORM4], "upsample_bilateral_unorm4CS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DOWNSAMPLE4X], "downsample4xCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT1], "blur_gaussian_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT3], "blur_gaussian_float3CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT4], "blur_gaussian_float4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM1], "blur_gaussian_unorm1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM4], "blur_gaussian_unorm4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT1], "blur_gaussian_wide_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT3], "blur_gaussian_wide_float3CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT4], "blur_gaussian_wide_float4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM1], "blur_gaussian_wide_unorm1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM4], "blur_gaussian_wide_unorm4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT1], "blur_bilateral_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT3], "blur_bilateral_float3CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT4], "blur_bilateral_float4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM1], "blur_bilateral_unorm1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM4], "blur_bilateral_unorm4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT1], "blur_bilateral_wide_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT3], "blur_bilateral_wide_float3CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT4], "blur_bilateral_wide_float4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM1], "blur_bilateral_wide_unorm1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM4], "blur_bilateral_wide_unorm4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSAO], "ssaoCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_HBAO], "hbaoCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_PREPAREDEPTHBUFFERS1], "msao_preparedepthbuffers1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_PREPAREDEPTHBUFFERS2], "msao_preparedepthbuffers2CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_INTERLEAVE], "msao_interleaveCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO], "msaoCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE], "msao_blurupsampleCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE_BLENDOUT], "msao_blurupsampleCS_blendout.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE_PREMIN], "msao_blurupsampleCS_premin.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE_PREMIN_BLENDOUT], "msao_blurupsampleCS_premin_blendout.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_RAYTRACE], "ssr_raytraceCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_RESOLVE], "ssr_resolveCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_TEMPORAL], "ssr_temporalCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_MEDIAN], "ssr_medianCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_LIGHTSHAFTS], "lightshaftsCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_TILEMAXCOC_HORIZONTAL], "depthoffield_tileMaxCOC_horizontalCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_TILEMAXCOC_VERTICAL], "depthoffield_tileMaxCOC_verticalCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_NEIGHBORHOODMAXCOC], "depthoffield_neighborhoodMaxCOCCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_KICKJOBS], "depthoffield_kickjobsCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_PREPASS], "depthoffield_prepassCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_PREPASS_EARLYEXIT], "depthoffield_prepassCS_earlyexit.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN], "depthoffield_mainCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN_EARLYEXIT], "depthoffield_mainCS_earlyexit.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN_CHEAP], "depthoffield_mainCS_cheap.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_POSTFILTER], "depthoffield_postfilterCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_UPSAMPLE], "depthoffield_upsampleCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_TILEMAXVELOCITY_HORIZONTAL], "motionblur_tileMaxVelocity_horizontalCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_TILEMAXVELOCITY_VERTICAL], "motionblur_tileMaxVelocity_verticalCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_NEIGHBORHOODMAXVELOCITY], "motionblur_neighborhoodMaxVelocityCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_KICKJOBS], "motionblur_kickjobsCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR], "motionblurCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_EARLYEXIT], "motionblurCS_earlyexit.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_CHEAP], "motionblurCS_cheap.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLOOMSEPARATE], "bloomseparateCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLOOMCOMBINE], "bloomcombineCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_FXAA], "fxaaCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_TEMPORALAA], "temporalaaCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_LINEARDEPTH], "lineardepthCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SHARPEN], "sharpenCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_TONEMAP], "tonemapCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_CHROMATIC_ABERRATION], "chromatic_aberrationCS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_FLOAT1], "upsample_bilateral_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_UNORM1], "upsample_bilateral_unorm1CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_FLOAT4], "upsample_bilateral_float4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_UNORM4], "upsample_bilateral_unorm4CS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_DOWNSAMPLE4X], "downsample4xCS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(HS, hullShaders[HSTYPE_OBJECT], "objectHS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(HS, hullShaders[HSTYPE_OBJECT], "objectHS.cso"); }); - wiJobSystem::Execute(ctx, [] { LoadShader(DS, domainShaders[DSTYPE_OBJECT], "objectDS.cso"); }); + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(DS, domainShaders[DSTYPE_OBJECT], "objectDS.cso"); }); wiJobSystem::Wait(ctx); @@ -1425,7 +1434,7 @@ void LoadShaders() { for (int pom = 0; pom < OBJECTRENDERING_POM_COUNT; ++pom) { - wiJobSystem::Execute(ctx, [device, renderPass, blendMode, doublesided, tessellation, alphatest, normalmap, planarreflection, pom] { + wiJobSystem::Execute(ctx, [device, renderPass, blendMode, doublesided, tessellation, alphatest, normalmap, planarreflection, pom](wiJobArgs args) { const bool transparency = blendMode != BLENDMODE_OPAQUE; VSTYPES realVS = GetVSTYPE((RENDERPASS)renderPass, tessellation, alphatest, transparency); ILTYPES realVL = GetILTYPE((RENDERPASS)renderPass, tessellation, alphatest, transparency); @@ -1546,7 +1555,7 @@ void LoadShaders() } } - wiJobSystem::Dispatch(ctx, RENDERPASS_COUNT, 1, [device](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, RENDERPASS_COUNT, 1, [device](wiJobArgs args) { VSTYPES realVS = GetVSTYPE((RENDERPASS)args.jobIndex, false, false, false); ILTYPES realVL = GetILTYPE((RENDERPASS)args.jobIndex, false, false, false); @@ -1604,7 +1613,7 @@ void LoadShaders() customShaders.clear(); // Hologram sample shader will be registered as custom shader: - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { VSTYPES realVS = GetVSTYPE(RENDERPASS_FORWARD, false, false, true); ILTYPES realVL = GetILTYPE(RENDERPASS_FORWARD, false, false, true); @@ -1628,7 +1637,7 @@ void LoadShaders() }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_OBJECT_COMMON]; desc.rs = &rasterizers[RSTYPE_DOUBLESIDED]; @@ -1658,7 +1667,7 @@ void LoadShaders() desc.ps = &pixelShaders[GetPSTYPE(RENDERPASS_ENVMAPCAPTURE, false, true, false, false, false)]; device->CreatePipelineState(&desc, &PSO_object_water[RENDERPASS_ENVMAPCAPTURE]); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_OBJECT_SIMPLE]; desc.ps = &pixelShaders[PSTYPE_OBJECT_SIMPLEST]; @@ -1669,7 +1678,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_object_wire); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_DECAL]; desc.ps = &pixelShaders[PSTYPE_DECAL]; @@ -1680,7 +1689,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_decal); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_CUBE]; desc.rs = &rasterizers[RSTYPE_OCCLUDEE]; @@ -1690,7 +1699,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_occlusionquery); }); - wiJobSystem::Dispatch(ctx, RENDERPASS_COUNT, 1, [device](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, RENDERPASS_COUNT, 1, [device](wiJobArgs args) { const bool impostorRequest = args.jobIndex != RENDERPASS_VOXELIZE && args.jobIndex != RENDERPASS_SHADOW && @@ -1735,7 +1744,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_impostor[args.jobIndex]); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_IMPOSTOR]; desc.ps = &pixelShaders[PSTYPE_IMPOSTOR_WIRE]; @@ -1746,7 +1755,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_impostor_wire); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_OBJECT_COMMON]; desc.rs = &rasterizers[RSTYPE_DOUBLESIDED]; @@ -1764,7 +1773,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_captureimpostor_surface); }); - wiJobSystem::Dispatch(ctx, LightComponent::LIGHTTYPE_COUNT, 1, [device](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, LightComponent::LIGHTTYPE_COUNT, 1, [device](wiJobArgs args) { PipelineStateDesc desc; // deferred lights: @@ -1883,7 +1892,7 @@ void LoadShaders() }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_DIRLIGHT]; desc.ps = &pixelShaders[PSTYPE_ENVIRONMENTALLIGHT]; @@ -1893,7 +1902,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_enviromentallight); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.il = &inputLayouts[ILTYPE_RENDERLIGHTMAP]; desc.vs = &vertexShaders[VSTYPE_RENDERLIGHTMAP]; @@ -1904,7 +1913,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_renderlightmap); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_SCREEN]; desc.ps = &pixelShaders[PSTYPE_DOWNSAMPLEDEPTHBUFFER]; @@ -1914,7 +1923,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_downsampledepthbuffer); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_SCREEN]; desc.ps = &pixelShaders[PSTYPE_DEFERREDCOMPOSITION]; @@ -1924,7 +1933,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_deferredcomposition); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_SCREEN]; desc.ps = &pixelShaders[PSTYPE_POSTPROCESS_SSS]; @@ -1934,7 +1943,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_sss); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_SCREEN]; desc.ps = &pixelShaders[PSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL]; @@ -1944,7 +1953,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_upsample_bilateral); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_SCREEN]; desc.ps = &pixelShaders[PSTYPE_POSTPROCESS_OUTLINE]; @@ -1954,7 +1963,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_outline); }); - wiJobSystem::Execute(ctx, [device] { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { PipelineStateDesc desc; desc.vs = &vertexShaders[VSTYPE_LENSFLARE]; desc.ps = &pixelShaders[PSTYPE_LENSFLARE]; @@ -1966,7 +1975,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_lensflare); }); - wiJobSystem::Dispatch(ctx, SKYRENDERING_COUNT, 1, [device](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, SKYRENDERING_COUNT, 1, [device](wiJobArgs args) { PipelineStateDesc desc; desc.rs = &rasterizers[RSTYPE_SKY]; desc.dss = &depthStencils[DSSTYPE_DEPTHREAD]; @@ -2002,7 +2011,7 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_sky[args.jobIndex]); }); - wiJobSystem::Dispatch(ctx, DEBUGRENDERING_COUNT, 1, [device](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, DEBUGRENDERING_COUNT, 1, [device](wiJobArgs args) { PipelineStateDesc desc; switch (args.jobIndex) @@ -2123,7 +2132,7 @@ void LoadShaders() { for (int k = 0; k < TILEDLIGHTING_DEBUG_COUNT; ++k) { - wiJobSystem::Execute(ctx, [device, i, j, k] { + wiJobSystem::Execute(ctx, [device, i, j, k](wiJobArgs args) { string name = "lightCullingCS"; if (i == TILEDLIGHTING_TYPE_DEFERRED) { @@ -2781,8 +2790,8 @@ void Initialize() { GetCamera().CreatePerspective((float)GetInternalResolution().x, (float)GetInternalResolution().y, 0.1f, 800); - frameCullings.insert(make_pair(&GetCamera(), FrameCulling())); - frameCullings.insert(make_pair(&GetRefCamera(), FrameCulling())); + frameCullings[&GetCamera()].Clear(); + frameCullings[&GetRefCamera()].Clear(); SetUpStates(); LoadBuffers(); @@ -3642,8 +3651,27 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) cameraTransform = INVALID_ENTITY; // but this is only active for the current frame } + if (GetTemporalAAEnabled()) + { + const XMFLOAT4& halton = wiMath::GetHaltonSequence(GetDevice()->GetFrameCount() % 256); + static float jitter = 1.0f; + temporalAAJitterPrev = temporalAAJitter; + temporalAAJitter.x = jitter * (halton.x * 2 - 1) / (float)GetInternalResolution().x; + temporalAAJitter.y = jitter * (halton.y * 2 - 1) / (float)GetInternalResolution().y; + GetCamera().jitter = temporalAAJitter; + } + else + { + temporalAAJitter = XMFLOAT2(0, 0); + temporalAAJitterPrev = XMFLOAT2(0, 0); + } + + GetCamera().UpdateCamera(); + GetRefCamera() = GetCamera(); + GetRefCamera().Reflect(waterPlane); + // See which materials will need to update their GPU render data: - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { pendingMaterialUpdates.clear(); for (size_t i = 0; i < scene.materials.GetCount(); ++i) { @@ -3669,7 +3697,7 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) // Need to swap prev and current vertex buffers for any dynamic meshes BEFORE render threads are kicked // and also create skinning bone buffers: - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { for (size_t i = 0; i < scene.meshes.GetCount(); ++i) { Entity entity = scene.meshes.GetEntity(i); @@ -3730,7 +3758,7 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) // Update Voxelization parameters: if (scene.objects.GetCount() > 0) { - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { // We don't update it if the scene is empty, this even makes it easier to debug const float f = 0.05f / voxelSceneData.voxelsize; XMFLOAT3 center = XMFLOAT3(floorf(GetCamera().Eye.x * f) / f, floorf(GetCamera().Eye.y * f) / f, floorf(GetCamera().Eye.z * f) / f); @@ -3747,14 +3775,23 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) }); } - // Perform culling and obtain closest reflector: + // Perform parallel frustum culling and obtain closest reflector: + wiSpinLock locker; + float closestRefPlane = FLT_MAX; requestReflectionRendering = false; requestVolumetricLightRendering = false; auto range = wiProfiler::BeginRangeCPU("Frustum Culling"); { + // The parallel frustum culling is first performed in shared memory, + // then each group writes out it's local list to global memory + // The shared memory approach reduces atomics and helps the list to remain + // more coherent (less randomly organized compared to original order) + const uint32_t groupSize = 64; + const size_t sharedmemory_size = (groupSize + 1) * sizeof(uint32_t); // list + counter per group + for (auto& x : frameCullings) { - const CameraComponent* camera = x.first; + auto& camera = x.first; FrameCulling& culling = x.second; culling.Clear(); @@ -3764,59 +3801,110 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) } // Cull objects for each camera: - wiJobSystem::Execute(ctx, [&] { - for (size_t i = 0; i < scene.aabb_objects.GetCount(); ++i) + culling.culledObjects.resize(scene.aabb_objects.GetCount()); + wiJobSystem::Dispatch(ctx, (uint32_t)scene.aabb_objects.GetCount(), groupSize, [&](wiJobArgs args) { + + Entity entity = scene.aabb_objects.GetEntity(args.jobIndex); + const LayerComponent* layer = scene.layers.GetComponent(entity); + if (layer != nullptr && !(layer->GetLayerMask() & layerMask)) { - Entity entity = scene.aabb_objects.GetEntity(i); - const LayerComponent* layer = scene.layers.GetComponent(entity); - if (layer != nullptr && !(layer->GetLayerMask() & layerMask)) + return; + } + + const AABB& aabb = scene.aabb_objects[args.jobIndex]; + + // Setup stream compaction: + uint32_t& group_count = *(uint32_t*)args.sharedmemory; + uint32_t* group_list = (uint32_t*)args.sharedmemory + 1; + if (args.isFirstJobInGroup) + { + group_count = 0; // first thread initializes local counter + } + + if (culling.frustum.CheckBox(aabb)) + { + // Local stream compaction: + group_list[group_count++] = args.jobIndex; + + // Main camera can request reflection rendering: + if (camera == &GetCamera()) { - continue; - } - - const AABB& aabb = scene.aabb_objects[i]; - - if (culling.frustum.CheckBox(aabb)) - { - culling.culledObjects.push_back((uint32_t)i); - - // Main camera can request reflection rendering: - if (camera == &GetCamera()) + const ObjectComponent& object = scene.objects[args.jobIndex]; + if (object.IsRequestPlanarReflection()) { - const ObjectComponent& object = scene.objects[i]; - if (object.IsRequestPlanarReflection()) + float dist = wiMath::DistanceEstimated(camera->Eye, object.center); + locker.lock(); + if (dist < closestRefPlane) { + closestRefPlane = dist; + const TransformComponent& transform = scene.transforms[object.transform_index]; + XMVECTOR P = transform.GetPositionV(); + XMVECTOR N = XMVectorSet(0, 1, 0, 0); + N = XMVector3TransformNormal(N, XMLoadFloat4x4(&transform.world)); + XMVECTOR _refPlane = XMPlaneFromPointNormal(P, N); + XMStoreFloat4(&waterPlane, _refPlane); + requestReflectionRendering = true; } + locker.unlock(); } } } - }); + + // Global stream compaction: + if (args.isLastJobInGroup && group_count > 0) + { + uint32_t prev_count = culling.object_counter.fetch_add(group_count); + for (uint32_t i = 0; i < group_count; ++i) + { + culling.culledObjects[prev_count + i] = group_list[i]; + } + } + + }, sharedmemory_size); // the following cullings will be only for the main camera: if (camera == &GetCamera()) { - wiJobSystem::Execute(ctx, [&] { - // Cull decals: - for (size_t i = 0; i < scene.aabb_decals.GetCount(); ++i) + culling.culledDecals.resize(scene.aabb_decals.GetCount()); + wiJobSystem::Dispatch(ctx, (uint32_t)scene.aabb_decals.GetCount(), groupSize, [&](wiJobArgs args) { + + Entity entity = scene.aabb_decals.GetEntity(args.jobIndex); + const LayerComponent* layer = scene.layers.GetComponent(entity); + if (layer != nullptr && !(layer->GetLayerMask() & layerMask)) { - Entity entity = scene.aabb_decals.GetEntity(i); - const LayerComponent* layer = scene.layers.GetComponent(entity); - if (layer != nullptr && !(layer->GetLayerMask() & layerMask)) - { - continue; - } + return; + } - const AABB& aabb = scene.aabb_decals[i]; + const AABB& aabb = scene.aabb_decals[args.jobIndex]; - if (culling.frustum.CheckBox(aabb)) + // Setup stream compaction: + uint32_t& group_count = *(uint32_t*)args.sharedmemory; + uint32_t* group_list = (uint32_t*)args.sharedmemory + 1; + if (args.isFirstJobInGroup) + { + group_count = 0; // first thread initializes local counter + } + + if (culling.frustum.CheckBox(aabb)) + { + // Local stream compaction: + group_list[group_count++] = args.jobIndex; + } + + // Global stream compaction: + if (args.isLastJobInGroup && group_count > 0) + { + uint32_t prev_count = culling.decal_counter.fetch_add(group_count); + for (uint32_t i = 0; i < group_count; ++i) { - culling.culledDecals.push_back((uint32_t)i); + culling.culledDecals[prev_count + i] = group_list[i]; } } - }); - wiJobSystem::Execute(ctx, [&] { + }, sharedmemory_size); + + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { // Cull probes: for (size_t i = 0; i < scene.aabb_probes.GetCount(); ++i) { @@ -3836,27 +3924,46 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) } }); - wiJobSystem::Execute(ctx, [&] { - // Cull lights: - for (size_t i = 0; i < scene.aabb_lights.GetCount(); ++i) + // Cull lights: + culling.culledLights.resize(scene.aabb_lights.GetCount()); + wiJobSystem::Dispatch(ctx, (uint32_t)scene.aabb_lights.GetCount(), groupSize, [&](wiJobArgs args) { + + Entity entity = scene.aabb_lights.GetEntity(args.jobIndex); + const LayerComponent* layer = scene.layers.GetComponent(entity); + if (layer != nullptr && !(layer->GetLayerMask() & layerMask)) { - Entity entity = scene.aabb_lights.GetEntity(i); - const LayerComponent* layer = scene.layers.GetComponent(entity); - if (layer != nullptr && !(layer->GetLayerMask() & layerMask)) - { - continue; - } + return; + } - const AABB& aabb = scene.aabb_lights[i]; + const AABB& aabb = scene.aabb_lights[args.jobIndex]; - if (culling.frustum.CheckBox(aabb)) + // Setup stream compaction: + uint32_t& group_count = *(uint32_t*)args.sharedmemory; + uint32_t* group_list = (uint32_t*)args.sharedmemory + 1; + if (args.isFirstJobInGroup) + { + group_count = 0; // first thread initializes local counter + } + + if (culling.frustum.CheckBox(aabb)) + { + // Local stream compaction: + group_list[group_count++] = args.jobIndex; + } + + // Global stream compaction: + if (args.isLastJobInGroup && group_count > 0) + { + uint32_t prev_count = culling.light_counter.fetch_add(group_count); + for (uint32_t i = 0; i < group_count; ++i) { - culling.culledLights.push_back((uint32_t)i); + culling.culledLights[prev_count + i] = group_list[i]; } } - }); - wiJobSystem::Execute(ctx, [&] { + }, sharedmemory_size); + + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { // Cull emitters: for (size_t i = 0; i < scene.emitters.GetCount(); ++i) { @@ -3870,7 +3977,7 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) } }); - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { // Cull hairs: for (size_t i = 0; i < scene.hairs.GetCount(); ++i) { @@ -3889,10 +3996,31 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) culling.culledHairs.push_back((uint32_t)i); } }); + } - wiJobSystem::Wait(ctx); + } + } + wiJobSystem::Wait(ctx); + // finalize stream compaction: + for (auto& x : frameCullings) + { + FrameCulling& culling = x.second; + culling.culledObjects.resize((size_t)culling.object_counter.load()); + culling.culledLights.resize((size_t)culling.light_counter.load()); + culling.culledDecals.resize((size_t)culling.decal_counter.load()); + } + wiProfiler::EndRange(range); // Frustum Culling + // Light sorting: + for (auto& x : frameCullings) + { + FrameCulling& culling = x.second; + + if (!culling.culledLights.empty()) + { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { // Sort lights based on distance so that closer lights will receive shadow map priority: + const CameraComponent* camera = x.first; const size_t lightCount = culling.culledLights.size(); assert(lightCount < 0x0000FFFF); // watch out for sorting hash truncation! uint32_t* lightSortingHashes = (uint32_t*)GetUpdateFrameAllocator().allocate(sizeof(uint32_t) * lightCount); @@ -3953,15 +4081,11 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) } } } - - } - + }); } } - wiProfiler::EndRange(range); // Frustum Culling // Ocean will override any current reflectors - waterPlane = scene.waterPlane; if (scene.weather.IsOceanEnabled()) { requestReflectionRendering = true; @@ -3978,38 +4102,19 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) ocean.reset(); } - if (GetTemporalAAEnabled()) - { - const XMFLOAT4& halton = wiMath::GetHaltonSequence(GetDevice()->GetFrameCount() % 256); - static float jitter = 1.0f; - temporalAAJitterPrev = temporalAAJitter; - temporalAAJitter.x = jitter * (halton.x * 2 - 1) / (float)GetInternalResolution().x; - temporalAAJitter.y = jitter * (halton.y * 2 - 1) / (float)GetInternalResolution().y; - GetCamera().jitter = temporalAAJitter; - } - else - { - temporalAAJitter = XMFLOAT2(0, 0); - temporalAAJitterPrev = XMFLOAT2(0, 0); - } - - GetCamera().UpdateCamera(); - GetRefCamera() = GetCamera(); - GetRefCamera().Reflect(waterPlane); - - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { ManageDecalAtlas(); }); - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { ManageLightmapAtlas(); }); - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { ManageImpostors(); }); - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { ManageEnvProbes(); }); - wiJobSystem::Execute(ctx, [&] { + wiJobSystem::Execute(ctx, [&](wiJobArgs args) { for (auto& x : waterRipples) { x->Update(dt * 60); diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 29ebe22db..65e001492 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -1116,49 +1116,54 @@ namespace wiScene { wiJobSystem::context ctx; - RunPreviousFrameTransformUpdateSystem(ctx, transforms, prev_transforms); + RunPreviousFrameTransformUpdateSystem(ctx); - RunAnimationUpdateSystem(ctx, animations, transforms, dt); + RunAnimationUpdateSystem(ctx, dt); - RunTransformUpdateSystem(ctx, transforms); + RunTransformUpdateSystem(ctx); wiJobSystem::Wait(ctx); // dependecies - RunHierarchyUpdateSystem(ctx, hierarchy, transforms, layers); + RunHierarchyUpdateSystem(ctx); - RunSpringUpdateSystem(ctx, weather, hierarchy, transforms, springs, dt); + RunSpringUpdateSystem(ctx, dt); - RunInverseKinematicsUpdateSystem(ctx, inverse_kinematics, hierarchy, transforms); + RunInverseKinematicsUpdateSystem(ctx); - RunArmatureUpdateSystem(ctx, transforms, armatures); + RunArmatureUpdateSystem(ctx); - RunMaterialUpdateSystem(ctx, materials, dt); + RunMaterialUpdateSystem(ctx, dt); - RunImpostorUpdateSystem(ctx, impostors); + RunImpostorUpdateSystem(ctx); + + RunWeatherUpdateSystem(ctx); + + wiPhysicsEngine::RunPhysicsUpdateSystem(ctx, *this, dt); // this syncs dependencies internally + + RunObjectUpdateSystem(ctx); + + RunCameraUpdateSystem(ctx); + + RunDecalUpdateSystem(ctx); + + RunProbeUpdateSystem(ctx); + + RunForceUpdateSystem(ctx); + + RunLightUpdateSystem(ctx); + + RunParticleUpdateSystem(ctx, dt); + + RunSoundUpdateSystem(ctx); wiJobSystem::Wait(ctx); // dependecies - RunObjectUpdateSystem(ctx, prev_transforms, transforms, meshes, materials, armatures, objects, aabb_objects, impostors, softbodies, bounds, waterPlane); - - wiPhysicsEngine::RunPhysicsUpdateSystem(ctx, weather, armatures, transforms, meshes, objects, rigidbodies, softbodies, dt); - - RunCameraUpdateSystem(ctx, transforms, cameras); - - RunDecalUpdateSystem(ctx, transforms, materials, aabb_decals, decals); - - RunProbeUpdateSystem(ctx, transforms, aabb_probes, probes); - - RunForceUpdateSystem(ctx, transforms, forces); - - RunLightUpdateSystem(ctx, transforms, aabb_lights, lights); - - RunParticleUpdateSystem(ctx, transforms, meshes, emitters, hairs, dt); - - wiJobSystem::Wait(ctx); // dependecies - - RunWeatherUpdateSystem(ctx, weathers, lights, weather); - - RunSoundUpdateSystem(ctx, transforms, sounds); + // Merge parallel bounds computation (depends on object update system): + bounds = AABB(); + for (auto& group_bound : parallel_bounds) + { + bounds = AABB::Merge(bounds, group_bound); + } } void Scene::Clear() { @@ -1614,15 +1619,11 @@ namespace wiScene } - const uint32_t small_subtask_groupsize = 1024; + const uint32_t small_subtask_groupsize = 64; - void RunPreviousFrameTransformUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& transforms, - ComponentManager& prev_transforms - ) + void Scene::RunPreviousFrameTransformUpdateSystem(wiJobSystem::context& ctx) { - wiJobSystem::Dispatch(ctx, (uint32_t)prev_transforms.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)prev_transforms.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { PreviousFrameTransformComponent& prev_transform = prev_transforms[args.jobIndex]; Entity entity = prev_transforms.GetEntity(args.jobIndex); @@ -1631,12 +1632,7 @@ namespace wiScene prev_transform.world_prev = transform.world; }); } - void RunAnimationUpdateSystem( - wiJobSystem::context& ctx, - ComponentManager& animations, - ComponentManager& transforms, - float dt - ) + void Scene::RunAnimationUpdateSystem(wiJobSystem::context& ctx, float dt) { for (size_t i = 0; i < animations.GetCount(); ++i) { @@ -1774,22 +1770,15 @@ namespace wiScene } } } - void RunTransformUpdateSystem( - wiJobSystem::context& ctx, - ComponentManager& transforms) + void Scene::RunTransformUpdateSystem(wiJobSystem::context& ctx) { - wiJobSystem::Dispatch(ctx, (uint32_t)transforms.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)transforms.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { TransformComponent& transform = transforms[args.jobIndex]; transform.UpdateTransform(); }); } - void RunHierarchyUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& hierarchy, - ComponentManager& transforms, - ComponentManager& layers - ) + void Scene::RunHierarchyUpdateSystem(wiJobSystem::context& ctx) { // This needs serialized execution because there are dependencies enforced by component order! @@ -1815,14 +1804,7 @@ namespace wiScene } } - void RunSpringUpdateSystem( - wiJobSystem::context& ctx, - const WeatherComponent& weather, - const ComponentManager& hierarchy, - ComponentManager& transforms, - ComponentManager& springs, - float dt - ) + void Scene::RunSpringUpdateSystem(wiJobSystem::context& ctx, float dt) { static float time = 0; time += dt; @@ -1910,12 +1892,7 @@ namespace wiScene *((XMFLOAT3*)&transform->world._41) = spring.center_of_mass; } } - void RunInverseKinematicsUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& inverse_kinematics, - const ComponentManager& hierarchy, - ComponentManager& transforms - ) + void Scene::RunInverseKinematicsUpdateSystem(wiJobSystem::context& ctx) { bool recompute_hierarchy = false; for (size_t i = 0; i < inverse_kinematics.GetCount(); ++i) @@ -2014,13 +1991,9 @@ namespace wiScene } } } - void RunArmatureUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& transforms, - ComponentManager& armatures - ) + void Scene::RunArmatureUpdateSystem(wiJobSystem::context& ctx) { - wiJobSystem::Dispatch(ctx, (uint32_t)armatures.GetCount(), 1, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)armatures.GetCount(), 1, [&](wiJobArgs args) { ArmatureComponent& armature = armatures[args.jobIndex]; Entity entity = armatures.GetEntity(args.jobIndex); @@ -2066,11 +2039,9 @@ namespace wiScene }); } - void RunMaterialUpdateSystem( - wiJobSystem::context& ctx, - ComponentManager& materials, float dt) + void Scene::RunMaterialUpdateSystem(wiJobSystem::context& ctx, float dt) { - wiJobSystem::Dispatch(ctx, (uint32_t)materials.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)materials.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { MaterialComponent& material = materials[args.jobIndex]; @@ -2091,182 +2062,170 @@ namespace wiScene } }); } - void RunImpostorUpdateSystem( - wiJobSystem::context& ctx, - ComponentManager& impostors) + void Scene::RunImpostorUpdateSystem(wiJobSystem::context& ctx) { - wiJobSystem::Dispatch(ctx, (uint32_t)impostors.GetCount(), 1, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)impostors.GetCount(), 1, [&](wiJobArgs args) { ImpostorComponent& impostor = impostors[args.jobIndex]; impostor.aabb = AABB(); impostor.instanceMatrices.clear(); }); } - void RunObjectUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& prev_transforms, - const ComponentManager& transforms, - const ComponentManager& meshes, - const ComponentManager& materials, - const ComponentManager& armatures, - ComponentManager& objects, - ComponentManager& aabb_objects, - ComponentManager& impostors, - ComponentManager& softbodies, - AABB& sceneBounds, - XMFLOAT4& waterPlane - ) + void Scene::RunObjectUpdateSystem(wiJobSystem::context& ctx) { assert(objects.GetCount() == aabb_objects.GetCount()); - sceneBounds = AABB(); + parallel_bounds.clear(); + parallel_bounds.resize((size_t)wiJobSystem::DispatchGroupCount((uint32_t)objects.GetCount(), small_subtask_groupsize)); + + wiJobSystem::Dispatch(ctx, (uint32_t)objects.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { - // Instead of Dispatching, this will be one big job, because there is contention for several resources (sceneBounds, waterPlane, impostors) - wiJobSystem::Execute(ctx, [&] { + ObjectComponent& object = objects[args.jobIndex]; + AABB& aabb = aabb_objects[args.jobIndex]; - for (size_t i = 0; i < objects.GetCount(); ++i) + aabb = AABB(); + object.rendertypeMask = 0; + object.SetDynamic(false); + object.SetCastShadow(false); + object.SetImpostorPlacement(false); + object.SetRequestPlanarReflection(false); + + if (object.meshID != INVALID_ENTITY) { - ObjectComponent& object = objects[i]; - AABB& aabb = aabb_objects[i]; + Entity entity = objects.GetEntity(args.jobIndex); + const MeshComponent* mesh = meshes.GetComponent(object.meshID); - aabb = AABB(); - object.rendertypeMask = 0; - object.SetDynamic(false); - object.SetCastShadow(false); - object.SetImpostorPlacement(false); - object.SetRequestPlanarReflection(false); + // These will only be valid for a single frame: + object.transform_index = (int)transforms.GetIndex(entity); + object.prev_transform_index = (int)prev_transforms.GetIndex(entity); - if (object.meshID != INVALID_ENTITY) + const TransformComponent& transform = transforms[object.transform_index]; + + if (mesh != nullptr) { - Entity entity = objects.GetEntity(i); - const MeshComponent* mesh = meshes.GetComponent(object.meshID); + XMMATRIX W = XMLoadFloat4x4(&transform.world); + aabb = mesh->aabb.transform(W); - // These will only be valid for a single frame: - object.transform_index = (int)transforms.GetIndex(entity); - object.prev_transform_index = (int)prev_transforms.GetIndex(entity); + // This is instance bounding box matrix: + XMFLOAT4X4 meshMatrix; + XMStoreFloat4x4(&meshMatrix, mesh->aabb.getAsBoxMatrix() * W); - const TransformComponent& transform = transforms[object.transform_index]; + // We need sometimes the center of the instance bounding box, not the transform position (which can be outside the bounding box) + object.center = *((XMFLOAT3*)&meshMatrix._41); - if (mesh != nullptr) + if (mesh->IsSkinned() || mesh->IsDynamic()) { - XMMATRIX W = XMLoadFloat4x4(&transform.world); - aabb = mesh->aabb.transform(W); - - // This is instance bounding box matrix: - XMFLOAT4X4 meshMatrix; - XMStoreFloat4x4(&meshMatrix, mesh->aabb.getAsBoxMatrix() * W); - - // We need sometimes the center of the instance bounding box, not the transform position (which can be outside the bounding box) - object.center = *((XMFLOAT3*)&meshMatrix._41); - - if (mesh->IsSkinned() || mesh->IsDynamic()) + object.SetDynamic(true); + const ArmatureComponent* armature = armatures.GetComponent(mesh->armatureID); + if (armature != nullptr) { - object.SetDynamic(true); - const ArmatureComponent* armature = armatures.GetComponent(mesh->armatureID); - if (armature != nullptr) - { - aabb = AABB::Merge(aabb, armature->aabb); - } + aabb = AABB::Merge(aabb, armature->aabb); } + } - for (auto& subset : mesh->subsets) + for (auto& subset : mesh->subsets) + { + const MaterialComponent* material = materials.GetComponent(subset.materialID); + + if (material != nullptr) { - const MaterialComponent* material = materials.GetComponent(subset.materialID); - - if (material != nullptr) + if (material->IsCustomShader()) { - if (material->IsCustomShader()) + object.rendertypeMask |= RENDERTYPE_ALL; + } + else + { + if (material->IsTransparent()) { - object.rendertypeMask |= RENDERTYPE_ALL; + object.rendertypeMask |= RENDERTYPE_TRANSPARENT; } else { - if (material->IsTransparent()) - { - object.rendertypeMask |= RENDERTYPE_TRANSPARENT; - } - else - { - object.rendertypeMask |= RENDERTYPE_OPAQUE; - } - - if (material->IsWater()) - { - object.rendertypeMask |= RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER; - } + object.rendertypeMask |= RENDERTYPE_OPAQUE; } - if (material->HasPlanarReflection()) + if (material->IsWater()) { - object.SetRequestPlanarReflection(true); - XMVECTOR P = transform.GetPositionV(); - XMVECTOR N = XMVectorSet(0, 1, 0, 0); - N = XMVector3TransformNormal(N, XMLoadFloat4x4(&transform.world)); - XMVECTOR _refPlane = XMPlaneFromPointNormal(P, N); - XMStoreFloat4(&waterPlane, _refPlane); + object.rendertypeMask |= RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER; } - - object.SetCastShadow(material->IsCastingShadow()); } - } - ImpostorComponent* impostor = impostors.GetComponent(object.meshID); - if (impostor != nullptr) - { - object.SetImpostorPlacement(true); - object.impostorSwapDistance = impostor->swapInDistance; - object.impostorFadeThresholdRadius = aabb.getRadius(); - - impostor->aabb = AABB::Merge(impostor->aabb, aabb); - impostor->color = object.color; - impostor->fadeThresholdRadius = object.impostorFadeThresholdRadius; - - const SPHERE boundingsphere = mesh->GetBoundingSphere(); - - impostor->instanceMatrices.emplace_back(); - XMStoreFloat4x4(&impostor->instanceMatrices.back(), - XMMatrixScaling(boundingsphere.radius, boundingsphere.radius, boundingsphere.radius) * - XMMatrixTranslation(boundingsphere.center.x, boundingsphere.center.y, boundingsphere.center.z) * - W - ); - } - - SoftBodyPhysicsComponent* softbody = softbodies.GetComponent(object.meshID); - if (softbody != nullptr) - { - // this will be registered as soft body in the next physics update - softbody->_flags |= SoftBodyPhysicsComponent::SAFE_TO_REGISTER; - - // soft body manipulated with the object matrix - softbody->worldMatrix = transform.world; - - if (softbody->graphicsToPhysicsVertexMapping.empty()) + if (material->HasPlanarReflection()) { - softbody->CreateFromMesh(*mesh); + object.SetRequestPlanarReflection(true); } - // simulation aabb will be used for soft bodies - aabb = softbody->aabb; + object.SetCastShadow(material->IsCastingShadow()); + } + } - // soft bodies have no transform, their vertices are simulated in world space - object.transform_index = -1; - object.prev_transform_index = -1; + ImpostorComponent* impostor = impostors.GetComponent(object.meshID); + if (impostor != nullptr) + { + object.SetImpostorPlacement(true); + object.impostorSwapDistance = impostor->swapInDistance; + object.impostorFadeThresholdRadius = aabb.getRadius(); + + impostor->aabb = AABB::Merge(impostor->aabb, aabb); + impostor->color = object.color; + impostor->fadeThresholdRadius = object.impostorFadeThresholdRadius; + + const SPHERE boundingsphere = mesh->GetBoundingSphere(); + + locker.lock(); + impostor->instanceMatrices.emplace_back(); + XMStoreFloat4x4(&impostor->instanceMatrices.back(), + XMMatrixScaling(boundingsphere.radius, boundingsphere.radius, boundingsphere.radius) * + XMMatrixTranslation(boundingsphere.center.x, boundingsphere.center.y, boundingsphere.center.z) * + W + ); + locker.unlock(); + } + + SoftBodyPhysicsComponent* softbody = softbodies.GetComponent(object.meshID); + if (softbody != nullptr) + { + // this will be registered as soft body in the next physics update + softbody->_flags |= SoftBodyPhysicsComponent::SAFE_TO_REGISTER; + + // soft body manipulated with the object matrix + softbody->worldMatrix = transform.world; + + if (softbody->graphicsToPhysicsVertexMapping.empty()) + { + softbody->CreateFromMesh(*mesh); } - sceneBounds = AABB::Merge(sceneBounds, aabb); + // simulation aabb will be used for soft bodies + aabb = softbody->aabb; + + // soft bodies have no transform, their vertices are simulated in world space + object.transform_index = -1; + object.prev_transform_index = -1; } } + + // parallel bounds computation using shared memory: + AABB* shared_bounds = (AABB*)args.sharedmemory; + if (args.isFirstJobInGroup) + { + *shared_bounds = aabb_objects[args.jobIndex]; + } + else + { + *shared_bounds = AABB::Merge(*shared_bounds, aabb_objects[args.jobIndex]); + } + if (args.isLastJobInGroup) + { + parallel_bounds[args.groupID] = *shared_bounds; + } } - }); + }, sizeof(AABB)); } - void RunCameraUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& transforms, - ComponentManager& cameras - ) + void Scene::RunCameraUpdateSystem(wiJobSystem::context& ctx) { - wiJobSystem::Dispatch(ctx, (uint32_t)cameras.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)cameras.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { CameraComponent& camera = cameras[args.jobIndex]; Entity entity = cameras.GetEntity(args.jobIndex); @@ -2278,17 +2237,11 @@ namespace wiScene camera.UpdateCamera(); }); } - void RunDecalUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& transforms, - const ComponentManager& materials, - ComponentManager& aabb_decals, - ComponentManager& decals - ) + void Scene::RunDecalUpdateSystem(wiJobSystem::context& ctx) { assert(decals.GetCount() == aabb_decals.GetCount()); - wiJobSystem::Dispatch(ctx, (uint32_t)decals.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)decals.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { DecalComponent& decal = decals[args.jobIndex]; Entity entity = decals.GetEntity(args.jobIndex); @@ -2318,16 +2271,11 @@ namespace wiScene decal.normal = material.normalMap; }); } - void RunProbeUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& transforms, - ComponentManager& aabb_probes, - ComponentManager& probes - ) + void Scene::RunProbeUpdateSystem(wiJobSystem::context& ctx) { assert(probes.GetCount() == aabb_probes.GetCount()); - wiJobSystem::Dispatch(ctx, (uint32_t)probes.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)probes.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { EnvironmentProbeComponent& probe = probes[args.jobIndex]; Entity entity = probes.GetEntity(args.jobIndex); @@ -2349,13 +2297,9 @@ namespace wiScene aabb = aabb.transform(transform.world); }); } - void RunForceUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& transforms, - ComponentManager& forces - ) + void Scene::RunForceUpdateSystem(wiJobSystem::context& ctx) { - wiJobSystem::Dispatch(ctx, (uint32_t)forces.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)forces.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { ForceFieldComponent& force = forces[args.jobIndex]; Entity entity = forces.GetEntity(args.jobIndex); @@ -2371,16 +2315,11 @@ namespace wiScene force.range_global = force.range_local * std::max(XMVectorGetX(S), std::max(XMVectorGetY(S), XMVectorGetZ(S))); }); } - void RunLightUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& transforms, - ComponentManager& aabb_lights, - ComponentManager& lights - ) + void Scene::RunLightUpdateSystem(wiJobSystem::context& ctx) { assert(lights.GetCount() == aabb_lights.GetCount()); - wiJobSystem::Dispatch(ctx, (uint32_t)lights.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)lights.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { LightComponent& light = lights[args.jobIndex]; Entity entity = lights.GetEntity(args.jobIndex); @@ -2402,6 +2341,14 @@ namespace wiScene { case LightComponent::DIRECTIONAL: aabb.createFromHalfWidth(wiRenderer::GetCamera().Eye, XMFLOAT3(10000, 10000, 10000)); + locker.lock(); + if (args.jobIndex < weather.most_important_light_index) + { + weather.most_important_light_index = args.jobIndex; + weather.sunColor = light.color; + weather.sunDirection = light.direction; + } + locker.unlock(); break; case LightComponent::SPOT: aabb.createFromHalfWidth(light.position, XMFLOAT3(light.GetRange(), light.GetRange(), light.GetRange())); @@ -2422,16 +2369,9 @@ namespace wiScene }); } - void RunParticleUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& transforms, - const ComponentManager& meshes, - ComponentManager& emitters, - ComponentManager& hairs, - float dt - ) + void Scene::RunParticleUpdateSystem(wiJobSystem::context& ctx, float dt) { - wiJobSystem::Dispatch(ctx, (uint32_t)emitters.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)emitters.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { wiEmittedParticle& emitter = emitters[args.jobIndex]; Entity entity = emitters.GetEntity(args.jobIndex); @@ -2439,7 +2379,7 @@ namespace wiScene emitter.UpdateCPU(transform, dt); }); - wiJobSystem::Dispatch(ctx, (uint32_t)hairs.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) { + wiJobSystem::Dispatch(ctx, (uint32_t)hairs.GetCount(), small_subtask_groupsize, [&](wiJobArgs args) { wiHairParticle& hair = hairs[args.jobIndex]; @@ -2458,32 +2398,15 @@ namespace wiScene }); } - void RunWeatherUpdateSystem( - wiJobSystem::context& ctx, - const ComponentManager& weathers, - const ComponentManager& lights, - WeatherComponent& weather) + void Scene::RunWeatherUpdateSystem(wiJobSystem::context& ctx) { if (weathers.GetCount() > 0) { weather = weathers[0]; - } - - for (size_t i = 0; i < lights.GetCount(); ++i) - { - const LightComponent& light = lights[i]; - if (light.GetType() == LightComponent::DIRECTIONAL) - { - weather.sunColor = light.color; - weather.sunDirection = light.direction; - } + weather.most_important_light_index = ~0; } } - void RunSoundUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - wiECS::ComponentManager& sounds - ) + void Scene::RunSoundUpdateSystem(wiJobSystem::context& ctx) { const CameraComponent& camera = wiRenderer::GetCamera(); wiAudio::SoundInstance3D instance3D; diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index 2b311b3f5..1582a18f6 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -9,6 +9,7 @@ #include "wiAudio.h" #include "wiRenderer.h" #include "wiResourceManager.h" +#include "wiSpinLock.h" #include "wiECS.h" #include "wiScene_Decl.h" @@ -995,6 +996,9 @@ namespace wiScene std::string skyMapName; std::shared_ptr skyMap; + // Non-serialized attributes: + uint32_t most_important_light_index = ~0; + void Serialize(wiArchive& archive, wiECS::Entity seed = wiECS::INVALID_ENTITY); }; @@ -1107,8 +1111,9 @@ namespace wiScene wiECS::ComponentManager springs; // Non-serialized attributes: + wiSpinLock locker; AABB bounds; - XMFLOAT4 waterPlane = XMFLOAT4(0, 1, 0, 0); + std::vector parallel_bounds; WeatherComponent weather; // Update all components by a given timestep (in seconds): @@ -1187,118 +1192,26 @@ namespace wiScene void Component_DetachChildren(wiECS::Entity parent); void Serialize(wiArchive& archive); - }; - void RunPreviousFrameTransformUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - wiECS::ComponentManager& prev_transforms - ); - void RunAnimationUpdateSystem( - wiJobSystem::context& ctx, - wiECS::ComponentManager& animations, - wiECS::ComponentManager& transforms, - float dt - ); - void RunTransformUpdateSystem( - wiJobSystem::context& ctx, - wiECS::ComponentManager& transforms - ); - void RunHierarchyUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& hierarchy, - wiECS::ComponentManager& transforms, - wiECS::ComponentManager& layers - ); - void RunSpringUpdateSystem( - wiJobSystem::context& ctx, - const WeatherComponent& weather, - const wiECS::ComponentManager& hierarchy, - wiECS::ComponentManager& transforms, - wiECS::ComponentManager& springs, - float dt - ); - void RunInverseKinematicsUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& inverse_kinematics, - const wiECS::ComponentManager& hierarchy, - wiECS::ComponentManager& transforms - ); - void RunArmatureUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - wiECS::ComponentManager& armatures - ); - void RunMaterialUpdateSystem( - wiJobSystem::context& ctx, - wiECS::ComponentManager& materials, float dt - ); - void RunImpostorUpdateSystem( - wiJobSystem::context& ctx, - wiECS::ComponentManager& impostors - ); - void RunObjectUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& prev_transforms, - const wiECS::ComponentManager& transforms, - const wiECS::ComponentManager& meshes, - const wiECS::ComponentManager& materials, - const wiECS::ComponentManager& armatures, - wiECS::ComponentManager& objects, - wiECS::ComponentManager& aabb_objects, - wiECS::ComponentManager& impostors, - wiECS::ComponentManager& softbodies, - AABB& sceneBounds, - XMFLOAT4& waterPlane - ); - void RunCameraUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - wiECS::ComponentManager& cameras - ); - void RunDecalUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - const wiECS::ComponentManager& materials, - wiECS::ComponentManager& aabb_decals, - wiECS::ComponentManager& decals - ); - void RunProbeUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - wiECS::ComponentManager& aabb_probes, - wiECS::ComponentManager& probes - ); - void RunForceUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - wiECS::ComponentManager& forces - ); - void RunLightUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - wiECS::ComponentManager& aabb_lights, - wiECS::ComponentManager& lights - ); - void RunParticleUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - const wiECS::ComponentManager& meshes, - wiECS::ComponentManager& emitters, - wiECS::ComponentManager& hairs, - float dt - ); - void RunWeatherUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& weathers, - const wiECS::ComponentManager& lights, - WeatherComponent& weather - ); - void RunSoundUpdateSystem( - wiJobSystem::context& ctx, - const wiECS::ComponentManager& transforms, - wiECS::ComponentManager& sounds - ); + void RunPreviousFrameTransformUpdateSystem(wiJobSystem::context& ctx); + void RunAnimationUpdateSystem(wiJobSystem::context& ctx, float dt); + void RunTransformUpdateSystem(wiJobSystem::context& ctx); + void RunHierarchyUpdateSystem(wiJobSystem::context& ctx); + void RunSpringUpdateSystem(wiJobSystem::context& ctx, float dt); + void RunInverseKinematicsUpdateSystem(wiJobSystem::context& ctx); + void RunArmatureUpdateSystem(wiJobSystem::context& ctx); + void RunMaterialUpdateSystem(wiJobSystem::context& ctx, float dt); + void RunImpostorUpdateSystem(wiJobSystem::context& ctx); + void RunObjectUpdateSystem(wiJobSystem::context& ctx); + void RunCameraUpdateSystem(wiJobSystem::context& ctx); + void RunDecalUpdateSystem(wiJobSystem::context& ctx); + void RunProbeUpdateSystem(wiJobSystem::context& ctx); + void RunForceUpdateSystem(wiJobSystem::context& ctx); + void RunLightUpdateSystem(wiJobSystem::context& ctx); + void RunParticleUpdateSystem(wiJobSystem::context& ctx, float dt); + void RunWeatherUpdateSystem(wiJobSystem::context& ctx); + void RunSoundUpdateSystem(wiJobSystem::context& ctx); + }; // Returns skinned vertex position in armature local space // N : normal (out, optional) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 83ee60430..66a95344a 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 42; // minor bug fixes, alterations, refactors, updates - const int revision = 3; + const int revision = 4; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);