Skip to content

Commit 594c480

Browse files
jazzvazXottab-DUTY
authored andcommitted
Replace ttapi with thread pool
1 parent cb29816 commit 594c480

File tree

15 files changed

+180
-324
lines changed

15 files changed

+180
-324
lines changed

src/Layers/xrRender/ParticleEffect.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "ParticleEffect.h"
44
#ifndef _EDITOR
55
#include <xmmintrin.h>
6-
#include "xrCore/Threading/ttapi.h"
6+
#include "xrCore/Threading/ThreadPool.hpp"
77
#endif
88

99
using namespace PAPI;
@@ -434,7 +434,7 @@ __forceinline void magnitude_sse(Fvector& vec, float& res)
434434
_mm_store_ss((float*)&res, tv);
435435
}
436436

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

590-
u32 nWorkers = ttapi_GetWorkerCount();
590+
u32 nWorkers = ttapi.threads.size();
591591

592+
// XXX: Xottab_DUTY: Review this
592593
if (p_cnt < nWorkers * 64)
593594
nWorkers = 1;
594595

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

616-
ttapi_Run();
617+
ttapi.wait();
617618

618619
dwCount = p_cnt << 2;
619620

src/Layers/xrRenderPC_R1/FStaticRender.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
#include "Layers/xrRender/lighttrack.h"
1616
#include "Layers/xrRender/dxWallMarkArray.h"
1717
#include "Layers/xrRender/dxUIShader.h"
18-
#ifndef _EDITOR
19-
#include "xrCore/Threading/ttapi.h"
20-
#endif
2118

2219
using namespace R_dsgraph;
2320

src/Layers/xrRenderPC_R1/LightProjector.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88
#include "xrEngine/xr_object.h"
99
#include "Layers/xrRender/LightTrack.h"
1010

11-
#ifndef _EDITOR
12-
#include "xrCore/Threading/ttapi.h"
13-
#endif
14-
1511
// tir2.xrdemo -> 45.2
1612
// tir2.xrdemo -> 61.8
1713

src/Layers/xrRenderPC_R1/LightShadows.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
#include "xrEngine/xr_object.h"
55
#include "Layers/xrRender/FBasicVisual.h"
66
#include "xrEngine/CustomHUD.h"
7-
#ifndef _EDITOR
8-
#include "xrCore/Threading/ttapi.h"
9-
#endif
107
#include "xrCore/Math/MathUtil.hpp"
118
using namespace XRay::Math;
129

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

353+
// XXX: use PLC_energy from xrCore
356354
IC float PLC_energy(Fvector& P, Fvector& N, light* L, float E)
357355
{
358356
Fvector Ldir;
@@ -386,6 +384,7 @@ IC float PLC_energy(Fvector& P, Fvector& N, light* L, float E)
386384
}
387385
}
388386

387+
// XXX: use PLC_calc from xrCore (maybe)
389388
IC int PLC_calc(Fvector& P, Fvector& N, light* L, float energy, Fvector& O)
390389
{
391390
float E = PLC_energy(P, N, L, energy);

src/xrCore/Math/MathUtil.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "stdafx.h"
22
#include "MathUtil.hpp"
3-
#include "Threading/ttapi.h"
3+
#include "Threading/ThreadPool.hpp"
44

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

59-
if (ttapi_GetWorkerCount() > 1)
63+
if (ttapi.threads.size() > 1)
6064
Skin4W = Skin4W_MT;
6165

6266
initialized = true;
6367
}
64-
6568
} // namespace Math
6669
} // namespace XRay

src/xrCore/Math/Skin4W_MT.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "stdafx.h"
22
#include "Skin4W_MT.hpp"
3-
#include "Threading/ttapi.h"
3+
#include "Threading/ThreadPool.hpp"
44
#ifdef _EDITOR
55
#include "SkeletonX.h"
66
#include "SkeletonCustom.h"
@@ -28,6 +28,7 @@ void Skin4W_Stream(void* params)
2828
#ifdef _GPA_ENABLED
2929
TAL_SCOPED_TASK_NAMED("Skin4W_Stream()");
3030
#endif
31+
3132
auto& sp = *(SkinParams*)params;
3233
auto dst = (vertRender*)sp.Dest;
3334
auto src = (vertBoned4W*)sp.Src;
@@ -40,7 +41,7 @@ void Skin4W_MT(vertRender* dst, vertBoned4W* src, u32 vCount, CBoneInstance* bon
4041
#ifdef _GPA_ENABLED
4142
TAL_SCOPED_TASK_NAMED("Skin4W_MT()");
4243
#endif
43-
u32 workerCount = ttapi_GetWorkerCount();
44+
u32 workerCount = ttapi.threads.size();
4445
if (vCount < workerCount * 64)
4546
{
4647
Skin4W_MTs(dst, src, vCount, bones);
@@ -57,10 +58,10 @@ void Skin4W_MT(vertRender* dst, vertBoned4W* src, u32 vCount, CBoneInstance* bon
5758
params[i].Src = src + i * nStep;
5859
params[i].Count = i == (workerCount - 1) ? nLast : nStep;
5960
params[i].Data = bones;
60-
ttapi_AddWorker(Skin4W_Stream, &params[i]);
61+
ttapi.threads[i]->addJob([=] { Skin4W_Stream(&params[i]); });
6162
}
62-
ttapi_Run();
63+
ttapi.wait();
6364
}
6465

65-
} // namespace Util3D
66+
} // namespace Math
6667
} // namespace XRay

