From 81955276bf6d652e3f92eea25f25f68cbbe85d7d Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Wed, 13 Dec 2023 18:04:01 +0100 Subject: [PATCH] early-access version 4018 --- README.md | 2 +- src/audio_core/sink/cubeb_sink.cpp | 3 +- src/audio_core/sink/sdl2_sink.cpp | 3 +- src/audio_core/sink/sink.h | 12 ++++++ src/audio_core/sink/sink_stream.cpp | 43 +++++++++++-------- src/core/hle/service/audio/audren_u.cpp | 2 +- .../renderer_vulkan/vk_present_manager.cpp | 6 +++ .../renderer_vulkan/vk_present_manager.h | 4 ++ .../renderer_vulkan/vk_update_descriptor.h | 4 +- 9 files changed, 55 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index cf435e2cb..6b4f3b578 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 4017. +This is the source code for early-access 4018. ## Legal Notice diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp index 1bb1214fd..47f49ff2f 100755 --- a/src/audio_core/sink/cubeb_sink.cpp +++ b/src/audio_core/sink/cubeb_sink.cpp @@ -253,8 +253,9 @@ CubebSink::~CubebSink() { #endif } -SinkStream* CubebSink::AcquireSinkStream(Core::System& system, u32 system_channels, +SinkStream* CubebSink::AcquireSinkStream(Core::System& system, u32 system_channels_, const std::string& name, StreamType type) { + system_channels = system_channels_; SinkStreamPtr& stream = sink_streams.emplace_back(std::make_unique( ctx, device_channels, system_channels, output_device, input_device, name, type, system)); diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp index 79ea6e09a..41cefd1ba 100755 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl2_sink.cpp @@ -168,8 +168,9 @@ SDLSink::SDLSink(std::string_view target_device_name) { SDLSink::~SDLSink() = default; -SinkStream* SDLSink::AcquireSinkStream(Core::System& system, u32 system_channels, +SinkStream* SDLSink::AcquireSinkStream(Core::System& system, u32 system_channels_, const std::string&, StreamType type) { + system_channels = system_channels_; SinkStreamPtr& stream = sink_streams.emplace_back(std::make_unique( device_channels, system_channels, output_device, input_device, type, system)); return stream.get(); diff --git a/src/audio_core/sink/sink.h b/src/audio_core/sink/sink.h index 6524d1536..c1f9a721d 100755 --- a/src/audio_core/sink/sink.h +++ b/src/audio_core/sink/sink.h @@ -85,9 +85,21 @@ public: */ virtual void SetSystemVolume(f32 volume) = 0; + /** + * Get the number of channels the game has set, can be different to the host hardware's support. + * Either 2 or 6. + * + * @return Number of device channels. + */ + u32 GetSystemChannels() const { + return system_channels; + } + protected: /// Number of device channels supported by the hardware u32 device_channels{2}; + /// Number of channels the game is sending + u32 system_channels{2}; }; using SinkPtr = std::unique_ptr; diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp index 886b77c9d..1360d0949 100755 --- a/src/audio_core/sink/sink_stream.cpp +++ b/src/audio_core/sink/sink_stream.cpp @@ -40,29 +40,38 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span samples) { if (system_channels == 6 && device_channels == 2) { // We're given 6 channels, but our device only outputs 2, so downmix. - static constexpr std::array down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f}; + // Front = 1.0 + // Center = 0.596 + // Back = 0.707 + // LFE = 0.354 + // 1.0 + 0.596 + 0.707 + 0.354 = 2.657, 1/2.657 = 0.37636f downscale coefficient + static constexpr std::array down_mix_coeff{0.37636f, 0.22431056f, 0.13323144f, + 0.26608652f}; for (u32 read_index = 0, write_index = 0; read_index < samples.size(); read_index += system_channels, write_index += device_channels) { + const auto fl = + static_cast(samples[read_index + static_cast(Channels::FrontLeft)]); + const auto fr = + static_cast(samples[read_index + static_cast(Channels::FrontRight)]); + const auto c = + static_cast(samples[read_index + static_cast(Channels::Center)]); + const auto lfe = + static_cast(samples[read_index + static_cast(Channels::LFE)]); + const auto bl = + static_cast(samples[read_index + static_cast(Channels::BackLeft)]); + const auto br = + static_cast(samples[read_index + static_cast(Channels::BackRight)]); + const auto left_sample{ - ((Common::FixedPoint<49, 15>( - samples[read_index + static_cast(Channels::FrontLeft)]) * - down_mix_coeff[0] + - samples[read_index + static_cast(Channels::Center)] * down_mix_coeff[1] + - samples[read_index + static_cast(Channels::LFE)] * down_mix_coeff[2] + - samples[read_index + static_cast(Channels::BackLeft)] * down_mix_coeff[3]) * - volume) - .to_int()}; + static_cast((fl * down_mix_coeff[0] + c * down_mix_coeff[1] + + lfe * down_mix_coeff[2] + bl * down_mix_coeff[3]) * + volume)}; const auto right_sample{ - ((Common::FixedPoint<49, 15>( - samples[read_index + static_cast(Channels::FrontRight)]) * - down_mix_coeff[0] + - samples[read_index + static_cast(Channels::Center)] * down_mix_coeff[1] + - samples[read_index + static_cast(Channels::LFE)] * down_mix_coeff[2] + - samples[read_index + static_cast(Channels::BackRight)] * down_mix_coeff[3]) * - volume) - .to_int()}; + static_cast((fr * down_mix_coeff[0] + c * down_mix_coeff[1] + + lfe * down_mix_coeff[2] + br * down_mix_coeff[3]) * + volume)}; samples[write_index + static_cast(Channels::FrontLeft)] = static_cast(std::clamp(left_sample, min, max)); diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index f5077560c..ac212d069 100755 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -359,7 +359,7 @@ private: void GetActiveChannelCount(HLERequestContext& ctx) { const auto& sink{system.AudioCore().GetOutputSink()}; - u32 channel_count{sink.GetDeviceChannels()}; + u32 channel_count{sink.GetSystemChannels()}; LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", channel_count); diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index 8e4c74b5c..3a598b2e7 100755 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -165,6 +165,12 @@ void PresentManager::Present(Frame* frame) { return; } + { + // If we have run too far ahead of command processing, wait. + std::unique_lock lock{queue_mutex}; + frame_cv.wait(lock, [&] { return present_queue.size() < FRAMES_IN_FLIGHT - 1; }); + } + scheduler.Record([this, frame](vk::CommandBuffer) { std::unique_lock lock{queue_mutex}; present_queue.push(frame); diff --git a/src/video_core/renderer_vulkan/vk_present_manager.h b/src/video_core/renderer_vulkan/vk_present_manager.h index 337171a09..493f0aae2 100755 --- a/src/video_core/renderer_vulkan/vk_present_manager.h +++ b/src/video_core/renderer_vulkan/vk_present_manager.h @@ -22,6 +22,10 @@ class Device; class Scheduler; class Swapchain; +// This should be plenty for the vast majority of cases. Most desktop platforms only +// provide up to 3 swapchain images. +constexpr size_t FRAMES_IN_FLIGHT = 7; + struct Frame { u32 width; u32 height; diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h index 2b74d740c..c4d832ae9 100755 --- a/src/video_core/renderer_vulkan/vk_update_descriptor.h +++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h @@ -5,6 +5,7 @@ #include +#include "video_core/renderer_vulkan/vk_present_manager.h" #include "video_core/vulkan_common/vulkan_wrapper.h" namespace Vulkan { @@ -29,9 +30,6 @@ struct DescriptorUpdateEntry { }; class UpdateDescriptorQueue final { - // This should be plenty for the vast majority of cases. Most desktop platforms only - // provide up to 3 swapchain images. - static constexpr size_t FRAMES_IN_FLIGHT = 7; static constexpr size_t FRAME_PAYLOAD_SIZE = 0x20000; static constexpr size_t PAYLOAD_SIZE = FRAME_PAYLOAD_SIZE * FRAMES_IN_FLIGHT;