ref: 393e572945ba9f2c011d97d70292776d2207804e
parent: 95659d2f40f893b0709bc7704fdb4cb02d10b177
author: Snesrev <[email protected]>
date: Tue Oct 11 13:33:47 EDT 2022
Improve render perf by not locking the whole texture
--- a/main.c
+++ b/main.c
@@ -123,13 +123,12 @@
(SDL_GetModState() & KMOD_CTRL) != 0 ? SDL_HITTEST_DRAGGABLE : SDL_HITTEST_NORMAL;
}
-static bool RenderScreenWithPerf(uint8 *pixel_buffer, size_t pitch, uint32 render_flags) {
- bool rv;
+static void RenderScreenWithPerf(uint8 *pixel_buffer, size_t pitch, uint32 render_flags) {
if (g_display_perf || g_config.display_perf_title) {
static float history[64], average;
static int history_pos;
uint64 before = SDL_GetPerformanceCounter();
- rv = ZeldaDrawPpuFrame(pixel_buffer, pitch, render_flags);
+ ZeldaDrawPpuFrame(pixel_buffer, pitch, render_flags);
uint64 after = SDL_GetPerformanceCounter();
float v = (double)SDL_GetPerformanceFrequency() / (after - before);
average += v - history[history_pos];
@@ -137,9 +136,8 @@
history_pos = (history_pos + 1) & 63;
g_curr_fps = average * (1.0f / 64);
} else {
- rv = ZeldaDrawPpuFrame(pixel_buffer, pitch, render_flags);
+ ZeldaDrawPpuFrame(pixel_buffer, pitch, render_flags);
}
- return rv;
}
// Go some steps up and find zelda3.ini
@@ -481,30 +479,27 @@
}
static void RenderScreen(SDL_Window *window, SDL_Renderer *renderer, SDL_Texture *texture, bool fullscreen) {
- uint8* pixels = NULL;
+ uint8 *pixels = 0;
int pitch = 0;
+ int render_scale = PpuGetCurrentRenderScale(g_zenv.ppu, g_ppu_render_flags);
+ SDL_Rect src_rect = { 0, 0, g_snes_width * render_scale >> 1, g_snes_height * render_scale >> 1};
+
uint64 t0 = SDL_GetPerformanceCounter();
- if(SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch) != 0) {
+ if(SDL_LockTexture(texture, &src_rect, (void**)&pixels, &pitch) != 0) {
printf("Failed to lock texture: %s\n", SDL_GetError());
return;
}
uint64 t1 = SDL_GetPerformanceCounter();
- bool hq = RenderScreenWithPerf(pixels, pitch, g_ppu_render_flags);
+ RenderScreenWithPerf(pixels, pitch, g_ppu_render_flags);
if (g_display_perf) {
- RenderNumber(pixels + (pitch * 2 << hq), pitch, g_curr_fps, hq);
+ RenderNumber(pixels + pitch * render_scale, pitch, g_curr_fps, render_scale == 4);
}
- if (g_config.display_perf_title) {
- char title[60];
- snprintf(title, sizeof(title), "%s | FPS: %d", kWindowTitle, g_curr_fps);
- SDL_SetWindowTitle(window, title);
- }
uint64 t2 = SDL_GetPerformanceCounter();
SDL_UnlockTexture(texture);
uint64 t3 = SDL_GetPerformanceCounter();
SDL_RenderClear(renderer);
uint64 t4 = SDL_GetPerformanceCounter();
- SDL_Rect src_rect = { 0, 0, g_snes_width, g_snes_height };
- SDL_RenderCopy(renderer, texture, hq ? NULL : &src_rect, NULL);
+ SDL_RenderCopy(renderer, texture, &src_rect, NULL);
uint64 t5 = SDL_GetPerformanceCounter();
double f = 1e3 / (double)SDL_GetPerformanceFrequency();
@@ -516,7 +511,11 @@
(t5 - t4) * f
);
-
+ if (g_config.display_perf_title) {
+ char title[60];
+ snprintf(title, sizeof(title), "%s | FPS: %d", kWindowTitle, g_curr_fps);
+ SDL_SetWindowTitle(window, title);
+ }
}
static void HandleCommand_Locked(uint32 j, bool pressed);
--- a/snes/ppu.c
+++ b/snes/ppu.c
@@ -122,10 +122,14 @@
func(ctx, tmp, 123);
}
-bool PpuBeginDrawing(Ppu *ppu, uint8_t *pixels, size_t pitch, uint32_t render_flags) {
+int PpuGetCurrentRenderScale(Ppu *ppu, uint32_t render_flags) {
+ bool hq = ppu->mode == 7 && !ppu->forcedBlank &&
+ (ppu->renderFlags & (kPpuRenderFlags_4x4Mode7 | kPpuRenderFlags_NewRenderer)) == (kPpuRenderFlags_4x4Mode7 | kPpuRenderFlags_NewRenderer);
+ return hq ? 4 : 2;
+}
+
+void PpuBeginDrawing(Ppu *ppu, uint8_t *pixels, size_t pitch, uint32_t render_flags) {
ppu->renderFlags = render_flags;
- bool hq = ppu->mode == 7 && !ppu->forcedBlank &&
- (ppu->renderFlags & (kPpuRenderFlags_4x4Mode7 | kPpuRenderFlags_NewRenderer)) == (kPpuRenderFlags_4x4Mode7 | kPpuRenderFlags_NewRenderer);
ppu->renderPitch = (uint)pitch;
ppu->renderBuffer = pixels;
@@ -140,14 +144,12 @@
memset(&ppu->brightnessMult[32], ppu->brightnessMult[31], 31);
}
- if (hq) {
+ if (PpuGetCurrentRenderScale(ppu, ppu->renderFlags) == 4) {
for (int i = 0; i < 256; i++) {
uint32 color = ppu->cgram[i];
ppu->colorMapRgb[i] = ppu->brightnessMult[color & 0x1f] << 16 | ppu->brightnessMult[(color >> 5) & 0x1f] << 8 | ppu->brightnessMult[(color >> 10) & 0x1f];
}
}
-
- return hq;
}
static inline void ClearBackdrop(PpuPixelPrioBufs *buf) {
--- a/snes/ppu.h
+++ b/snes/ppu.h
@@ -135,7 +135,10 @@
uint8_t ppu_read(Ppu* ppu, uint8_t adr);
void ppu_write(Ppu* ppu, uint8_t adr, uint8_t val);
void ppu_saveload(Ppu *ppu, SaveLoadFunc *func, void *ctx);
-bool PpuBeginDrawing(Ppu *ppu, uint8_t *buffer, size_t pitch, uint32_t render_flags);
+void PpuBeginDrawing(Ppu *ppu, uint8_t *buffer, size_t pitch, uint32_t render_flags);
+
+// Returns the current render scale, 1x = 256px, 2x=512px, 4x=1024px
+int PpuGetCurrentRenderScale(Ppu *ppu, uint32_t render_flags);
void PpuSetMode7PerspectiveCorrection(Ppu *ppu, int low, int high);
void PpuSetExtraSideSpace(Ppu *ppu, int left, int right, int bottom);
--- a/zelda_rtl.c
+++ b/zelda_rtl.c
@@ -215,10 +215,10 @@
PpuSetExtraSideSpace(g_zenv.ppu, extra_left, extra_right, extra_bottom);
}
-bool ZeldaDrawPpuFrame(uint8 *pixel_buffer, size_t pitch, uint32 render_flags) {
+void ZeldaDrawPpuFrame(uint8 *pixel_buffer, size_t pitch, uint32 render_flags) {
SimpleHdma hdma_chans[2];
- bool rv = PpuBeginDrawing(g_zenv.ppu, pixel_buffer, pitch, render_flags);
+ PpuBeginDrawing(g_zenv.ppu, pixel_buffer, pitch, render_flags);
dma_startDma(g_zenv.dma, HDMAEN_copy, true);
@@ -257,8 +257,6 @@
SimpleHdma_DoLine(&hdma_chans[0]);
SimpleHdma_DoLine(&hdma_chans[1]);
}
-
- return rv;
}
void HdmaSetup(uint32 addr6, uint32 addr7, uint8 transfer_unit, uint8 reg6, uint8 reg7, uint8 indirect_bank) {
--- a/zelda_rtl.h
+++ b/zelda_rtl.h
@@ -42,7 +42,7 @@
void ZeldaInitialize();
void ZeldaReset(bool preserve_sram);
-bool ZeldaDrawPpuFrame(uint8 *pixel_buffer, size_t pitch, uint32 render_flags);
+void ZeldaDrawPpuFrame(uint8 *pixel_buffer, size_t pitch, uint32 render_flags);
void ZeldaRunFrameInternal(uint16 input, int run_what);
bool ZeldaRunFrame(int input_state);
void LoadSongBank(const uint8 *p);