src/xrCore/Threading/ThreadPool.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include "stdafx.h"
2+
#include "Threading/ThreadPool.hpp"
3+
#ifdef _GPA_ENABLED
4+
#include <tal.h>
5+
#endif
6+
7+
/*
8+
* Basic C++11 based thread pool with per-thread job queues
9+
*
10+
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
11+
*
12+
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
13+
*/
14+
15+
Thread::Thread()
16+
{
17+
worker = std::thread(&Thread::queueLoop, this);
18+
}
19+
20+
Thread::~Thread()
21+
{
22+
if (worker.joinable())
23+
{
24+
wait();
25+
queueMutex.lock();
26+
destroying = true;
27+
condition.notify_one();
28+
queueMutex.unlock();
29+
worker.join();
30+
}
31+
}
32+
33+
void Thread::addJob(std::function<void()> function)
34+
{
35+
std::lock_guard<std::mutex> lock(queueMutex);
36+
jobQueue.push(std::move(function));
37+
condition.notify_one();
38+
}
39+
40+
void Thread::wait()
41+
{
42+
std::unique_lock<std::mutex> lock(queueMutex);
43+
condition.wait(lock, [this]() { return jobQueue.empty(); });
44+
}
45+
46+
void Thread::queueLoop()
47+
{
48+
while (true)
49+
{
50+
std::function<void()> job;
51+
{
52+
std::unique_lock<std::mutex> lock(queueMutex);
53+
condition.wait(lock, [this] { return !jobQueue.empty() || destroying; });
54+
if (destroying)
55+
{
56+
break;
57+
}
58+
job = jobQueue.front();
59+
}
60+
61+
job();
62+
63+
{
64+
std::lock_guard<std::mutex> lock(queueMutex);
65+
jobQueue.pop();
66+
condition.notify_one();
67+
}
68+
}
69+
}
70+
71+
XRCORE_API ThreadPool ttapi;

src/xrCore/Threading/ThreadPool.hpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#pragma once
2+
#include "xrCore/xrCore.h"
3+
4+
/*
5+
* Basic C++11 based thread pool with per-thread job queues
6+
*
7+
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
8+
*
9+
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
10+
*/
11+
12+
#include <vector>
13+
#include <thread>
14+
#include <queue>
15+
#include <mutex>
16+
#include <condition_variable>
17+
#include <functional>
18+
#include <memory>
19+
20+
class XRCORE_API Thread
21+
{
22+
bool destroying = false;
23+
std::thread worker;
24+
std::queue<std::function<void()>> jobQueue;
25+
std::mutex queueMutex;
26+
std::condition_variable condition;
27+
28+
// Loop through all remaining jobs
29+
void queueLoop();
30+
31+
public:
32+
Thread();
33+
~Thread();
34+
35+
// Add a new job to the thread's queue
36+
void addJob(std::function<void()> function);
37+
38+
// Wait until all work items have been finished
39+
void wait();
40+
};
41+
42+
class ThreadPool
43+
{
44+
public:
45+
std::vector<std::unique_ptr<Thread>> threads;
46+
47+
void initialize()
48+
{
49+
const int num_threads = std::thread::hardware_concurrency();
50+
R_ASSERT(num_threads > 0);
51+
setThreadCount(num_threads);
52+
}
53+
54+
// Sets the number of threads to be allocated in this pool
55+
void setThreadCount(const uint32_t count)
56+
{
57+
threads.clear();
58+
for (auto i = 0; i < count; i++)
59+
threads.push_back(std::make_unique<Thread>());
60+
}
61+
62+
// Wait until all threads have finished their work items
63+
void wait()
64+
{
65+
for (auto &thread : threads)
66+
thread->wait();
67+
}
68+
};
69+
70+
extern XRCORE_API ThreadPool ttapi;

0 commit comments

Comments
 (0)