Compare commits

...

23 Commits

Author SHA1 Message Date
yuzubot
9ffb91e8f4 Android #94 2023-10-08 00:57:47 +00:00
liamwhite
bd42bba71c Merge pull request #11656 from liamwhite/recreate-surface-automatically
vk_present_manager: recreate surface on any surface loss
2023-10-07 12:49:54 -04:00
liamwhite
a27f94830a Merge pull request #11677 from Squall-Leonhart/D32FTOABGR8
Implements D32_Float to A8B8G8R8_UNORM format copy
2023-10-07 12:49:48 -04:00
liamwhite
bd6f9f1d91 Merge pull request #11630 from Kelebek1/clear_stencil_requires_depth_test
Enable depth test on depthstencil clear path
2023-10-07 12:49:37 -04:00
liamwhite
bf15aa093c Merge pull request #11639 from liamwhite/no-program-id-change
loader: don't reassign program ID on npdm reparse
2023-10-07 12:49:32 -04:00
liamwhite
0e9b839b6f Merge pull request #11648 from liamwhite/unicode-nonsense
gdbserver: use numeric character references for unicode
2023-10-07 12:49:27 -04:00
liamwhite
15a5bdd979 Merge pull request #11544 from Kelebek1/reduce_stream_buffer_renderdoc
Allow GPUs without rebar to open multiple RenderDoc captures
2023-10-07 12:49:19 -04:00
liamwhite
fc4cde7513 Merge pull request #11669 from german77/settings2
yuzu: Fix custom rtc and mute audio settings
2023-10-07 10:55:21 -04:00
liamwhite
ff3859d482 Merge pull request #11688 from Kelebek1/x8d42
Implement X8_D24 pixel format
2023-10-07 10:55:14 -04:00
liamwhite
10de8f2c60 Merge pull request #11684 from Kelebek1/disable_push_descriptor_maxwell
Disable push descriptor for Pascal and older nVidia architectures
2023-10-07 10:54:52 -04:00
Squall Leonhart
51b89fddd0 update shader to confirmed format copy 2023-10-07 18:28:09 +11:00
Kelebek1
f585dec48d Allow GPUs without rebar to open multiple RenderDoc captures 2023-10-06 07:52:06 +01:00
Kelebek1
ad1a9f3d3a Implement X8_D24 format 2023-10-06 00:58:30 +01:00
Kelebek1
71044f6def Rework nvidia architecture detection, disable push descriptor for Pascal and older 2023-10-05 03:13:42 +01:00
Squall-Leonhart
a17cde7b2c lets not convert depth to greyscale since this makes the exhaust and tire smoke light gray/white
tiresmoke should be a darker gray.
2023-10-05 03:14:53 +11:00
Squall-Leonhart
a84c928827 Fix CI Formatting check 2023-10-04 19:12:08 +11:00
Squall-Leonhart
9568d3bc60 Implements D32_Float to A8B8G8R8_UNORM format copy
Corrects some visual issues in games such as Disney SpeedStorm
2023-10-04 19:07:05 +11:00
Narr the Reg
0fe935a5de core: Update clocks when settings are saved 2023-10-03 20:20:26 -06:00
Narr the Reg
c84c35ac74 yuzu: Fix mute when in background setting 2023-10-03 20:12:06 -06:00
Liam
b32940d3ea vk_present_manager: recreate surface on any surface loss 2023-10-02 19:07:18 -04:00
Liam
38394f36d7 gdbserver: use numeric character references for unicode 2023-10-01 19:22:08 -04:00
Liam
2f0db2708c loader: don't reassign program ID on npdm reparse 2023-09-30 11:35:42 -04:00
Kelebek1
1a246bf135 Enable depth test on stencil clear path 2023-09-28 21:19:51 +01:00
37 changed files with 242 additions and 84 deletions

View File

@@ -1,3 +1,11 @@
| Pull Request | Commit | Title | Author | Merged? |
|----|----|----|----|----|
End of merge log. You can find the original README.md below the break.
-----
<!-- <!--
SPDX-FileCopyrightText: 2018 yuzu Emulator Project SPDX-FileCopyrightText: 2018 yuzu Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later

View File

