Skip to content

Commit 8ed928f

Browse files
committed
Fix after rebase
1 parent 17fb2ea commit 8ed928f

9 files changed

+1472
-2875
lines changed

Source/Render/sokol/SokolRender.cpp

+64-27
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "RenderTracker.h"
1515
#include <SDL_hints.h>
1616

17-
#ifdef SOKOL_GL
17+
#ifdef PERIMETER_SOKOL_GL
1818
#include <SDL_opengl.h>
1919
#endif
2020

@@ -41,7 +41,7 @@ eRenderDeviceSelection cSokolRender::GetRenderSelection() const {
4141

4242
uint32_t cSokolRender::GetWindowCreationFlags() const {
4343
uint32_t flags = cInterfaceRenderDevice::GetWindowCreationFlags();
44-
#ifdef SOKOL_GL
44+
#ifdef PERIMETER_SOKOL_GL
4545
flags |= SDL_WINDOW_OPENGL;
4646
#endif
4747
#ifdef SOKOL_METAL
@@ -62,6 +62,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
6262
return res;
6363
}
6464

65+
ClearPooledResources(0);
6566
ClearCommands();
6667
ClearPipelines();
6768

@@ -75,28 +76,21 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
7576
sg_desc desc = {};
7677
desc.pipeline_pool_size = PERIMETER_SOKOL_PIPELINES_MAX,
7778
desc.shader_pool_size = 8,
78-
desc.buffer_pool_size = 1024 * 8;
79+
desc.buffer_pool_size = 1024 * 32;
80+
desc.uniform_buffer_size = 1024 * 1024 * 32;
7981
desc.image_pool_size = 1024 * 4; //1024 is enough for PGW+PET game
8082
desc.logger.func = slog_func;
8183

8284
//Setup swapchain pass
8385
render_targets.emplace_back();
8486
auto& swapchain_pass = render_targets[0].render_pass;
85-
swapchain_pass.action.colors[0].load_action = SG_LOADACTION_CLEAR;
86-
swapchain_pass.action.colors[0].store_action = SG_STOREACTION_STORE;
87-
swapchain_pass.action.colors[0].clear_value = sg_color { 0.0f, 0.0f, 0.0f, 1.0f };
88-
swapchain_pass.action.depth.load_action = SG_LOADACTION_CLEAR;
89-
swapchain_pass.action.depth.store_action = SG_STOREACTION_DONTCARE;
90-
swapchain_pass.action.depth.clear_value = 1.0f;
91-
swapchain_pass.action.stencil.load_action = SG_LOADACTION_CLEAR;
92-
swapchain_pass.action.stencil.store_action = SG_STOREACTION_DONTCARE;
93-
swapchain_pass.action.stencil.clear_value = 0;
9487
swapchain_pass.swapchain.width = ScreenSize.x;
9588
swapchain_pass.swapchain.height = ScreenSize.y;
9689
swapchain_pass.swapchain.sample_count = 1;
90+
fill_color = sg_color { 0.0f, 0.0f, 0.0f, 1.0f };
9791

9892
//OpenGL / OpenGLES
99-
#ifdef SOKOL_GL
93+
#ifdef PERIMETER_SOKOL_GL
10094
//Setup some attributes before context creation
10195
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
10296
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
@@ -109,15 +103,15 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
109103
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);
110104
//*/
111105

112-
#ifdef SOKOL_GLCORE33
113-
//Use OpenGL 3.3 Core
114-
sokol_backend = "OpenGL Core 3.3";
106+
#ifdef SOKOL_GLCORE
107+
//Use OpenGL Core
108+
sokol_backend = "OpenGL Core";
115109

116110
SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "opengl", SDL_HINT_OVERRIDE);
117111
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
118112
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
119-
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
120-
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
113+
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
114+
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
121115
#endif
122116

123117
#if defined(SOKOL_GLES3)
@@ -139,7 +133,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
139133

140134
auto& swapchain_pass = render_targets[0].render_pass;
141135
swapchain_pass.swapchain.gl.framebuffer = 0;
142-
#endif //SOKOL_GL
136+
#endif //PERIMETER_SOKOL_GL
143137

