mirror of
https://github.com/libretro/beetle-psx-libretro.git
synced 2024-11-27 02:40:31 +00:00
Merge branch 'master' into r5/sw-renderer-set-geometry
This commit is contained in:
commit
3dd62f96bb
219
libretro.cpp
219
libretro.cpp
@ -1550,6 +1550,7 @@ static void InitCommon(std::vector<CDIF *> *_CDInterfaces, const bool EmulateMem
|
||||
PSX_CPU = new PS_CPU();
|
||||
PSX_SPU = new PS_SPU();
|
||||
|
||||
/* check_variables() has been previously called, we can now use psx_gpu_upscale_shift */
|
||||
GPU_Init(content_is_pal, sls, sle, psx_gpu_upscale_shift);
|
||||
|
||||
PSX_CDC = new PS_CDC();
|
||||
@ -1571,7 +1572,7 @@ static void InitCommon(std::vector<CDIF *> *_CDInterfaces, const bool EmulateMem
|
||||
switch (psx_gpu_dither_mode)
|
||||
{
|
||||
case DITHER_NATIVE:
|
||||
GPU_set_dither_upscale_shift(psx_gpu_upscale_shift);
|
||||
GPU_set_dither_upscale_shift(GPU_get_upscale_shift());
|
||||
break;
|
||||
case DITHER_UPSCALED:
|
||||
GPU_set_dither_upscale_shift(0);
|
||||
@ -2651,13 +2652,11 @@ static bool old_cdimagecache = true;
|
||||
static bool old_cdimagecache = false;
|
||||
#endif
|
||||
|
||||
static bool boot = true;
|
||||
|
||||
// shared memory cards support
|
||||
static bool shared_memorycards = false;
|
||||
static bool shared_memorycards_toggle = false;
|
||||
|
||||
static void check_variables(bool startup)
|
||||
|
||||
static void check_variables(void)
|
||||
{
|
||||
struct retro_variable var = {0};
|
||||
|
||||
@ -2719,21 +2718,21 @@ static void check_variables(bool startup)
|
||||
var.key = BEETLE_OPT(gpu_overclock);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
unsigned val = atoi(var.value);
|
||||
|
||||
// Upscale must be a power of two
|
||||
assert((val & (val - 1)) == 0);
|
||||
|
||||
// Crappy "ffs" implementation since the standard function is not
|
||||
// widely supported by libc in the wild
|
||||
uint8_t n;
|
||||
for (n = 0; (val & 1) == 0; ++n)
|
||||
{
|
||||
unsigned val = atoi(var.value);
|
||||
|
||||
// Upscale must be a power of two
|
||||
assert((val & (val - 1)) == 0);
|
||||
|
||||
// Crappy "ffs" implementation since the standard function is not
|
||||
// widely supported by libc in the wild
|
||||
uint8_t n;
|
||||
for (n = 0; (val & 1) == 0; ++n)
|
||||
{
|
||||
val >>= 1;
|
||||
}
|
||||
psx_gpu_overclock_shift = n;
|
||||
val >>= 1;
|
||||
}
|
||||
psx_gpu_overclock_shift = n;
|
||||
}
|
||||
else
|
||||
psx_gpu_overclock_shift = 0;
|
||||
|
||||
@ -2789,74 +2788,7 @@ static void check_variables(bool startup)
|
||||
else
|
||||
input_enable_calibration( false );
|
||||
|
||||
if (startup)
|
||||
{
|
||||
var.key = BEETLE_OPT(renderer);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (!strcmp(var.value, "software"))
|
||||
{
|
||||
var.key = BEETLE_OPT(internal_resolution);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
uint8_t new_upscale_shift;
|
||||
uint8_t val = atoi(var.value);
|
||||
|
||||
// Upscale must be a power of two
|
||||
assert((val & (val - 1)) == 0);
|
||||
|
||||
// Crappy "ffs" implementation since the standard function is not
|
||||
// widely supported by libc in the wild
|
||||
for (new_upscale_shift = 0; (val & 1) == 0; ++new_upscale_shift)
|
||||
val >>= 1;
|
||||
psx_gpu_upscale_shift = new_upscale_shift;
|
||||
}
|
||||
else
|
||||
psx_gpu_upscale_shift = 0;
|
||||
}
|
||||
else
|
||||
psx_gpu_upscale_shift = 0;
|
||||
}
|
||||
else
|
||||
/* If 'BEETLE_OPT(renderer)' option is not found, then
|
||||
* we are running in software mode */
|
||||
psx_gpu_upscale_shift = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rsx_intf_refresh_variables();
|
||||
|
||||
switch (rsx_intf_is_type())
|
||||
{
|
||||
case RSX_SOFTWARE:
|
||||
var.key = BEETLE_OPT(internal_resolution);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
uint8_t new_upscale_shift;
|
||||
uint8_t val = atoi(var.value);
|
||||
|
||||
// Upscale must be a power of two
|
||||
assert((val & (val - 1)) == 0);
|
||||
|
||||
// Crappy "ffs" implementation since the standard function is not
|
||||
// widely supported by libc in the wild
|
||||
for (new_upscale_shift = 0; (val & 1) == 0; ++new_upscale_shift)
|
||||
val >>= 1;
|
||||
psx_gpu_upscale_shift = new_upscale_shift;
|
||||
}
|
||||
else
|
||||
psx_gpu_upscale_shift = 0;
|
||||
|
||||
break;
|
||||
case RSX_OPENGL:
|
||||
case RSX_VULKAN:
|
||||
psx_gpu_upscale_shift = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rsx_intf_refresh_variables();
|
||||
|
||||
var.key = BEETLE_OPT(dither_mode);
|
||||
|
||||
@ -3081,46 +3013,6 @@ static void check_variables(bool startup)
|
||||
else
|
||||
input_set_player_count( 2 );
|
||||
|
||||
var.key = BEETLE_OPT(use_mednafen_memcard0_method);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (strcmp(var.value, "libretro") == 0)
|
||||
use_mednafen_memcard0_method = false;
|
||||
else if (strcmp(var.value, "mednafen") == 0)
|
||||
use_mednafen_memcard0_method = true;
|
||||
}
|
||||
|
||||
//this option depends on beetle_psx_use_mednafen_memcard0_method being disabled so it should be evaluated that
|
||||
var.key = BEETLE_OPT(shared_memory_cards);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
|
||||
if (strcmp(var.value, "enabled") == 0)
|
||||
{
|
||||
if(boot)
|
||||
{
|
||||
if(use_mednafen_memcard0_method)
|
||||
shared_memorycards_toggle = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(use_mednafen_memcard0_method)
|
||||
shared_memorycards_toggle = true;
|
||||
}
|
||||
}
|
||||
else if (strcmp(var.value, "disabled") == 0)
|
||||
{
|
||||
if(boot)
|
||||
shared_memorycards_toggle = false;
|
||||
else
|
||||
{
|
||||
shared_memorycards = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var.key = BEETLE_OPT(frame_duping);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
@ -3464,6 +3356,7 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
{
|
||||
char tocbasepath[4096];
|
||||
bool ret = false;
|
||||
is_startup = true;
|
||||
|
||||
if (failed_init)
|
||||
return false;
|
||||
@ -3484,10 +3377,26 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
else
|
||||
snprintf(retro_cd_path, sizeof(retro_cd_path), "%s", info->path);
|
||||
|
||||
check_variables(true);
|
||||
/* make sure shared memory cards and save states are enabled only at startup */
|
||||
struct retro_variable var = {0};
|
||||
var.key = BEETLE_OPT(use_mednafen_memcard0_method);
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (strcmp(var.value, "libretro") == 0)
|
||||
use_mednafen_memcard0_method = false;
|
||||
else if (strcmp(var.value, "mednafen") == 0)
|
||||
use_mednafen_memcard0_method = true;
|
||||
}
|
||||
|
||||
//make sure shared memory cards and save states are enabled only at startup
|
||||
shared_memorycards = shared_memorycards_toggle;
|
||||
/* this option depends on use_mednafen_memcard0_method being **enabled** */
|
||||
var.key = BEETLE_OPT(shared_memory_cards);
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (strcmp(var.value, "enabled") == 0 && use_mednafen_memcard0_method)
|
||||
shared_memorycards = true;
|
||||
else if (strcmp(var.value, "disabled") == 0)
|
||||
shared_memorycards = false;
|
||||
}
|
||||
|
||||
if (!MDFNI_LoadGame(retro_cd_path))
|
||||
{
|
||||
@ -3498,16 +3407,7 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
MDFN_LoadGameCheats(NULL);
|
||||
MDFNMP_InstallReadPatches();
|
||||
|
||||
alloc_surface();
|
||||
|
||||
#ifdef NEED_DEINTERLACER
|
||||
PrevInterlaced = false;
|
||||
deint.ClearState();
|
||||
#endif
|
||||
|
||||
input_init();
|
||||
|
||||
boot = false;
|
||||
input_init();
|
||||
|
||||
frame_count = 0;
|
||||
internal_frame_count = 0;
|
||||
@ -3524,9 +3424,16 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
how to copy the ugui framebuffer to the hardware renderer side with rsx_intf calls,
|
||||
so we don't have to force this anymore. */
|
||||
force_software_renderer = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NEED_DEINTERLACER
|
||||
PrevInterlaced = false;
|
||||
deint.ClearState();
|
||||
#endif
|
||||
|
||||
ret = rsx_intf_open(content_is_pal, force_software_renderer);
|
||||
check_variables();
|
||||
alloc_surface();
|
||||
|
||||
/* Hide irrelevant core options */
|
||||
switch (rsx_intf_is_type())
|
||||
@ -3594,8 +3501,6 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
option_display.key = BEETLE_OPT(display_vram);
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
||||
|
||||
option_display.key = BEETLE_OPT(crop_overscan);
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
||||
option_display.key = BEETLE_OPT(image_offset);
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
||||
option_display.key = BEETLE_OPT(image_crop);
|
||||
@ -3667,34 +3572,24 @@ void retro_run(void)
|
||||
|
||||
rsx_intf_prepare_frame();
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
|
||||
if (is_startup || environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
|
||||
{
|
||||
check_variables(false);
|
||||
struct retro_system_av_info new_av_info;
|
||||
/* Startup ends here */
|
||||
is_startup = false;
|
||||
check_variables();
|
||||
|
||||
/* Max width/height changed, need to call SET_SYSTEM_AV_INFO */
|
||||
if (GPU_get_upscale_shift() != psx_gpu_upscale_shift)
|
||||
/* Software renderer changed its upscale, the static MDFN_Surface needs to be recreated */
|
||||
if (need_new_surface)
|
||||
{
|
||||
retro_get_system_av_info(&new_av_info);
|
||||
if (environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &new_av_info))
|
||||
{
|
||||
// We successfully changed the frontend's resolution, we can
|
||||
// apply the change immediately
|
||||
GPU_Rescale(psx_gpu_upscale_shift);
|
||||
alloc_surface();
|
||||
has_new_geometry = false; /* New AV info also updates geometry */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed, we have to postpone the upscaling change */
|
||||
psx_gpu_upscale_shift = GPU_get_upscale_shift();
|
||||
}
|
||||
alloc_surface();
|
||||
need_new_surface = false;
|
||||
}
|
||||
struct retro_system_av_info new_av_info;
|
||||
|
||||
switch (psx_gpu_dither_mode)
|
||||
{
|
||||
case DITHER_NATIVE:
|
||||
GPU_set_dither_upscale_shift(psx_gpu_upscale_shift);
|
||||
GPU_set_dither_upscale_shift(GPU_get_upscale_shift());
|
||||
break;
|
||||
case DITHER_UPSCALED:
|
||||
GPU_set_dither_upscale_shift(0);
|
||||
|
@ -5,7 +5,7 @@ bool content_is_pal = false;
|
||||
retro_video_refresh_t video_cb;
|
||||
retro_environment_t environ_cb;
|
||||
uint8_t widescreen_hack;
|
||||
uint8_t psx_gpu_upscale_shift;
|
||||
uint8_t psx_gpu_upscale_shift; /* Used to keep track of the SW renderer upscale */
|
||||
int lineRenderMode;
|
||||
int filter_mode;
|
||||
bool opaque_check;
|
||||
@ -21,3 +21,5 @@ int initial_scanline = 0;
|
||||
int initial_scanline_pal = 0;
|
||||
int last_scanline = 239;
|
||||
int last_scanline_pal = 287;
|
||||
bool need_new_surface = false;
|
||||
bool is_startup = true;
|
||||
|
@ -27,6 +27,13 @@ extern int initial_scanline;
|
||||
extern int initial_scanline_pal;
|
||||
extern int last_scanline;
|
||||
extern int last_scanline_pal;
|
||||
|
||||
/* Warns the libretro implementation that it needs to update its static MDFN_Surface object */
|
||||
extern bool need_new_surface;
|
||||
|
||||
/* Whether or not the libretro core is starting up i.e. not in retro_run()
|
||||
* Prevents HW renderers from calling SET_SYSTEM_AV_INFO */
|
||||
extern bool is_startup;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ struct retro_core_option_definition option_defs_us[] = {
|
||||
#endif
|
||||
{
|
||||
BEETLE_OPT(use_mednafen_memcard0_method),
|
||||
"Memory Card 0 Method",
|
||||
"Memory Card 0 Method (Restart)",
|
||||
"Choose the save data format used for memory card 0. 'Libretro' is recommended. 'Mednafen' may be used for compatibility with the stand-alone version of Mednafen.",
|
||||
{
|
||||
{ "libretro", "Libretro" },
|
||||
|
@ -631,7 +631,7 @@ static uint16_t *VRAM_Alloc(uint8 upscale_shift)
|
||||
void GPU_Init(bool pal_clock_and_tv,
|
||||
int sls, int sle, uint8 upscale_shift)
|
||||
{
|
||||
|
||||
GPU_set_upscale_shift(upscale_shift);
|
||||
GPU.vram = VRAM_Alloc(upscale_shift);
|
||||
|
||||
int x, y, v;
|
||||
@ -724,7 +724,8 @@ void GPU_Rescale(uint8 ushift)
|
||||
}
|
||||
|
||||
/* Cleanup the old VRAM */
|
||||
delete [] GPU.vram;
|
||||
if (GPU.vram)
|
||||
delete [] GPU.vram;
|
||||
}
|
||||
|
||||
GPU.vram = NULL;
|
||||
@ -2092,4 +2093,4 @@ void GPU_SetVisibleLines(int sls, int sle)
|
||||
{
|
||||
GPU.LineVisFirst = sls;
|
||||
GPU.LineVisLast = sle;
|
||||
}
|
||||
}
|
||||
|
@ -443,8 +443,12 @@ static bool read_command(const CLIArguments &args, FILE *file, Device &device, R
|
||||
auto w = read_u32(file);
|
||||
auto h = read_u32(file);
|
||||
auto depth_24bpp = read_u32(file);
|
||||
auto is_pal = readu32(file);
|
||||
auto is_480i = readu32(file);
|
||||
auto width_mode = readu32(file);
|
||||
|
||||
renderer.set_display_mode({ x, y, w, h }, depth_24bpp != 0);
|
||||
renderer.set_display_mode({ x, y, w, h }, depth_24bpp != 0, is_pal != 0, is_480i != 0,
|
||||
static_cast<Renderer::WidthMode>(width_mode));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -675,6 +675,49 @@ void Renderer::mipmap_framebuffer()
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::DisplayRect Renderer::compute_display_rect()
|
||||
{
|
||||
unsigned display_width;
|
||||
unsigned display_height = (render_state.is_pal ? 288 : 240) * (render_state.is_480i ? 2 : 1);
|
||||
|
||||
int left_offset = 0;
|
||||
unsigned clock_div = 10;
|
||||
switch (render_state.width_mode)
|
||||
{
|
||||
case WidthMode::WIDTH_MODE_256:
|
||||
clock_div = 10;
|
||||
break;
|
||||
case WidthMode::WIDTH_MODE_320:
|
||||
clock_div = 8;
|
||||
break;
|
||||
case WidthMode::WIDTH_MODE_512:
|
||||
clock_div = 5;
|
||||
break;
|
||||
case WidthMode::WIDTH_MODE_640:
|
||||
clock_div = 4;
|
||||
break;
|
||||
case WidthMode::WIDTH_MODE_368:
|
||||
clock_div = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
if (render_state.crop_overscan)
|
||||
{
|
||||
// Horizontal crop amount is currently hardcoded. Future improvement could allow adjusting this.
|
||||
display_width = 2560/clock_div;
|
||||
left_offset = (render_state.horiz_start - 608) / (int) clock_div;
|
||||
}
|
||||
else
|
||||
{
|
||||
display_width = 2800/clock_div;
|
||||
left_offset = (render_state.horiz_start - 488) / (int) clock_div;
|
||||
}
|
||||
|
||||
int upper_offset = (render_state.vert_start - (render_state.is_pal ? 20 : 16)) * (render_state.is_480i ? 2 : 1);
|
||||
|
||||
return DisplayRect(left_offset, upper_offset, display_width, display_height);
|
||||
}
|
||||
|
||||
ImageHandle Renderer::scanout_to_texture()
|
||||
{
|
||||
atlas.flush_render_pass();
|
||||
@ -758,9 +801,13 @@ ImageHandle Renderer::scanout_to_texture()
|
||||
|
||||
bool scaled = !bpp24 && !ssaa;
|
||||
|
||||
unsigned render_scale = scaled ? scaling : 1;
|
||||
|
||||
auto display_rect = compute_display_rect();
|
||||
|
||||
auto info = ImageCreateInfo::render_target(
|
||||
rect.width * (scaled ? scaling : 1),
|
||||
rect.height * (scaled ? scaling : 1),
|
||||
display_rect.width * render_scale,
|
||||
display_rect.height * render_scale,
|
||||
render_state.scanout_mode == ScanoutMode::ABGR1555_Dither ? VK_FORMAT_A1R5G5B5_UNORM_PACK16 : VK_FORMAT_R8G8B8A8_UNORM);
|
||||
|
||||
if (!reuseable_scanout ||
|
||||
@ -779,6 +826,10 @@ ImageHandle Renderer::scanout_to_texture()
|
||||
rp.num_color_attachments = 1;
|
||||
rp.store_attachments = 1;
|
||||
|
||||
rp.clear_color[0] = {0, 0, 0, 0};
|
||||
//rp.clear_color[0] = {60.0f/256.0f, 230.0f/256.0f, 60.0f/256.0f, 0};
|
||||
rp.clear_attachments = 1;
|
||||
|
||||
cmd->image_barrier(*reuseable_scanout, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||
@ -786,6 +837,16 @@ ImageHandle Renderer::scanout_to_texture()
|
||||
cmd->begin_render_pass(rp);
|
||||
cmd->set_quad_state();
|
||||
|
||||
auto old_vp = cmd->get_viewport();
|
||||
VkViewport new_vp = {display_rect.x * (float) render_scale,
|
||||
display_rect.y * (float) render_scale,
|
||||
rect.width * (float) render_scale,
|
||||
rect.height * (float) render_scale,
|
||||
old_vp.minDepth,
|
||||
old_vp.maxDepth};
|
||||
|
||||
cmd->set_viewport(new_vp);
|
||||
|
||||
bool dither = render_state.scanout_mode == ScanoutMode::ABGR1555_Dither;
|
||||
|
||||
if (bpp24)
|
||||
|
@ -60,6 +60,33 @@ public:
|
||||
MDEC_YUV
|
||||
};
|
||||
|
||||
enum class WidthMode
|
||||
{
|
||||
WIDTH_MODE_256 = 0,
|
||||
WIDTH_MODE_320 = 1,
|
||||
WIDTH_MODE_512 = 2,
|
||||
WIDTH_MODE_640 = 3,
|
||||
WIDTH_MODE_368 = 4
|
||||
};
|
||||
|
||||
struct DisplayRect
|
||||
{
|
||||
// Unlike Rect, the x-y coordinates for a DisplayRect can be negative
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
|
||||
DisplayRect() = default;
|
||||
DisplayRect(int x, int y, unsigned width, unsigned height)
|
||||
: x(x)
|
||||
, y(y)
|
||||
, width(width)
|
||||
, height(height)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderState
|
||||
{
|
||||
Rect display_mode;
|
||||
@ -73,6 +100,16 @@ public:
|
||||
unsigned texture_offset_x = 0;
|
||||
unsigned texture_offset_y = 0;
|
||||
|
||||
int vert_start = 0x10;
|
||||
int vert_end = 0x100;
|
||||
int horiz_start = 0x200;
|
||||
int horiz_end = 0xC00;
|
||||
|
||||
bool is_pal = false;
|
||||
bool is_480i = false;
|
||||
WidthMode width_mode = WidthMode::WIDTH_MODE_320;
|
||||
bool crop_overscan = false;
|
||||
|
||||
TextureMode texture_mode = TextureMode::None;
|
||||
SemiTransparentMode semi_transparent = SemiTransparentMode::None;
|
||||
ScanoutMode scanout_mode = ScanoutMode::ABGR1555_555;
|
||||
@ -135,13 +172,35 @@ public:
|
||||
void end_copy(Vulkan::BufferHandle handle);
|
||||
|
||||
void blit_vram(const Rect &dst, const Rect &src);
|
||||
void set_display_mode(const Rect &rect, ScanoutMode mode)
|
||||
|
||||
void set_horizontal_display_range(int x1, int x2)
|
||||
{
|
||||
render_state.horiz_start = x1;
|
||||
render_state.horiz_end = x2;
|
||||
}
|
||||
|
||||
void set_vertical_display_range(int y1, int y2)
|
||||
{
|
||||
render_state.vert_start = y1;
|
||||
render_state.vert_end = y2;
|
||||
}
|
||||
|
||||
void set_display_mode(const Rect &rect, ScanoutMode mode, bool is_pal, bool is_480i, WidthMode width_mode)
|
||||
{
|
||||
if (rect != render_state.display_mode || render_state.scanout_mode != mode)
|
||||
last_scanout.reset();
|
||||
|
||||
render_state.display_mode = rect;
|
||||
render_state.scanout_mode = mode;
|
||||
|
||||
render_state.is_pal = is_pal;
|
||||
render_state.is_480i = is_480i;
|
||||
render_state.width_mode = width_mode;
|
||||
}
|
||||
|
||||
void set_horizontal_overscan_cropping(bool crop_overscan)
|
||||
{
|
||||
render_state.crop_overscan = crop_overscan;
|
||||
}
|
||||
|
||||
void set_display_filter(ScanoutFilter filter)
|
||||
@ -444,6 +503,7 @@ private:
|
||||
|
||||
Vulkan::ImageHandle last_scanout;
|
||||
Vulkan::ImageHandle reuseable_scanout;
|
||||
DisplayRect compute_display_rect();
|
||||
|
||||
void mipmap_framebuffer();
|
||||
Vulkan::BufferHandle quad;
|
||||
|
@ -2289,6 +2289,9 @@ static void rsx_gl_refresh_variables(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_startup)
|
||||
return;
|
||||
|
||||
if (retro_refresh_variables(renderer))
|
||||
{
|
||||
/* The resolution has changed, we must tell the frontend
|
||||
@ -3002,6 +3005,7 @@ static unsigned msaa = 1;
|
||||
static bool mdec_yuv;
|
||||
static vector<function<void ()>> defer;
|
||||
static dither_mode dither_mode = DITHER_NATIVE;
|
||||
static bool crop_overscan;
|
||||
|
||||
static retro_video_refresh_t video_refresh_cb;
|
||||
|
||||
@ -3201,6 +3205,15 @@ static void rsx_vulkan_refresh_variables(void)
|
||||
dither_mode = DITHER_OFF;
|
||||
}
|
||||
|
||||
var.key = BEETLE_OPT(crop_overscan);
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (!strcmp(var.value, "enabled"))
|
||||
crop_overscan = true;
|
||||
else
|
||||
crop_overscan = false;
|
||||
}
|
||||
|
||||
var.key = BEETLE_OPT(widescreen_hack);
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
@ -3210,6 +3223,10 @@ static void rsx_vulkan_refresh_variables(void)
|
||||
widescreen_hack = false;
|
||||
}
|
||||
|
||||
if (is_startup)
|
||||
return;
|
||||
|
||||
// Changing crop_overscan will likely need to be included here in future geometry fixes
|
||||
if ((old_scaling != scaling || old_super_sampling != super_sampling || old_msaa != msaa) && renderer)
|
||||
{
|
||||
retro_system_av_info info;
|
||||
@ -3228,6 +3245,7 @@ static void rsx_vulkan_finalize_frame(const void *fb, unsigned width,
|
||||
{
|
||||
renderer->set_adaptive_smoothing(adaptive_smoothing);
|
||||
renderer->set_dither_native_resolution(dither_mode == DITHER_NATIVE);
|
||||
renderer->set_horizontal_overscan_cropping(crop_overscan);
|
||||
|
||||
if (renderer->get_scanout_mode() == Renderer::ScanoutMode::BGR24)
|
||||
renderer->set_display_filter(mdec_yuv ? Renderer::ScanoutFilter::MDEC_YUV : Renderer::ScanoutFilter::None);
|
||||
@ -3772,7 +3790,54 @@ void rsx_intf_refresh_variables(void)
|
||||
switch (rsx_type)
|
||||
{
|
||||
case RSX_SOFTWARE:
|
||||
{
|
||||
struct retro_variable var = {0};
|
||||
var.key = BEETLE_OPT(internal_resolution);
|
||||
uint8_t old_psx_gpu_upscale_shift = GPU_get_upscale_shift();
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
uint8_t new_upscale_shift;
|
||||
uint8_t val = atoi(var.value);
|
||||
|
||||
// Upscale must be a power of two
|
||||
assert((val & (val - 1)) == 0);
|
||||
|
||||
// Crappy "ffs" implementation since the standard function is not
|
||||
// widely supported by libc in the wild
|
||||
for (new_upscale_shift = 0; (val & 1) == 0; ++new_upscale_shift)
|
||||
val >>= 1;
|
||||
psx_gpu_upscale_shift = new_upscale_shift;
|
||||
}
|
||||
else
|
||||
psx_gpu_upscale_shift = 0;
|
||||
|
||||
/* According to the libretro spec, can't call set_av_info when not in retro_run() */
|
||||
if (is_startup)
|
||||
GPU_Rescale(psx_gpu_upscale_shift);
|
||||
|
||||
/* Max width/height changed, need to call SET_SYSTEM_AV_INFO */
|
||||
else if (old_psx_gpu_upscale_shift != psx_gpu_upscale_shift)
|
||||
{
|
||||
retro_system_av_info info;
|
||||
rsx_intf_get_system_av_info(&info);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info))
|
||||
{
|
||||
/* We successfully changed the frontend's resolution, we can
|
||||
apply the change immediately */
|
||||
GPU_Rescale(psx_gpu_upscale_shift);
|
||||
need_new_surface = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed, we have to postpone the upscaling change */
|
||||
psx_gpu_upscale_shift = GPU_get_upscale_shift();
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RSX_OPENGL:
|
||||
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
|
||||
if (static_renderer.inited)
|
||||
@ -4034,7 +4099,16 @@ void rsx_intf_set_horizontal_display_range(uint16_t x1, uint16_t x2)
|
||||
#endif
|
||||
break;
|
||||
case RSX_VULKAN:
|
||||
//implement me for Vulkan and set HAVE_VULKAN define check
|
||||
#if defined(HAVE_VULKAN)
|
||||
if (renderer)
|
||||
renderer->set_horizontal_display_range(x1, x2);
|
||||
else
|
||||
{
|
||||
defer.push_back([=]() {
|
||||
renderer->set_horizontal_display_range(x1, x2);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4063,7 +4137,16 @@ void rsx_intf_set_vertical_display_range(uint16_t y1, uint16_t y2)
|
||||
#endif
|
||||
break;
|
||||
case RSX_VULKAN:
|
||||
//implement me for Vulkan and set HAVE_VULKAN define check
|
||||
#if defined(HAVE_VULKAN)
|
||||
if (renderer)
|
||||
renderer->set_vertical_display_range(y1, y2);
|
||||
else
|
||||
{
|
||||
defer.push_back([=]() {
|
||||
renderer->set_vertical_display_range(y1, y2);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4150,11 +4233,13 @@ void rsx_intf_set_display_mode(uint16_t x, uint16_t y,
|
||||
case RSX_VULKAN:
|
||||
#if defined(HAVE_VULKAN)
|
||||
if (renderer)
|
||||
renderer->set_display_mode({ x, y, w, h }, get_scanout_mode(depth_24bpp));
|
||||
renderer->set_display_mode({ x, y, w, h }, get_scanout_mode(depth_24bpp), is_pal,
|
||||
is_480i, static_cast<Renderer::WidthMode>(width_mode));
|
||||
else
|
||||
{
|
||||
defer.push_back([=]() {
|
||||
renderer->set_display_mode({ x, y, w, h }, get_scanout_mode(depth_24bpp));
|
||||
renderer->set_display_mode({ x, y, w, h }, get_scanout_mode(depth_24bpp), is_pal,
|
||||
is_480i, static_cast<Renderer::WidthMode>(width_mode));
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user