Add progress indicator when loading a file in case user reads from a server and not a local disk

This commit is contained in:
IrisZ64
2025-12-17 21:51:48 +01:00
parent b89ff3d212
commit f870d8f979
9 changed files with 196 additions and 102 deletions

View File

@@ -6,14 +6,13 @@
#include <resources/frag.spv.h>
#include <KaizenGui.hpp>
#include <imgui_impl_vulkan.h>
#include <mutex>
using namespace Vulkan;
using namespace RDP;
bool ParallelRDP::IsFramerateUnlocked() const { return wsi->get_present_mode() != PresentMode::SyncToVBlank; }
void ParallelRDP::SetFramerateUnlocked(bool unlocked) const {
void ParallelRDP::SetFramerateUnlocked(const bool unlocked) const {
if (unlocked) {
wsi->set_present_mode(PresentMode::UnlockedForceTearing);
} else {
@@ -24,11 +23,11 @@ void ParallelRDP::SetFramerateUnlocked(bool unlocked) const {
Program *fullscreen_quad_program;
// Copied and modified from WSI::init_context_from_platform
Util::IntrusivePtr<Context> InitVulkanContext(WSIPlatform *platform, unsigned num_thread_indices,
Util::IntrusivePtr<Context> InitVulkanContext(WSIPlatform *platform, const unsigned num_thread_indices,
const Context::SystemHandles &system_handles) {
VK_ASSERT(platform);
auto instance_ext = platform->get_instance_extensions();
auto device_ext = platform->get_device_extensions();
const auto instance_ext = platform->get_instance_extensions();
const auto device_ext = platform->get_device_extensions();
auto new_context = Util::make_handle<Context>();
new_context->set_application_info(platform->get_application_info());
@@ -39,9 +38,9 @@ Util::IntrusivePtr<Context> InitVulkanContext(WSIPlatform *platform, unsigned nu
panic("Failed to create Vulkan instance.\n");
}
VkSurfaceKHR tmp_surface = platform->create_surface(new_context->get_instance(), VK_NULL_HANDLE);
const auto tmp_surface = platform->create_surface(new_context->get_instance(), VK_NULL_HANDLE);
bool ret = new_context->init_device(VK_NULL_HANDLE, tmp_surface, device_ext.data(), device_ext.size(),
const bool ret = new_context->init_device(VK_NULL_HANDLE, tmp_surface, device_ext.data(), device_ext.size(),
CONTEXT_CREATION_ENABLE_ADVANCED_WSI_BIT);
if (tmp_surface) {
@@ -61,9 +60,9 @@ void ParallelRDP::LoadWSIPlatform(const std::shared_ptr<WSIPlatform> &wsi_platfo
wsi->set_backbuffer_srgb(false);
wsi->set_platform(wsi_platform.get());
wsi->set_present_mode(PresentMode::SyncToVBlank);
Context::SystemHandles handles;
if (!wsi->init_from_existing_context(InitVulkanContext(wsi_platform.get(), 1, handles))) {
if (constexpr Context::SystemHandles handles;
!wsi->init_from_existing_context(InitVulkanContext(wsi_platform.get(), 1, handles))) {
panic("Failed to initialize WSI: init_from_existing_context() failed");
}
@@ -97,8 +96,8 @@ void ParallelRDP::Init(const std::shared_ptr<WSIPlatform> &wsiPlatform,
fragLayout.sets[0].fp_mask = 1;
fragLayout.sets[0].array_size[0] = 1;
auto sizeVert = sizeof(vertex_shader);
auto sizeFrag = sizeof(fragment_shader);
constexpr auto sizeVert = sizeof(vertex_shader);
constexpr auto sizeFrag = sizeof(fragment_shader);
fullscreen_quad_program = wsi->get_device().request_program(
reinterpret_cast<const u32 *>(vertex_shader), sizeVert, reinterpret_cast<const u32 *>(fragment_shader),
@@ -108,8 +107,8 @@ void ParallelRDP::Init(const std::shared_ptr<WSIPlatform> &wsiPlatform,
uintptr_t offset = 0;
if (wsi->get_device().get_device_features().supports_external_memory_host) {
size_t align = wsi->get_device().get_device_features().host_memory_properties.minImportedHostPointerAlignment;
offset = aligned_rdram & (align - 1);
const size_t align = wsi->get_device().get_device_features().host_memory_properties.minImportedHostPointerAlignment;
offset = aligned_rdram & align - 1;
aligned_rdram -= offset;
}
@@ -128,7 +127,7 @@ void ParallelRDP::DrawFullscreenTexturedQuad(Util::IntrusivePtr<Image> image,
cmd->set_texture(0, 0, image->get_view(), StockSampler::LinearClamp);
cmd->set_program(fullscreen_quad_program);
cmd->set_quad_state();
auto data = static_cast<float *>(cmd->allocate_vertex_data(0, 6 * sizeof(float), 2 * sizeof(float)));
const auto data = static_cast<float *>(cmd->allocate_vertex_data(0, 6 * sizeof(float), 2 * sizeof(float)));
data[0] = -1.0f;
data[1] = -3.0f;
data[2] = -1.0f;
@@ -136,15 +135,15 @@ void ParallelRDP::DrawFullscreenTexturedQuad(Util::IntrusivePtr<Image> image,
data[4] = +3.0f;
data[5] = +1.0f;
auto windowSize = windowInfo->get_window_size();
const auto [x, y] = windowInfo->get_window_size();
float zoom = std::min(windowSize.x / wsi->get_platform().get_surface_width(),
windowSize.y / wsi->get_platform().get_surface_height());
const float zoom = std::min(x / static_cast<float>(wsi->get_platform().get_surface_width()),
y / static_cast<float>(wsi->get_platform().get_surface_height()));
float width = (wsi->get_platform().get_surface_width() / windowSize.x) * zoom;
float height = (wsi->get_platform().get_surface_height() / windowSize.y) * zoom;
const float width = static_cast<float>(wsi->get_platform().get_surface_width()) / x * zoom;
const float height = static_cast<float>(wsi->get_platform().get_surface_height()) / y * zoom;
float uniform_data[] = {// Size
const float uniform_data[] = {// Size
width, height,
// Offset
(1.0f - width) * 0.5f, (1.0f - height) * 0.5f};
@@ -190,43 +189,43 @@ void ParallelRDP::UpdateScreen(Util::IntrusivePtr<Image> image) const {
wsi->end_frame();
}
void ParallelRDP::UpdateScreen(bool playing) const {
if(playing) {
n64::Core& core = n64::Core::GetInstance();
n64::VI& vi = core.GetMem().mmio.vi;
command_processor->set_vi_register(VIRegister::Control, vi.status.raw);
command_processor->set_vi_register(VIRegister::Origin, vi.origin);
command_processor->set_vi_register(VIRegister::Width, vi.width);
command_processor->set_vi_register(VIRegister::Intr, vi.intr);
command_processor->set_vi_register(VIRegister::VCurrentLine, vi.current);
command_processor->set_vi_register(VIRegister::Timing, vi.burst.raw);
command_processor->set_vi_register(VIRegister::VSync, vi.vsync);
command_processor->set_vi_register(VIRegister::HSync, vi.hsync);
command_processor->set_vi_register(VIRegister::Leap, vi.hsyncLeap.raw);
command_processor->set_vi_register(VIRegister::HStart, vi.hstart.raw);
command_processor->set_vi_register(VIRegister::VStart, vi.vstart.raw);
command_processor->set_vi_register(VIRegister::VBurst, vi.vburst);
command_processor->set_vi_register(VIRegister::XScale, vi.xscale.raw);
command_processor->set_vi_register(VIRegister::YScale, vi.yscale.raw);
ScanoutOptions opts;
opts.persist_frame_on_invalid_input = true;
opts.vi.aa = true;
opts.vi.scale = true;
opts.vi.dither_filter = true;
opts.vi.divot_filter = true;
opts.vi.gamma_dither = true;
opts.downscale_steps = true;
opts.crop_overscan_pixels = true;
Util::IntrusivePtr<Image> image = command_processor->scanout(opts);
UpdateScreen(image);
command_processor->begin_frame_context();
return;
}
template <>
void ParallelRDP::UpdateScreen<true>() const {
const n64::VI& vi = n64::Core::GetMem().mmio.vi;
command_processor->set_vi_register(VIRegister::Control, vi.status.raw);
command_processor->set_vi_register(VIRegister::Origin, vi.origin);
command_processor->set_vi_register(VIRegister::Width, vi.width);
command_processor->set_vi_register(VIRegister::Intr, vi.intr);
command_processor->set_vi_register(VIRegister::VCurrentLine, vi.current);
command_processor->set_vi_register(VIRegister::Timing, vi.burst.raw);
command_processor->set_vi_register(VIRegister::VSync, vi.vsync);
command_processor->set_vi_register(VIRegister::HSync, vi.hsync);
command_processor->set_vi_register(VIRegister::Leap, vi.hsyncLeap.raw);
command_processor->set_vi_register(VIRegister::HStart, vi.hstart.raw);
command_processor->set_vi_register(VIRegister::VStart, vi.vstart.raw);
command_processor->set_vi_register(VIRegister::VBurst, vi.vburst);
command_processor->set_vi_register(VIRegister::XScale, vi.xscale.raw);
command_processor->set_vi_register(VIRegister::YScale, vi.yscale.raw);
ScanoutOptions opts;
opts.persist_frame_on_invalid_input = true;
opts.vi.aa = true;
opts.vi.scale = true;
opts.vi.dither_filter = true;
opts.vi.divot_filter = true;
opts.vi.gamma_dither = true;
opts.downscale_steps = true;
opts.crop_overscan_pixels = true;
const Util::IntrusivePtr<Image> image = command_processor->scanout(opts);
UpdateScreen(image);
command_processor->begin_frame_context();
}
template <>
void ParallelRDP::UpdateScreen<false>() const {
UpdateScreen(static_cast<Util::IntrusivePtr<Image>>(nullptr));
}
void ParallelRDP::EnqueueCommand(int command_length, const u32 *buffer) const {
void ParallelRDP::EnqueueCommand(const int command_length, const u32 *buffer) const {
command_processor->enqueue_command(command_length, buffer);
}

View File

@@ -17,11 +17,12 @@ public:
void Init(const std::shared_ptr<Vulkan::WSIPlatform> &,
const std::shared_ptr<WindowInfo> &, const u8 *);
void UpdateScreen(bool = true) const;
template <bool>
void UpdateScreen() const;
void EnqueueCommand(int, const u32 *) const;
void OnFullSync() const;
bool IsFramerateUnlocked() const;
[[nodiscard]] bool IsFramerateUnlocked() const;
void SetFramerateUnlocked(bool) const;
std::shared_ptr<Vulkan::WSI> wsi;