diff options
Diffstat (limited to 'src')
40 files changed, 281 insertions, 26 deletions
diff --git a/src/audio_core/renderer/performance/performance_manager.cpp b/src/audio_core/renderer/performance/performance_manager.cpp index fd5873e1e..8aa0f5ed0 100644 --- a/src/audio_core/renderer/performance/performance_manager.cpp +++ b/src/audio_core/renderer/performance/performance_manager.cpp | |||
| @@ -26,6 +26,7 @@ void PerformanceManager::CreateImpl(const size_t version) { | |||
| 26 | impl = std::make_unique< | 26 | impl = std::make_unique< |
| 27 | PerformanceManagerImpl<PerformanceVersion::Version1, PerformanceFrameHeaderVersion1, | 27 | PerformanceManagerImpl<PerformanceVersion::Version1, PerformanceFrameHeaderVersion1, |
| 28 | PerformanceEntryVersion1, PerformanceDetailVersion1>>(); | 28 | PerformanceEntryVersion1, PerformanceDetailVersion1>>(); |
| 29 | break; | ||
| 29 | } | 30 | } |
| 30 | } | 31 | } |
| 31 | 32 | ||
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c0555f840..b7c15c191 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -34,6 +34,8 @@ add_library(common STATIC | |||
| 34 | bit_util.h | 34 | bit_util.h |
| 35 | cityhash.cpp | 35 | cityhash.cpp |
| 36 | cityhash.h | 36 | cityhash.h |
| 37 | cache_management.cpp | ||
| 38 | cache_management.h | ||
| 37 | common_funcs.h | 39 | common_funcs.h |
| 38 | common_types.h | 40 | common_types.h |
| 39 | concepts.h | 41 | concepts.h |
diff --git a/src/common/atomic_helpers.h b/src/common/atomic_helpers.h index bef5015c1..aef3b66a4 100644 --- a/src/common/atomic_helpers.h +++ b/src/common/atomic_helpers.h | |||
| @@ -156,6 +156,7 @@ AE_FORCEINLINE void compiler_fence(memory_order order) AE_NO_TSAN { | |||
| 156 | break; | 156 | break; |
| 157 | default: | 157 | default: |
| 158 | assert(false); | 158 | assert(false); |
| 159 | break; | ||
| 159 | } | 160 | } |
| 160 | } | 161 | } |
| 161 | 162 | ||
diff --git a/src/common/cache_management.cpp b/src/common/cache_management.cpp new file mode 100644 index 000000000..57810b76a --- /dev/null +++ b/src/common/cache_management.cpp | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <cstring> | ||
| 5 | |||
| 6 | #include "alignment.h" | ||
| 7 | #include "cache_management.h" | ||
| 8 | #include "common_types.h" | ||
| 9 | |||
| 10 | namespace Common { | ||
| 11 | |||
| 12 | #if defined(ARCHITECTURE_x86_64) | ||
| 13 | |||
| 14 | // Most cache operations are no-ops on x86 | ||
| 15 | |||
| 16 | void DataCacheLineCleanByVAToPoU(void* start, size_t size) {} | ||
| 17 | void DataCacheLineCleanAndInvalidateByVAToPoC(void* start, size_t size) {} | ||
| 18 | void DataCacheLineCleanByVAToPoC(void* start, size_t size) {} | ||
| 19 | void DataCacheZeroByVA(void* start, size_t size) { | ||
| 20 | std::memset(start, 0, size); | ||
| 21 | } | ||
| 22 | |||
| 23 | #elif defined(ARCHITECTURE_arm64) | ||
| 24 | |||
| 25 | // BS/DminLine is log2(cache size in words), we want size in bytes | ||
| 26 | #define EXTRACT_DMINLINE(ctr_el0) (1 << ((((ctr_el0) >> 16) & 0xf) + 2)) | ||
| 27 | #define EXTRACT_BS(dczid_el0) (1 << (((dczid_el0)&0xf) + 2)) | ||
| 28 | |||
| 29 | #define DEFINE_DC_OP(op_name, function_name) \ | ||
| 30 | void function_name(void* start, size_t size) { \ | ||
| 31 | size_t ctr_el0; \ | ||
| 32 | asm volatile("mrs %[ctr_el0], ctr_el0\n\t" : [ctr_el0] "=r"(ctr_el0)); \ | ||
| 33 | size_t cacheline_size = EXTRACT_DMINLINE(ctr_el0); \ | ||
| 34 | uintptr_t va_start = reinterpret_cast<uintptr_t>(start); \ | ||
| 35 | uintptr_t va_end = va_start + size; \ | ||
| 36 | for (uintptr_t va = va_start; va < va_end; va += cacheline_size) { \ | ||
| 37 | asm volatile("dc " #op_name ", %[va]\n\t" : : [va] "r"(va) : "memory"); \ | ||
| 38 | } \ | ||
| 39 | } | ||
| 40 | |||
| 41 | #define DEFINE_DC_OP_DCZID(op_name, function_name) \ | ||
| 42 | void function_name(void* start, size_t size) { \ | ||
| 43 | size_t dczid_el0; \ | ||
| 44 | asm volatile("mrs %[dczid_el0], dczid_el0\n\t" : [dczid_el0] "=r"(dczid_el0)); \ | ||
| 45 | size_t cacheline_size = EXTRACT_BS(dczid_el0); \ | ||
| 46 | uintptr_t va_start = reinterpret_cast<uintptr_t>(start); \ | ||
| 47 | uintptr_t va_end = va_start + size; \ | ||
| 48 | for (uintptr_t va = va_start; va < va_end; va += cacheline_size) { \ | ||
| 49 | asm volatile("dc " #op_name ", %[va]\n\t" : : [va] "r"(va) : "memory"); \ | ||
| 50 | } \ | ||
| 51 | } | ||
| 52 | |||
| 53 | DEFINE_DC_OP(cvau, DataCacheLineCleanByVAToPoU); | ||
| 54 | DEFINE_DC_OP(civac, DataCacheLineCleanAndInvalidateByVAToPoC); | ||
| 55 | DEFINE_DC_OP(cvac, DataCacheLineCleanByVAToPoC); | ||
| 56 | DEFINE_DC_OP_DCZID(zva, DataCacheZeroByVA); | ||
| 57 | |||
| 58 | #endif | ||
| 59 | |||
| 60 | } // namespace Common | ||
diff --git a/src/common/cache_management.h b/src/common/cache_management.h new file mode 100644 index 000000000..e467b87e4 --- /dev/null +++ b/src/common/cache_management.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "stdlib.h" | ||
| 7 | |||
| 8 | namespace Common { | ||
| 9 | |||
| 10 | // Data cache instructions enabled at EL0 by SCTLR_EL1.UCI. | ||
| 11 | // VA = virtual address | ||
| 12 | // PoC = point of coherency | ||
| 13 | // PoU = point of unification | ||
| 14 | |||
| 15 | // dc cvau | ||
| 16 | void DataCacheLineCleanByVAToPoU(void* start, size_t size); | ||
| 17 | |||
| 18 | // dc civac | ||
| 19 | void DataCacheLineCleanAndInvalidateByVAToPoC(void* start, size_t size); | ||
| 20 | |||
| 21 | // dc cvac | ||
| 22 | void DataCacheLineCleanByVAToPoC(void* start, size_t size); | ||
| 23 | |||
| 24 | // dc zva | ||
| 25 | void DataCacheZeroByVA(void* start, size_t size); | ||
| 26 | |||
| 27 | } // namespace Common | ||
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index bda098511..7b363eb1e 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp | |||
| @@ -243,6 +243,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { | |||
| 243 | // If we somehow get an invalid type, abort. | 243 | // If we somehow get an invalid type, abort. |
| 244 | default: | 244 | default: |
| 245 | ASSERT_MSG(false, "Unknown slab type: {}", slab_types[i]); | 245 | ASSERT_MSG(false, "Unknown slab type: {}", slab_types[i]); |
| 246 | break; | ||
| 246 | } | 247 | } |
| 247 | 248 | ||
| 248 | // If we've hit the end of a gap, free it. | 249 | // If we've hit the end of a gap, free it. |
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 5387bf5fe..612fc76fa 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -2301,6 +2301,7 @@ Result KPageTable::SetProcessMemoryPermission(VAddr addr, size_t size, | |||
| 2301 | break; | 2301 | break; |
| 2302 | default: | 2302 | default: |
| 2303 | ASSERT(false); | 2303 | ASSERT(false); |
| 2304 | break; | ||
| 2304 | } | 2305 | } |
| 2305 | } | 2306 | } |
| 2306 | 2307 | ||
| @@ -2803,6 +2804,7 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_ | |||
| 2803 | break; | 2804 | break; |
| 2804 | default: | 2805 | default: |
| 2805 | ASSERT(false); | 2806 | ASSERT(false); |
| 2807 | break; | ||
| 2806 | } | 2808 | } |
| 2807 | 2809 | ||
| 2808 | addr += size; | 2810 | addr += size; |
| @@ -2838,6 +2840,7 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm, | |||
| 2838 | break; | 2840 | break; |
| 2839 | default: | 2841 | default: |
| 2840 | ASSERT(false); | 2842 | ASSERT(false); |
| 2843 | break; | ||
| 2841 | } | 2844 | } |
| 2842 | R_SUCCEED(); | 2845 | R_SUCCEED(); |
| 2843 | } | 2846 | } |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 55a9c5fae..d1dc62401 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -395,6 +395,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: | |||
| 395 | 395 | ||
| 396 | default: | 396 | default: |
| 397 | ASSERT(false); | 397 | ASSERT(false); |
| 398 | break; | ||
| 398 | } | 399 | } |
| 399 | 400 | ||
| 400 | // Create TLS region | 401 | // Create TLS region |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9962ad171..e520cab47 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -2701,14 +2701,24 @@ static Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr ou | |||
| 2701 | return ResultSuccess; | 2701 | return ResultSuccess; |
| 2702 | } | 2702 | } |
| 2703 | 2703 | ||
| 2704 | static Result FlushProcessDataCache32([[maybe_unused]] Core::System& system, | 2704 | static Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 address, |
| 2705 | [[maybe_unused]] Handle handle, [[maybe_unused]] u32 address, | 2705 | u64 size) { |
| 2706 | [[maybe_unused]] u32 size) { | 2706 | // Validate address/size. |
| 2707 | // Note(Blinkhawk): For emulation purposes of the data cache this is mostly a no-op, | 2707 | R_UNLESS(size > 0, ResultInvalidSize); |
| 2708 | // as all emulation is done in the same cache level in host architecture, thus data cache | 2708 | R_UNLESS(address == static_cast<uintptr_t>(address), ResultInvalidCurrentMemory); |
| 2709 | // does not need flushing. | 2709 | R_UNLESS(size == static_cast<size_t>(size), ResultInvalidCurrentMemory); |
| 2710 | LOG_DEBUG(Kernel_SVC, "called"); | 2710 | |
| 2711 | return ResultSuccess; | 2711 | // Get the process from its handle. |
| 2712 | KScopedAutoObject process = | ||
| 2713 | system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle); | ||
| 2714 | R_UNLESS(process.IsNotNull(), ResultInvalidHandle); | ||
| 2715 | |||
| 2716 | // Verify the region is within range. | ||
| 2717 | auto& page_table = process->PageTable(); | ||
| 2718 | R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); | ||
| 2719 | |||
| 2720 | // Perform the operation. | ||
| 2721 | R_RETURN(system.Memory().FlushDataCache(*process, address, size)); | ||
| 2712 | } | 2722 | } |
| 2713 | 2723 | ||
| 2714 | namespace { | 2724 | namespace { |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 272c54cf7..3730937fe 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -722,4 +722,12 @@ void SvcWrap32(Core::System& system) { | |||
| 722 | FuncReturn(system, retval); | 722 | FuncReturn(system, retval); |
| 723 | } | 723 | } |
| 724 | 724 | ||
| 725 | // Used by Invalidate/Store/FlushProcessDataCache32 | ||
| 726 | template <Result func(Core::System&, Handle, u64, u64)> | ||
| 727 | void SvcWrap32(Core::System& system) { | ||
| 728 | const u64 address = (Param(system, 3) << 32) | Param(system, 2); | ||
| 729 | const u64 size = (Param(system, 4) << 32) | Param(system, 1); | ||
| 730 | FuncReturn32(system, func(system, Param32(system, 0), address, size).raw); | ||
| 731 | } | ||
| 732 | |||
| 725 | } // namespace Kernel | 733 | } // namespace Kernel |
diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp index fcf34bf7e..bae0d99a6 100644 --- a/src/core/hle/service/am/applets/applet_error.cpp +++ b/src/core/hle/service/am/applets/applet_error.cpp | |||
| @@ -144,6 +144,7 @@ void Error::Initialize() { | |||
| 144 | break; | 144 | break; |
| 145 | default: | 145 | default: |
| 146 | UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode); | 146 | UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode); |
| 147 | break; | ||
| 147 | } | 148 | } |
| 148 | } | 149 | } |
| 149 | 150 | ||
diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp index c34ef08b3..e50acdaf6 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.cpp +++ b/src/core/hle/service/am/applets/applet_general_backend.cpp | |||
| @@ -129,6 +129,7 @@ void Auth::Execute() { | |||
| 129 | } | 129 | } |
| 130 | default: | 130 | default: |
| 131 | unimplemented_log(); | 131 | unimplemented_log(); |
| 132 | break; | ||
| 132 | } | 133 | } |
| 133 | } | 134 | } |
| 134 | 135 | ||
| @@ -192,6 +193,7 @@ void PhotoViewer::Execute() { | |||
| 192 | break; | 193 | break; |
| 193 | default: | 194 | default: |
| 194 | UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", mode); | 195 | UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", mode); |
| 196 | break; | ||
| 195 | } | 197 | } |
| 196 | } | 198 | } |
| 197 | 199 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index ced57dfe6..b97813fbc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -300,11 +300,10 @@ Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) { | |||
| 300 | return error_notifier_event; | 300 | return error_notifier_event; |
| 301 | case 2: | 301 | case 2: |
| 302 | return unknown_event; | 302 | return unknown_event; |
| 303 | default: { | 303 | default: |
| 304 | LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); | 304 | LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); |
| 305 | return nullptr; | ||
| 305 | } | 306 | } |
| 306 | } | ||
| 307 | return nullptr; | ||
| 308 | } | 307 | } |
| 309 | 308 | ||
| 310 | } // namespace Service::Nvidia::Devices | 309 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 45a759fa8..e123564c6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -364,11 +364,10 @@ Kernel::KEvent* nvhost_gpu::QueryEvent(u32 event_id) { | |||
| 364 | return sm_exception_breakpoint_pause_report_event; | 364 | return sm_exception_breakpoint_pause_report_event; |
| 365 | case 3: | 365 | case 3: |
| 366 | return error_notifier_event; | 366 | return error_notifier_event; |
| 367 | default: { | 367 | default: |
| 368 | LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); | 368 | LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); |
| 369 | return nullptr; | ||
| 369 | } | 370 | } |
| 370 | } | ||
| 371 | return nullptr; | ||
| 372 | } | 371 | } |
| 373 | 372 | ||
| 374 | } // namespace Service::Nvidia::Devices | 373 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.cpp b/src/core/hle/service/nvflinger/buffer_queue_core.cpp index ea4a14ea4..3d1338e66 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_core.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_core.cpp | |||
| @@ -23,15 +23,17 @@ void BufferQueueCore::NotifyShutdown() { | |||
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void BufferQueueCore::SignalDequeueCondition() { | 25 | void BufferQueueCore::SignalDequeueCondition() { |
| 26 | dequeue_possible.store(true); | ||
| 26 | dequeue_condition.notify_all(); | 27 | dequeue_condition.notify_all(); |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | bool BufferQueueCore::WaitForDequeueCondition() { | 30 | bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk) { |
| 30 | if (is_shutting_down) { | 31 | if (is_shutting_down) { |
| 31 | return false; | 32 | return false; |
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | dequeue_condition.wait(mutex); | 35 | dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); }); |
| 36 | dequeue_possible.store(false); | ||
| 35 | 37 | ||
| 36 | return true; | 38 | return true; |
| 37 | } | 39 | } |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.h b/src/core/hle/service/nvflinger/buffer_queue_core.h index ca6baefaf..85b3bc4c1 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_core.h +++ b/src/core/hle/service/nvflinger/buffer_queue_core.h | |||
| @@ -38,7 +38,7 @@ public: | |||
| 38 | 38 | ||
| 39 | private: | 39 | private: |
| 40 | void SignalDequeueCondition(); | 40 | void SignalDequeueCondition(); |
| 41 | bool WaitForDequeueCondition(); | 41 | bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk); |
| 42 | 42 | ||
| 43 | s32 GetMinUndequeuedBufferCountLocked(bool async) const; | 43 | s32 GetMinUndequeuedBufferCountLocked(bool async) const; |
| 44 | s32 GetMinMaxBufferCountLocked(bool async) const; | 44 | s32 GetMinMaxBufferCountLocked(bool async) const; |
| @@ -60,7 +60,8 @@ private: | |||
| 60 | BufferQueueDefs::SlotsType slots{}; | 60 | BufferQueueDefs::SlotsType slots{}; |
| 61 | std::vector<BufferItem> queue; | 61 | std::vector<BufferItem> queue; |
| 62 | s32 override_max_buffer_count{}; | 62 | s32 override_max_buffer_count{}; |
| 63 | mutable std::condition_variable_any dequeue_condition; | 63 | std::condition_variable dequeue_condition; |
| 64 | std::atomic<bool> dequeue_possible{}; | ||
| 64 | const bool use_async_buffer{}; // This is always disabled on HOS | 65 | const bool use_async_buffer{}; // This is always disabled on HOS |
| 65 | bool dequeue_buffer_cannot_block{}; | 66 | bool dequeue_buffer_cannot_block{}; |
| 66 | PixelFormat default_buffer_format{PixelFormat::Rgba8888}; | 67 | PixelFormat default_buffer_format{PixelFormat::Rgba8888}; |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp index 41ba44b21..e601b5da1 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp | |||
| @@ -121,8 +121,8 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) { | |||
| 121 | return Status::NoError; | 121 | return Status::NoError; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, | 124 | Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags, |
| 125 | Status* return_flags) const { | 125 | std::unique_lock<std::mutex>& lk) const { |
| 126 | bool try_again = true; | 126 | bool try_again = true; |
| 127 | 127 | ||
| 128 | while (try_again) { | 128 | while (try_again) { |
| @@ -214,7 +214,7 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, | |||
| 214 | return Status::WouldBlock; | 214 | return Status::WouldBlock; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | if (!core->WaitForDequeueCondition()) { | 217 | if (!core->WaitForDequeueCondition(lk)) { |
| 218 | // We are no longer running | 218 | // We are no longer running |
| 219 | return Status::NoError; | 219 | return Status::NoError; |
| 220 | } | 220 | } |
| @@ -237,7 +237,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool | |||
| 237 | Status return_flags = Status::NoError; | 237 | Status return_flags = Status::NoError; |
| 238 | bool attached_by_consumer = false; | 238 | bool attached_by_consumer = false; |
| 239 | { | 239 | { |
| 240 | std::scoped_lock lock{core->mutex}; | 240 | std::unique_lock lock{core->mutex}; |
| 241 | core->WaitWhileAllocatingLocked(); | 241 | core->WaitWhileAllocatingLocked(); |
| 242 | 242 | ||
| 243 | if (format == PixelFormat::NoFormat) { | 243 | if (format == PixelFormat::NoFormat) { |
| @@ -248,7 +248,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool | |||
| 248 | usage |= core->consumer_usage_bit; | 248 | usage |= core->consumer_usage_bit; |
| 249 | 249 | ||
| 250 | s32 found{}; | 250 | s32 found{}; |
| 251 | Status status = WaitForFreeSlotThenRelock(async, &found, &return_flags); | 251 | Status status = WaitForFreeSlotThenRelock(async, &found, &return_flags, lock); |
| 252 | if (status != Status::NoError) { | 252 | if (status != Status::NoError) { |
| 253 | return status; | 253 | return status; |
| 254 | } | 254 | } |
| @@ -400,13 +400,13 @@ Status BufferQueueProducer::AttachBuffer(s32* out_slot, | |||
| 400 | return Status::BadValue; | 400 | return Status::BadValue; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | std::scoped_lock lock{core->mutex}; | 403 | std::unique_lock lock{core->mutex}; |
| 404 | core->WaitWhileAllocatingLocked(); | 404 | core->WaitWhileAllocatingLocked(); |
| 405 | 405 | ||
| 406 | Status return_flags = Status::NoError; | 406 | Status return_flags = Status::NoError; |
| 407 | s32 found{}; | 407 | s32 found{}; |
| 408 | 408 | ||
| 409 | const auto status = WaitForFreeSlotThenRelock(false, &found, &return_flags); | 409 | const auto status = WaitForFreeSlotThenRelock(false, &found, &return_flags, lock); |
| 410 | if (status != Status::NoError) { | 410 | if (status != Status::NoError) { |
| 411 | return status; | 411 | return status; |
| 412 | } | 412 | } |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.h b/src/core/hle/service/nvflinger/buffer_queue_producer.h index 7526bf8ec..1d380480f 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.h | |||
| @@ -70,7 +70,8 @@ public: | |||
| 70 | private: | 70 | private: |
| 71 | BufferQueueProducer(const BufferQueueProducer&) = delete; | 71 | BufferQueueProducer(const BufferQueueProducer&) = delete; |
| 72 | 72 | ||
| 73 | Status WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags) const; | 73 | Status WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags, |
| 74 | std::unique_lock<std::mutex>& lk) const; | ||
| 74 | 75 | ||
| 75 | Kernel::KEvent* buffer_wait_event{}; | 76 | Kernel::KEvent* buffer_wait_event{}; |
| 76 | Service::KernelHelpers::ServiceContext& service_context; | 77 | Service::KernelHelpers::ServiceContext& service_context; |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 5ab41c0c4..0de67f1e1 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -228,6 +228,7 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, | |||
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType()); | 230 | UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType()); |
| 231 | break; | ||
| 231 | } | 232 | } |
| 232 | 233 | ||
| 233 | // If emulation was shutdown, we are closing service threads, do not write the response back to | 234 | // If emulation was shutdown, we are closing service threads, do not write the response back to |
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index 2aa675df9..f9ada7c93 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp | |||
| @@ -280,6 +280,7 @@ static constexpr int TransitionTime(int year, Rule rule, int offset) { | |||
| 280 | } | 280 | } |
| 281 | default: | 281 | default: |
| 282 | ASSERT(false); | 282 | ASSERT(false); |
| 283 | break; | ||
| 283 | } | 284 | } |
| 284 | return value + rule.transition_time + offset; | 285 | return value + rule.transition_time + offset; |
| 285 | } | 286 | } |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 3ca80c8ff..3141122f1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/atomic_ops.h" | 8 | #include "common/atomic_ops.h" |
| 9 | #include "common/cache_management.h" | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 11 | #include "common/page_table.h" | 12 | #include "common/page_table.h" |
| @@ -329,6 +330,55 @@ struct Memory::Impl { | |||
| 329 | }); | 330 | }); |
| 330 | } | 331 | } |
| 331 | 332 | ||
| 333 | template <typename Callback> | ||
| 334 | Result PerformCacheOperation(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size, | ||
| 335 | Callback&& cb) { | ||
| 336 | class InvalidMemoryException : public std::exception {}; | ||
| 337 | |||
| 338 | try { | ||
| 339 | WalkBlock( | ||
| 340 | process, dest_addr, size, | ||
| 341 | [&](const std::size_t block_size, const VAddr current_vaddr) { | ||
| 342 | LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", current_vaddr); | ||
| 343 | throw InvalidMemoryException(); | ||
| 344 | }, | ||
| 345 | [&](const std::size_t block_size, u8* const host_ptr) { cb(block_size, host_ptr); }, | ||
| 346 | [&](const VAddr current_vaddr, const std::size_t block_size, u8* const host_ptr) { | ||
| 347 | system.GPU().FlushRegion(current_vaddr, block_size); | ||
| 348 | cb(block_size, host_ptr); | ||
| 349 | }, | ||
| 350 | [](const std::size_t block_size) {}); | ||
| 351 | } catch (InvalidMemoryException&) { | ||
| 352 | return Kernel::ResultInvalidCurrentMemory; | ||
| 353 | } | ||
| 354 | |||
| 355 | return ResultSuccess; | ||
| 356 | } | ||
| 357 | |||
| 358 | Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { | ||
| 359 | auto perform = [&](const std::size_t block_size, u8* const host_ptr) { | ||
| 360 | // Do nothing; this operation (dc ivac) cannot be supported | ||
| 361 | // from EL0 | ||
| 362 | }; | ||
| 363 | return PerformCacheOperation(process, dest_addr, size, perform); | ||
| 364 | } | ||
| 365 | |||
| 366 | Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { | ||
| 367 | auto perform = [&](const std::size_t block_size, u8* const host_ptr) { | ||
| 368 | // dc cvac: Store to point of coherency | ||
| 369 | Common::DataCacheLineCleanByVAToPoC(host_ptr, block_size); | ||
| 370 | }; | ||
| 371 | return PerformCacheOperation(process, dest_addr, size, perform); | ||
| 372 | } | ||
| 373 | |||
| 374 | Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { | ||
| 375 | auto perform = [&](const std::size_t block_size, u8* const host_ptr) { | ||
| 376 | // dc civac: Store to point of coherency, and invalidate from cache | ||
| 377 | Common::DataCacheLineCleanAndInvalidateByVAToPoC(host_ptr, block_size); | ||
| 378 | }; | ||
| 379 | return PerformCacheOperation(process, dest_addr, size, perform); | ||
| 380 | } | ||
| 381 | |||
| 332 | void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { | 382 | void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { |
| 333 | if (vaddr == 0) { | 383 | if (vaddr == 0) { |
| 334 | return; | 384 | return; |
| @@ -786,6 +836,21 @@ void Memory::ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, const s | |||
| 786 | impl->ZeroBlock(process, dest_addr, size); | 836 | impl->ZeroBlock(process, dest_addr, size); |
| 787 | } | 837 | } |
| 788 | 838 | ||
| 839 | Result Memory::InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, | ||
| 840 | const std::size_t size) { | ||
| 841 | return impl->InvalidateDataCache(process, dest_addr, size); | ||
| 842 | } | ||
| 843 | |||
| 844 | Result Memory::StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, | ||
| 845 | const std::size_t size) { | ||
| 846 | return impl->StoreDataCache(process, dest_addr, size); | ||
| 847 | } | ||
| 848 | |||
| 849 | Result Memory::FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, | ||
| 850 | const std::size_t size) { | ||
| 851 | return impl->FlushDataCache(process, dest_addr, size); | ||
| 852 | } | ||
| 853 | |||
| 789 | void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { | 854 | void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { |
| 790 | impl->RasterizerMarkRegionCached(vaddr, size, cached); | 855 | impl->RasterizerMarkRegionCached(vaddr, size, cached); |
| 791 | } | 856 | } |
diff --git a/src/core/memory.h b/src/core/memory.h index 81eac448b..31fe699d8 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/hle/result.h" | ||
| 10 | 11 | ||
| 11 | namespace Common { | 12 | namespace Common { |
| 12 | struct PageTable; | 13 | struct PageTable; |
| @@ -450,6 +451,39 @@ public: | |||
| 450 | void ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); | 451 | void ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); |
| 451 | 452 | ||
| 452 | /** | 453 | /** |
| 454 | * Invalidates a range of bytes within the current process' address space at the specified | ||
| 455 | * virtual address. | ||
| 456 | * | ||
| 457 | * @param process The process that will have data invalidated within its address space. | ||
| 458 | * @param dest_addr The destination virtual address to invalidate the data from. | ||
| 459 | * @param size The size of the range to invalidate, in bytes. | ||
| 460 | * | ||
| 461 | */ | ||
| 462 | Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); | ||
| 463 | |||
| 464 | /** | ||
| 465 | * Stores a range of bytes within the current process' address space at the specified | ||
| 466 | * virtual address. | ||
| 467 | * | ||
| 468 | * @param process The process that will have data stored within its address space. | ||
| 469 | * @param dest_addr The destination virtual address to store the data from. | ||
| 470 | * @param size The size of the range to store, in bytes. | ||
| 471 | * | ||
| 472 | */ | ||
| 473 | Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); | ||
| 474 | |||
| 475 | /** | ||
| 476 | * Flushes a range of bytes within the current process' address space at the specified | ||
| 477 | * virtual address. | ||
| 478 | * | ||
| 479 | * @param process The process that will have data flushed within its address space. | ||
| 480 | * @param dest_addr The destination virtual address to flush the data from. | ||
| 481 | * @param size The size of the range to flush, in bytes. | ||
| 482 | * | ||
| 483 | */ | ||
| 484 | Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); | ||
| 485 | |||
| 486 | /** | ||
| 453 | * Marks each page within the specified address range as cached or uncached. | 487 | * Marks each page within the specified address range as cached or uncached. |
| 454 | * | 488 | * |
| 455 | * @param vaddr The virtual address indicating the start of the address range. | 489 | * @param vaddr The virtual address indicating the start of the address range. |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp index 3b0176bf6..0cb1e193e 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp | |||
| @@ -320,6 +320,7 @@ void SetupOptions(const IR::Program& program, const Profile& profile, | |||
| 320 | } | 320 | } |
| 321 | if (stage == Stage::Fragment) { | 321 | if (stage == Stage::Fragment) { |
| 322 | header += "OPTION ARB_draw_buffers;"; | 322 | header += "OPTION ARB_draw_buffers;"; |
| 323 | header += "OPTION ARB_fragment_layer_viewport;"; | ||
| 323 | } | 324 | } |
| 324 | } | 325 | } |
| 325 | 326 | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp index d6562c842..f0bd84ab2 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp | |||
| @@ -104,6 +104,9 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, Scal | |||
| 104 | case IR::Attribute::PrimitiveId: | 104 | case IR::Attribute::PrimitiveId: |
| 105 | ctx.Add("MOV.F {}.x,primitive.id;", inst); | 105 | ctx.Add("MOV.F {}.x,primitive.id;", inst); |
| 106 | break; | 106 | break; |
| 107 | case IR::Attribute::Layer: | ||
| 108 | ctx.Add("MOV.F {}.x,fragment.layer;", inst); | ||
| 109 | break; | ||
| 107 | case IR::Attribute::PositionX: | 110 | case IR::Attribute::PositionX: |
| 108 | case IR::Attribute::PositionY: | 111 | case IR::Attribute::PositionY: |
| 109 | case IR::Attribute::PositionZ: | 112 | case IR::Attribute::PositionZ: |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index c1671c37b..39579cf5d 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp | |||
| @@ -205,6 +205,9 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, | |||
| 205 | case IR::Attribute::PrimitiveId: | 205 | case IR::Attribute::PrimitiveId: |
| 206 | ctx.AddF32("{}=itof(gl_PrimitiveID);", inst); | 206 | ctx.AddF32("{}=itof(gl_PrimitiveID);", inst); |
| 207 | break; | 207 | break; |
| 208 | case IR::Attribute::Layer: | ||
| 209 | ctx.AddF32("{}=itof(gl_Layer);", inst); | ||
| 210 | break; | ||
| 208 | case IR::Attribute::PositionX: | 211 | case IR::Attribute::PositionX: |
| 209 | case IR::Attribute::PositionY: | 212 | case IR::Attribute::PositionY: |
| 210 | case IR::Attribute::PositionZ: | 213 | case IR::Attribute::PositionZ: |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 5b3b5d1f3..01f6ec9b5 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -315,6 +315,8 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) { | |||
| 315 | switch (attr) { | 315 | switch (attr) { |
| 316 | case IR::Attribute::PrimitiveId: | 316 | case IR::Attribute::PrimitiveId: |
| 317 | return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.primitive_id)); | 317 | return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.primitive_id)); |
| 318 | case IR::Attribute::Layer: | ||
| 319 | return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.layer)); | ||
| 318 | case IR::Attribute::PositionX: | 320 | case IR::Attribute::PositionX: |
| 319 | case IR::Attribute::PositionY: | 321 | case IR::Attribute::PositionY: |
| 320 | case IR::Attribute::PositionZ: | 322 | case IR::Attribute::PositionZ: |
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 0bfc2dd89..dd96b7803 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | |||
| @@ -1359,6 +1359,10 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1359 | if (loads[IR::Attribute::PrimitiveId]) { | 1359 | if (loads[IR::Attribute::PrimitiveId]) { |
| 1360 | primitive_id = DefineInput(*this, U32[1], false, spv::BuiltIn::PrimitiveId); | 1360 | primitive_id = DefineInput(*this, U32[1], false, spv::BuiltIn::PrimitiveId); |
| 1361 | } | 1361 | } |
| 1362 | if (loads[IR::Attribute::Layer]) { | ||
| 1363 | AddCapability(spv::Capability::Geometry); | ||
| 1364 | layer = DefineInput(*this, U32[1], false, spv::BuiltIn::Layer); | ||
| 1365 | } | ||
| 1362 | if (loads.AnyComponent(IR::Attribute::PositionX)) { | 1366 | if (loads.AnyComponent(IR::Attribute::PositionX)) { |
| 1363 | const bool is_fragment{stage != Stage::Fragment}; | 1367 | const bool is_fragment{stage != Stage::Fragment}; |
| 1364 | const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::Position : spv::BuiltIn::FragCoord}; | 1368 | const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::Position : spv::BuiltIn::FragCoord}; |
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 54523a4b2..1bf6ca2dd 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -314,6 +314,7 @@ void MaxwellDMA::ReleaseSemaphore() { | |||
| 314 | } | 314 | } |
| 315 | default: | 315 | default: |
| 316 | ASSERT_MSG(false, "Unknown semaphore type: {}", static_cast<u32>(type.Value())); | 316 | ASSERT_MSG(false, "Unknown semaphore type: {}", static_cast<u32>(type.Value())); |
| 317 | break; | ||
| 317 | } | 318 | } |
| 318 | } | 319 | } |
| 319 | 320 | ||
diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp index 3977bb0fb..4d2278811 100644 --- a/src/video_core/engines/puller.cpp +++ b/src/video_core/engines/puller.cpp | |||
| @@ -50,6 +50,7 @@ void Puller::ProcessBindMethod(const MethodCall& method_call) { | |||
| 50 | break; | 50 | break; |
| 51 | default: | 51 | default: |
| 52 | UNIMPLEMENTED_MSG("Unimplemented engine {:04X}", engine_id); | 52 | UNIMPLEMENTED_MSG("Unimplemented engine {:04X}", engine_id); |
| 53 | break; | ||
| 53 | } | 54 | } |
| 54 | } | 55 | } |
| 55 | 56 | ||
| @@ -65,6 +66,7 @@ void Puller::ProcessFenceActionMethod() { | |||
| 65 | break; | 66 | break; |
| 66 | default: | 67 | default: |
| 67 | UNIMPLEMENTED_MSG("Unimplemented operation {}", regs.fence_action.op.Value()); | 68 | UNIMPLEMENTED_MSG("Unimplemented operation {}", regs.fence_action.op.Value()); |
| 69 | break; | ||
| 68 | } | 70 | } |
| 69 | } | 71 | } |
| 70 | 72 | ||
| @@ -228,6 +230,7 @@ void Puller::CallEngineMethod(const MethodCall& method_call) { | |||
| 228 | break; | 230 | break; |
| 229 | default: | 231 | default: |
| 230 | UNIMPLEMENTED_MSG("Unimplemented engine"); | 232 | UNIMPLEMENTED_MSG("Unimplemented engine"); |
| 233 | break; | ||
| 231 | } | 234 | } |
| 232 | } | 235 | } |
| 233 | 236 | ||
| @@ -254,6 +257,7 @@ void Puller::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_s | |||
| 254 | break; | 257 | break; |
| 255 | default: | 258 | default: |
| 256 | UNIMPLEMENTED_MSG("Unimplemented engine"); | 259 | UNIMPLEMENTED_MSG("Unimplemented engine"); |
| 260 | break; | ||
| 257 | } | 261 | } |
| 258 | } | 262 | } |
| 259 | 263 | ||
diff --git a/src/video_core/macro/macro_interpreter.cpp b/src/video_core/macro/macro_interpreter.cpp index c0d32c112..0d63495a9 100644 --- a/src/video_core/macro/macro_interpreter.cpp +++ b/src/video_core/macro/macro_interpreter.cpp | |||
| @@ -201,6 +201,7 @@ bool MacroInterpreterImpl::Step(bool is_delay_slot) { | |||
| 201 | } | 201 | } |
| 202 | default: | 202 | default: |
| 203 | UNIMPLEMENTED_MSG("Unimplemented macro operation {}", opcode.operation.Value()); | 203 | UNIMPLEMENTED_MSG("Unimplemented macro operation {}", opcode.operation.Value()); |
| 204 | break; | ||
| 204 | } | 205 | } |
| 205 | 206 | ||
| 206 | // An instruction with the Exit flag will not actually | 207 | // An instruction with the Exit flag will not actually |
| @@ -297,6 +298,7 @@ void MacroInterpreterImpl::ProcessResult(Macro::ResultOperation operation, u32 r | |||
| 297 | break; | 298 | break; |
| 298 | default: | 299 | default: |
| 299 | UNIMPLEMENTED_MSG("Unimplemented result operation {}", operation); | 300 | UNIMPLEMENTED_MSG("Unimplemented result operation {}", operation); |
| 301 | break; | ||
| 300 | } | 302 | } |
| 301 | } | 303 | } |
| 302 | 304 | ||
diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp index 25c1ce798..7347cbd88 100644 --- a/src/video_core/macro/macro_jit_x64.cpp +++ b/src/video_core/macro/macro_jit_x64.cpp | |||
| @@ -652,6 +652,7 @@ void MacroJITx64Impl::Compile_ProcessResult(Macro::ResultOperation operation, u3 | |||
| 652 | break; | 652 | break; |
| 653 | default: | 653 | default: |
| 654 | UNIMPLEMENTED_MSG("Unimplemented macro operation {}", operation); | 654 | UNIMPLEMENTED_MSG("Unimplemented macro operation {}", operation); |
| 655 | break; | ||
| 655 | } | 656 | } |
| 656 | } | 657 | } |
| 657 | 658 | ||
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 99cd11d1e..9f7ce7414 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -891,6 +891,7 @@ void Image::CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t b | |||
| 891 | break; | 891 | break; |
| 892 | default: | 892 | default: |
| 893 | ASSERT(false); | 893 | ASSERT(false); |
| 894 | break; | ||
| 894 | } | 895 | } |
| 895 | } | 896 | } |
| 896 | 897 | ||
| @@ -927,6 +928,7 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b | |||
| 927 | break; | 928 | break; |
| 928 | default: | 929 | default: |
| 929 | ASSERT(false); | 930 | ASSERT(false); |
| 931 | break; | ||
| 930 | } | 932 | } |
| 931 | // Compressed formats don't have a pixel format or type | 933 | // Compressed formats don't have a pixel format or type |
| 932 | const bool is_compressed = gl_format == GL_NONE; | 934 | const bool is_compressed = gl_format == GL_NONE; |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 8bd5eba7e..f29462f7c 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -340,6 +340,7 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | |||
| 340 | texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; | 340 | texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; |
| 341 | // UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}", | 341 | // UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}", |
| 342 | // static_cast<u32>(framebuffer.pixel_format)); | 342 | // static_cast<u32>(framebuffer.pixel_format)); |
| 343 | break; | ||
| 343 | } | 344 | } |
| 344 | 345 | ||
| 345 | texture.resource.Release(); | 346 | texture.resource.Release(); |
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 7934f2a51..4a7b633b7 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp | |||
| @@ -221,6 +221,7 @@ void Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_s | |||
| 221 | [[fallthrough]]; | 221 | [[fallthrough]]; |
| 222 | default: | 222 | default: |
| 223 | vk::Check(result); | 223 | vk::Check(result); |
| 224 | break; | ||
| 224 | } | 225 | } |
| 225 | }); | 226 | }); |
| 226 | chunk->MarkSubmit(); | 227 | chunk->MarkSubmit(); |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 853b80d8a..a65bbeb1c 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -108,6 +108,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 108 | break; | 108 | break; |
| 109 | default: | 109 | default: |
| 110 | ASSERT_MSG(false, "Invalid surface type"); | 110 | ASSERT_MSG(false, "Invalid surface type"); |
| 111 | break; | ||
| 111 | } | 112 | } |
| 112 | } | 113 | } |
| 113 | if (info.storage) { | 114 | if (info.storage) { |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index fd1a4b987..59120cd09 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -170,6 +170,7 @@ void Swizzle(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixe | |||
| 170 | #undef BPP_CASE | 170 | #undef BPP_CASE |
| 171 | default: | 171 | default: |
| 172 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); | 172 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); |
| 173 | break; | ||
| 173 | } | 174 | } |
| 174 | } | 175 | } |
| 175 | 176 | ||
| @@ -217,6 +218,7 @@ void SwizzleSubrect(std::span<u8> output, std::span<const u8> input, u32 bytes_p | |||
| 217 | #undef BPP_CASE | 218 | #undef BPP_CASE |
| 218 | default: | 219 | default: |
| 219 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); | 220 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); |
| 221 | break; | ||
| 220 | } | 222 | } |
| 221 | } | 223 | } |
| 222 | 224 | ||
| @@ -240,6 +242,7 @@ void UnswizzleSubrect(std::span<u8> output, std::span<const u8> input, u32 bytes | |||
| 240 | #undef BPP_CASE | 242 | #undef BPP_CASE |
| 241 | default: | 243 | default: |
| 242 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); | 244 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); |
| 245 | break; | ||
| 243 | } | 246 | } |
| 244 | } | 247 | } |
| 245 | 248 | ||
diff --git a/src/yuzu/compatdb.cpp b/src/yuzu/compatdb.cpp index b03e71248..05f49c0d2 100644 --- a/src/yuzu/compatdb.cpp +++ b/src/yuzu/compatdb.cpp | |||
| @@ -126,6 +126,7 @@ void CompatDB::Submit() { | |||
| 126 | break; | 126 | break; |
| 127 | default: | 127 | default: |
| 128 | LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); | 128 | LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); |
| 129 | break; | ||
| 129 | } | 130 | } |
| 130 | } | 131 | } |
| 131 | 132 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 72498f52a..7ee2302cc 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1956,6 +1956,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 1956 | } | 1956 | } |
| 1957 | default: | 1957 | default: |
| 1958 | UNIMPLEMENTED(); | 1958 | UNIMPLEMENTED(); |
| 1959 | break; | ||
| 1959 | } | 1960 | } |
| 1960 | 1961 | ||
| 1961 | const QString qpath = QString::fromStdString(Common::FS::PathToUTF8String(path)); | 1962 | const QString qpath = QString::fromStdString(Common::FS::PathToUTF8String(path)); |
| @@ -3199,6 +3200,7 @@ void GMainWindow::OnToggleGpuAccuracy() { | |||
| 3199 | case Settings::GPUAccuracy::Extreme: | 3200 | case Settings::GPUAccuracy::Extreme: |
| 3200 | default: { | 3201 | default: { |
| 3201 | Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::High); | 3202 | Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::High); |
| 3203 | break; | ||
| 3202 | } | 3204 | } |
| 3203 | } | 3205 | } |
| 3204 | 3206 | ||
| @@ -3531,6 +3533,7 @@ void GMainWindow::UpdateGPUAccuracyButton() { | |||
| 3531 | default: { | 3533 | default: { |
| 3532 | gpu_accuracy_button->setText(tr("GPU ERROR")); | 3534 | gpu_accuracy_button->setText(tr("GPU ERROR")); |
| 3533 | gpu_accuracy_button->setChecked(true); | 3535 | gpu_accuracy_button->setChecked(true); |
| 3536 | break; | ||
| 3534 | } | 3537 | } |
| 3535 | } | 3538 | } |
| 3536 | } | 3539 | } |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index 65455c86e..25948328c 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp | |||
| @@ -84,6 +84,7 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste | |||
| 84 | default: | 84 | default: |
| 85 | LOG_CRITICAL(Frontend, "Window manager subsystem not implemented"); | 85 | LOG_CRITICAL(Frontend, "Window manager subsystem not implemented"); |
| 86 | std::exit(EXIT_FAILURE); | 86 | std::exit(EXIT_FAILURE); |
| 87 | break; | ||
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | OnResize(); | 90 | OnResize(); |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index e16f79eb4..dfe5a30ea 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -351,6 +351,7 @@ int main(int argc, char** argv) { | |||
| 351 | "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", | 351 | "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", |
| 352 | loader_id, error_id, static_cast<Loader::ResultStatus>(error_id)); | 352 | loader_id, error_id, static_cast<Loader::ResultStatus>(error_id)); |
| 353 | } | 353 | } |
| 354 | break; | ||
| 354 | } | 355 | } |
| 355 | 356 | ||
| 356 | system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "SDL"); | 357 | system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "SDL"); |