Skip to content

Commit

Permalink
Replace ttapi with thread pool
Browse files Browse the repository at this point in the history
  • Loading branch information
jazzvaz authored and Xottab-DUTY committed Dec 28, 2017
1 parent cb29816 commit 594c480
Show file tree
Hide file tree
Showing 15 changed files with 180 additions and 324 deletions.
11 changes: 6 additions & 5 deletions src/Layers/xrRender/ParticleEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "ParticleEffect.h"
#ifndef _EDITOR
#include <xmmintrin.h>
#include "xrCore/Threading/ttapi.h"
#include "xrCore/Threading/ThreadPool.hpp"
#endif

using namespace PAPI;
Expand Down Expand Up @@ -434,7 +434,7 @@ __forceinline void magnitude_sse(Fvector& vec, float& res)
_mm_store_ss((float*)&res, tv);
}

void ParticleRenderStream(LPVOID lpvParams)
void ParticleRenderStream(void* lpvParams)
{
#ifdef _GPA_ENABLED
TAL_SCOPED_TASK_NAMED("ParticleRenderStream()");
Expand Down Expand Up @@ -587,8 +587,9 @@ void CParticleEffect::Render(float)
FVF::LIT* pv_start = (FVF::LIT*)RCache.Vertex.Lock(p_cnt * 4 * 4, geom->vb_stride, dwOffset);
FVF::LIT* pv = pv_start;

u32 nWorkers = ttapi_GetWorkerCount();
u32 nWorkers = ttapi.threads.size();

// XXX: Xottab_DUTY: Review this
if (p_cnt < nWorkers * 64)
nWorkers = 1;

Expand All @@ -610,10 +611,10 @@ void CParticleEffect::Render(float)
prsParams[i].p_to = (i == (nWorkers - 1)) ? p_cnt : (prsParams[i].p_from + nStep);
prsParams[i].particles = particles;
prsParams[i].pPE = this;
ttapi_AddWorker(ParticleRenderStream, (LPVOID)&prsParams[i]);
ttapi.threads[i]->addJob([=] { ParticleRenderStream((void*)&prsParams[i]); });
}

ttapi_Run();
ttapi.wait();

dwCount = p_cnt << 2;

Expand Down
3 changes: 0 additions & 3 deletions src/Layers/xrRenderPC_R1/FStaticRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
#include "Layers/xrRender/lighttrack.h"
#include "Layers/xrRender/dxWallMarkArray.h"
#include "Layers/xrRender/dxUIShader.h"
#ifndef _EDITOR
#include "xrCore/Threading/ttapi.h"
#endif

using namespace R_dsgraph;

Expand Down
4 changes: 0 additions & 4 deletions src/Layers/xrRenderPC_R1/LightProjector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
#include "xrEngine/xr_object.h"
#include "Layers/xrRender/LightTrack.h"

#ifndef _EDITOR
#include "xrCore/Threading/ttapi.h"
#endif

// tir2.xrdemo -> 45.2
// tir2.xrdemo -> 61.8

Expand Down
5 changes: 2 additions & 3 deletions src/Layers/xrRenderPC_R1/LightShadows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
#include "xrEngine/xr_object.h"
#include "Layers/xrRender/FBasicVisual.h"
#include "xrEngine/CustomHUD.h"
#ifndef _EDITOR
#include "xrCore/Threading/ttapi.h"
#endif
#include "xrCore/Math/MathUtil.hpp"
using namespace XRay::Math;

Expand Down Expand Up @@ -353,6 +350,7 @@ IC bool cache_search(const CLightShadows::cache_item& A, const CLightShadows::ca
return false; // eq
}

// XXX: use PLC_energy from xrCore
IC float PLC_energy(Fvector& P, Fvector& N, light* L, float E)
{
Fvector Ldir;
Expand Down Expand Up @@ -386,6 +384,7 @@ IC float PLC_energy(Fvector& P, Fvector& N, light* L, float E)
}
}

// XXX: use PLC_calc from xrCore (maybe)
IC int PLC_calc(Fvector& P, Fvector& N, light* L, float energy, Fvector& O)
{
float E = PLC_energy(P, N, L, energy);
Expand Down
9 changes: 6 additions & 3 deletions src/xrCore/Math/MathUtil.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "stdafx.h"
#include "MathUtil.hpp"
#include "Threading/ttapi.h"
#include "Threading/ThreadPool.hpp"

#ifdef _EDITOR
#include "SkeletonX.h"
Expand Down Expand Up @@ -55,12 +55,15 @@ void Initialize()
PLCCalc = PLCCalc_SSE;
//PLCCalc = PLCCalc_CPP;
#endif
// XXX: use PLC_energy and iCeil too
// SSE implementations of this functions is not used.
// Found duplicate implementation in src\Layers\xrRenderPC_R1\LightShadows.cpp
// Search for other duplicates

if (ttapi_GetWorkerCount() > 1)
if (ttapi.threads.size() > 1)
Skin4W = Skin4W_MT;

initialized = true;
}

} // namespace Math
} // namespace XRay
11 changes: 6 additions & 5 deletions src/xrCore/Math/Skin4W_MT.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "stdafx.h"
#include "Skin4W_MT.hpp"
#include "Threading/ttapi.h"
#include "Threading/ThreadPool.hpp"
#ifdef _EDITOR
#include "SkeletonX.h"
#include "SkeletonCustom.h"
Expand Down Expand Up @@ -28,6 +28,7 @@ void Skin4W_Stream(void* params)
#ifdef _GPA_ENABLED
TAL_SCOPED_TASK_NAMED("Skin4W_Stream()");
#endif