144138
//Direct3D
145139
#ifdef SOKOL_D3D11
@@ -231,10 +225,10 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
231225
swap_chain_desc->BufferDesc.RefreshRate = { static_cast<uint32_t>(RefreshRateInHz), 1 };
232226
swap_chain_desc->OutputWindow = d3d_context->hwnd;
233227
swap_chain_desc->Windowed = (mode & RENDERDEVICE_MODE_WINDOW) != 0;
234-
swap_chain_desc->SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
235-
swap_chain_desc->BufferCount = 1;
236-
swap_chain_desc->SampleDesc.Count = sample_count;
237-
swap_chain_desc->SampleDesc.Quality = 1 < sample_count ? static_cast<uint32_t>(D3D11_STANDARD_MULTISAMPLE_PATTERN) : 0;
228+
swap_chain_desc->SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
229+
swap_chain_desc->BufferCount = 2;
230+
swap_chain_desc->SampleDesc.Count = 1;
231+
swap_chain_desc->SampleDesc.Quality = 0;
238232
swap_chain_desc->BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
239233
swap_chain_desc->Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
240234
hr = dxgiFactory->CreateSwapChain(d3d_context->device, swap_chain_desc, &d3d_context->swap_chain);
@@ -321,7 +315,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
321315
}
322316

323317
bool cSokolRender::ChangeSize(int xScr, int yScr, int mode) {
324-
int mode_mask = RENDERDEVICE_MODE_WINDOW;
318+
int mode_mask = RENDERDEVICE_MODE_WINDOW | RENDERDEVICE_MODE_VSYNC;
325319

326320
bool need_resize = xScr != ScreenSize.x || yScr != ScreenSize.y;
327321

@@ -333,6 +327,11 @@ bool cSokolRender::ChangeSize(int xScr, int yScr, int mode) {
333327
ScreenSize.y = yScr;
334328
RenderMode &= ~mode_mask;
335329
RenderMode |= mode;
330+
331+
//Set vsync
332+
#ifdef PERIMETER_SOKOL_GL
333+
SDL_GL_SetSwapInterval(RenderMode & RENDERDEVICE_MODE_VSYNC ? 1 : 0);
334+
#endif
336335

337336
//Update swapchain
338337
auto& swapchain_pass = render_targets[0].render_pass;
@@ -368,6 +367,7 @@ int cSokolRender::Done() {
368367
bool do_sg_shutdown = sdl_window != nullptr;
369368
int ret = cInterfaceRenderDevice::Done();
370369
activeCommand.Clear();
370+
ClearPooledResources(0);
371371
ClearCommands();
372372
ClearPipelines();
373373
shaders.clear();
@@ -397,7 +397,7 @@ int cSokolRender::Done() {
397397
sokol_metal_destroy(&swapchain_pass.swapchain);
398398
}
399399
#endif
400-
#ifdef SOKOL_GL
400+
#ifdef PERIMETER_SOKOL_GL
401401
if (sdl_gl_context != nullptr) {
402402
RenderSubmitEvent(RenderEvent::DONE, "Sokol GL shutdown");
403403
SDL_GL_DeleteContext(sdl_gl_context);
@@ -432,6 +432,33 @@ void cSokolRender::DeleteIndexBuffer(IndexBuffer &ib) {
432432
ib.FreeData();
433433
}
434434

435+
#define ClearPooledResources_Debug 0
436+
void cSokolRender::ClearPooledResources(uint32_t max_life) {
437+
if (bufferPool.empty()) {
438+
return;
439+
}
440+
#if defined(PERIMETER_DEBUG) && ClearPooledResources_Debug
441+
size_t count = bufferPool.size();
442+
#endif
443+
auto it = bufferPool.begin();
444+
while (it != bufferPool.end()) {
445+
auto& res = it->second;
446+
res.unused_since++;
447+
if (res.unused_since >= max_life) {
448+
res.resource->DecRef();
449+
res.resource = nullptr;
450+
it = bufferPool.erase(it);
451+
} else {
452+
it++;
453+
}
454+
}
455+
#if defined(PERIMETER_DEBUG) && ClearPooledResources_Debug
456+
if (count != bufferPool.size()) {
457+
printf("ClearPooledResources %" PRIsize " -> %" PRIsize "\n", count, bufferPool.size());
458+
}
459+
#endif
460+
}
461+
435462
void cSokolRender::ClearCommands() {
436463
std::unordered_set<SokolResourceBuffer*> pooled;
437464
for (auto& render_target : render_targets) {
@@ -441,14 +468,20 @@ void cSokolRender::ClearCommands() {
441468
if (vertex_buffer && vertex_buffer->key != SokolResourceKeyNone && pooled.count(vertex_buffer) == 0) {
442469
command->vertex_buffer = nullptr;
443470
xassert(0 < vertex_buffer->RefCount() && vertex_buffer->RefCount() <= 50);
444-
bufferPool.emplace(vertex_buffer->key, vertex_buffer);
471+
bufferPool.emplace(
472+
vertex_buffer->key,
473+
SokolResourcePooled(vertex_buffer)
474+
);
445475
pooled.emplace(vertex_buffer);
446476
}
447477
SokolResourceBuffer* index_buffer = command->index_buffer;
448478
if (index_buffer && index_buffer->key != SokolResourceKeyNone && pooled.count(index_buffer) == 0) {
449479
command->index_buffer = nullptr;
450480
xassert(0 < index_buffer->RefCount() && index_buffer->RefCount() <= 50);
451-
bufferPool.emplace(index_buffer->key, index_buffer);
481+
bufferPool.emplace(
482+
index_buffer->key,
483+
SokolResourcePooled(index_buffer)
484+
);
452485
pooled.emplace(index_buffer);
453486
}
454487

@@ -626,6 +659,10 @@ void SokolCommand::CreateShaderParams() {
626659
}
627660

628661
void SokolCommand::ClearDrawData() {
662+
if (pass_action) {
663+
delete pass_action;
664+
pass_action = nullptr;
665+
}
629666
if (vertex_buffer) {
630667
vertex_buffer->DecRef();
631668
vertex_buffer = nullptr;

Source/Render/sokol/SokolRender.h

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#ifndef PERIMETER_SOKOLRENDER_H
22
#define PERIMETER_SOKOLRENDER_H
33

4-
#if defined(SOKOL_GLCORE33) || defined(SOKOL_GLES3)
5-
#define SOKOL_GL (1)
4+
#if defined(SOKOL_GLCORE) || defined(SOKOL_GLES3)
5+
#define PERIMETER_SOKOL_GL (1)
66
#endif
77

88
#include <tuple>
@@ -26,6 +26,7 @@ struct SokolCommand {
2626
NO_COPY_CONSTRUCTOR(SokolCommand)
2727

2828
struct SokolPipeline* pipeline = nullptr;
29+
sg_pass_action* pass_action = nullptr;
2930
size_t base_elements = 0;
3031
size_t vertices = 0;
3132
size_t indices = 0;
@@ -54,10 +55,20 @@ struct SokolPipelineContext {
5455
}
5556
};
5657

58+
template<typename T>
59+
struct SokolResourcePooled {
60+
///How many frames passed since last time it was used
61+
uint32_t unused_since = 0;
62+
SokolResource<T>* resource = nullptr;
63+
64+
explicit SokolResourcePooled(SokolResource<T>* res) : resource(res) {
65+
}
66+
};
67+
5768
class cSokolRender: public cInterfaceRenderDevice {
5869
private:
5970
//SDL context
60-
#ifdef SOKOL_GL
71+
#ifdef PERIMETER_SOKOL_GL
6172
SDL_GLContext sdl_gl_context = nullptr;
6273
#endif
6374
#ifdef SOKOL_METAL
@@ -81,8 +92,11 @@ class cSokolRender: public cInterfaceRenderDevice {
8192
float kShadow = 0.25f;
8293

8394
//Stores resources for reusing
84-
std::unordered_multimap<uint64_t, SokolResourceBuffer*> bufferPool;
85-
95+
void ClearPooledResources(uint32_t max_life);
96+
std::unordered_multimap<uint64_t, SokolResourcePooled<sg_buffer>> bufferPool;
97+
98+
sg_color fill_color = {};
99+
86100
//Renderer state
87101
bool ActiveScene = false;
88102
bool isOrthographicProjSet = false;
@@ -137,8 +151,10 @@ class cSokolRender: public cInterfaceRenderDevice {
137151
Vect2f activeWorldSize{};
138152

139153
//Commands handling
154+
void ClearActiveBufferAndPassAction();
140155
void ClearCommands();
141156
void FinishActiveDrawBuffer();
157+
void CreateCommandEmpty();
142158
void CreateCommand(class VertexBuffer* vb, size_t vertices, class IndexBuffer* ib, size_t indices);
143159
void SetVPMatrix(const Mat4f* matrix);
144160
void SetTex2Lerp(float lerp);

0 commit comments

Comments
 (0)