Skip to content

Commit e9f7c4f

Browse files
committed
Fixed amount of render targets
1 parent 1efae6f commit e9f7c4f

8 files changed

+240
-232
lines changed

Source/Render/sokol/SokolImpl.mm

+22-21
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,29 @@ void StartCapture() {
2424
return;
2525
}
2626

27-
MTLCaptureManager* capture_manager = [MTLCaptureManager sharedCaptureManager];
28-
if (![capture_manager supportsDestination:MTLCaptureDestinationGPUTraceDocument]) {
29-
fprintf(stderr, "FrameCaptureManager: unsupported destination\n");
30-
return;
31-
}
32-
33-
MTLCaptureDescriptor* capture_descriptor = [MTLCaptureDescriptor new];
34-
capture_descriptor.captureObject = mtl_device;
35-
capture_descriptor.destination = MTLCaptureDestinationGPUTraceDocument;
36-
const auto current_time = static_cast<unsigned long>([NSDate date].timeIntervalSince1970);
37-
_path = [[NSString stringWithFormat:@"/tmp/Perimeter_%lu.gputrace", current_time] copy];
38-
capture_descriptor.outputURL = [NSURL fileURLWithPath:_path];
39-
40-
NSError* error;
41-
BOOL result = [capture_manager startCaptureWithDescriptor:capture_descriptor error:&error];
42-
if (!result) {
43-
fprintf(stderr, "FrameCaptureManager: start capture error: %s\n", error.localizedDescription.UTF8String);
44-
return;
27+
@autoreleasepool {
28+
MTLCaptureManager* capture_manager = [MTLCaptureManager sharedCaptureManager];
29+
if (![capture_manager supportsDestination:MTLCaptureDestinationGPUTraceDocument]) {
30+
fprintf(stderr, "FrameCaptureManager: unsupported destination\n");
31+
return;
32+
}
33+
34+
MTLCaptureDescriptor* capture_descriptor = [MTLCaptureDescriptor new];
35+
capture_descriptor.captureObject = mtl_device;
36+
capture_descriptor.destination = MTLCaptureDestinationGPUTraceDocument;
37+
const auto current_time = static_cast<unsigned long>([NSDate date].timeIntervalSince1970);
38+
_path = [[NSString stringWithFormat:@"/tmp/Perimeter_%lu.gputrace", current_time] copy];
39+
capture_descriptor.outputURL = [NSURL fileURLWithPath:_path];
40+
41+
NSError* error;
42+
BOOL result = [capture_manager startCaptureWithDescriptor:capture_descriptor error:&error];
43+
if (!result) {
44+
fprintf(stderr, "FrameCaptureManager: start capture error: %s\n", error.localizedDescription.UTF8String);
45+
return;
46+
}
47+
48+
_is_capturing_frame = true;
4549
}
46-
47-
_is_capturing_frame = true;
4850
}
4951

5052
void StopCapture() {
@@ -59,7 +61,6 @@ void StopCapture() {
5961
_is_capturing_frame = false;
6062

6163
[_path release];
62-
_path = nil;
6364
}
6465

6566
private:

Source/Render/sokol/SokolRender.cpp

+30-27
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <array>
12
#include <unordered_set>
23
#include "StdAfxRD.h"
34
#include "xmath.h"
@@ -82,11 +83,10 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
8283
desc.logger.func = slog_func;
8384

8485
//Setup swapchain and fill color
85-
render_targets.emplace_back();
86-
auto& swapchain_pass = render_targets[0].render_pass;
87-
swapchain_pass.swapchain.width = ScreenSize.x;
88-
swapchain_pass.swapchain.height = ScreenSize.y;
89-
swapchain_pass.swapchain.sample_count = 1;
86+
swapchain = {};
87+
swapchain.width = ScreenSize.x;
88+
swapchain.height = ScreenSize.y;
89+
swapchain.sample_count = 1;
9090
fill_color = sg_color { 0.0f, 0.0f, 0.0f, 1.0f };
9191

9292
//OpenGL / OpenGLES
@@ -131,8 +131,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
131131
}
132132
printf("GPU vendor: %s, renderer: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDER));
133133

134-
auto& swapchain_pass = render_targets[0].render_pass;
135-
swapchain_pass.swapchain.gl.framebuffer = 0;
134+
swapchain.gl.framebuffer = 0;
136135
#endif //PERIMETER_SOKOL_GL
137136

138137
//Direct3D
@@ -215,8 +214,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
215214
dxgiAdapter->Release();
216215

217216
//Create swap chain
218-
auto& swapchain_pass = render_targets[0].render_pass;
219-
uint32_t sample_count = swapchain_pass.swapchain.sample_count;
217+
uint32_t sample_count = swapchain.sample_count;
220218
DXGI_SWAP_CHAIN_DESC* swap_chain_desc = &d3d_context->swap_chain_desc;
221219
memset(&d3d_context->swap_chain_desc, 0, sizeof(DXGI_SWAP_CHAIN_DESC));
222220
swap_chain_desc->BufferDesc.Width = static_cast<uint32_t>(xScr);
@@ -253,7 +251,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
253251
SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "metal", SDL_HINT_OVERRIDE);
254252

