Merge pull request #2377 from brooksytech/dev

S922X: Fix citra & set GC, PS2, & 3DS to perf mode by default
This commit is contained in:
Brooksytech 2023-11-15 09:49:17 -08:00 committed by GitHub
commit 18e4db9625
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 340 additions and 1 deletions

View file

@ -0,0 +1,339 @@
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index ca2289b79..83dd77594 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -686,9 +686,9 @@ void GRenderWindow::CaptureScreenshot(u32 res_scale, const QString& screenshot_p
screenshot_image = QImage(QSize(layout.width, layout.height), QImage::Format_RGB32);
system.Renderer().RequestScreenshot(
screenshot_image.bits(),
- [this, screenshot_path](bool invert_y) {
+ [this, screenshot_path] {
const std::string std_screenshot_path = screenshot_path.toStdString();
- if (screenshot_image.mirrored(false, invert_y).save(screenshot_path)) {
+ if (screenshot_image.mirrored(false, true).save(screenshot_path)) {
LOG_INFO(Frontend, "Screenshot saved to \"{}\"", std_screenshot_path);
} else {
LOG_ERROR(Frontend, "Failed to save screenshot to \"{}\"", std_screenshot_path);
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp
index 112d95436..79986592b 100644
--- a/src/video_core/renderer_base.cpp
+++ b/src/video_core/renderer_base.cpp
@@ -59,7 +59,7 @@ bool RendererBase::IsScreenshotPending() const {
return settings.screenshot_requested;
}
-void RendererBase::RequestScreenshot(void* data, std::function<void(bool)> callback,
+void RendererBase::RequestScreenshot(void* data, std::function<void()> callback,
const Layout::FramebufferLayout& layout) {
if (settings.screenshot_requested) {
LOG_ERROR(Render, "A screenshot is already requested or in progress, ignoring the request");
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h
index 55cb90d0b..d6958ec1e 100644
--- a/src/video_core/renderer_base.h
+++ b/src/video_core/renderer_base.h
@@ -28,7 +28,7 @@ struct RendererSettings {
// Screenshot
std::atomic_bool screenshot_requested{false};
void* screenshot_bits{};
- std::function<void(bool)> screenshot_complete_callback;
+ std::function<void()> screenshot_complete_callback;
Layout::FramebufferLayout screenshot_framebuffer_layout;
// Renderer
std::atomic_bool bg_color_update_requested{false};
@@ -103,7 +103,7 @@ public:
[[nodiscard]] bool IsScreenshotPending() const;
/// Request a screenshot of the next frame
- void RequestScreenshot(void* data, std::function<void(bool)> callback,
+ void RequestScreenshot(void* data, std::function<void()> callback,
const Layout::FramebufferLayout& layout);
protected:
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index c58f07a2c..f94109378 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -151,7 +151,7 @@ void RendererOpenGL::RenderScreenshot() {
state.Apply();
glDeleteRenderbuffers(1, &renderbuffer);
- settings.screenshot_complete_callback(true);
+ settings.screenshot_complete_callback();
}
}
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 5986b3b7e..7c82b8bcc 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -6,7 +6,6 @@
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/settings.h"
-#include "common/texture.h"
#include "core/core.h"
#include "core/frontend/emu_window.h"
#include "core/hw/gpu.h"
@@ -19,7 +18,6 @@
#include "video_core/host_shaders/vulkan_present_frag_spv.h"
#include "video_core/host_shaders/vulkan_present_interlaced_frag_spv.h"
#include "video_core/host_shaders/vulkan_present_vert_spv.h"
-#include "vulkan/vulkan_format_traits.hpp"
#include <vk_mem_alloc.h>
@@ -869,9 +867,20 @@ void RendererVulkan::RenderScreenshot() {
const u32 width = layout.width;
const u32 height = layout.height;
- const vk::BufferCreateInfo staging_buffer_info = {
- .size = width * height * 4,
- .usage = vk::BufferUsageFlagBits::eTransferDst,
+ const vk::ImageCreateInfo staging_image_info = {
+ .imageType = vk::ImageType::e2D,
+ .format = vk::Format::eB8G8R8A8Unorm,
+ .extent{
+ .width = width,
+ .height = height,
+ .depth = 1,
+ },
+ .mipLevels = 1,
+ .arrayLayers = 1,
+ .samples = vk::SampleCountFlagBits::e1,
+ .tiling = vk::ImageTiling::eLinear,
+ .usage = vk::ImageUsageFlagBits::eTransferDst,
+ .initialLayout = vk::ImageLayout::eUndefined,
};
const VmaAllocationCreateInfo alloc_create_info = {
@@ -884,18 +893,18 @@ void RendererVulkan::RenderScreenshot() {
.pUserData = nullptr,
};
- VkBuffer unsafe_buffer{};
+ VkImage unsafe_image{};
VmaAllocation allocation{};
VmaAllocationInfo alloc_info;
- VkBufferCreateInfo unsafe_buffer_info = static_cast<VkBufferCreateInfo>(staging_buffer_info);
+ VkImageCreateInfo unsafe_image_info = static_cast<VkImageCreateInfo>(staging_image_info);
- VkResult result = vmaCreateBuffer(instance.GetAllocator(), &unsafe_buffer_info,
- &alloc_create_info, &unsafe_buffer, &allocation, &alloc_info);
+ VkResult result = vmaCreateImage(instance.GetAllocator(), &unsafe_image_info,
+ &alloc_create_info, &unsafe_image, &allocation, &alloc_info);
if (result != VK_SUCCESS) [[unlikely]] {
LOG_CRITICAL(Render_Vulkan, "Failed allocating texture with error {}", result);
UNREACHABLE();
}
- vk::Buffer staging_buffer{unsafe_buffer};
+ vk::Image staging_image{unsafe_image};
Frame frame{};
main_window.RecreateFrame(&frame, width, height);
@@ -903,37 +912,73 @@ void RendererVulkan::RenderScreenshot() {
DrawScreens(&frame, layout, false);
scheduler.Record(
- [width, height, source_image = frame.image, staging_buffer](vk::CommandBuffer cmdbuf) {
- const vk::ImageMemoryBarrier read_barrier = {
- .srcAccessMask = vk::AccessFlagBits::eMemoryWrite,
- .dstAccessMask = vk::AccessFlagBits::eTransferRead,
- .oldLayout = vk::ImageLayout::eTransferSrcOptimal,
- .newLayout = vk::ImageLayout::eTransferSrcOptimal,
- .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .image = source_image,
- .subresourceRange{
- .aspectMask = vk::ImageAspectFlagBits::eColor,
- .baseMipLevel = 0,
- .levelCount = VK_REMAINING_MIP_LEVELS,
- .baseArrayLayer = 0,
- .layerCount = VK_REMAINING_ARRAY_LAYERS,
+ [width, height, source_image = frame.image, staging_image](vk::CommandBuffer cmdbuf) {
+ const std::array read_barriers = {
+ vk::ImageMemoryBarrier{
+ .srcAccessMask = vk::AccessFlagBits::eMemoryWrite,
+ .dstAccessMask = vk::AccessFlagBits::eTransferRead,
+ .oldLayout = vk::ImageLayout::eTransferSrcOptimal,
+ .newLayout = vk::ImageLayout::eTransferSrcOptimal,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = source_image,
+ .subresourceRange{
+ .aspectMask = vk::ImageAspectFlagBits::eColor,
+ .baseMipLevel = 0,
+ .levelCount = VK_REMAINING_MIP_LEVELS,
+ .baseArrayLayer = 0,
+ .layerCount = VK_REMAINING_ARRAY_LAYERS,
+ },
+ },
+ vk::ImageMemoryBarrier{
+ .srcAccessMask = vk::AccessFlagBits::eNone,
+ .dstAccessMask = vk::AccessFlagBits::eTransferWrite,
+ .oldLayout = vk::ImageLayout::eUndefined,
+ .newLayout = vk::ImageLayout::eTransferDstOptimal,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = staging_image,
+ .subresourceRange{
+ .aspectMask = vk::ImageAspectFlagBits::eColor,
+ .baseMipLevel = 0,
+ .levelCount = VK_REMAINING_MIP_LEVELS,
+ .baseArrayLayer = 0,
+ .layerCount = VK_REMAINING_ARRAY_LAYERS,
+ },
},
};
- const vk::ImageMemoryBarrier write_barrier = {
- .srcAccessMask = vk::AccessFlagBits::eTransferRead,
- .dstAccessMask = vk::AccessFlagBits::eMemoryWrite,
- .oldLayout = vk::ImageLayout::eTransferSrcOptimal,
- .newLayout = vk::ImageLayout::eTransferSrcOptimal,
- .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .image = source_image,
- .subresourceRange{
- .aspectMask = vk::ImageAspectFlagBits::eColor,
- .baseMipLevel = 0,
- .levelCount = VK_REMAINING_MIP_LEVELS,
- .baseArrayLayer = 0,
- .layerCount = VK_REMAINING_ARRAY_LAYERS,
+ const std::array write_barriers = {
+ vk::ImageMemoryBarrier{
+ .srcAccessMask = vk::AccessFlagBits::eTransferRead,
+ .dstAccessMask = vk::AccessFlagBits::eMemoryWrite,
+ .oldLayout = vk::ImageLayout::eTransferSrcOptimal,
+ .newLayout = vk::ImageLayout::eTransferSrcOptimal,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = source_image,
+ .subresourceRange{
+ .aspectMask = vk::ImageAspectFlagBits::eColor,
+ .baseMipLevel = 0,
+ .levelCount = VK_REMAINING_MIP_LEVELS,
+ .baseArrayLayer = 0,
+ .layerCount = VK_REMAINING_ARRAY_LAYERS,
+ },
+ },
+ vk::ImageMemoryBarrier{
+ .srcAccessMask = vk::AccessFlagBits::eTransferWrite,
+ .dstAccessMask = vk::AccessFlagBits::eMemoryRead,
+ .oldLayout = vk::ImageLayout::eTransferDstOptimal,
+ .newLayout = vk::ImageLayout::eGeneral,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = staging_image,
+ .subresourceRange{
+ .aspectMask = vk::ImageAspectFlagBits::eColor,
+ .baseMipLevel = 0,
+ .levelCount = VK_REMAINING_MIP_LEVELS,
+ .baseArrayLayer = 0,
+ .layerCount = VK_REMAINING_ARRAY_LAYERS,
+ },
},
};
static constexpr vk::MemoryBarrier memory_write_barrier = {
@@ -941,29 +986,41 @@ void RendererVulkan::RenderScreenshot() {
.dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite,
};
- const vk::BufferImageCopy image_copy = {
- .bufferOffset = 0,
- .bufferRowLength = 0,
- .bufferImageHeight = 0,
- .imageSubresource =
- {
- .aspectMask = vk::ImageAspectFlagBits::eColor,
- .mipLevel = 0,
- .baseArrayLayer = 0,
- .layerCount = 1,
- },
- .imageOffset = {0, 0, 0},
- .imageExtent = {width, height, 1},
+ const std::array src_offsets = {
+ vk::Offset3D{0, 0, 0},
+ vk::Offset3D{static_cast<s32>(width), static_cast<s32>(height), 1},
+ };
+
+ const std::array dst_offsets = {
+ vk::Offset3D{0, static_cast<s32>(height), 0},
+ vk::Offset3D{static_cast<s32>(width), 0, 1},
+ };
+
+ const vk::ImageBlit blit_area = {
+ .srcSubresource{
+ .aspectMask = vk::ImageAspectFlagBits::eColor,
+ .mipLevel = 0,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ },
+ .srcOffsets = src_offsets,
+ .dstSubresource{
+ .aspectMask = vk::ImageAspectFlagBits::eColor,
+ .mipLevel = 0,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ },
+ .dstOffsets = dst_offsets,
};
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eTransfer,
- vk::DependencyFlagBits::eByRegion, {}, {}, read_barrier);
- cmdbuf.copyImageToBuffer(source_image, vk::ImageLayout::eTransferSrcOptimal,
- staging_buffer, image_copy);
+ vk::DependencyFlagBits::eByRegion, {}, {}, read_barriers);
+ cmdbuf.blitImage(source_image, vk::ImageLayout::eTransferSrcOptimal, staging_image,
+ vk::ImageLayout::eTransferDstOptimal, blit_area, vk::Filter::eNearest);
cmdbuf.pipelineBarrier(
vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eAllCommands,
- vk::DependencyFlagBits::eByRegion, memory_write_barrier, {}, write_barrier);
+ vk::DependencyFlagBits::eByRegion, memory_write_barrier, {}, write_barriers);
});
// Ensure the copy is fully completed before saving the screenshot
@@ -971,16 +1028,27 @@ void RendererVulkan::RenderScreenshot() {
const vk::Device device = instance.GetDevice();
+ // Get layout of the image (including row pitch)
+ const vk::ImageSubresource subresource = {
+ .aspectMask = vk::ImageAspectFlagBits::eColor,
+ .mipLevel = 0,
+ .arrayLayer = 0,
+ };
+
+ const vk::SubresourceLayout subresource_layout =
+ device.getImageSubresourceLayout(staging_image, subresource);
+
// Copy backing image data to the QImage screenshot buffer
- std::memcpy(settings.screenshot_bits, alloc_info.pMappedData, staging_buffer_info.size);
+ const u8* data = reinterpret_cast<const u8*>(alloc_info.pMappedData);
+ std::memcpy(settings.screenshot_bits, data + subresource_layout.offset,
+ subresource_layout.size);
// Destroy allocated resources
- vmaDestroyBuffer(instance.GetAllocator(), unsafe_buffer, allocation);
vmaDestroyImage(instance.GetAllocator(), frame.image, frame.allocation);
device.destroyFramebuffer(frame.framebuffer);
device.destroyImageView(frame.image_view);
- settings.screenshot_complete_callback(false);
+ settings.screenshot_complete_callback();
}
} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index ee83e0378..260839c8f 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -150,7 +150,8 @@ void Swapchain::FindPresentFormat() {
return;
}
- UNREACHABLE_MSG("Unable to find required swapchain format!");
+ LOG_CRITICAL(Render_Vulkan, "Unable to find required swapchain format!");
+ UNREACHABLE();
}
void Swapchain::SetPresentMode() {

View file

@ -5,7 +5,7 @@
. /etc/profile.d/001-functions
### Set the default performance scaling mode for a few systems.
for SYSTEM in dreamcast n64 psp saturn
for SYSTEM in 3ds dreamcast gamecube n64 ps2 psp saturn
do
SETTING=$(get_setting ${SYSTEM})
if [ -z ${SETTING} ]