@@ -218,7 +218,6 @@ public:
return; return;
} }
m_window->OnSurfaceChanged(m_native_window); m_window->OnSurfaceChanged(m_native_window);
m_system.Renderer().NotifySurfaceChanged();
} }
void ConfigureFilesystemProvider(const std::string& filepath) { void ConfigureFilesystemProvider(const std::string& filepath) {

View File

@@ -135,6 +135,11 @@ std::u16string UTF8ToUTF16(std::string_view input) {
return convert.from_bytes(input.data(), input.data() + input.size()); return convert.from_bytes(input.data(), input.data() + input.size());
} }
std::u32string UTF8ToUTF32(std::string_view input) {
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
return convert.from_bytes(input.data(), input.data() + input.size());
}
#ifdef _WIN32 #ifdef _WIN32
static std::wstring CPToUTF16(u32 code_page, std::string_view input) { static std::wstring CPToUTF16(u32 code_page, std::string_view input) {
const auto size = const auto size =

View File

@@ -38,6 +38,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
[[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input); [[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input);
[[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input); [[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input);
[[nodiscard]] std::u32string UTF8ToUTF32(std::string_view input);
#ifdef _WIN32 #ifdef _WIN32
[[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input); [[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input);

View File

@@ -1078,6 +1078,10 @@ void System::ApplySettings() {
impl->RefreshTime(); impl->RefreshTime();
if (IsPoweredOn()) { if (IsPoweredOn()) {
if (Settings::values.custom_rtc_enabled) {
const s64 posix_time{Settings::values.custom_rtc.GetValue()};
GetTimeManager().UpdateLocalSystemClockTime(posix_time);
}
Renderer().RefreshBaseSettings(); Renderer().RefreshBaseSettings();
} }
} }

View File

@@ -2,6 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <atomic> #include <atomic>
#include <codecvt>
#include <locale>
#include <numeric> #include <numeric>
#include <optional> #include <optional>
#include <thread> #include <thread>
@@ -12,6 +14,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/scope_exit.h" #include "common/scope_exit.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/string_util.h"
#include "core/arm/arm_interface.h" #include "core/arm/arm_interface.h"
#include "core/core.h" #include "core/core.h"
#include "core/debugger/gdbstub.h" #include "core/debugger/gdbstub.h"
@@ -68,10 +71,16 @@ static std::string EscapeGDB(std::string_view data) {
} }
static std::string EscapeXML(std::string_view data) { static std::string EscapeXML(std::string_view data) {
std::u32string converted = U"[Encoding error]";
try {
converted = Common::UTF8ToUTF32(data);
} catch (std::range_error&) {
}
std::string escaped; std::string escaped;
escaped.reserve(data.size()); escaped.reserve(data.size());
for (char c : data) { for (char32_t c : converted) {
switch (c) { switch (c) {
case '&': case '&':
escaped += "&amp;"; escaped += "&amp;";
@@ -86,7 +95,11 @@ static std::string EscapeXML(std::string_view data) {
escaped += "&gt;"; escaped += "&gt;";
break; break;
default: default:
escaped += c; if (c > 0x7f) {
escaped += fmt::format("&#{};", static_cast<u32>(c));
} else {
escaped += static_cast<char>(c);
}
break; break;
} }
} }

View File

@@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/scope_exit.h"
#include "core/file_sys/program_metadata.h" #include "core/file_sys/program_metadata.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
@@ -95,6 +96,13 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) {
return Loader::ResultStatus::Success; return Loader::ResultStatus::Success;
} }
Loader::ResultStatus ProgramMetadata::Reload(VirtualFile file) {
const u64 original_program_id = aci_header.title_id;
SCOPE_EXIT({ aci_header.title_id = original_program_id; });
return this->Load(file);
}
/*static*/ ProgramMetadata ProgramMetadata::GetDefault() { /*static*/ ProgramMetadata ProgramMetadata::GetDefault() {
// Allow use of cores 0~3 and thread priorities 1~63. // Allow use of cores 0~3 and thread priorities 1~63.
constexpr u32 default_thread_info_capability = 0x30007F7; constexpr u32 default_thread_info_capability = 0x30007F7;

View File

@@ -56,6 +56,7 @@ public:
static ProgramMetadata GetDefault(); static ProgramMetadata GetDefault();
Loader::ResultStatus Load(VirtualFile file); Loader::ResultStatus Load(VirtualFile file);
Loader::ResultStatus Reload(VirtualFile file);
/// Load from parameters instead of NPDM file, used for KIP /// Load from parameters instead of NPDM file, used for KIP
void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio, void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio,

View File

@@ -118,7 +118,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
return {ResultStatus::ErrorMissingNPDM, {}}; return {ResultStatus::ErrorMissingNPDM, {}};
} }
const ResultStatus result2 = metadata.Load(npdm); const ResultStatus result2 = metadata.Reload(npdm);
if (result2 != ResultStatus::Success) { if (result2 != ResultStatus::Success) {
return {result2, {}}; return {result2, {}};
} }

View File

@@ -19,6 +19,7 @@ set(SHADER_FILES
block_linear_unswizzle_2d.comp block_linear_unswizzle_2d.comp
block_linear_unswizzle_3d.comp block_linear_unswizzle_3d.comp
convert_abgr8_to_d24s8.frag convert_abgr8_to_d24s8.frag
convert_d32f_to_abgr8.frag
convert_d24s8_to_abgr8.frag convert_d24s8_to_abgr8.frag
convert_depth_to_float.frag convert_depth_to_float.frag
convert_float_to_depth.frag convert_float_to_depth.frag

View File

@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#version 450
layout(binding = 0) uniform sampler2D depth_tex;
layout(location = 0) out vec4 color;
void main() {
ivec2 coord = ivec2(gl_FragCoord.xy);
float depth = textureLod(depth_tex, coord, 0).r;
color = vec4(depth, depth, depth, 1.0);
}

View File

@@ -89,9 +89,6 @@ public:
void RequestScreenshot(void* data, std::function<void(bool)> callback, void RequestScreenshot(void* data, std::function<void(bool)> callback,
const Layout::FramebufferLayout& layout); const Layout::FramebufferLayout& layout);
/// This is called to notify the rendering backend of a surface change
virtual void NotifySurfaceChanged() {}
protected: protected:
Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle. Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle.
std::unique_ptr<Core::Frontend::GraphicsContext> context; std::unique_ptr<Core::Frontend::GraphicsContext> context;

View File

@@ -116,6 +116,7 @@ constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> FORMAT_TAB
{GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9_FLOAT {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9_FLOAT
{GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32_FLOAT {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32_FLOAT
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16_UNORM {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16_UNORM
{GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8}, // X8_D24_UNORM
{GL_STENCIL_INDEX8, GL_STENCIL, GL_UNSIGNED_BYTE}, // S8_UINT {GL_STENCIL_INDEX8, GL_STENCIL, GL_UNSIGNED_BYTE}, // S8_UINT
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24_UNORM_S8_UINT {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24_UNORM_S8_UINT
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8_UINT_D24_UNORM {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8_UINT_D24_UNORM

View File

@@ -9,6 +9,7 @@
#include "video_core/host_shaders/blit_color_float_frag_spv.h" #include "video_core/host_shaders/blit_color_float_frag_spv.h"
#include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h"
#include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h"
#include "video_core/host_shaders/convert_d32f_to_abgr8_frag_spv.h"
#include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h"
#include "video_core/host_shaders/convert_float_to_depth_frag_spv.h" #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h"
#include "video_core/host_shaders/convert_s8d24_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_s8d24_to_abgr8_frag_spv.h"
@@ -433,6 +434,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)),
convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)),
convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)),
convert_d32f_to_abgr8_frag(BuildShader(device, CONVERT_D32F_TO_ABGR8_FRAG_SPV)),
convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)),
convert_s8d24_to_abgr8_frag(BuildShader(device, CONVERT_S8D24_TO_ABGR8_FRAG_SPV)), convert_s8d24_to_abgr8_frag(BuildShader(device, CONVERT_S8D24_TO_ABGR8_FRAG_SPV)),
linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)), linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)),
@@ -557,6 +559,13 @@ void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view); Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertD32FToABGR8(const Framebuffer* dst_framebuffer,
ImageView& src_image_view) {
ConvertPipelineColorTargetEx(convert_d32f_to_abgr8_pipeline, dst_framebuffer->RenderPass(),
convert_d32f_to_abgr8_frag);
ConvertDepthStencil(*convert_d32f_to_abgr8_pipeline, dst_framebuffer, src_image_view);
}
void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
ImageView& src_image_view) { ImageView& src_image_view) {
ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(),
@@ -609,6 +618,8 @@ void BlitImageHelper::ClearDepthStencil(const Framebuffer* dst_framebuffer, bool
const VkPipelineLayout layout = *clear_color_pipeline_layout; const VkPipelineLayout layout = *clear_color_pipeline_layout;
scheduler.RequestRenderpass(dst_framebuffer); scheduler.RequestRenderpass(dst_framebuffer);
scheduler.Record([pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf) { scheduler.Record([pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf) {
constexpr std::array blend_constants{0.0f, 0.0f, 0.0f, 0.0f};
cmdbuf.SetBlendConstants(blend_constants.data());
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
BindBlitState(cmdbuf, dst_region); BindBlitState(cmdbuf, dst_region);
cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_depth); cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_depth);
@@ -865,7 +876,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.depthTestEnable = VK_FALSE, .depthTestEnable = key.depth_clear,
.depthWriteEnable = key.depth_clear, .depthWriteEnable = key.depth_clear,
.depthCompareOp = VK_COMPARE_OP_ALWAYS, .depthCompareOp = VK_COMPARE_OP_ALWAYS,
.depthBoundsTestEnable = VK_FALSE, .depthBoundsTestEnable = VK_FALSE,

View File

@@ -67,6 +67,8 @@ public:
void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
void ConvertD32FToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view);
void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view);
void ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); void ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view);
@@ -128,6 +130,7 @@ private:
vk::ShaderModule convert_depth_to_float_frag; vk::ShaderModule convert_depth_to_float_frag;
vk::ShaderModule convert_float_to_depth_frag; vk::ShaderModule convert_float_to_depth_frag;
vk::ShaderModule convert_abgr8_to_d24s8_frag; vk::ShaderModule convert_abgr8_to_d24s8_frag;
vk::ShaderModule convert_d32f_to_abgr8_frag;
vk::ShaderModule convert_d24s8_to_abgr8_frag; vk::ShaderModule convert_d24s8_to_abgr8_frag;
vk::ShaderModule convert_s8d24_to_abgr8_frag; vk::ShaderModule convert_s8d24_to_abgr8_frag;
vk::Sampler linear_sampler; vk::Sampler linear_sampler;
@@ -146,6 +149,7 @@ private:
vk::Pipeline convert_d16_to_r16_pipeline; vk::Pipeline convert_d16_to_r16_pipeline;
vk::Pipeline convert_r16_to_d16_pipeline; vk::Pipeline convert_r16_to_d16_pipeline;
vk::Pipeline convert_abgr8_to_d24s8_pipeline; vk::Pipeline convert_abgr8_to_d24s8_pipeline;
vk::Pipeline convert_d32f_to_abgr8_pipeline;
vk::Pipeline convert_d24s8_to_abgr8_pipeline; vk::Pipeline convert_d24s8_to_abgr8_pipeline;
vk::Pipeline convert_s8d24_to_abgr8_pipeline; vk::Pipeline convert_s8d24_to_abgr8_pipeline;
}; };