255253
//Setup metal sokol context
256-
sokol_metal_setup(sdl_window, &desc, &swapchain_pass.swapchain, ScreenHZ);
254+
sokol_metal_setup(sdl_window, &desc, &swapchain, ScreenHZ);
257255
#endif
258256

259257
const char* render_driver = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
@@ -334,9 +332,8 @@ bool cSokolRender::ChangeSize(int xScr, int yScr, int mode) {
334332
#endif
335333

336334
//Update swapchain
337-
auto& swapchain_pass = render_targets[0].render_pass;
338-
swapchain_pass.swapchain.width = ScreenSize.x;
339-
swapchain_pass.swapchain.height = ScreenSize.y;
335+
swapchain.width = ScreenSize.x;
336+
swapchain.height = ScreenSize.y;
340337

341338
#ifdef SOKOL_D3D11
342339
if (d3d_context->swap_chain && need_resize) {
@@ -391,10 +388,9 @@ int cSokolRender::Done() {
391388
}
392389
#endif
393390
#ifdef SOKOL_METAL
394-
auto& swapchain_pass = render_targets[0].render_pass;
395-
if (swapchain_pass.swapchain.metal.current_drawable != nullptr) {
391+
if (swapchain.metal.current_drawable != nullptr) {
396392
RenderSubmitEvent(RenderEvent::DONE, "Sokol Metal shutdown");
397-
sokol_metal_destroy(&swapchain_pass.swapchain);
393+
sokol_metal_destroy(&swapchain);
398394
}
399395
#endif
400396
#ifdef PERIMETER_SOKOL_GL
@@ -461,8 +457,8 @@ void cSokolRender::ClearPooledResources(uint32_t max_life) {
461457

462458
void cSokolRender::ClearCommands() {
463459
std::unordered_set<SokolResourceBuffer*> pooled;
464-
for (auto& render_target : render_targets) {
465-
for (SokolCommand* command : render_target.commands) {
460+
auto ClearCommands = [&pooled, this](std::vector<SokolCommand*>& commands) {
461+
for (SokolCommand* command : commands) {
466462
//Reclaim resources that can be reused
467463
SokolResourceBuffer* vertex_buffer = command->vertex_buffer;
468464
if (vertex_buffer && vertex_buffer->key != SokolResourceKeyNone && pooled.count(vertex_buffer) == 0) {
@@ -487,9 +483,18 @@ void cSokolRender::ClearCommands() {
487483

488484
delete command;
489485
}
490-
render_target.commands.clear();
486+
};
487+
488+
for (auto& target : std::array<SokolRenderTarget*, 2>{shadowMapRenderTarget, lightMapRenderTarget}) {
489+
if (target != nullptr) {
490+
ClearCommands(target->commands);
491+
target->commands.clear();
492+
}
491493
}
492494

495+
ClearCommands(commands);
496+
commands.clear();
497+
493498
#ifdef PERIMETER_DEBUG
494499
//printf("%ld %ld\n", reclaimed.size(), bufferPool.size());
495500
#endif
@@ -593,17 +598,15 @@ void cSokolRender::d3d_CreateDefaultRenderTarget() {
593598
assert(SUCCEEDED(hr) && d3d_context->depth_stencil_view);
594599

595600
//Apply into swapchain pass
596-
auto& swapchain_pass = render_targets[0].render_pass;
597-
swapchain_pass.swapchain.d3d11.render_view = 1 < sample_count ? d3d_context->msaa_view : d3d_context->render_target_view;
598-
swapchain_pass.swapchain.d3d11.resolve_view = 1 < sample_count ? d3d_context->render_target_view : nullptr;
599-
swapchain_pass.swapchain.d3d11.depth_stencil_view = d3d_context->depth_stencil_view;
601+
swapchain.d3d11.render_view = 1 < sample_count ? d3d_context->msaa_view : d3d_context->render_target_view;
602+
swapchain.d3d11.resolve_view = 1 < sample_count ? d3d_context->render_target_view : nullptr;
603+
swapchain.d3d11.depth_stencil_view = d3d_context->depth_stencil_view;
600604
}
601605

602606
void cSokolRender::d3d_DestroyDefaultRenderTarget() {
603-
auto& swapchain_pass = render_targets[0].render_pass;
604-
swapchain_pass.swapchain.d3d11.render_view = nullptr;
605-
swapchain_pass.swapchain.d3d11.resolve_view = nullptr;
606-
swapchain_pass.swapchain.d3d11.depth_stencil_view = nullptr;
607+
swapchain.d3d11.render_view = nullptr;
608+
swapchain.d3d11.resolve_view = nullptr;
609+
swapchain.d3d11.depth_stencil_view = nullptr;
607610
RELEASE(d3d_context->render_target_texture);
608611
RELEASE(d3d_context->render_target_view);
609612
RELEASE(d3d_context->depth_stencil_texture);

Source/Render/sokol/SokolRender.h

+22-17
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,23 @@ struct SokolCommand {
4141
Vect2i clip[2]; //0 Pos 1 Size
4242
};
4343

44+
struct SokolRenderTarget final {
45+
cTexture* texture = nullptr;
46+
sg_pass render_pass{};
47+
std::vector<SokolCommand*> commands;
48+
49+
~SokolRenderTarget() {
50+
RELEASE(texture);
51+
}
52+
};
53+
4454
struct SokolPipelineContext {
4555
PIPELINE_TYPE pipeline_type;
4656
PIPELINE_MODE pipeline_mode;
4757
ePrimitiveType primitive_type;
4858
vertex_fmt_t vertex_fmt;
4959
sg_pipeline_desc desc{};
50-
struct shader_funcs* shader_funcs;
60+
struct shader_funcs* shader_funcs = nullptr;
5161

5262
bool operator==(const SokolPipelineContext& other) const {
5363
return std::tie(pipeline_type, pipeline_mode, primitive_type, vertex_fmt)
@@ -84,36 +94,31 @@ class cSokolRender: public cInterfaceRenderDevice {
8494
friend const void* sokol_d3d_render_target_view_cb();
8595
friend const void* sokol_d3d_depth_stencil_view_cb();
8696
#endif
87-
88-
cTexture* pShadowMap = nullptr;
89-
cTexture* pLightMap = nullptr;
90-
bool use_shadow = false;
91-
cCamera* pShadow = nullptr;
92-
float kShadow = 0.25f;
93-
97+
9498
//Stores resources for reusing
9599
void ClearPooledResources(uint32_t max_life);
96100
std::unordered_multimap<uint64_t, SokolResourcePooled<sg_buffer>> bufferPool;
97101

102+
//For swapchain pass that renders into final device
103+
sg_swapchain swapchain = {};
98104
sg_color fill_color = {};
99-
105+
100106
//Renderer state
101107
bool ActiveScene = false;
102108
bool isOrthographicProjSet = false;
109+
std::vector<SokolCommand*> commands;
103110
sg_sampler sampler;
104111
sg_sampler shadow_sampler;
105112

106113
#ifdef PERIMETER_DEBUG
107114
bool is_capturing_frame = false;
108115
#endif
109116

110-
struct RenderTarget final {
111-
cTexture* target_texture = nullptr;
112-
SokolTexture2D* depth_image = nullptr;
113-
sg_pass render_pass{};
114-
std::vector<SokolCommand*> commands;
115-
};
116-
std::vector<RenderTarget> render_targets;
117+
SokolRenderTarget* shadowMapRenderTarget = nullptr;
118+
SokolRenderTarget* lightMapRenderTarget = nullptr;
119+
bool use_shadow = false;
120+
cCamera* pShadow = nullptr;
121+
float kShadow = 0.25f;
117122

118123
//Empty texture when texture slot is unused
119124
SokolTexture2D* emptyTexture = nullptr;
@@ -150,7 +155,7 @@ class cSokolRender: public cInterfaceRenderDevice {
150155
Mat4f activeTextureTransform[PERIMETER_SOKOL_TEXTURES];
151156

152157
//Shadow and Light map rendering
153-
size_t activeRenderTarget = 0;
158+
SokolRenderTarget* activeRenderTarget = nullptr;
154159
Mat4f activeShadowMatrix{};
155160
Vect2f activeWorldSize{};
156161

Source/Render/sokol/SokolRenderDraw.cpp

+37-10
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ void cSokolRender::DrawNoMaterialShadow(cObjMesh* mesh) {
226226
}
227227

228228
void cSokolRender::SetMaterialTilemap(cTileMap *TileMap) {
229+
auto pShadowMap = shadowMapRenderTarget->texture;
230+
auto pLightMap = lightMapRenderTarget->texture;
231+
229232
float fOffsetX = 0.5f + (0.0f / pShadowMap->GetWidth());
230233
float fOffsetY = 0.5f + (0.0f / pShadowMap->GetWidth());
231234
float range = 1;
@@ -279,32 +282,56 @@ bool cSokolRender::CreateShadowTexture(int xysize) {
279282
texture->dirty = false;
280283
};
281284

282-
pShadowMap=GetTexLibrary()->CreateRenderTexture(xysize, xysize, TEXTURE_RENDER16, false);
283-
if (!pShadowMap) {
285+
shadowMapRenderTarget = new SokolRenderTarget{};
286+
shadowMapRenderTarget->texture = GetTexLibrary()->CreateRenderTexture(xysize, xysize, TEXTURE_RENDER16, false);
287+
if (!shadowMapRenderTarget->texture) {
284288
DeleteShadowTexture();
285289
return false;
286290
}
287-
SetupTexture(pShadowMap->GetFrameImage(0)->sg, SG_PIXELFORMAT_DEPTH);
291+
SetupTexture(shadowMapRenderTarget->texture->GetFrameImage(0)->sg, SG_PIXELFORMAT_DEPTH);
292+
293+
{
294+
auto& render_pass = shadowMapRenderTarget->render_pass;
295+
render_pass.action.depth.load_action = SG_LOADACTION_CLEAR;
296+
render_pass.action.depth.store_action = SG_STOREACTION_STORE;
297+
render_pass.action.depth.clear_value = 1.0f;
298+
299+
sg_attachments_desc description{};
300+
description.depth_stencil.image = shadowMapRenderTarget->texture->GetFrameImage(0)->sg->image->res;
301+
render_pass.attachments = sg_make_attachments(&description);
302+
}
288303

289-
pLightMap = GetTexLibrary()->CreateRenderTexture(256, 256, TEXTURE_RENDER32, false);
290-
if (!pLightMap) {
304+
lightMapRenderTarget = new SokolRenderTarget{};
305+
lightMapRenderTarget->texture = GetTexLibrary()->CreateRenderTexture(256, 256, TEXTURE_RENDER32, false);
306+
if (!lightMapRenderTarget->texture) {
291307
DeleteShadowTexture();
292308
return false;
293309
}
294-
SetupTexture(pLightMap->GetFrameImage(0)->sg, SG_PIXELFORMAT_BGRA8);
310+
SetupTexture(lightMapRenderTarget->texture->GetFrameImage(0)->sg, SG_PIXELFORMAT_BGRA8);
311+
312+
{
313+
auto& render_pass = lightMapRenderTarget->render_pass;
314+
render_pass.action.colors[0].load_action = SG_LOADACTION_CLEAR;
315+
render_pass.action.colors[0].store_action = SG_STOREACTION_STORE;
316+
render_pass.action.colors[0].clear_value = { 1.0f, 1.0f, 1.0f, 1.0f};
317+
318+
sg_attachments_desc description{};
319+
description.colors[0].image = lightMapRenderTarget->texture->GetFrameImage(0)->sg->image->res;
320+
render_pass.attachments = sg_make_attachments(&description);
321+
}
295322

296323
return true;
297324
}
298325

299326
void cSokolRender::DeleteShadowTexture() {
300-
RELEASE(pShadowMap);
301-
RELEASE(pLightMap);
327+
delete shadowMapRenderTarget;
328+
delete lightMapRenderTarget;
302329
}
303330

304331
cTexture* cSokolRender::GetShadowMap() {
305-
return pShadowMap;
332+
return shadowMapRenderTarget != nullptr ? shadowMapRenderTarget->texture : nullptr;
306333
}
307334

308335
cTexture* cSokolRender::GetLightMap() {
309-
return pLightMap;
336+
return lightMapRenderTarget != nullptr ? lightMapRenderTarget->texture : nullptr;
310337
}

0 commit comments

Comments
 (0)