Skip to content

Commit

Permalink
sokol: Implement depth buffer clear
Browse files Browse the repository at this point in the history
  • Loading branch information
IonAgorria committed May 19, 2024
1 parent 0af93fe commit f85702f
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 43 deletions.
50 changes: 23 additions & 27 deletions Source/Render/sokol/SokolRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,12 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
desc.image_pool_size = 1024 * 4; //1024 is enough for PGW+PET game
desc.logger.func = slog_func;

//Setup swapchain pass
swapchain_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;
//Setup swapchain and fill color
swapchain = {};
swapchain.width = ScreenSize.x;
swapchain.height = ScreenSize.y;
swapchain.sample_count = 1;
fill_color = sg_color { 0.0f, 0.0f, 0.0f, 1.0f };

//OpenGL / OpenGLES
#ifdef SOKOL_GL
Expand Down Expand Up @@ -138,7 +130,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
}
printf("GPU vendor: %s, renderer: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDER));

swapchain_pass.swapchain.gl.framebuffer = 0;
swapchain.gl.framebuffer = 0;
#endif //SOKOL_GL

//Direct3D
Expand Down Expand Up @@ -221,7 +213,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
dxgiAdapter->Release();

//Create swap chain
uint32_t sample_count = swapchain_pass.swapchain.sample_count;
uint32_t sample_count = swapchain.sample_count;
DXGI_SWAP_CHAIN_DESC* swap_chain_desc = &d3d_context->swap_chain_desc;
memset(&d3d_context->swap_chain_desc, 0, sizeof(DXGI_SWAP_CHAIN_DESC));
swap_chain_desc->BufferDesc.Width = static_cast<uint32_t>(xScr);
Expand Down Expand Up @@ -258,7 +250,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "metal", SDL_HINT_OVERRIDE);

//Setup metal sokol context
sokol_metal_setup(sdl_window, &desc, &swapchain_pass.swapchain, ScreenHZ);
sokol_metal_setup(sdl_window, &desc, &swapchain, ScreenHZ);
#endif