View File

@@ -216,6 +216,7 @@ struct FormatTuple {
// Depth formats // Depth formats
{VK_FORMAT_D32_SFLOAT, Attachable}, // D32_FLOAT {VK_FORMAT_D32_SFLOAT, Attachable}, // D32_FLOAT
{VK_FORMAT_D16_UNORM, Attachable}, // D16_UNORM {VK_FORMAT_D16_UNORM, Attachable}, // D16_UNORM
{VK_FORMAT_X8_D24_UNORM_PACK32, Attachable}, // X8_D24_UNORM
// Stencil formats // Stencil formats
{VK_FORMAT_S8_UINT, Attachable}, // S8_UINT {VK_FORMAT_S8_UINT, Attachable}, // S8_UINT

View File

@@ -56,10 +56,6 @@ public:
return device.GetDriverName(); return device.GetDriverName();
} }
void NotifySurfaceChanged() override {
present_manager.NotifySurfaceChanged();
}
private: private:
void Report() const; void Report() const;

View File

@@ -96,6 +96,7 @@ std::size_t GetSizeInBytes(const Tegra::FramebufferConfig& framebuffer) {
VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) { VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) {
switch (framebuffer.pixel_format) { switch (framebuffer.pixel_format) {
case Service::android::PixelFormat::Rgba8888: case Service::android::PixelFormat::Rgba8888:
case Service::android::PixelFormat::Rgbx8888:
return VK_FORMAT_A8B8G8R8_UNORM_PACK32; return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
case Service::android::PixelFormat::Rgb565: case Service::android::PixelFormat::Rgb565:
return VK_FORMAT_R5G6B5_UNORM_PACK16; return VK_FORMAT_R5G6B5_UNORM_PACK16;

View File

@@ -103,8 +103,7 @@ PresentManager::PresentManager(const vk::Instance& instance_,
surface{surface_}, blit_supported{CanBlitToSwapchain(device.GetPhysical(), surface{surface_}, blit_supported{CanBlitToSwapchain(device.GetPhysical(),
swapchain.GetImageViewFormat())}, swapchain.GetImageViewFormat())},
use_present_thread{Settings::values.async_presentation.GetValue()}, use_present_thread{Settings::values.async_presentation.GetValue()},
image_count{swapchain.GetImageCount()}, last_render_surface{ image_count{swapchain.GetImageCount()} {
render_window_.GetWindowInfo().render_surface} {
auto& dld = device.GetLogical(); auto& dld = device.GetLogical();
cmdpool = dld.CreateCommandPool({ cmdpool = dld.CreateCommandPool({
@@ -289,44 +288,36 @@ void PresentManager::PresentThread(std::stop_token token) {
} }
} }
void PresentManager::NotifySurfaceChanged() { void PresentManager::RecreateSwapchain(Frame* frame) {
#ifdef ANDROID swapchain.Create(*surface, frame->width, frame->height, frame->is_srgb);
std::scoped_lock lock{recreate_surface_mutex}; image_count = swapchain.GetImageCount();
recreate_surface_cv.notify_one();
#endif
} }
void PresentManager::CopyToSwapchain(Frame* frame) { void PresentManager::CopyToSwapchain(Frame* frame) {
MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain); bool requires_recreation = false;
const auto recreate_swapchain = [&] { while (true) {
swapchain.Create(*surface, frame->width, frame->height, frame->is_srgb); try {
image_count = swapchain.GetImageCount(); // Recreate surface and swapchain if needed.
}; if (requires_recreation) {
#ifdef ANDROID
std::unique_lock lock{recreate_surface_mutex};
const auto needs_recreation = [&] {
if (last_render_surface != render_window.GetWindowInfo().render_surface) {
return true;
}
if (swapchain.NeedsRecreation(frame->is_srgb)) {
return true;
}
return false;
};
recreate_surface_cv.wait_for(lock, std::chrono::milliseconds(400),
[&]() { return !needs_recreation(); });
// If the frontend recreated the surface, recreate the renderer surface and swapchain.
if (last_render_surface != render_window.GetWindowInfo().render_surface) {
last_render_surface = render_window.GetWindowInfo().render_surface;
surface = CreateSurface(instance, render_window.GetWindowInfo()); surface = CreateSurface(instance, render_window.GetWindowInfo());
recreate_swapchain(); RecreateSwapchain(frame);
} }
#endif
// Draw to swapchain.
return CopyToSwapchainImpl(frame);
} catch (const vk::Exception& except) {
if (except.GetResult() != VK_ERROR_SURFACE_LOST_KHR) {
throw;
}
requires_recreation = true;
}
}
}
void PresentManager::CopyToSwapchainImpl(Frame* frame) {
MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain);
// If the size or colorspace of the incoming frames has changed, recreate the swapchain // If the size or colorspace of the incoming frames has changed, recreate the swapchain
// to account for that. // to account for that.
@@ -334,11 +325,11 @@ void PresentManager::CopyToSwapchain(Frame* frame) {
const bool size_changed = const bool size_changed =
swapchain.GetWidth() != frame->width || swapchain.GetHeight() != frame->height; swapchain.GetWidth() != frame->width || swapchain.GetHeight() != frame->height;
if (srgb_changed || size_changed) { if (srgb_changed || size_changed) {
recreate_swapchain(); RecreateSwapchain(frame);
} }
while (swapchain.AcquireNextImage()) { while (swapchain.AcquireNextImage()) {
recreate_swapchain(); RecreateSwapchain(frame);
} }
const vk::CommandBuffer cmdbuf{frame->cmdbuf}; const vk::CommandBuffer cmdbuf{frame->cmdbuf};

View File

@@ -54,14 +54,15 @@ public:
/// 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();
/// This is called to notify the rendering backend of a surface change
void NotifySurfaceChanged();
private: private:
void PresentThread(std::stop_token token); void PresentThread(std::stop_token token);
void CopyToSwapchain(Frame* frame); void CopyToSwapchain(Frame* frame);
void CopyToSwapchainImpl(Frame* frame);
void RecreateSwapchain(Frame* frame);
private: private:
const vk::Instance& instance; const vk::Instance& instance;
Core::Frontend::EmuWindow& render_window; Core::Frontend::EmuWindow& render_window;
@@ -76,16 +77,13 @@ private:
std::queue<Frame*> free_queue; std::queue<Frame*> free_queue;
std::condition_variable_any frame_cv; std::condition_variable_any frame_cv;
std::condition_variable free_cv; std::condition_variable free_cv;
std::condition_variable recreate_surface_cv;
std::mutex swapchain_mutex; std::mutex swapchain_mutex;
std::mutex recreate_surface_mutex;
std::mutex queue_mutex; std::mutex queue_mutex;
std::mutex free_mutex; std::mutex free_mutex;
std::jthread present_thread; std::jthread present_thread;
bool blit_supported; bool blit_supported;
bool use_present_thread; bool use_present_thread;
std::size_t image_count{}; std::size_t image_count{};
void* last_render_surface{};
}; };
} // namespace Vulkan } // namespace Vulkan

View File

@@ -422,7 +422,8 @@ void RasterizerVulkan::Clear(u32 layer_count) {
return; return;
} }
if (use_stencil && regs.stencil_front_mask != 0xFF && regs.stencil_front_mask != 0) { if (use_stencil && framebuffer->HasAspectStencilBit() && regs.stencil_front_mask != 0xFF &&
regs.stencil_front_mask != 0) {
Region2D dst_region = { Region2D dst_region = {
Offset2D{.x = clear_rect.rect.offset.x, .y = clear_rect.rect.offset.y}, Offset2D{.x = clear_rect.rect.offset.x, .y = clear_rect.rect.offset.y},
Offset2D{.x = clear_rect.rect.offset.x + static_cast<s32>(clear_rect.rect.extent.width), Offset2D{.x = clear_rect.rect.offset.x + static_cast<s32>(clear_rect.rect.extent.width),

View File

@@ -24,25 +24,38 @@ using namespace Common::Literals;
// Maximum potential alignment of a Vulkan buffer // Maximum potential alignment of a Vulkan buffer
constexpr VkDeviceSize MAX_ALIGNMENT = 256; constexpr VkDeviceSize MAX_ALIGNMENT = 256;
// Maximum size to put elements in the stream buffer
constexpr VkDeviceSize MAX_STREAM_BUFFER_REQUEST_SIZE = 8_MiB;
// Stream buffer size in bytes // Stream buffer size in bytes
constexpr VkDeviceSize STREAM_BUFFER_SIZE = 128_MiB; constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 128_MiB;
constexpr VkDeviceSize REGION_SIZE = STREAM_BUFFER_SIZE / StagingBufferPool::NUM_SYNCS;
size_t Region(size_t iterator) noexcept { size_t GetStreamBufferSize(const Device& device) {
return iterator / REGION_SIZE; VkDeviceSize size{0};
if (device.HasDebuggingToolAttached()) {
ForEachDeviceLocalHostVisibleHeap(device, [&size](size_t index, VkMemoryHeap& heap) {
size = std::max(size, heap.size);
});
// If rebar is not supported, cut the max heap size to 40%. This will allow 2 captures to be
// loaded at the same time in RenderDoc. If rebar is supported, this shouldn't be an issue
// as the heap will be much larger.
if (size <= 256_MiB) {
size = size * 40 / 100;
}
} else {
size = MAX_STREAM_BUFFER_SIZE;
}
return std::min(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE);
} }
} // Anonymous namespace } // Anonymous namespace
StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_,
Scheduler& scheduler_) Scheduler& scheduler_)
: device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_} { : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_},
stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size /
StagingBufferPool::NUM_SYNCS} {
VkBufferCreateInfo stream_ci = { VkBufferCreateInfo stream_ci = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.size = STREAM_BUFFER_SIZE, .size = stream_buffer_size,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
@@ -63,7 +76,7 @@ StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& mem
StagingBufferPool::~StagingBufferPool() = default; StagingBufferPool::~StagingBufferPool() = default;
StagingBufferRef StagingBufferPool::Request(size_t size, MemoryUsage usage, bool deferred) { StagingBufferRef StagingBufferPool::Request(size_t size, MemoryUsage usage, bool deferred) {
if (!deferred && usage == MemoryUsage::Upload && size <= MAX_STREAM_BUFFER_REQUEST_SIZE) { if (!deferred && usage == MemoryUsage::Upload && size <= region_size) {
return GetStreamBuffer(size); return GetStreamBuffer(size);
} }
return GetStagingBuffer(size, usage, deferred); return GetStagingBuffer(size, usage, deferred);
@@ -101,7 +114,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
used_iterator = iterator; used_iterator = iterator;
free_iterator = std::max(free_iterator, iterator + size); free_iterator = std::max(free_iterator, iterator + size);
if (iterator + size >= STREAM_BUFFER_SIZE) { if (iterator + size >= stream_buffer_size) {
std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + NUM_SYNCS, std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + NUM_SYNCS,
current_tick); current_tick);
used_iterator = 0; used_iterator = 0;

View File

@@ -90,6 +90,9 @@ private:
void ReleaseCache(MemoryUsage usage); void ReleaseCache(MemoryUsage usage);
void ReleaseLevel(StagingBuffersCache& cache, size_t log2); void ReleaseLevel(StagingBuffersCache& cache, size_t log2);
size_t Region(size_t iter) const noexcept {
return iter / region_size;
}
const Device& device; const Device& device;
MemoryAllocator& memory_allocator; MemoryAllocator& memory_allocator;
@@ -97,6 +100,8 @@ private:
vk::Buffer stream_buffer; vk::Buffer stream_buffer;
std::span<u8> stream_pointer; std::span<u8> stream_pointer;
VkDeviceSize stream_buffer_size;
VkDeviceSize region_size;
size_t iterator = 0; size_t iterator = 0;
size_t used_iterator = 0; size_t used_iterator = 0;

View File

@@ -238,6 +238,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
return any_r ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; return any_r ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
case PixelFormat::D16_UNORM: case PixelFormat::D16_UNORM:
case PixelFormat::D32_FLOAT: case PixelFormat::D32_FLOAT:
case PixelFormat::X8_D24_UNORM:
return VK_IMAGE_ASPECT_DEPTH_BIT; return VK_IMAGE_ASPECT_DEPTH_BIT;
case PixelFormat::S8_UINT: case PixelFormat::S8_UINT:
return VK_IMAGE_ASPECT_STENCIL_BIT; return VK_IMAGE_ASPECT_STENCIL_BIT;
@@ -1200,6 +1201,9 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im
if (src_view.format == PixelFormat::D24_UNORM_S8_UINT) { if (src_view.format == PixelFormat::D24_UNORM_S8_UINT) {
return blit_image_helper.ConvertS8D24ToABGR8(dst, src_view); return blit_image_helper.ConvertS8D24ToABGR8(dst, src_view);
} }
if (src_view.format == PixelFormat::D32_FLOAT) {
return blit_image_helper.ConvertD32FToABGR8(dst, src_view);
}
break; break;
case PixelFormat::R32_FLOAT: case PixelFormat::R32_FLOAT:
if (src_view.format == PixelFormat::D32_FLOAT) { if (src_view.format == PixelFormat::D32_FLOAT) {

View File

@@ -85,6 +85,8 @@ PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
return PixelFormat::S8_UINT; return PixelFormat::S8_UINT;
case Tegra::DepthFormat::Z32_FLOAT_X24S8_UINT: case Tegra::DepthFormat::Z32_FLOAT_X24S8_UINT:
return PixelFormat::D32_FLOAT_S8_UINT; return PixelFormat::D32_FLOAT_S8_UINT;
case Tegra::DepthFormat::X8Z24_UNORM:
return PixelFormat::X8_D24_UNORM;
default: default:
UNIMPLEMENTED_MSG("Unimplemented format={}", format); UNIMPLEMENTED_MSG("Unimplemented format={}", format);
return PixelFormat::S8_UINT_D24_UNORM; return PixelFormat::S8_UINT_D24_UNORM;
@@ -202,6 +204,7 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format)
PixelFormat PixelFormatFromGPUPixelFormat(Service::android::PixelFormat format) { PixelFormat PixelFormatFromGPUPixelFormat(Service::android::PixelFormat format) {
switch (format) { switch (format) {
case Service::android::PixelFormat::Rgba8888: case Service::android::PixelFormat::Rgba8888:
case Service::android::PixelFormat::Rgbx8888:
return PixelFormat::A8B8G8R8_UNORM; return PixelFormat::A8B8G8R8_UNORM;
case Service::android::PixelFormat::Rgb565: case Service::android::PixelFormat::Rgb565:
return PixelFormat::R5G6B5_UNORM; return PixelFormat::R5G6B5_UNORM;

View File

@@ -115,6 +115,7 @@ enum class PixelFormat {
// Depth formats // Depth formats
D32_FLOAT = MaxColorFormat, D32_FLOAT = MaxColorFormat,
D16_UNORM, D16_UNORM,
X8_D24_UNORM,
MaxDepthFormat, MaxDepthFormat,
@@ -251,6 +252,7 @@ constexpr std::array<u8, MaxPixelFormat> BLOCK_WIDTH_TABLE = {{
1, // E5B9G9R9_FLOAT 1, // E5B9G9R9_FLOAT
1, // D32_FLOAT 1, // D32_FLOAT
1, // D16_UNORM 1, // D16_UNORM
1, // X8_D24_UNORM
1, // S8_UINT 1, // S8_UINT
1, // D24_UNORM_S8_UINT 1, // D24_UNORM_S8_UINT
1, // S8_UINT_D24_UNORM 1, // S8_UINT_D24_UNORM
@@ -360,6 +362,7 @@ constexpr std::array<u8, MaxPixelFormat> BLOCK_HEIGHT_TABLE = {{
1, // E5B9G9R9_FLOAT 1, // E5B9G9R9_FLOAT
1, // D32_FLOAT 1, // D32_FLOAT
1, // D16_UNORM 1, // D16_UNORM
1, // X8_D24_UNORM
1, // S8_UINT 1, // S8_UINT
1, // D24_UNORM_S8_UINT 1, // D24_UNORM_S8_UINT
1, // S8_UINT_D24_UNORM 1, // S8_UINT_D24_UNORM
@@ -469,6 +472,7 @@ constexpr std::array<u8, MaxPixelFormat> BITS_PER_BLOCK_TABLE = {{
32, // E5B9G9R9_FLOAT 32, // E5B9G9R9_FLOAT
32, // D32_FLOAT 32, // D32_FLOAT
16, // D16_UNORM 16, // D16_UNORM
32, // X8_D24_UNORM
8, // S8_UINT 8, // S8_UINT
32, // D24_UNORM_S8_UINT 32, // D24_UNORM_S8_UINT
32, // S8_UINT_D24_UNORM 32, // S8_UINT_D24_UNORM

View File

@@ -142,6 +142,10 @@ PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red,
return PixelFormat::D16_UNORM; return PixelFormat::D16_UNORM;
case Hash(TextureFormat::Z16, UNORM, UINT, UINT, UINT, LINEAR): case Hash(TextureFormat::Z16, UNORM, UINT, UINT, UINT, LINEAR):
return PixelFormat::D16_UNORM; return PixelFormat::D16_UNORM;
case Hash(TextureFormat::X8Z24, UNORM):
return PixelFormat::X8_D24_UNORM;
case Hash(TextureFormat::X8Z24, UNORM, UINT, UINT, UINT, LINEAR):
return PixelFormat::X8_D24_UNORM;
case Hash(TextureFormat::Z24S8, UINT, UNORM, UNORM, UNORM, LINEAR): case Hash(TextureFormat::Z24S8, UINT, UNORM, UNORM, UNORM, LINEAR):
return PixelFormat::S8_UINT_D24_UNORM; return PixelFormat::S8_UINT_D24_UNORM;
case Hash(TextureFormat::Z24S8, UINT, UNORM, UINT, UINT, LINEAR): case Hash(TextureFormat::Z24S8, UINT, UNORM, UINT, UINT, LINEAR):

View File

@@ -211,6 +211,8 @@ struct fmt::formatter<VideoCore::Surface::PixelFormat> : fmt::formatter<fmt::str
return "D32_FLOAT"; return "D32_FLOAT";
case PixelFormat::D16_UNORM: case PixelFormat::D16_UNORM:
return "D16_UNORM"; return "D16_UNORM";
case PixelFormat::X8_D24_UNORM:
return "X8_D24_UNORM";
case PixelFormat::S8_UINT: case PixelFormat::S8_UINT:
return "S8_UINT"; return "S8_UINT";
case PixelFormat::D24_UNORM_S8_UINT: case PixelFormat::D24_UNORM_S8_UINT:

View File

@@ -85,6 +85,7 @@ bool ImageViewBase::SupportsAnisotropy() const noexcept {
// Depth formats // Depth formats
case PixelFormat::D32_FLOAT: case PixelFormat::D32_FLOAT:
case PixelFormat::D16_UNORM: case PixelFormat::D16_UNORM:
case PixelFormat::X8_D24_UNORM:
// Stencil formats // Stencil formats
case PixelFormat::S8_UINT: case PixelFormat::S8_UINT:
// DepthStencil formats // DepthStencil formats

View File

@@ -84,9 +84,12 @@ constexpr std::array VK_FORMAT_A4B4G4R4_UNORM_PACK16{
} // namespace Alternatives } // namespace Alternatives
enum class NvidiaArchitecture { enum class NvidiaArchitecture {
AmpereOrNewer, KeplerOrOlder,
Maxwell,
Pascal,
Volta,
Turing, Turing,
VoltaOrOlder, AmpereOrNewer,
}; };
template <typename T> template <typename T>
@@ -200,6 +203,7 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica
VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK,
VK_FORMAT_D16_UNORM, VK_FORMAT_D16_UNORM,
VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT,
VK_FORMAT_X8_D24_UNORM_PACK32,
VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT,
VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT,
@@ -321,13 +325,38 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
physical.GetProperties2(physical_properties); physical.GetProperties2(physical_properties);
if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) { if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) {
// Only Ampere and newer support this feature // Only Ampere and newer support this feature
// TODO: Find a way to differentiate Ampere and Ada
return NvidiaArchitecture::AmpereOrNewer; return NvidiaArchitecture::AmpereOrNewer;
} }
}
if (exts.contains(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME)) {
return NvidiaArchitecture::Turing; return NvidiaArchitecture::Turing;
} }
return NvidiaArchitecture::VoltaOrOlder;
if (exts.contains(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME)) {
VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT advanced_blending_props{};
advanced_blending_props.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT;
VkPhysicalDeviceProperties2 physical_properties{};
physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
physical_properties.pNext = &advanced_blending_props;
physical.GetProperties2(physical_properties);
if (advanced_blending_props.advancedBlendMaxColorAttachments == 1) {
return NvidiaArchitecture::Maxwell;
}
if (exts.contains(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) {
VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservative_raster_props{};
conservative_raster_props.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT;
physical_properties.pNext = &conservative_raster_props;
physical.GetProperties2(physical_properties);
if (conservative_raster_props.degenerateLinesRasterized) {
return NvidiaArchitecture::Volta;
}
return NvidiaArchitecture::Pascal;
}
}
return NvidiaArchitecture::KeplerOrOlder;
} }
std::vector<const char*> ExtensionListForVulkan( std::vector<const char*> ExtensionListForVulkan(
@@ -504,19 +533,14 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
if (is_nvidia) { if (is_nvidia) {
const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff; const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff;
const auto arch = GetNvidiaArchitecture(physical, supported_extensions); const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
switch (arch) { if (arch >= NvidiaArchitecture::AmpereOrNewer) {
case NvidiaArchitecture::AmpereOrNewer:
LOG_WARNING(Render_Vulkan, "Ampere and newer have broken float16 math"); LOG_WARNING(Render_Vulkan, "Ampere and newer have broken float16 math");
features.shader_float16_int8.shaderFloat16 = false; features.shader_float16_int8.shaderFloat16 = false;
break; } else if (arch <= NvidiaArchitecture::Volta) {
case NvidiaArchitecture::Turing:
break;
case NvidiaArchitecture::VoltaOrOlder:
if (nv_major_version < 527) { if (nv_major_version < 527) {
LOG_WARNING(Render_Vulkan, "Volta and older have broken VK_KHR_push_descriptor"); LOG_WARNING(Render_Vulkan, "Volta and older have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
} }
break;
} }
if (nv_major_version >= 510) { if (nv_major_version >= 510) {
LOG_WARNING(Render_Vulkan, "NVIDIA Drivers >= 510 do not support MSAA image blits"); LOG_WARNING(Render_Vulkan, "NVIDIA Drivers >= 510 do not support MSAA image blits");
@@ -661,7 +685,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
"ANV drivers 22.3.0 to 23.1.0 have broken VK_KHR_push_descriptor"); "ANV drivers 22.3.0 to 23.1.0 have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
} }
} else if (extensions.push_descriptor && is_nvidia) {
const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
if (arch <= NvidiaArchitecture::Pascal) {
LOG_WARNING(Render_Vulkan,
"Pascal and older architectures have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
} }
}
if (is_mvk) { if (is_mvk) {
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"MVK driver breaks when using more than 16 vertex attributes/bindings"); "MVK driver breaks when using more than 16 vertex attributes/bindings");

View File

@@ -9,6 +9,7 @@
#include "common/alignment.h" #include "common/alignment.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/literals.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/polyfill_ranges.h" #include "common/polyfill_ranges.h"
#include "video_core/vulkan_common/vma.h" #include "video_core/vulkan_common/vma.h"
@@ -69,8 +70,7 @@ struct Range {
case MemoryUsage::Download: case MemoryUsage::Download:
return VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; return VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
case MemoryUsage::DeviceLocal: case MemoryUsage::DeviceLocal:
return VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | return {};
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT;
} }
return {}; return {};
} }
@@ -212,7 +212,20 @@ MemoryAllocator::MemoryAllocator(const Device& device_)
: device{device_}, allocator{device.GetAllocator()}, : device{device_}, allocator{device.GetAllocator()},
properties{device_.GetPhysical().GetMemoryProperties().memoryProperties}, properties{device_.GetPhysical().GetMemoryProperties().memoryProperties},
buffer_image_granularity{ buffer_image_granularity{
device_.GetPhysical().GetProperties().limits.bufferImageGranularity} {} device_.GetPhysical().GetProperties().limits.bufferImageGranularity} {
// GPUs not supporting rebar may only have a region with less than 256MB host visible/device
// local memory. In that case, opening 2 RenderDoc captures side-by-side is not possible due to
// the heap running out of memory. With RenderDoc attached and only a small host/device region,
// only allow the stream buffer in this memory heap.
if (device.HasDebuggingToolAttached()) {
using namespace Common::Literals;
ForEachDeviceLocalHostVisibleHeap(device, [this](size_t index, VkMemoryHeap& heap) {
if (heap.size <= 256_MiB) {
valid_memory_types &= ~(1u << index);
}
});
}
}
MemoryAllocator::~MemoryAllocator() = default; MemoryAllocator::~MemoryAllocator() = default;
@@ -244,7 +257,7 @@ vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsa
.usage = MemoryUsageVma(usage), .usage = MemoryUsageVma(usage),
.requiredFlags = 0, .requiredFlags = 0,
.preferredFlags = MemoryUsagePreferedVmaFlags(usage), .preferredFlags = MemoryUsagePreferedVmaFlags(usage),
.memoryTypeBits = 0, .memoryTypeBits = usage == MemoryUsage::Stream ? 0u : valid_memory_types,
.pool = VK_NULL_HANDLE, .pool = VK_NULL_HANDLE,
.pUserData = nullptr, .pUserData = nullptr,
.priority = 0.f, .priority = 0.f,

View File

@@ -7,6 +7,7 @@
#include <span> #include <span>
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/vulkan_common/vulkan_wrapper.h"
VK_DEFINE_HANDLE(VmaAllocator) VK_DEFINE_HANDLE(VmaAllocator)
@@ -26,6 +27,18 @@ enum class MemoryUsage {
Stream, ///< Requests device local host visible buffer, falling back host memory. Stream, ///< Requests device local host visible buffer, falling back host memory.
}; };
template <typename F>
void ForEachDeviceLocalHostVisibleHeap(const Device& device, F&& f) {
auto memory_props = device.GetPhysical().GetMemoryProperties().memoryProperties;
for (size_t i = 0; i < memory_props.memoryTypeCount; i++) {
auto& memory_type = memory_props.memoryTypes[i];
if ((memory_type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) &&
(memory_type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
f(memory_type.heapIndex, memory_props.memoryHeaps[memory_type.heapIndex]);
}
}
}
/// Ownership handle of a memory commitment. /// Ownership handle of a memory commitment.
/// Points to a subregion of a memory allocation. /// Points to a subregion of a memory allocation.
class MemoryCommit { class MemoryCommit {
@@ -124,6 +137,7 @@ private:
std::vector<std::unique_ptr<MemoryAllocation>> allocations; ///< Current allocations. std::vector<std::unique_ptr<MemoryAllocation>> allocations; ///< Current allocations.
VkDeviceSize buffer_image_granularity; // The granularity for adjacent offsets between buffers VkDeviceSize buffer_image_granularity; // The granularity for adjacent offsets between buffers
// and optimal images // and optimal images
u32 valid_memory_types{~0u};
}; };
} // namespace Vulkan } // namespace Vulkan

View File

@@ -117,6 +117,9 @@ public:
virtual ~Exception() = default; virtual ~Exception() = default;
const char* what() const noexcept override; const char* what() const noexcept override;
VkResult GetResult() const noexcept {
return result;
}
private: private:
VkResult result; VkResult result;

View File

@@ -42,6 +42,9 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
for (auto* setting : Settings::values.linkage.by_category[category]) { for (auto* setting : Settings::values.linkage.by_category[category]) {
settings.push_back(setting); settings.push_back(setting);
} }
for (auto* setting : UISettings::values.linkage.by_category[category]) {
settings.push_back(setting);
}
}; };
push(Settings::Category::Audio); push(Settings::Category::Audio);

View File

@@ -29,9 +29,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
INSERT(Settings, sink_id, "Output Engine:", ""); INSERT(Settings, sink_id, "Output Engine:", "");
INSERT(Settings, audio_output_device_id, "Output Device:", ""); INSERT(Settings, audio_output_device_id, "Output Device:", "");
INSERT(Settings, audio_input_device_id, "Input Device:", ""); INSERT(Settings, audio_input_device_id, "Input Device:", "");
INSERT(Settings, audio_muted, "Mute audio when in background", ""); INSERT(Settings, audio_muted, "Mute audio", "");
INSERT(Settings, volume, "Volume:", ""); INSERT(Settings, volume, "Volume:", "");
INSERT(Settings, dump_audio_commands, "", ""); INSERT(Settings, dump_audio_commands, "", "");
INSERT(UISettings, mute_when_in_background, "Mute audio when in background", "");
// Core // Core
INSERT(Settings, use_multi_core, "Multicore CPU Emulation", ""); INSERT(Settings, use_multi_core, "Multicore CPU Emulation", "");

View File

@@ -1447,6 +1447,7 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) {
Settings::values.audio_muted = false; Settings::values.audio_muted = false;
auto_muted = false; auto_muted = false;
} }
UpdateVolumeUI();
} }
} }

View File

@@ -103,7 +103,7 @@ struct Values {
true, true,
true}; true};
Setting<bool> mute_when_in_background{ Setting<bool> mute_when_in_background{
linkage, false, "muteWhenInBackground", Category::Ui, Settings::Specialization::Default, linkage, false, "muteWhenInBackground", Category::Audio, Settings::Specialization::Default,
true, true}; true, true};
Setting<bool> hide_mouse{ Setting<bool> hide_mouse{
linkage, true, "hideInactiveMouse", Category::UiGeneral, Settings::Specialization::Default, linkage, true, "hideInactiveMouse", Category::UiGeneral, Settings::Specialization::Default,