diff options
Diffstat (limited to 'src')
42 files changed, 478 insertions, 339 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 919da4a53..790193b00 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -22,6 +22,11 @@ add_custom_command(OUTPUT scm_rev.cpp | |||
| 22 | -DTITLE_BAR_FORMAT_RUNNING=${TITLE_BAR_FORMAT_RUNNING} | 22 | -DTITLE_BAR_FORMAT_RUNNING=${TITLE_BAR_FORMAT_RUNNING} |
| 23 | -DBUILD_TAG=${BUILD_TAG} | 23 | -DBUILD_TAG=${BUILD_TAG} |
| 24 | -DBUILD_ID=${DISPLAY_VERSION} | 24 | -DBUILD_ID=${DISPLAY_VERSION} |
| 25 | -DGIT_REF_SPEC=${GIT_REF_SPEC} | ||
| 26 | -DGIT_REV=${GIT_REV} | ||
| 27 | -DGIT_DESC=${GIT_DESC} | ||
| 28 | -DGIT_BRANCH=${GIT_BRANCH} | ||
| 29 | -DBUILD_FULLNAME=${BUILD_FULLNAME} | ||
| 25 | -DGIT_EXECUTABLE=${GIT_EXECUTABLE} | 30 | -DGIT_EXECUTABLE=${GIT_EXECUTABLE} |
| 26 | -P ${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake | 31 | -P ${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake |
| 27 | DEPENDS | 32 | DEPENDS |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 49bed614a..698c4f912 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -265,8 +265,6 @@ add_library(core STATIC | |||
| 265 | hle/kernel/svc_wrap.h | 265 | hle/kernel/svc_wrap.h |
| 266 | hle/kernel/time_manager.cpp | 266 | hle/kernel/time_manager.cpp |
| 267 | hle/kernel/time_manager.h | 267 | hle/kernel/time_manager.h |
| 268 | hle/lock.cpp | ||
| 269 | hle/lock.h | ||
| 270 | hle/result.h | 268 | hle/result.h |
| 271 | hle/service/acc/acc.cpp | 269 | hle/service/acc/acc.cpp |
| 272 | hle/service/acc/acc.h | 270 | hle/service/acc/acc.h |
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp index 685ec080c..08f8af551 100644 --- a/src/core/hid/emulated_console.cpp +++ b/src/core/hid/emulated_console.cpp | |||
| @@ -161,7 +161,10 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) { | |||
| 161 | motion.rotation = emulated.GetGyroscope(); | 161 | motion.rotation = emulated.GetGyroscope(); |
| 162 | motion.orientation = emulated.GetOrientation(); | 162 | motion.orientation = emulated.GetOrientation(); |
| 163 | motion.quaternion = emulated.GetQuaternion(); | 163 | motion.quaternion = emulated.GetQuaternion(); |
| 164 | motion.gyro_bias = emulated.GetGyroBias(); | ||
| 164 | motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); | 165 | motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); |
| 166 | // Find what is this value | ||
| 167 | motion.verticalization_error = 0.0f; | ||
| 165 | 168 | ||
| 166 | TriggerOnChange(ConsoleTriggerType::Motion); | 169 | TriggerOnChange(ConsoleTriggerType::Motion); |
| 167 | } | 170 | } |
diff --git a/src/core/hid/emulated_console.h b/src/core/hid/emulated_console.h index 3afd284d5..707419102 100644 --- a/src/core/hid/emulated_console.h +++ b/src/core/hid/emulated_console.h | |||
| @@ -50,6 +50,8 @@ struct ConsoleMotion { | |||
| 50 | Common::Vec3f rotation{}; | 50 | Common::Vec3f rotation{}; |
| 51 | std::array<Common::Vec3f, 3> orientation{}; | 51 | std::array<Common::Vec3f, 3> orientation{}; |
| 52 | Common::Quaternion<f32> quaternion{}; | 52 | Common::Quaternion<f32> quaternion{}; |
| 53 | Common::Vec3f gyro_bias{}; | ||
| 54 | f32 verticalization_error{}; | ||
| 53 | bool is_at_rest{}; | 55 | bool is_at_rest{}; |
| 54 | }; | 56 | }; |
| 55 | 57 | ||
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 93372445b..ff9d7a7e3 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -843,23 +843,18 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v | |||
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | bool EmulatedController::TestVibration(std::size_t device_index) { | 845 | bool EmulatedController::TestVibration(std::size_t device_index) { |
| 846 | if (device_index >= output_devices.size()) { | 846 | static constexpr VibrationValue test_vibration = { |
| 847 | return false; | ||
| 848 | } | ||
| 849 | if (!output_devices[device_index]) { | ||
| 850 | return false; | ||
| 851 | } | ||
| 852 | |||
| 853 | // Send a slight vibration to test for rumble support | ||
| 854 | constexpr Common::Input::VibrationStatus status = { | ||
| 855 | .low_amplitude = 0.001f, | 847 | .low_amplitude = 0.001f, |
| 856 | .low_frequency = 160.0f, | 848 | .low_frequency = 160.0f, |
| 857 | .high_amplitude = 0.001f, | 849 | .high_amplitude = 0.001f, |
| 858 | .high_frequency = 320.0f, | 850 | .high_frequency = 320.0f, |
| 859 | .type = Common::Input::VibrationAmplificationType::Linear, | ||
| 860 | }; | 851 | }; |
| 861 | return output_devices[device_index]->SetVibration(status) == | 852 | |
| 862 | Common::Input::VibrationError::None; | 853 | // Send a slight vibration to test for rumble support |
| 854 | SetVibration(device_index, test_vibration); | ||
| 855 | |||
| 856 | // Stop any vibration and return the result | ||
| 857 | return SetVibration(device_index, DEFAULT_VIBRATION_VALUE); | ||
| 863 | } | 858 | } |
| 864 | 859 | ||
| 865 | void EmulatedController::SetLedPattern() { | 860 | void EmulatedController::SetLedPattern() { |
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h index 7c12f01fc..4eca68533 100644 --- a/src/core/hid/hid_types.h +++ b/src/core/hid/hid_types.h | |||
| @@ -496,6 +496,13 @@ struct VibrationValue { | |||
| 496 | }; | 496 | }; |
| 497 | static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size."); | 497 | static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size."); |
| 498 | 498 | ||
| 499 | constexpr VibrationValue DEFAULT_VIBRATION_VALUE{ | ||
| 500 | .low_amplitude = 0.0f, | ||
| 501 | .low_frequency = 160.0f, | ||
| 502 | .high_amplitude = 0.0f, | ||
| 503 | .high_frequency = 320.0f, | ||
| 504 | }; | ||
| 505 | |||
| 499 | // This is nn::hid::VibrationDeviceInfo | 506 | // This is nn::hid::VibrationDeviceInfo |
| 500 | struct VibrationDeviceInfo { | 507 | struct VibrationDeviceInfo { |
| 501 | VibrationDeviceType type{}; | 508 | VibrationDeviceType type{}; |
diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp index c25fea966..a23f192d7 100644 --- a/src/core/hid/motion_input.cpp +++ b/src/core/hid/motion_input.cpp | |||
| @@ -23,11 +23,11 @@ void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) { | |||
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) { | 25 | void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) { |
| 26 | gyro = gyroscope - gyro_drift; | 26 | gyro = gyroscope - gyro_bias; |
| 27 | 27 | ||
| 28 | // Auto adjust drift to minimize drift | 28 | // Auto adjust drift to minimize drift |
| 29 | if (!IsMoving(0.1f)) { | 29 | if (!IsMoving(0.1f)) { |
| 30 | gyro_drift = (gyro_drift * 0.9999f) + (gyroscope * 0.0001f); | 30 | gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | if (gyro.Length2() < gyro_threshold) { | 33 | if (gyro.Length2() < gyro_threshold) { |
| @@ -41,8 +41,8 @@ void MotionInput::SetQuaternion(const Common::Quaternion<f32>& quaternion) { | |||
| 41 | quat = quaternion; | 41 | quat = quaternion; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void MotionInput::SetGyroDrift(const Common::Vec3f& drift) { | 44 | void MotionInput::SetGyroBias(const Common::Vec3f& bias) { |
| 45 | gyro_drift = drift; | 45 | gyro_bias = bias; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | void MotionInput::SetGyroThreshold(f32 threshold) { | 48 | void MotionInput::SetGyroThreshold(f32 threshold) { |
| @@ -192,6 +192,10 @@ Common::Vec3f MotionInput::GetGyroscope() const { | |||
| 192 | return gyro; | 192 | return gyro; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | Common::Vec3f MotionInput::GetGyroBias() const { | ||
| 196 | return gyro_bias; | ||
| 197 | } | ||
| 198 | |||
| 195 | Common::Quaternion<f32> MotionInput::GetQuaternion() const { | 199 | Common::Quaternion<f32> MotionInput::GetQuaternion() const { |
| 196 | return quat; | 200 | return quat; |
| 197 | } | 201 | } |
diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h index 5b5b420bb..bca4520fa 100644 --- a/src/core/hid/motion_input.h +++ b/src/core/hid/motion_input.h | |||
| @@ -24,7 +24,7 @@ public: | |||
| 24 | void SetAcceleration(const Common::Vec3f& acceleration); | 24 | void SetAcceleration(const Common::Vec3f& acceleration); |
| 25 | void SetGyroscope(const Common::Vec3f& gyroscope); | 25 | void SetGyroscope(const Common::Vec3f& gyroscope); |
| 26 | void SetQuaternion(const Common::Quaternion<f32>& quaternion); | 26 | void SetQuaternion(const Common::Quaternion<f32>& quaternion); |
| 27 | void SetGyroDrift(const Common::Vec3f& drift); | 27 | void SetGyroBias(const Common::Vec3f& bias); |
| 28 | void SetGyroThreshold(f32 threshold); | 28 | void SetGyroThreshold(f32 threshold); |
| 29 | 29 | ||
| 30 | void EnableReset(bool reset); | 30 | void EnableReset(bool reset); |
| @@ -36,6 +36,7 @@ public: | |||
| 36 | [[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const; | 36 | [[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const; |
| 37 | [[nodiscard]] Common::Vec3f GetAcceleration() const; | 37 | [[nodiscard]] Common::Vec3f GetAcceleration() const; |
| 38 | [[nodiscard]] Common::Vec3f GetGyroscope() const; | 38 | [[nodiscard]] Common::Vec3f GetGyroscope() const; |
| 39 | [[nodiscard]] Common::Vec3f GetGyroBias() const; | ||
| 39 | [[nodiscard]] Common::Vec3f GetRotations() const; | 40 | [[nodiscard]] Common::Vec3f GetRotations() const; |
| 40 | [[nodiscard]] Common::Quaternion<f32> GetQuaternion() const; | 41 | [[nodiscard]] Common::Quaternion<f32> GetQuaternion() const; |
| 41 | 42 | ||
| @@ -69,7 +70,7 @@ private: | |||
| 69 | Common::Vec3f gyro; | 70 | Common::Vec3f gyro; |
| 70 | 71 | ||
| 71 | // Vector to be substracted from gyro measurements | 72 | // Vector to be substracted from gyro measurements |
| 72 | Common::Vec3f gyro_drift; | 73 | Common::Vec3f gyro_bias; |
| 73 | 74 | ||
| 74 | // Minimum gyro amplitude to detect if the device is moving | 75 | // Minimum gyro amplitude to detect if the device is moving |
| 75 | f32 gyro_threshold = 0.0f; | 76 | f32 gyro_threshold = 0.0f; |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 90dda40dc..aee313995 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include "core/hle/kernel/k_thread.h" | 28 | #include "core/hle/kernel/k_thread.h" |
| 29 | #include "core/hle/kernel/kernel.h" | 29 | #include "core/hle/kernel/kernel.h" |
| 30 | #include "core/hle/kernel/svc_results.h" | 30 | #include "core/hle/kernel/svc_results.h" |
| 31 | #include "core/hle/lock.h" | ||
| 32 | #include "core/memory.h" | 31 | #include "core/memory.h" |
| 33 | 32 | ||
| 34 | namespace Kernel { | 33 | namespace Kernel { |
| @@ -543,7 +542,6 @@ void KProcess::FreeTLSRegion(VAddr tls_address) { | |||
| 543 | } | 542 | } |
| 544 | 543 | ||
| 545 | void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { | 544 | void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { |
| 546 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 547 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, | 545 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, |
| 548 | KMemoryPermission permission) { | 546 | KMemoryPermission permission) { |
| 549 | page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); | 547 | page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2e4e4cb1c..1225e1fba 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -182,7 +182,10 @@ struct KernelCore::Impl { | |||
| 182 | // Shutdown all processes. | 182 | // Shutdown all processes. |
| 183 | if (current_process) { | 183 | if (current_process) { |
| 184 | current_process->Finalize(); | 184 | current_process->Finalize(); |
| 185 | current_process->Close(); | 185 | // current_process->Close(); |
| 186 | // TODO: The current process should be destroyed based on accurate ref counting after | ||
| 187 | // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak. | ||
| 188 | current_process->Destroy(); | ||
| 186 | current_process = nullptr; | 189 | current_process = nullptr; |
| 187 | } | 190 | } |
| 188 | 191 | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index a9f7438ea..bb9475c56 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include "core/hle/kernel/svc_results.h" | 41 | #include "core/hle/kernel/svc_results.h" |
| 42 | #include "core/hle/kernel/svc_types.h" | 42 | #include "core/hle/kernel/svc_types.h" |
| 43 | #include "core/hle/kernel/svc_wrap.h" | 43 | #include "core/hle/kernel/svc_wrap.h" |
| 44 | #include "core/hle/lock.h" | ||
| 45 | #include "core/hle/result.h" | 44 | #include "core/hle/result.h" |
| 46 | #include "core/memory.h" | 45 | #include "core/memory.h" |
| 47 | #include "core/reporter.h" | 46 | #include "core/reporter.h" |
| @@ -137,7 +136,6 @@ enum class ResourceLimitValueType { | |||
| 137 | 136 | ||
| 138 | /// Set the process heap to a given Size. It can both extend and shrink the heap. | 137 | /// Set the process heap to a given Size. It can both extend and shrink the heap. |
| 139 | static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) { | 138 | static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) { |
| 140 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 141 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); | 139 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); |
| 142 | 140 | ||
| 143 | // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB. | 141 | // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB. |
| @@ -168,7 +166,6 @@ static ResultCode SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_s | |||
| 168 | 166 | ||
| 169 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, | 167 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, |
| 170 | u32 attribute) { | 168 | u32 attribute) { |
| 171 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 172 | LOG_DEBUG(Kernel_SVC, | 169 | LOG_DEBUG(Kernel_SVC, |
| 173 | "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, | 170 | "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, |
| 174 | size, mask, attribute); | 171 | size, mask, attribute); |
| @@ -212,7 +209,6 @@ static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 si | |||
| 212 | 209 | ||
| 213 | /// Maps a memory range into a different range. | 210 | /// Maps a memory range into a different range. |
| 214 | static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 211 | static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 215 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 216 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 212 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 217 | src_addr, size); | 213 | src_addr, size); |
| 218 | 214 | ||
| @@ -232,7 +228,6 @@ static ResultCode MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, | |||
| 232 | 228 | ||
| 233 | /// Unmaps a region that was previously mapped with svcMapMemory | 229 | /// Unmaps a region that was previously mapped with svcMapMemory |
| 234 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 230 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 235 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 236 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 231 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 237 | src_addr, size); | 232 | src_addr, size); |
| 238 | 233 | ||
| @@ -642,7 +637,6 @@ static void OutputDebugString(Core::System& system, VAddr address, u64 len) { | |||
| 642 | /// Gets system/memory information for the current process | 637 | /// Gets system/memory information for the current process |
| 643 | static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, | 638 | static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, |
| 644 | u64 info_sub_id) { | 639 | u64 info_sub_id) { |
| 645 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 646 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, | 640 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, |
| 647 | info_sub_id, handle); | 641 | info_sub_id, handle); |
| 648 | 642 | ||
| @@ -924,7 +918,6 @@ static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_h | |||
| 924 | 918 | ||
| 925 | /// Maps memory at a desired address | 919 | /// Maps memory at a desired address |
| 926 | static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 920 | static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 927 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 928 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | 921 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); |
| 929 | 922 | ||
| 930 | if (!Common::Is4KBAligned(addr)) { | 923 | if (!Common::Is4KBAligned(addr)) { |
| @@ -978,7 +971,6 @@ static ResultCode MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) | |||
| 978 | 971 | ||
| 979 | /// Unmaps memory previously mapped via MapPhysicalMemory | 972 | /// Unmaps memory previously mapped via MapPhysicalMemory |
| 980 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 973 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 981 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 982 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | 974 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); |
| 983 | 975 | ||
| 984 | if (!Common::Is4KBAligned(addr)) { | 976 | if (!Common::Is4KBAligned(addr)) { |
| @@ -1520,7 +1512,6 @@ static ResultCode ControlCodeMemory(Core::System& system, Handle code_memory_han | |||
| 1520 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | 1512 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, |
| 1521 | VAddr page_info_address, Handle process_handle, | 1513 | VAddr page_info_address, Handle process_handle, |
| 1522 | VAddr address) { | 1514 | VAddr address) { |
| 1523 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 1524 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); | 1515 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); |
| 1525 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1516 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1526 | KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); | 1517 | KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); |
diff --git a/src/core/hle/lock.cpp b/src/core/hle/lock.cpp deleted file mode 100644 index be4bfce3b..000000000 --- a/src/core/hle/lock.cpp +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <core/hle/lock.h> | ||
| 6 | |||
| 7 | namespace HLE { | ||
| 8 | std::recursive_mutex g_hle_lock; | ||
| 9 | } | ||
diff --git a/src/core/hle/lock.h b/src/core/hle/lock.h deleted file mode 100644 index 5c99fe996..000000000 --- a/src/core/hle/lock.h +++ /dev/null | |||
| @@ -1,18 +0,0 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <mutex> | ||
| 8 | |||
| 9 | namespace HLE { | ||
| 10 | /* | ||
| 11 | * Synchronizes access to the internal HLE kernel structures, it is acquired when a guest | ||
| 12 | * application thread performs a syscall. It should be acquired by any host threads that read or | ||
| 13 | * modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or writes | ||
| 14 | * to the emulated memory is not protected by this mutex, and should be avoided in any threads other | ||
| 15 | * than the CPU thread. | ||
| 16 | */ | ||
| 17 | extern std::recursive_mutex g_hle_lock; | ||
| 18 | } // namespace HLE | ||
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp index 4c7d3bb6e..ee49edbb9 100644 --- a/src/core/hle/service/bcat/backend/backend.cpp +++ b/src/core/hle/service/bcat/backend/backend.cpp | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/k_event.h" | 8 | #include "core/hle/kernel/k_event.h" |
| 9 | #include "core/hle/lock.h" | ||
| 10 | #include "core/hle/service/bcat/backend/backend.h" | 9 | #include "core/hle/service/bcat/backend/backend.h" |
| 11 | 10 | ||
| 12 | namespace Service::BCAT { | 11 | namespace Service::BCAT { |
| @@ -29,10 +28,6 @@ DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() { | |||
| 29 | return impl; | 28 | return impl; |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | void ProgressServiceBackend::SetNeedHLELock(bool need) { | ||
| 33 | need_hle_lock = need; | ||
| 34 | } | ||
| 35 | |||
| 36 | void ProgressServiceBackend::SetTotalSize(u64 size) { | 31 | void ProgressServiceBackend::SetTotalSize(u64 size) { |
| 37 | impl.total_bytes = size; | 32 | impl.total_bytes = size; |
| 38 | SignalUpdate(); | 33 | SignalUpdate(); |
| @@ -88,12 +83,7 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) { | |||
| 88 | } | 83 | } |
| 89 | 84 | ||
| 90 | void ProgressServiceBackend::SignalUpdate() { | 85 | void ProgressServiceBackend::SignalUpdate() { |
| 91 | if (need_hle_lock) { | 86 | update_event->GetWritableEvent().Signal(); |
| 92 | std::lock_guard lock(HLE::g_hle_lock); | ||
| 93 | update_event->GetWritableEvent().Signal(); | ||
| 94 | } else { | ||
| 95 | update_event->GetWritableEvent().Signal(); | ||
| 96 | } | ||
| 97 | } | 87 | } |
| 98 | 88 | ||
| 99 | Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} | 89 | Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} |
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h index 59c6d4740..63833c927 100644 --- a/src/core/hle/service/bcat/backend/backend.h +++ b/src/core/hle/service/bcat/backend/backend.h | |||
| @@ -71,10 +71,6 @@ class ProgressServiceBackend { | |||
| 71 | public: | 71 | public: |
| 72 | ~ProgressServiceBackend(); | 72 | ~ProgressServiceBackend(); |
| 73 | 73 | ||
| 74 | // Clients should call this with true if any of the functions are going to be called from a | ||
| 75 | // non-HLE thread and this class need to lock the hle mutex. (default is false) | ||
| 76 | void SetNeedHLELock(bool need); | ||
| 77 | |||
| 78 | // Sets the number of bytes total in the entire download. | 74 | // Sets the number of bytes total in the entire download. |
| 79 | void SetTotalSize(u64 size); | 75 | void SetTotalSize(u64 size); |
| 80 | 76 | ||
| @@ -109,7 +105,6 @@ private: | |||
| 109 | 105 | ||
| 110 | DeliveryCacheProgressImpl impl{}; | 106 | DeliveryCacheProgressImpl impl{}; |
| 111 | Kernel::KEvent* update_event; | 107 | Kernel::KEvent* update_event; |
| 112 | bool need_hle_lock = false; | ||
| 113 | }; | 108 | }; |
| 114 | 109 | ||
| 115 | // A class representing an abstract backend for BCAT functionality. | 110 | // A class representing an abstract backend for BCAT functionality. |
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp index f0f3105dc..a727b3582 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp +++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp | |||
| @@ -33,15 +33,14 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti | |||
| 33 | const auto& last_entry = seven_sixaxis_lifo.ReadCurrentEntry().state; | 33 | const auto& last_entry = seven_sixaxis_lifo.ReadCurrentEntry().state; |
| 34 | next_seven_sixaxis_state.sampling_number = last_entry.sampling_number + 1; | 34 | next_seven_sixaxis_state.sampling_number = last_entry.sampling_number + 1; |
| 35 | 35 | ||
| 36 | // Try to read sixaxis sensor states | ||
| 37 | const auto motion_status = console->GetMotion(); | 36 | const auto motion_status = console->GetMotion(); |
| 37 | last_global_timestamp = core_timing.GetGlobalTimeNs().count(); | ||
| 38 | 38 | ||
| 39 | console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; | 39 | // This value increments every time the switch goes to sleep |
| 40 | 40 | next_seven_sixaxis_state.unknown = 1; | |
| 41 | next_seven_sixaxis_state.timestamp = last_global_timestamp - last_saved_timestamp; | ||
| 41 | next_seven_sixaxis_state.accel = motion_status.accel; | 42 | next_seven_sixaxis_state.accel = motion_status.accel; |
| 42 | // Zero gyro values as they just mess up with the camera | 43 | next_seven_sixaxis_state.gyro = motion_status.gyro; |
| 43 | // Note: Probably a correct sensivity setting must be set | ||
| 44 | next_seven_sixaxis_state.gyro = {}; | ||
| 45 | next_seven_sixaxis_state.quaternion = { | 44 | next_seven_sixaxis_state.quaternion = { |
| 46 | { | 45 | { |
| 47 | motion_status.quaternion.xyz.y, | 46 | motion_status.quaternion.xyz.y, |
| @@ -52,9 +51,9 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti | |||
| 52 | }; | 51 | }; |
| 53 | 52 | ||
| 54 | console_six_axis.sampling_number++; | 53 | console_six_axis.sampling_number++; |
| 55 | // TODO(German77): Find the purpose of those values | 54 | console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; |
| 56 | console_six_axis.verticalization_error = 0.0f; | 55 | console_six_axis.verticalization_error = motion_status.verticalization_error; |
| 57 | console_six_axis.gyro_bias = {0.0f, 0.0f, 0.0f}; | 56 | console_six_axis.gyro_bias = motion_status.gyro_bias; |
| 58 | 57 | ||
| 59 | // Update console six axis shared memory | 58 | // Update console six axis shared memory |
| 60 | std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis)); | 59 | std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis)); |
| @@ -69,7 +68,6 @@ void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem) { | |||
| 69 | } | 68 | } |
| 70 | 69 | ||
| 71 | void Controller_ConsoleSixAxis::ResetTimestamp() { | 70 | void Controller_ConsoleSixAxis::ResetTimestamp() { |
| 72 | seven_sixaxis_lifo.buffer_count = 0; | 71 | last_saved_timestamp = last_global_timestamp; |
| 73 | seven_sixaxis_lifo.buffer_tail = 0; | ||
| 74 | } | 72 | } |
| 75 | } // namespace Service::HID | 73 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h index 279241858..26d153f0c 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.h +++ b/src/core/hle/service/hid/controllers/console_sixaxis.h | |||
| @@ -39,8 +39,9 @@ public: | |||
| 39 | 39 | ||
| 40 | private: | 40 | private: |
| 41 | struct SevenSixAxisState { | 41 | struct SevenSixAxisState { |
| 42 | INSERT_PADDING_WORDS(4); // unused | 42 | INSERT_PADDING_WORDS(2); // unused |
| 43 | s64 sampling_number{}; | 43 | u64 timestamp{}; |
| 44 | u64 sampling_number{}; | ||
| 44 | u64 unknown{}; | 45 | u64 unknown{}; |
| 45 | Common::Vec3f accel{}; | 46 | Common::Vec3f accel{}; |
| 46 | Common::Vec3f gyro{}; | 47 | Common::Vec3f gyro{}; |
| @@ -52,9 +53,10 @@ private: | |||
| 52 | struct ConsoleSharedMemory { | 53 | struct ConsoleSharedMemory { |
| 53 | u64 sampling_number{}; | 54 | u64 sampling_number{}; |
| 54 | bool is_seven_six_axis_sensor_at_rest{}; | 55 | bool is_seven_six_axis_sensor_at_rest{}; |
| 55 | INSERT_PADDING_BYTES(4); // padding | 56 | INSERT_PADDING_BYTES(3); // padding |
| 56 | f32 verticalization_error{}; | 57 | f32 verticalization_error{}; |
| 57 | Common::Vec3f gyro_bias{}; | 58 | Common::Vec3f gyro_bias{}; |
| 59 | INSERT_PADDING_BYTES(4); // padding | ||
| 58 | }; | 60 | }; |
| 59 | static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); | 61 | static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); |
| 60 | 62 | ||
| @@ -64,6 +66,8 @@ private: | |||
| 64 | Core::HID::EmulatedConsole* console; | 66 | Core::HID::EmulatedConsole* console; |
| 65 | u8* transfer_memory = nullptr; | 67 | u8* transfer_memory = nullptr; |
| 66 | bool is_transfer_memory_set = false; | 68 | bool is_transfer_memory_set = false; |
| 69 | u64 last_saved_timestamp{}; | ||
| 70 | u64 last_global_timestamp{}; | ||
| 67 | ConsoleSharedMemory console_six_axis{}; | 71 | ConsoleSharedMemory console_six_axis{}; |
| 68 | SevenSixAxisState next_seven_sixaxis_state{}; | 72 | SevenSixAxisState next_seven_sixaxis_state{}; |
| 69 | }; | 73 | }; |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 2705e9dcb..e5c951e06 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -66,9 +66,9 @@ Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, | |||
| 66 | auto& controller = controller_data[i]; | 66 | auto& controller = controller_data[i]; |
| 67 | controller.device = hid_core.GetEmulatedControllerByIndex(i); | 67 | controller.device = hid_core.GetEmulatedControllerByIndex(i); |
| 68 | controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = | 68 | controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = |
| 69 | DEFAULT_VIBRATION_VALUE; | 69 | Core::HID::DEFAULT_VIBRATION_VALUE; |
| 70 | controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex].latest_vibration_value = | 70 | controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex].latest_vibration_value = |
| 71 | DEFAULT_VIBRATION_VALUE; | 71 | Core::HID::DEFAULT_VIBRATION_VALUE; |
| 72 | Core::HID::ControllerUpdateCallback engine_callback{ | 72 | Core::HID::ControllerUpdateCallback engine_callback{ |
| 73 | .on_change = [this, | 73 | .on_change = [this, |
| 74 | i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }, | 74 | i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }, |
| @@ -781,7 +781,8 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, | |||
| 781 | Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f}; | 781 | Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f}; |
| 782 | controller.device->SetVibration(device_index, vibration); | 782 | controller.device->SetVibration(device_index, vibration); |
| 783 | // Then reset the vibration value to its default value. | 783 | // Then reset the vibration value to its default value. |
| 784 | controller.vibration[device_index].latest_vibration_value = DEFAULT_VIBRATION_VALUE; | 784 | controller.vibration[device_index].latest_vibration_value = |
| 785 | Core::HID::DEFAULT_VIBRATION_VALUE; | ||
| 785 | } | 786 | } |
| 786 | 787 | ||
| 787 | return false; | 788 | return false; |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 63281cb35..6b2872bad 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -90,13 +90,6 @@ public: | |||
| 90 | Default = 3, | 90 | Default = 3, |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | static constexpr Core::HID::VibrationValue DEFAULT_VIBRATION_VALUE{ | ||
| 94 | .low_amplitude = 0.0f, | ||
| 95 | .low_frequency = 160.0f, | ||
| 96 | .high_amplitude = 0.0f, | ||
| 97 | .high_frequency = 320.0f, | ||
| 98 | }; | ||
| 99 | |||
| 100 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); | 93 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); |
| 101 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; | 94 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; |
| 102 | 95 | ||
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 7163e1a4e..6e12381fb 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -1404,7 +1404,7 @@ void Hid::SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { | |||
| 1404 | .high_frequency = 0.0f, | 1404 | .high_frequency = 0.0f, |
| 1405 | }; | 1405 | }; |
| 1406 | default: | 1406 | default: |
| 1407 | return Controller_NPad::DEFAULT_VIBRATION_VALUE; | 1407 | return Core::HID::DEFAULT_VIBRATION_VALUE; |
| 1408 | } | 1408 | } |
| 1409 | }(); | 1409 | }(); |
| 1410 | 1410 | ||
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 693ffc71a..761d0d3c6 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/ipc_helpers.h" | 10 | #include "core/hle/ipc_helpers.h" |
| 11 | #include "core/hle/kernel/k_event.h" | 11 | #include "core/hle/kernel/k_event.h" |
| 12 | #include "core/hle/lock.h" | ||
| 13 | #include "core/hle/service/nfp/nfp.h" | 12 | #include "core/hle/service/nfp/nfp.h" |
| 14 | #include "core/hle/service/nfp/nfp_user.h" | 13 | #include "core/hle/service/nfp/nfp_user.h" |
| 15 | 14 | ||
| @@ -337,7 +336,6 @@ void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { | |||
| 337 | } | 336 | } |
| 338 | 337 | ||
| 339 | bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { | 338 | bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { |
| 340 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 341 | if (buffer.size() < sizeof(AmiiboFile)) { | 339 | if (buffer.size() < sizeof(AmiiboFile)) { |
| 342 | return false; | 340 | return false; |
| 343 | } | 341 | } |
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp index 3ae9e6e0e..99ed34b00 100644 --- a/src/core/loader/kip.cpp +++ b/src/core/loader/kip.cpp | |||
| @@ -71,7 +71,6 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, | |||
| 71 | kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, 0x1FE00000, | 71 | kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, 0x1FE00000, |
| 72 | kip->GetKernelCapabilities()); | 72 | kip->GetKernelCapabilities()); |
| 73 | 73 | ||
| 74 | const VAddr base_address = process.PageTable().GetCodeRegionStart(); | ||
| 75 | Kernel::CodeSet codeset; | 74 | Kernel::CodeSet codeset; |
| 76 | Kernel::PhysicalMemory program_image; | 75 | Kernel::PhysicalMemory program_image; |
| 77 | 76 | ||
| @@ -91,7 +90,14 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, | |||
| 91 | program_image.resize(PageAlignSize(kip->GetBSSOffset()) + kip->GetBSSSize()); | 90 | program_image.resize(PageAlignSize(kip->GetBSSOffset()) + kip->GetBSSSize()); |
| 92 | codeset.DataSegment().size += kip->GetBSSSize(); | 91 | codeset.DataSegment().size += kip->GetBSSSize(); |
| 93 | 92 | ||
| 93 | // Setup the process code layout | ||
| 94 | if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size()) | ||
| 95 | .IsError()) { | ||
| 96 | return {ResultStatus::ErrorNotInitialized, {}}; | ||
| 97 | } | ||
| 98 | |||
| 94 | codeset.memory = std::move(program_image); | 99 | codeset.memory = std::move(program_image); |
| 100 | const VAddr base_address = process.PageTable().GetCodeRegionStart(); | ||
| 95 | process.LoadModule(std::move(codeset), base_address); | 101 | process.LoadModule(std::move(codeset), base_address); |
| 96 | 102 | ||
| 97 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); | 103 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); |
diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp index 4ab991a7d..a1ce4525d 100644 --- a/src/input_common/drivers/udp_client.cpp +++ b/src/input_common/drivers/udp_client.cpp | |||
| @@ -536,42 +536,46 @@ CalibrationConfigurationJob::CalibrationConfigurationJob( | |||
| 536 | std::function<void(u16, u16, u16, u16)> data_callback) { | 536 | std::function<void(u16, u16, u16, u16)> data_callback) { |
| 537 | 537 | ||
| 538 | std::thread([=, this] { | 538 | std::thread([=, this] { |
| 539 | u16 min_x{UINT16_MAX}; | ||
| 540 | u16 min_y{UINT16_MAX}; | ||
| 541 | u16 max_x{}; | ||
| 542 | u16 max_y{}; | ||
| 543 | |||
| 539 | Status current_status{Status::Initialized}; | 544 | Status current_status{Status::Initialized}; |
| 540 | SocketCallback callback{ | 545 | SocketCallback callback{[](Response::Version) {}, [](Response::PortInfo) {}, |
| 541 | [](Response::Version) {}, [](Response::PortInfo) {}, | 546 | [&](Response::PadData data) { |
| 542 | [&](Response::PadData data) { | 547 | constexpr u16 CALIBRATION_THRESHOLD = 100; |
| 543 | static constexpr u16 CALIBRATION_THRESHOLD = 100; | 548 | |
| 544 | static constexpr u16 MAX_VALUE = UINT16_MAX; | 549 | if (current_status == Status::Initialized) { |
| 545 | 550 | // Receiving data means the communication is ready now | |
| 546 | if (current_status == Status::Initialized) { | 551 | current_status = Status::Ready; |
| 547 | // Receiving data means the communication is ready now | 552 | status_callback(current_status); |
| 548 | current_status = Status::Ready; | 553 | } |
| 549 | status_callback(current_status); | 554 | if (data.touch[0].is_active == 0) { |
| 550 | } | 555 | return; |
| 551 | const auto& touchpad_0 = data.touch[0]; | 556 | } |
| 552 | if (touchpad_0.is_active == 0) { | 557 | LOG_DEBUG(Input, "Current touch: {} {}", data.touch[0].x, |
| 553 | return; | 558 | data.touch[0].y); |
| 554 | } | 559 | min_x = std::min(min_x, static_cast<u16>(data.touch[0].x)); |
| 555 | LOG_DEBUG(Input, "Current touch: {} {}", touchpad_0.x, touchpad_0.y); | 560 | min_y = std::min(min_y, static_cast<u16>(data.touch[0].y)); |
| 556 | const u16 min_x = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.x)); | 561 | if (current_status == Status::Ready) { |
| 557 | const u16 min_y = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.y)); | 562 | // First touch - min data (min_x/min_y) |
| 558 | if (current_status == Status::Ready) { | 563 | current_status = Status::Stage1Completed; |
| 559 | // First touch - min data (min_x/min_y) | 564 | status_callback(current_status); |
| 560 | current_status = Status::Stage1Completed; | 565 | } |
| 561 | status_callback(current_status); | 566 | if (data.touch[0].x - min_x > CALIBRATION_THRESHOLD && |
| 562 | } | 567 | data.touch[0].y - min_y > CALIBRATION_THRESHOLD) { |
| 563 | if (touchpad_0.x - min_x > CALIBRATION_THRESHOLD && | 568 | // Set the current position as max value and finishes |
| 564 | touchpad_0.y - min_y > CALIBRATION_THRESHOLD) { | 569 | // configuration |
| 565 | // Set the current position as max value and finishes configuration | 570 | max_x = data.touch[0].x; |
| 566 | const u16 max_x = touchpad_0.x; | 571 | max_y = data.touch[0].y; |
| 567 | const u16 max_y = touchpad_0.y; | 572 | current_status = Status::Completed; |
| 568 | current_status = Status::Completed; | 573 | data_callback(min_x, min_y, max_x, max_y); |
| 569 | data_callback(min_x, min_y, max_x, max_y); | 574 | status_callback(current_status); |
| 570 | status_callback(current_status); | 575 | |
| 571 | 576 | complete_event.Set(); | |
| 572 | complete_event.Set(); | 577 | } |
| 573 | } | 578 | }}; |
| 574 | }}; | ||
| 575 | Socket socket{host, port, std::move(callback)}; | 579 | Socket socket{host, port, std::move(callback)}; |
| 576 | std::thread worker_thread{SocketLoop, &socket}; | 580 | std::thread worker_thread{SocketLoop, &socket}; |
| 577 | complete_event.Wait(); | 581 | complete_event.Wait(); |
diff --git a/src/input_common/helpers/udp_protocol.h b/src/input_common/helpers/udp_protocol.h index bcba12c58..2d5d54ddb 100644 --- a/src/input_common/helpers/udp_protocol.h +++ b/src/input_common/helpers/udp_protocol.h | |||
| @@ -54,6 +54,18 @@ struct Message { | |||
| 54 | template <typename T> | 54 | template <typename T> |
| 55 | constexpr Type GetMessageType(); | 55 | constexpr Type GetMessageType(); |
| 56 | 56 | ||
| 57 | template <typename T> | ||
| 58 | Message<T> CreateMessage(const u32 magic, const T data, const u32 sender_id) { | ||
| 59 | boost::crc_32_type crc; | ||
| 60 | Header header{ | ||
| 61 | magic, PROTOCOL_VERSION, sizeof(T) + sizeof(Type), 0, sender_id, GetMessageType<T>(), | ||
| 62 | }; | ||
| 63 | Message<T> message{header, data}; | ||
| 64 | crc.process_bytes(&message, sizeof(Message<T>)); | ||
| 65 | message.header.crc = crc.checksum(); | ||
| 66 | return message; | ||
| 67 | } | ||
| 68 | |||
| 57 | namespace Request { | 69 | namespace Request { |
| 58 | 70 | ||
| 59 | enum RegisterFlags : u8 { | 71 | enum RegisterFlags : u8 { |
| @@ -101,14 +113,7 @@ static_assert(std::is_trivially_copyable_v<PadData>, | |||
| 101 | */ | 113 | */ |
| 102 | template <typename T> | 114 | template <typename T> |
| 103 | Message<T> Create(const T data, const u32 client_id = 0) { | 115 | Message<T> Create(const T data, const u32 client_id = 0) { |
| 104 | boost::crc_32_type crc; | 116 | return CreateMessage(CLIENT_MAGIC, data, client_id); |
| 105 | Header header{ | ||
| 106 | CLIENT_MAGIC, PROTOCOL_VERSION, sizeof(T) + sizeof(Type), 0, client_id, GetMessageType<T>(), | ||
| 107 | }; | ||
| 108 | Message<T> message{header, data}; | ||
| 109 | crc.process_bytes(&message, sizeof(Message<T>)); | ||
| 110 | message.header.crc = crc.checksum(); | ||
| 111 | return message; | ||
| 112 | } | 117 | } |
| 113 | } // namespace Request | 118 | } // namespace Request |
| 114 | 119 | ||
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index c4c012f3d..4a20c0768 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt | |||
| @@ -10,11 +10,12 @@ add_executable(tests | |||
| 10 | core/network/network.cpp | 10 | core/network/network.cpp |
| 11 | tests.cpp | 11 | tests.cpp |
| 12 | video_core/buffer_base.cpp | 12 | video_core/buffer_base.cpp |
| 13 | input_common/calibration_configuration_job.cpp | ||
| 13 | ) | 14 | ) |
| 14 | 15 | ||
| 15 | create_target_directory_groups(tests) | 16 | create_target_directory_groups(tests) |
| 16 | 17 | ||
| 17 | target_link_libraries(tests PRIVATE common core) | 18 | target_link_libraries(tests PRIVATE common core input_common) |
| 18 | target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads) | 19 | target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads) |
| 19 | 20 | ||
| 20 | add_test(NAME tests COMMAND tests) | 21 | add_test(NAME tests COMMAND tests) |
diff --git a/src/tests/input_common/calibration_configuration_job.cpp b/src/tests/input_common/calibration_configuration_job.cpp new file mode 100644 index 000000000..8c77d81e9 --- /dev/null +++ b/src/tests/input_common/calibration_configuration_job.cpp | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <string> | ||
| 7 | #include <thread> | ||
| 8 | #include <boost/asio.hpp> | ||
| 9 | #include <boost/crc.hpp> | ||
| 10 | #include <catch2/catch.hpp> | ||
| 11 | |||
| 12 | #include "input_common/drivers/udp_client.h" | ||
| 13 | #include "input_common/helpers/udp_protocol.h" | ||
| 14 | |||
| 15 | class FakeCemuhookServer { | ||
| 16 | public: | ||
| 17 | FakeCemuhookServer() | ||
| 18 | : socket(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) {} | ||
| 19 | |||
| 20 | ~FakeCemuhookServer() { | ||
| 21 | is_running = false; | ||
| 22 | boost::system::error_code error_code; | ||
| 23 | socket.shutdown(boost::asio::socket_base::shutdown_both, error_code); | ||
| 24 | socket.close(); | ||
| 25 | if (handler.joinable()) { | ||
| 26 | handler.join(); | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | u16 GetPort() { | ||
| 31 | return socket.local_endpoint().port(); | ||
| 32 | } | ||
| 33 | |||
| 34 | std::string GetHost() { | ||
| 35 | return socket.local_endpoint().address().to_string(); | ||
| 36 | } | ||
| 37 | |||
| 38 | void Run(const std::vector<InputCommon::CemuhookUDP::Response::TouchPad> touch_movement_path) { | ||
| 39 | constexpr size_t HeaderSize = sizeof(InputCommon::CemuhookUDP::Header); | ||
| 40 | constexpr size_t PadDataSize = | ||
| 41 | sizeof(InputCommon::CemuhookUDP::Message<InputCommon::CemuhookUDP::Response::PadData>); | ||
| 42 | |||
| 43 | REQUIRE(touch_movement_path.size() > 0); | ||
| 44 | is_running = true; | ||
| 45 | handler = std::thread([touch_movement_path, this]() { | ||
| 46 | auto current_touch_position = touch_movement_path.begin(); | ||
| 47 | while (is_running) { | ||
| 48 | boost::asio::ip::udp::endpoint sender_endpoint; | ||
| 49 | boost::system::error_code error_code; | ||
| 50 | auto received_size = socket.receive_from(boost::asio::buffer(receive_buffer), | ||
| 51 | sender_endpoint, 0, error_code); | ||
| 52 | |||
| 53 | if (received_size < HeaderSize) { | ||
| 54 | continue; | ||
| 55 | } | ||
| 56 | |||
| 57 | InputCommon::CemuhookUDP::Header header{}; | ||
| 58 | std::memcpy(&header, receive_buffer.data(), HeaderSize); | ||
| 59 | switch (header.type) { | ||
| 60 | case InputCommon::CemuhookUDP::Type::PadData: { | ||
| 61 | InputCommon::CemuhookUDP::Response::PadData pad_data{}; | ||
| 62 | pad_data.touch[0] = *current_touch_position; | ||
| 63 | const auto pad_message = InputCommon::CemuhookUDP::CreateMessage( | ||
| 64 | InputCommon::CemuhookUDP::SERVER_MAGIC, pad_data, 0); | ||
| 65 | std::memcpy(send_buffer.data(), &pad_message, PadDataSize); | ||
| 66 | socket.send_to(boost::asio::buffer(send_buffer, PadDataSize), sender_endpoint, | ||
| 67 | 0, error_code); | ||
| 68 | |||
| 69 | bool can_advance = | ||
| 70 | std::next(current_touch_position) != touch_movement_path.end(); | ||
| 71 | if (can_advance) { | ||
| 72 | std::advance(current_touch_position, 1); | ||
| 73 | } | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | case InputCommon::CemuhookUDP::Type::PortInfo: | ||
| 77 | case InputCommon::CemuhookUDP::Type::Version: | ||
| 78 | default: | ||
| 79 | break; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | }); | ||
| 83 | } | ||
| 84 | |||
| 85 | private: | ||
| 86 | boost::asio::io_service io_service; | ||
| 87 | boost::asio::ip::udp::socket socket; | ||
| 88 | std::array<u8, InputCommon::CemuhookUDP::MAX_PACKET_SIZE> send_buffer; | ||
| 89 | std::array<u8, InputCommon::CemuhookUDP::MAX_PACKET_SIZE> receive_buffer; | ||
| 90 | bool is_running = false; | ||
| 91 | std::thread handler; | ||
| 92 | }; | ||
| 93 | |||
| 94 | TEST_CASE("CalibrationConfigurationJob completed", "[input_common]") { | ||
| 95 | Common::Event complete_event; | ||
| 96 | FakeCemuhookServer server; | ||
| 97 | server.Run({{ | ||
| 98 | .is_active = 1, | ||
| 99 | .x = 0, | ||
| 100 | .y = 0, | ||
| 101 | }, | ||
| 102 | { | ||
| 103 | .is_active = 1, | ||
| 104 | .x = 200, | ||
| 105 | .y = 200, | ||
| 106 | }}); | ||
| 107 | |||
| 108 | InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status status{}; | ||
| 109 | u16 min_x{}; | ||
| 110 | u16 min_y{}; | ||
| 111 | u16 max_x{}; | ||
| 112 | u16 max_y{}; | ||
| 113 | InputCommon::CemuhookUDP::CalibrationConfigurationJob job( | ||
| 114 | server.GetHost(), server.GetPort(), | ||
| 115 | [&status, | ||
| 116 | &complete_event](InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status status_) { | ||
| 117 | status = status_; | ||
| 118 | if (status == | ||
| 119 | InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status::Completed) { | ||
| 120 | complete_event.Set(); | ||
| 121 | } | ||
| 122 | }, | ||
| 123 | [&](u16 min_x_, u16 min_y_, u16 max_x_, u16 max_y_) { | ||
| 124 | min_x = min_x_; | ||
| 125 | min_y = min_y_; | ||
| 126 | max_x = max_x_; | ||
| 127 | max_y = max_y_; | ||
| 128 | }); | ||
| 129 | |||
| 130 | complete_event.WaitUntil(std::chrono::system_clock::now() + std::chrono::seconds(10)); | ||
| 131 | REQUIRE(status == InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status::Completed); | ||
| 132 | REQUIRE(min_x == 0); | ||
| 133 | REQUIRE(min_y == 0); | ||
| 134 | REQUIRE(max_x == 200); | ||
| 135 | REQUIRE(max_y == 200); | ||
| 136 | } | ||
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp index 2a532b883..04d0f3a2f 100644 --- a/src/video_core/command_classes/codecs/codec.cpp +++ b/src/video_core/command_classes/codecs/codec.cpp | |||
| @@ -32,7 +32,7 @@ constexpr std::array PREFERRED_GPU_DECODERS = { | |||
| 32 | #ifdef _WIN32 | 32 | #ifdef _WIN32 |
| 33 | AV_HWDEVICE_TYPE_D3D11VA, | 33 | AV_HWDEVICE_TYPE_D3D11VA, |
| 34 | AV_HWDEVICE_TYPE_DXVA2, | 34 | AV_HWDEVICE_TYPE_DXVA2, |
| 35 | #elif defined(__linux__) | 35 | #elif defined(__unix__) |
| 36 | AV_HWDEVICE_TYPE_VAAPI, | 36 | AV_HWDEVICE_TYPE_VAAPI, |
| 37 | AV_HWDEVICE_TYPE_VDPAU, | 37 | AV_HWDEVICE_TYPE_VDPAU, |
| 38 | #endif | 38 | #endif |
| @@ -130,6 +130,12 @@ bool Codec::CreateGpuAvDevice() { | |||
| 130 | } | 130 | } |
| 131 | if (config->methods & HW_CONFIG_METHOD && config->device_type == type) { | 131 | if (config->methods & HW_CONFIG_METHOD && config->device_type == type) { |
| 132 | av_codec_ctx->pix_fmt = config->pix_fmt; | 132 | av_codec_ctx->pix_fmt = config->pix_fmt; |
| 133 | if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) { | ||
| 134 | // skip zero-copy decoders, we don't currently support them | ||
| 135 | LOG_DEBUG(Service_NVDRV, "Skipping decoder {} with unsupported capability {}.", | ||
| 136 | av_hwdevice_get_type_name(type), config->methods); | ||
| 137 | continue; | ||
| 138 | } | ||
| 133 | LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type)); | 139 | LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type)); |
| 134 | return true; | 140 | return true; |
| 135 | } | 141 | } |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 37d5e6a6b..dbf1df79c 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -92,7 +92,7 @@ public: | |||
| 92 | 92 | ||
| 93 | void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); | 93 | void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); |
| 94 | 94 | ||
| 95 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled) { | 95 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) { |
| 96 | UNIMPLEMENTED(); | 96 | UNIMPLEMENTED(); |
| 97 | } | 97 | } |
| 98 | 98 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 28daacd82..f81c1b233 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -437,39 +437,29 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 437 | 437 | ||
| 438 | glBindTextureUnit(0, fxaa_texture.handle); | 438 | glBindTextureUnit(0, fxaa_texture.handle); |
| 439 | } | 439 | } |
| 440 | |||
| 441 | // Set projection matrix | ||
| 442 | const std::array ortho_matrix = | 440 | const std::array ortho_matrix = |
| 443 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); | 441 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); |
| 444 | 442 | ||
| 445 | GLuint fragment_handle; | 443 | const auto fragment_handle = [this]() { |
| 446 | const auto filter = Settings::values.scaling_filter.GetValue(); | 444 | switch (Settings::values.scaling_filter.GetValue()) { |
| 447 | switch (filter) { | 445 | case Settings::ScalingFilter::NearestNeighbor: |
| 448 | case Settings::ScalingFilter::NearestNeighbor: | 446 | case Settings::ScalingFilter::Bilinear: |
| 449 | fragment_handle = present_bilinear_fragment.handle; | 447 | return present_bilinear_fragment.handle; |
| 450 | break; | 448 | case Settings::ScalingFilter::Bicubic: |
| 451 | case Settings::ScalingFilter::Bilinear: | 449 | return present_bicubic_fragment.handle; |
| 452 | fragment_handle = present_bilinear_fragment.handle; | 450 | case Settings::ScalingFilter::Gaussian: |
| 453 | break; | 451 | return present_gaussian_fragment.handle; |
| 454 | case Settings::ScalingFilter::Bicubic: | 452 | case Settings::ScalingFilter::ScaleForce: |
| 455 | fragment_handle = present_bicubic_fragment.handle; | 453 | return present_scaleforce_fragment.handle; |
| 456 | break; | 454 | case Settings::ScalingFilter::Fsr: |
| 457 | case Settings::ScalingFilter::Gaussian: | 455 | LOG_WARNING( |
| 458 | fragment_handle = present_gaussian_fragment.handle; | 456 | Render_OpenGL, |
| 459 | break; | 457 | "FidelityFX Super Resolution is not supported in OpenGL, changing to ScaleForce"); |
| 460 | case Settings::ScalingFilter::ScaleForce: | 458 | return present_scaleforce_fragment.handle; |
| 461 | fragment_handle = present_scaleforce_fragment.handle; | 459 | default: |
| 462 | break; | 460 | return present_bilinear_fragment.handle; |
| 463 | case Settings::ScalingFilter::Fsr: | 461 | } |
| 464 | LOG_WARNING( | 462 | }(); |
| 465 | Render_OpenGL, | ||
| 466 | "FidelityFX FSR Super Sampling is not supported in OpenGL, changing to ScaleForce"); | ||
| 467 | fragment_handle = present_scaleforce_fragment.handle; | ||
| 468 | break; | ||
| 469 | default: | ||
| 470 | fragment_handle = present_bilinear_fragment.handle; | ||
| 471 | break; | ||
| 472 | } | ||
| 473 | program_manager.BindPresentPrograms(present_vertex.handle, fragment_handle); | 463 | program_manager.BindPresentPrograms(present_vertex.handle, fragment_handle); |
| 474 | glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE, | 464 | glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE, |
| 475 | ortho_matrix.data()); | 465 | ortho_matrix.data()); |
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index 9a38b6b34..cd5995897 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | 6 | ||
| 7 | #include "common/settings.h" | ||
| 7 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" | 8 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" |
| 8 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" | 9 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" |
| 9 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" | 10 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" |
| @@ -335,6 +336,17 @@ void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Regi | |||
| 335 | cmdbuf.SetScissor(0, scissor); | 336 | cmdbuf.SetScissor(0, scissor); |
| 336 | cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); | 337 | cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); |
| 337 | } | 338 | } |
| 339 | |||
| 340 | VkExtent2D GetConversionExtent(const ImageView& src_image_view) { | ||
| 341 | const auto& resolution = Settings::values.resolution_info; | ||
| 342 | const bool is_rescaled = src_image_view.IsRescaled(); | ||
| 343 | u32 width = src_image_view.size.width; | ||
| 344 | u32 height = src_image_view.size.height; | ||
| 345 | return VkExtent2D{ | ||
| 346 | .width = is_rescaled ? resolution.ScaleUp(width) : width, | ||
| 347 | .height = is_rescaled ? resolution.ScaleUp(height) : height, | ||
| 348 | }; | ||
| 349 | } | ||
| 338 | } // Anonymous namespace | 350 | } // Anonymous namespace |
| 339 | 351 | ||
| 340 | BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, | 352 | BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, |
| @@ -425,61 +437,52 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, | |||
| 425 | } | 437 | } |
| 426 | 438 | ||
| 427 | void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer, | 439 | void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer, |
| 428 | const ImageView& src_image_view, u32 up_scale, | 440 | const ImageView& src_image_view) { |
| 429 | u32 down_shift) { | ||
| 430 | ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass()); | 441 | ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass()); |
| 431 | Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 442 | Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view); |
| 432 | } | 443 | } |
| 433 | 444 | ||
| 434 | void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer, | 445 | void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer, |
| 435 | const ImageView& src_image_view, u32 up_scale, | 446 | const ImageView& src_image_view) { |
| 436 | u32 down_shift) { | ||
| 437 | ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass()); | 447 | ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass()); |
| 438 | Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 448 | Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view); |
| 439 | } | 449 | } |
| 440 | 450 | ||
| 441 | void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer, | 451 | void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer, |
| 442 | const ImageView& src_image_view, u32 up_scale, | 452 | const ImageView& src_image_view) { |
| 443 | u32 down_shift) { | ||
| 444 | ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass()); | 453 | ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass()); |
| 445 | Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 454 | Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view); |
| 446 | } | 455 | } |
| 447 | 456 | ||
| 448 | void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, | 457 | void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, |
| 449 | const ImageView& src_image_view, u32 up_scale, | 458 | const ImageView& src_image_view) { |
| 450 | u32 down_shift) { | ||
| 451 | ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass()); | 459 | ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass()); |
| 452 | Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 460 | Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view); |
| 453 | } | 461 | } |
| 454 | 462 | ||
| 455 | void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, | 463 | void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, |
| 456 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 464 | const ImageView& src_image_view) { |
| 457 | ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), | 465 | ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), |
| 458 | convert_abgr8_to_d24s8_frag, true); | 466 | convert_abgr8_to_d24s8_frag); |
| 459 | ConvertColor(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, | 467 | Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view); |
| 460 | down_shift); | ||
| 461 | } | 468 | } |
| 462 | 469 | ||
| 463 | void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, | 470 | void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, |
| 464 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 471 | ImageView& src_image_view) { |
| 465 | ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), | 472 | ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), |
| 466 | convert_d24s8_to_abgr8_frag, false); | 473 | convert_d24s8_to_abgr8_frag); |
| 467 | ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view, up_scale, | 474 | ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view); |
| 468 | down_shift); | ||
| 469 | } | 475 | } |
| 470 | 476 | ||
| 471 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 477 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 472 | const ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 478 | const ImageView& src_image_view) { |
| 473 | const VkPipelineLayout layout = *one_texture_pipeline_layout; | 479 | const VkPipelineLayout layout = *one_texture_pipeline_layout; |
| 474 | const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); | 480 | const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); |
| 475 | const VkSampler sampler = *nearest_sampler; | 481 | const VkSampler sampler = *nearest_sampler; |
| 476 | const VkExtent2D extent{ | 482 | const VkExtent2D extent = GetConversionExtent(src_image_view); |
| 477 | .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), | 483 | |
| 478 | .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U), | ||
| 479 | }; | ||
| 480 | scheduler.RequestRenderpass(dst_framebuffer); | 484 | scheduler.RequestRenderpass(dst_framebuffer); |
| 481 | scheduler.Record([pipeline, layout, sampler, src_view, extent, up_scale, down_shift, | 485 | scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) { |
| 482 | this](vk::CommandBuffer cmdbuf) { | ||
| 483 | const VkOffset2D offset{ | 486 | const VkOffset2D offset{ |
| 484 | .x = 0, | 487 | .x = 0, |
| 485 | .y = 0, | 488 | .y = 0, |
| @@ -563,18 +566,16 @@ void BlitImageHelper::ConvertColor(VkPipeline pipeline, const Framebuffer* dst_f | |||
| 563 | } | 566 | } |
| 564 | 567 | ||
| 565 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 568 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 566 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 569 | ImageView& src_image_view) { |
| 567 | const VkPipelineLayout layout = *two_textures_pipeline_layout; | 570 | const VkPipelineLayout layout = *two_textures_pipeline_layout; |
| 568 | const VkImageView src_depth_view = src_image_view.DepthView(); | 571 | const VkImageView src_depth_view = src_image_view.DepthView(); |
| 569 | const VkImageView src_stencil_view = src_image_view.StencilView(); | 572 | const VkImageView src_stencil_view = src_image_view.StencilView(); |
| 570 | const VkSampler sampler = *nearest_sampler; | 573 | const VkSampler sampler = *nearest_sampler; |
| 571 | const VkExtent2D extent{ | 574 | const VkExtent2D extent = GetConversionExtent(src_image_view); |
| 572 | .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), | 575 | |
| 573 | .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U), | ||
| 574 | }; | ||
| 575 | scheduler.RequestRenderpass(dst_framebuffer); | 576 | scheduler.RequestRenderpass(dst_framebuffer); |
| 576 | scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, up_scale, | 577 | scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, |
| 577 | down_shift, this](vk::CommandBuffer cmdbuf) { | 578 | this](vk::CommandBuffer cmdbuf) { |
| 578 | const VkOffset2D offset{ | 579 | const VkOffset2D offset{ |
| 579 | .x = 0, | 580 | .x = 0, |
| 580 | .y = 0, | 581 | .y = 0, |
| @@ -695,11 +696,14 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip | |||
| 695 | return *blit_depth_stencil_pipelines.back(); | 696 | return *blit_depth_stencil_pipelines.back(); |
| 696 | } | 697 | } |
| 697 | 698 | ||
| 698 | void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | 699 | void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 700 | bool is_target_depth) { | ||
| 699 | if (pipeline) { | 701 | if (pipeline) { |
| 700 | return; | 702 | return; |
| 701 | } | 703 | } |
| 702 | const std::array stages = MakeStages(*full_screen_vert, *convert_depth_to_float_frag); | 704 | VkShaderModule frag_shader = |
| 705 | is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag; | ||
| 706 | const std::array stages = MakeStages(*full_screen_vert, frag_shader); | ||
| 703 | pipeline = device.GetLogical().CreateGraphicsPipeline({ | 707 | pipeline = device.GetLogical().CreateGraphicsPipeline({ |
| 704 | .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | 708 | .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, |
| 705 | .pNext = nullptr, | 709 | .pNext = nullptr, |
| @@ -712,8 +716,9 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend | |||
| 712 | .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, | 716 | .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, |
| 713 | .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | 717 | .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, |
| 714 | .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | 718 | .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, |
| 715 | .pDepthStencilState = nullptr, | 719 | .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr, |
| 716 | .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, | 720 | .pColorBlendState = is_target_depth ? &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO |
| 721 | : &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, | ||
| 717 | .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, | 722 | .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, |
| 718 | .layout = *one_texture_pipeline_layout, | 723 | .layout = *one_texture_pipeline_layout, |
| 719 | .renderPass = renderpass, | 724 | .renderPass = renderpass, |
| @@ -723,37 +728,17 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend | |||
| 723 | }); | 728 | }); |
| 724 | } | 729 | } |
| 725 | 730 | ||
| 731 | void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | ||
| 732 | ConvertPipeline(pipeline, renderpass, false); | ||
| 733 | } | ||
| 734 | |||
| 726 | void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | 735 | void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { |
| 727 | if (pipeline) { | 736 | ConvertPipeline(pipeline, renderpass, true); |
| 728 | return; | ||
| 729 | } | ||
| 730 | const std::array stages = MakeStages(*full_screen_vert, *convert_float_to_depth_frag); | ||
| 731 | pipeline = device.GetLogical().CreateGraphicsPipeline({ | ||
| 732 | .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | ||
| 733 | .pNext = nullptr, | ||
| 734 | .flags = 0, | ||
| 735 | .stageCount = static_cast<u32>(stages.size()), | ||
| 736 | .pStages = stages.data(), | ||
| 737 | .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | ||
| 738 | .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | ||
| 739 | .pTessellationState = nullptr, | ||
| 740 | .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, | ||
| 741 | .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | ||
| 742 | .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | ||
| 743 | .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, | ||
| 744 | .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO, | ||
| 745 | .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, | ||
| 746 | .layout = *one_texture_pipeline_layout, | ||
| 747 | .renderPass = renderpass, | ||
| 748 | .subpass = 0, | ||
| 749 | .basePipelineHandle = VK_NULL_HANDLE, | ||
| 750 | .basePipelineIndex = 0, | ||
| 751 | }); | ||
| 752 | } | 737 | } |
| 753 | 738 | ||
| 754 | void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 739 | void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 755 | vk::ShaderModule& module, bool is_target_depth, | 740 | vk::ShaderModule& module, bool single_texture, |
| 756 | bool single_texture) { | 741 | bool is_target_depth) { |
| 757 | if (pipeline) { | 742 | if (pipeline) { |
| 758 | return; | 743 | return; |
| 759 | } | 744 | } |
| @@ -782,13 +767,13 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass ren | |||
| 782 | } | 767 | } |
| 783 | 768 | ||
| 784 | void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 769 | void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 785 | vk::ShaderModule& module, bool single_texture) { | 770 | vk::ShaderModule& module) { |
| 786 | ConvertPipelineEx(pipeline, renderpass, module, false, single_texture); | 771 | ConvertPipelineEx(pipeline, renderpass, module, false, false); |
| 787 | } | 772 | } |
| 788 | 773 | ||
| 789 | void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 774 | void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 790 | vk::ShaderModule& module, bool single_texture) { | 775 | vk::ShaderModule& module) { |
| 791 | ConvertPipelineEx(pipeline, renderpass, module, true, single_texture); | 776 | ConvertPipelineEx(pipeline, renderpass, module, true, true); |
| 792 | } | 777 | } |
| 793 | 778 | ||
| 794 | } // namespace Vulkan | 779 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index b1a717090..1d9f61a52 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h | |||
| @@ -44,50 +44,46 @@ public: | |||
| 44 | const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, | 44 | const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, |
| 45 | Tegra::Engines::Fermi2D::Operation operation); | 45 | Tegra::Engines::Fermi2D::Operation operation); |
| 46 | 46 | ||
| 47 | void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 47 | void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 48 | u32 up_scale, u32 down_shift); | ||
| 49 | 48 | ||
| 50 | void ConvertR32ToD32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 49 | void ConvertR32ToD32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 51 | u32 up_scale, u32 down_shift); | ||
| 52 | 50 | ||
| 53 | void ConvertD16ToR16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 51 | void ConvertD16ToR16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 54 | u32 up_scale, u32 down_shift); | ||
| 55 | 52 | ||
| 56 | void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 53 | void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 57 | u32 up_scale, u32 down_shift); | ||
| 58 | 54 | ||
| 59 | void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, | 55 | void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 60 | u32 up_scale, u32 down_shift); | ||
| 61 | 56 | ||
| 62 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, | 57 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); |
| 63 | u32 up_scale, u32 down_shift); | ||
| 64 | 58 | ||
| 65 | private: | 59 | private: |
| 66 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 60 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 67 | const ImageView& src_image_view, u32 up_scale, u32 down_shift); | 61 | const ImageView& src_image_view); |
| 68 | 62 | ||
| 69 | void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 63 | void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 70 | ImageView& src_image_view, u32 up_scale, u32 down_shift); | 64 | ImageView& src_image_view, u32 up_scale, u32 down_shift); |
| 71 | 65 | ||
| 72 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 66 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 73 | ImageView& src_image_view, u32 up_scale, u32 down_shift); | 67 | ImageView& src_image_view); |
| 74 | 68 | ||
| 75 | [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key); | 69 | [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key); |
| 76 | 70 | ||
| 77 | [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key); | 71 | [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key); |
| 78 | 72 | ||
| 73 | void ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, bool is_target_depth); | ||
| 74 | |||
| 79 | void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); | 75 | void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); |
| 80 | 76 | ||
| 81 | void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); | 77 | void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); |
| 82 | 78 | ||
| 83 | void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 79 | void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 84 | vk::ShaderModule& module, bool is_target_depth, bool single_texture); | 80 | vk::ShaderModule& module, bool single_texture, bool is_target_depth); |
| 85 | 81 | ||
| 86 | void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 82 | void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 87 | vk::ShaderModule& module, bool single_texture); | 83 | vk::ShaderModule& module); |
| 88 | 84 | ||
| 89 | void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 85 | void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 90 | vk::ShaderModule& module, bool single_texture); | 86 | vk::ShaderModule& module); |
| 91 | 87 | ||
| 92 | const Device& device; | 88 | const Device& device; |
| 93 | VKScheduler& scheduler; | 89 | VKScheduler& scheduler; |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 1e447e621..c71a1f44d 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -391,28 +391,23 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, | |||
| 391 | .offset = {0, 0}, | 391 | .offset = {0, 0}, |
| 392 | .extent = size, | 392 | .extent = size, |
| 393 | }; | 393 | }; |
| 394 | const auto filter = Settings::values.scaling_filter.GetValue(); | ||
| 395 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); | 394 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); |
| 396 | switch (filter) { | 395 | auto graphics_pipeline = [this]() { |
| 397 | case Settings::ScalingFilter::NearestNeighbor: | 396 | switch (Settings::values.scaling_filter.GetValue()) { |
| 398 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); | 397 | case Settings::ScalingFilter::NearestNeighbor: |
| 399 | break; | 398 | case Settings::ScalingFilter::Bilinear: |
| 400 | case Settings::ScalingFilter::Bilinear: | 399 | return *bilinear_pipeline; |
| 401 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); | 400 | case Settings::ScalingFilter::Bicubic: |
| 402 | break; | 401 | return *bicubic_pipeline; |
| 403 | case Settings::ScalingFilter::Bicubic: | 402 | case Settings::ScalingFilter::Gaussian: |
| 404 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bicubic_pipeline); | 403 | return *gaussian_pipeline; |
| 405 | break; | 404 | case Settings::ScalingFilter::ScaleForce: |
| 406 | case Settings::ScalingFilter::Gaussian: | 405 | return *scaleforce_pipeline; |
| 407 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *gaussian_pipeline); | 406 | default: |
| 408 | break; | 407 | return *bilinear_pipeline; |
| 409 | case Settings::ScalingFilter::ScaleForce: | 408 | } |
| 410 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *scaleforce_pipeline); | 409 | }(); |
| 411 | break; | 410 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline); |
| 412 | default: | ||
| 413 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); | ||
| 414 | break; | ||
| 415 | } | ||
| 416 | cmdbuf.SetViewport(0, viewport); | 411 | cmdbuf.SetViewport(0, viewport); |
| 417 | cmdbuf.SetScissor(0, scissor); | 412 | cmdbuf.SetScissor(0, scissor); |
| 418 | 413 | ||
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 616a7b457..d514b71d0 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -605,7 +605,11 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 605 | .flags = 0, | 605 | .flags = 0, |
| 606 | .topology = input_assembly_topology, | 606 | .topology = input_assembly_topology, |
| 607 | .primitiveRestartEnable = key.state.primitive_restart_enable != 0 && | 607 | .primitiveRestartEnable = key.state.primitive_restart_enable != 0 && |
| 608 | SupportsPrimitiveRestart(input_assembly_topology), | 608 | ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && |
| 609 | device.IsTopologyListPrimitiveRestartSupported()) || | ||
| 610 | SupportsPrimitiveRestart(input_assembly_topology) || | ||
| 611 | (input_assembly_topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && | ||
| 612 | device.IsPatchListPrimitiveRestartSupported())), | ||
| 609 | }; | 613 | }; |
| 610 | const VkPipelineTessellationStateCreateInfo tessellation_ci{ | 614 | const VkPipelineTessellationStateCreateInfo tessellation_ci{ |
| 611 | .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, | 615 | .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, |
| @@ -613,7 +617,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 613 | .flags = 0, | 617 | .flags = 0, |
| 614 | .patchControlPoints = key.state.patch_control_points_minus_one.Value() + 1, | 618 | .patchControlPoints = key.state.patch_control_points_minus_one.Value() + 1, |
| 615 | }; | 619 | }; |
| 616 | |||
| 617 | std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles; | 620 | std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles; |
| 618 | std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle); | 621 | std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle); |
| 619 | const VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{ | 622 | const VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{ |
| @@ -748,8 +751,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 748 | .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, | 751 | .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, |
| 749 | .pNext = nullptr, | 752 | .pNext = nullptr, |
| 750 | .flags = 0, | 753 | .flags = 0, |
| 751 | .logicOpEnable = VK_FALSE, | 754 | .logicOpEnable = key.state.logic_op_enable != 0, |
| 752 | .logicOp = VK_LOGIC_OP_COPY, | 755 | .logicOp = static_cast<VkLogicOp>(key.state.logic_op.Value()), |
| 753 | .attachmentCount = static_cast<u32>(cb_attachments.size()), | 756 | .attachmentCount = static_cast<u32>(cb_attachments.size()), |
| 754 | .pAttachments = cb_attachments.data(), | 757 | .pAttachments = cb_attachments.data(), |
| 755 | .blendConstants = {}, | 758 | .blendConstants = {}, |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 197cba8e3..1941170cb 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -1057,37 +1057,37 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst | |||
| 1057 | }); | 1057 | }); |
| 1058 | } | 1058 | } |
| 1059 | 1059 | ||
| 1060 | void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, | 1060 | void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) { |
| 1061 | bool rescaled) { | ||
| 1062 | const u32 up_scale = rescaled ? resolution.up_scale : 1; | ||
| 1063 | const u32 down_shift = rescaled ? resolution.down_shift : 0; | ||
| 1064 | switch (dst_view.format) { | 1061 | switch (dst_view.format) { |
| 1065 | case PixelFormat::R16_UNORM: | 1062 | case PixelFormat::R16_UNORM: |
| 1066 | if (src_view.format == PixelFormat::D16_UNORM) { | 1063 | if (src_view.format == PixelFormat::D16_UNORM) { |
| 1067 | return blit_image_helper.ConvertD16ToR16(dst, src_view, up_scale, down_shift); | 1064 | return blit_image_helper.ConvertD16ToR16(dst, src_view); |
| 1068 | } | 1065 | } |
| 1069 | break; | 1066 | break; |
| 1070 | case PixelFormat::A8B8G8R8_UNORM: | 1067 | case PixelFormat::A8B8G8R8_UNORM: |
| 1071 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { | 1068 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { |
| 1072 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view, up_scale, down_shift); | 1069 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view); |
| 1073 | } | 1070 | } |
| 1074 | break; | 1071 | break; |
| 1075 | case PixelFormat::R32_FLOAT: | 1072 | case PixelFormat::R32_FLOAT: |
| 1076 | if (src_view.format == PixelFormat::D32_FLOAT) { | 1073 | if (src_view.format == PixelFormat::D32_FLOAT) { |
| 1077 | return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift); | 1074 | return blit_image_helper.ConvertD32ToR32(dst, src_view); |
| 1078 | } | 1075 | } |
| 1079 | break; | 1076 | break; |
| 1080 | case PixelFormat::D16_UNORM: | 1077 | case PixelFormat::D16_UNORM: |
| 1081 | if (src_view.format == PixelFormat::R16_UNORM) { | 1078 | if (src_view.format == PixelFormat::R16_UNORM) { |
| 1082 | return blit_image_helper.ConvertR16ToD16(dst, src_view, up_scale, down_shift); | 1079 | return blit_image_helper.ConvertR16ToD16(dst, src_view); |
| 1083 | } | 1080 | } |
| 1084 | break; | 1081 | break; |
| 1085 | case PixelFormat::S8_UINT_D24_UNORM: | 1082 | case PixelFormat::S8_UINT_D24_UNORM: |
| 1086 | return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift); | 1083 | if (src_view.format == PixelFormat::A8B8G8R8_UNORM || |
| 1084 | src_view.format == PixelFormat::B8G8R8A8_UNORM) { | ||
| 1085 | return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view); | ||
| 1086 | } | ||
| 1087 | break; | 1087 | break; |
| 1088 | case PixelFormat::D32_FLOAT: | 1088 | case PixelFormat::D32_FLOAT: |
| 1089 | if (src_view.format == PixelFormat::R32_FLOAT) { | 1089 | if (src_view.format == PixelFormat::R32_FLOAT) { |
| 1090 | return blit_image_helper.ConvertR32ToD32(dst, src_view, up_scale, down_shift); | 1090 | return blit_image_helper.ConvertR32ToD32(dst, src_view); |
| 1091 | } | 1091 | } |
| 1092 | break; | 1092 | break; |
| 1093 | default: | 1093 | default: |
| @@ -1329,6 +1329,10 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm | |||
| 1329 | } | 1329 | } |
| 1330 | } | 1330 | } |
| 1331 | 1331 | ||
| 1332 | bool Image::IsRescaled() const noexcept { | ||
| 1333 | return True(flags & ImageFlagBits::Rescaled); | ||
| 1334 | } | ||
| 1335 | |||
| 1332 | bool Image::ScaleUp(bool ignore) { | 1336 | bool Image::ScaleUp(bool ignore) { |
| 1333 | if (True(flags & ImageFlagBits::Rescaled)) { | 1337 | if (True(flags & ImageFlagBits::Rescaled)) { |
| 1334 | return false; | 1338 | return false; |
| @@ -1469,7 +1473,8 @@ bool Image::BlitScaleHelper(bool scale_up) { | |||
| 1469 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, | 1473 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, |
| 1470 | ImageId image_id_, Image& image) | 1474 | ImageId image_id_, Image& image) |
| 1471 | : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, | 1475 | : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, |
| 1472 | image_handle{image.Handle()}, samples{ConvertSampleCount(image.info.num_samples)} { | 1476 | src_image{&image}, image_handle{image.Handle()}, |
| 1477 | samples(ConvertSampleCount(image.info.num_samples)) { | ||
| 1473 | using Shader::TextureType; | 1478 | using Shader::TextureType; |
| 1474 | 1479 | ||
| 1475 | const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); | 1480 | const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); |
| @@ -1607,6 +1612,13 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type, | |||
| 1607 | return *view; | 1612 | return *view; |
| 1608 | } | 1613 | } |
| 1609 | 1614 | ||
| 1615 | bool ImageView::IsRescaled() const noexcept { | ||
| 1616 | if (!src_image) { | ||
| 1617 | return false; | ||
| 1618 | } | ||
| 1619 | return src_image->IsRescaled(); | ||
| 1620 | } | ||
| 1621 | |||
| 1610 | vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { | 1622 | vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { |
| 1611 | return device->GetLogical().CreateImageView({ | 1623 | return device->GetLogical().CreateImageView({ |
| 1612 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, | 1624 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 753e3e8a1..c592f2666 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -65,7 +65,7 @@ public: | |||
| 65 | 65 | ||
| 66 | void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); | 66 | void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); |
| 67 | 67 | ||
| 68 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled); | 68 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view); |
| 69 | 69 | ||
| 70 | bool CanAccelerateImageUpload(Image&) const noexcept { | 70 | bool CanAccelerateImageUpload(Image&) const noexcept { |
| 71 | return false; | 71 | return false; |
| @@ -139,6 +139,8 @@ public: | |||
| 139 | return std::exchange(initialized, true); | 139 | return std::exchange(initialized, true); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | bool IsRescaled() const noexcept; | ||
| 143 | |||
| 142 | bool ScaleUp(bool ignore = false); | 144 | bool ScaleUp(bool ignore = false); |
| 143 | 145 | ||
| 144 | bool ScaleDown(bool ignore = false); | 146 | bool ScaleDown(bool ignore = false); |
| @@ -189,6 +191,8 @@ public: | |||
| 189 | [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, | 191 | [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, |
| 190 | Shader::ImageFormat image_format); | 192 | Shader::ImageFormat image_format); |
| 191 | 193 | ||
| 194 | [[nodiscard]] bool IsRescaled() const noexcept; | ||
| 195 | |||
| 192 | [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept { | 196 | [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept { |
| 193 | return *image_views[static_cast<size_t>(texture_type)]; | 197 | return *image_views[static_cast<size_t>(texture_type)]; |
| 194 | } | 198 | } |
| @@ -222,6 +226,8 @@ private: | |||
| 222 | [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); | 226 | [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); |
| 223 | 227 | ||
| 224 | const Device* device = nullptr; | 228 | const Device* device = nullptr; |
| 229 | const Image* src_image{}; | ||
| 230 | |||
| 225 | std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views; | 231 | std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views; |
| 226 | std::unique_ptr<StorageViews> storage_views; | 232 | std::unique_ptr<StorageViews> storage_views; |
| 227 | vk::ImageView depth_view; | 233 | vk::ImageView depth_view; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 5aaeb16ca..2e19fced2 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -1855,9 +1855,20 @@ void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<Imag | |||
| 1855 | .height = std::min(dst_view.size.height, src_view.size.height), | 1855 | .height = std::min(dst_view.size.height, src_view.size.height), |
| 1856 | .depth = std::min(dst_view.size.depth, src_view.size.depth), | 1856 | .depth = std::min(dst_view.size.depth, src_view.size.depth), |
| 1857 | }; | 1857 | }; |
| 1858 | UNIMPLEMENTED_IF(copy.extent != expected_size); | 1858 | const Extent3D scaled_extent = [is_rescaled, expected_size]() { |
| 1859 | if (!is_rescaled) { | ||
| 1860 | return expected_size; | ||
| 1861 | } | ||
| 1862 | const auto& resolution = Settings::values.resolution_info; | ||
| 1863 | return Extent3D{ | ||
| 1864 | .width = resolution.ScaleUp(expected_size.width), | ||
| 1865 | .height = resolution.ScaleUp(expected_size.height), | ||
| 1866 | .depth = expected_size.depth, | ||
| 1867 | }; | ||
| 1868 | }(); | ||
| 1869 | UNIMPLEMENTED_IF(copy.extent != scaled_extent); | ||
| 1859 | 1870 | ||
| 1860 | runtime.ConvertImage(dst_framebuffer, dst_view, src_view, is_rescaled); | 1871 | runtime.ConvertImage(dst_framebuffer, dst_view, src_view); |
| 1861 | } | 1872 | } |
| 1862 | } | 1873 | } |
| 1863 | 1874 | ||
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 7bf5b6578..9862b815b 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -271,7 +271,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 271 | .tessellationShader = true, | 271 | .tessellationShader = true, |
| 272 | .sampleRateShading = true, | 272 | .sampleRateShading = true, |
| 273 | .dualSrcBlend = true, | 273 | .dualSrcBlend = true, |
| 274 | .logicOp = false, | 274 | .logicOp = true, |
| 275 | .multiDrawIndirect = false, | 275 | .multiDrawIndirect = false, |
| 276 | .drawIndirectFirstInstance = false, | 276 | .drawIndirectFirstInstance = false, |
| 277 | .depthClamp = true, | 277 | .depthClamp = true, |
| @@ -433,6 +433,19 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 433 | LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes"); | 433 | LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes"); |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT primitive_topology_list_restart; | ||
| 437 | if (is_topology_list_restart_supported || is_patch_list_restart_supported) { | ||
| 438 | primitive_topology_list_restart = { | ||
| 439 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT, | ||
| 440 | .pNext = nullptr, | ||
| 441 | .primitiveTopologyListRestart = is_topology_list_restart_supported, | ||
| 442 | .primitiveTopologyPatchListRestart = is_patch_list_restart_supported, | ||
| 443 | }; | ||
| 444 | SetNext(next, primitive_topology_list_restart); | ||
| 445 | } else { | ||
| 446 | LOG_INFO(Render_Vulkan, "Device doesn't support list topology primitive restart"); | ||
| 447 | } | ||
| 448 | |||
| 436 | VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback; | 449 | VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback; |
| 437 | if (ext_transform_feedback) { | 450 | if (ext_transform_feedback) { |
| 438 | transform_feedback = { | 451 | transform_feedback = { |
| @@ -891,6 +904,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 891 | bool has_ext_provoking_vertex{}; | 904 | bool has_ext_provoking_vertex{}; |
| 892 | bool has_ext_vertex_input_dynamic_state{}; | 905 | bool has_ext_vertex_input_dynamic_state{}; |
| 893 | bool has_ext_line_rasterization{}; | 906 | bool has_ext_line_rasterization{}; |
| 907 | bool has_ext_primitive_topology_list_restart{}; | ||
| 894 | for (const std::string& extension : supported_extensions) { | 908 | for (const std::string& extension : supported_extensions) { |
| 895 | const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name, | 909 | const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name, |
| 896 | bool push) { | 910 | bool push) { |
| @@ -915,6 +929,8 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 915 | test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); | 929 | test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); |
| 916 | test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); | 930 | test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); |
| 917 | test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); | 931 | test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); |
| 932 | test(has_ext_primitive_topology_list_restart, | ||
| 933 | VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME, true); | ||
| 918 | test(ext_sampler_filter_minmax, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME, true); | 934 | test(ext_sampler_filter_minmax, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME, true); |
| 919 | test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, | 935 | test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, |
| 920 | true); | 936 | true); |
| @@ -1113,6 +1129,19 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1113 | khr_pipeline_executable_properties = true; | 1129 | khr_pipeline_executable_properties = true; |
| 1114 | } | 1130 | } |
| 1115 | } | 1131 | } |
| 1132 | if (has_ext_primitive_topology_list_restart) { | ||
| 1133 | VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT primitive_topology_list_restart{}; | ||
| 1134 | primitive_topology_list_restart.sType = | ||
| 1135 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; | ||
| 1136 | primitive_topology_list_restart.pNext = nullptr; | ||
| 1137 | features.pNext = &primitive_topology_list_restart; | ||
| 1138 | physical.GetFeatures2KHR(features); | ||
| 1139 | |||
| 1140 | is_topology_list_restart_supported = | ||
| 1141 | primitive_topology_list_restart.primitiveTopologyListRestart; | ||
| 1142 | is_patch_list_restart_supported = | ||
| 1143 | primitive_topology_list_restart.primitiveTopologyPatchListRestart; | ||
| 1144 | } | ||
| 1116 | if (has_khr_image_format_list && has_khr_swapchain_mutable_format) { | 1145 | if (has_khr_image_format_list && has_khr_swapchain_mutable_format) { |
| 1117 | extensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); | 1146 | extensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); |
| 1118 | extensions.push_back(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME); | 1147 | extensions.push_back(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME); |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 10653ac6b..4c9d86aad 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -238,6 +238,16 @@ public: | |||
| 238 | return khr_workgroup_memory_explicit_layout; | 238 | return khr_workgroup_memory_explicit_layout; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | /// Returns true if the device supports VK_EXT_primitive_topology_list_restart. | ||
| 242 | bool IsTopologyListPrimitiveRestartSupported() const { | ||
| 243 | return is_topology_list_restart_supported; | ||
| 244 | } | ||
| 245 | |||
| 246 | /// Returns true if the device supports VK_EXT_primitive_topology_list_restart. | ||
| 247 | bool IsPatchListPrimitiveRestartSupported() const { | ||
| 248 | return is_patch_list_restart_supported; | ||
| 249 | } | ||
| 250 | |||
| 241 | /// Returns true if the device supports VK_EXT_index_type_uint8. | 251 | /// Returns true if the device supports VK_EXT_index_type_uint8. |
| 242 | bool IsExtIndexTypeUint8Supported() const { | 252 | bool IsExtIndexTypeUint8Supported() const { |
| 243 | return ext_index_type_uint8; | 253 | return ext_index_type_uint8; |
| @@ -401,6 +411,9 @@ private: | |||
| 401 | bool is_shader_int16_supported{}; ///< Support for int16. | 411 | bool is_shader_int16_supported{}; ///< Support for int16. |
| 402 | bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images. | 412 | bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images. |
| 403 | bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil. | 413 | bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil. |
| 414 | bool is_topology_list_restart_supported{}; ///< Support for primitive restart with list | ||
| 415 | ///< topologies. | ||
| 416 | bool is_patch_list_restart_supported{}; ///< Support for primitive restart with list patch. | ||
| 404 | bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. | 417 | bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. |
| 405 | bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2. | 418 | bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2. |
| 406 | bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough. | 419 | bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough. |
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp index c5685db2e..c6222b571 100644 --- a/src/yuzu/applets/qt_controller.cpp +++ b/src/yuzu/applets/qt_controller.cpp | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #include "core/hid/emulated_controller.h" | 12 | #include "core/hid/emulated_controller.h" |
| 13 | #include "core/hid/hid_core.h" | 13 | #include "core/hid/hid_core.h" |
| 14 | #include "core/hid/hid_types.h" | 14 | #include "core/hid/hid_types.h" |
| 15 | #include "core/hle/lock.h" | ||
| 16 | #include "core/hle/service/hid/controllers/npad.h" | 15 | #include "core/hle/service/hid/controllers/npad.h" |
| 17 | #include "core/hle/service/hid/hid.h" | 16 | #include "core/hle/service/hid/hid.h" |
| 18 | #include "core/hle/service/sm/sm.h" | 17 | #include "core/hle/service/sm/sm.h" |
| @@ -664,7 +663,5 @@ void QtControllerSelector::ReconfigureControllers( | |||
| 664 | } | 663 | } |
| 665 | 664 | ||
| 666 | void QtControllerSelector::MainWindowReconfigureFinished() { | 665 | void QtControllerSelector::MainWindowReconfigureFinished() { |
| 667 | // Acquire the HLE mutex | ||
| 668 | std::lock_guard lock(HLE::g_hle_lock); | ||
| 669 | callback(); | 666 | callback(); |
| 670 | } | 667 | } |
diff --git a/src/yuzu/applets/qt_error.cpp b/src/yuzu/applets/qt_error.cpp index 45cf64603..879e73660 100644 --- a/src/yuzu/applets/qt_error.cpp +++ b/src/yuzu/applets/qt_error.cpp | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <QDateTime> | 5 | #include <QDateTime> |
| 6 | #include "core/hle/lock.h" | ||
| 7 | #include "yuzu/applets/qt_error.h" | 6 | #include "yuzu/applets/qt_error.h" |
| 8 | #include "yuzu/main.h" | 7 | #include "yuzu/main.h" |
| 9 | 8 | ||
| @@ -57,7 +56,5 @@ void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_te | |||
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | void QtErrorDisplay::MainWindowFinishedError() { | 58 | void QtErrorDisplay::MainWindowFinishedError() { |
| 60 | // Acquire the HLE mutex | ||
| 61 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 62 | callback(); | 59 | callback(); |
| 63 | } | 60 | } |
diff --git a/src/yuzu/applets/qt_profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp index 7b19f1f8d..5b32da923 100644 --- a/src/yuzu/applets/qt_profile_select.cpp +++ b/src/yuzu/applets/qt_profile_select.cpp | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include "common/fs/path_util.h" | 14 | #include "common/fs/path_util.h" |
| 15 | #include "common/string_util.h" | 15 | #include "common/string_util.h" |
| 16 | #include "core/constants.h" | 16 | #include "core/constants.h" |
| 17 | #include "core/hle/lock.h" | ||
| 18 | #include "yuzu/applets/qt_profile_select.h" | 17 | #include "yuzu/applets/qt_profile_select.h" |
| 19 | #include "yuzu/main.h" | 18 | #include "yuzu/main.h" |
| 20 | #include "yuzu/util/controller_navigation.h" | 19 | #include "yuzu/util/controller_navigation.h" |
| @@ -170,7 +169,5 @@ void QtProfileSelector::SelectProfile( | |||
| 170 | } | 169 | } |
| 171 | 170 | ||
| 172 | void QtProfileSelector::MainWindowFinishedSelection(std::optional<Common::UUID> uuid) { | 171 | void QtProfileSelector::MainWindowFinishedSelection(std::optional<Common::UUID> uuid) { |
| 173 | // Acquire the HLE mutex | ||
| 174 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 175 | callback(uuid); | 172 | callback(uuid); |
| 176 | } | 173 | } |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index b7bb43348..a7271e075 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -2546,39 +2546,30 @@ void GMainWindow::ToggleFullscreen() { | |||
| 2546 | } | 2546 | } |
| 2547 | 2547 | ||
| 2548 | void GMainWindow::ShowFullscreen() { | 2548 | void GMainWindow::ShowFullscreen() { |
| 2549 | const auto show_fullscreen = [](QWidget* window) { | ||
| 2550 | if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { | ||
| 2551 | window->showFullScreen(); | ||
| 2552 | return; | ||
| 2553 | } | ||
| 2554 | window->hide(); | ||
| 2555 | window->setWindowFlags(window->windowFlags() | Qt::FramelessWindowHint); | ||
| 2556 | const auto screen_geometry = QApplication::desktop()->screenGeometry(window); | ||
| 2557 | window->setGeometry(screen_geometry.x(), screen_geometry.y(), screen_geometry.width(), | ||
| 2558 | screen_geometry.height() + 1); | ||
| 2559 | window->raise(); | ||
| 2560 | window->showNormal(); | ||
| 2561 | }; | ||
| 2562 | |||
| 2549 | if (ui->action_Single_Window_Mode->isChecked()) { | 2563 | if (ui->action_Single_Window_Mode->isChecked()) { |
| 2550 | UISettings::values.geometry = saveGeometry(); | 2564 | UISettings::values.geometry = saveGeometry(); |
| 2551 | 2565 | ||
| 2552 | ui->menubar->hide(); | 2566 | ui->menubar->hide(); |
| 2553 | statusBar()->hide(); | 2567 | statusBar()->hide(); |
| 2554 | 2568 | ||
| 2555 | if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { | 2569 | show_fullscreen(this); |
| 2556 | showFullScreen(); | ||
| 2557 | return; | ||
| 2558 | } | ||
| 2559 | |||
| 2560 | hide(); | ||
| 2561 | setWindowFlags(windowFlags() | Qt::FramelessWindowHint); | ||
| 2562 | const auto screen_geometry = QApplication::desktop()->screenGeometry(this); | ||
| 2563 | setGeometry(screen_geometry.x(), screen_geometry.y(), screen_geometry.width(), | ||
| 2564 | screen_geometry.height() + 1); | ||
| 2565 | raise(); | ||
| 2566 | showNormal(); | ||
| 2567 | } else { | 2570 | } else { |
| 2568 | UISettings::values.renderwindow_geometry = render_window->saveGeometry(); | 2571 | UISettings::values.renderwindow_geometry = render_window->saveGeometry(); |
| 2569 | 2572 | show_fullscreen(render_window); | |
| 2570 | if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { | ||
| 2571 | render_window->showFullScreen(); | ||
| 2572 | return; | ||
| 2573 | } | ||
| 2574 | |||
| 2575 | render_window->hide(); | ||
| 2576 | render_window->setWindowFlags(windowFlags() | Qt::FramelessWindowHint); | ||
| 2577 | const auto screen_geometry = QApplication::desktop()->screenGeometry(this); | ||
| 2578 | render_window->setGeometry(screen_geometry.x(), screen_geometry.y(), | ||
| 2579 | screen_geometry.width(), screen_geometry.height() + 1); | ||
| 2580 | render_window->raise(); | ||
| 2581 | render_window->showNormal(); | ||
| 2582 | } | 2573 | } |
| 2583 | } | 2574 | } |
| 2584 | 2575 | ||