diff options
-rwxr-xr-x | README.md | 2 | ||||
-rwxr-xr-x | src/common/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | src/common/range_mutex.h | 93 | ||||
-rwxr-xr-x | src/common/settings.h | 11 | ||||
-rwxr-xr-x | src/core/device_memory_manager.h | 3 | ||||
-rwxr-xr-x | src/core/device_memory_manager.inc | 16 | ||||
-rwxr-xr-x | src/core/file_sys/system_archive/system_archive.cpp | 12 | ||||
-rwxr-xr-x | src/core/hle/service/glue/time/manager.cpp | 3 | ||||
-rwxr-xr-x | src/core/hle/service/glue/time/time_zone_binary.cpp | 11 | ||||
-rwxr-xr-x | src/core/memory.cpp | 14 | ||||
-rwxr-xr-x | src/video_core/buffer_cache/buffer_cache.h | 5 | ||||
-rwxr-xr-x | src/video_core/renderer_opengl/renderer_opengl.cpp | 10 | ||||
-rwxr-xr-x | src/video_core/renderer_vulkan/vk_blit_screen.cpp | 8 | ||||
-rwxr-xr-x | src/video_core/renderer_vulkan/vk_query_cache.cpp | 14 |
14 files changed, 167 insertions, 36 deletions
@@ -1,7 +1,7 @@ | |||
1 | yuzu emulator early access | 1 | yuzu emulator early access |
2 | ============= | 2 | ============= |
3 | 3 | ||
4 | This is the source code for early-access 4083. | 4 | This is the source code for early-access 4084. |
5 | 5 | ||
6 | ## Legal Notice | 6 | ## Legal Notice |
7 | 7 | ||
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index f1483331f..b008fbe6b 100755 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
@@ -106,6 +106,7 @@ add_library(common STATIC | |||
106 | precompiled_headers.h | 106 | precompiled_headers.h |
107 | quaternion.h | 107 | quaternion.h |
108 | range_map.h | 108 | range_map.h |
109 | range_mutex.h | ||
109 | reader_writer_queue.h | 110 | reader_writer_queue.h |
110 | ring_buffer.h | 111 | ring_buffer.h |
111 | ${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp | 112 | ${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp |
diff --git a/src/common/range_mutex.h b/src/common/range_mutex.h new file mode 100755 index 000000000..d6c949811 --- /dev/null +++ b/src/common/range_mutex.h | |||
@@ -0,0 +1,93 @@ | |||
1 | // SPDX-FileCopyrightText: 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include <condition_variable> | ||
7 | #include <mutex> | ||
8 | |||
9 | #include "common/intrusive_list.h" | ||
10 | |||
11 | namespace Common { | ||
12 | |||
13 | class ScopedRangeLock; | ||
14 | |||
15 | class RangeMutex { | ||
16 | public: | ||
17 | explicit RangeMutex() = default; | ||
18 | ~RangeMutex() = default; | ||
19 | |||
20 | private: | ||
21 | friend class ScopedRangeLock; | ||
22 | |||
23 | void Lock(ScopedRangeLock& l); | ||
24 | void Unlock(ScopedRangeLock& l); | ||
25 | bool HasIntersectionLocked(ScopedRangeLock& l); | ||
26 | |||
27 | private: | ||
28 | std::mutex m_mutex; | ||
29 | std::condition_variable m_cv; | ||
30 | |||
31 | using LockList = Common::IntrusiveListBaseTraits<ScopedRangeLock>::ListType; | ||
32 | LockList m_list; | ||
33 | }; | ||
34 | |||
35 | class ScopedRangeLock : public Common::IntrusiveListBaseNode<ScopedRangeLock> { | ||
36 | public: | ||
37 | explicit ScopedRangeLock(RangeMutex& mutex, u64 address, u64 size) | ||
38 | : m_mutex(mutex), m_address(address), m_size(size) { | ||
39 | if (m_size > 0) { | ||
40 | m_mutex.Lock(*this); | ||
41 | } | ||
42 | } | ||
43 | ~ScopedRangeLock() { | ||
44 | if (m_size > 0) { | ||
45 | m_mutex.Unlock(*this); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | u64 GetAddress() const { | ||
50 | return m_address; | ||
51 | } | ||
52 | |||
53 | u64 GetSize() const { | ||
54 | return m_size; | ||
55 | } | ||
56 | |||
57 | private: | ||
58 | RangeMutex& m_mutex; | ||
59 | const u64 m_address{}; | ||
60 | const u64 m_size{}; | ||
61 | }; | ||
62 | |||
63 | inline void RangeMutex::Lock(ScopedRangeLock& l) { | ||
64 | std::unique_lock lk{m_mutex}; | ||
65 | m_cv.wait(lk, [&] { return !HasIntersectionLocked(l); }); | ||
66 | m_list.push_back(l); | ||
67 | } | ||
68 | |||
69 | inline void RangeMutex::Unlock(ScopedRangeLock& l) { | ||
70 | { | ||
71 | std::scoped_lock lk{m_mutex}; | ||
72 | m_list.erase(m_list.iterator_to(l)); | ||
73 | } | ||
74 | m_cv.notify_all(); | ||
75 | } | ||
76 | |||
77 | inline bool RangeMutex::HasIntersectionLocked(ScopedRangeLock& l) { | ||
78 | const auto cur_begin = l.GetAddress(); | ||
79 | const auto cur_last = l.GetAddress() + l.GetSize() - 1; | ||
80 | |||
81 | for (const auto& other : m_list) { | ||
82 | const auto other_begin = other.GetAddress(); | ||
83 | const auto other_last = other.GetAddress() + other.GetSize() - 1; | ||
84 | |||
85 | if (cur_begin <= other_last && other_begin <= cur_last) { | ||
86 | return true; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | return false; | ||
91 | } | ||
92 | |||
93 | } // namespace Common | ||
diff --git a/src/common/settings.h b/src/common/settings.h index db8606f93..a3e34528b 100755 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
@@ -420,8 +420,15 @@ struct Values { | |||
420 | SwitchableSetting<s64> custom_rtc{ | 420 | SwitchableSetting<s64> custom_rtc{ |
421 | linkage, 0, "custom_rtc", Category::System, Specialization::Time, | 421 | linkage, 0, "custom_rtc", Category::System, Specialization::Time, |
422 | false, true, &custom_rtc_enabled}; | 422 | false, true, &custom_rtc_enabled}; |
423 | SwitchableSetting<s64, false> custom_rtc_offset{ | 423 | SwitchableSetting<s64, true> custom_rtc_offset{linkage, |
424 | linkage, 0, "custom_rtc_offset", Category::System, Specialization::Countable, true, true}; | 424 | 0, |
425 | std::numeric_limits<int>::min(), | ||
426 | std::numeric_limits<int>::max(), | ||
427 | "custom_rtc_offset", | ||
428 | Category::System, | ||
429 | Specialization::Countable, | ||
430 | true, | ||
431 | true}; | ||
425 | SwitchableSetting<bool> rng_seed_enabled{ | 432 | SwitchableSetting<bool> rng_seed_enabled{ |
426 | linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true}; | 433 | linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true}; |
427 | SwitchableSetting<u32> rng_seed{ | 434 | SwitchableSetting<u32> rng_seed{ |
diff --git a/src/core/device_memory_manager.h b/src/core/device_memory_manager.h index ffeed46cc..63823602c 100755 --- a/src/core/device_memory_manager.h +++ b/src/core/device_memory_manager.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <mutex> | 10 | #include <mutex> |
11 | 11 | ||
12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
13 | #include "common/range_mutex.h" | ||
13 | #include "common/scratch_buffer.h" | 14 | #include "common/scratch_buffer.h" |
14 | #include "common/virtual_buffer.h" | 15 | #include "common/virtual_buffer.h" |
15 | 16 | ||
@@ -204,7 +205,7 @@ private: | |||
204 | (1ULL << (device_virtual_bits - page_bits)) / subentries; | 205 | (1ULL << (device_virtual_bits - page_bits)) / subentries; |
205 | using CachedPages = std::array<CounterEntry, num_counter_entries>; | 206 | using CachedPages = std::array<CounterEntry, num_counter_entries>; |
206 | std::unique_ptr<CachedPages> cached_pages; | 207 | std::unique_ptr<CachedPages> cached_pages; |
207 | std::mutex counter_guard; | 208 | Common::RangeMutex counter_guard; |
208 | std::mutex mapping_guard; | 209 | std::mutex mapping_guard; |
209 | }; | 210 | }; |
210 | 211 | ||
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 8ce122872..0a59000aa 100755 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc | |||
@@ -31,9 +31,8 @@ public: | |||
31 | buffer.resize(0); | 31 | buffer.resize(0); |
32 | size_t index = 0; | 32 | size_t index = 0; |
33 | const auto add_value = [&](u32 value) { | 33 | const auto add_value = [&](u32 value) { |
34 | buffer[index] = value; | 34 | buffer.resize(index + 1); |
35 | index++; | 35 | buffer[index++] = value; |
36 | buffer.resize(index); | ||
37 | }; | 36 | }; |
38 | 37 | ||
39 | u32 iter_entry = start_entry; | 38 | u32 iter_entry = start_entry; |
@@ -509,12 +508,7 @@ void DeviceMemoryManager<Traits>::UnregisterProcess(Asid asid) { | |||
509 | 508 | ||
510 | template <typename Traits> | 509 | template <typename Traits> |
511 | void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size, s32 delta) { | 510 | void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size, s32 delta) { |
512 | std::unique_lock<std::mutex> lk(counter_guard, std::defer_lock); | 511 | Common::ScopedRangeLock lk(counter_guard, addr, size); |
513 | const auto Lock = [&] { | ||
514 | if (!lk) { | ||
515 | lk.lock(); | ||
516 | } | ||
517 | }; | ||
518 | u64 uncache_begin = 0; | 512 | u64 uncache_begin = 0; |
519 | u64 cache_begin = 0; | 513 | u64 cache_begin = 0; |
520 | u64 uncache_bytes = 0; | 514 | u64 uncache_bytes = 0; |
@@ -549,7 +543,6 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
549 | } | 543 | } |
550 | uncache_bytes += Memory::YUZU_PAGESIZE; | 544 | uncache_bytes += Memory::YUZU_PAGESIZE; |
551 | } else if (uncache_bytes > 0) { | 545 | } else if (uncache_bytes > 0) { |
552 | Lock(); | ||
553 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, | 546 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, |
554 | uncache_bytes, false); | 547 | uncache_bytes, false); |
555 | uncache_bytes = 0; | 548 | uncache_bytes = 0; |
@@ -560,7 +553,6 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
560 | } | 553 | } |
561 | cache_bytes += Memory::YUZU_PAGESIZE; | 554 | cache_bytes += Memory::YUZU_PAGESIZE; |
562 | } else if (cache_bytes > 0) { | 555 | } else if (cache_bytes > 0) { |
563 | Lock(); | ||
564 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, | 556 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, |
565 | true); | 557 | true); |
566 | cache_bytes = 0; | 558 | cache_bytes = 0; |
@@ -568,12 +560,10 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
568 | vpage++; | 560 | vpage++; |
569 | } | 561 | } |
570 | if (uncache_bytes > 0) { | 562 | if (uncache_bytes > 0) { |
571 | Lock(); | ||
572 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes, | 563 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes, |
573 | false); | 564 | false); |
574 | } | 565 | } |
575 | if (cache_bytes > 0) { | 566 | if (cache_bytes > 0) { |
576 | Lock(); | ||
577 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, | 567 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, |
578 | true); | 568 | true); |
579 | } | 569 | } |
diff --git a/src/core/file_sys/system_archive/system_archive.cpp b/src/core/file_sys/system_archive/system_archive.cpp index 09caaface..2d62a92a5 100755 --- a/src/core/file_sys/system_archive/system_archive.cpp +++ b/src/core/file_sys/system_archive/system_archive.cpp | |||
@@ -67,25 +67,29 @@ constexpr std::array<SystemArchiveDescriptor, SYSTEM_ARCHIVE_COUNT> SYSTEM_ARCHI | |||
67 | }}; | 67 | }}; |
68 | 68 | ||
69 | VirtualFile SynthesizeSystemArchive(const u64 title_id) { | 69 | VirtualFile SynthesizeSystemArchive(const u64 title_id) { |
70 | if (title_id < SYSTEM_ARCHIVES.front().title_id || title_id > SYSTEM_ARCHIVES.back().title_id) | 70 | if (title_id < SYSTEM_ARCHIVES.front().title_id || title_id > SYSTEM_ARCHIVES.back().title_id) { |
71 | return nullptr; | 71 | return nullptr; |
72 | } | ||
72 | 73 | ||
73 | const auto& desc = SYSTEM_ARCHIVES[title_id - SYSTEM_ARCHIVE_BASE_TITLE_ID]; | 74 | const auto& desc = SYSTEM_ARCHIVES[title_id - SYSTEM_ARCHIVE_BASE_TITLE_ID]; |
74 | 75 | ||
75 | LOG_INFO(Service_FS, "Synthesizing system archive '{}' (0x{:016X}).", desc.name, desc.title_id); | 76 | LOG_INFO(Service_FS, "Synthesizing system archive '{}' (0x{:016X}).", desc.name, desc.title_id); |
76 | 77 | ||
77 | if (desc.supplier == nullptr) | 78 | if (desc.supplier == nullptr) { |
78 | return nullptr; | 79 | return nullptr; |
80 | } | ||
79 | 81 | ||
80 | const auto dir = desc.supplier(); | 82 | const auto dir = desc.supplier(); |
81 | 83 | ||
82 | if (dir == nullptr) | 84 | if (dir == nullptr) { |
83 | return nullptr; | 85 | return nullptr; |
86 | } | ||
84 | 87 | ||
85 | const auto romfs = CreateRomFS(dir); | 88 | const auto romfs = CreateRomFS(dir); |
86 | 89 | ||
87 | if (romfs == nullptr) | 90 | if (romfs == nullptr) { |
88 | return nullptr; | 91 | return nullptr; |
92 | } | ||
89 | 93 | ||
90 | LOG_INFO(Service_FS, " - System archive generation successful!"); | 94 | LOG_INFO(Service_FS, " - System archive generation successful!"); |
91 | return romfs; | 95 | return romfs; |
diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp index afaea4135..6423e5089 100755 --- a/src/core/hle/service/glue/time/manager.cpp +++ b/src/core/hle/service/glue/time/manager.cpp | |||
@@ -89,7 +89,8 @@ Service::PSC::Time::LocationName GetTimeZoneString(Service::PSC::Time::LocationN | |||
89 | std::min(configured_name.name.size(), configured_zone.size())); | 89 | std::min(configured_name.name.size(), configured_zone.size())); |
90 | } | 90 | } |
91 | 91 | ||
92 | ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone!"); | 92 | ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone {}!", |
93 | configured_name.name.data()); | ||
93 | 94 | ||
94 | return configured_name; | 95 | return configured_name; |
95 | } | 96 | } |
diff --git a/src/core/hle/service/glue/time/time_zone_binary.cpp b/src/core/hle/service/glue/time/time_zone_binary.cpp index 96530dce5..67969aa3f 100755 --- a/src/core/hle/service/glue/time/time_zone_binary.cpp +++ b/src/core/hle/service/glue/time/time_zone_binary.cpp | |||
@@ -61,6 +61,16 @@ Result MountTimeZoneBinary(Core::System& system) { | |||
61 | g_time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS()); | 61 | g_time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS()); |
62 | } | 62 | } |
63 | 63 | ||
64 | if (g_time_zone_binary_romfs) { | ||
65 | // Validate that the romfs is readable, using invalid firmware keys can cause this to get | ||
66 | // set but the files to be garbage. In that case, we want to hit the next path and | ||
67 | // synthesise them instead. | ||
68 | Service::PSC::Time::LocationName name{"Etc/GMT"}; | ||
69 | if (!IsTimeZoneBinaryValid(name)) { | ||
70 | ResetTimeZoneBinary(); | ||
71 | } | ||
72 | } | ||
73 | |||
64 | if (!g_time_zone_binary_romfs) { | 74 | if (!g_time_zone_binary_romfs) { |
65 | g_time_zone_binary_romfs = FileSys::ExtractRomFS( | 75 | g_time_zone_binary_romfs = FileSys::ExtractRomFS( |
66 | FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId)); | 76 | FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId)); |
@@ -102,6 +112,7 @@ bool IsTimeZoneBinaryValid(Service::PSC::Time::LocationName& name) { | |||
102 | 112 | ||
103 | auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)}; | 113 | auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)}; |
104 | if (!vfs_file) { | 114 | if (!vfs_file) { |
115 | LOG_INFO(Service_Time, "Could not find timezone file {}", path); | ||
105 | return false; | 116 | return false; |
106 | } | 117 | } |
107 | return vfs_file->GetSize() != 0; | 118 | return vfs_file->GetSize() != 0; |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 1db44d504..4b046a1f8 100755 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
@@ -1093,6 +1093,20 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) { | |||
1093 | [&] { rasterizer = true; }); | 1093 | [&] { rasterizer = true; }); |
1094 | if (rasterizer) { | 1094 | if (rasterizer) { |
1095 | impl->InvalidateGPUMemory(ptr, size); | 1095 | impl->InvalidateGPUMemory(ptr, size); |
1096 | |||
1097 | const auto type = impl->current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Type(); | ||
1098 | if (type == Common::PageType::RasterizerCachedMemory) { | ||
1099 | // Check if device mapped. If not, this bugged and we can unmark. | ||
1100 | DAddr addr{}; | ||
1101 | Common::ScratchBuffer<u32> buffer; | ||
1102 | impl->gpu_device_memory->ApplyOpOnPointer(ptr, buffer, | ||
1103 | [&](DAddr address) { addr = address; }); | ||
1104 | |||
1105 | if (addr == 0) { | ||
1106 | LOG_ERROR(HW_Memory, "Fixing unmapped cached region {:#x}", GetInteger(vaddr)); | ||
1107 | impl->RasterizerMarkRegionCached(GetInteger(vaddr), size, false); | ||
1108 | } | ||
1109 | } | ||
1096 | } | 1110 | } |
1097 | 1111 | ||
1098 | #ifdef __linux__ | 1112 | #ifdef __linux__ |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 74fd10286..61b1e85bf 100755 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
@@ -1546,7 +1546,10 @@ void BufferCache<P>::ImmediateUploadMemory([[maybe_unused]] Buffer& buffer, | |||
1546 | std::span<const u8> upload_span; | 1546 | std::span<const u8> upload_span; |
1547 | const DAddr device_addr = buffer.CpuAddr() + copy.dst_offset; | 1547 | const DAddr device_addr = buffer.CpuAddr() + copy.dst_offset; |
1548 | if (IsRangeGranular(device_addr, copy.size)) { | 1548 | if (IsRangeGranular(device_addr, copy.size)) { |
1549 | upload_span = std::span(device_memory.GetPointer<u8>(device_addr), copy.size); | 1549 | auto* const ptr = device_memory.GetPointer<u8>(device_addr); |
1550 | if (ptr != nullptr) { | ||
1551 | upload_span = std::span(ptr, copy.size); | ||
1552 | } | ||
1550 | } else { | 1553 | } else { |
1551 | if (immediate_buffer.empty()) { | 1554 | if (immediate_buffer.empty()) { |
1552 | immediate_buffer = ImmediateBuffer(largest_copy); | 1555 | immediate_buffer = ImmediateBuffer(largest_copy); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 18bbfc348..1b3a6916f 100755 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
@@ -243,10 +243,12 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf | |||
243 | const u64 size_in_bytes{Tegra::Texture::CalculateSize( | 243 | const u64 size_in_bytes{Tegra::Texture::CalculateSize( |
244 | true, bytes_per_pixel, framebuffer.stride, framebuffer.height, 1, block_height_log2, 0)}; | 244 | true, bytes_per_pixel, framebuffer.stride, framebuffer.height, 1, block_height_log2, 0)}; |
245 | const u8* const host_ptr{device_memory.GetPointer<u8>(framebuffer_addr)}; | 245 | const u8* const host_ptr{device_memory.GetPointer<u8>(framebuffer_addr)}; |
246 | const std::span<const u8> input_data(host_ptr, size_in_bytes); | 246 | if (host_ptr != nullptr) { |
247 | Tegra::Texture::UnswizzleTexture(gl_framebuffer_data, input_data, bytes_per_pixel, | 247 | const std::span<const u8> input_data(host_ptr, size_in_bytes); |
248 | framebuffer.width, framebuffer.height, 1, block_height_log2, | 248 | Tegra::Texture::UnswizzleTexture(gl_framebuffer_data, input_data, bytes_per_pixel, |
249 | 0); | 249 | framebuffer.width, framebuffer.height, 1, |
250 | block_height_log2, 0); | ||
251 | } | ||
250 | 252 | ||
251 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 253 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
252 | glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(framebuffer.stride)); | 254 | glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(framebuffer.stride)); |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 3c0299a85..f632005f5 100755 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
@@ -230,9 +230,11 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, | |||
230 | const u64 tiled_size{Tegra::Texture::CalculateSize(true, bytes_per_pixel, | 230 | const u64 tiled_size{Tegra::Texture::CalculateSize(true, bytes_per_pixel, |
231 | framebuffer.stride, framebuffer.height, | 231 | framebuffer.stride, framebuffer.height, |
232 | 1, block_height_log2, 0)}; | 232 | 1, block_height_log2, 0)}; |
233 | Tegra::Texture::UnswizzleTexture( | 233 | if (host_ptr != nullptr) { |
234 | mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size), | 234 | Tegra::Texture::UnswizzleTexture( |
235 | bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0); | 235 | mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size), |
236 | bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0); | ||
237 | } | ||
236 | 238 | ||
237 | const VkBufferImageCopy copy{ | 239 | const VkBufferImageCopy copy{ |
238 | .bufferOffset = image_offset, | 240 | .bufferOffset = image_offset, |
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 025d250ba..56ac24b67 100755 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp | |||
@@ -1064,8 +1064,6 @@ public: | |||
1064 | } | 1064 | } |
1065 | }); | 1065 | }); |
1066 | } | 1066 | } |
1067 | auto* ptr = device_memory.GetPointer<u8>(new_query->dependant_address); | ||
1068 | ASSERT(ptr != nullptr); | ||
1069 | 1067 | ||
1070 | new_query->dependant_manage = must_manage_dependance; | 1068 | new_query->dependant_manage = must_manage_dependance; |
1071 | pending_flush_queries.push_back(index); | 1069 | pending_flush_queries.push_back(index); |
@@ -1104,9 +1102,11 @@ public: | |||
1104 | tfb_streamer.Free(query->dependant_index); | 1102 | tfb_streamer.Free(query->dependant_index); |
1105 | } else { | 1103 | } else { |
1106 | u8* pointer = device_memory.GetPointer<u8>(query->dependant_address); | 1104 | u8* pointer = device_memory.GetPointer<u8>(query->dependant_address); |
1107 | u32 result; | 1105 | if (pointer != nullptr) { |
1108 | std::memcpy(&result, pointer, sizeof(u32)); | 1106 | u32 result; |
1109 | num_vertices = static_cast<u64>(result) / query->stride; | 1107 | std::memcpy(&result, pointer, sizeof(u32)); |
1108 | num_vertices = static_cast<u64>(result) / query->stride; | ||
1109 | } | ||
1110 | } | 1110 | } |
1111 | query->value = [&]() -> u64 { | 1111 | query->value = [&]() -> u64 { |
1112 | switch (query->topology) { | 1112 | switch (query->topology) { |
@@ -1360,7 +1360,9 @@ bool QueryCacheRuntime::HostConditionalRenderingCompareValues(VideoCommon::Looku | |||
1360 | const auto check_value = [&](DAddr address) { | 1360 | const auto check_value = [&](DAddr address) { |
1361 | u8* ptr = impl->device_memory.GetPointer<u8>(address); | 1361 | u8* ptr = impl->device_memory.GetPointer<u8>(address); |
1362 | u64 value{}; | 1362 | u64 value{}; |
1363 | std::memcpy(&value, ptr, sizeof(value)); | 1363 | if (ptr != nullptr) { |
1364 | std::memcpy(&value, ptr, sizeof(value)); | ||
1365 | } | ||
1364 | return value == 0; | 1366 | return value == 0; |
1365 | }; | 1367 | }; |
1366 | std::array<VideoCommon::LookupData*, 2> objects{&object_1, &object_2}; | 1368 | std::array<VideoCommon::LookupData*, 2> objects{&object_1, &object_2}; |