diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/logging/backend.cpp | 50 | ||||
| -rw-r--r-- | src/common/logging/backend.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 37 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.h | 3 | ||||
| -rw-r--r-- | src/video_core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.cpp | 116 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.h | 87 | ||||
| -rw-r--r-- | src/web_service/verify_login.h | 2 | ||||
| -rw-r--r-- | src/web_service/web_backend.cpp | 1 | ||||
| -rw-r--r-- | src/yuzu/compatdb.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 5 |
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: | |||
| 39 | Impl(Impl const&) = delete; | 39 | Impl(Impl const&) = delete; |
| 40 | const Impl& operator=(Impl const&) = delete; | 40 | const Impl& operator=(Impl const&) = delete; |
| 41 | 41 | ||
| 42 | void PushEntry(Entry e) { | 42 | void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, |
| 43 | message_queue.Push(std::move(e)); | 43 | const char* function, std::string message) { |
| 44 | message_queue.Push( | ||
| 45 | CreateEntry(log_class, log_level, filename, line_num, function, std::move(message))); | ||
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | void AddBackend(std::unique_ptr<Backend> backend) { | 48 | void AddBackend(std::unique_ptr<Backend> backend) { |
| @@ -108,11 +110,30 @@ private: | |||
| 108 | backend_thread.join(); | 110 | backend_thread.join(); |
| 109 | } | 111 | } |
| 110 | 112 | ||
| 113 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | ||
| 114 | const char* function, std::string message) const { | ||
| 115 | using std::chrono::duration_cast; | ||
| 116 | using std::chrono::steady_clock; | ||
| 117 | |||
| 118 | Entry entry; | ||
| 119 | entry.timestamp = | ||
| 120 | duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin); | ||
| 121 | entry.log_class = log_class; | ||
| 122 | entry.log_level = log_level; | ||
| 123 | entry.filename = Common::TrimSourcePath(filename); | ||
| 124 | entry.line_num = line_nr; | ||
| 125 | entry.function = function; | ||
| 126 | entry.message = std::move(message); | ||
| 127 | |||
| 128 | return entry; | ||
| 129 | } | ||
| 130 | |||
| 111 | std::mutex writing_mutex; | 131 | std::mutex writing_mutex; |
| 112 | std::thread backend_thread; | 132 | std::thread backend_thread; |
| 113 | std::vector<std::unique_ptr<Backend>> backends; | 133 | std::vector<std::unique_ptr<Backend>> backends; |
| 114 | Common::MPSCQueue<Log::Entry> message_queue; | 134 | Common::MPSCQueue<Log::Entry> message_queue; |
| 115 | Filter filter; | 135 | Filter filter; |
| 136 | std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; | ||
| 116 | }; | 137 | }; |
| 117 | 138 | ||
| 118 | void ConsoleBackend::Write(const Entry& entry) { | 139 | void ConsoleBackend::Write(const Entry& entry) { |
| @@ -271,25 +292,6 @@ const char* GetLevelName(Level log_level) { | |||
| 271 | #undef LVL | 292 | #undef LVL |
| 272 | } | 293 | } |
| 273 | 294 | ||
| 274 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | ||
| 275 | const char* function, std::string message) { | ||
| 276 | using std::chrono::duration_cast; | ||
| 277 | using std::chrono::steady_clock; | ||
| 278 | |||
| 279 | static steady_clock::time_point time_origin = steady_clock::now(); | ||
| 280 | |||
| 281 | Entry entry; | ||
| 282 | entry.timestamp = duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin); | ||
| 283 | entry.log_class = log_class; | ||
| 284 | entry.log_level = log_level; | ||
| 285 | entry.filename = Common::TrimSourcePath(filename); | ||
| 286 | entry.line_num = line_nr; | ||
| 287 | entry.function = function; | ||
| 288 | entry.message = std::move(message); | ||
| 289 | |||
| 290 | return entry; | ||
| 291 | } | ||
| 292 | |||
| 293 | void SetGlobalFilter(const Filter& filter) { | 295 | void SetGlobalFilter(const Filter& filter) { |
| 294 | Impl::Instance().SetGlobalFilter(filter); | 296 | Impl::Instance().SetGlobalFilter(filter); |
| 295 | } | 297 | } |
| @@ -314,9 +316,7 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, | |||
| 314 | if (!filter.CheckMessage(log_class, log_level)) | 316 | if (!filter.CheckMessage(log_class, log_level)) |
| 315 | return; | 317 | return; |
| 316 | 318 | ||
| 317 | Entry entry = | 319 | instance.PushEntry(log_class, log_level, filename, line_num, function, |
| 318 | CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args)); | 320 | fmt::vformat(format, args)); |
| 319 | |||
| 320 | instance.PushEntry(std::move(entry)); | ||
| 321 | } | 321 | } |
| 322 | } // namespace Log | 322 | } // 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); | |||
| 135 | */ | 135 | */ |
| 136 | const char* GetLevelName(Level log_level); | 136 | const char* GetLevelName(Level log_level); |
| 137 | 137 | ||
| 138 | /// Creates a log entry by formatting the given source location, and message. | ||
| 139 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | ||
| 140 | const char* function, std::string message); | ||
| 141 | |||
| 142 | /** | 138 | /** |
| 143 | * The global filter will prevent any messages from even being processed if they are filtered. Each | 139 | * The global filter will prevent any messages from even being processed if they are filtered. Each |
| 144 | * backend can have a filter, but if the level is lower than the global filter, the backend will | 140 | * 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: | |||
| 37 | {8, &IAudioRenderer::SetRenderingTimeLimit, "SetRenderingTimeLimit"}, | 37 | {8, &IAudioRenderer::SetRenderingTimeLimit, "SetRenderingTimeLimit"}, |
| 38 | {9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"}, | 38 | {9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"}, |
| 39 | {10, &IAudioRenderer::RequestUpdateImpl, "RequestUpdateAuto"}, | 39 | {10, &IAudioRenderer::RequestUpdateImpl, "RequestUpdateAuto"}, |
| 40 | {11, nullptr, "ExecuteAudioRendererRendering"}, | 40 | {11, &IAudioRenderer::ExecuteAudioRendererRendering, "ExecuteAudioRendererRendering"}, |
| 41 | }; | 41 | }; |
| 42 | // clang-format on | 42 | // clang-format on |
| 43 | RegisterHandlers(functions); | 43 | RegisterHandlers(functions); |
| @@ -138,6 +138,17 @@ private: | |||
| 138 | rb.Push(rendering_time_limit_percent); | 138 | rb.Push(rendering_time_limit_percent); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | void ExecuteAudioRendererRendering(Kernel::HLERequestContext& ctx) { | ||
| 142 | LOG_DEBUG(Service_Audio, "called"); | ||
| 143 | |||
| 144 | // This service command currently only reports an unsupported operation | ||
| 145 | // error code, or aborts. Given that, we just always return an error | ||
| 146 | // code in this case. | ||
| 147 | |||
| 148 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 149 | rb.Push(ResultCode{ErrorModule::Audio, 201}); | ||
| 150 | } | ||
| 151 | |||
| 141 | Kernel::EventPair system_event; | 152 | Kernel::EventPair system_event; |
| 142 | std::unique_ptr<AudioCore::AudioRenderer> renderer; | 153 | std::unique_ptr<AudioCore::AudioRenderer> renderer; |
| 143 | u32 rendering_time_limit_percent = 100; | 154 | u32 rendering_time_limit_percent = 100; |
| @@ -235,7 +246,7 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") { | |||
| 235 | {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, | 246 | {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, |
| 236 | {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"}, | 247 | {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"}, |
| 237 | {2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"}, | 248 | {2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"}, |
| 238 | {3, nullptr, "OpenAudioRendererAuto"}, | 249 | {3, &AudRenU::OpenAudioRendererAuto, "OpenAudioRendererAuto"}, |
| 239 | {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"}, | 250 | {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"}, |
| 240 | }; | 251 | }; |
| 241 | // clang-format on | 252 | // clang-format on |
| @@ -248,12 +259,7 @@ AudRenU::~AudRenU() = default; | |||
| 248 | void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { | 259 | void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { |
| 249 | LOG_DEBUG(Service_Audio, "called"); | 260 | LOG_DEBUG(Service_Audio, "called"); |
| 250 | 261 | ||
| 251 | IPC::RequestParser rp{ctx}; | 262 | OpenAudioRendererImpl(ctx); |
| 252 | auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); | ||
| 253 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 254 | |||
| 255 | rb.Push(RESULT_SUCCESS); | ||
| 256 | rb.PushIpcInterface<Audio::IAudioRenderer>(std::move(params)); | ||
| 257 | } | 263 | } |
| 258 | 264 | ||
| 259 | void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { | 265 | void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { |
| @@ -325,6 +331,12 @@ void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) { | |||
| 325 | rb.PushIpcInterface<Audio::IAudioDevice>(); | 331 | rb.PushIpcInterface<Audio::IAudioDevice>(); |
| 326 | } | 332 | } |
| 327 | 333 | ||
| 334 | void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { | ||
| 335 | LOG_DEBUG(Service_Audio, "called"); | ||
| 336 | |||
| 337 | OpenAudioRendererImpl(ctx); | ||
| 338 | } | ||
| 339 | |||
| 328 | void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) { | 340 | void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) { |
| 329 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 341 | LOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 330 | 342 | ||
| @@ -335,6 +347,15 @@ void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& c | |||
| 335 | // based on the current revision | 347 | // based on the current revision |
| 336 | } | 348 | } |
| 337 | 349 | ||
| 350 | void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) { | ||
| 351 | IPC::RequestParser rp{ctx}; | ||
| 352 | const auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); | ||
| 353 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 354 | |||
| 355 | rb.Push(RESULT_SUCCESS); | ||
| 356 | rb.PushIpcInterface<IAudioRenderer>(params); | ||
| 357 | } | ||
| 358 | |||
| 338 | bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const { | 359 | bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const { |
| 339 | u32_be version_num = (revision - Common::MakeMagic('R', 'E', 'V', '0')); // Byte swap | 360 | u32_be version_num = (revision - Common::MakeMagic('R', 'E', 'V', '0')); // Byte swap |
| 340 | switch (feature) { | 361 | 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: | |||
| 21 | void OpenAudioRenderer(Kernel::HLERequestContext& ctx); | 21 | void OpenAudioRenderer(Kernel::HLERequestContext& ctx); |
| 22 | void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); | 22 | void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); |
| 23 | void GetAudioDeviceService(Kernel::HLERequestContext& ctx); | 23 | void GetAudioDeviceService(Kernel::HLERequestContext& ctx); |
| 24 | void OpenAudioRendererAuto(Kernel::HLERequestContext& ctx); | ||
| 24 | void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx); | 25 | void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx); |
| 25 | 26 | ||
| 27 | void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx); | ||
| 28 | |||
| 26 | enum class AudioFeatures : u32 { | 29 | enum class AudioFeatures : u32 { |
| 27 | Splitter, | 30 | Splitter, |
| 28 | }; | 31 | }; |
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 | |||
| 104 | if (ENABLE_VULKAN) | 104 | if (ENABLE_VULKAN) |
| 105 | target_sources(video_core PRIVATE | 105 | target_sources(video_core PRIVATE |
| 106 | renderer_vulkan/declarations.h | 106 | renderer_vulkan/declarations.h |
| 107 | renderer_vulkan/vk_buffer_cache.cpp | ||
| 108 | renderer_vulkan/vk_buffer_cache.h | ||
| 107 | renderer_vulkan/vk_device.cpp | 109 | renderer_vulkan/vk_device.cpp |
| 108 | renderer_vulkan/vk_device.h | 110 | renderer_vulkan/vk_device.h |
| 109 | renderer_vulkan/vk_memory_manager.cpp | 111 | 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 | |||
| 966 | const auto& regs{gpu.regs}; | 966 | const auto& regs{gpu.regs}; |
| 967 | 967 | ||
| 968 | if (!gpu.dirty_flags.color_buffer[index]) { | 968 | if (!gpu.dirty_flags.color_buffer[index]) { |
| 969 | return last_color_buffers[index]; | 969 | return current_color_buffers[index]; |
| 970 | } | 970 | } |
| 971 | gpu.dirty_flags.color_buffer.reset(index); | 971 | gpu.dirty_flags.color_buffer.reset(index); |
| 972 | 972 | ||
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 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <cstring> | ||
| 6 | #include <memory> | ||
| 7 | #include <optional> | ||
| 8 | #include <tuple> | ||
| 9 | |||
| 10 | #include "common/alignment.h" | ||
| 11 | #include "core/core.h" | ||
| 12 | #include "core/memory.h" | ||
| 13 | #include "video_core/renderer_vulkan/declarations.h" | ||
| 14 | #include "video_core/renderer_vulkan/vk_buffer_cache.h" | ||
| 15 | #include "video_core/renderer_vulkan/vk_scheduler.h" | ||
| 16 | #include "video_core/renderer_vulkan/vk_stream_buffer.h" | ||
| 17 | |||
| 18 | namespace Vulkan { | ||
| 19 | |||
| 20 | VKBufferCache::VKBufferCache(Tegra::MemoryManager& tegra_memory_manager, | ||
| 21 | VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, | ||
| 22 | VKMemoryManager& memory_manager, VKScheduler& scheduler, u64 size) | ||
| 23 | : RasterizerCache{rasterizer}, tegra_memory_manager{tegra_memory_manager} { | ||
| 24 | const auto usage = vk::BufferUsageFlagBits::eVertexBuffer | | ||
| 25 | vk::BufferUsageFlagBits::eIndexBuffer | | ||
| 26 | vk::BufferUsageFlagBits::eUniformBuffer; | ||
| 27 | const auto access = vk::AccessFlagBits::eVertexAttributeRead | vk::AccessFlagBits::eIndexRead | | ||
| 28 | vk::AccessFlagBits::eUniformRead; | ||
| 29 | stream_buffer = | ||
| 30 | std::make_unique<VKStreamBuffer>(device, memory_manager, scheduler, size, usage, access, | ||
| 31 | vk::PipelineStageFlagBits::eAllCommands); | ||
| 32 | buffer_handle = stream_buffer->GetBuffer(); | ||
| 33 | } | ||
| 34 | |||
| 35 | VKBufferCache::~VKBufferCache() = default; | ||
| 36 | |||
| 37 | u64 VKBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, u64 alignment, | ||
| 38 | bool cache) { | ||
| 39 | const auto cpu_addr{tegra_memory_manager.GpuToCpuAddress(gpu_addr)}; | ||
| 40 | ASSERT(cpu_addr); | ||
| 41 | |||
| 42 | // Cache management is a big overhead, so only cache entries with a given size. | ||
| 43 | // TODO: Figure out which size is the best for given games. | ||
| 44 | cache &= size >= 2048; | ||
| 45 | |||
| 46 | if (cache) { | ||
| 47 | if (auto entry = TryGet(*cpu_addr); entry) { | ||
| 48 | if (entry->size >= size && entry->alignment == alignment) { | ||
| 49 | return entry->offset; | ||
| 50 | } | ||
| 51 | Unregister(entry); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | AlignBuffer(alignment); | ||
| 56 | const u64 uploaded_offset = buffer_offset; | ||
| 57 | |||
| 58 | Memory::ReadBlock(*cpu_addr, buffer_ptr, size); | ||
| 59 | |||
| 60 | buffer_ptr += size; | ||
| 61 | buffer_offset += size; | ||
| 62 | |||
| 63 | if (cache) { | ||
| 64 | auto entry = std::make_shared<CachedBufferEntry>(); | ||
| 65 | entry->offset = uploaded_offset; | ||
| 66 | entry->size = size; | ||
| 67 | entry->alignment = alignment; | ||
| 68 | entry->addr = *cpu_addr; | ||
| 69 | Register(entry); | ||
| 70 | } | ||
| 71 | |||
| 72 | return uploaded_offset; | ||
| 73 | } | ||
| 74 | |||
| 75 | u64 VKBufferCache::UploadHostMemory(const u8* raw_pointer, std::size_t size, u64 alignment) { | ||
| 76 | AlignBuffer(alignment); | ||
| 77 | std::memcpy(buffer_ptr, raw_pointer, size); | ||
| 78 | const u64 uploaded_offset = buffer_offset; | ||
| 79 | |||
| 80 | buffer_ptr += size; | ||
| 81 | buffer_offset += size; | ||
| 82 | return uploaded_offset; | ||
| 83 | } | ||
| 84 | |||
| 85 | std::tuple<u8*, u64> VKBufferCache::ReserveMemory(std::size_t size, u64 alignment) { | ||
| 86 | AlignBuffer(alignment); | ||
| 87 | u8* const uploaded_ptr = buffer_ptr; | ||
| 88 | const u64 uploaded_offset = buffer_offset; | ||
| 89 | |||
| 90 | buffer_ptr += size; | ||
| 91 | buffer_offset += size; | ||
| 92 | return {uploaded_ptr, uploaded_offset}; | ||
| 93 | } | ||
| 94 | |||
| 95 | void VKBufferCache::Reserve(std::size_t max_size) { | ||
| 96 | bool invalidate; | ||
| 97 | std::tie(buffer_ptr, buffer_offset_base, invalidate) = stream_buffer->Reserve(max_size); | ||
| 98 | buffer_offset = buffer_offset_base; | ||
| 99 | |||
| 100 | if (invalidate) { | ||
| 101 | InvalidateAll(); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | VKExecutionContext VKBufferCache::Send(VKExecutionContext exctx) { | ||
| 106 | return stream_buffer->Send(exctx, buffer_offset - buffer_offset_base); | ||
| 107 | } | ||
| 108 | |||
| 109 | void VKBufferCache::AlignBuffer(std::size_t alignment) { | ||
| 110 | // Align the offset, not the mapped pointer | ||
| 111 | const u64 offset_aligned = Common::AlignUp(buffer_offset, alignment); | ||
| 112 | buffer_ptr += offset_aligned - buffer_offset; | ||
| 113 | buffer_offset = offset_aligned; | ||
| 114 | } | ||
| 115 | |||
| 116 | } // 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 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <tuple> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "video_core/gpu.h" | ||
| 12 | #include "video_core/rasterizer_cache.h" | ||
| 13 | #include "video_core/renderer_vulkan/declarations.h" | ||
| 14 | #include "video_core/renderer_vulkan/vk_scheduler.h" | ||
| 15 | |||
| 16 | namespace Tegra { | ||
| 17 | class MemoryManager; | ||
| 18 | } | ||
| 19 | |||
| 20 | namespace Vulkan { | ||
| 21 | |||
| 22 | class VKDevice; | ||
| 23 | class VKFence; | ||
| 24 | class VKMemoryManager; | ||
| 25 | class VKStreamBuffer; | ||
| 26 | |||
| 27 | struct CachedBufferEntry final : public RasterizerCacheObject { | ||
| 28 | VAddr GetAddr() const override { | ||
| 29 | return addr; | ||
| 30 | } | ||
| 31 | |||
| 32 | std::size_t GetSizeInBytes() const override { | ||
| 33 | return size; | ||
| 34 | } | ||
| 35 | |||
| 36 | // We do not have to flush this cache as things in it are never modified by us. | ||
| 37 | void Flush() override {} | ||
| 38 | |||
| 39 | VAddr addr; | ||
| 40 | std::size_t size; | ||
| 41 | u64 offset; | ||
| 42 | std::size_t alignment; | ||
| 43 | }; | ||
| 44 | |||
| 45 | class VKBufferCache final : public RasterizerCache<std::shared_ptr<CachedBufferEntry>> { | ||
| 46 | public: | ||
| 47 | explicit VKBufferCache(Tegra::MemoryManager& tegra_memory_manager, | ||
| 48 | VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, | ||
| 49 | VKMemoryManager& memory_manager, VKScheduler& scheduler, u64 size); | ||
| 50 | ~VKBufferCache(); | ||
| 51 | |||
| 52 | /// Uploads data from a guest GPU address. Returns host's buffer offset where it's been | ||
| 53 | /// allocated. | ||
| 54 | u64 UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, u64 alignment = 4, | ||
| 55 | bool cache = true); | ||
| 56 | |||
| 57 | /// Uploads from a host memory. Returns host's buffer offset where it's been allocated. | ||
| 58 | u64 UploadHostMemory(const u8* raw_pointer, std::size_t size, u64 alignment = 4); | ||
| 59 | |||
| 60 | /// Reserves memory to be used by host's CPU. Returns mapped address and offset. | ||
| 61 | std::tuple<u8*, u64> ReserveMemory(std::size_t size, u64 alignment = 4); | ||
| 62 | |||
| 63 | /// Reserves a region of memory to be used in subsequent upload/reserve operations. | ||
| 64 | void Reserve(std::size_t max_size); | ||
| 65 | |||
| 66 | /// Ensures that the set data is sent to the device. | ||
| 67 | [[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx); | ||
| 68 | |||
| 69 | /// Returns the buffer cache handle. | ||
| 70 | vk::Buffer GetBuffer() const { | ||
| 71 | return buffer_handle; | ||
| 72 | } | ||
| 73 | |||
| 74 | private: | ||
| 75 | void AlignBuffer(std::size_t alignment); | ||
| 76 | |||
| 77 | Tegra::MemoryManager& tegra_memory_manager; | ||
| 78 | |||
| 79 | std::unique_ptr<VKStreamBuffer> stream_buffer; | ||
| 80 | vk::Buffer buffer_handle; | ||
| 81 | |||
| 82 | u8* buffer_ptr = nullptr; | ||
| 83 | u64 buffer_offset = 0; | ||
| 84 | u64 buffer_offset_base = 0; | ||
| 85 | }; | ||
| 86 | |||
| 87 | } // 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 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <functional> | ||
| 8 | #include <future> | ||
| 9 | #include <string> | 7 | #include <string> |
| 10 | 8 | ||
| 11 | namespace WebService { | 9 | 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 @@ | |||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 12 | #include "common/web_result.h" | 12 | #include "common/web_result.h" |
| 13 | #include "core/settings.h" | ||
| 14 | #include "web_service/web_backend.h" | 13 | #include "web_service/web_backend.h" |
| 15 | 14 | ||
| 16 | namespace WebService { | 15 | 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() { | |||
| 61 | button(QWizard::CancelButton)->setVisible(false); | 61 | button(QWizard::CancelButton)->setVisible(false); |
| 62 | 62 | ||
| 63 | testcase_watcher.setFuture(QtConcurrent::run( | 63 | testcase_watcher.setFuture(QtConcurrent::run( |
| 64 | [this]() { return Core::System::GetInstance().TelemetrySession().SubmitTestcase(); })); | 64 | [] { return Core::System::GetInstance().TelemetrySession().SubmitTestcase(); })); |
| 65 | break; | 65 | break; |
| 66 | default: | 66 | default: |
| 67 | LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); | 67 | 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() { | |||
| 561 | Settings::values.use_frame_limit = !Settings::values.use_frame_limit; | 561 | Settings::values.use_frame_limit = !Settings::values.use_frame_limit; |
| 562 | UpdateStatusBar(); | 562 | UpdateStatusBar(); |
| 563 | }); | 563 | }); |
| 564 | constexpr u16 SPEED_LIMIT_STEP = 5; | 564 | // TODO: Remove this comment/static whenever the next major release of |
| 565 | // MSVC occurs and we make it a requirement (see: | ||
| 566 | // https://developercommunity.visualstudio.com/content/problem/93922/constexprs-are-trying-to-be-captured-in-lambda-fun.html) | ||
| 567 | static constexpr u16 SPEED_LIMIT_STEP = 5; | ||
| 565 | connect(hotkey_registry.GetHotkey("Main Window", "Increase Speed Limit", this), | 568 | connect(hotkey_registry.GetHotkey("Main Window", "Increase Speed Limit", this), |
| 566 | &QShortcut::activated, this, [&] { | 569 | &QShortcut::activated, this, [&] { |
| 567 | if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) { | 570 | if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) { |