Skip to content

Commit

Permalink
gpu_neon: rework buffering to reduce flickering
Browse files Browse the repository at this point in the history
... maybe

#324
  • Loading branch information
notaz committed Oct 23, 2023
1 parent f3746ee commit 2da2fc7
Show file tree
Hide file tree
Showing 17 changed files with 252 additions and 268 deletions.
7 changes: 7 additions & 0 deletions frontend/plat_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,13 @@ void plat_video_menu_end(void)

void plat_video_menu_leave(void)
{
void *fb = NULL;
if (plat_sdl_overlay != NULL || plat_sdl_gl_active)
fb = shadow_fb;
else if (plat_sdl_screen)
fb = plat_sdl_screen->pixels;
if (fb)
memset(fb, 0, g_menuscreen_w * g_menuscreen_h * 2);
in_menu = 0;
}

Expand Down
18 changes: 12 additions & 6 deletions frontend/plugin_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static __attribute__((noinline)) void draw_active_chans(int vout_w, int vout_h)

static const unsigned short colors[2] = { 0x1fe3, 0x0700 };
unsigned short *dest = (unsigned short *)pl_vout_buf +
vout_w * (vout_h - HUD_HEIGHT) + vout_w / 2 - 192/2;
pl_vout_w * (vout_h - HUD_HEIGHT) + pl_vout_w / 2 - 192/2;
unsigned short *d, p;
int c, x, y;

Expand All @@ -149,7 +149,7 @@ static __attribute__((noinline)) void draw_active_chans(int vout_w, int vout_h)
(fmod_chans & (1<<c)) ? 0xf000 :
(noise_chans & (1<<c)) ? 0x001f :
colors[c & 1];
for (y = 0; y < 8; y++, d += vout_w)
for (y = 0; y < 8; y++, d += pl_vout_w)
for (x = 0; x < 8; x++)
d[x] = p;
}
Expand Down Expand Up @@ -302,10 +302,16 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
menu_notify_mode_change(pl_vout_w, pl_vout_h, pl_vout_bpp);
}

static int flip_clear_counter;

void pl_force_clear(void)
{
flip_clear_counter = 2;
}

