Improve render perf by not locking the whole texture

This commit is contained in:
Snesrev
2022-10-11 17:33:47 +02:00
parent 95659d2f40
commit 393e572945
5 changed files with 31 additions and 29 deletions

33
main.c
View File

@@ -123,13 +123,12 @@ static SDL_HitTestResult HitTestCallback(SDL_Window *win, const SDL_Point *area,
(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 @@ static bool RenderScreenWithPerf(uint8 *pixel_buffer, size_t pitch, uint32 rende
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 RenderNumber(uint8 *dst, size_t pitch, int n, bool big) {
}
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);
}
if (g_config.display_perf_title) {
char title[60];
snprintf(title, sizeof(title), "%s | FPS: %d", kWindowTitle, g_curr_fps);
SDL_SetWindowTitle(window, title);
RenderNumber(pixels + pitch * render_scale, pitch, g_curr_fps, render_scale == 4);
}
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 @@ static void RenderScreen(SDL_Window *window, SDL_Renderer *renderer, SDL_Texture
(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);

View File

@@ -122,10 +122,14 @@ void ppu_saveload(Ppu *ppu, SaveLoadFunc *func, void *ctx) {
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 @@ bool PpuBeginDrawing(Ppu *ppu, uint8_t *pixels, size_t pitch, uint32_t render_fl
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) {

View File

@@ -135,7 +135,10 @@ void ppu_runLine(Ppu* ppu, int line);
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);

View File

@@ -215,10 +215,10 @@ static void ConfigurePpuSideSpace() {
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 @@ bool ZeldaDrawPpuFrame(uint8 *pixel_buffer, size_t pitch, uint32 render_flags) {
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) {

View File

@@ -42,7 +42,7 @@ void HdmaSetup(uint32 addr6, uint32 addr7, uint8 transfer_unit, uint8 reg6, uint
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);