early-access version 1798

This commit is contained in:
pineappleEA 2021-06-20 20:27:37 +02:00
parent 424fda557d
commit 6924d51f6d
9 changed files with 147 additions and 91 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 1797. This is the source code for early-access 1798.
## Legal Notice ## Legal Notice

View file

@ -12,6 +12,7 @@
#include "audio_core/voice_context.h" #include "audio_core/voice_context.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h" #include "common/settings.h"
#include "core/core_timing.h"
#include "core/memory.h" #include "core/memory.h"
namespace { namespace {
@ -68,7 +69,7 @@ namespace {
} // namespace } // namespace
namespace AudioCore { namespace AudioCore {
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_,
AudioCommon::AudioRendererParameter params, AudioCommon::AudioRendererParameter params,
Stream::ReleaseCallback&& release_callback, Stream::ReleaseCallback&& release_callback,
std::size_t instance_number) std::size_t instance_number)
@ -77,7 +78,8 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory
sink_context(params.sink_count), splitter_context(), sink_context(params.sink_count), splitter_context(),
voices(params.voice_count), memory{memory_}, voices(params.voice_count), memory{memory_},
command_generator(worker_params, voice_context, mix_context, splitter_context, effect_context, command_generator(worker_params, voice_context, mix_context, splitter_context, effect_context,
memory) { memory),
core_timing{core_timing_} {
behavior_info.SetUserRevision(params.revision); behavior_info.SetUserRevision(params.revision);
splitter_context.Initialize(behavior_info, params.splitter_count, splitter_context.Initialize(behavior_info, params.splitter_count,
params.num_splitter_send_channels); params.num_splitter_send_channels);
@ -86,16 +88,27 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory
stream = audio_out->OpenStream( stream = audio_out->OpenStream(
core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS, core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS,
fmt::format("AudioRenderer-Instance{}", instance_number), std::move(release_callback)); fmt::format("AudioRenderer-Instance{}", instance_number), std::move(release_callback));
audio_out->StartStream(stream); process_event = Core::Timing::CreateEvent(
fmt::format("AudioRenderer-Instance{}-Consume", instance_number),
QueueMixedBuffer(0); [this](std::uintptr_t, std::chrono::nanoseconds) { ReleaseAndQueueBuffers(); });
QueueMixedBuffer(1); for (size_t i = 0; i < NUM_BUFFERS; ++i) {
QueueMixedBuffer(2); QueueMixedBuffer(i);
QueueMixedBuffer(3); }
} }
AudioRenderer::~AudioRenderer() = default; AudioRenderer::~AudioRenderer() = default;
ResultCode AudioRenderer::Start() {
audio_out->StartStream(stream);
ReleaseAndQueueBuffers();
return ResultSuccess;
}
ResultCode AudioRenderer::Stop() {
audio_out->StopStream(stream);
return ResultSuccess;
}
u32 AudioRenderer::GetSampleRate() const { u32 AudioRenderer::GetSampleRate() const {
return worker_params.sample_rate; return worker_params.sample_rate;
} }
@ -114,7 +127,8 @@ Stream::State AudioRenderer::GetStreamState() const {
ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params, ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params,
std::vector<u8>& output_params) { std::vector<u8>& output_params) {
{
std::scoped_lock l{lock};
InfoUpdater info_updater{input_params, output_params, behavior_info}; InfoUpdater info_updater{input_params, output_params, behavior_info};
if (!info_updater.UpdateBehaviorInfo(behavior_info)) { if (!info_updater.UpdateBehaviorInfo(behavior_info)) {
@ -150,8 +164,8 @@ ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_param
} }
} }
const auto mix_result = info_updater.UpdateMixes(mix_context, worker_params.mix_buffer_count, const auto mix_result = info_updater.UpdateMixes(
splitter_context, effect_context); mix_context, worker_params.mix_buffer_count, splitter_context, effect_context);
if (mix_result.IsError()) { if (mix_result.IsError()) {
LOG_ERROR(Audio, "Failed to update mix parameters"); LOG_ERROR(Audio, "Failed to update mix parameters");
@ -194,9 +208,7 @@ ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_param
LOG_ERROR(Audio, "Audio buffers were not consumed!"); LOG_ERROR(Audio, "Audio buffers were not consumed!");
return AudioCommon::Audren::ERR_INVALID_PARAMETERS; return AudioCommon::Audren::ERR_INVALID_PARAMETERS;
} }
}
ReleaseAndQueueBuffers();
return ResultSuccess; return ResultSuccess;
} }
@ -315,10 +327,24 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
} }
void AudioRenderer::ReleaseAndQueueBuffers() { void AudioRenderer::ReleaseAndQueueBuffers() {
if (!stream->IsPlaying()) {
return;
}
{
std::scoped_lock l{lock};
const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream)}; const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream)};
for (const auto& tag : released_buffers) { for (const auto& tag : released_buffers) {
QueueMixedBuffer(tag); QueueMixedBuffer(tag);
} }
}
const f32 sampleRate = static_cast<f32>(GetSampleRate());
const f32 sampleCount = static_cast<f32>(GetSampleCount());
const f32 consumeRate = sampleRate / (sampleCount * (sampleCount / 240));
const s32 ms = (1000 / static_cast<s32>(consumeRate)) - 1;
const std::chrono::milliseconds next_event_time(std::max(ms / NUM_BUFFERS, 1));
core_timing.ScheduleEvent(next_event_time, process_event, {});
} }
} // namespace AudioCore } // namespace AudioCore