auto& sp = *(SkinParams*)params;
auto dst = (vertRender*)sp.Dest;
auto src = (vertBoned4W*)sp.Src;
Expand All @@ -40,7 +41,7 @@ void Skin4W_MT(vertRender* dst, vertBoned4W* src, u32 vCount, CBoneInstance* bon
#ifdef _GPA_ENABLED
TAL_SCOPED_TASK_NAMED("Skin4W_MT()");
#endif
u32 workerCount = ttapi_GetWorkerCount();
u32 workerCount = ttapi.threads.size();
if (vCount < workerCount * 64)
{
Skin4W_MTs(dst, src, vCount, bones);
Expand All @@ -57,10 +58,10 @@ void Skin4W_MT(vertRender* dst, vertBoned4W* src, u32 vCount, CBoneInstance* bon
params[i].Src = src + i * nStep;
params[i].Count = i == (workerCount - 1) ? nLast : nStep;
params[i].Data = bones;
ttapi_AddWorker(Skin4W_Stream, &params[i]);
ttapi.threads[i]->addJob([=] { Skin4W_Stream(&params[i]); });
}
ttapi_Run();
ttapi.wait();
}

} // namespace Util3D
} // namespace Math
} // namespace XRay
71 changes: 71 additions & 0 deletions src/xrCore/Threading/ThreadPool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "stdafx.h"
#include "Threading/ThreadPool.hpp"
#ifdef _GPA_ENABLED
#include <tal.h>
#endif

/*
* Basic C++11 based thread pool with per-thread job queues
*
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/

Thread::Thread()
{
worker = std::thread(&Thread::queueLoop, this);
}

Thread::~Thread()
{
if (worker.joinable())
{
wait();
queueMutex.lock();
destroying = true;
condition.notify_one();
queueMutex.unlock();
worker.join();
}
}

void Thread::addJob(std::function<void()> function)
{
std::lock_guard<std::mutex> lock(queueMutex);
jobQueue.push(std::move(function));
condition.notify_one();
}

void Thread::wait()
{
std::unique_lock<std::mutex> lock(queueMutex);
condition.wait(lock, [this]() { return jobQueue.empty(); });
}

void Thread::queueLoop()
{
while (true)
{
std::function<void()> job;
{
std::unique_lock<std::mutex> lock(queueMutex);
condition.wait(lock, [this] { return !jobQueue.empty() || destroying; });
if (destroying)
{
break;
}
job = jobQueue.front();
}

job();

{
std::lock_guard<std::mutex> lock(queueMutex);
jobQueue.pop();
condition.notify_one();
}
}
}

XRCORE_API ThreadPool ttapi;
70 changes: 70 additions & 0 deletions src/xrCore/Threading/ThreadPool.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#pragma once
#include "xrCore/xrCore.h"

/*
* Basic C++11 based thread pool with per-thread job queues
*
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/

#include <vector>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <memory>

class XRCORE_API Thread
{
bool destroying = false;
std::thread worker;
std::queue<std::function<void()>> jobQueue;
std::mutex queueMutex;
std::condition_variable condition;

// Loop through all remaining jobs
void queueLoop();

public:
Thread();
~Thread();

// Add a new job to the thread's queue
void addJob(std::function<void()> function);

// Wait until all work items have been finished
void wait();
};

class ThreadPool
{
public:
std::vector<std::unique_ptr<Thread>> threads;

void initialize()
{
const int num_threads = std::thread::hardware_concurrency();
R_ASSERT(num_threads > 0);
setThreadCount(num_threads);
}

// Sets the number of threads to be allocated in this pool
void setThreadCount(const uint32_t count)
{
threads.clear();
for (auto i = 0; i < count; i++)
threads.push_back(std::make_unique<Thread>());
}

// Wait until all threads have finished their work items
void wait()
{
for (auto &thread : threads)
thread->wait();
}
};

extern XRCORE_API ThreadPool ttapi;
Loading

0 comments on commit 594c480

Please sign in to comment.