14
14
#include " RenderTracker.h"
15
15
#include < SDL_hints.h>
16
16
17
- #ifdef SOKOL_GL
17
+ #ifdef PERIMETER_SOKOL_GL
18
18
#include < SDL_opengl.h>
19
19
#endif
20
20
@@ -41,7 +41,7 @@ eRenderDeviceSelection cSokolRender::GetRenderSelection() const {
41
41
42
42
uint32_t cSokolRender::GetWindowCreationFlags () const {
43
43
uint32_t flags = cInterfaceRenderDevice::GetWindowCreationFlags ();
44
- #ifdef SOKOL_GL
44
+ #ifdef PERIMETER_SOKOL_GL
45
45
flags |= SDL_WINDOW_OPENGL;
46
46
#endif
47
47
#ifdef SOKOL_METAL
@@ -62,6 +62,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
62
62
return res;
63
63
}
64
64
65
+ ClearPooledResources (0 );
65
66
ClearCommands ();
66
67
ClearPipelines ();
67
68
@@ -75,28 +76,21 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
75
76
sg_desc desc = {};
76
77
desc.pipeline_pool_size = PERIMETER_SOKOL_PIPELINES_MAX,
77
78
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 ;
79
81
desc.image_pool_size = 1024 * 4 ; // 1024 is enough for PGW+PET game
80
82
desc.logger .func = slog_func;
81
83
82
84
// Setup swapchain pass
83
85
render_targets.emplace_back ();
84
86
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 ;
94
87
swapchain_pass.swapchain .width = ScreenSize.x ;
95
88
swapchain_pass.swapchain .height = ScreenSize.y ;
96
89
swapchain_pass.swapchain .sample_count = 1 ;
90
+ fill_color = sg_color { 0 .0f , 0 .0f , 0 .0f , 1 .0f };
97
91
98
92
// OpenGL / OpenGLES
99
- #ifdef SOKOL_GL
93
+ #ifdef PERIMETER_SOKOL_GL
100
94
// Setup some attributes before context creation
101
95
SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1 );
102
96
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
109
103
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);
110
104
//*/
111
105
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" ;
115
109
116
110
SDL_SetHintWithPriority (SDL_HINT_RENDER_DRIVER, " opengl" , SDL_HINT_OVERRIDE);
117
111
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
118
112
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 );
121
115
#endif
122
116
123
117
#if defined(SOKOL_GLES3)
@@ -139,7 +133,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
139
133
140
134
auto & swapchain_pass = render_targets[0 ].render_pass ;
141
135
swapchain_pass.swapchain .gl .framebuffer = 0 ;
142
- #endif // SOKOL_GL
136
+ #endif // PERIMETER_SOKOL_GL
143
137
144
138
// Direct3D
145
139
#ifdef SOKOL_D3D11
@@ -231,10 +225,10 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
231
225
swap_chain_desc->BufferDesc .RefreshRate = { static_cast <uint32_t >(RefreshRateInHz), 1 };
232
226
swap_chain_desc->OutputWindow = d3d_context->hwnd ;
233
227
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 ;
238
232
swap_chain_desc->BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
239
233
swap_chain_desc->Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
240
234
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
321
315
}
322
316
323
317
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 ;
325
319
326
320
bool need_resize = xScr != ScreenSize.x || yScr != ScreenSize.y ;
327
321
@@ -333,6 +327,11 @@ bool cSokolRender::ChangeSize(int xScr, int yScr, int mode) {
333
327
ScreenSize.y = yScr;
334
328
RenderMode &= ~mode_mask;
335
329
RenderMode |= mode;
330
+
331
+ // Set vsync
332
+ #ifdef PERIMETER_SOKOL_GL
333
+ SDL_GL_SetSwapInterval (RenderMode & RENDERDEVICE_MODE_VSYNC ? 1 : 0 );
334
+ #endif
336
335
337
336
// Update swapchain
338
337
auto & swapchain_pass = render_targets[0 ].render_pass ;
@@ -368,6 +367,7 @@ int cSokolRender::Done() {
368
367
bool do_sg_shutdown = sdl_window != nullptr ;
369
368
int ret = cInterfaceRenderDevice::Done ();
370
369
activeCommand.Clear ();
370
+ ClearPooledResources (0 );
371
371
ClearCommands ();
372
372
ClearPipelines ();
373
373
shaders.clear ();
@@ -397,7 +397,7 @@ int cSokolRender::Done() {
397
397
sokol_metal_destroy (&swapchain_pass.swapchain );
398
398
}
399
399
#endif
400
- #ifdef SOKOL_GL
400
+ #ifdef PERIMETER_SOKOL_GL
401
401
if (sdl_gl_context != nullptr ) {
402
402
RenderSubmitEvent (RenderEvent::DONE, " Sokol GL shutdown" );
403
403
SDL_GL_DeleteContext (sdl_gl_context);
@@ -432,6 +432,33 @@ void cSokolRender::DeleteIndexBuffer(IndexBuffer &ib) {
432
432
ib.FreeData ();
433
433
}
434
434
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
+
435
462
void cSokolRender::ClearCommands () {
436
463
std::unordered_set<SokolResourceBuffer*> pooled;
437
464
for (auto & render_target : render_targets) {
@@ -441,14 +468,20 @@ void cSokolRender::ClearCommands() {
441
468
if (vertex_buffer && vertex_buffer->key != SokolResourceKeyNone && pooled.count (vertex_buffer) == 0 ) {
442
469
command->vertex_buffer = nullptr ;
443
470
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
+ );
445
475
pooled.emplace (vertex_buffer);
446
476
}
447
477
SokolResourceBuffer* index_buffer = command->index_buffer ;
448
478
if (index_buffer && index_buffer->key != SokolResourceKeyNone && pooled.count (index_buffer) == 0 ) {
449
479
command->index_buffer = nullptr ;
450
480
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
+ );
452
485
pooled.emplace (index_buffer);
453
486
}
454
487
@@ -626,6 +659,10 @@ void SokolCommand::CreateShaderParams() {
626
659
}
627
660
628
661
void SokolCommand::ClearDrawData () {
662
+ if (pass_action) {
663
+ delete pass_action;
664
+ pass_action = nullptr ;
665
+ }
629
666
if (vertex_buffer) {
630
667
vertex_buffer->DecRef ();
631
668
vertex_buffer = nullptr ;
0 commit comments