Skip to content

Commit

Permalink
Fix after rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-ushakov committed May 23, 2024
1 parent 17fb2ea commit e4f9d7b
Show file tree
Hide file tree
Showing 13 changed files with 1,489 additions and 2,894 deletions.
22 changes: 11 additions & 11 deletions Source/Game/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,23 +141,23 @@ SET(perimeter_LINK_LIBS
${SDL2_MIXER_LIBRARY}
${SDL2_NET_LIBRARY}
${EXE_LINK_LIBS_POST}
"-framework Foundation"
"-framework AppKit"
"-framework QuartzCore"
"-framework CoreAudio"
"-framework AudioToolbox"
"-framework CoreHaptics"
"-framework Carbon"
"-framework Cocoa"
"-framework CoreAudio"
"-framework CoreBluetooth"
"-framework CoreGraphics"
"-framework CoreHaptics"
"-framework CoreMedia"
"-framework CoreMotion"
"-framework ForceFeedback"
"-framework Foundation"
"-framework GameController"
"-framework IOKit"
"-framework Metal"
"-framework CoreBluetooth"
"-framework CoreMotion"
"-framework CoreMedia"
"-framework QuartzCore"
"-framework Security"
"-framework Carbon"
"-framework Cocoa"
"-framework IOKit"
"-framework ForceFeedback"
)

IF(PERIMETER_WINDOWS)
Expand Down
93 changes: 65 additions & 28 deletions Source/Render/sokol/SokolRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "RenderTracker.h"
#include <SDL_hints.h>

#ifdef SOKOL_GL
#ifdef PERIMETER_SOKOL_GL
#include <SDL_opengl.h>
#endif

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

uint32_t cSokolRender::GetWindowCreationFlags() const {
uint32_t flags = cInterfaceRenderDevice::GetWindowCreationFlags();
#ifdef SOKOL_GL
#ifdef PERIMETER_SOKOL_GL
flags |= SDL_WINDOW_OPENGL;
#endif
#ifdef SOKOL_METAL
Expand All @@ -62,6 +62,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
return res;
}

ClearPooledResources(0);
ClearCommands();
ClearPipelines();

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

//Setup swapchain pass
//Setup swapchain and fill color
render_targets.emplace_back();
auto& swapchain_pass = render_targets[0].render_pass;
swapchain_pass.action.colors[0].load_action = SG_LOADACTION_CLEAR;
swapchain_pass.action.colors[0].store_action = SG_STOREACTION_STORE;
swapchain_pass.action.colors[0].clear_value = sg_color { 0.0f, 0.0f, 0.0f, 1.0f };
swapchain_pass.action.depth.load_action = SG_LOADACTION_CLEAR;
swapchain_pass.action.depth.store_action = SG_STOREACTION_DONTCARE;
swapchain_pass.action.depth.clear_value = 1.0f;
swapchain_pass.action.stencil.load_action = SG_LOADACTION_CLEAR;
swapchain_pass.action.stencil.store_action = SG_STOREACTION_DONTCARE;
swapchain_pass.action.stencil.clear_value = 0;
swapchain_pass.swapchain.width = ScreenSize.x;
swapchain_pass.swapchain.height = ScreenSize.y;
swapchain_pass.swapchain.sample_count = 1;
fill_color = sg_color { 0.0f, 0.0f, 0.0f, 1.0f };

//OpenGL / OpenGLES
#ifdef SOKOL_GL
#ifdef PERIMETER_SOKOL_GL
//Setup some attributes before context creation
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
Expand All @@ -109,15 +103,15 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);
//*/

#ifdef SOKOL_GLCORE33
//Use OpenGL 3.3 Core
sokol_backend = "OpenGL Core 3.3";
#ifdef SOKOL_GLCORE
//Use OpenGL Core
sokol_backend = "OpenGL Core";

SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "opengl", SDL_HINT_OVERRIDE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
#endif

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

auto& swapchain_pass = render_targets[0].render_pass;
swapchain_pass.swapchain.gl.framebuffer = 0;
#endif //SOKOL_GL
#endif //PERIMETER_SOKOL_GL

