Skip to content

Commit fe4a579

Browse files
committed
feat: Multithread architecture prototype
1 parent 08da044 commit fe4a579

8 files changed

Lines changed: 233 additions & 123 deletions

File tree

include/Render/IDrawable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,7 @@ namespace sh::render
2828

2929
SH_RENDER_API virtual void SetFramebuffer(Framebuffer& framebuffer) = 0;
3030
SH_RENDER_API virtual auto GetFramebuffer() const -> const Framebuffer* = 0;
31+
32+
SH_RENDER_API virtual void SyncGameThread() = 0;
3133
};
3234
}

include/Render/Renderer.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "glm/vec2.hpp"
88

9+
#include <array>
910
#include <map>
1011
#include <queue>
1112
#include <set>
@@ -34,15 +35,21 @@ namespace sh::render {
3435
sh::window::Window* window;
3536
uint32_t nextCameraId;
3637
protected:
38+
static constexpr int GAME_THREAD = 0;
39+
static constexpr int RENDER_THREAD = 1;
40+
3741
std::queue<CameraHandle> emptyHandle;
42+
//todo
3843
std::vector<const Camera*> camHandles;
39-
std::map<Camera, std::queue<IDrawable*>> drawList;
44+
std::array<std::map<Camera, std::vector<IDrawable*>>, 2> drawList;
4045

4146
glm::vec2 viewportStart;
4247
glm::vec2 viewportEnd;
4348

4449
CameraHandle mainCamera;
4550

51+
std::mutex drawListMutex;
52+
4653
bool bPause;
4754
public:
4855
const RenderAPI apiType;
@@ -69,6 +76,10 @@ namespace sh::render {
6976
SH_RENDER_API auto GetViewportEnd() const -> const glm::vec2&;
7077

7178
SH_RENDER_API void ClearDrawList();
79+
/// @brief [게임 스레드 전용] 드로우 객체를 큐에 집어 넣는다.
80+
/// @param drawable 드로우 객체 포인터
81+
/// @param camHandle 카메라 핸들
82+
/// @return
7283
SH_RENDER_API void PushDrawAble(IDrawable* drawable, CameraHandle camHandle = 0);
7384

7485
SH_RENDER_API auto GetWindow() -> sh::window::Window&;
@@ -77,5 +88,9 @@ namespace sh::render {
7788
SH_RENDER_API void DeleteCamera(CameraHandle cam);
7889
SH_RENDER_API void SetMainCamera(CameraHandle cam);
7990
SH_RENDER_API void SetCameraDepth(CameraHandle, int depth);
91+
92+
/// @brief 메인 스레드와 동기화 하는 함수.
93+
/// @return
94+
SH_RENDER_API void SyncGameThread();
8095
};
8196
}

include/Render/VulkanDrawable.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <vector>
1212
#include <memory>
13+
#include <array>
1314

1415
namespace sh::render
1516
{
@@ -18,21 +19,23 @@ namespace sh::render
1819
{
1920
SCLASS(VulkanDrawable)
2021
private:
22+
static constexpr int GAME_THREAD = 0;
23+
static constexpr int RENDER_THREAD = 1;
24+
2125
VulkanRenderer& renderer;
2226
PROPERTY(mat)
2327
Material* mat;
2428
PROPERTY(mesh)
2529
Mesh* mesh;
26-
27-
std::unique_ptr<impl::VulkanPipeline> pipeline;
28-
29-
VkDescriptorSet descriptorSet;
30-
31-
std::map<uint32_t, impl::VulkanBuffer> uniformBuffers;
32-
PROPERTY(mesh)
30+
PROPERTY(textures)
3331
std::map<uint32_t, Texture*> textures;
3432

3533
Framebuffer* framebuffer;
34+
35+
std::unique_ptr<impl::VulkanPipeline> pipeline;
36+
//동기화 필요 목록
37+
std::array<VkDescriptorSet, 2> descriptorSet;
38+
std::array<std::map<uint32_t, impl::VulkanBuffer>, 2> uniformBuffers;
3639
private:
3740
void CreateDescriptorSet();
3841
public:
@@ -48,6 +51,10 @@ namespace sh::render
4851
SH_RENDER_API auto GetMaterial() const -> Material* override;
4952
SH_RENDER_API auto GetMesh() const-> Mesh* override;
5053

54+
/// @brief [게임 스레드용] 유니폼에 데이터를 지정한다.
55+
/// @param binding 바인딩 번호
56+
/// @param data 데이터 위치 포인터
57+
/// @return
5158
SH_RENDER_API void SetUniformData(uint32_t binding, const void* data) override;
5259
SH_RENDER_API void SetTextureData(uint32_t binding, Texture* tex) override;
5360

@@ -56,5 +63,7 @@ namespace sh::render
5663

5764
SH_RENDER_API void SetFramebuffer(Framebuffer& framebuffer) override;
5865
SH_RENDER_API auto GetFramebuffer() const -> const Framebuffer* override;
66+
67+
SH_RENDER_API void SyncGameThread() override;
5968
};
6069
}

src/Editor/EditorUI.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ namespace sh::editor
254254
}
255255
}
256256
}
257+
257258
void EditorUI::Render()
258259
{
259260
if (!imgui.IsInit())

src/Render/Renderer.cpp

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "Renderer.h"
2+
#include "IDrawable.h"
23

34
#include <cassert>
45
namespace sh::render
@@ -31,24 +32,25 @@ namespace sh::render
3132
{
3233
if (drawable == nullptr)
3334
return;
34-
if (drawList.empty()) //카메라가 없다.
35+
if (drawList[GAME_THREAD].empty()) //카메라가 없다.
3536
return;
3637
if (cam >= camHandles.size())
3738
return;
3839
if (camHandles[cam] == nullptr)
3940
return;
4041

41-
if (auto it = drawList.find(*camHandles[cam]); it != drawList.end())
42+
auto& map = drawList[GAME_THREAD];
43+
if (auto it = map.find(*camHandles[cam]); it != map.end())
4244
{
43-
it->second.push(drawable);
45+
it->second.push_back(drawable);
4446
}
4547
}
4648

4749
void Renderer::ClearDrawList()
4850
{
4951
emptyHandle = std::queue<CameraHandle>{};
5052
camHandles.clear();
51-
drawList.clear();
53+
drawList[GAME_THREAD].clear();
5254
AddCamera(0);
5355
}
5456

@@ -76,8 +78,13 @@ namespace sh::render
7678
{
7779
id = nextCameraId++;
7880
Camera cam{ id, depth };
79-
auto result = drawList.insert({cam , std::queue<IDrawable*>{} });
80-
if (drawList.size() == 1)
81+
auto result = drawList[GAME_THREAD].insert({ cam , std::vector<IDrawable*>{} });
82+
83+
drawListMutex.lock();
84+
drawList[RENDER_THREAD].insert({ cam, std::vector<IDrawable*>{} });
85+
drawListMutex.unlock();
86+
87+
if (drawList[GAME_THREAD].size() == 1)
8188
mainCamera = id;
8289

8390
camHandles.push_back(&result.first->first);
@@ -87,8 +94,13 @@ namespace sh::render
8794
id = emptyHandle.front();
8895
emptyHandle.pop();
8996
Camera cam{ id, depth };
90-
auto result = drawList.insert({ cam , std::queue<IDrawable*>{} });
91-
if (drawList.size() == 1)
97+
auto result = drawList[GAME_THREAD].insert({ cam , std::vector<IDrawable*>{} });
98+
99+
drawListMutex.lock();
100+
drawList[RENDER_THREAD].insert({ cam , std::vector<IDrawable*>{} });
101+
drawListMutex.unlock();
102+
103+
if (drawList[GAME_THREAD].size() == 1)
92104
mainCamera = id;
93105

94106
camHandles[id] = &result.first->first;
@@ -105,18 +117,22 @@ namespace sh::render
105117

106118
const Camera* camera = camHandles[cam];
107119

108-
auto it = drawList.find(*camera);
109-
if (it == drawList.end())
120+
auto it = drawList[GAME_THREAD].find(*camera);
121+
if (it == drawList[GAME_THREAD].end())
110122
return;
111123

112124
emptyHandle.push(it->first.id);
113-
drawList.erase(it);
125+
drawList[GAME_THREAD].erase(it);
126+
127+
drawListMutex.lock();
128+
drawList[RENDER_THREAD].erase(*camera);
129+
drawListMutex.unlock();
114130

115131
if (mainCamera == cam)
116132
{
117-
if (drawList.empty())
133+
if (drawList[GAME_THREAD].empty())
118134
return;
119-
mainCamera = drawList.begin()->first.id;
135+
mainCamera = drawList[GAME_THREAD].begin()->first.id;
120136
}
121137
}
122138

@@ -132,16 +148,38 @@ namespace sh::render
132148
if (camHandles[cam] == nullptr)
133149
return;
134150

135-
auto it = drawList.find(*camHandles[cam]);
136-
if (it == drawList.end())
151+
auto it = drawList[GAME_THREAD].find(*camHandles[cam]);
152+
if (it == drawList[GAME_THREAD].end())
137153
return;
138154

139-
auto queue = std::move(it->second);
155+
auto& vec = it->second;
140156

141157
Camera tempCam{ it->first.id, depth };
142158

143-
drawList.erase(it);
144-
auto result = drawList.insert({ tempCam, std::move(queue) });
159+
drawList[GAME_THREAD].erase(it);
160+
auto result = drawList[GAME_THREAD].insert({ tempCam, std::move(vec) });
161+
162+
drawListMutex.lock();
163+
drawList[RENDER_THREAD].erase(*camHandles[cam]);
164+
drawList[RENDER_THREAD].insert({ tempCam, std::vector<IDrawable*>{} });
165+
drawListMutex.unlock();
166+
145167
camHandles[cam] = &result.first->first;
146168
}
169+
170+
void Renderer::SyncGameThread()
171+
{
172+
std::swap(drawList[GAME_THREAD], drawList[RENDER_THREAD]);
173+
for (auto& pair : drawList[GAME_THREAD])
174+
{
175+
pair.second.clear();
176+
}
177+
for (auto& pair : drawList[RENDER_THREAD])
178+
{
179+
for (auto drawable : pair.second)
180+
{
181+
drawable->SyncGameThread();
182+
}
183+
}
184+
}
147185
}

0 commit comments

Comments
 (0)