From 7d5a72c9e08e5bb3ec47382a6513eb61cfc1d765 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 8 Mar 2021 20:47:37 +0300 Subject: [PATCH] vk: Add options to system configuration --- rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp | 20 +++++++++++++------- rpcs3/Emu/RSX/VK/VKAsyncScheduler.h | 3 +++ rpcs3/Emu/RSX/VK/VKDMA.cpp | 13 ++++++++++--- rpcs3/Emu/RSX/VK/VKTextureCache.h | 5 ++++- rpcs3/Emu/system_config.h | 2 ++ rpcs3/Emu/system_config_types.cpp | 15 +++++++++++++++ rpcs3/Emu/system_config_types.h | 6 ++++++ 7 files changed, 53 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp b/rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp index 150c23184d..47722c1b8f 100644 --- a/rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp +++ b/rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp @@ -8,13 +8,18 @@ #include -#define WITH_CPU_SCHEDULER 1 - namespace vk { void AsyncTaskScheduler::operator()() { -#if WITH_CPU_SCHEDULER + if (!m_use_host_scheduler) + { + // No need to keep the GPU alive using a CPU thread. + return; + } + + // If this thread is unavailable for too long, your GPU will hard crash and force a full reset + // TODO: Investigate if this can be executed outside the application context. Attach a debugger to rpcs3 and boom - GPU reset. Not fun rebooting so often. thread_ctrl::set_native_priority(1); add_ref(); @@ -29,7 +34,6 @@ namespace vk } release(); -#endif } void AsyncTaskScheduler::delayed_init() @@ -43,6 +47,9 @@ namespace vk auto ev2 = std::make_unique(*get_current_renderer(), sync_domain::gpu); m_events_pool.emplace_back(std::move(ev1), std::move(ev2), 0ull); } + + m_use_host_scheduler = g_cfg.video.vk.asynchronous_scheduler == vk_gpu_scheduler_mode::host || g_cfg.video.strict_rendering_mode; + rsx_log.notice("Asynchronous task scheduler is active running in %s mode", m_use_host_scheduler? "'Host'" : "'Device'"); } void AsyncTaskScheduler::insert_sync_event() @@ -67,16 +74,15 @@ namespace vk sync_label->queue1_signal->signal(*m_current_cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0); -#if WITH_CPU_SCHEDULER + if (m_use_host_scheduler) { m_event_queue.push(sync_label); m_sync_label = sync_label->queue2_signal.get(); } -#else + else { m_sync_label = sync_label->queue1_signal.get(); } -#endif } AsyncTaskScheduler::~AsyncTaskScheduler() diff --git a/rpcs3/Emu/RSX/VK/VKAsyncScheduler.h b/rpcs3/Emu/RSX/VK/VKAsyncScheduler.h index e01cff797c..7d5f004435 100644 --- a/rpcs3/Emu/RSX/VK/VKAsyncScheduler.h +++ b/rpcs3/Emu/RSX/VK/VKAsyncScheduler.h @@ -27,6 +27,9 @@ namespace vk command_buffer* m_current_cb = nullptr; usz m_next_cb_index = 0; + // Scheduler + bool m_use_host_scheduler = false; + // Sync event* m_sync_label = nullptr; atomic_t m_sync_required = false; diff --git a/rpcs3/Emu/RSX/VK/VKDMA.cpp b/rpcs3/Emu/RSX/VK/VKDMA.cpp index 18f1127639..95499c59da 100644 --- a/rpcs3/Emu/RSX/VK/VKDMA.cpp +++ b/rpcs3/Emu/RSX/VK/VKDMA.cpp @@ -262,9 +262,16 @@ namespace vk bool allow_host_buffers; if (vendor == driver_vendor::NVIDIA) { - allow_host_buffers = (chip != chip_class::NV_mobile_kepler) ? - test_host_pointer(base_address, expected_length) : - false; + if (g_cfg.video.vk.asynchronous_texture_streaming) + { + allow_host_buffers = (chip != chip_class::NV_mobile_kepler) ? + test_host_pointer(base_address, expected_length) : + false; + } + else + { + allow_host_buffers = false; + } } else { diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index b64680671a..62cf3dca70 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -935,8 +935,11 @@ namespace vk input_swizzled = false; } + rsx::flags32_t upload_command_flags = initialize_image_layout | + (g_cfg.video.vk.asynchronous_texture_streaming? upload_contents_async : upload_contents_inline); + vk::upload_image(cmd, image, subresource_layout, gcm_format, input_swizzled, mipmaps, image->aspect(), - *m_texture_upload_heap, upload_heap_align_default, initialize_image_layout | upload_contents_async); + *m_texture_upload_heap, upload_heap_align_default, upload_command_flags); vk::leave_uninterruptible(); diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index bfbfb67e56..cec1db15d7 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -168,6 +168,8 @@ struct cfg_root : cfg::node cfg::_bool force_fifo{ this, "Force FIFO present mode" }; cfg::_bool force_primitive_restart{ this, "Force primitive restart flag" }; cfg::_bool force_disable_exclusive_fullscreen_mode{this, "Force Disable Exclusive Fullscreen Mode"}; + cfg::_bool asynchronous_texture_streaming{ this, "Asynchronous Texture Streaming Placeholder", false, true }; // Placeholder text because it'll have to be updated later + cfg::_enum asynchronous_scheduler{ this, "Asynchronous Queue Scheduler", vk_gpu_scheduler_mode::device }; } vk{ this }; diff --git a/rpcs3/Emu/system_config_types.cpp b/rpcs3/Emu/system_config_types.cpp index 7e3154e3c3..360aa0bdbb 100644 --- a/rpcs3/Emu/system_config_types.cpp +++ b/rpcs3/Emu/system_config_types.cpp @@ -421,3 +421,18 @@ void fmt_class_string::format(std::string& out, u64 arg) return unknown; }); } + +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](vk_gpu_scheduler_mode value) + { + switch (value) + { + case vk_gpu_scheduler_mode::host: return "Host"; + case vk_gpu_scheduler_mode::device: return "Device"; + } + + return unknown; + }); +} diff --git a/rpcs3/Emu/system_config_types.h b/rpcs3/Emu/system_config_types.h index c0acf82d44..57c924e35c 100644 --- a/rpcs3/Emu/system_config_types.h +++ b/rpcs3/Emu/system_config_types.h @@ -195,3 +195,9 @@ enum class shader_mode async_with_interpreter, interpreter_only }; + +enum class vk_gpu_scheduler_mode +{ + host, + device +};