mirror of
https://github.com/libretro/beetle-psx-libretro.git
synced 2024-11-24 01:09:51 +00:00
Merge pull request #551 from ggdrt/gl-height-pad
Implement framebuffer height padding for GL renderer
This commit is contained in:
commit
a82b3a71f6
@ -541,9 +541,17 @@ static void UpdateDisplayMode(void)
|
|||||||
|
|
||||||
uint16_t yres = GPU.VertEnd - GPU.VertStart;
|
uint16_t yres = GPU.VertEnd - GPU.VertStart;
|
||||||
|
|
||||||
|
bool is_pal_mode = false;
|
||||||
|
if((GPU.DisplayMode & DISP_PAL) == DISP_PAL)
|
||||||
|
is_pal_mode = true;
|
||||||
|
|
||||||
// Both 2nd bit and 5th bit have to be enabled to use interlacing properly.
|
// Both 2nd bit and 5th bit have to be enabled to use interlacing properly.
|
||||||
|
bool is_480i_mode = false;
|
||||||
if((GPU.DisplayMode & (DISP_INTERLACED | DISP_VERT480)) == (DISP_INTERLACED | DISP_VERT480))
|
if((GPU.DisplayMode & (DISP_INTERLACED | DISP_VERT480)) == (DISP_INTERLACED | DISP_VERT480))
|
||||||
|
{
|
||||||
yres *= 2;
|
yres *= 2;
|
||||||
|
is_480i_mode = true;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned pixelclock_divider;
|
unsigned pixelclock_divider;
|
||||||
|
|
||||||
@ -588,7 +596,9 @@ static void UpdateDisplayMode(void)
|
|||||||
GPU.DisplayFB_XStart,
|
GPU.DisplayFB_XStart,
|
||||||
GPU.DisplayFB_YStart,
|
GPU.DisplayFB_YStart,
|
||||||
xres, yres,
|
xres, yres,
|
||||||
depth_24bpp);
|
depth_24bpp,
|
||||||
|
is_pal_mode,
|
||||||
|
is_480i_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forward decls */
|
/* Forward decls */
|
||||||
@ -1112,6 +1122,7 @@ void GPU_Write(const int32_t timestamp, uint32_t A, uint32_t V)
|
|||||||
GPU_SoftReset();
|
GPU_SoftReset();
|
||||||
rsx_intf_set_draw_area(GPU.ClipX0, GPU.ClipY0,
|
rsx_intf_set_draw_area(GPU.ClipX0, GPU.ClipY0,
|
||||||
GPU.ClipX1, GPU.ClipY1);
|
GPU.ClipX1, GPU.ClipY1);
|
||||||
|
rsx_intf_set_display_range(GPU.VertStart, GPU.VertEnd); //0x10, 0x100 set by GPU_SoftReset()
|
||||||
UpdateDisplayMode();
|
UpdateDisplayMode();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1150,6 +1161,7 @@ void GPU_Write(const int32_t timestamp, uint32_t A, uint32_t V)
|
|||||||
case 0x07:
|
case 0x07:
|
||||||
GPU.VertStart = V & 0x3FF;
|
GPU.VertStart = V & 0x3FF;
|
||||||
GPU.VertEnd = (V >> 10) & 0x3FF;
|
GPU.VertEnd = (V >> 10) & 0x3FF;
|
||||||
|
rsx_intf_set_display_range(GPU.VertStart, GPU.VertEnd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08:
|
case 0x08:
|
||||||
@ -1854,6 +1866,8 @@ void GPU_RestoreStateP3(void)
|
|||||||
1024, 512,
|
1024, 512,
|
||||||
GPU.vram, false, false);
|
GPU.vram, false, false);
|
||||||
|
|
||||||
|
rsx_intf_set_display_range(GPU.VertStart, GPU.VertEnd);
|
||||||
|
|
||||||
UpdateDisplayMode();
|
UpdateDisplayMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,15 @@ void rsx_dump_set_draw_area(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
|
|||||||
write_u32(y1);
|
write_u32(y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rsx_dump_set_display_mode(uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool depth_24bpp)
|
void rsx_dump_set_display_range(uint16_t y1, uint16_t y2)
|
||||||
|
{
|
||||||
|
if (!file)
|
||||||
|
return;
|
||||||
|
write_u32(y1);
|
||||||
|
write_u32(y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rsx_dump_set_display_mode(uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool depth_24bpp, bool is_pal, bool is_480i)
|
||||||
{
|
{
|
||||||
if (!file)
|
if (!file)
|
||||||
return;
|
return;
|
||||||
@ -140,6 +148,8 @@ void rsx_dump_set_display_mode(uint16_t x, uint16_t y, uint16_t w, uint16_t h, b
|
|||||||
write_u32(w);
|
write_u32(w);
|
||||||
write_u32(h);
|
write_u32(h);
|
||||||
write_u32(depth_24bpp);
|
write_u32(depth_24bpp);
|
||||||
|
write_u32(is_pal);
|
||||||
|
write_u32(is_480i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rsx_dump_triangle(const struct rsx_dump_vertex *vertices, const struct rsx_render_state *state)
|
void rsx_dump_triangle(const struct rsx_dump_vertex *vertices, const struct rsx_render_state *state)
|
||||||
|
@ -16,7 +16,8 @@ void rsx_dump_finalize_frame(void);
|
|||||||
void rsx_dump_set_tex_window(uint8_t tww, uint8_t twh, uint8_t twx, uint8_t twy);
|
void rsx_dump_set_tex_window(uint8_t tww, uint8_t twh, uint8_t twx, uint8_t twy);
|
||||||
void rsx_dump_set_draw_offset(int16_t x, int16_t y);
|
void rsx_dump_set_draw_offset(int16_t x, int16_t y);
|
||||||
void rsx_dump_set_draw_area(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
void rsx_dump_set_draw_area(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
||||||
void rsx_dump_set_display_mode(uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool depth_24bpp);
|
void rsx_dump_set_display_range(uint16_t y1, uint16_t y2);
|
||||||
|
void rsx_dump_set_display_mode(uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool depth_24bpp, bool is_pal, bool is_480i);
|
||||||
|
|
||||||
struct rsx_dump_vertex
|
struct rsx_dump_vertex
|
||||||
{
|
{
|
||||||
|
@ -224,6 +224,9 @@ struct DrawConfig
|
|||||||
int16_t draw_offset[2];
|
int16_t draw_offset[2];
|
||||||
uint16_t draw_area_top_left[2];
|
uint16_t draw_area_top_left[2];
|
||||||
uint16_t draw_area_bot_right[2];
|
uint16_t draw_area_bot_right[2];
|
||||||
|
uint16_t display_area_yrange[2];
|
||||||
|
bool is_pal;
|
||||||
|
bool is_480i;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Texture
|
struct Texture
|
||||||
@ -344,6 +347,9 @@ static DrawConfig persistent_config = {
|
|||||||
{0, 0}, /* draw_area_top_left */
|
{0, 0}, /* draw_area_top_left */
|
||||||
{0, 0}, /* draw_area_dimensions */
|
{0, 0}, /* draw_area_dimensions */
|
||||||
{0, 0}, /* draw_offset */
|
{0, 0}, /* draw_offset */
|
||||||
|
{0x10, 0x100}, /* display_area_yrange (hardware reset values)*/
|
||||||
|
false, /* is_pal */
|
||||||
|
false, /* is_480i */
|
||||||
};
|
};
|
||||||
|
|
||||||
static RetroGl static_renderer;
|
static RetroGl static_renderer;
|
||||||
@ -1457,6 +1463,11 @@ static void bind_libretro_framebuffer(GlRenderer *renderer)
|
|||||||
float aspect_ratio = widescreen_hack ? 16.0 / 9.0 :
|
float aspect_ratio = widescreen_hack ? 16.0 / 9.0 :
|
||||||
MEDNAFEN_CORE_GEOMETRY_ASPECT_RATIO;
|
MEDNAFEN_CORE_GEOMETRY_ASPECT_RATIO;
|
||||||
|
|
||||||
|
/* Padding vars */
|
||||||
|
uint32_t unpadded_h;
|
||||||
|
uint32_t top_pad = 0;
|
||||||
|
uint32_t bottom_pad = 0;
|
||||||
|
|
||||||
if (renderer->display_vram)
|
if (renderer->display_vram)
|
||||||
{
|
{
|
||||||
_w = VRAM_WIDTH_PIXELS;
|
_w = VRAM_WIDTH_PIXELS;
|
||||||
@ -1464,10 +1475,42 @@ static void bind_libretro_framebuffer(GlRenderer *renderer)
|
|||||||
/* Is this accurate? */
|
/* Is this accurate? */
|
||||||
aspect_ratio = 2.0 / 1.0;
|
aspect_ratio = 2.0 / 1.0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Height padding for non-standard framebuffer heights
|
||||||
|
*
|
||||||
|
* We check the config.is_pal set by UpdateDisplayMode
|
||||||
|
* instead of querying content_is_pal since config.is_pal
|
||||||
|
* is a runtime GPU value while content_is_pal is only set
|
||||||
|
* at load time */
|
||||||
|
|
||||||
|
uint16_t first_line = renderer->config.is_pal ? 20 : 16;
|
||||||
|
uint16_t last_line = renderer->config.is_pal ? 308 : 256; //non-inclusive bound
|
||||||
|
|
||||||
|
if (renderer->config.display_area_yrange[0] > first_line) //check bounds
|
||||||
|
top_pad = (uint32_t) (renderer->config.display_area_yrange[0] - first_line);
|
||||||
|
if (renderer->config.display_area_yrange[1] < last_line)
|
||||||
|
bottom_pad = (uint32_t) (last_line - renderer->config.display_area_yrange[1]);
|
||||||
|
|
||||||
|
if (renderer->config.is_480i) //double padding if 480-line mode
|
||||||
|
{
|
||||||
|
top_pad *= 2;
|
||||||
|
bottom_pad *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
w = (uint32_t) _w * upscale;
|
w = (uint32_t) _w * upscale;
|
||||||
h = (uint32_t) _h * upscale;
|
h = (uint32_t) _h * upscale;
|
||||||
|
|
||||||
|
//printf("VertStart = %3u, VertEnd = %3u\n", renderer->config.display_area_yrange[0], renderer->config.display_area_yrange[1]);
|
||||||
|
//printf("_w = %3u, _h = %3u, top_pad = %3u, bottom_pad = %3u\n", _w, _h, top_pad, bottom_pad);
|
||||||
|
|
||||||
|
/* Scale pad heights up and add to scaled height */
|
||||||
|
unpadded_h = h;
|
||||||
|
top_pad *= upscale;
|
||||||
|
bottom_pad *= upscale;
|
||||||
|
h += (top_pad + bottom_pad);
|
||||||
|
|
||||||
if (w != f_w || h != f_h)
|
if (w != f_w || h != f_h)
|
||||||
{
|
{
|
||||||
/* We need to change the frontend's resolution */
|
/* We need to change the frontend's resolution */
|
||||||
@ -1490,7 +1533,7 @@ static void bind_libretro_framebuffer(GlRenderer *renderer)
|
|||||||
/* Bind the output framebuffer provided by the frontend */
|
/* Bind the output framebuffer provided by the frontend */
|
||||||
fbo = glsm_get_current_framebuffer();
|
fbo = glsm_get_current_framebuffer();
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||||
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
|
glViewport(0, (GLsizei) bottom_pad, (GLsizei) w, (GLsizei) unpadded_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool retro_refresh_variables(GlRenderer *renderer)
|
static bool retro_refresh_variables(GlRenderer *renderer)
|
||||||
@ -2145,6 +2188,12 @@ static void rsx_gl_finalize_frame(const void *fb, unsigned width,
|
|||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
/* Clear the screen no matter what: prevents possible leftover
|
||||||
|
pixels from previous frame when loading save state for any
|
||||||
|
games not using standard framebuffer heights */
|
||||||
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
/* If the display is off, just clear the screen */
|
/* If the display is off, just clear the screen */
|
||||||
if (renderer->config.display_off && !renderer->display_vram)
|
if (renderer->config.display_off && !renderer->display_vram)
|
||||||
{
|
{
|
||||||
@ -3733,12 +3782,44 @@ void rsx_intf_set_draw_area(uint16_t x0, uint16_t y0,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rsx_intf_set_display_mode(uint16_t x, uint16_t y,
|
void rsx_intf_set_display_range(uint16_t y1, uint16_t y2)
|
||||||
uint16_t w, uint16_t h,
|
|
||||||
bool depth_24bpp)
|
|
||||||
{
|
{
|
||||||
#ifdef RSX_DUMP
|
#ifdef RSX_DUMP
|
||||||
rsx_dump_set_display_mode(x, y, w, h, depth_24bpp);
|
rsx_dump_set_display_range(y1, y2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (rsx_type)
|
||||||
|
{
|
||||||
|
case RSX_SOFTWARE:
|
||||||
|
break;
|
||||||
|
case RSX_OPENGL:
|
||||||
|
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
|
||||||
|
{
|
||||||
|
GlRenderer *renderer = static_renderer.state_data;
|
||||||
|
if (static_renderer.state != GlState_Invalid
|
||||||
|
&& renderer)
|
||||||
|
{
|
||||||
|
renderer->config.display_area_yrange[0] = y1;
|
||||||
|
renderer->config.display_area_yrange[1] = y2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case RSX_VULKAN:
|
||||||
|
//implement me for Vulkan and set HAVE_VULKAN define check
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rsx_intf_set_display_mode(uint16_t x, uint16_t y,
|
||||||
|
uint16_t w, uint16_t h,
|
||||||
|
bool depth_24bpp,
|
||||||
|
bool is_pal,
|
||||||
|
bool is_480i)
|
||||||
|
{
|
||||||
|
#ifdef RSX_DUMP
|
||||||
|
rsx_dump_set_display_mode(x, y, w, h, depth_24bpp, is_pal, is_480i);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (rsx_type)
|
switch (rsx_type)
|
||||||
@ -3758,6 +3839,9 @@ void rsx_intf_set_display_mode(uint16_t x, uint16_t y,
|
|||||||
renderer->config.display_resolution[0] = w;
|
renderer->config.display_resolution[0] = w;
|
||||||
renderer->config.display_resolution[1] = h;
|
renderer->config.display_resolution[1] = h;
|
||||||
renderer->config.display_24bpp = depth_24bpp;
|
renderer->config.display_24bpp = depth_24bpp;
|
||||||
|
|
||||||
|
renderer->config.is_pal = is_pal;
|
||||||
|
renderer->config.is_480i = is_480i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,9 +45,12 @@ void rsx_intf_set_mask_setting(uint32_t mask_set_or, uint32_t mask_eval_and);
|
|||||||
void rsx_intf_set_draw_offset(int16_t x, int16_t y);
|
void rsx_intf_set_draw_offset(int16_t x, int16_t y);
|
||||||
void rsx_intf_set_draw_area(uint16_t x0, uint16_t y0,
|
void rsx_intf_set_draw_area(uint16_t x0, uint16_t y0,
|
||||||
uint16_t x1, uint16_t y1);
|
uint16_t x1, uint16_t y1);
|
||||||
|
void rsx_intf_set_display_range(uint16_t y1, uint16_t y2);
|
||||||
void rsx_intf_set_display_mode(uint16_t x, uint16_t y,
|
void rsx_intf_set_display_mode(uint16_t x, uint16_t y,
|
||||||
uint16_t w, uint16_t h,
|
uint16_t w, uint16_t h,
|
||||||
bool depth_24bpp);
|
bool depth_24bpp,
|
||||||
|
bool is_pal,
|
||||||
|
bool is_480i);
|
||||||
|
|
||||||
void rsx_intf_push_triangle(float p0x, float p0y, float p0w,
|
void rsx_intf_push_triangle(float p0x, float p0y, float p0w,
|
||||||
float p1x, float p1y, float p1w,
|
float p1x, float p1y, float p1w,
|
||||||
|
Loading…
Reference in New Issue
Block a user