mirror of
https://github.com/libretro/beetle-psx-libretro.git
synced 2024-11-27 02:40:31 +00:00
VK renderer: Add Display VRAM core option support
This commit is contained in:
parent
e3e511be78
commit
fe3cb3394e
@ -4119,8 +4119,6 @@ bool retro_load_game(const struct retro_game_info *info)
|
|||||||
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
||||||
option_display.key = BEETLE_OPT(wireframe);
|
option_display.key = BEETLE_OPT(wireframe);
|
||||||
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
||||||
option_display.key = BEETLE_OPT(display_vram);
|
|
||||||
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
|
||||||
|
|
||||||
option_display.key = BEETLE_OPT(image_offset);
|
option_display.key = BEETLE_OPT(image_offset);
|
||||||
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
|
||||||
|
@ -195,10 +195,12 @@ struct retro_core_option_definition option_defs_us[] = {
|
|||||||
},
|
},
|
||||||
"disabled"
|
"disabled"
|
||||||
},
|
},
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(HAVE_VULKAN)
|
||||||
{
|
{
|
||||||
BEETLE_OPT(display_vram),
|
BEETLE_OPT(display_vram),
|
||||||
"Display Full VRAM (Debug)",
|
"Display Full VRAM (Debug)",
|
||||||
"When enabled, visualises the entire emulated console's VRAM. Only supported by the OpenGL hardware renderer. Note: This is for debugging purposes, and should normally be disabled.",
|
"When enabled, visualises the entire emulated console's VRAM. Only supported by the OpenGL and Vulkan hardware renderers. Note: This is for debugging purposes, and should normally be disabled.",
|
||||||
{
|
{
|
||||||
{ "disabled", NULL },
|
{ "disabled", NULL },
|
||||||
{ "enabled", NULL },
|
{ "enabled", NULL },
|
||||||
|
@ -766,6 +766,115 @@ Renderer::DisplayRect Renderer::compute_display_rect()
|
|||||||
return DisplayRect(left_offset, upper_offset, display_width, display_height);
|
return DisplayRect(left_offset, upper_offset, display_width, display_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageHandle Renderer::scanout_vram_to_texture(bool scaled)
|
||||||
|
{
|
||||||
|
// Like scanout_to_texture(), but synchronizes the entire
|
||||||
|
// VRAM framebuffer atlas before scanout. Does not apply
|
||||||
|
// any scanout filters and currently outputs at 15-bit
|
||||||
|
// color depth. Current implementation does not reuse
|
||||||
|
// prior scanouts.
|
||||||
|
|
||||||
|
atlas.flush_render_pass();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (last_scanout)
|
||||||
|
return last_scanout;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Rect vram_rect = {0, 0, FB_WIDTH, FB_HEIGHT};
|
||||||
|
|
||||||
|
if (scaled)
|
||||||
|
atlas.read_fragment(Domain::Scaled, vram_rect);
|
||||||
|
else
|
||||||
|
atlas.read_fragment(Domain::Unscaled, vram_rect);
|
||||||
|
|
||||||
|
ensure_command_buffer();
|
||||||
|
|
||||||
|
if (scanout_semaphore)
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
device.add_wait_semaphore(CommandBuffer::Type::Generic, scanout_semaphore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, true);
|
||||||
|
scanout_semaphore.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_command_buffer();
|
||||||
|
|
||||||
|
unsigned render_scale = scaled ? scaling : 1;
|
||||||
|
|
||||||
|
auto info = ImageCreateInfo::render_target(
|
||||||
|
FB_WIDTH * render_scale,
|
||||||
|
FB_HEIGHT * render_scale,
|
||||||
|
VK_FORMAT_A1R5G5B5_UNORM_PACK16); // Default to 15bit color for now
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (!reuseable_scanout ||
|
||||||
|
reuseable_scanout->get_create_info().width != info.width ||
|
||||||
|
reuseable_scanout->get_create_info().height != info.height ||
|
||||||
|
reuseable_scanout->get_create_info().format != info.format)
|
||||||
|
{
|
||||||
|
info.initial_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
reuseable_scanout = device.create_image(info);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
info.initial_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
reuseable_scanout = device.create_image(info);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RenderPassInfo rp;
|
||||||
|
rp.color_attachments[0] = &reuseable_scanout->get_view();
|
||||||
|
rp.num_color_attachments = 1;
|
||||||
|
rp.store_attachments = 1;
|
||||||
|
|
||||||
|
rp.clear_color[0] = {0, 0, 0, 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);
|
||||||
|
|
||||||
|
cmd->begin_render_pass(rp);
|
||||||
|
cmd->set_quad_state();
|
||||||
|
|
||||||
|
cmd->set_program(*pipelines.scaled_quad_blitter);
|
||||||
|
cmd->set_texture(0, 0, *scaled_views[0], StockSampler::LinearClamp);
|
||||||
|
|
||||||
|
cmd->set_vertex_binding(0, *quad, 0, 2);
|
||||||
|
struct Push
|
||||||
|
{
|
||||||
|
float offset[2];
|
||||||
|
float scale[2];
|
||||||
|
float uv_min[2];
|
||||||
|
float uv_max[2];
|
||||||
|
float max_bias;
|
||||||
|
};
|
||||||
|
|
||||||
|
Push push = { { float(vram_rect.x) / FB_WIDTH, float(vram_rect.y) / FB_HEIGHT },
|
||||||
|
{ float(vram_rect.width) / FB_WIDTH, float(vram_rect.height) / FB_HEIGHT },
|
||||||
|
{ (vram_rect.x + 0.5f) / FB_WIDTH, (vram_rect.y + 0.5f) / FB_HEIGHT },
|
||||||
|
{ (vram_rect.x + vram_rect.width - 0.5f) / FB_WIDTH, (vram_rect.y + vram_rect.height - 0.5f) / FB_HEIGHT },
|
||||||
|
float(scaled_views.size() - 1) };
|
||||||
|
|
||||||
|
cmd->push_constants(&push, 0, sizeof(push));
|
||||||
|
cmd->set_vertex_attrib(0, 0, VK_FORMAT_R8G8_SNORM, 0);
|
||||||
|
cmd->set_primitive_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
|
||||||
|
counters.draw_calls++;
|
||||||
|
counters.vertices += 4;
|
||||||
|
cmd->draw(4);
|
||||||
|
|
||||||
|
cmd->end_render_pass();
|
||||||
|
|
||||||
|
cmd->image_barrier(*reuseable_scanout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||||
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
|
VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
|
||||||
|
last_scanout = reuseable_scanout;
|
||||||
|
|
||||||
|
return reuseable_scanout;
|
||||||
|
}
|
||||||
|
|
||||||
ImageHandle Renderer::scanout_to_texture()
|
ImageHandle Renderer::scanout_to_texture()
|
||||||
{
|
{
|
||||||
atlas.flush_render_pass();
|
atlas.flush_render_pass();
|
||||||
|
@ -268,6 +268,7 @@ public:
|
|||||||
void scanout();
|
void scanout();
|
||||||
Vulkan::BufferHandle scanout_to_buffer(bool draw_area, unsigned &width, unsigned &height);
|
Vulkan::BufferHandle scanout_to_buffer(bool draw_area, unsigned &width, unsigned &height);
|
||||||
Vulkan::BufferHandle scanout_vram_to_buffer(unsigned &width, unsigned &height);
|
Vulkan::BufferHandle scanout_vram_to_buffer(unsigned &width, unsigned &height);
|
||||||
|
Vulkan::ImageHandle scanout_vram_to_texture(bool scaled = true);
|
||||||
Vulkan::ImageHandle scanout_to_texture();
|
Vulkan::ImageHandle scanout_to_texture();
|
||||||
|
|
||||||
inline void set_texture_mode(TextureMode mode)
|
inline void set_texture_mode(TextureMode mode)
|
||||||
|
@ -60,6 +60,7 @@ static int last_scanline_pal;
|
|||||||
static bool frame_duping_enabled = false;
|
static bool frame_duping_enabled = false;
|
||||||
static uint32_t prev_frame_width = 320;
|
static uint32_t prev_frame_width = 320;
|
||||||
static uint32_t prev_frame_height = 240;
|
static uint32_t prev_frame_height = 240;
|
||||||
|
static bool show_vram = false;
|
||||||
|
|
||||||
static retro_video_refresh_t video_refresh_cb;
|
static retro_video_refresh_t video_refresh_cb;
|
||||||
|
|
||||||
@ -205,7 +206,13 @@ void rsx_vulkan_get_system_av_info(struct retro_system_av_info *info)
|
|||||||
info->geometry.max_height = MEDNAFEN_CORE_GEOMETRY_MAX_H * (super_sampling ? 1 : scaling);
|
info->geometry.max_height = MEDNAFEN_CORE_GEOMETRY_MAX_H * (super_sampling ? 1 : scaling);
|
||||||
info->timing.sample_rate = SOUND_FREQUENCY;
|
info->timing.sample_rate = SOUND_FREQUENCY;
|
||||||
|
|
||||||
info->geometry.aspect_ratio = !widescreen_hack ? MEDNAFEN_CORE_GEOMETRY_ASPECT_RATIO : 16.0 / 9.0;
|
if (show_vram)
|
||||||
|
info->geometry.aspect_ratio = 2.0 / 1.0;
|
||||||
|
else if (widescreen_hack)
|
||||||
|
info->geometry.aspect_ratio = 16.0 / 9.0;
|
||||||
|
else
|
||||||
|
info->geometry.aspect_ratio = MEDNAFEN_CORE_GEOMETRY_ASPECT_RATIO;
|
||||||
|
|
||||||
if (content_is_pal)
|
if (content_is_pal)
|
||||||
info->timing.fps = FPS_PAL_NONINTERLACED;
|
info->timing.fps = FPS_PAL_NONINTERLACED;
|
||||||
else
|
else
|
||||||
@ -232,6 +239,7 @@ void rsx_vulkan_refresh_variables(void)
|
|||||||
unsigned old_scaling = scaling;
|
unsigned old_scaling = scaling;
|
||||||
unsigned old_msaa = msaa;
|
unsigned old_msaa = msaa;
|
||||||
bool old_super_sampling = super_sampling;
|
bool old_super_sampling = super_sampling;
|
||||||
|
bool old_show_vram = show_vram;
|
||||||
|
|
||||||
var.key = BEETLE_OPT(internal_resolution);
|
var.key = BEETLE_OPT(internal_resolution);
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||||
@ -353,8 +361,21 @@ void rsx_vulkan_refresh_variables(void)
|
|||||||
frame_duping_enabled = false;
|
frame_duping_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var.key = BEETLE_OPT(display_vram);
|
||||||
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||||
|
{
|
||||||
|
if (!strcmp(var.value, "enabled"))
|
||||||
|
show_vram = true;
|
||||||
|
else
|
||||||
|
show_vram = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Changing crop_overscan and scanlines will likely need to be included here in future geometry fixes
|
// Changing crop_overscan and scanlines will likely need to be included here in future geometry fixes
|
||||||
if ((old_scaling != scaling || old_super_sampling != super_sampling || old_msaa != msaa) && renderer)
|
if ((old_scaling != scaling ||
|
||||||
|
old_super_sampling != super_sampling ||
|
||||||
|
old_msaa != msaa ||
|
||||||
|
old_show_vram != show_vram)
|
||||||
|
&& renderer)
|
||||||
{
|
{
|
||||||
retro_system_av_info info;
|
retro_system_av_info info;
|
||||||
rsx_vulkan_get_system_av_info(&info);
|
rsx_vulkan_get_system_av_info(&info);
|
||||||
@ -415,7 +436,7 @@ void rsx_vulkan_finalize_frame(const void *fb, unsigned width,
|
|||||||
else
|
else
|
||||||
renderer->set_display_filter(super_sampling ? Renderer::ScanoutFilter::SSAA : Renderer::ScanoutFilter::None);
|
renderer->set_display_filter(super_sampling ? Renderer::ScanoutFilter::SSAA : Renderer::ScanoutFilter::None);
|
||||||
|
|
||||||
auto scanout = renderer->scanout_to_texture();
|
auto scanout = show_vram ? renderer->scanout_vram_to_texture() : renderer->scanout_to_texture();
|
||||||
|
|
||||||
retro_vulkan_image *image = &swapchain_image;
|
retro_vulkan_image *image = &swapchain_image;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user