summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/common/logging/backend.cpp50
-rw-r--r--src/common/logging/backend.h4
-rw-r--r--src/core/hle/service/audio/audren_u.cpp37
-rw-r--r--src/core/hle/service/audio/audren_u.h3
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp116
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h87
-rw-r--r--src/web_service/verify_login.h2
-rw-r--r--src/web_service/web_backend.cpp1
-rw-r--r--src/yuzu/compatdb.cpp2
-rw-r--r--src/yuzu/main.cpp5
12 files changed, 268 insertions, 43 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index b369f199f..4462ff3fb 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -39,8 +39,10 @@ public:
Impl(Impl const&) = delete;
const Impl& operator=(Impl const&) = delete;
- void PushEntry(Entry e) {
- message_queue.Push(std::move(e));
+ void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
+ const char* function, std::string message) {
+ message_queue.Push(
+ CreateEntry(log_class, log_level, filename, line_num, function, std::move(message)));
}
void AddBackend(std::unique_ptr<Backend> backend) {
@@ -108,11 +110,30 @@ private:
backend_thread.join();
}
+ Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
+ const char* function, std::string message) const {
+ using std::chrono::duration_cast;
+ using std::chrono::steady_clock;
+
+ Entry entry;
+ entry.timestamp =
+ duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin);
+ entry.log_class = log_class;
+ entry.log_level = log_level;
+ entry.filename = Common::TrimSourcePath(filename);
+ entry.line_num = line_nr;
+ entry.function = function;
+ entry.message = std::move(message);
+
+ return entry;
+ }
+
std::mutex writing_mutex;
std::thread backend_thread;
std::vector<std::unique_ptr<Backend>> backends;
Common::MPSCQueue<Log::Entry> message_queue;
Filter filter;
+ std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
};
void ConsoleBackend::Write(const Entry& entry) {
@@ -271,25 +292,6 @@ const char* GetLevelName(Level log_level) {
#undef LVL
}
-Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
- const char* function, std::string message) {
- using std::chrono::duration_cast;
- using std::chrono::steady_clock;
-
- static steady_clock::time_point time_origin = steady_clock::now();
-
- Entry entry;
- entry.timestamp = duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin);
- entry.log_class = log_class;
- entry.log_level = log_level;
- entry.filename = Common::TrimSourcePath(filename);
- entry.line_num = line_nr;
- entry.function = function;
- entry.message = std::move(message);
-
- return entry;
-}
-
void SetGlobalFilter(const Filter& filter) {
Impl::Instance().SetGlobalFilter(filter);
}
@@ -314,9 +316,7 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
if (!filter.CheckMessage(log_class, log_level))
return;
- Entry entry =
- CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args));
-
- instance.PushEntry(std::move(entry));
+ instance.PushEntry(log_class, log_level, filename, line_num, function,
+ fmt::vformat(format, args));
}
} // namespace Log
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index a31ee6968..fca0267a1 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -135,10 +135,6 @@ const char* GetLogClassName(Class log_class);
*/
const char* GetLevelName(Level log_level);
-/// Creates a log entry by formatting the given source location, and message.
-Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
- const char* function, std::string message);
-
/**
* The global filter will prevent any messages from even being processed if they are filtered. Each
* backend can have a filter, but if the level is lower than the global filter, the backend will
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 49648394c..ea8f9d0bb 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -37,7 +37,7 @@ public:
{8, &IAudioRenderer::SetRenderingTimeLimit, "SetRenderingTimeLimit"},
{9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"},
{10, &IAudioRenderer::RequestUpdateImpl, "RequestUpdateAuto"},
- {11, nullptr, "ExecuteAudioRendererRendering"},
+ {11, &IAudioRenderer::ExecuteAudioRendererRendering, "ExecuteAudioRendererRendering"},
};
// clang-format on
RegisterHandlers(functions);
@@ -138,6 +138,17 @@ private:
rb.Push(rendering_time_limit_percent);
}
+ void ExecuteAudioRendererRendering(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+
+ // This service command currently only reports an unsupported operation
+ // error code, or aborts. Given that, we just always return an error
+ // code in this case.
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultCode{ErrorModule::Audio, 201});
+ }
+
Kernel::EventPair system_event;
std::unique_ptr<AudioCore::AudioRenderer> renderer;
u32 rendering_time_limit_percent = 100;
@@ -235,7 +246,7 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") {
{0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
{1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"},
{2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"},
- {3, nullptr, "OpenAudioRendererAuto"},
+ {3, &AudRenU::OpenAudioRendererAuto, "OpenAudioRendererAuto"},
{4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"},
};
// clang-format on
@@ -248,12 +259,7 @@ AudRenU::~AudRenU() = default;
void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
- IPC::RequestParser rp{ctx};
- auto params = rp.PopRaw<AudioCore::AudioRendererParameter>();
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-
- rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<Audio::IAudioRenderer>(std::move(params));
+ OpenAudioRendererImpl(ctx);
}
void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
@@ -325,6 +331,12 @@ void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<Audio::IAudioDevice>();
}
+void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+
+ OpenAudioRendererImpl(ctx);
+}
+
void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
@@ -335,6 +347,15 @@ void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& c
// based on the current revision
}
+void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto params = rp.PopRaw<AudioCore::AudioRendererParameter>();
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IAudioRenderer>(params);
+}
+
bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const {
u32_be version_num = (revision - Common::MakeMagic('R', 'E', 'V', '0')); // Byte swap
switch (feature) {
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index 3d63388fb..e55d25973 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -21,8 +21,11 @@ private:
void OpenAudioRenderer(Kernel::HLERequestContext& ctx);
void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx);
void GetAudioDeviceService(Kernel::HLERequestContext& ctx);
+ void OpenAudioRendererAuto(Kernel::HLERequestContext& ctx);
void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx);
+ void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx);
+
enum class AudioFeatures : u32 {
Splitter,
};
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 60529323e..3e9d2b3be 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -104,6 +104,8 @@ add_library(video_core STATIC
if (ENABLE_VULKAN)
target_sources(video_core PRIVATE
renderer_vulkan/declarations.h
+ renderer_vulkan/vk_buffer_cache.cpp
+ renderer_vulkan/vk_buffer_cache.h
renderer_vulkan/vk_device.cpp
renderer_vulkan/vk_device.h
renderer_vulkan/vk_memory_manager.cpp
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 5fdf1164d..b5a9722f9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -966,7 +966,7 @@ Surface RasterizerCacheOpenGL::GetColorBufferSurface(std::size_t index, bool pre
const auto& regs{gpu.regs};
if (!gpu.dirty_flags.color_buffer[index]) {
- return last_color_buffers[index];
+ return current_color_buffers[index];
}
gpu.dirty_flags.color_buffer.reset(index);
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
new file mode 100644
index 000000000..18b7b94a1
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -0,0 +1,116 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <cstring>
+#include <memory>
+#include <optional>
+#include <tuple>
+
+#include "common/alignment.h"
+#include "core/core.h"
+#include "core/memory.h"
+#include "video_core/renderer_vulkan/declarations.h"
+#include "video_core/renderer_vulkan/vk_buffer_cache.h"
+#include "video_core/renderer_vulkan/vk_scheduler.h"
+#include "video_core/renderer_vulkan/vk_stream_buffer.h"
+
+namespace Vulkan {
+
+VKBufferCache::VKBufferCache(Tegra::MemoryManager& tegra_memory_manager,
+ VideoCore::RasterizerInterface& rasterizer, const VKDevice& device,
+ VKMemoryManager& memory_manager, VKScheduler& scheduler, u64 size)
+ : RasterizerCache{rasterizer}, tegra_memory_manager{tegra_memory_manager} {
+ const auto usage = vk::BufferUsageFlagBits::eVertexBuffer |
+ vk::BufferUsageFlagBits::eIndexBuffer |
+ vk::BufferUsageFlagBits::eUniformBuffer;
+ const auto access = vk::AccessFlagBits::eVertexAttributeRead | vk::AccessFlagBits::eIndexRead |
+ vk::AccessFlagBits::eUniformRead;
+ stream_buffer =
+ std::make_unique<VKStreamBuffer>(device, memory_manager, scheduler, size, usage, access,
+ vk::PipelineStageFlagBits::eAllCommands);
+ buffer_handle = stream_buffer->GetBuffer();
+}
+
+VKBufferCache::~VKBufferCache() = default;
+
+u64 VKBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, u64 alignment,
+ bool cache) {
+ const auto cpu_addr{tegra_memory_manager.GpuToCpuAddress(gpu_addr)};
+ ASSERT(cpu_addr);
+
+ // Cache management is a big overhead, so only cache entries with a given size.
+ // TODO: Figure out which size is the best for given games.
+ cache &= size >= 2048;
+
+ if (cache) {
+ if (auto entry = TryGet(*cpu_addr); entry) {
+ if (entry->size >= size && entry->alignment == alignment) {
+ return entry->offset;
+ }
+ Unregister(entry);
+ }
+ }
+
+ AlignBuffer(alignment);
+ const u64 uploaded_offset = buffer_offset;
+
+ Memory::ReadBlock(*cpu_addr, buffer_ptr, size);
+
+ buffer_ptr += size;
+ buffer_offset += size;
+
+ if (cache) {
+ auto entry = std::make_shared<CachedBufferEntry>();
+ entry->offset = uploaded_offset;
+ entry->size = size;
+ entry->alignment = alignment;
+ entry->addr = *cpu_addr;
+ Register(entry);
+ }
+
+ return uploaded_offset;
+}
+
+u64 VKBufferCache::UploadHostMemory(const u8* raw_pointer, std::size_t size, u64 alignment) {
+ AlignBuffer(alignment);
+ std::memcpy(buffer_ptr, raw_pointer, size);
+ const u64 uploaded_offset = buffer_offset;
+
+ buffer_ptr += size;
+ buffer_offset += size;
+ return uploaded_offset;
+}
+
+std::tuple<u8*, u64> VKBufferCache::ReserveMemory(std::size_t size, u64 alignment) {
+ AlignBuffer(alignment);
+ u8* const uploaded_ptr = buffer_ptr;
+ const u64 uploaded_offset = buffer_offset;
+
+ buffer_ptr += size;
+ buffer_offset += size;
+ return {uploaded_ptr, uploaded_offset};
+}
+
+void VKBufferCache::Reserve(std::size_t max_size) {
+ bool invalidate;
+ std::tie(buffer_ptr, buffer_offset_base, invalidate) = stream_buffer->Reserve(max_size);
+ buffer_offset = buffer_offset_base;
+
+ if (invalidate) {
+ InvalidateAll();
+ }
+}
+
+VKExecutionContext VKBufferCache::Send(VKExecutionContext exctx) {
+ return stream_buffer->Send(exctx, buffer_offset - buffer_offset_base);
+}
+
+void VKBufferCache::AlignBuffer(std::size_t alignment) {
+ // Align the offset, not the mapped pointer
+ const u64 offset_aligned = Common::AlignUp(buffer_offset, alignment);
+ buffer_ptr += offset_aligned - buffer_offset;
+ buffer_offset = offset_aligned;
+}
+
+} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
new file mode 100644
index 000000000..d8e916f31
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -0,0 +1,87 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <tuple>
+
+#include "common/common_types.h"
+#include "video_core/gpu.h"
+#include "video_core/rasterizer_cache.h"
+#include "video_core/renderer_vulkan/declarations.h"
+#include "video_core/renderer_vulkan/vk_scheduler.h"
+
+namespace Tegra {
+class MemoryManager;
+}
+
+namespace Vulkan {
+
+class VKDevice;
+class VKFence;
+class VKMemoryManager;
+class VKStreamBuffer;
+
+struct CachedBufferEntry final : public RasterizerCacheObject {
+ VAddr GetAddr() const override {
+ return addr;
+ }
+
+ std::size_t GetSizeInBytes() const override {
+ return size;
+ }
+
+ // We do not have to flush this cache as things in it are never modified by us.
+ void Flush() override {}
+
+ VAddr addr;
+ std::size_t size;
+ u64 offset;
+ std::size_t alignment;
+};
+
+class VKBufferCache final : public RasterizerCache<std::shared_ptr<CachedBufferEntry>> {
+public:
+ explicit VKBufferCache(Tegra::MemoryManager& tegra_memory_manager,
+ VideoCore::RasterizerInterface& rasterizer, const VKDevice& device,
+ VKMemoryManager& memory_manager, VKScheduler& scheduler, u64 size);
+ ~VKBufferCache();
+
+ /// Uploads data from a guest GPU address. Returns host's buffer offset where it's been
+ /// allocated.
+ u64 UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, u64 alignment = 4,
+ bool cache = true);
+
+ /// Uploads from a host memory. Returns host's buffer offset where it's been allocated.
+ u64 UploadHostMemory(const u8* raw_pointer, std::size_t size, u64 alignment = 4);
+
+ /// Reserves memory to be used by host's CPU. Returns mapped address and offset.
+ std::tuple<u8*, u64> ReserveMemory(std::size_t size, u64 alignment = 4);
+
+ /// Reserves a region of memory to be used in subsequent upload/reserve operations.
+ void Reserve(std::size_t max_size);
+
+ /// Ensures that the set data is sent to the device.
+ [[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx);
+
+ /// Returns the buffer cache handle.
+ vk::Buffer GetBuffer() const {
+ return buffer_handle;
+ }
+
+private:
+ void AlignBuffer(std::size_t alignment);
+
+ Tegra::MemoryManager& tegra_memory_manager;
+
+ std::unique_ptr<VKStreamBuffer> stream_buffer;
+ vk::Buffer buffer_handle;
+
+ u8* buffer_ptr = nullptr;
+ u64 buffer_offset = 0;
+ u64 buffer_offset_base = 0;
+};
+
+} // namespace Vulkan
diff --git a/src/web_service/verify_login.h b/src/web_service/verify_login.h
index 39db32dbb..821b345d7 100644
--- a/src/web_service/verify_login.h
+++ b/src/web_service/verify_login.h
@@ -4,8 +4,6 @@
#pragma once
-#include <functional>
-#include <future>
#include <string>
namespace WebService {
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp
index b7737b615..40da1a4e2 100644
--- a/src/web_service/web_backend.cpp
+++ b/src/web_service/web_backend.cpp
@@ -10,7 +10,6 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/web_result.h"
-#include "core/settings.h"
#include "web_service/web_backend.h"
namespace WebService {
diff --git a/src/yuzu/compatdb.cpp b/src/yuzu/compatdb.cpp
index 5f0896f84..c09a06520 100644
--- a/src/yuzu/compatdb.cpp
+++ b/src/yuzu/compatdb.cpp
@@ -61,7 +61,7 @@ void CompatDB::Submit() {
button(QWizard::CancelButton)->setVisible(false);
testcase_watcher.setFuture(QtConcurrent::run(
- [this]() { return Core::System::GetInstance().TelemetrySession().SubmitTestcase(); }));
+ [] { return Core::System::GetInstance().TelemetrySession().SubmitTestcase(); }));
break;
default:
LOG_ERROR(Frontend, "Unexpected page: {}", currentId());
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 1d460c189..5ab7896d4 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -561,7 +561,10 @@ void GMainWindow::InitializeHotkeys() {
Settings::values.use_frame_limit = !Settings::values.use_frame_limit;
UpdateStatusBar();
});
- constexpr u16 SPEED_LIMIT_STEP = 5;
+ // TODO: Remove this comment/static whenever the next major release of
+ // MSVC occurs and we make it a requirement (see:
+ // https://developercommunity.visualstudio.com/content/problem/93922/constexprs-are-trying-to-be-captured-in-lambda-fun.html)
+ static constexpr u16 SPEED_LIMIT_STEP = 5;
connect(hotkey_registry.GetHotkey("Main Window", "Increase Speed Limit", this),
&QShortcut::activated, this, [&] {
if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) {