View file

@ -6,6 +6,7 @@
#include <array> #include <array>
#include <memory> #include <memory>
#include <mutex>
#include <vector> #include <vector>
#include "audio_core/behavior_info.h" #include "audio_core/behavior_info.h"
@ -33,6 +34,7 @@ class Memory;
namespace AudioCore { namespace AudioCore {
using DSPStateHolder = std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT>; using DSPStateHolder = std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT>;
constexpr s32 NUM_BUFFERS = 2;
class AudioOut; class AudioOut;
@ -45,6 +47,8 @@ public:
[[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params, [[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params,
std::vector<u8>& output_params); std::vector<u8>& output_params);
[[nodiscard]] ResultCode Start();
[[nodiscard]] ResultCode Stop();
void QueueMixedBuffer(Buffer::Tag tag); void QueueMixedBuffer(Buffer::Tag tag);
void ReleaseAndQueueBuffers(); void ReleaseAndQueueBuffers();
[[nodiscard]] u32 GetSampleRate() const; [[nodiscard]] u32 GetSampleRate() const;
@ -68,6 +72,9 @@ private:
Core::Memory::Memory& memory; Core::Memory::Memory& memory;
CommandGenerator command_generator; CommandGenerator command_generator;
std::size_t elapsed_frame_count{}; std::size_t elapsed_frame_count{};
Core::Timing::CoreTiming& core_timing;
std::shared_ptr<Core::Timing::EventType> process_event;
std::mutex lock;
}; };
} // namespace AudioCore } // namespace AudioCore

View file

@ -110,17 +110,19 @@ private:
void Start(Kernel::HLERequestContext& ctx) { void Start(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called"); LOG_WARNING(Service_Audio, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2}; const auto result = renderer->Start();
rb.Push(ResultSuccess); IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void Stop(Kernel::HLERequestContext& ctx) { void Stop(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called"); LOG_WARNING(Service_Audio, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2}; const auto result = renderer->Stop();
rb.Push(ResultSuccess); IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void QuerySystemEvent(Kernel::HLERequestContext& ctx) { void QuerySystemEvent(Kernel::HLERequestContext& ctx) {

View file

@ -737,6 +737,8 @@ Image::Image(TextureCacheRuntime& runtime, const VideoCommon::ImageInfo& info_,
} }
} }
Image::~Image() = default;
void Image::UploadMemory(const ImageBufferMap& map, void Image::UploadMemory(const ImageBufferMap& map,
std::span<const VideoCommon::BufferImageCopy> copies) { std::span<const VideoCommon::BufferImageCopy> copies) {
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, map.buffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, map.buffer);

View file

@ -143,6 +143,14 @@ public:
explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr, explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr,
VAddr cpu_addr); VAddr cpu_addr);
~Image();
Image(const Image&) = delete;
Image& operator=(const Image&) = delete;
Image(Image&&) = default;
Image& operator=(Image&&) = default;
void UploadMemory(const ImageBufferMap& map, void UploadMemory(const ImageBufferMap& map,
std::span<const VideoCommon::BufferImageCopy> copies); std::span<const VideoCommon::BufferImageCopy> copies);

View file

@ -880,6 +880,8 @@ Image::Image(TextureCacheRuntime& runtime, const ImageInfo& info_, GPUVAddr gpu_
} }
} }
Image::~Image() = default;
void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) {
// TODO: Move this to another API // TODO: Move this to another API
scheduler->RequestOutsideRenderPassOperationContext(); scheduler->RequestOutsideRenderPassOperationContext();

View file

@ -106,6 +106,14 @@ public:
explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr, explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr,
VAddr cpu_addr); VAddr cpu_addr);
~Image();
Image(const Image&) = delete;
Image& operator=(const Image&) = delete;
Image(Image&&) = default;
Image& operator=(Image&&) = default;
void UploadMemory(const StagingBufferRef& map, void UploadMemory(const StagingBufferRef& map,
std::span<const VideoCommon::BufferImageCopy> copies); std::span<const VideoCommon::BufferImageCopy> copies);

View file

@ -397,8 +397,9 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY); expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY);
critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY); critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY);
} else { } else {
expected_memory = DEFAULT_EXPECTED_MEMORY; // on OGL we can be more conservatives as the driver takes care.
critical_memory = DEFAULT_CRITICAL_MEMORY; expected_memory = DEFAULT_EXPECTED_MEMORY + Common::Size_512_MB;
critical_memory = DEFAULT_CRITICAL_MEMORY + Common::Size_1_GB;
} }
} }