//Direct3D
#ifdef SOKOL_D3D11
Expand Down Expand Up @@ -231,10 +225,10 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
swap_chain_desc->BufferDesc.RefreshRate = { static_cast<uint32_t>(RefreshRateInHz), 1 };
swap_chain_desc->OutputWindow = d3d_context->hwnd;
swap_chain_desc->Windowed = (mode & RENDERDEVICE_MODE_WINDOW) != 0;
swap_chain_desc->SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swap_chain_desc->BufferCount = 1;
swap_chain_desc->SampleDesc.Count = sample_count;
swap_chain_desc->SampleDesc.Quality = 1 < sample_count ? static_cast<uint32_t>(D3D11_STANDARD_MULTISAMPLE_PATTERN) : 0;
swap_chain_desc->SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swap_chain_desc->BufferCount = 2;
swap_chain_desc->SampleDesc.Count = 1;
swap_chain_desc->SampleDesc.Quality = 0;
swap_chain_desc->BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swap_chain_desc->Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
hr = dxgiFactory->CreateSwapChain(d3d_context->device, swap_chain_desc, &d3d_context->swap_chain);
Expand Down Expand Up @@ -321,7 +315,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
}

bool cSokolRender::ChangeSize(int xScr, int yScr, int mode) {
int mode_mask = RENDERDEVICE_MODE_WINDOW;
int mode_mask = RENDERDEVICE_MODE_WINDOW | RENDERDEVICE_MODE_VSYNC;

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

Expand All @@ -333,6 +327,11 @@ bool cSokolRender::ChangeSize(int xScr, int yScr, int mode) {
ScreenSize.y = yScr;
RenderMode &= ~mode_mask;
RenderMode |= mode;

//Set vsync
#ifdef PERIMETER_SOKOL_GL
SDL_GL_SetSwapInterval(RenderMode & RENDERDEVICE_MODE_VSYNC ? 1 : 0);
#endif

//Update swapchain
auto& swapchain_pass = render_targets[0].render_pass;
Expand Down Expand Up @@ -368,6 +367,7 @@ int cSokolRender::Done() {
bool do_sg_shutdown = sdl_window != nullptr;
int ret = cInterfaceRenderDevice::Done();
activeCommand.Clear();
ClearPooledResources(0);
ClearCommands();
ClearPipelines();
shaders.clear();
Expand Down Expand Up @@ -397,7 +397,7 @@ int cSokolRender::Done() {
sokol_metal_destroy(&swapchain_pass.swapchain);
}
#endif
#ifdef SOKOL_GL
#ifdef PERIMETER_SOKOL_GL
if (sdl_gl_context != nullptr) {
RenderSubmitEvent(RenderEvent::DONE, "Sokol GL shutdown");
SDL_GL_DeleteContext(sdl_gl_context);
Expand Down Expand Up @@ -432,6 +432,33 @@ void cSokolRender::DeleteIndexBuffer(IndexBuffer &ib) {
ib.FreeData();
}

#define ClearPooledResources_Debug 0
void cSokolRender::ClearPooledResources(uint32_t max_life) {
if (bufferPool.empty()) {
return;
}
#if defined(PERIMETER_DEBUG) && ClearPooledResources_Debug
size_t count = bufferPool.size();
#endif
auto it = bufferPool.begin();
while (it != bufferPool.end()) {
auto& res = it->second;
res.unused_since++;
if (res.unused_since >= max_life) {
res.resource->DecRef();
res.resource = nullptr;
it = bufferPool.erase(it);
} else {
it++;
}
}
#if defined(PERIMETER_DEBUG) && ClearPooledResources_Debug
if (count != bufferPool.size()) {
printf("ClearPooledResources %" PRIsize " -> %" PRIsize "\n", count, bufferPool.size());
}
#endif
}

void cSokolRender::ClearCommands() {
std::unordered_set<SokolResourceBuffer*> pooled;
for (auto& render_target : render_targets) {
Expand All @@ -441,14 +468,20 @@ void cSokolRender::ClearCommands() {
if (vertex_buffer && vertex_buffer->key != SokolResourceKeyNone && pooled.count(vertex_buffer) == 0) {
command->vertex_buffer = nullptr;
xassert(0 < vertex_buffer->RefCount() && vertex_buffer->RefCount() <= 50);
bufferPool.emplace(vertex_buffer->key, vertex_buffer);
bufferPool.emplace(
vertex_buffer->key,
SokolResourcePooled(vertex_buffer)
);
pooled.emplace(vertex_buffer);
}
SokolResourceBuffer* index_buffer = command->index_buffer;
if (index_buffer && index_buffer->key != SokolResourceKeyNone && pooled.count(index_buffer) == 0) {
command->index_buffer = nullptr;
xassert(0 < index_buffer->RefCount() && index_buffer->RefCount() <= 50);
bufferPool.emplace(index_buffer->key, index_buffer);
bufferPool.emplace(
index_buffer->key,
SokolResourcePooled(index_buffer)
);
pooled.emplace(index_buffer);
}

Expand Down Expand Up @@ -626,6 +659,10 @@ void SokolCommand::CreateShaderParams() {
}

void SokolCommand::ClearDrawData() {
if (pass_action) {
delete pass_action;
pass_action = nullptr;
}
if (vertex_buffer) {
vertex_buffer->DecRef();
vertex_buffer = nullptr;
Expand Down
28 changes: 22 additions & 6 deletions Source/Render/sokol/SokolRender.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef PERIMETER_SOKOLRENDER_H
#define PERIMETER_SOKOLRENDER_H

#if defined(SOKOL_GLCORE33) || defined(SOKOL_GLES3)
#define SOKOL_GL (1)
#if defined(SOKOL_GLCORE) || defined(SOKOL_GLES3)
#define PERIMETER_SOKOL_GL (1)
#endif

#include <tuple>
Expand All @@ -23,9 +23,10 @@ struct SokolCommand {
void ClearShaderParams();
void SetTexture(size_t index, SokolResource<sg_image>* sokol_texture);
void ClearTextures();
NO_COPY_CONSTRUCTOR(SokolCommand)
NO_COPY_CONSTRUCTOR(SokolCommand);

struct SokolPipeline* pipeline = nullptr;
sg_pass_action* pass_action = nullptr;
size_t base_elements = 0;
size_t vertices = 0;
size_t indices = 0;
Expand Down Expand Up @@ -54,10 +55,20 @@ struct SokolPipelineContext {
}
};

template<typename T>
struct SokolResourcePooled {
///How many frames passed since last time it was used
uint32_t unused_since = 0;
SokolResource<T>* resource = nullptr;

explicit SokolResourcePooled(SokolResource<T>* res) : resource(res) {
}
};

class cSokolRender: public cInterfaceRenderDevice {
private:
//SDL context
#ifdef SOKOL_GL
#ifdef PERIMETER_SOKOL_GL
SDL_GLContext sdl_gl_context = nullptr;
#endif
#ifdef SOKOL_METAL
Expand All @@ -81,8 +92,11 @@ class cSokolRender: public cInterfaceRenderDevice {
float kShadow = 0.25f;

//Stores resources for reusing
std::unordered_multimap<uint64_t, SokolResourceBuffer*> bufferPool;

void ClearPooledResources(uint32_t max_life);
std::unordered_multimap<uint64_t, SokolResourcePooled<sg_buffer>> bufferPool;

sg_color fill_color = {};

//Renderer state
bool ActiveScene = false;
bool isOrthographicProjSet = false;
Expand Down Expand Up @@ -137,8 +151,10 @@ class cSokolRender: public cInterfaceRenderDevice {
Vect2f activeWorldSize{};

//Commands handling
void ClearActiveBufferAndPassAction();
void ClearCommands();
void FinishActiveDrawBuffer();
void CreateCommandEmpty();
void CreateCommand(class VertexBuffer* vb, size_t vertices, class IndexBuffer* ib, size_t indices);
void SetVPMatrix(const Mat4f* matrix);
void SetTex2Lerp(float lerp);
Expand Down
Loading

0 comments on commit e4f9d7b

Please sign in to comment.