static void pl_vout_flip(const void *vram, int stride, int bgr24,
int x, int y, int w, int h, int dims_changed)
{
static int clear_counter;
unsigned char *dest = pl_vout_buf;
const unsigned short *src = vram;
int dstride = pl_vout_w, h1 = h;
Expand All @@ -332,15 +338,15 @@ static void pl_vout_flip(const void *vram, int stride, int bgr24,
doffs = xoffs + y * dstride;

if (dims_changed)
clear_counter = 2;
flip_clear_counter = 2;

if (clear_counter > 0) {
if (flip_clear_counter > 0) {
if (pl_plat_clear)
pl_plat_clear();
else
memset(pl_vout_buf, 0,
dstride * h_full * pl_vout_bpp / 8);
clear_counter--;
flip_clear_counter--;
}

if (pl_plat_blit)
Expand Down
1 change: 1 addition & 0 deletions frontend/plugin_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void pl_start_watchdog(void);
void *pl_prepare_screenshot(int *w, int *h, int *bpp);
void pl_init(void);
void pl_switch_dispmode(void);
void pl_force_clear(void);

void pl_timing_prepare(int is_pal);
void pl_frame_limit(void);
Expand Down
2 changes: 1 addition & 1 deletion plugins/dfxvideo/gpulib_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ void renderer_notify_res_change(void)
{
}

void renderer_notify_scanout_x_change(int x, int w)
void renderer_notify_scanout_change(int x, int y)
{
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/gpu-gles/gpulib_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ void renderer_notify_res_change(void)
{
}

void renderer_notify_scanout_x_change(int x, int w)
void renderer_notify_scanout_change(int x, int y)
{
}

Expand Down
5 changes: 5 additions & 0 deletions plugins/gpu_neon/psx_gpu/psx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>

Expand All @@ -23,6 +24,7 @@
#include "vector_ops.h"
#endif
#include "psx_gpu_simd.h"
#include "psx_gpu_offsets.h"

#if 0
void dump_r_d(const char *name, void *dump);
Expand Down Expand Up @@ -5012,6 +5014,9 @@ void initialize_psx_gpu(psx_gpu_struct *psx_gpu, u16 *vram)
psx_gpu->primitive_type = PRIMITIVE_TYPE_UNKNOWN;

psx_gpu->saved_hres = 256;

// check some offset
psx_gpu->reserved_a[(offsetof(psx_gpu_struct, blocks) == psx_gpu_blocks_offset) - 1] = 0;
}

u64 get_us(void)
Expand Down
16 changes: 8 additions & 8 deletions plugins/gpu_neon/psx_gpu/psx_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,15 @@ typedef struct
u32 triangle_color;
u32 dither_table[4];

u32 uvrgb_phase;

struct render_block_handler_struct *render_block_handler;
void *texture_page_ptr;
void *texture_page_base;
u16 *clut_ptr;
u16 *vram_ptr;
u16 *vram_out_ptr;

u32 uvrgb_phase;

u16 render_state_base;
u16 render_state;

Expand Down Expand Up @@ -194,15 +194,15 @@ typedef struct
s16 saved_viewport_start_y;
s16 saved_viewport_end_x;
s16 saved_viewport_end_y;
u8 enhancement_buf_by_x16[64]; // 0-3 specifying which buf
u16 enhancement_buf_start[4]; // x pos where buf[n] begins

u16 enhancement_scanout_x[4];
u16 enhancement_scanout_select;
struct psx_gpu_scanout {
u16 x, y, w, h;
} enhancement_scanouts[4]; // 0-3 specifying which buf to use
u16 enhancement_scanout_eselect; // eviction selector
u16 enhancement_current_buf;

// Align up to 64 byte boundary to keep the upcoming buffers cache line
// aligned, also make reachable with single immediate addition
u8 reserved_a[142];
u8 reserved_a[188 + 9*4 - 9*sizeof(void *)];

// 8KB
block_struct blocks[MAX_BLOCKS_PER_ROW];
Expand Down
22 changes: 10 additions & 12 deletions plugins/gpu_neon/psx_gpu/psx_gpu_4x.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
#define select_enhancement_buf_index(psx_gpu, x) \
((psx_gpu)->enhancement_buf_by_x16[(u32)(x) / \
(1024u / sizeof((psx_gpu)->enhancement_buf_by_x16))])

#define select_enhancement_buf_ptr(psx_gpu, x) \
((psx_gpu)->enhancement_buf_ptr + \
(select_enhancement_buf_index(psx_gpu, x) << 20))

#if !defined(NEON_BUILD) || defined(SIMD_BUILD)

#ifndef zip_4x32b
Expand Down Expand Up @@ -325,12 +317,12 @@ render_block_handler_struct render_sprite_block_handlers_4x[] =
render_sprite_blocks_switch_block_4x()
};


void render_sprite_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, u32 u, u32 v,
s32 width, s32 height, u32 flags, u32 color)
{
s32 x_right = x + width - 1;
s32 y_bottom = y + height - 1;
s16 end_x;

#ifdef PROFILE
sprites++;
Expand All @@ -352,16 +344,22 @@ void render_sprite_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, u32 u, u32 v,
height -= clip;
}

if(x_right > psx_gpu->viewport_end_x)
width -= x_right - psx_gpu->viewport_end_x;
end_x = psx_gpu->viewport_end_x;
if (end_x - psx_gpu->viewport_start_x + 1 > 512)
end_x = psx_gpu->viewport_start_x + 511;

if(x_right > end_x)
width -= x_right - end_x;

if(y_bottom > psx_gpu->viewport_end_y)
height -= y_bottom - psx_gpu->viewport_end_y;

if((width <= 0) || (height <= 0))
return;

psx_gpu->vram_out_ptr = select_enhancement_buf_ptr(psx_gpu, x);
if (!psx_gpu->enhancement_current_buf_ptr)
return;
psx_gpu->vram_out_ptr = psx_gpu->enhancement_current_buf_ptr;

x *= 2;
y *= 2;
Expand Down
31 changes: 6 additions & 25 deletions plugins/gpu_neon/psx_gpu/psx_gpu_offsets.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef __P_PSX_GPU_OFFSETS_H__
#define __P_PSX_GPU_OFFSETS_H__

#define psx_gpu_test_mask_offset 0x0
#define psx_gpu_uvrg_offset 0x10
#define psx_gpu_uvrg_dx_offset 0x20
#define psx_gpu_uvrg_dy_offset 0x30
Expand All @@ -13,23 +12,18 @@
#define psx_gpu_b_offset 0x90
#define psx_gpu_b_dy_offset 0x94
#define psx_gpu_triangle_area_offset 0x98
#define psx_gpu_texture_window_settings_offset 0x9c
#define psx_gpu_current_texture_mask_offset 0xa0
#define psx_gpu_viewport_mask_offset 0xa4
#define psx_gpu_dirty_textures_4bpp_mask_offset 0xa8
#define psx_gpu_dirty_textures_8bpp_mask_offset 0xac
#define psx_gpu_dirty_textures_8bpp_alternate_mask_offset 0xb0
#define psx_gpu_triangle_color_offset 0xb4
#define psx_gpu_dither_table_offset 0xb8
#define psx_gpu_uvrgb_phase_offset 0xc8
#define psx_gpu_render_block_handler_offset 0xcc
#define psx_gpu_texture_page_ptr_offset 0xd0
#define psx_gpu_texture_page_base_offset 0xd4
#define psx_gpu_clut_ptr_offset 0xd8
#define psx_gpu_vram_ptr_offset 0xdc
#define psx_gpu_vram_out_ptr_offset 0xe0
#define psx_gpu_render_state_base_offset 0xe4
#define psx_gpu_render_state_offset 0xe6
#define psx_gpu_texture_page_ptr_offset 0xcc
#define psx_gpu_texture_page_base_offset 0xd0
#define psx_gpu_clut_ptr_offset 0xd4
#define psx_gpu_vram_ptr_offset 0xd8
#define psx_gpu_vram_out_ptr_offset 0xdc
#define psx_gpu_uvrgb_phase_offset 0xe0
#define psx_gpu_num_spans_offset 0xe8
#define psx_gpu_num_blocks_offset 0xea
#define psx_gpu_viewport_start_x_offset 0xec
Expand All @@ -38,26 +32,13 @@
#define psx_gpu_viewport_end_y_offset 0xf2
#define psx_gpu_mask_msb_offset 0xf4
#define psx_gpu_triangle_winding_offset 0xf6
#define psx_gpu_display_area_draw_enable_offset 0xf7
#define psx_gpu_current_texture_page_offset 0xf8
#define psx_gpu_last_8bpp_texture_page_offset 0xf9
#define psx_gpu_texture_mask_width_offset 0xfa
#define psx_gpu_texture_mask_height_offset 0xfb
#define psx_gpu_texture_window_x_offset 0xfc
#define psx_gpu_texture_window_y_offset 0xfd
#define psx_gpu_primitive_type_offset 0xfe
#define psx_gpu_render_mode_offset 0xff
#define psx_gpu_offset_x_offset 0x100
#define psx_gpu_offset_y_offset 0x102
#define psx_gpu_clut_settings_offset 0x104
#define psx_gpu_texture_settings_offset 0x106
#define psx_gpu_reciprocal_table_ptr_offset 0x108
#define psx_gpu_blocks_offset 0x200
#define psx_gpu_span_uvrg_offset_offset 0x2200
#define psx_gpu_span_edge_data_offset 0x4200
#define psx_gpu_span_b_offset_offset 0x5200
#define psx_gpu_texture_4bpp_cache_offset 0x5a00
#define psx_gpu_texture_8bpp_even_cache_offset 0x205a00
#define psx_gpu_texture_8bpp_odd_cache_offset 0x305a00

#endif /* __P_PSX_GPU_OFFSETS_H__ */
46 changes: 25 additions & 21 deletions plugins/gpu_neon/psx_gpu/psx_gpu_offsets_update.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "common.h"

#define WRITE_OFFSET(f, member) \
fprintf(f, "#define %-50s0x%x\n", \
fprintf(f, "#define %-50s0x%zx\n", \
"psx_gpu_" #member "_offset", \
offsetof(psx_gpu_struct, member));

Expand All @@ -22,8 +22,10 @@ int main()
perror("fopen");
return 1;
}
fputs("#ifndef __P_PSX_GPU_OFFSETS_H__\n", f);
fputs("#define __P_PSX_GPU_OFFSETS_H__\n\n", f);

WRITE_OFFSET(f, test_mask);
//WRITE_OFFSET(f, test_mask);
WRITE_OFFSET(f, uvrg);
WRITE_OFFSET(f, uvrg_dx);
WRITE_OFFSET(f, uvrg_dy);
Expand All @@ -35,23 +37,23 @@ int main()
WRITE_OFFSET(f, b);
WRITE_OFFSET(f, b_dy);
WRITE_OFFSET(f, triangle_area);
WRITE_OFFSET(f, texture_window_settings);
//WRITE_OFFSET(f, texture_window_settings);
WRITE_OFFSET(f, current_texture_mask);
WRITE_OFFSET(f, viewport_mask);
//WRITE_OFFSET(f, viewport_mask);
WRITE_OFFSET(f, dirty_textures_4bpp_mask);
WRITE_OFFSET(f, dirty_textures_8bpp_mask);
WRITE_OFFSET(f, dirty_textures_8bpp_alternate_mask);
WRITE_OFFSET(f, triangle_color);
WRITE_OFFSET(f, dither_table);
WRITE_OFFSET(f, uvrgb_phase);
WRITE_OFFSET(f, render_block_handler);
//WRITE_OFFSET(f, render_block_handler);
WRITE_OFFSET(f, texture_page_ptr);
WRITE_OFFSET(f, texture_page_base);
WRITE_OFFSET(f, clut_ptr);
WRITE_OFFSET(f, vram_ptr);
WRITE_OFFSET(f, vram_out_ptr);
WRITE_OFFSET(f, render_state_base);
WRITE_OFFSET(f, render_state);
WRITE_OFFSET(f, uvrgb_phase);
//WRITE_OFFSET(f, render_state_base);
//WRITE_OFFSET(f, render_state);
WRITE_OFFSET(f, num_spans);
WRITE_OFFSET(f, num_blocks);
WRITE_OFFSET(f, viewport_start_x);
Expand All @@ -60,27 +62,29 @@ int main()
WRITE_OFFSET(f, viewport_end_y);
WRITE_OFFSET(f, mask_msb);
WRITE_OFFSET(f, triangle_winding);
WRITE_OFFSET(f, display_area_draw_enable);
//WRITE_OFFSET(f, display_area_draw_enable);
WRITE_OFFSET(f, current_texture_page);
WRITE_OFFSET(f, last_8bpp_texture_page);
//WRITE_OFFSET(f, last_8bpp_texture_page);
WRITE_OFFSET(f, texture_mask_width);
WRITE_OFFSET(f, texture_mask_height);
WRITE_OFFSET(f, texture_window_x);
WRITE_OFFSET(f, texture_window_y);
WRITE_OFFSET(f, primitive_type);
WRITE_OFFSET(f, render_mode);
WRITE_OFFSET(f, offset_x);
WRITE_OFFSET(f, offset_y);
WRITE_OFFSET(f, clut_settings);
WRITE_OFFSET(f, texture_settings);
//WRITE_OFFSET(f, texture_window_x);
//WRITE_OFFSET(f, texture_window_y);
//WRITE_OFFSET(f, primitive_type);
//WRITE_OFFSET(f, render_mode);
//WRITE_OFFSET(f, offset_x);
//WRITE_OFFSET(f, offset_y);
//WRITE_OFFSET(f, clut_settings);
//WRITE_OFFSET(f, texture_settings);
WRITE_OFFSET(f, reciprocal_table_ptr);
WRITE_OFFSET(f, blocks);
WRITE_OFFSET(f, span_uvrg_offset);
WRITE_OFFSET(f, span_edge_data);
WRITE_OFFSET(f, span_b_offset);
WRITE_OFFSET(f, texture_4bpp_cache);
WRITE_OFFSET(f, texture_8bpp_even_cache);
WRITE_OFFSET(f, texture_8bpp_odd_cache);
//WRITE_OFFSET(f, texture_4bpp_cache);
//WRITE_OFFSET(f, texture_8bpp_even_cache);
//WRITE_OFFSET(f, texture_8bpp_odd_cache);

fputs("\n#endif /* __P_PSX_GPU_OFFSETS_H__ */\n", f);
fclose(f);

return 0;
Expand Down
Loading

0 comments on commit 2da2fc7

Please sign in to comment.