shithub: zelda3

Download patch

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);