diff --git a/config.def.h b/config.def.h index 52f3bcb5fb5..602db4dd521 100644 --- a/config.def.h +++ b/config.def.h @@ -994,6 +994,8 @@ /* Screenshots post-shaded GPU output if available. */ #define DEFAULT_GPU_SCREENSHOT true +#define DEFAULT_GPU_SCREENSHOT_INCLUDE_SHADERS true +#define DEFAULT_GPU_SCREENSHOT_INCLUDE_OVERLAY true /* Watch shader files for changes and auto-apply as necessary. */ #define DEFAULT_VIDEO_SHADER_WATCH_FILES false diff --git a/configuration.c b/configuration.c index 7eb6c08e1e2..2681f3d2c5f 100644 --- a/configuration.c +++ b/configuration.c @@ -1883,6 +1883,8 @@ static struct config_bool_setting *populate_settings_bool( SETTING_BOOL("video_waitable_swapchains", &settings->bools.video_waitable_swapchains, true, DEFAULT_WAITABLE_SWAPCHAINS, false); SETTING_BOOL("video_disable_composition", &settings->bools.video_disable_composition, true, DEFAULT_DISABLE_COMPOSITION, false); SETTING_BOOL("video_gpu_screenshot", &settings->bools.video_gpu_screenshot, true, DEFAULT_GPU_SCREENSHOT, false); + SETTING_BOOL("video_gpu_screenshot_include_shaders", &settings->bools.video_gpu_screenshot_include_shaders, true, DEFAULT_GPU_SCREENSHOT_INCLUDE_SHADERS, false); + SETTING_BOOL("video_gpu_screenshot_include_overlay", &settings->bools.video_gpu_screenshot_include_overlay, true, DEFAULT_GPU_SCREENSHOT_INCLUDE_OVERLAY, false); SETTING_BOOL("video_post_filter_record", &settings->bools.video_post_filter_record, true, DEFAULT_POST_FILTER_RECORD, false); SETTING_BOOL("video_notch_write_over_enable", &settings->bools.video_notch_write_over_enable, true, DEFAULT_NOTCH_WRITE_OVER_ENABLE, false); SETTING_BOOL("video_msg_bgcolor_enable", &settings->bools.video_msg_bgcolor_enable, true, DEFAULT_MESSAGE_BGCOLOR_ENABLE, false); diff --git a/configuration.h b/configuration.h index b61d3a22c95..ddfa98b46a4 100644 --- a/configuration.h +++ b/configuration.h @@ -631,6 +631,8 @@ typedef struct settings bool video_post_filter_record; bool video_gpu_record; bool video_gpu_screenshot; + bool video_gpu_screenshot_include_shaders; + bool video_gpu_screenshot_include_overlay; bool video_allow_rotate; bool video_shared_context; bool video_force_srgb_disable; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 802b005e065..5920c32309e 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -4426,6 +4426,14 @@ MSG_HASH( MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT, "video_gpu_screenshot" ) +MSG_HASH( + MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS, + "video_gpu_screenshot_include_shaders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY, + "video_gpu_screenshot_include_overlay" + ) MSG_HASH( MENU_ENUM_LABEL_VIDEO_HARD_SYNC, "video_hard_sync" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 89118f23295..90f3c869237 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2158,6 +2158,22 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, "GPU Screenshot" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS, + "GPU Screenshot Shaders" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS, + "Include shaders when capturing GPU screenshots" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY, + "GPU Screenshot Overlay" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY, + "Include overlay when capturing GPU screenshots" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_SCAN_SUBFRAMES, "Rolling scanline simulation" @@ -2172,7 +2188,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, - "Screenshots capture GPU shaded material if available." + "Screenshots capture GPU material if available." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 9df92f8806f..b02954967b0 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -724,6 +724,8 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer, MENU_ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer_axis, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_AXIS) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scale_integer_scaling, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER_SCALING) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_screenshot, MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_screenshot_include_shaders, MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_screenshot_include_overlay, MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_rotation, MENU_ENUM_SUBLABEL_VIDEO_ROTATION) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_screen_orientation, MENU_ENUM_SUBLABEL_SCREEN_ORIENTATION) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_force_srgb_enable, MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE) @@ -4235,6 +4237,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_gpu_screenshot); break; + case MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_gpu_screenshot_include_shaders); + break; + case MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_gpu_screenshot_include_overlay); + break; case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 2a7db944aff..0b4e67debf6 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -7825,12 +7825,26 @@ unsigned menu_displaylist_build_list( #ifdef HAVE_SCREENSHOTS { video_driver_state_t *video_st = video_state_get_ptr(); - if ( video_st->current_video->read_viewport - && video_st->current_video->viewport_info) + if (video_st->current_video->read_viewport + && video_st->current_video->viewport_info) + { if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, - MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT, - PARSE_ONLY_BOOL, false) == 0) + MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT, + PARSE_ONLY_BOOL, false) == 0) + count++; +#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS, + PARSE_ONLY_BOOL, false) == 0) count++; +#endif +#ifdef HAVE_OVERLAY + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY, + PARSE_ONLY_BOOL, false) == 0) + count++; +#endif + } } #endif if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 589cbe7f490..5635e498dd9 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -14412,6 +14412,38 @@ static bool setting_append_list( ); SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ADVANCED); + CONFIG_BOOL( + list, list_info, + &settings->bools.video_gpu_screenshot_include_shaders, + MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS, + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS, + DEFAULT_GPU_SCREENSHOT_INCLUDE_SHADERS, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_ADVANCED + ); + + CONFIG_BOOL( + list, list_info, + &settings->bools.video_gpu_screenshot_include_overlay, + MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY, + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY, + DEFAULT_GPU_SCREENSHOT_INCLUDE_OVERLAY, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_ADVANCED + ); + CONFIG_BOOL( list, list_info, &settings->bools.video_crop_overscan, diff --git a/msg_hash.h b/msg_hash.h index bc9404d5aac..7a8ced86191 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1406,6 +1406,8 @@ enum msg_hash_enums MENU_LABEL(VIDEO_WAITABLE_SWAPCHAINS), MENU_LABEL(VIDEO_MAX_FRAME_LATENCY), MENU_LABEL(VIDEO_GPU_SCREENSHOT), + MENU_LABEL(VIDEO_GPU_SCREENSHOT_INCLUDE_SHADERS), + MENU_LABEL(VIDEO_GPU_SCREENSHOT_INCLUDE_OVERLAY), MENU_LBL_H(VIDEO_BLACK_FRAME_INSERTION), MENU_LBL_H(VIDEO_BFI_DARK_FRAMES), MENU_LBL_H(VIDEO_SHADER_SUBFRAMES), diff --git a/tasks/task_screenshot.c b/tasks/task_screenshot.c index 8173eedc488..19a28234992 100644 --- a/tasks/task_screenshot.c +++ b/tasks/task_screenshot.c @@ -455,6 +455,9 @@ static bool take_screenshot_viewport( unsigned pixel_format_type) { struct video_viewport vp; + bool success; + bool shaders_used; + settings_t* settings; video_driver_state_t *video_st = video_state_get_ptr(); uint8_t *buffer = NULL; @@ -465,6 +468,8 @@ static bool take_screenshot_viewport( vp.full_width = 0; vp.full_height = 0; + settings = config_get_ptr(); + video_driver_get_viewport_info(&vp); if (!vp.width || !vp.height) @@ -472,10 +477,34 @@ static bool take_screenshot_viewport( if (!(buffer = (uint8_t*)malloc(vp.width * vp.height * 3))) return false; - if (!( video_st->current_video->read_viewport - && video_st->current_video->read_viewport( - video_st->data, buffer, runloop_flags & RUNLOOP_FLAG_IDLE))) + shaders_used = settings->bools.video_shader_enable; + if (!settings->bools.video_gpu_screenshot_include_shaders && + shaders_used) + { + command_event(CMD_EVENT_SHADER_TOGGLE, NULL); + video_driver_cached_frame(); + } + if (!settings->bools.video_gpu_screenshot_include_overlay && + settings->bools.input_overlay_enable) + { + command_event(CMD_EVENT_OVERLAY_UNLOAD, NULL); + video_driver_cached_frame(); + } + + success = (video_st->current_video->read_viewport + && video_st->current_video->read_viewport( + video_st->data, buffer, runloop_flags & RUNLOOP_FLAG_IDLE)); + + if (!settings->bools.video_gpu_screenshot_include_shaders && + shaders_used) + command_event(CMD_EVENT_SHADER_TOGGLE, NULL); + if (!settings->bools.video_gpu_screenshot_include_overlay && + settings->bools.input_overlay_enable) + command_event(CMD_EVENT_OVERLAY_INIT, NULL); + + if (!success) goto error; + /* Limit image to screen size */ if (vp.width > video_st->width)