summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/core/CMakeLists.txt7
-rw-r--r--src/core/arm/arm_interface.cpp4
-rw-r--r--src/core/file_sys/patch_manager.cpp3
-rw-r--r--src/core/file_sys/registered_cache.cpp23
-rw-r--r--src/core/file_sys/vfs_libzip.cpp4
-rw-r--r--src/core/frontend/framebuffer_layout.cpp2
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp24
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/core/hle/service/audio/audren_u.cpp2
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp3
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp3
-rw-r--r--src/core/hle/service/time/interface.cpp2
-rw-r--r--src/core/hle/service/time/time.cpp23
-rw-r--r--src/core/hle/service/time/time.h1
-rw-r--r--src/core/hle/service/time/time_zone_manager.cpp14
-rw-r--r--src/core/hle/service/vi/vi.cpp4
-rw-r--r--src/core/memory/dmnt_cheat_vm.cpp5
-rw-r--r--src/core/telemetry_session.cpp6
-rw-r--r--src/input_common/CMakeLists.txt2
-rw-r--r--src/input_common/sdl/sdl_impl.cpp1
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h47
-rw-r--r--src/video_core/engines/shader_bytecode.h2
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h12
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp39
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp3
-rw-r--r--src/video_core/renderer_opengl/utils.cpp62
-rw-r--r--src/video_core/renderer_opengl/utils.h43
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp12
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pass.cpp16
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pass.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_memory_manager.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp30
-rw-r--r--src/video_core/renderer_vulkan/vk_update_descriptor.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_update_descriptor.h16
-rw-r--r--src/video_core/shader/control_flow.cpp6
-rw-r--r--src/video_core/shader/decode/image.cpp11
-rw-r--r--src/video_core/shader/decode/shift.cpp1
-rw-r--r--src/video_core/shader/shader_ir.cpp7
-rw-r--r--src/video_core/shader/track.cpp7
-rw-r--r--src/video_core/texture_cache/surface_base.cpp6
-rw-r--r--src/video_core/texture_cache/surface_base.h4
-rw-r--r--src/video_core/texture_cache/surface_params.cpp1
-rw-r--r--src/video_core/texture_cache/surface_view.cpp4
-rw-r--r--src/video_core/texture_cache/surface_view.h1
-rw-r--r--src/video_core/texture_cache/texture_cache.h11
-rw-r--r--src/web_service/CMakeLists.txt7
-rw-r--r--src/web_service/web_backend.cpp14
-rw-r--r--src/yuzu/debugger/profiler.cpp3
-rw-r--r--src/yuzu/game_list_worker.cpp3
-rw-r--r--src/yuzu/main.cpp8
55 files changed, 236 insertions, 323 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e40e9b0a5..0913be72c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -53,8 +53,11 @@ if (MSVC)
53else() 53else()
54 add_compile_options( 54 add_compile_options(
55 -Wall 55 -Wall
56 -Werror=implicit-fallthrough
56 -Werror=reorder 57 -Werror=reorder
58 -Wextra
57 -Wno-attributes 59 -Wno-attributes
60 -Wno-unused-parameter
58 ) 61 )
59 62
60 if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) 63 if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 66497a386..c15d9f52f 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -591,11 +591,8 @@ target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
591target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt json-headers mbedtls opus unicorn) 591target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt json-headers mbedtls opus unicorn)
592 592
593if (YUZU_ENABLE_BOXCAT) 593if (YUZU_ENABLE_BOXCAT)
594 get_directory_property(OPENSSL_LIBS 594 target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT)
595 DIRECTORY ${PROJECT_SOURCE_DIR}/externals/libressl 595 target_link_libraries(core PRIVATE httplib json-headers zip)
596 DEFINITION OPENSSL_LIBS)
597 target_compile_definitions(core PRIVATE -DCPPHTTPLIB_OPENSSL_SUPPORT -DYUZU_ENABLE_BOXCAT)
598 target_link_libraries(core PRIVATE httplib json-headers ${OPENSSL_LIBS} zip)
599endif() 596endif()
600 597
601if (ENABLE_WEB_SERVICE) 598if (ENABLE_WEB_SERVICE)
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 7e846ddd5..fb9e616b9 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -123,7 +123,7 @@ Symbols GetSymbols(VAddr text_offset, Memory::Memory& memory) {
123std::optional<std::string> GetSymbolName(const Symbols& symbols, VAddr func_address) { 123std::optional<std::string> GetSymbolName(const Symbols& symbols, VAddr func_address) {
124 const auto iter = 124 const auto iter =
125 std::find_if(symbols.begin(), symbols.end(), [func_address](const auto& pair) { 125 std::find_if(symbols.begin(), symbols.end(), [func_address](const auto& pair) {
126 const auto& [symbol, name] = pair; 126 const auto& symbol = pair.first;
127 const auto end_address = symbol.value + symbol.size; 127 const auto end_address = symbol.value + symbol.size;
128 return func_address >= symbol.value && func_address < end_address; 128 return func_address >= symbol.value && func_address < end_address;
129 }); 129 });
@@ -146,7 +146,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const {
146 auto fp = GetReg(29); 146 auto fp = GetReg(29);
147 auto lr = GetReg(30); 147 auto lr = GetReg(30);
148 while (true) { 148 while (true) {
149 out.push_back({"", 0, lr, 0}); 149 out.push_back({"", 0, lr, 0, ""});
150 if (!fp) { 150 if (!fp) {
151 break; 151 break;
152 } 152 }
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index e77e82b8d..81ec06cd4 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -440,7 +440,8 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
440 // Game Updates 440 // Game Updates
441 const auto update_tid = GetUpdateTitleID(title_id); 441 const auto update_tid = GetUpdateTitleID(title_id);
442 PatchManager update{update_tid}; 442 PatchManager update{update_tid};
443 auto [nacp, discard_icon_file] = update.GetControlMetadata(); 443 const auto metadata = update.GetControlMetadata();
444 const auto& nacp = metadata.first;
444 445
445 const auto update_disabled = 446 const auto update_disabled =
446 std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend(); 447 std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend();
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 6e9cf67ef..ba5f76288 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -591,14 +591,18 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
591InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type, 591InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
592 bool overwrite_if_exists, const VfsCopyFunction& copy) { 592 bool overwrite_if_exists, const VfsCopyFunction& copy) {
593 CNMTHeader header{ 593 CNMTHeader header{
594 nca.GetTitleId(), ///< Title ID 594 nca.GetTitleId(), // Title ID
595 0, ///< Ignore/Default title version 595 0, // Ignore/Default title version
596 type, ///< Type 596 type, // Type
597 {}, ///< Padding 597 {}, // Padding
598 0x10, ///< Default table offset 598 0x10, // Default table offset
599 1, ///< 1 Content Entry 599 1, // 1 Content Entry
600 0, ///< No Meta Entries 600 0, // No Meta Entries
601 {}, ///< Padding 601 {}, // Padding
602 {}, // Reserved 1
603 0, // Is committed
604 0, // Required download system version
605 {}, // Reserved 2
602 }; 606 };
603 OptionalHeader opt_header{0, 0}; 607 OptionalHeader opt_header{0, 0};
604 ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca.GetType()), {}}; 608 ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca.GetType()), {}};
@@ -848,7 +852,8 @@ VirtualFile ManualContentProvider::GetEntryUnparsed(u64 title_id, ContentRecordT
848VirtualFile ManualContentProvider::GetEntryRaw(u64 title_id, ContentRecordType type) const { 852VirtualFile ManualContentProvider::GetEntryRaw(u64 title_id, ContentRecordType type) const {
849 const auto iter = 853 const auto iter =
850 std::find_if(entries.begin(), entries.end(), [title_id, type](const auto& entry) { 854 std::find_if(entries.begin(), entries.end(), [title_id, type](const auto& entry) {
851 const auto [title_type, content_type, e_title_id] = entry.first; 855 const auto content_type = std::get<1>(entry.first);
856 const auto e_title_id = std::get<2>(entry.first);
852 return content_type == type && e_title_id == title_id; 857 return content_type == type && e_title_id == title_id;
853 }); 858 });
854 if (iter == entries.end()) 859 if (iter == entries.end())
diff --git a/src/core/file_sys/vfs_libzip.cpp b/src/core/file_sys/vfs_libzip.cpp
index 11d1978ea..d69952940 100644
--- a/src/core/file_sys/vfs_libzip.cpp
+++ b/src/core/file_sys/vfs_libzip.cpp
@@ -42,11 +42,11 @@ VirtualDir ExtractZIP(VirtualFile file) {
42 continue; 42 continue;
43 43
44 if (name.back() != '/') { 44 if (name.back() != '/') {
45 std::unique_ptr<zip_file_t, decltype(&zip_fclose)> file{ 45 std::unique_ptr<zip_file_t, decltype(&zip_fclose)> file2{
46 zip_fopen_index(zip.get(), i, 0), zip_fclose}; 46 zip_fopen_index(zip.get(), i, 0), zip_fclose};
47 47
48 std::vector<u8> buf(stat.size); 48 std::vector<u8> buf(stat.size);
49 if (zip_fread(file.get(), buf.data(), buf.size()) != buf.size()) 49 if (zip_fread(file2.get(), buf.data(), buf.size()) != s64(buf.size()))
50 return nullptr; 50 return nullptr;
51 51
52 const auto parts = FileUtil::SplitPathComponents(stat.name); 52 const auto parts = FileUtil::SplitPathComponents(stat.name);
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 68a0e0906..d0c43447c 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -25,7 +25,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
25 ASSERT(height > 0); 25 ASSERT(height > 0);
26 // The drawing code needs at least somewhat valid values for both screens 26 // The drawing code needs at least somewhat valid values for both screens
27 // so just calculate them both even if the other isn't showing. 27 // so just calculate them both even if the other isn't showing.
28 FramebufferLayout res{width, height}; 28 FramebufferLayout res{width, height, false, {}};
29 29
30 const float window_aspect_ratio = static_cast<float>(height) / width; 30 const float window_aspect_ratio = static_cast<float>(height) / width;
31 const float emulation_aspect_ratio = EmulationAspectRatio( 31 const float emulation_aspect_ratio = EmulationAspectRatio(
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index c558a2f33..d65dae3ae 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -284,17 +284,17 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
284 284
285std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const { 285std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const {
286 std::vector<u8> buffer; 286 std::vector<u8> buffer;
287 const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && 287 const bool is_buffer_a{BufferDescriptorA().size() > std::size_t(buffer_index) &&
288 BufferDescriptorA()[buffer_index].Size()}; 288 BufferDescriptorA()[buffer_index].Size()};
289 auto& memory = Core::System::GetInstance().Memory(); 289 auto& memory = Core::System::GetInstance().Memory();
290 290
291 if (is_buffer_a) { 291 if (is_buffer_a) {
292 ASSERT_MSG(BufferDescriptorA().size() > buffer_index, 292 ASSERT_MSG(BufferDescriptorA().size() > std::size_t(buffer_index),
293 "BufferDescriptorA invalid buffer_index {}", buffer_index); 293 "BufferDescriptorA invalid buffer_index {}", buffer_index);
294 buffer.resize(BufferDescriptorA()[buffer_index].Size()); 294 buffer.resize(BufferDescriptorA()[buffer_index].Size());
295 memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size()); 295 memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size());
296 } else { 296 } else {
297 ASSERT_MSG(BufferDescriptorX().size() > buffer_index, 297 ASSERT_MSG(BufferDescriptorX().size() > std::size_t(buffer_index),
298 "BufferDescriptorX invalid buffer_index {}", buffer_index); 298 "BufferDescriptorX invalid buffer_index {}", buffer_index);
299 buffer.resize(BufferDescriptorX()[buffer_index].Size()); 299 buffer.resize(BufferDescriptorX()[buffer_index].Size());
300 memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size()); 300 memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size());
@@ -310,7 +310,7 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
310 return 0; 310 return 0;
311 } 311 }
312 312
313 const bool is_buffer_b{BufferDescriptorB().size() > buffer_index && 313 const bool is_buffer_b{BufferDescriptorB().size() > std::size_t(buffer_index) &&
314 BufferDescriptorB()[buffer_index].Size()}; 314 BufferDescriptorB()[buffer_index].Size()};
315 const std::size_t buffer_size{GetWriteBufferSize(buffer_index)}; 315 const std::size_t buffer_size{GetWriteBufferSize(buffer_index)};
316 if (size > buffer_size) { 316 if (size > buffer_size) {
@@ -321,13 +321,13 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
321 321
322 auto& memory = Core::System::GetInstance().Memory(); 322 auto& memory = Core::System::GetInstance().Memory();
323 if (is_buffer_b) { 323 if (is_buffer_b) {
324 ASSERT_MSG(BufferDescriptorB().size() > buffer_index, 324 ASSERT_MSG(BufferDescriptorB().size() > std::size_t(buffer_index),
325 "BufferDescriptorB invalid buffer_index {}", buffer_index); 325 "BufferDescriptorB invalid buffer_index {}", buffer_index);
326 ASSERT_MSG(BufferDescriptorB()[buffer_index].Size() >= size, 326 ASSERT_MSG(BufferDescriptorB()[buffer_index].Size() >= size,
327 "BufferDescriptorB buffer_index {} is not large enough", buffer_index); 327 "BufferDescriptorB buffer_index {} is not large enough", buffer_index);
328 memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); 328 memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size);
329 } else { 329 } else {
330 ASSERT_MSG(BufferDescriptorC().size() > buffer_index, 330 ASSERT_MSG(BufferDescriptorC().size() > std::size_t(buffer_index),
331 "BufferDescriptorC invalid buffer_index {}", buffer_index); 331 "BufferDescriptorC invalid buffer_index {}", buffer_index);
332 ASSERT_MSG(BufferDescriptorC()[buffer_index].Size() >= size, 332 ASSERT_MSG(BufferDescriptorC()[buffer_index].Size() >= size,
333 "BufferDescriptorC buffer_index {} is not large enough", buffer_index); 333 "BufferDescriptorC buffer_index {} is not large enough", buffer_index);
@@ -338,16 +338,16 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
338} 338}
339 339
340std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { 340std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const {
341 const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && 341 const bool is_buffer_a{BufferDescriptorA().size() > std::size_t(buffer_index) &&
342 BufferDescriptorA()[buffer_index].Size()}; 342 BufferDescriptorA()[buffer_index].Size()};
343 if (is_buffer_a) { 343 if (is_buffer_a) {
344 ASSERT_MSG(BufferDescriptorA().size() > buffer_index, 344 ASSERT_MSG(BufferDescriptorA().size() > std::size_t(buffer_index),
345 "BufferDescriptorA invalid buffer_index {}", buffer_index); 345 "BufferDescriptorA invalid buffer_index {}", buffer_index);
346 ASSERT_MSG(BufferDescriptorA()[buffer_index].Size() > 0, 346 ASSERT_MSG(BufferDescriptorA()[buffer_index].Size() > 0,
347 "BufferDescriptorA buffer_index {} is empty", buffer_index); 347 "BufferDescriptorA buffer_index {} is empty", buffer_index);
348 return BufferDescriptorA()[buffer_index].Size(); 348 return BufferDescriptorA()[buffer_index].Size();
349 } else { 349 } else {
350 ASSERT_MSG(BufferDescriptorX().size() > buffer_index, 350 ASSERT_MSG(BufferDescriptorX().size() > std::size_t(buffer_index),
351 "BufferDescriptorX invalid buffer_index {}", buffer_index); 351 "BufferDescriptorX invalid buffer_index {}", buffer_index);
352 ASSERT_MSG(BufferDescriptorX()[buffer_index].Size() > 0, 352 ASSERT_MSG(BufferDescriptorX()[buffer_index].Size() > 0,
353 "BufferDescriptorX buffer_index {} is empty", buffer_index); 353 "BufferDescriptorX buffer_index {} is empty", buffer_index);
@@ -356,14 +356,14 @@ std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const {
356} 356}
357 357
358std::size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const { 358std::size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const {
359 const bool is_buffer_b{BufferDescriptorB().size() > buffer_index && 359 const bool is_buffer_b{BufferDescriptorB().size() > std::size_t(buffer_index) &&
360 BufferDescriptorB()[buffer_index].Size()}; 360 BufferDescriptorB()[buffer_index].Size()};
361 if (is_buffer_b) { 361 if (is_buffer_b) {
362 ASSERT_MSG(BufferDescriptorB().size() > buffer_index, 362 ASSERT_MSG(BufferDescriptorB().size() > std::size_t(buffer_index),
363 "BufferDescriptorB invalid buffer_index {}", buffer_index); 363 "BufferDescriptorB invalid buffer_index {}", buffer_index);
364 return BufferDescriptorB()[buffer_index].Size(); 364 return BufferDescriptorB()[buffer_index].Size();
365 } else { 365 } else {
366 ASSERT_MSG(BufferDescriptorC().size() > buffer_index, 366 ASSERT_MSG(BufferDescriptorC().size() > std::size_t(buffer_index),
367 "BufferDescriptorC invalid buffer_index {}", buffer_index); 367 "BufferDescriptorC invalid buffer_index {}", buffer_index);
368 return BufferDescriptorC()[buffer_index].Size(); 368 return BufferDescriptorC()[buffer_index].Size();
369 } 369 }
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 83e956036..4c0451c01 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -85,6 +85,7 @@ void Thread::ResumeFromWait() {
85 ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); 85 ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects");
86 86
87 switch (status) { 87 switch (status) {
88 case ThreadStatus::Paused:
88 case ThreadStatus::WaitSynch: 89 case ThreadStatus::WaitSynch:
89 case ThreadStatus::WaitHLEEvent: 90 case ThreadStatus::WaitHLEEvent:
90 case ThreadStatus::WaitSleep: 91 case ThreadStatus::WaitSleep:
@@ -92,6 +93,7 @@ void Thread::ResumeFromWait() {
92 case ThreadStatus::WaitMutex: 93 case ThreadStatus::WaitMutex:
93 case ThreadStatus::WaitCondVar: 94 case ThreadStatus::WaitCondVar:
94 case ThreadStatus::WaitArb: 95 case ThreadStatus::WaitArb:
96 case ThreadStatus::Dormant:
95 break; 97 break;
96 98
97 case ThreadStatus::Ready: 99 case ThreadStatus::Ready:
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 82a5dbf14..175cabf45 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -129,7 +129,7 @@ private:
129 LOG_DEBUG(Service_Audio, "called. rendering_time_limit_percent={}", 129 LOG_DEBUG(Service_Audio, "called. rendering_time_limit_percent={}",
130 rendering_time_limit_percent); 130 rendering_time_limit_percent);
131 131
132 ASSERT(rendering_time_limit_percent >= 0 && rendering_time_limit_percent <= 100); 132 ASSERT(rendering_time_limit_percent <= 100);
133 133
134 IPC::ResponseBuilder rb{ctx, 2}; 134 IPC::ResponseBuilder rb{ctx, 2};
135 rb.Push(RESULT_SUCCESS); 135 rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 102017d73..cadc03805 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -451,7 +451,8 @@ FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataTy
451 451
452 if (res != Loader::ResultStatus::Success) { 452 if (res != Loader::ResultStatus::Success) {
453 FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()}; 453 FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
454 auto [nacp_unique, discard] = pm.GetControlMetadata(); 454 const auto metadata = pm.GetControlMetadata();
455 const auto& nacp_unique = metadata.first;
455 456
456 if (nacp_unique != nullptr) { 457 if (nacp_unique != nullptr) {
457 new_size = {nacp_unique->GetDefaultNormalSaveSize(), 458 new_size = {nacp_unique->GetDefaultNormalSaveSize(),
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index e6811d5b5..61045c75c 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -575,6 +575,7 @@ private:
575 0, 575 0,
576 user_id->GetSize(), 576 user_id->GetSize(),
577 {}, 577 {},
578 {},
578 }); 579 });
579 580
580 continue; 581 continue;
@@ -595,6 +596,7 @@ private:
595 stoull_be(title_id->GetName()), 596 stoull_be(title_id->GetName()),
596 title_id->GetSize(), 597 title_id->GetSize(),
597 {}, 598 {},
599 {},
598 }); 600 });
599 } 601 }
600 } 602 }
@@ -619,6 +621,7 @@ private:
619 stoull_be(title_id->GetName()), 621 stoull_be(title_id->GetName()),
620 title_id->GetSize(), 622 title_id->GetSize(),
621 {}, 623 {},
624 {},
622 }); 625 });
623 } 626 }
624 } 627 }
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp
index f509653a3..ba8fd6152 100644
--- a/src/core/hle/service/time/interface.cpp
+++ b/src/core/hle/service/time/interface.cpp
@@ -29,7 +29,7 @@ Time::Time(std::shared_ptr<Module> module, Core::System& system, const char* nam
29 {300, &Time::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, 29 {300, &Time::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"},
30 {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, 30 {400, &Time::GetClockSnapshot, "GetClockSnapshot"},
31 {401, &Time::GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, 31 {401, &Time::GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"},
32 {500, nullptr, "CalculateStandardUserSystemClockDifferenceByUser"}, 32 {500, &Time::CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"},
33 {501, &Time::CalculateSpanBetween, "CalculateSpanBetween"}, 33 {501, &Time::CalculateSpanBetween, "CalculateSpanBetween"},
34 }; 34 };
35 // clang-format on 35 // clang-format on
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index ce859f18d..e722886de 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -308,6 +308,29 @@ void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLEReques
308 ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot)); 308 ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot));
309} 309}
310 310
311void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(
312 Kernel::HLERequestContext& ctx) {
313 LOG_DEBUG(Service_Time, "called");
314
315 IPC::RequestParser rp{ctx};
316 const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>();
317 const auto snapshot_b = rp.PopRaw<Clock::ClockSnapshot>();
318
319 auto time_span_type{Clock::TimeSpanType::FromSeconds(snapshot_b.user_context.offset -
320 snapshot_a.user_context.offset)};
321
322 if ((snapshot_b.user_context.steady_time_point.clock_source_id !=
323 snapshot_a.user_context.steady_time_point.clock_source_id) ||
324 (snapshot_b.is_automatic_correction_enabled &&
325 snapshot_a.is_automatic_correction_enabled)) {
326 time_span_type.nanoseconds = 0;
327 }
328
329 IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2};
330 rb.Push(RESULT_SUCCESS);
331 rb.PushRaw(time_span_type.nanoseconds);
332}
333
311void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { 334void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) {
312 LOG_DEBUG(Service_Time, "called"); 335 LOG_DEBUG(Service_Time, "called");
313 336
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 351988468..41f3002e9 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -32,6 +32,7 @@ public:
32 void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx); 32 void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx);
33 void GetClockSnapshot(Kernel::HLERequestContext& ctx); 33 void GetClockSnapshot(Kernel::HLERequestContext& ctx);
34 void GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx); 34 void GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx);
35 void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx);
35 void CalculateSpanBetween(Kernel::HLERequestContext& ctx); 36 void CalculateSpanBetween(Kernel::HLERequestContext& ctx);
36 void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); 37 void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx);
37 38
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp
index 07b553a43..c8159bcd5 100644
--- a/src/core/hle/service/time/time_zone_manager.cpp
+++ b/src/core/hle/service/time/time_zone_manager.cpp
@@ -309,7 +309,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
309 offset = GetTZName(name, offset); 309 offset = GetTZName(name, offset);
310 std_len = offset; 310 std_len = offset;
311 } 311 }
312 if (!std_len) { 312 if (std_len == 0) {
313 return {}; 313 return {};
314 } 314 }
315 if (!GetOffset(name, offset, std_offset)) { 315 if (!GetOffset(name, offset, std_offset)) {
@@ -320,7 +320,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
320 int dest_len{}; 320 int dest_len{};
321 int dest_offset{}; 321 int dest_offset{};
322 const char* dest_name{name + offset}; 322 const char* dest_name{name + offset};
323 if (rule.chars.size() < char_count) { 323 if (rule.chars.size() < std::size_t(char_count)) {
324 return {}; 324 return {};
325 } 325 }
326 326
@@ -343,7 +343,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
343 return {}; 343 return {};
344 } 344 }
345 char_count += dest_len + 1; 345 char_count += dest_len + 1;
346 if (rule.chars.size() < char_count) { 346 if (rule.chars.size() < std::size_t(char_count)) {
347 return {}; 347 return {};
348 } 348 }
349 if (name[offset] != '\0' && name[offset] != ',' && name[offset] != ';') { 349 if (name[offset] != '\0' && name[offset] != ',' && name[offset] != ';') {
@@ -414,7 +414,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
414 if (is_reversed || 414 if (is_reversed ||
415 (start_time < end_time && 415 (start_time < end_time &&
416 (end_time - start_time < (year_seconds + (std_offset - dest_offset))))) { 416 (end_time - start_time < (year_seconds + (std_offset - dest_offset))))) {
417 if (rule.ats.size() - 2 < time_count) { 417 if (rule.ats.size() - 2 < std::size_t(time_count)) {
418 break; 418 break;
419 } 419 }
420 420
@@ -609,7 +609,7 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi
609 } 609 }
610 610
611 const u64 position{(read_offset - sizeof(TzifHeader))}; 611 const u64 position{(read_offset - sizeof(TzifHeader))};
612 const std::size_t bytes_read{vfs_file->GetSize() - sizeof(TzifHeader) - position}; 612 const s64 bytes_read = s64(vfs_file->GetSize() - sizeof(TzifHeader) - position);
613 if (bytes_read < 0) { 613 if (bytes_read < 0) {
614 return {}; 614 return {};
615 } 615 }
@@ -621,11 +621,11 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi
621 std::array<char, time_zone_name_max + 1> temp_name{}; 621 std::array<char, time_zone_name_max + 1> temp_name{};
622 vfs_file->ReadArray(temp_name.data(), bytes_read, read_offset); 622 vfs_file->ReadArray(temp_name.data(), bytes_read, read_offset);
623 if (bytes_read > 2 && temp_name[0] == '\n' && temp_name[bytes_read - 1] == '\n' && 623 if (bytes_read > 2 && temp_name[0] == '\n' && temp_name[bytes_read - 1] == '\n' &&
624 time_zone_rule.type_count + 2 <= time_zone_rule.ttis.size()) { 624 std::size_t(time_zone_rule.type_count) + 2 <= time_zone_rule.ttis.size()) {
625 temp_name[bytes_read - 1] = '\0'; 625 temp_name[bytes_read - 1] = '\0';
626 626
627 std::array<char, time_zone_name_max> name{}; 627 std::array<char, time_zone_name_max> name{};
628 std::memcpy(name.data(), temp_name.data() + 1, bytes_read - 1); 628 std::memcpy(name.data(), temp_name.data() + 1, std::size_t(bytes_read - 1));
629 629
630 TimeZoneRule temp_rule; 630 TimeZoneRule temp_rule;
631 if (ParsePosixName(name.data(), temp_rule)) { 631 if (ParsePosixName(name.data(), temp_rule)) {
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index fdc62d05b..7f109f4eb 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -101,8 +101,8 @@ public:
101 } 101 }
102 102
103 std::u16string ReadInterfaceToken() { 103 std::u16string ReadInterfaceToken() {
104 u32 unknown = Read<u32_le>(); 104 [[maybe_unused]] const u32 unknown = Read<u32_le>();
105 u32 length = Read<u32_le>(); 105 const u32 length = Read<u32_le>();
106 106
107 std::u16string token{}; 107 std::u16string token{};
108 108
diff --git a/src/core/memory/dmnt_cheat_vm.cpp b/src/core/memory/dmnt_cheat_vm.cpp
index 4f4fa5099..5bb26a36f 100644
--- a/src/core/memory/dmnt_cheat_vm.cpp
+++ b/src/core/memory/dmnt_cheat_vm.cpp
@@ -55,7 +55,7 @@ void DmntCheatVm::LogOpcode(const CheatVmOpcode& opcode) {
55 fmt::format("Cond Type: {:X}", static_cast<u32>(begin_cond->cond_type))); 55 fmt::format("Cond Type: {:X}", static_cast<u32>(begin_cond->cond_type)));
56 callbacks->CommandLog(fmt::format("Rel Addr: {:X}", begin_cond->rel_address)); 56 callbacks->CommandLog(fmt::format("Rel Addr: {:X}", begin_cond->rel_address));
57 callbacks->CommandLog(fmt::format("Value: {:X}", begin_cond->value.bit64)); 57 callbacks->CommandLog(fmt::format("Value: {:X}", begin_cond->value.bit64));
58 } else if (auto end_cond = std::get_if<EndConditionalOpcode>(&opcode.opcode)) { 58 } else if (std::holds_alternative<EndConditionalOpcode>(opcode.opcode)) {
59 callbacks->CommandLog("Opcode: End Conditional"); 59 callbacks->CommandLog("Opcode: End Conditional");
60 } else if (auto ctrl_loop = std::get_if<ControlLoopOpcode>(&opcode.opcode)) { 60 } else if (auto ctrl_loop = std::get_if<ControlLoopOpcode>(&opcode.opcode)) {
61 if (ctrl_loop->start_loop) { 61 if (ctrl_loop->start_loop) {
@@ -399,6 +399,7 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
399 // 8kkkkkkk 399 // 8kkkkkkk
400 // Just parse the mask. 400 // Just parse the mask.
401 begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF; 401 begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF;
402 opcode.opcode = begin_keypress_cond;
402 } break; 403 } break;
403 case CheatVmOpcodeType::PerformArithmeticRegister: { 404 case CheatVmOpcodeType::PerformArithmeticRegister: {
404 PerformArithmeticRegisterOpcode perform_math_reg{}; 405 PerformArithmeticRegisterOpcode perform_math_reg{};
@@ -779,7 +780,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
779 if (!cond_met) { 780 if (!cond_met) {
780 SkipConditionalBlock(); 781 SkipConditionalBlock();
781 } 782 }
782 } else if (auto end_cond = std::get_if<EndConditionalOpcode>(&cur_opcode.opcode)) { 783 } else if (std::holds_alternative<EndConditionalOpcode>(cur_opcode.opcode)) {
783 // Decrement the condition depth. 784 // Decrement the condition depth.
784 // We will assume, graciously, that mismatched conditional block ends are a nop. 785 // We will assume, graciously, that mismatched conditional block ends are a nop.
785 if (condition_depth > 0) { 786 if (condition_depth > 0) {
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index 0f3685d1c..fd5a3ee9f 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -153,9 +153,9 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
153 app_loader.ReadTitle(name); 153 app_loader.ReadTitle(name);
154 154
155 if (name.empty()) { 155 if (name.empty()) {
156 auto [nacp, icon_file] = FileSys::PatchManager(program_id).GetControlMetadata(); 156 const auto metadata = FileSys::PatchManager(program_id).GetControlMetadata();
157 if (nacp != nullptr) { 157 if (metadata.first != nullptr) {
158 name = nacp->GetApplicationName(); 158 name = metadata.first->GetApplicationName();
159 } 159 }
160 } 160 }
161 161
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 2520ba321..a9c2392b1 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -27,4 +27,4 @@ if(SDL2_FOUND)
27endif() 27endif()
28 28
29create_target_directory_groups(input_common) 29create_target_directory_groups(input_common)
30target_link_libraries(input_common PUBLIC core PRIVATE common ${Boost_LIBRARIES}) 30target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost)
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index a2e0c0bd2..675b477fa 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -603,6 +603,7 @@ public:
603 if (std::abs(event.jaxis.value / 32767.0) < 0.5) { 603 if (std::abs(event.jaxis.value / 32767.0) < 0.5) {
604 break; 604 break;
605 } 605 }
606 [[fallthrough]];
606 case SDL_JOYBUTTONUP: 607 case SDL_JOYBUTTONUP:
607 case SDL_JOYHATMOTION: 608 case SDL_JOYHATMOTION:
608 return SDLEventToButtonParamPackage(state, event); 609 return SDLEventToButtonParamPackage(state, event);
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index b57c0d4d4..83e7a1cde 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -29,10 +29,10 @@ namespace VideoCommon {
29 29
30using MapInterval = std::shared_ptr<MapIntervalBase>; 30using MapInterval = std::shared_ptr<MapIntervalBase>;
31 31
32template <typename TBuffer, typename TBufferType, typename StreamBuffer> 32template <typename OwnerBuffer, typename BufferType, typename StreamBuffer>
33class BufferCache { 33class BufferCache {
34public: 34public:
35 using BufferInfo = std::pair<const TBufferType*, u64>; 35 using BufferInfo = std::pair<BufferType, u64>;
36 36
37 BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4, 37 BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4,
38 bool is_written = false, bool use_fast_cbuf = false) { 38 bool is_written = false, bool use_fast_cbuf = false) {
@@ -89,9 +89,7 @@ public:
89 } 89 }
90 } 90 }
91 91
92 const u64 offset = static_cast<u64>(block->GetOffset(cpu_addr)); 92 return {ToHandle(block), static_cast<u64>(block->GetOffset(cpu_addr))};
93
94 return {ToHandle(block), offset};
95 } 93 }
96 94
97 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset. 95 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset.
@@ -156,7 +154,7 @@ public:
156 } 154 }
157 } 155 }
158 156
159 virtual const TBufferType* GetEmptyBuffer(std::size_t size) = 0; 157 virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
160 158
161protected: 159protected:
162 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, 160 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system,
@@ -166,19 +164,19 @@ protected:
166 164
167 ~BufferCache() = default; 165 ~BufferCache() = default;
168 166
169 virtual const TBufferType* ToHandle(const TBuffer& storage) = 0; 167 virtual BufferType ToHandle(const OwnerBuffer& storage) = 0;
170 168
171 virtual void WriteBarrier() = 0; 169 virtual void WriteBarrier() = 0;
172 170
173 virtual TBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0; 171 virtual OwnerBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0;
174 172
175 virtual void UploadBlockData(const TBuffer& buffer, std::size_t offset, std::size_t size, 173 virtual void UploadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size,
176 const u8* data) = 0; 174 const u8* data) = 0;
177 175
178 virtual void DownloadBlockData(const TBuffer& buffer, std::size_t offset, std::size_t size, 176 virtual void DownloadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size,
179 u8* data) = 0; 177 u8* data) = 0;
180 178
181 virtual void CopyBlock(const TBuffer& src, const TBuffer& dst, std::size_t src_offset, 179 virtual void CopyBlock(const OwnerBuffer& src, const OwnerBuffer& dst, std::size_t src_offset,
182 std::size_t dst_offset, std::size_t size) = 0; 180 std::size_t dst_offset, std::size_t size) = 0;
183 181
184 virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) { 182 virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) {
@@ -221,9 +219,8 @@ private:
221 return std::make_shared<MapIntervalBase>(start, end, gpu_addr); 219 return std::make_shared<MapIntervalBase>(start, end, gpu_addr);
222 } 220 }
223 221
224 MapInterval MapAddress(const TBuffer& block, const GPUVAddr gpu_addr, const VAddr cpu_addr, 222 MapInterval MapAddress(const OwnerBuffer& block, const GPUVAddr gpu_addr, const VAddr cpu_addr,
225 const std::size_t size) { 223 const std::size_t size) {
226
227 std::vector<MapInterval> overlaps = GetMapsInRange(cpu_addr, size); 224 std::vector<MapInterval> overlaps = GetMapsInRange(cpu_addr, size);
228 if (overlaps.empty()) { 225 if (overlaps.empty()) {
229 auto& memory_manager = system.GPU().MemoryManager(); 226 auto& memory_manager = system.GPU().MemoryManager();
@@ -272,7 +269,7 @@ private:
272 return new_map; 269 return new_map;
273 } 270 }
274 271
275 void UpdateBlock(const TBuffer& block, VAddr start, VAddr end, 272 void UpdateBlock(const OwnerBuffer& block, VAddr start, VAddr end,
276 std::vector<MapInterval>& overlaps) { 273 std::vector<MapInterval>& overlaps) {
277 const IntervalType base_interval{start, end}; 274 const IntervalType base_interval{start, end};
278 IntervalSet interval_set{}; 275 IntervalSet interval_set{};
@@ -313,7 +310,7 @@ private:
313 310
314 void FlushMap(MapInterval map) { 311 void FlushMap(MapInterval map) {
315 std::size_t size = map->GetEnd() - map->GetStart(); 312 std::size_t size = map->GetEnd() - map->GetStart();
316 TBuffer block = blocks[map->GetStart() >> block_page_bits]; 313 OwnerBuffer block = blocks[map->GetStart() >> block_page_bits];
317 staging_buffer.resize(size); 314 staging_buffer.resize(size);
318 DownloadBlockData(block, block->GetOffset(map->GetStart()), size, staging_buffer.data()); 315 DownloadBlockData(block, block->GetOffset(map->GetStart()), size, staging_buffer.data());
319 system.Memory().WriteBlockUnsafe(map->GetStart(), staging_buffer.data(), size); 316 system.Memory().WriteBlockUnsafe(map->GetStart(), staging_buffer.data(), size);
@@ -328,7 +325,7 @@ private:
328 325
329 buffer_ptr += size; 326 buffer_ptr += size;
330 buffer_offset += size; 327 buffer_offset += size;
331 return {&stream_buffer_handle, uploaded_offset}; 328 return {stream_buffer_handle, uploaded_offset};
332 } 329 }
333 330
334 void AlignBuffer(std::size_t alignment) { 331 void AlignBuffer(std::size_t alignment) {
@@ -338,11 +335,11 @@ private:
338 buffer_offset = offset_aligned; 335 buffer_offset = offset_aligned;
339 } 336 }
340 337
341 TBuffer EnlargeBlock(TBuffer buffer) { 338 OwnerBuffer EnlargeBlock(OwnerBuffer buffer) {
342 const std::size_t old_size = buffer->GetSize(); 339 const std::size_t old_size = buffer->GetSize();
343 const std::size_t new_size = old_size + block_page_size; 340 const std::size_t new_size = old_size + block_page_size;
344 const VAddr cpu_addr = buffer->GetCpuAddr(); 341 const VAddr cpu_addr = buffer->GetCpuAddr();
345 TBuffer new_buffer = CreateBlock(cpu_addr, new_size); 342 OwnerBuffer new_buffer = CreateBlock(cpu_addr, new_size);
346 CopyBlock(buffer, new_buffer, 0, 0, old_size); 343 CopyBlock(buffer, new_buffer, 0, 0, old_size);
347 buffer->SetEpoch(epoch); 344 buffer->SetEpoch(epoch);
348 pending_destruction.push_back(buffer); 345 pending_destruction.push_back(buffer);
@@ -356,14 +353,14 @@ private:
356 return new_buffer; 353 return new_buffer;
357 } 354 }
358 355
359 TBuffer MergeBlocks(TBuffer first, TBuffer second) { 356 OwnerBuffer MergeBlocks(OwnerBuffer first, OwnerBuffer second) {
360 const std::size_t size_1 = first->GetSize(); 357 const std::size_t size_1 = first->GetSize();
361 const std::size_t size_2 = second->GetSize(); 358 const std::size_t size_2 = second->GetSize();
362 const VAddr first_addr = first->GetCpuAddr(); 359 const VAddr first_addr = first->GetCpuAddr();
363 const VAddr second_addr = second->GetCpuAddr(); 360 const VAddr second_addr = second->GetCpuAddr();
364 const VAddr new_addr = std::min(first_addr, second_addr); 361 const VAddr new_addr = std::min(first_addr, second_addr);
365 const std::size_t new_size = size_1 + size_2; 362 const std::size_t new_size = size_1 + size_2;
366 TBuffer new_buffer = CreateBlock(new_addr, new_size); 363 OwnerBuffer new_buffer = CreateBlock(new_addr, new_size);
367 CopyBlock(first, new_buffer, 0, new_buffer->GetOffset(first_addr), size_1); 364 CopyBlock(first, new_buffer, 0, new_buffer->GetOffset(first_addr), size_1);
368 CopyBlock(second, new_buffer, 0, new_buffer->GetOffset(second_addr), size_2); 365 CopyBlock(second, new_buffer, 0, new_buffer->GetOffset(second_addr), size_2);
369 first->SetEpoch(epoch); 366 first->SetEpoch(epoch);
@@ -380,8 +377,8 @@ private:
380 return new_buffer; 377 return new_buffer;
381 } 378 }
382 379
383 TBuffer GetBlock(const VAddr cpu_addr, const std::size_t size) { 380 OwnerBuffer GetBlock(const VAddr cpu_addr, const std::size_t size) {
384 TBuffer found{}; 381 OwnerBuffer found;
385 const VAddr cpu_addr_end = cpu_addr + size - 1; 382 const VAddr cpu_addr_end = cpu_addr + size - 1;
386 u64 page_start = cpu_addr >> block_page_bits; 383 u64 page_start = cpu_addr >> block_page_bits;
387 const u64 page_end = cpu_addr_end >> block_page_bits; 384 const u64 page_end = cpu_addr_end >> block_page_bits;
@@ -457,7 +454,7 @@ private:
457 Core::System& system; 454 Core::System& system;
458 455
459 std::unique_ptr<StreamBuffer> stream_buffer; 456 std::unique_ptr<StreamBuffer> stream_buffer;
460 TBufferType stream_buffer_handle{}; 457 BufferType stream_buffer_handle{};
461 458
462 bool invalidated = false; 459 bool invalidated = false;
463 460
@@ -475,9 +472,9 @@ private:
475 472
476 static constexpr u64 block_page_bits = 21; 473 static constexpr u64 block_page_bits = 21;
477 static constexpr u64 block_page_size = 1ULL << block_page_bits; 474 static constexpr u64 block_page_size = 1ULL << block_page_bits;
478 std::unordered_map<u64, TBuffer> blocks; 475 std::unordered_map<u64, OwnerBuffer> blocks;
479 476
480 std::list<TBuffer> pending_destruction; 477 std::list<OwnerBuffer> pending_destruction;
481 u64 epoch = 0; 478 u64 epoch = 0;
482 u64 modified_ticks = 0; 479 u64 modified_ticks = 0;
483 480
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 5e9cfba22..7231597d4 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -1507,7 +1507,7 @@ union Instruction {
1507 1507
1508 TextureType GetTextureType() const { 1508 TextureType GetTextureType() const {
1509 // The TLDS instruction has a weird encoding for the texture type. 1509 // The TLDS instruction has a weird encoding for the texture type.
1510 if (texture_info >= 0 && texture_info <= 1) { 1510 if (texture_info <= 1) {
1511 return TextureType::Texture1D; 1511 return TextureType::Texture1D;
1512 } 1512 }
1513 if (texture_info == 2 || texture_info == 8 || texture_info == 12 || 1513 if (texture_info == 2 || texture_info == 8 || texture_info == 12 ||
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 4eb37a96c..cb5792407 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -55,33 +55,31 @@ void OGLBufferCache::WriteBarrier() {
55 glMemoryBarrier(GL_ALL_BARRIER_BITS); 55 glMemoryBarrier(GL_ALL_BARRIER_BITS);
56} 56}
57 57
58const GLuint* OGLBufferCache::ToHandle(const Buffer& buffer) { 58GLuint OGLBufferCache::ToHandle(const Buffer& buffer) {
59 return buffer->GetHandle(); 59 return buffer->GetHandle();
60} 60}
61 61
62const GLuint* OGLBufferCache::GetEmptyBuffer(std::size_t) { 62GLuint OGLBufferCache::GetEmptyBuffer(std::size_t) {
63 static const GLuint null_buffer = 0; 63 return 0;
64 return &null_buffer;
65} 64}
66 65
67void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 66void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
68 const u8* data) { 67 const u8* data) {
69 glNamedBufferSubData(*buffer->GetHandle(), static_cast<GLintptr>(offset), 68 glNamedBufferSubData(buffer->GetHandle(), static_cast<GLintptr>(offset),
70 static_cast<GLsizeiptr>(size), data); 69 static_cast<GLsizeiptr>(size), data);
71} 70}
72 71
73void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 72void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
74 u8* data) { 73 u8* data) {
75 MICROPROFILE_SCOPE(OpenGL_Buffer_Download); 74 MICROPROFILE_SCOPE(OpenGL_Buffer_Download);
76 glGetNamedBufferSubData(*buffer->GetHandle(), static_cast<GLintptr>(offset), 75 glGetNamedBufferSubData(buffer->GetHandle(), static_cast<GLintptr>(offset),
77 static_cast<GLsizeiptr>(size), data); 76 static_cast<GLsizeiptr>(size), data);
78} 77}
79 78
80void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, 79void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
81 std::size_t dst_offset, std::size_t size) { 80 std::size_t dst_offset, std::size_t size) {
82 glCopyNamedBufferSubData(*src->GetHandle(), *dst->GetHandle(), 81 glCopyNamedBufferSubData(src->GetHandle(), dst->GetHandle(), static_cast<GLintptr>(src_offset),
83 static_cast<GLintptr>(src_offset), static_cast<GLintptr>(dst_offset), 82 static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
84 static_cast<GLsizeiptr>(size));
85} 83}
86 84
87OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer, 85OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer,
@@ -89,7 +87,7 @@ OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_poi
89 DEBUG_ASSERT(cbuf_cursor < std::size(cbufs)); 87 DEBUG_ASSERT(cbuf_cursor < std::size(cbufs));
90 const GLuint& cbuf = cbufs[cbuf_cursor++]; 88 const GLuint& cbuf = cbufs[cbuf_cursor++];
91 glNamedBufferSubData(cbuf, 0, static_cast<GLsizeiptr>(size), raw_pointer); 89 glNamedBufferSubData(cbuf, 0, static_cast<GLsizeiptr>(size), raw_pointer);
92 return {&cbuf, 0}; 90 return {cbuf, 0};
93} 91}
94 92
95} // namespace OpenGL 93} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index d94a11252..a74817857 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -34,12 +34,12 @@ public:
34 explicit CachedBufferBlock(VAddr cpu_addr, const std::size_t size); 34 explicit CachedBufferBlock(VAddr cpu_addr, const std::size_t size);
35 ~CachedBufferBlock(); 35 ~CachedBufferBlock();
36 36
37 const GLuint* GetHandle() const { 37 GLuint GetHandle() const {
38 return &gl_buffer.handle; 38 return gl_buffer.handle;
39 } 39 }
40 40
41private: 41private:
42 OGLBuffer gl_buffer{}; 42 OGLBuffer gl_buffer;
43}; 43};
44 44
45class OGLBufferCache final : public GenericBufferCache { 45class OGLBufferCache final : public GenericBufferCache {
@@ -48,7 +48,7 @@ public:
48 const Device& device, std::size_t stream_size); 48 const Device& device, std::size_t stream_size);
49 ~OGLBufferCache(); 49 ~OGLBufferCache();
50 50
51 const GLuint* GetEmptyBuffer(std::size_t) override; 51 GLuint GetEmptyBuffer(std::size_t) override;
52 52
53 void Acquire() noexcept { 53 void Acquire() noexcept {
54 cbuf_cursor = 0; 54 cbuf_cursor = 0;
@@ -57,9 +57,9 @@ public:
57protected: 57protected:
58 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override; 58 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override;
59 59
60 void WriteBarrier() override; 60 GLuint ToHandle(const Buffer& buffer) override;
61 61
62 const GLuint* ToHandle(const Buffer& buffer) override; 62 void WriteBarrier() override;
63 63
64 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 64 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
65 const u8* data) override; 65 const u8* data) override;
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index c286502ba..d83dca25a 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -87,7 +87,7 @@ u32 Extract(u32& base, u32& num, u32 amount, std::optional<GLenum> limit = {}) {
87std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> BuildBaseBindings() noexcept { 87std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> BuildBaseBindings() noexcept {
88 std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> bindings; 88 std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> bindings;
89 89
90 static std::array<std::size_t, 5> stage_swizzle = {0, 1, 2, 3, 4}; 90 static constexpr std::array<std::size_t, 5> stage_swizzle{0, 1, 2, 3, 4};
91 const u32 total_ubos = GetInteger<u32>(GL_MAX_UNIFORM_BUFFER_BINDINGS); 91 const u32 total_ubos = GetInteger<u32>(GL_MAX_UNIFORM_BUFFER_BINDINGS);
92 const u32 total_ssbos = GetInteger<u32>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS); 92 const u32 total_ssbos = GetInteger<u32>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
93 const u32 total_samplers = GetInteger<u32>(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); 93 const u32 total_samplers = GetInteger<u32>(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index f4598fbf7..175374f0d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -188,10 +188,8 @@ void RasterizerOpenGL::SetupVertexBuffer() {
188 ASSERT(end > start); 188 ASSERT(end > start);
189 const u64 size = end - start + 1; 189 const u64 size = end - start + 1;
190 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); 190 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
191 191 glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset,
192 // Bind the vertex array to the buffer at the current offset. 192 vertex_array.stride);
193 vertex_array_pushbuffer.SetVertexBuffer(static_cast<GLuint>(index), vertex_buffer,
194 vertex_buffer_offset, vertex_array.stride);
195 } 193 }
196} 194}
197 195
@@ -222,7 +220,7 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() {
222 const auto& regs = system.GPU().Maxwell3D().regs; 220 const auto& regs = system.GPU().Maxwell3D().regs;
223 const std::size_t size = CalculateIndexBufferSize(); 221 const std::size_t size = CalculateIndexBufferSize();
224 const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size); 222 const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
225 vertex_array_pushbuffer.SetIndexBuffer(buffer); 223 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
226 return offset; 224 return offset;
227} 225}
228 226
@@ -524,7 +522,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
524 522
525 // Prepare vertex array format. 523 // Prepare vertex array format.
526 SetupVertexFormat(); 524 SetupVertexFormat();
527 vertex_array_pushbuffer.Setup();
528 525
529 // Upload vertex and index data. 526 // Upload vertex and index data.
530 SetupVertexBuffer(); 527 SetupVertexBuffer();
@@ -534,17 +531,13 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
534 index_buffer_offset = SetupIndexBuffer(); 531 index_buffer_offset = SetupIndexBuffer();
535 } 532 }
536 533
537 // Prepare packed bindings.
538 bind_ubo_pushbuffer.Setup();
539 bind_ssbo_pushbuffer.Setup();
540
541 // Setup emulation uniform buffer. 534 // Setup emulation uniform buffer.
542 GLShader::MaxwellUniformData ubo; 535 GLShader::MaxwellUniformData ubo;
543 ubo.SetFromRegs(gpu); 536 ubo.SetFromRegs(gpu);
544 const auto [buffer, offset] = 537 const auto [buffer, offset] =
545 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment()); 538 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
546 bind_ubo_pushbuffer.Push(EmulationUniformBlockBinding, buffer, offset, 539 glBindBufferRange(GL_UNIFORM_BUFFER, EmulationUniformBlockBinding, buffer, offset,
547 static_cast<GLsizeiptr>(sizeof(ubo))); 540 static_cast<GLsizeiptr>(sizeof(ubo)));
548 541
549 // Setup shaders and their used resources. 542 // Setup shaders and their used resources.
550 texture_cache.GuardSamplers(true); 543 texture_cache.GuardSamplers(true);
@@ -557,11 +550,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
557 // Signal the buffer cache that we are not going to upload more things. 550 // Signal the buffer cache that we are not going to upload more things.
558 buffer_cache.Unmap(); 551 buffer_cache.Unmap();
559 552
560 // Now that we are no longer uploading data, we can safely bind the buffers to OpenGL.
561 vertex_array_pushbuffer.Bind();
562 bind_ubo_pushbuffer.Bind();
563 bind_ssbo_pushbuffer.Bind();
564
565 program_manager.BindGraphicsPipeline(); 553 program_manager.BindGraphicsPipeline();
566 554
567 if (texture_cache.TextureBarrier()) { 555 if (texture_cache.TextureBarrier()) {
@@ -630,17 +618,11 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
630 (Maxwell::MaxConstBufferSize + device.GetUniformBufferAlignment()); 618 (Maxwell::MaxConstBufferSize + device.GetUniformBufferAlignment());
631 buffer_cache.Map(buffer_size); 619 buffer_cache.Map(buffer_size);
632 620
633 bind_ubo_pushbuffer.Setup();
634 bind_ssbo_pushbuffer.Setup();
635
636 SetupComputeConstBuffers(kernel); 621 SetupComputeConstBuffers(kernel);
637 SetupComputeGlobalMemory(kernel); 622 SetupComputeGlobalMemory(kernel);
638 623
639 buffer_cache.Unmap(); 624 buffer_cache.Unmap();
640 625
641 bind_ubo_pushbuffer.Bind();
642 bind_ssbo_pushbuffer.Bind();
643
644 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 626 const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
645 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); 627 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
646 ++num_queued_commands; 628 ++num_queued_commands;
@@ -771,8 +753,8 @@ void RasterizerOpenGL::SetupConstBuffer(u32 binding, const Tegra::Engines::Const
771 const ConstBufferEntry& entry) { 753 const ConstBufferEntry& entry) {
772 if (!buffer.enabled) { 754 if (!buffer.enabled) {
773 // Set values to zero to unbind buffers 755 // Set values to zero to unbind buffers
774 bind_ubo_pushbuffer.Push(binding, buffer_cache.GetEmptyBuffer(sizeof(float)), 0, 756 glBindBufferRange(GL_UNIFORM_BUFFER, binding, buffer_cache.GetEmptyBuffer(sizeof(float)), 0,
775 sizeof(float)); 757 sizeof(float));
776 return; 758 return;
777 } 759 }
778 760
@@ -783,7 +765,7 @@ void RasterizerOpenGL::SetupConstBuffer(u32 binding, const Tegra::Engines::Const
783 const auto alignment = device.GetUniformBufferAlignment(); 765 const auto alignment = device.GetUniformBufferAlignment();
784 const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment, false, 766 const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment, false,
785 device.HasFastBufferSubData()); 767 device.HasFastBufferSubData());
786 bind_ubo_pushbuffer.Push(binding, cbuf, offset, size); 768 glBindBufferRange(GL_UNIFORM_BUFFER, binding, cbuf, offset, size);
787} 769}
788 770
789void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) { 771void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) {
@@ -819,7 +801,8 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e
819 const auto alignment{device.GetShaderStorageBufferAlignment()}; 801 const auto alignment{device.GetShaderStorageBufferAlignment()};
820 const auto [ssbo, buffer_offset] = 802 const auto [ssbo, buffer_offset] =
821 buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.IsWritten()); 803 buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.IsWritten());
822 bind_ssbo_pushbuffer.Push(binding, ssbo, buffer_offset, static_cast<GLsizeiptr>(size)); 804 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, ssbo, buffer_offset,
805 static_cast<GLsizeiptr>(size));
823} 806}
824 807
825void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) { 808void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) {
@@ -1432,7 +1415,7 @@ void RasterizerOpenGL::EndTransformFeedback() {
1432 const GPUVAddr gpu_addr = binding.Address(); 1415 const GPUVAddr gpu_addr = binding.Address();
1433 const std::size_t size = binding.buffer_size; 1416 const std::size_t size = binding.buffer_size;
1434 const auto [dest_buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true); 1417 const auto [dest_buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true);
1435 glCopyNamedBufferSubData(handle, *dest_buffer, 0, offset, static_cast<GLsizeiptr>(size)); 1418 glCopyNamedBufferSubData(handle, dest_buffer, 0, offset, static_cast<GLsizeiptr>(size));
1436 } 1419 }
1437} 1420}
1438 1421
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 435da4425..caea174d2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -231,9 +231,7 @@ private:
231 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 231 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
232 OGLBufferCache buffer_cache; 232 OGLBufferCache buffer_cache;
233 233
234 VertexArrayPushBuffer vertex_array_pushbuffer{state_tracker}; 234 GLint vertex_binding = 0;
235 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
236 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
237 235
238 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> 236 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
239 transform_feedback_buffers; 237 transform_feedback_buffers;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index b1804e9ea..9495f48a2 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -835,7 +835,8 @@ private:
835 835
836 void DeclareConstantBuffers() { 836 void DeclareConstantBuffers() {
837 u32 binding = device.GetBaseBindings(stage).uniform_buffer; 837 u32 binding = device.GetBaseBindings(stage).uniform_buffer;
838 for (const auto& [index, cbuf] : ir.GetConstantBuffers()) { 838 for (const auto& buffers : ir.GetConstantBuffers()) {
839 const auto index = buffers.first;
839 code.AddLine("layout (std140, binding = {}) uniform {} {{", binding++, 840 code.AddLine("layout (std140, binding = {}) uniform {} {{", binding++,
840 GetConstBufferBlock(index)); 841 GetConstBufferBlock(index));
841 code.AddLine(" uvec4 {}[{}];", GetConstBuffer(index), MAX_CONSTBUFFER_ELEMENTS); 842 code.AddLine(" uvec4 {}[{}];", GetConstBuffer(index), MAX_CONSTBUFFER_ELEMENTS);
diff --git a/src/video_core/renderer_opengl/utils.cpp b/src/video_core/renderer_opengl/utils.cpp
index b751086fa..6d7bb16b2 100644
--- a/src/video_core/renderer_opengl/utils.cpp
+++ b/src/video_core/renderer_opengl/utils.cpp
@@ -14,68 +14,6 @@
14 14
15namespace OpenGL { 15namespace OpenGL {
16 16
17struct VertexArrayPushBuffer::Entry {
18 GLuint binding_index{};
19 const GLuint* buffer{};
20 GLintptr offset{};
21 GLsizei stride{};
22};
23
24VertexArrayPushBuffer::VertexArrayPushBuffer(StateTracker& state_tracker)
25 : state_tracker{state_tracker} {}
26
27VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
28
29void VertexArrayPushBuffer::Setup() {
30 index_buffer = nullptr;
31 vertex_buffers.clear();
32}
33
34void VertexArrayPushBuffer::SetIndexBuffer(const GLuint* buffer) {
35 index_buffer = buffer;
36}
37
38void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint* buffer,
39 GLintptr offset, GLsizei stride) {
40 vertex_buffers.push_back(Entry{binding_index, buffer, offset, stride});
41}
42
43void VertexArrayPushBuffer::Bind() {
44 if (index_buffer) {
45 state_tracker.BindIndexBuffer(*index_buffer);
46 }
47
48 for (const auto& entry : vertex_buffers) {
49 glBindVertexBuffer(entry.binding_index, *entry.buffer, entry.offset, entry.stride);
50 }
51}
52
53struct BindBuffersRangePushBuffer::Entry {
54 GLuint binding;
55 const GLuint* buffer;
56 GLintptr offset;
57 GLsizeiptr size;
58};
59
60BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {}
61
62BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default;
63
64void BindBuffersRangePushBuffer::Setup() {
65 entries.clear();
66}
67
68void BindBuffersRangePushBuffer::Push(GLuint binding, const GLuint* buffer, GLintptr offset,
69 GLsizeiptr size) {
70 entries.push_back(Entry{binding, buffer, offset, size});
71}
72
73void BindBuffersRangePushBuffer::Bind() {
74 for (const Entry& entry : entries) {
75 glBindBufferRange(target, entry.binding, *entry.buffer, entry.offset, entry.size);
76 }
77}
78
79void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info) { 17void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info) {
80 if (!GLAD_GL_KHR_debug) { 18 if (!GLAD_GL_KHR_debug) {
81 // We don't need to throw an error as this is just for debugging 19 // We don't need to throw an error as this is just for debugging
diff --git a/src/video_core/renderer_opengl/utils.h b/src/video_core/renderer_opengl/utils.h
index 47ee3177b..9c09ee12c 100644
--- a/src/video_core/renderer_opengl/utils.h
+++ b/src/video_core/renderer_opengl/utils.h
@@ -11,49 +11,6 @@
11 11
12namespace OpenGL { 12namespace OpenGL {
13 13
14class StateTracker;
15
16class VertexArrayPushBuffer final {
17public:
18 explicit VertexArrayPushBuffer(StateTracker& state_tracker);
19 ~VertexArrayPushBuffer();
20
21 void Setup();
22
23 void SetIndexBuffer(const GLuint* buffer);
24
25 void SetVertexBuffer(GLuint binding_index, const GLuint* buffer, GLintptr offset,
26 GLsizei stride);
27
28 void Bind();
29
30private:
31 struct Entry;
32
33 StateTracker& state_tracker;
34
35 const GLuint* index_buffer{};
36 std::vector<Entry> vertex_buffers;
37};
38
39class BindBuffersRangePushBuffer final {
40public:
41 explicit BindBuffersRangePushBuffer(GLenum target);
42 ~BindBuffersRangePushBuffer();
43
44 void Setup();
45
46 void Push(GLuint binding, const GLuint* buffer, GLintptr offset, GLsizeiptr size);
47
48 void Bind();
49
50private:
51 struct Entry;
52
53 GLenum target;
54 std::vector<Entry> entries;
55};
56
57void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info = {}); 14void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info = {});
58 15
59} // namespace OpenGL 16} // namespace OpenGL
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 0d167afbd..81e1de2be 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -74,18 +74,18 @@ Buffer VKBufferCache::CreateBlock(VAddr cpu_addr, std::size_t size) {
74 return std::make_shared<CachedBufferBlock>(device, memory_manager, cpu_addr, size); 74 return std::make_shared<CachedBufferBlock>(device, memory_manager, cpu_addr, size);
75} 75}
76 76
77const VkBuffer* VKBufferCache::ToHandle(const Buffer& buffer) { 77VkBuffer VKBufferCache::ToHandle(const Buffer& buffer) {
78 return buffer->GetHandle(); 78 return buffer->GetHandle();
79} 79}
80 80
81const VkBuffer* VKBufferCache::GetEmptyBuffer(std::size_t size) { 81VkBuffer VKBufferCache::GetEmptyBuffer(std::size_t size) {
82 size = std::max(size, std::size_t(4)); 82 size = std::max(size, std::size_t(4));
83 const auto& empty = staging_pool.GetUnusedBuffer(size, false); 83 const auto& empty = staging_pool.GetUnusedBuffer(size, false);
84 scheduler.RequestOutsideRenderPassOperationContext(); 84 scheduler.RequestOutsideRenderPassOperationContext();
85 scheduler.Record([size, buffer = *empty.handle](vk::CommandBuffer cmdbuf) { 85 scheduler.Record([size, buffer = *empty.handle](vk::CommandBuffer cmdbuf) {
86 cmdbuf.FillBuffer(buffer, 0, size, 0); 86 cmdbuf.FillBuffer(buffer, 0, size, 0);
87 }); 87 });
88 return empty.handle.address(); 88 return *empty.handle;
89} 89}
90 90
91void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 91void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
@@ -94,7 +94,7 @@ void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, st
94 std::memcpy(staging.commit->Map(size), data, size); 94 std::memcpy(staging.commit->Map(size), data, size);
95 95
96 scheduler.RequestOutsideRenderPassOperationContext(); 96 scheduler.RequestOutsideRenderPassOperationContext();
97 scheduler.Record([staging = *staging.handle, buffer = *buffer->GetHandle(), offset, 97 scheduler.Record([staging = *staging.handle, buffer = buffer->GetHandle(), offset,
98 size](vk::CommandBuffer cmdbuf) { 98 size](vk::CommandBuffer cmdbuf) {
99 cmdbuf.CopyBuffer(staging, buffer, VkBufferCopy{0, offset, size}); 99 cmdbuf.CopyBuffer(staging, buffer, VkBufferCopy{0, offset, size});
100 100
@@ -117,7 +117,7 @@ void VKBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset,
117 u8* data) { 117 u8* data) {
118 const auto& staging = staging_pool.GetUnusedBuffer(size, true); 118 const auto& staging = staging_pool.GetUnusedBuffer(size, true);
119 scheduler.RequestOutsideRenderPassOperationContext(); 119 scheduler.RequestOutsideRenderPassOperationContext();
120 scheduler.Record([staging = *staging.handle, buffer = *buffer->GetHandle(), offset, 120 scheduler.Record([staging = *staging.handle, buffer = buffer->GetHandle(), offset,
121 size](vk::CommandBuffer cmdbuf) { 121 size](vk::CommandBuffer cmdbuf) {
122 VkBufferMemoryBarrier barrier; 122 VkBufferMemoryBarrier barrier;
123 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 123 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
@@ -144,7 +144,7 @@ void VKBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset,
144void VKBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, 144void VKBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
145 std::size_t dst_offset, std::size_t size) { 145 std::size_t dst_offset, std::size_t size) {
146 scheduler.RequestOutsideRenderPassOperationContext(); 146 scheduler.RequestOutsideRenderPassOperationContext();
147 scheduler.Record([src_buffer = *src->GetHandle(), dst_buffer = *dst->GetHandle(), src_offset, 147 scheduler.Record([src_buffer = src->GetHandle(), dst_buffer = dst->GetHandle(), src_offset,
148 dst_offset, size](vk::CommandBuffer cmdbuf) { 148 dst_offset, size](vk::CommandBuffer cmdbuf) {
149 cmdbuf.CopyBuffer(src_buffer, dst_buffer, VkBufferCopy{src_offset, dst_offset, size}); 149 cmdbuf.CopyBuffer(src_buffer, dst_buffer, VkBufferCopy{src_offset, dst_offset, size});
150 150
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index d3c23da98..3cd2e2774 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -33,8 +33,8 @@ public:
33 VAddr cpu_addr, std::size_t size); 33 VAddr cpu_addr, std::size_t size);
34 ~CachedBufferBlock(); 34 ~CachedBufferBlock();
35 35
36 const VkBuffer* GetHandle() const { 36 VkBuffer GetHandle() const {
37 return buffer.handle.address(); 37 return *buffer.handle;
38 } 38 }
39 39
40private: 40private:
@@ -50,15 +50,15 @@ public:
50 VKScheduler& scheduler, VKStagingBufferPool& staging_pool); 50 VKScheduler& scheduler, VKStagingBufferPool& staging_pool);
51 ~VKBufferCache(); 51 ~VKBufferCache();
52 52
53 const VkBuffer* GetEmptyBuffer(std::size_t size) override; 53 VkBuffer GetEmptyBuffer(std::size_t size) override;
54 54
55protected: 55protected:
56 VkBuffer ToHandle(const Buffer& buffer) override;
57
56 void WriteBarrier() override {} 58 void WriteBarrier() override {}
57 59
58 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override; 60 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override;
59 61
60 const VkBuffer* ToHandle(const Buffer& buffer) override;
61
62 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 62 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
63 const u8* data) override; 63 const u8* data) override;
64 64
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
index 9d92305f4..878a78755 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
@@ -343,13 +343,13 @@ QuadArrayPass::QuadArrayPass(const VKDevice& device, VKScheduler& scheduler,
343 343
344QuadArrayPass::~QuadArrayPass() = default; 344QuadArrayPass::~QuadArrayPass() = default;
345 345
346std::pair<const VkBuffer*, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 first) { 346std::pair<VkBuffer, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 first) {
347 const u32 num_triangle_vertices = num_vertices * 6 / 4; 347 const u32 num_triangle_vertices = num_vertices * 6 / 4;
348 const std::size_t staging_size = num_triangle_vertices * sizeof(u32); 348 const std::size_t staging_size = num_triangle_vertices * sizeof(u32);
349 auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false); 349 auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false);
350 350
351 update_descriptor_queue.Acquire(); 351 update_descriptor_queue.Acquire();
352 update_descriptor_queue.AddBuffer(buffer.handle.address(), 0, staging_size); 352 update_descriptor_queue.AddBuffer(*buffer.handle, 0, staging_size);
353 const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence()); 353 const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence());
354 354
355 scheduler.RequestOutsideRenderPassOperationContext(); 355 scheduler.RequestOutsideRenderPassOperationContext();
@@ -377,7 +377,7 @@ std::pair<const VkBuffer*, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertice
377 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 377 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
378 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, {barrier}, {}); 378 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, {barrier}, {});
379 }); 379 });
380 return {buffer.handle.address(), 0}; 380 return {*buffer.handle, 0};
381} 381}
382 382
383Uint8Pass::Uint8Pass(const VKDevice& device, VKScheduler& scheduler, 383Uint8Pass::Uint8Pass(const VKDevice& device, VKScheduler& scheduler,
@@ -391,14 +391,14 @@ Uint8Pass::Uint8Pass(const VKDevice& device, VKScheduler& scheduler,
391 391
392Uint8Pass::~Uint8Pass() = default; 392Uint8Pass::~Uint8Pass() = default;
393 393
394std::pair<const VkBuffer*, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer src_buffer, 394std::pair<VkBuffer, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer src_buffer,
395 u64 src_offset) { 395 u64 src_offset) {
396 const auto staging_size = static_cast<u32>(num_vertices * sizeof(u16)); 396 const auto staging_size = static_cast<u32>(num_vertices * sizeof(u16));
397 auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false); 397 auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false);
398 398
399 update_descriptor_queue.Acquire(); 399 update_descriptor_queue.Acquire();
400 update_descriptor_queue.AddBuffer(&src_buffer, src_offset, num_vertices); 400 update_descriptor_queue.AddBuffer(src_buffer, src_offset, num_vertices);
401 update_descriptor_queue.AddBuffer(buffer.handle.address(), 0, staging_size); 401 update_descriptor_queue.AddBuffer(*buffer.handle, 0, staging_size);
402 const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence()); 402 const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence());
403 403
404 scheduler.RequestOutsideRenderPassOperationContext(); 404 scheduler.RequestOutsideRenderPassOperationContext();
@@ -422,7 +422,7 @@ std::pair<const VkBuffer*, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer s
422 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 422 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
423 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, barrier, {}); 423 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, barrier, {});
424 }); 424 });
425 return {buffer.handle.address(), 0}; 425 return {*buffer.handle, 0};
426} 426}
427 427
428} // namespace Vulkan 428} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.h b/src/video_core/renderer_vulkan/vk_compute_pass.h
index c62516bff..ec80c8683 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.h
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.h
@@ -50,7 +50,7 @@ public:
50 VKUpdateDescriptorQueue& update_descriptor_queue); 50 VKUpdateDescriptorQueue& update_descriptor_queue);
51 ~QuadArrayPass(); 51 ~QuadArrayPass();
52 52
53 std::pair<const VkBuffer*, VkDeviceSize> Assemble(u32 num_vertices, u32 first); 53 std::pair<VkBuffer, VkDeviceSize> Assemble(u32 num_vertices, u32 first);
54 54
55private: 55private:
56 VKScheduler& scheduler; 56 VKScheduler& scheduler;
@@ -65,7 +65,7 @@ public:
65 VKUpdateDescriptorQueue& update_descriptor_queue); 65 VKUpdateDescriptorQueue& update_descriptor_queue);
66 ~Uint8Pass(); 66 ~Uint8Pass();
67 67
68 std::pair<const VkBuffer*, u64> Assemble(u32 num_vertices, VkBuffer src_buffer, u64 src_offset); 68 std::pair<VkBuffer, u64> Assemble(u32 num_vertices, VkBuffer src_buffer, u64 src_offset);
69 69
70private: 70private:
71 VKScheduler& scheduler; 71 VKScheduler& scheduler;
diff --git a/src/video_core/renderer_vulkan/vk_memory_manager.h b/src/video_core/renderer_vulkan/vk_memory_manager.h
index 35ee54d30..5b6858e9b 100644
--- a/src/video_core/renderer_vulkan/vk_memory_manager.h
+++ b/src/video_core/renderer_vulkan/vk_memory_manager.h
@@ -32,7 +32,7 @@ public:
32 * memory. When passing false, it will try to allocate device local memory. 32 * memory. When passing false, it will try to allocate device local memory.
33 * @returns A memory commit. 33 * @returns A memory commit.
34 */ 34 */
35 VKMemoryCommit Commit(const VkMemoryRequirements& reqs, bool host_visible); 35 VKMemoryCommit Commit(const VkMemoryRequirements& requirements, bool host_visible);
36 36
37 /// Commits memory required by the buffer and binds it. 37 /// Commits memory required by the buffer and binds it.
38 VKMemoryCommit Commit(const vk::Buffer& buffer, bool host_visible); 38 VKMemoryCommit Commit(const vk::Buffer& buffer, bool host_visible);
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 774ba1f26..4ca0febb8 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -137,13 +137,13 @@ Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry
137 137
138class BufferBindings final { 138class BufferBindings final {
139public: 139public:
140 void AddVertexBinding(const VkBuffer* buffer, VkDeviceSize offset) { 140 void AddVertexBinding(VkBuffer buffer, VkDeviceSize offset) {
141 vertex.buffer_ptrs[vertex.num_buffers] = buffer; 141 vertex.buffers[vertex.num_buffers] = buffer;
142 vertex.offsets[vertex.num_buffers] = offset; 142 vertex.offsets[vertex.num_buffers] = offset;
143 ++vertex.num_buffers; 143 ++vertex.num_buffers;
144 } 144 }
145 145
146 void SetIndexBinding(const VkBuffer* buffer, VkDeviceSize offset, VkIndexType type) { 146 void SetIndexBinding(VkBuffer buffer, VkDeviceSize offset, VkIndexType type) {
147 index.buffer = buffer; 147 index.buffer = buffer;
148 index.offset = offset; 148 index.offset = offset;
149 index.type = type; 149 index.type = type;
@@ -227,19 +227,19 @@ private:
227 // Some of these fields are intentionally left uninitialized to avoid initializing them twice. 227 // Some of these fields are intentionally left uninitialized to avoid initializing them twice.
228 struct { 228 struct {
229 std::size_t num_buffers = 0; 229 std::size_t num_buffers = 0;
230 std::array<const VkBuffer*, Maxwell::NumVertexArrays> buffer_ptrs; 230 std::array<VkBuffer, Maxwell::NumVertexArrays> buffers;
231 std::array<VkDeviceSize, Maxwell::NumVertexArrays> offsets; 231 std::array<VkDeviceSize, Maxwell::NumVertexArrays> offsets;
232 } vertex; 232 } vertex;
233 233
234 struct { 234 struct {
235 const VkBuffer* buffer = nullptr; 235 VkBuffer buffer = nullptr;
236 VkDeviceSize offset; 236 VkDeviceSize offset;
237 VkIndexType type; 237 VkIndexType type;
238 } index; 238 } index;
239 239
240 template <std::size_t N> 240 template <std::size_t N>
241 void BindStatic(VKScheduler& scheduler) const { 241 void BindStatic(VKScheduler& scheduler) const {
242 if (index.buffer != nullptr) { 242 if (index.buffer) {
243 BindStatic<N, true>(scheduler); 243 BindStatic<N, true>(scheduler);
244 } else { 244 } else {
245 BindStatic<N, false>(scheduler); 245 BindStatic<N, false>(scheduler);
@@ -254,18 +254,14 @@ private:
254 } 254 }
255 255
256 std::array<VkBuffer, N> buffers; 256 std::array<VkBuffer, N> buffers;
257 std::transform(vertex.buffer_ptrs.begin(), vertex.buffer_ptrs.begin() + N, buffers.begin(),
258 [](const auto ptr) { return *ptr; });
259
260 std::array<VkDeviceSize, N> offsets; 257 std::array<VkDeviceSize, N> offsets;
258 std::copy(vertex.buffers.begin(), vertex.buffers.begin() + N, buffers.begin());
261 std::copy(vertex.offsets.begin(), vertex.offsets.begin() + N, offsets.begin()); 259 std::copy(vertex.offsets.begin(), vertex.offsets.begin() + N, offsets.begin());
262 260
263 if constexpr (is_indexed) { 261 if constexpr (is_indexed) {
264 // Indexed draw 262 // Indexed draw
265 scheduler.Record([buffers, offsets, index_buffer = *index.buffer, 263 scheduler.Record([buffers, offsets, index = index](vk::CommandBuffer cmdbuf) {
266 index_offset = index.offset, 264 cmdbuf.BindIndexBuffer(index.buffer, index.offset, index.type);
267 index_type = index.type](vk::CommandBuffer cmdbuf) {
268 cmdbuf.BindIndexBuffer(index_buffer, index_offset, index_type);
269 cmdbuf.BindVertexBuffers(0, static_cast<u32>(N), buffers.data(), offsets.data()); 265 cmdbuf.BindVertexBuffers(0, static_cast<u32>(N), buffers.data(), offsets.data());
270 }); 266 });
271 } else { 267 } else {
@@ -790,7 +786,7 @@ void RasterizerVulkan::BeginTransformFeedback() {
790 const std::size_t size = binding.buffer_size; 786 const std::size_t size = binding.buffer_size;
791 const auto [buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true); 787 const auto [buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true);
792 788
793 scheduler.Record([buffer = *buffer, offset = offset, size](vk::CommandBuffer cmdbuf) { 789 scheduler.Record([buffer = buffer, offset = offset, size](vk::CommandBuffer cmdbuf) {
794 cmdbuf.BindTransformFeedbackBuffersEXT(0, 1, &buffer, &offset, &size); 790 cmdbuf.BindTransformFeedbackBuffersEXT(0, 1, &buffer, &offset, &size);
795 cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); 791 cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr);
796 }); 792 });
@@ -870,7 +866,7 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar
870 auto format = regs.index_array.format; 866 auto format = regs.index_array.format;
871 const bool is_uint8 = format == Maxwell::IndexFormat::UnsignedByte; 867 const bool is_uint8 = format == Maxwell::IndexFormat::UnsignedByte;
872 if (is_uint8 && !device.IsExtIndexTypeUint8Supported()) { 868 if (is_uint8 && !device.IsExtIndexTypeUint8Supported()) {
873 std::tie(buffer, offset) = uint8_pass.Assemble(params.num_vertices, *buffer, offset); 869 std::tie(buffer, offset) = uint8_pass.Assemble(params.num_vertices, buffer, offset);
874 format = Maxwell::IndexFormat::UnsignedShort; 870 format = Maxwell::IndexFormat::UnsignedShort;
875 } 871 }
876 872
@@ -1007,8 +1003,8 @@ void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAdd
1007 const auto size = memory_manager.Read<u32>(address + 8); 1003 const auto size = memory_manager.Read<u32>(address + 8);
1008 1004
1009 if (size == 0) { 1005 if (size == 0) {
1010 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry because 1006 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry
1011 // Vulkan doesn't like empty buffers. 1007 // because Vulkan doesn't like empty buffers.
1012 constexpr std::size_t dummy_size = 4; 1008 constexpr std::size_t dummy_size = 4;
1013 const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size); 1009 const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size);
1014 update_descriptor_queue.AddBuffer(buffer, 0, dummy_size); 1010 update_descriptor_queue.AddBuffer(buffer, 0, dummy_size);
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp
index 4bfec0077..681ecde98 100644
--- a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp
+++ b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp
@@ -35,12 +35,13 @@ void VKUpdateDescriptorQueue::Send(VkDescriptorUpdateTemplateKHR update_template
35 payload.clear(); 35 payload.clear();
36 } 36 }
37 37
38 // TODO(Rodrigo): Rework to write the payload directly
38 const auto payload_start = payload.data() + payload.size(); 39 const auto payload_start = payload.data() + payload.size();
39 for (const auto& entry : entries) { 40 for (const auto& entry : entries) {
40 if (const auto image = std::get_if<VkDescriptorImageInfo>(&entry)) { 41 if (const auto image = std::get_if<VkDescriptorImageInfo>(&entry)) {
41 payload.push_back(*image); 42 payload.push_back(*image);
42 } else if (const auto buffer = std::get_if<Buffer>(&entry)) { 43 } else if (const auto buffer = std::get_if<VkDescriptorBufferInfo>(&entry)) {
43 payload.emplace_back(*buffer->buffer, buffer->offset, buffer->size); 44 payload.push_back(*buffer);
44 } else if (const auto texel = std::get_if<VkBufferView>(&entry)) { 45 } else if (const auto texel = std::get_if<VkBufferView>(&entry)) {
45 payload.push_back(*texel); 46 payload.push_back(*texel);
46 } else { 47 } else {
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h
index a9e3d5dba..6ba2c9997 100644
--- a/src/video_core/renderer_vulkan/vk_update_descriptor.h
+++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h
@@ -18,12 +18,11 @@ class VKScheduler;
18 18
19class DescriptorUpdateEntry { 19class DescriptorUpdateEntry {
20public: 20public:
21 explicit DescriptorUpdateEntry() : image{} {} 21 explicit DescriptorUpdateEntry() {}
22 22
23 DescriptorUpdateEntry(VkDescriptorImageInfo image) : image{image} {} 23 DescriptorUpdateEntry(VkDescriptorImageInfo image) : image{image} {}
24 24
25 DescriptorUpdateEntry(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size) 25 DescriptorUpdateEntry(VkDescriptorBufferInfo buffer) : buffer{buffer} {}
26 : buffer{buffer, offset, size} {}
27 26
28 DescriptorUpdateEntry(VkBufferView texel_buffer) : texel_buffer{texel_buffer} {} 27 DescriptorUpdateEntry(VkBufferView texel_buffer) : texel_buffer{texel_buffer} {}
29 28
@@ -54,8 +53,8 @@ public:
54 entries.emplace_back(VkDescriptorImageInfo{{}, image_view, {}}); 53 entries.emplace_back(VkDescriptorImageInfo{{}, image_view, {}});
55 } 54 }
56 55
57 void AddBuffer(const VkBuffer* buffer, u64 offset, std::size_t size) { 56 void AddBuffer(VkBuffer buffer, u64 offset, std::size_t size) {
58 entries.push_back(Buffer{buffer, offset, size}); 57 entries.emplace_back(VkDescriptorBufferInfo{buffer, offset, size});
59 } 58 }
60 59
61 void AddTexelBuffer(VkBufferView texel_buffer) { 60 void AddTexelBuffer(VkBufferView texel_buffer) {
@@ -67,12 +66,7 @@ public:
67 } 66 }
68 67
69private: 68private:
70 struct Buffer { 69 using Variant = std::variant<VkDescriptorImageInfo, VkDescriptorBufferInfo, VkBufferView>;
71 const VkBuffer* buffer = nullptr;
72 u64 offset = 0;
73 std::size_t size = 0;
74 };
75 using Variant = std::variant<VkDescriptorImageInfo, Buffer, VkBufferView>;
76 70
77 const VKDevice& device; 71 const VKDevice& device;
78 VKScheduler& scheduler; 72 VKScheduler& scheduler;
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp
index 2e2711350..6d313963a 100644
--- a/src/video_core/shader/control_flow.cpp
+++ b/src/video_core/shader/control_flow.cpp
@@ -484,17 +484,17 @@ bool TryInspectAddress(CFGRebuildState& state) {
484 } 484 }
485 case BlockCollision::Inside: { 485 case BlockCollision::Inside: {
486 // This case is the tricky one: 486 // This case is the tricky one:
487 // We need to Split the block in 2 sepparate blocks 487 // We need to split the block into 2 separate blocks
488 const u32 end = state.block_info[block_index].end; 488 const u32 end = state.block_info[block_index].end;
489 BlockInfo& new_block = CreateBlockInfo(state, address, end); 489 BlockInfo& new_block = CreateBlockInfo(state, address, end);
490 BlockInfo& current_block = state.block_info[block_index]; 490 BlockInfo& current_block = state.block_info[block_index];
491 current_block.end = address - 1; 491 current_block.end = address - 1;
492 new_block.branch = current_block.branch; 492 new_block.branch = std::move(current_block.branch);
493 BlockBranchInfo forward_branch = MakeBranchInfo<SingleBranch>(); 493 BlockBranchInfo forward_branch = MakeBranchInfo<SingleBranch>();
494 const auto branch = std::get_if<SingleBranch>(forward_branch.get()); 494 const auto branch = std::get_if<SingleBranch>(forward_branch.get());
495 branch->address = address; 495 branch->address = address;
496 branch->ignore = true; 496 branch->ignore = true;
497 current_block.branch = forward_branch; 497 current_block.branch = std::move(forward_branch);
498 return true; 498 return true;
499 } 499 }
500 default: 500 default:
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index 0dd7a1196..85ee9aa5e 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -352,8 +352,10 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
352 registry.ObtainBoundSampler(static_cast<u32>(instr.image.index.Value())); 352 registry.ObtainBoundSampler(static_cast<u32>(instr.image.index.Value()));
353 } else { 353 } else {
354 const Node image_register = GetRegister(instr.gpr39); 354 const Node image_register = GetRegister(instr.gpr39);
355 const auto [base_image, buffer, offset] = TrackCbuf( 355 const auto result = TrackCbuf(image_register, global_code,
356 image_register, global_code, static_cast<s64>(global_code.size())); 356 static_cast<s64>(global_code.size()));
357 const auto buffer = std::get<1>(result);
358 const auto offset = std::get<2>(result);
357 descriptor = registry.ObtainBindlessSampler(buffer, offset); 359 descriptor = registry.ObtainBindlessSampler(buffer, offset);
358 } 360 }
359 if (!descriptor) { 361 if (!descriptor) {
@@ -497,9 +499,12 @@ Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType t
497 499
498Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) { 500Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) {
499 const Node image_register = GetRegister(reg); 501 const Node image_register = GetRegister(reg);
500 const auto [base_image, buffer, offset] = 502 const auto result =
501 TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size())); 503 TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()));
502 504
505 const auto buffer = std::get<1>(result);
506 const auto offset = std::get<2>(result);
507
503 const auto it = 508 const auto it =
504 std::find_if(std::begin(used_images), std::end(used_images), 509 std::find_if(std::begin(used_images), std::end(used_images),
505 [buffer = buffer, offset = offset](const Image& entry) { 510 [buffer = buffer, offset = offset](const Image& entry) {
diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp
index 3b391d3e6..d4ffa8014 100644
--- a/src/video_core/shader/decode/shift.cpp
+++ b/src/video_core/shader/decode/shift.cpp
@@ -23,7 +23,6 @@ Node IsFull(Node shift) {
23} 23}
24 24
25Node Shift(OperationCode opcode, Node value, Node shift) { 25Node Shift(OperationCode opcode, Node value, Node shift) {
26 Node is_full = Operation(OperationCode::LogicalIEqual, shift, Immediate(32));
27 Node shifted = Operation(opcode, move(value), shift); 26 Node shifted = Operation(opcode, move(value), shift);
28 return Operation(OperationCode::Select, IsFull(move(shift)), Immediate(0), move(shifted)); 27 return Operation(OperationCode::Select, IsFull(move(shift)), Immediate(0), move(shifted));
29} 28}
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 8852c8a1b..822674926 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -56,8 +56,7 @@ Node ShaderIR::GetConstBuffer(u64 index_, u64 offset_) {
56 const auto index = static_cast<u32>(index_); 56 const auto index = static_cast<u32>(index_);
57 const auto offset = static_cast<u32>(offset_); 57 const auto offset = static_cast<u32>(offset_);
58 58
59 const auto [entry, is_new] = used_cbufs.try_emplace(index); 59 used_cbufs.try_emplace(index).first->second.MarkAsUsed(offset);
60 entry->second.MarkAsUsed(offset);
61 60
62 return MakeNode<CbufNode>(index, Immediate(offset)); 61 return MakeNode<CbufNode>(index, Immediate(offset));
63} 62}
@@ -66,8 +65,7 @@ Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) {
66 const auto index = static_cast<u32>(index_); 65 const auto index = static_cast<u32>(index_);
67 const auto offset = static_cast<u32>(offset_); 66 const auto offset = static_cast<u32>(offset_);
68 67
69 const auto [entry, is_new] = used_cbufs.try_emplace(index); 68 used_cbufs.try_emplace(index).first->second.MarkAsUsedIndirect();
70 entry->second.MarkAsUsedIndirect();
71 69
72 Node final_offset = [&] { 70 Node final_offset = [&] {
73 // Attempt to inline constant buffer without a variable offset. This is done to allow 71 // Attempt to inline constant buffer without a variable offset. This is done to allow
@@ -166,6 +164,7 @@ Node ShaderIR::ConvertIntegerSize(Node value, Register::Size size, bool is_signe
166 std::move(value), Immediate(16)); 164 std::move(value), Immediate(16));
167 value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, 165 value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE,
168 std::move(value), Immediate(16)); 166 std::move(value), Immediate(16));
167 return value;
169 case Register::Size::Word: 168 case Register::Size::Word:
170 // Default - do nothing 169 // Default - do nothing
171 return value; 170 return value;
diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp
index 10739b37d..224943ad9 100644
--- a/src/video_core/shader/track.cpp
+++ b/src/video_core/shader/track.cpp
@@ -27,8 +27,9 @@ std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
27 27
28 if (const auto conditional = std::get_if<ConditionalNode>(&*node)) { 28 if (const auto conditional = std::get_if<ConditionalNode>(&*node)) {
29 const auto& conditional_code = conditional->GetCode(); 29 const auto& conditional_code = conditional->GetCode();
30 auto [found, internal_cursor] = FindOperation( 30 auto result = FindOperation(
31 conditional_code, static_cast<s64>(conditional_code.size() - 1), operation_code); 31 conditional_code, static_cast<s64>(conditional_code.size() - 1), operation_code);
32 auto& found = result.first;
32 if (found) { 33 if (found) {
33 return {std::move(found), cursor}; 34 return {std::move(found), cursor};
34 } 35 }
@@ -186,8 +187,8 @@ std::tuple<Node, u32, u32> ShaderIR::TrackCbuf(Node tracked, const NodeBlock& co
186std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const { 187std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const {
187 // Reduce the cursor in one to avoid infinite loops when the instruction sets the same register 188 // Reduce the cursor in one to avoid infinite loops when the instruction sets the same register
188 // that it uses as operand 189 // that it uses as operand
189 const auto [found, found_cursor] = 190 const auto result = TrackRegister(&std::get<GprNode>(*tracked), code, cursor - 1);
190 TrackRegister(&std::get<GprNode>(*tracked), code, cursor - 1); 191 const auto& found = result.first;
191 if (!found) { 192 if (!found) {
192 return {}; 193 return {};
193 } 194 }
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp
index 7af0e792c..715f39d0d 100644
--- a/src/video_core/texture_cache/surface_base.cpp
+++ b/src/video_core/texture_cache/surface_base.cpp
@@ -248,8 +248,14 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager,
248 248
249 // Use an extra temporal buffer 249 // Use an extra temporal buffer
250 auto& tmp_buffer = staging_cache.GetBuffer(1); 250 auto& tmp_buffer = staging_cache.GetBuffer(1);
251 // Special case for 3D Texture Segments
252 const bool must_read_current_data =
253 params.block_depth > 0 && params.target == VideoCore::Surface::SurfaceTarget::Texture2D;
251 tmp_buffer.resize(guest_memory_size); 254 tmp_buffer.resize(guest_memory_size);
252 host_ptr = tmp_buffer.data(); 255 host_ptr = tmp_buffer.data();
256 if (must_read_current_data) {
257 memory_manager.ReadBlockUnsafe(gpu_addr, host_ptr, guest_memory_size);
258 }
253 259
254 if (params.is_tiled) { 260 if (params.is_tiled) {
255 ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width); 261 ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width);
diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h
index a39a8661b..c5ab21f56 100644
--- a/src/video_core/texture_cache/surface_base.h
+++ b/src/video_core/texture_cache/surface_base.h
@@ -72,9 +72,9 @@ public:
72 return (cpu_addr < end) && (cpu_addr_end > start); 72 return (cpu_addr < end) && (cpu_addr_end > start);
73 } 73 }
74 74
75 bool IsInside(const GPUVAddr other_start, const GPUVAddr other_end) { 75 bool IsInside(const GPUVAddr other_start, const GPUVAddr other_end) const {
76 const GPUVAddr gpu_addr_end = gpu_addr + guest_memory_size; 76 const GPUVAddr gpu_addr_end = gpu_addr + guest_memory_size;
77 return (gpu_addr <= other_start && other_end <= gpu_addr_end); 77 return gpu_addr <= other_start && other_end <= gpu_addr_end;
78 } 78 }
79 79
80 // Use only when recycling a surface 80 // Use only when recycling a surface
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp
index 6f3ef45be..0de499946 100644
--- a/src/video_core/texture_cache/surface_params.cpp
+++ b/src/video_core/texture_cache/surface_params.cpp
@@ -167,7 +167,6 @@ SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_tabl
167 167
168SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) { 168SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) {
169 const auto& regs = system.GPU().Maxwell3D().regs; 169 const auto& regs = system.GPU().Maxwell3D().regs;
170 regs.zeta_width, regs.zeta_height, regs.zeta.format, regs.zeta.memory_layout.type;
171 SurfaceParams params; 170 SurfaceParams params;
172 params.is_tiled = regs.zeta.memory_layout.type == 171 params.is_tiled = regs.zeta.memory_layout.type ==
173 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; 172 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
diff --git a/src/video_core/texture_cache/surface_view.cpp b/src/video_core/texture_cache/surface_view.cpp
index 57a1f5803..6b5f5984b 100644
--- a/src/video_core/texture_cache/surface_view.cpp
+++ b/src/video_core/texture_cache/surface_view.cpp
@@ -20,4 +20,8 @@ bool ViewParams::operator==(const ViewParams& rhs) const {
20 std::tie(rhs.base_layer, rhs.num_layers, rhs.base_level, rhs.num_levels, rhs.target); 20 std::tie(rhs.base_layer, rhs.num_layers, rhs.base_level, rhs.num_levels, rhs.target);
21} 21}
22 22
23bool ViewParams::operator!=(const ViewParams& rhs) const {
24 return !operator==(rhs);
25}
26
23} // namespace VideoCommon 27} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/surface_view.h b/src/video_core/texture_cache/surface_view.h
index b17fd11a9..90a8bb0ae 100644
--- a/src/video_core/texture_cache/surface_view.h
+++ b/src/video_core/texture_cache/surface_view.h
@@ -21,6 +21,7 @@ struct ViewParams {
21 std::size_t Hash() const; 21 std::size_t Hash() const;
22 22
23 bool operator==(const ViewParams& rhs) const; 23 bool operator==(const ViewParams& rhs) const;
24 bool operator!=(const ViewParams& rhs) const;
24 25
25 bool IsLayered() const { 26 bool IsLayered() const {
26 switch (target) { 27 switch (target) {
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 4edd4313b..69ca08fd1 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -614,10 +614,10 @@ private:
614 * textures within the GPU if possible. Falls back to LLE when it isn't possible to use any of 614 * textures within the GPU if possible. Falls back to LLE when it isn't possible to use any of
615 * the HLE methods. 615 * the HLE methods.
616 * 616 *
617 * @param overlaps The overlapping surfaces registered in the cache. 617 * @param overlaps The overlapping surfaces registered in the cache.
618 * @param params The parameters on the new surface. 618 * @param params The parameters on the new surface.
619 * @param gpu_addr The starting address of the new surface. 619 * @param gpu_addr The starting address of the new surface.
620 * @param cache_addr The starting address of the new surface on physical memory. 620 * @param cpu_addr The starting address of the new surface on physical memory.
621 */ 621 */
622 std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(std::vector<TSurface>& overlaps, 622 std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(std::vector<TSurface>& overlaps,
623 const SurfaceParams& params, 623 const SurfaceParams& params,
@@ -647,7 +647,8 @@ private:
647 break; 647 break;
648 } 648 }
649 const u32 offset = static_cast<u32>(surface->GetCpuAddr() - cpu_addr); 649 const u32 offset = static_cast<u32>(surface->GetCpuAddr() - cpu_addr);
650 const auto [x, y, z] = params.GetBlockOffsetXYZ(offset); 650 const auto offsets = params.GetBlockOffsetXYZ(offset);
651 const auto z = std::get<2>(offsets);
651 modified |= surface->IsModified(); 652 modified |= surface->IsModified();
652 const CopyParams copy_params(0, 0, 0, 0, 0, z, 0, 0, params.width, params.height, 653 const CopyParams copy_params(0, 0, 0, 0, 0, z, 0, 0, params.width, params.height,
653 1); 654 1);
diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt
index 01f2d129d..0c9bb0d55 100644
--- a/src/web_service/CMakeLists.txt
+++ b/src/web_service/CMakeLists.txt
@@ -8,9 +8,4 @@ add_library(web_service STATIC
8) 8)
9 9
10create_target_directory_groups(web_service) 10create_target_directory_groups(web_service)
11 11target_link_libraries(web_service PRIVATE common json-headers httplib lurlparser)
12get_directory_property(OPENSSL_LIBS
13 DIRECTORY ${PROJECT_SOURCE_DIR}/externals/libressl
14 DEFINITION OPENSSL_LIBS)
15target_compile_definitions(web_service PRIVATE -DCPPHTTPLIB_OPENSSL_SUPPORT)
16target_link_libraries(web_service PRIVATE common json-headers ${OPENSSL_LIBS} httplib lurlparser)
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp
index 737ffe409..09d1651ac 100644
--- a/src/web_service/web_backend.cpp
+++ b/src/web_service/web_backend.cpp
@@ -43,7 +43,7 @@ struct Client::Impl {
43 if (jwt.empty() && !allow_anonymous) { 43 if (jwt.empty() && !allow_anonymous) {
44 LOG_ERROR(WebService, "Credentials must be provided for authenticated requests"); 44 LOG_ERROR(WebService, "Credentials must be provided for authenticated requests");
45 return Common::WebResult{Common::WebResult::Code::CredentialsMissing, 45 return Common::WebResult{Common::WebResult::Code::CredentialsMissing,
46 "Credentials needed"}; 46 "Credentials needed", ""};
47 } 47 }
48 48
49 auto result = GenericRequest(method, path, data, accept, jwt); 49 auto result = GenericRequest(method, path, data, accept, jwt);
@@ -81,12 +81,12 @@ struct Client::Impl {
81 cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port); 81 cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port);
82 } else { 82 } else {
83 LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme); 83 LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme);
84 return Common::WebResult{Common::WebResult::Code::InvalidURL, "Bad URL scheme"}; 84 return Common::WebResult{Common::WebResult::Code::InvalidURL, "Bad URL scheme", ""};
85 } 85 }
86 } 86 }
87 if (cli == nullptr) { 87 if (cli == nullptr) {
88 LOG_ERROR(WebService, "Invalid URL {}", host + path); 88 LOG_ERROR(WebService, "Invalid URL {}", host + path);
89 return Common::WebResult{Common::WebResult::Code::InvalidURL, "Invalid URL"}; 89 return Common::WebResult{Common::WebResult::Code::InvalidURL, "Invalid URL", ""};
90 } 90 }
91 cli->set_timeout_sec(TIMEOUT_SECONDS); 91 cli->set_timeout_sec(TIMEOUT_SECONDS);
92 92
@@ -118,27 +118,27 @@ struct Client::Impl {
118 118
119 if (!cli->send(request, response)) { 119 if (!cli->send(request, response)) {
120 LOG_ERROR(WebService, "{} to {} returned null", method, host + path); 120 LOG_ERROR(WebService, "{} to {} returned null", method, host + path);
121 return Common::WebResult{Common::WebResult::Code::LibError, "Null response"}; 121 return Common::WebResult{Common::WebResult::Code::LibError, "Null response", ""};
122 } 122 }
123 123
124 if (response.status >= 400) { 124 if (response.status >= 400) {
125 LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path, 125 LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path,
126 response.status); 126 response.status);
127 return Common::WebResult{Common::WebResult::Code::HttpError, 127 return Common::WebResult{Common::WebResult::Code::HttpError,
128 std::to_string(response.status)}; 128 std::to_string(response.status), ""};
129 } 129 }
130 130
131 auto content_type = response.headers.find("content-type"); 131 auto content_type = response.headers.find("content-type");
132 132
133 if (content_type == response.headers.end()) { 133 if (content_type == response.headers.end()) {
134 LOG_ERROR(WebService, "{} to {} returned no content", method, host + path); 134 LOG_ERROR(WebService, "{} to {} returned no content", method, host + path);
135 return Common::WebResult{Common::WebResult::Code::WrongContent, ""}; 135 return Common::WebResult{Common::WebResult::Code::WrongContent, "", ""};
136 } 136 }
137 137
138 if (content_type->second.find(accept) == std::string::npos) { 138 if (content_type->second.find(accept) == std::string::npos) {
139 LOG_ERROR(WebService, "{} to {} returned wrong content: {}", method, host + path, 139 LOG_ERROR(WebService, "{} to {} returned wrong content: {}", method, host + path,
140 content_type->second); 140 content_type->second);
141 return Common::WebResult{Common::WebResult::Code::WrongContent, "Wrong content"}; 141 return Common::WebResult{Common::WebResult::Code::WrongContent, "Wrong content", ""};
142 } 142 }
143 return Common::WebResult{Common::WebResult::Code::Success, "", response.body}; 143 return Common::WebResult{Common::WebResult::Code::Success, "", response.body};
144 } 144 }
diff --git a/src/yuzu/debugger/profiler.cpp b/src/yuzu/debugger/profiler.cpp
index f594ef076..53049ffd6 100644
--- a/src/yuzu/debugger/profiler.cpp
+++ b/src/yuzu/debugger/profiler.cpp
@@ -51,7 +51,8 @@ MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Di
51 setWindowTitle(tr("MicroProfile")); 51 setWindowTitle(tr("MicroProfile"));
52 resize(1000, 600); 52 resize(1000, 600);
53 // Remove the "?" button from the titlebar and enable the maximize button 53 // Remove the "?" button from the titlebar and enable the maximize button
54 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::WindowMaximizeButtonHint); 54 setWindowFlags((windowFlags() & ~Qt::WindowContextHelpButtonHint) |
55 Qt::WindowMaximizeButtonHint);
55 56
56#if MICROPROFILE_ENABLED 57#if MICROPROFILE_ENABLED
57 58
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index da2c27aa2..2018150db 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -91,7 +91,8 @@ std::pair<std::vector<u8>, std::string> GetGameListCachedObject(
91 return generator(); 91 return generator();
92 } 92 }
93 93
94 if (file1.write(reinterpret_cast<const char*>(icon.data()), icon.size()) != icon.size()) { 94 if (file1.write(reinterpret_cast<const char*>(icon.data()), icon.size()) !=
95 s64(icon.size())) {
95 LOG_ERROR(Frontend, "Failed to write data to cache file."); 96 LOG_ERROR(Frontend, "Failed to write data to cache file.");
96 return generator(); 97 return generator();
97 } 98 }
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 1717e06f9..2c8eb481d 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1019,9 +1019,9 @@ void GMainWindow::BootGame(const QString& filename) {
1019 std::string title_name; 1019 std::string title_name;
1020 const auto res = Core::System::GetInstance().GetGameName(title_name); 1020 const auto res = Core::System::GetInstance().GetGameName(title_name);
1021 if (res != Loader::ResultStatus::Success) { 1021 if (res != Loader::ResultStatus::Success) {
1022 const auto [nacp, icon_file] = FileSys::PatchManager(title_id).GetControlMetadata(); 1022 const auto metadata = FileSys::PatchManager(title_id).GetControlMetadata();
1023 if (nacp != nullptr) 1023 if (metadata.first != nullptr)
1024 title_name = nacp->GetApplicationName(); 1024 title_name = metadata.first->GetApplicationName();
1025 1025
1026 if (title_name.empty()) 1026 if (title_name.empty())
1027 title_name = FileUtil::GetFilename(filename.toStdString()); 1027 title_name = FileUtil::GetFilename(filename.toStdString());
@@ -1628,7 +1628,7 @@ void GMainWindow::OnMenuInstallToNAND() {
1628 } 1628 }
1629 1629
1630 FileSys::InstallResult res; 1630 FileSys::InstallResult res;
1631 if (index >= static_cast<size_t>(FileSys::TitleType::Application)) { 1631 if (index >= static_cast<s32>(FileSys::TitleType::Application)) {
1632 res = Core::System::GetInstance() 1632 res = Core::System::GetInstance()
1633 .GetFileSystemController() 1633 .GetFileSystemController()
1634 .GetUserNANDContents() 1634 .GetUserNANDContents()