const char* render_driver = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
Expand Down Expand Up @@ -325,8 +317,8 @@ bool cSokolRender::ChangeSize(int xScr, int yScr, int mode) {
RenderMode |= mode;

//Update swapchain
swapchain_pass.swapchain.width = ScreenSize.x;
swapchain_pass.swapchain.height = ScreenSize.y;
swapchain.width = ScreenSize.x;
swapchain.height = ScreenSize.y;

#ifdef SOKOL_D3D11
if (d3d_context->swap_chain && need_resize) {
Expand Down Expand Up @@ -381,9 +373,9 @@ int cSokolRender::Done() {
}
#endif
#ifdef SOKOL_METAL
if (swapchain_pass.swapchain.metal.current_drawable != nullptr) {
if (swapchain.metal.current_drawable != nullptr) {
RenderSubmitEvent(RenderEvent::DONE, "Sokol Metal shutdown");
sokol_metal_destroy(&swapchain_pass.swapchain);
sokol_metal_destroy(&swapchain);
}
#endif
#ifdef SOKOL_GL
Expand Down Expand Up @@ -582,15 +574,15 @@ void cSokolRender::d3d_CreateDefaultRenderTarget() {
assert(SUCCEEDED(hr) && d3d_context->depth_stencil_view);

//Apply into swapchain pass
swapchain_pass.swapchain.d3d11.render_view = 1 < sample_count ? d3d_context->msaa_view : d3d_context->render_target_view;
swapchain_pass.swapchain.d3d11.resolve_view = 1 < sample_count ? d3d_context->render_target_view : nullptr;
swapchain_pass.swapchain.d3d11.depth_stencil_view = d3d_context->depth_stencil_view;
swapchain.d3d11.render_view = 1 < sample_count ? d3d_context->msaa_view : d3d_context->render_target_view;
swapchain.d3d11.resolve_view = 1 < sample_count ? d3d_context->render_target_view : nullptr;
swapchain.d3d11.depth_stencil_view = d3d_context->depth_stencil_view;
}

void cSokolRender::d3d_DestroyDefaultRenderTarget() {
swapchain_pass.swapchain.d3d11.render_view = nullptr;
swapchain_pass.swapchain.d3d11.resolve_view = nullptr;
swapchain_pass.swapchain.d3d11.depth_stencil_view = nullptr;
swapchain.d3d11.render_view = nullptr;
swapchain.d3d11.resolve_view = nullptr;
swapchain.d3d11.depth_stencil_view = nullptr;
RELEASE(d3d_context->render_target_texture);
RELEASE(d3d_context->render_target_view);
RELEASE(d3d_context->depth_stencil_texture);
Expand Down Expand Up @@ -638,6 +630,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
8 changes: 6 additions & 2 deletions Source/Render/sokol/SokolRender.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ struct SokolCommand {
void ClearShaderParams();
void SetTexture(size_t index, SokolResource<sg_image>* sokol_texture);
void ClearTextures();
NO_COPY_CONSTRUCTOR(SokolCommand)
NO_COPY_CONSTRUCTOR(SokolCommand);

pipeline_id_t pipeline_id = 0;
SOKOL_SHADER_ID shader_id = SOKOL_SHADER_ID_NONE;
sg_pass_action* pass_action = nullptr;
size_t base_elements = 0;
size_t vertices = 0;
size_t indices = 0;
Expand Down Expand Up @@ -73,7 +74,8 @@ class cSokolRender: public cInterfaceRenderDevice {
std::unordered_multimap<uint64_t, SokolResourcePooled<sg_buffer>> bufferPool;

//For swapchain pass that renders into final device
sg_pass swapchain_pass;
sg_swapchain swapchain = {};
sg_color fill_color = {};

//Renderer state
bool ActiveScene = false;
Expand Down Expand Up @@ -117,8 +119,10 @@ class cSokolRender: public cInterfaceRenderDevice {
Mat4f activeTextureTransform[PERIMETER_SOKOL_TEXTURES];

//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
115 changes: 101 additions & 14 deletions Source/Render/sokol/SokolRenderState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ int cSokolRender::EndScene() {
}

//Make sure there is nothing left to send as command
FinishActiveDrawBuffer();

ClearActiveBufferAndPassAction();
xassert(activeDrawBuffer == nullptr);
xassert(activeCommand.pass_action == nullptr);

ActiveScene = false;

#ifdef SOKOL_METAL
sokol_metal_render(&swapchain_pass.swapchain, &sokol_metal_render_callback);
sokol_metal_render(&swapchain, &sokol_metal_render_callback);
#else
DoSokolRendering();
#endif
Expand All @@ -77,18 +78,39 @@ int cSokolRender::EndScene() {

void cSokolRender::DoSokolRendering() {
//This function might be called from a callback!

//Begin main swapchain pass

//Create the pass, clear all buffers
sg_pass swapchain_pass = {};
swapchain_pass.label = "PassSwapchain";
swapchain_pass.swapchain = swapchain;
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 = fill_color;
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;
sg_begin_pass(&swapchain_pass);

//Iterate each command
for (auto& command : commands) {
#ifdef PERIMETER_RENDER_TRACKER_COMMANDS
RenderSubmitEvent(RenderEvent::PROCESS_COMMAND, "", command);
#endif
//Change pass if set
if (command->pass_action) {
sg_end_pass();
memcpy(&swapchain_pass.action, command->pass_action, sizeof(sg_pass_action));
swapchain_pass.swapchain = swapchain;
sg_begin_pass(&swapchain_pass);
}

//Nothing to draw
if (3 > command->vertices) {
xassert(0);
continue;
}

Expand Down Expand Up @@ -268,6 +290,39 @@ int cSokolRender::Flush(bool wnd) {
return 0;
}


void cSokolRender::ClearActiveBufferAndPassAction() {
if (activeDrawBuffer) {
//Send out any active DB before we set a pass action
//otherwise it might be renderer after setting new pass
FinishActiveDrawBuffer();
}
if (activeCommand.pass_action) {
//Active command has a pass action already and there was no active DB
//Create a empty command
CreateCommandEmpty();
if (activeCommand.pass_action) {
xassert(0);
delete activeCommand.pass_action;
activeCommand.pass_action = nullptr;
}
}
}

void cSokolRender::ClearZBuffer() {
//Keep color and stencil buffers, clear depth buffer
ClearActiveBufferAndPassAction();
sg_pass_action* action = new sg_pass_action();
action->colors[0].load_action = SG_LOADACTION_LOAD;
action->colors[0].store_action = SG_STOREACTION_STORE;
action->depth.load_action = SG_LOADACTION_CLEAR;
action->depth.store_action = SG_STOREACTION_DONTCARE;
action->depth.clear_value = 1.0f;
action->stencil.load_action = SG_LOADACTION_LOAD;
action->stencil.store_action = SG_STOREACTION_DONTCARE;
activeCommand.pass_action = action;
}

int cSokolRender::Fill(int r, int g, int b, int a) {
RenderSubmitEvent(RenderEvent::FILL);
if (ActiveScene) {
Expand All @@ -284,12 +339,10 @@ int cSokolRender::Fill(int r, int g, int b, int a) {
}
#endif

sg_color fill_color;
fill_color.r = static_cast<float>(r) / 255.f;
fill_color.g = static_cast<float>(g) / 255.f;
fill_color.b = static_cast<float>(b) / 255.f;
fill_color.a = static_cast<float>(a) / 255.f;
swapchain_pass.action.colors[0].clear_value = fill_color;

return 0;
}
Expand Down Expand Up @@ -383,8 +436,42 @@ void cSokolRender::FinishActiveDrawBuffer() {
activeDrawBuffer = nullptr;
}

void cSokolRender::CreateCommandEmpty() {
xassert(ActiveScene);
MT_IS_GRAPH();

#ifdef PERIMETER_RENDER_TRACKER_COMMANDS
std::string label = "Pipeline: Empty";
RenderSubmitEvent(RenderEvent::CREATE_COMMAND, label.c_str());
#endif

//Create command to be send
SokolCommand* cmd = new SokolCommand();
memcpy(cmd->viewport, activeCommand.viewport, sizeof(Vect2i) * 2);
memcpy(cmd->clip, activeCommand.clip, sizeof(Vect2i) * 2);

//Pass the pass action
if (activeCommand.pass_action) {
cmd->pass_action = activeCommand.pass_action;
activeCommand.pass_action = nullptr;
}

//Submit command
commands.emplace_back(cmd);

#ifdef PERIMETER_RENDER_TRACKER_COMMANDS
label = "Submit - Pipeline: " + std::to_string(pipeline_id)
+ " Vtxs: " + std::to_string(cmd->vertices)
+ " Idxs: " + std::to_string(cmd->indices)
+ " Tex0: " + std::to_string(reinterpret_cast<size_t>(cmd->sokol_textures[0]))
+ " Tex1: " + std::to_string(reinterpret_cast<size_t>(cmd->sokol_textures[1]));
RenderSubmitEvent(RenderEvent::CREATE_COMMAND, label.c_str(), cmd);
#endif
}

void cSokolRender::CreateCommand(VertexBuffer* vb, size_t vertices, IndexBuffer* ib, size_t indices) {
xassert(ActiveScene);
xassert(vb);
MT_IS_GRAPH();
if (0 == vertices) vertices = activeCommand.vertices;
if (0 == indices) indices = activeCommand.indices;
Expand Down Expand Up @@ -510,14 +597,17 @@ void cSokolRender::CreateCommand(VertexBuffer* vb, size_t vertices, IndexBuffer*
activeCommand.vertices = 0;
activeCommand.indices = 0;

//Pass the pass action
if (activeCommand.pass_action) {
cmd->pass_action = activeCommand.pass_action;
activeCommand.pass_action = nullptr;
}

//Submit command
commands.emplace_back(cmd);

#ifdef PERIMETER_RENDER_TRACKER_COMMANDS
label = "Submit - Pipeline: " + std::to_string(pipeline_id)
+ " ColM: " + std::to_string(activeCommand.fs_color_mode)
+ " OwVB: " + std::to_string(cmd->owned_vertex_buffer)
+ " OwIB: " + std::to_string(cmd->owned_index_buffer)
+ " Vtxs: " + std::to_string(cmd->vertices)
+ " Idxs: " + std::to_string(cmd->indices)
+ " Tex0: " + std::to_string(reinterpret_cast<size_t>(cmd->sokol_textures[0]))
Expand Down Expand Up @@ -927,7 +1017,4 @@ void cSokolRender::SetGlobalLight(Vect3f *vLight, sColor4f *Ambient, sColor4f *D
activeLightAmbient = *Ambient;
activeLightSpecular = *Specular;
}
}

void cSokolRender::ClearZBuffer() {
}
}

0 comments on commit f85702f

Please sign in to comment.