Quick tests

This commit is contained in:
CamilleLaVey
2026-09-11 02:15:04 -04:00
parent bbae69f09a
commit 01ca6071c5
5 changed files with 39 additions and 28 deletions
@@ -1189,9 +1189,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
quickSettings.addDivider(container) quickSettings.addDivider(container)
if (::emulationState.isInitialized && emulationState.frameGenAtLaunch && if (LosslessScalingHelper.isInstalled() && LosslessScalingHelper.isSupportedByGpu()) {
LosslessScalingHelper.isInstalled() && LosslessScalingHelper.isSupportedByGpu()
) {
quickSettings.addFrameGen(container) quickSettings.addFrameGen(container)
quickSettings.addDivider(container) quickSettings.addDivider(container)
} }
@@ -2281,10 +2279,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
private var surface: Surface? = null private var surface: Surface? = null
lateinit var emulationThread: Thread lateinit var emulationThread: Thread
@get:Synchronized
var frameGenAtLaunch = false
private set
init { init {
state = State.STOPPED state = State.STOPPED
} }
@@ -2369,7 +2363,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
@Synchronized @Synchronized
fun changeProgram(programIndex: Int) { fun changeProgram(programIndex: Int) {
emulationThread.join() emulationThread.join()
frameGenAtLaunch = BooleanSetting.RENDERER_FRAME_GEN.getBoolean(false)
emulationThread = Thread({ emulationThread = Thread({
Log.debug("[EmulationFragment] Starting emulation thread.") Log.debug("[EmulationFragment] Starting emulation thread.")
NativeLibrary.run(gamePath, programIndex, false) NativeLibrary.run(gamePath, programIndex, false)
@@ -2437,7 +2430,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
when (state) { when (state) {
State.STOPPED -> { State.STOPPED -> {
NativeLibrary.surfaceChanged(currentSurface) NativeLibrary.surfaceChanged(currentSurface)
frameGenAtLaunch = BooleanSetting.RENDERER_FRAME_GEN.getBoolean(false)
emulationThread = Thread({ emulationThread = Thread({
Log.debug("[EmulationFragment] Starting emulation thread.") Log.debug("[EmulationFragment] Starting emulation thread.")
NativeLibrary.run(gamePath, programIndex, true) NativeLibrary.run(gamePath, programIndex, true)
@@ -198,6 +198,10 @@ void FrameGen::Process(const Device& device, Frame* frame, VkFormat format,
VkExtent2D guest_extent) { VkExtent2D guest_extent) {
generated = false; generated = false;
if (!shaders) {
shaders.emplace(device);
}
if (unavailable || !Settings::values.frame_gen.GetValue()) { if (unavailable || !Settings::values.frame_gen.GetValue()) {
if (chain) { if (chain) {
scheduler.Finish(); scheduler.Finish();
@@ -207,17 +211,14 @@ void FrameGen::Process(const Device& device, Frame* frame, VkFormat format,
return; return;
} }
if (!frame->storage_view) { if (!shaders->IsValid()) {
unavailable = true; unavailable = true;
return; return;
} }
if (!shaders) { if (!frame->storage_view) {
shaders.emplace(device); warm_streak = 0;
if (!shaders->IsValid()) { return;
unavailable = true;
return;
}
} }
peak_guest_extent.width = std::max(peak_guest_extent.width, guest_extent.width); peak_guest_extent.width = std::max(peak_guest_extent.width, guest_extent.width);
@@ -8,6 +8,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include "common/settings.h"
#include "video_core/framebuffer_config.h" #include "video_core/framebuffer_config.h"
#include "video_core/present.h" #include "video_core/present.h"
#include "video_core/renderer_vulkan/present/filters.h" #include "video_core/renderer_vulkan/present/filters.h"
@@ -87,13 +88,18 @@ void BlitScreen::SetWindowAdaptPass(const Device& device) {
void BlitScreen::PrepareFrame(const Device& device, Frame* frame, void BlitScreen::PrepareFrame(const Device& device, Frame* frame,
const Layout::FramebufferLayout& layout) { const Layout::FramebufferLayout& layout) {
if (!window_adapt || (frame->width == layout.width && frame->height == layout.height)) { if (!window_adapt) {
return;
}
if (frame->width != layout.width || frame->height != layout.height) {
WaitIdle(device);
} else if (!present_manager.NeedsStorage(frame, true)) {
return; return;
} }
WaitIdle(device);
present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format, present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format,
window_adapt->GetRenderPass()); window_adapt->GetRenderPass(), true);
} }
void BlitScreen::DrawToFrame(const Device& device, RasterizerVulkan& rasterizer, Frame* frame, void BlitScreen::DrawToFrame(const Device& device, RasterizerVulkan& rasterizer, Frame* frame,
@@ -120,16 +126,20 @@ void BlitScreen::DrawToFrame(const Device& device, RasterizerVulkan& rasterizer,
swapchain_view_format = current_swapchain_view_format; swapchain_view_format = current_swapchain_view_format;
} }
const bool storage_required = Settings::values.frame_gen.GetValue();
if (resource_update_required) { if (resource_update_required) {
WaitIdle(device); WaitIdle(device);
SetWindowAdaptPass(device); SetWindowAdaptPass(device);
if (presentation_recreate_required) { if (presentation_recreate_required) {
present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format, present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format,
window_adapt->GetRenderPass()); window_adapt->GetRenderPass(), storage_required);
} }
image_index = 0; image_index = 0;
} else if (present_manager.NeedsStorage(frame, storage_required)) {
present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format,
window_adapt->GetRenderPass(), true);
} }
const VkExtent2D window_size{ const VkExtent2D window_size{
@@ -29,9 +29,6 @@ static_assert(MAX_FRAMES_IN_FLIGHT <= LSFG_MAX_TARGETS);
bool CanStoreToFrame(const vk::PhysicalDevice& physical_device, VkFormat format) { bool CanStoreToFrame(const vk::PhysicalDevice& physical_device, VkFormat format) {
#ifdef HAS_LSFG #ifdef HAS_LSFG
if (!Settings::values.frame_gen.GetValue()) {
return false;
}
const VkFormatProperties props{physical_device.GetFormatProperties(format)}; const VkFormatProperties props{physical_device.GetFormatProperties(format)};
return (props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0; return (props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0;
#else #else
@@ -160,6 +157,7 @@ PresentManager::PresentManager(const vk::Instance& instance_,
.pNext = nullptr, .pNext = nullptr,
.flags = VK_FENCE_CREATE_SIGNALED_BIT, .flags = VK_FENCE_CREATE_SIGNALED_BIT,
}); });
frame.storage_capable = storage_supported;
free_queue.push_back(&frame); free_queue.push_back(&frame);
} }
@@ -205,15 +203,22 @@ size_t PresentManager::MaxExtraFrames() const {
return image_count - 1; return image_count - 1;
} }
bool PresentManager::NeedsStorage(const Frame* frame, bool required) const {
return required && frame->storage_capable && !frame->storage_view;
}
void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat image_view_format, void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat image_view_format,
VkRenderPass rd) { VkRenderPass rd, bool storage) {
auto& dld = device.GetLogical(); auto& dld = device.GetLogical();
frame->width = width; frame->width = width;
frame->height = height; frame->height = height;
const VkImageUsageFlags storage_usage = const bool with_storage = storage && frame->storage_capable;
storage_supported ? static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_STORAGE_BIT) : 0; VkImageUsageFlags storage_usage = 0;
if (with_storage) {
storage_usage = VK_IMAGE_USAGE_STORAGE_BIT;
}
frame->image = memory_allocator.CreateImage({ frame->image = memory_allocator.CreateImage({
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -264,7 +269,7 @@ void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat
}); });
frame->storage_view = vk::ImageView{}; frame->storage_view = vk::ImageView{};
if (storage_supported) { if (with_storage) {
frame->storage_view = dld.CreateImageView({ frame->storage_view = dld.CreateImageView({
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
@@ -36,6 +36,7 @@ struct Frame {
vk::CommandBuffer cmdbuf; vk::CommandBuffer cmdbuf;
vk::Semaphore render_ready; vk::Semaphore render_ready;
vk::Fence present_done; vk::Fence present_done;
bool storage_capable{};
}; };
class PresentManager { class PresentManager {
@@ -57,7 +58,9 @@ public:
/// Recreates the present frame to match the provided parameters /// Recreates the present frame to match the provided parameters
void RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat image_view_format, void RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat image_view_format,
VkRenderPass rd); VkRenderPass rd, bool storage);
[[nodiscard]] bool NeedsStorage(const Frame* frame, bool required) const;
/// Waits for the present thread to finish presenting all queued frames. /// Waits for the present thread to finish presenting all queued frames.
void WaitPresent(); void WaitPresent();