diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 5bdcb4cfda..eb6f639517 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -879,7 +879,7 @@ void GLGSRender::on_init_thread() type.disable_cancel = true; type.progress_bar_count = 2; - dlg = fxm::get()->create(true); + dlg = fxm::get()->create((bool)g_cfg.video.shader_preloading_dialog.use_custom_background); dlg->progress_bar_set_taskbar_index(-1); dlg->show("Loading precompiled shaders from disk...", type, [](s32 status) { diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 430acbfda4..1b73795461 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -367,6 +367,56 @@ namespace gl "uniform int read_texture;\n" "uniform int pulse_glow;\n" "uniform int clip_region;\n" + "uniform int blur_strength;\n" + "\n" + "vec4 blur_sample(sampler2D tex, vec2 coord, vec2 tex_offset)\n" + "{\n" + " vec2 coords[9];\n" + " coords[0] = coord - tex_offset\n;" + " coords[1] = coord + vec2(0., -tex_offset.y);\n" + " coords[2] = coord + vec2(tex_offset.x, -tex_offset.y);\n" + " coords[3] = coord + vec2(-tex_offset.x, 0.);\n" + " coords[4] = coord;\n" + " coords[5] = coord + vec2(tex_offset.x, 0.);\n" + " coords[6] = coord + vec2(-tex_offset.x, tex_offset.y);\n" + " coords[7] = coord + vec2(0., tex_offset.y);\n" + " coords[8] = coord + tex_offset;\n" + "\n" + " float weights[9] =\n" + " {\n" + " 1., 2., 1.,\n" + " 2., 4., 2.,\n" + " 1., 2., 1.\n" + " };\n" + "\n" + " vec4 blurred = vec4(0.);\n" + " for (int n = 0; n < 9; ++n)\n" + " {\n" + " blurred += texture(tex, coords[n]) * weights[n];\n" + " }\n" + "\n" + " return blurred / 16.f;\n" + "}\n" + "\n" + "vec4 sample_image(sampler2D tex, vec2 coord)\n" + "{\n" + " vec4 original = texture(tex, coord);\n" + " if (blur_strength == 0) return original;\n" + " \n" + " vec2 constraints = 1.f / vec2(640, 360);\n" + " vec2 res_offset = 1.f / textureSize(fs0, 0);\n" + " vec2 tex_offset = max(res_offset, constraints);\n" + "\n" + " // Sample triangle pattern and average\n" + " // TODO: Nicer looking gaussian blur with less sampling\n" + " vec4 blur0 = blur_sample(tex, coord + vec2(-res_offset.x, 0.), tex_offset);\n" + " vec4 blur1 = blur_sample(tex, coord + vec2(res_offset.x, 0.), tex_offset);\n" + " vec4 blur2 = blur_sample(tex, coord + vec2(0., res_offset.y), tex_offset);\n" + "\n" + " vec4 blurred = blur0 + blur1 + blur2;\n" + " blurred /= 3.;\n" + " return mix(original, blurred, float(blur_strength) / 100.);\n" + "}\n" "\n" "void main()\n" "{\n" @@ -385,7 +435,7 @@ namespace gl " diff_color.a *= (sin(time) + 1.f) * 0.5f;\n" "\n" " if (read_texture != 0)\n" - " ocol = texture(fs0, tc0) * diff_color;\n" + " ocol = sample_image(fs0, tc0) * diff_color;\n" " else\n" " ocol = diff_color;\n" "}\n" @@ -567,6 +617,7 @@ namespace gl program_handle.uniforms["color"] = cmd.config.color; program_handle.uniforms["read_texture"] = texture_exists; program_handle.uniforms["pulse_glow"] = (s32)cmd.config.pulse_glow; + program_handle.uniforms["blur_strength"] = (s32)cmd.config.blur_strength; program_handle.uniforms["clip_region"] = (s32)cmd.config.clip_region; program_handle.uniforms["clip_bounds"] = cmd.config.clip_rect; overlay_pass::run(w, h, target, false, true); diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index 5468847b41..7e55e829d0 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -570,6 +570,8 @@ namespace rsx font *font_ref = nullptr; void *external_data_ref = nullptr; + u8 blur_strength = 0; + command_config() {} void set_image_resource(u8 ref) @@ -1199,6 +1201,9 @@ namespace rsx u8 image_resource_ref = image_resource_id::none; void *external_ref = nullptr; + // Strength of blur effect + u8 blur_strength = 0; + public: using overlay_element::overlay_element; @@ -1213,6 +1218,8 @@ namespace rsx cmd_img.config.color = fore_color; cmd_img.config.external_data_ref = external_ref; + cmd_img.config.blur_strength = blur_strength; + // Make padding work for images (treat them as the content instead of the 'background') auto& verts = cmd_img.verts; @@ -1238,6 +1245,11 @@ namespace rsx image_resource_ref = image_resource_id::raw_image; external_ref = raw_image; } + + void set_blur_strength(u8 strength) + { + blur_strength = strength; + } }; struct image_button : public image_view diff --git a/rpcs3/Emu/RSX/Overlays/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h index bd6ab27eb3..cb6eea5a5e 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -777,11 +777,11 @@ namespace rsx std::string root_path = Emu.GetBoot(); root_path = root_path.substr(0, root_path.find_last_of("/")); - auto icon_path = root_path + "../../PIC1.PNG"; + auto icon_path = root_path + "/../PIC1.PNG"; if (!fs::exists(icon_path)) { // Fallback path - icon_path = root_path + "../../ICON0.PNG"; + icon_path = root_path + "/../ICON0.PNG"; } if (fs::exists(icon_path)) @@ -789,10 +789,13 @@ namespace rsx background_image = std::make_unique(icon_path.c_str()); if (background_image->data) { - background.back_color.a = 0.65; + f32 color = (100 - g_cfg.video.shader_preloading_dialog.darkening_strength) / 100.f; + background_poster.fore_color = color4f(color, color, color, 1.); + background.back_color.a = 0.f; background_poster.set_size(1280, 720); background_poster.set_raw_image(background_image.get()); + background_poster.set_blur_strength((u8)g_cfg.video.shader_preloading_dialog.blur_strength); } } } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 716aff274c..9325c64bcb 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1616,7 +1616,7 @@ void VKGSRender::on_init_thread() type.disable_cancel = true; type.progress_bar_count = 2; - dlg = fxm::get()->create(true); + dlg = fxm::get()->create((bool)g_cfg.video.shader_preloading_dialog.use_custom_background); dlg->progress_bar_set_taskbar_index(-1); dlg->show("Loading precompiled shaders from disk...", type, [](s32 status) { diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index b061294c47..0b64178a11 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -437,6 +437,7 @@ namespace vk struct ui_overlay_renderer : public overlay_pass { f32 m_time = 0.f; + f32 m_blur_strength = 0.f; color4f m_scale_offset; color4f m_color; bool m_pulse_glow = false; @@ -463,12 +464,14 @@ namespace vk "layout(location=1) out vec4 color;\n" "layout(location=2) out vec4 parameters;\n" "layout(location=3) out vec4 clip_rect;\n" + "layout(location=4) out vec4 parameters2;\n" "\n" "void main()\n" "{\n" " tc0.xy = in_pos.zw;\n" " color = regs[1];\n" " parameters = regs[2];\n" + " parameters2 = regs[4];\n" " clip_rect = regs[3] * regs[0].zwzw;\n" " vec4 pos = vec4((in_pos.xy * regs[0].zw) / regs[0].xy, 0.5, 1.);\n" " gl_Position = (pos + pos) - 1.;\n" @@ -484,8 +487,58 @@ namespace vk "layout(location=1) in vec4 color;\n" "layout(location=2) in vec4 parameters;\n" "layout(location=3) in vec4 clip_rect;\n" + "layout(location=4) in vec4 parameters2;\n" "layout(location=0) out vec4 ocol;\n" "\n" + "vec4 blur_sample(sampler2D tex, vec2 coord, vec2 tex_offset)\n" + "{\n" + " vec2 coords[9];\n" + " coords[0] = coord - tex_offset\n;" + " coords[1] = coord + vec2(0., -tex_offset.y);\n" + " coords[2] = coord + vec2(tex_offset.x, -tex_offset.y);\n" + " coords[3] = coord + vec2(-tex_offset.x, 0.);\n" + " coords[4] = coord;\n" + " coords[5] = coord + vec2(tex_offset.x, 0.);\n" + " coords[6] = coord + vec2(-tex_offset.x, tex_offset.y);\n" + " coords[7] = coord + vec2(0., tex_offset.y);\n" + " coords[8] = coord + tex_offset;\n" + "\n" + " float weights[9] =\n" + " {\n" + " 1., 2., 1.,\n" + " 2., 4., 2.,\n" + " 1., 2., 1.\n" + " };\n" + "\n" + " vec4 blurred = vec4(0.);\n" + " for (int n = 0; n < 9; ++n)\n" + " {\n" + " blurred += texture(tex, coords[n]) * weights[n];\n" + " }\n" + "\n" + " return blurred / 16.f;\n" + "}\n" + "\n" + "vec4 sample_image(sampler2D tex, vec2 coord, float blur_strength)\n" + "{\n" + " vec4 original = texture(tex, coord);\n" + " if (blur_strength == 0) return original;\n" + " \n" + " vec2 constraints = 1.f / vec2(640, 360);\n" + " vec2 res_offset = 1.f / textureSize(fs0, 0);\n" + " vec2 tex_offset = max(res_offset, constraints);\n" + "\n" + " // Sample triangle pattern and average\n" + " // TODO: Nicer looking gaussian blur with less sampling\n" + " vec4 blur0 = blur_sample(tex, coord + vec2(-res_offset.x, 0.), tex_offset);\n" + " vec4 blur1 = blur_sample(tex, coord + vec2(res_offset.x, 0.), tex_offset);\n" + " vec4 blur2 = blur_sample(tex, coord + vec2(0., res_offset.y), tex_offset);\n" + "\n" + " vec4 blurred = blur0 + blur1 + blur2;\n" + " blurred /= 3.;\n" + " return mix(original, blurred, blur_strength);\n" + "}\n" + "\n" "void main()\n" "{\n" " if (parameters.w != 0)\n" @@ -507,7 +560,7 @@ namespace vk " else if (parameters.z > 1.)\n" " ocol = texture(fs0, tc0).rrrr * diff_color;\n" " else\n" - " ocol = texture(fs0, tc0).bgra * diff_color;\n" + " ocol = sample_image(fs0, tc0, parameters2.x).bgra * diff_color;\n" "}\n" }; @@ -664,6 +717,7 @@ namespace vk dst[13] = m_clip_region.y1; dst[14] = m_clip_region.x2; dst[15] = m_clip_region.y2; + dst[16] = m_blur_strength; m_ubo.unmap(); } @@ -696,6 +750,7 @@ namespace vk m_skip_texture_read = false; m_color = command.config.color; m_pulse_glow = command.config.pulse_glow; + m_blur_strength = f32(command.config.blur_strength) * 0.01f; m_clip_enabled = command.config.clip_region; m_clip_region = command.config.clip_rect; m_texture_type = 1; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index b0021c2f99..76d9bba34f 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -477,6 +477,16 @@ struct cfg_root : cfg::node } shader_compilation_hint{this}; + struct node_shader_preloading_dialog : cfg::node + { + node_shader_preloading_dialog(cfg::node* _this) : cfg::node(_this, "Shader Loading Dialog"){} + + cfg::_bool use_custom_background{this, "Allow custom background", true}; + cfg::_int<0, 100> darkening_strength{this, "Darkening effect strength", 30}; + cfg::_int<0, 100> blur_strength{this, "Blur effect strength", 0}; + + } shader_preloading_dialog{this}; + } video{this}; struct node_audio : cfg::node