diff options
33 files changed, 370 insertions, 130 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 467d769a2..c906c5a50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -164,7 +164,7 @@ if (ENABLE_SDL2) | |||
| 164 | set(SDL2_LIBRARIES "SDL2::SDL2") | 164 | set(SDL2_LIBRARIES "SDL2::SDL2") |
| 165 | endif() | 165 | endif() |
| 166 | 166 | ||
| 167 | include_directories(${SDL2_INCLUDE_DIRS}) | 167 | include_directories(SYSTEM ${SDL2_INCLUDE_DIRS}) |
| 168 | add_library(SDL2 INTERFACE) | 168 | add_library(SDL2 INTERFACE) |
| 169 | target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}") | 169 | target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}") |
| 170 | endif() | 170 | endif() |
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index d4421f697..653c64f47 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt | |||
| @@ -16,11 +16,11 @@ add_library(catch-single-include INTERFACE) | |||
| 16 | target_include_directories(catch-single-include INTERFACE catch/single_include) | 16 | target_include_directories(catch-single-include INTERFACE catch/single_include) |
| 17 | 17 | ||
| 18 | # libfmt | 18 | # libfmt |
| 19 | pkg_check_modules(FMT IMPORTED_TARGET GLOBAL fmt>=6.1.0) | 19 | pkg_check_modules(FMT IMPORTED_TARGET GLOBAL fmt>=6.2.0) |
| 20 | if (FMT_FOUND) | 20 | if (FMT_FOUND) |
| 21 | add_library(fmt::fmt ALIAS PkgConfig::FMT) | 21 | add_library(fmt::fmt ALIAS PkgConfig::FMT) |
| 22 | else() | 22 | else() |
| 23 | message(STATUS "fmt 6.1.0 or newer not found, falling back to externals") | 23 | message(STATUS "fmt 6.2.0 or newer not found, falling back to externals") |
| 24 | add_subdirectory(fmt) | 24 | add_subdirectory(fmt) |
| 25 | add_library(fmt::fmt ALIAS fmt) | 25 | add_library(fmt::fmt ALIAS fmt) |
| 26 | endif() | 26 | endif() |
diff --git a/externals/fmt b/externals/fmt | |||
| Subproject 4b8f8fac96a7819f28f4be523ca10a2d5d8aaaf | Subproject 9bdd1596cef1b57b9556f8bef32dc4a32322ef3 | ||
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 7f613891b..45b750e1e 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp | |||
| @@ -888,7 +888,14 @@ std::string SanitizePath(std::string_view path_, DirectorySeparator directory_se | |||
| 888 | } | 888 | } |
| 889 | 889 | ||
| 890 | std::replace(path.begin(), path.end(), type1, type2); | 890 | std::replace(path.begin(), path.end(), type1, type2); |
| 891 | path.erase(std::unique(path.begin(), path.end(), | 891 | |
| 892 | auto start = path.begin(); | ||
| 893 | #ifdef _WIN32 | ||
| 894 | // allow network paths which start with a double backslash (e.g. \\server\share) | ||
| 895 | if (start != path.end()) | ||
| 896 | ++start; | ||
| 897 | #endif | ||
| 898 | path.erase(std::unique(start, path.end(), | ||
| 892 | [type2](char c1, char c2) { return c1 == type2 && c2 == type2; }), | 899 | [type2](char c1, char c2) { return c1 == type2 && c2 == type2; }), |
| 893 | path.end()); | 900 | path.end()); |
| 894 | return std::string(RemoveTrailingSlash(path)); | 901 | return std::string(RemoveTrailingSlash(path)); |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index d65dae3ae..91d94025c 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -282,19 +282,19 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { | |||
| 282 | return RESULT_SUCCESS; | 282 | return RESULT_SUCCESS; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const { | 285 | std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { |
| 286 | std::vector<u8> buffer; | 286 | std::vector<u8> buffer; |
| 287 | const bool is_buffer_a{BufferDescriptorA().size() > std::size_t(buffer_index) && | 287 | const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && |
| 288 | BufferDescriptorA()[buffer_index].Size()}; | 288 | BufferDescriptorA()[buffer_index].Size()}; |
| 289 | auto& memory = Core::System::GetInstance().Memory(); | 289 | auto& memory = Core::System::GetInstance().Memory(); |
| 290 | 290 | ||
| 291 | if (is_buffer_a) { | 291 | if (is_buffer_a) { |
| 292 | ASSERT_MSG(BufferDescriptorA().size() > std::size_t(buffer_index), | 292 | ASSERT_MSG(BufferDescriptorA().size() > buffer_index, |
| 293 | "BufferDescriptorA invalid buffer_index {}", buffer_index); | 293 | "BufferDescriptorA invalid buffer_index {}", buffer_index); |
| 294 | buffer.resize(BufferDescriptorA()[buffer_index].Size()); | 294 | buffer.resize(BufferDescriptorA()[buffer_index].Size()); |
| 295 | memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size()); | 295 | memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size()); |
| 296 | } else { | 296 | } else { |
| 297 | ASSERT_MSG(BufferDescriptorX().size() > std::size_t(buffer_index), | 297 | ASSERT_MSG(BufferDescriptorX().size() > buffer_index, |
| 298 | "BufferDescriptorX invalid buffer_index {}", buffer_index); | 298 | "BufferDescriptorX invalid buffer_index {}", buffer_index); |
| 299 | buffer.resize(BufferDescriptorX()[buffer_index].Size()); | 299 | buffer.resize(BufferDescriptorX()[buffer_index].Size()); |
| 300 | memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size()); | 300 | memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size()); |
| @@ -304,13 +304,13 @@ std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const { | |||
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, | 306 | std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, |
| 307 | int buffer_index) const { | 307 | std::size_t buffer_index) const { |
| 308 | if (size == 0) { | 308 | if (size == 0) { |
| 309 | LOG_WARNING(Core, "skip empty buffer write"); | 309 | LOG_WARNING(Core, "skip empty buffer write"); |
| 310 | return 0; | 310 | return 0; |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | const bool is_buffer_b{BufferDescriptorB().size() > std::size_t(buffer_index) && | 313 | const bool is_buffer_b{BufferDescriptorB().size() > buffer_index && |
| 314 | BufferDescriptorB()[buffer_index].Size()}; | 314 | BufferDescriptorB()[buffer_index].Size()}; |
| 315 | const std::size_t buffer_size{GetWriteBufferSize(buffer_index)}; | 315 | const std::size_t buffer_size{GetWriteBufferSize(buffer_index)}; |
| 316 | if (size > buffer_size) { | 316 | if (size > buffer_size) { |
| @@ -321,13 +321,13 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, | |||
| 321 | 321 | ||
| 322 | auto& memory = Core::System::GetInstance().Memory(); | 322 | auto& memory = Core::System::GetInstance().Memory(); |
| 323 | if (is_buffer_b) { | 323 | if (is_buffer_b) { |
| 324 | ASSERT_MSG(BufferDescriptorB().size() > std::size_t(buffer_index), | 324 | ASSERT_MSG(BufferDescriptorB().size() > buffer_index, |
| 325 | "BufferDescriptorB invalid buffer_index {}", buffer_index); | 325 | "BufferDescriptorB invalid buffer_index {}", buffer_index); |
| 326 | ASSERT_MSG(BufferDescriptorB()[buffer_index].Size() >= size, | 326 | ASSERT_MSG(BufferDescriptorB()[buffer_index].Size() >= size, |
| 327 | "BufferDescriptorB buffer_index {} is not large enough", buffer_index); | 327 | "BufferDescriptorB buffer_index {} is not large enough", buffer_index); |
| 328 | memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); | 328 | memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); |
| 329 | } else { | 329 | } else { |
| 330 | ASSERT_MSG(BufferDescriptorC().size() > std::size_t(buffer_index), | 330 | ASSERT_MSG(BufferDescriptorC().size() > buffer_index, |
| 331 | "BufferDescriptorC invalid buffer_index {}", buffer_index); | 331 | "BufferDescriptorC invalid buffer_index {}", buffer_index); |
| 332 | ASSERT_MSG(BufferDescriptorC()[buffer_index].Size() >= size, | 332 | ASSERT_MSG(BufferDescriptorC()[buffer_index].Size() >= size, |
| 333 | "BufferDescriptorC buffer_index {} is not large enough", buffer_index); | 333 | "BufferDescriptorC buffer_index {} is not large enough", buffer_index); |
| @@ -337,17 +337,17 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, | |||
| 337 | return size; | 337 | return size; |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { | 340 | std::size_t HLERequestContext::GetReadBufferSize(std::size_t buffer_index) const { |
| 341 | const bool is_buffer_a{BufferDescriptorA().size() > std::size_t(buffer_index) && | 341 | const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && |
| 342 | BufferDescriptorA()[buffer_index].Size()}; | 342 | BufferDescriptorA()[buffer_index].Size()}; |
| 343 | if (is_buffer_a) { | 343 | if (is_buffer_a) { |
| 344 | ASSERT_MSG(BufferDescriptorA().size() > std::size_t(buffer_index), | 344 | ASSERT_MSG(BufferDescriptorA().size() > buffer_index, |
| 345 | "BufferDescriptorA invalid buffer_index {}", buffer_index); | 345 | "BufferDescriptorA invalid buffer_index {}", buffer_index); |
| 346 | ASSERT_MSG(BufferDescriptorA()[buffer_index].Size() > 0, | 346 | ASSERT_MSG(BufferDescriptorA()[buffer_index].Size() > 0, |
| 347 | "BufferDescriptorA buffer_index {} is empty", buffer_index); | 347 | "BufferDescriptorA buffer_index {} is empty", buffer_index); |
| 348 | return BufferDescriptorA()[buffer_index].Size(); | 348 | return BufferDescriptorA()[buffer_index].Size(); |
| 349 | } else { | 349 | } else { |
| 350 | ASSERT_MSG(BufferDescriptorX().size() > std::size_t(buffer_index), | 350 | ASSERT_MSG(BufferDescriptorX().size() > buffer_index, |
| 351 | "BufferDescriptorX invalid buffer_index {}", buffer_index); | 351 | "BufferDescriptorX invalid buffer_index {}", buffer_index); |
| 352 | ASSERT_MSG(BufferDescriptorX()[buffer_index].Size() > 0, | 352 | ASSERT_MSG(BufferDescriptorX()[buffer_index].Size() > 0, |
| 353 | "BufferDescriptorX buffer_index {} is empty", buffer_index); | 353 | "BufferDescriptorX buffer_index {} is empty", buffer_index); |
| @@ -355,15 +355,15 @@ std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { | |||
| 355 | } | 355 | } |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | std::size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const { | 358 | std::size_t HLERequestContext::GetWriteBufferSize(std::size_t buffer_index) const { |
| 359 | const bool is_buffer_b{BufferDescriptorB().size() > std::size_t(buffer_index) && | 359 | const bool is_buffer_b{BufferDescriptorB().size() > buffer_index && |
| 360 | BufferDescriptorB()[buffer_index].Size()}; | 360 | BufferDescriptorB()[buffer_index].Size()}; |
| 361 | if (is_buffer_b) { | 361 | if (is_buffer_b) { |
| 362 | ASSERT_MSG(BufferDescriptorB().size() > std::size_t(buffer_index), | 362 | ASSERT_MSG(BufferDescriptorB().size() > buffer_index, |
| 363 | "BufferDescriptorB invalid buffer_index {}", buffer_index); | 363 | "BufferDescriptorB invalid buffer_index {}", buffer_index); |
| 364 | return BufferDescriptorB()[buffer_index].Size(); | 364 | return BufferDescriptorB()[buffer_index].Size(); |
| 365 | } else { | 365 | } else { |
| 366 | ASSERT_MSG(BufferDescriptorC().size() > std::size_t(buffer_index), | 366 | ASSERT_MSG(BufferDescriptorC().size() > buffer_index, |
| 367 | "BufferDescriptorC invalid buffer_index {}", buffer_index); | 367 | "BufferDescriptorC invalid buffer_index {}", buffer_index); |
| 368 | return BufferDescriptorC()[buffer_index].Size(); | 368 | return BufferDescriptorC()[buffer_index].Size(); |
| 369 | } | 369 | } |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 050ad8fd7..af3330297 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -179,10 +179,11 @@ public: | |||
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | /// Helper function to read a buffer using the appropriate buffer descriptor | 181 | /// Helper function to read a buffer using the appropriate buffer descriptor |
| 182 | std::vector<u8> ReadBuffer(int buffer_index = 0) const; | 182 | std::vector<u8> ReadBuffer(std::size_t buffer_index = 0) const; |
| 183 | 183 | ||
| 184 | /// Helper function to write a buffer using the appropriate buffer descriptor | 184 | /// Helper function to write a buffer using the appropriate buffer descriptor |
| 185 | std::size_t WriteBuffer(const void* buffer, std::size_t size, int buffer_index = 0) const; | 185 | std::size_t WriteBuffer(const void* buffer, std::size_t size, |
| 186 | std::size_t buffer_index = 0) const; | ||
| 186 | 187 | ||
| 187 | /* Helper function to write a buffer using the appropriate buffer descriptor | 188 | /* Helper function to write a buffer using the appropriate buffer descriptor |
| 188 | * | 189 | * |
| @@ -194,7 +195,8 @@ public: | |||
| 194 | */ | 195 | */ |
| 195 | template <typename ContiguousContainer, | 196 | template <typename ContiguousContainer, |
| 196 | typename = std::enable_if_t<!std::is_pointer_v<ContiguousContainer>>> | 197 | typename = std::enable_if_t<!std::is_pointer_v<ContiguousContainer>>> |
| 197 | std::size_t WriteBuffer(const ContiguousContainer& container, int buffer_index = 0) const { | 198 | std::size_t WriteBuffer(const ContiguousContainer& container, |
| 199 | std::size_t buffer_index = 0) const { | ||
| 198 | using ContiguousType = typename ContiguousContainer::value_type; | 200 | using ContiguousType = typename ContiguousContainer::value_type; |
| 199 | 201 | ||
| 200 | static_assert(std::is_trivially_copyable_v<ContiguousType>, | 202 | static_assert(std::is_trivially_copyable_v<ContiguousType>, |
| @@ -205,10 +207,10 @@ public: | |||
| 205 | } | 207 | } |
| 206 | 208 | ||
| 207 | /// Helper function to get the size of the input buffer | 209 | /// Helper function to get the size of the input buffer |
| 208 | std::size_t GetReadBufferSize(int buffer_index = 0) const; | 210 | std::size_t GetReadBufferSize(std::size_t buffer_index = 0) const; |
| 209 | 211 | ||
| 210 | /// Helper function to get the size of the output buffer | 212 | /// Helper function to get the size of the output buffer |
| 211 | std::size_t GetWriteBufferSize(int buffer_index = 0) const; | 213 | std::size_t GetWriteBufferSize(std::size_t buffer_index = 0) const; |
| 212 | 214 | ||
| 213 | template <typename T> | 215 | template <typename T> |
| 214 | std::shared_ptr<T> GetCopyObject(std::size_t index) { | 216 | std::shared_ptr<T> GetCopyObject(std::size_t index) { |
diff --git a/src/core/hle/kernel/memory/slab_heap.h b/src/core/hle/kernel/memory/slab_heap.h index 049403e15..be95fc3f7 100644 --- a/src/core/hle/kernel/memory/slab_heap.h +++ b/src/core/hle/kernel/memory/slab_heap.h | |||
| @@ -51,7 +51,7 @@ public: | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | void Free(void* obj) { | 53 | void Free(void* obj) { |
| 54 | Node* node = reinterpret_cast<Node*>(obj); | 54 | Node* node = static_cast<Node*>(obj); |
| 55 | 55 | ||
| 56 | Node* cur_head = head.load(); | 56 | Node* cur_head = head.load(); |
| 57 | do { | 57 | do { |
| @@ -145,7 +145,7 @@ public: | |||
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | T* Allocate() { | 147 | T* Allocate() { |
| 148 | T* obj = reinterpret_cast<T*>(AllocateImpl()); | 148 | T* obj = static_cast<T*>(AllocateImpl()); |
| 149 | if (obj != nullptr) { | 149 | if (obj != nullptr) { |
| 150 | new (obj) T(); | 150 | new (obj) T(); |
| 151 | } | 151 | } |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 557608e76..3ece2cf3c 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -903,7 +903,7 @@ private: | |||
| 903 | void PopOutData(Kernel::HLERequestContext& ctx) { | 903 | void PopOutData(Kernel::HLERequestContext& ctx) { |
| 904 | LOG_DEBUG(Service_AM, "called"); | 904 | LOG_DEBUG(Service_AM, "called"); |
| 905 | 905 | ||
| 906 | const auto storage = applet->GetBroker().PopNormalDataToGame(); | 906 | auto storage = applet->GetBroker().PopNormalDataToGame(); |
| 907 | if (storage == nullptr) { | 907 | if (storage == nullptr) { |
| 908 | LOG_ERROR(Service_AM, | 908 | LOG_ERROR(Service_AM, |
| 909 | "storage is a nullptr. There is no data in the current normal channel"); | 909 | "storage is a nullptr. There is no data in the current normal channel"); |
| @@ -934,7 +934,7 @@ private: | |||
| 934 | void PopInteractiveOutData(Kernel::HLERequestContext& ctx) { | 934 | void PopInteractiveOutData(Kernel::HLERequestContext& ctx) { |
| 935 | LOG_DEBUG(Service_AM, "called"); | 935 | LOG_DEBUG(Service_AM, "called"); |
| 936 | 936 | ||
| 937 | const auto storage = applet->GetBroker().PopInteractiveDataToGame(); | 937 | auto storage = applet->GetBroker().PopInteractiveDataToGame(); |
| 938 | if (storage == nullptr) { | 938 | if (storage == nullptr) { |
| 939 | LOG_ERROR(Service_AM, | 939 | LOG_ERROR(Service_AM, |
| 940 | "storage is a nullptr. There is no data in the current interactive channel"); | 940 | "storage is a nullptr. There is no data in the current interactive channel"); |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 175cabf45..851433595 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -252,8 +252,6 @@ private: | |||
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | void GetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { | 254 | void GetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { |
| 255 | IPC::RequestParser rp{ctx}; | ||
| 256 | |||
| 257 | const auto device_name_buffer = ctx.ReadBuffer(); | 255 | const auto device_name_buffer = ctx.ReadBuffer(); |
| 258 | const std::string name = Common::StringFromBuffer(device_name_buffer); | 256 | const std::string name = Common::StringFromBuffer(device_name_buffer); |
| 259 | 257 | ||
diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp index df00ae625..86f36915a 100644 --- a/src/core/hle/service/es/es.cpp +++ b/src/core/hle/service/es/es.cpp | |||
| @@ -76,7 +76,6 @@ private: | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | void ImportTicket(Kernel::HLERequestContext& ctx) { | 78 | void ImportTicket(Kernel::HLERequestContext& ctx) { |
| 79 | IPC::RequestParser rp{ctx}; | ||
| 80 | const auto ticket = ctx.ReadBuffer(); | 79 | const auto ticket = ctx.ReadBuffer(); |
| 81 | const auto cert = ctx.ReadBuffer(1); | 80 | const auto cert = ctx.ReadBuffer(1); |
| 82 | 81 | ||
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index c1e32b28c..2ccfffc19 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -107,6 +107,7 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { | |||
| 107 | switch (controller_type) { | 107 | switch (controller_type) { |
| 108 | case NPadControllerType::None: | 108 | case NPadControllerType::None: |
| 109 | UNREACHABLE(); | 109 | UNREACHABLE(); |
| 110 | break; | ||
| 110 | case NPadControllerType::Handheld: | 111 | case NPadControllerType::Handheld: |
| 111 | controller.joy_styles.handheld.Assign(1); | 112 | controller.joy_styles.handheld.Assign(1); |
| 112 | controller.device_type.handheld.Assign(1); | 113 | controller.device_type.handheld.Assign(1); |
| @@ -363,6 +364,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 363 | switch (controller_type) { | 364 | switch (controller_type) { |
| 364 | case NPadControllerType::None: | 365 | case NPadControllerType::None: |
| 365 | UNREACHABLE(); | 366 | UNREACHABLE(); |
| 367 | break; | ||
| 366 | case NPadControllerType::Handheld: | 368 | case NPadControllerType::Handheld: |
| 367 | handheld_entry.connection_status.raw = 0; | 369 | handheld_entry.connection_status.raw = 0; |
| 368 | handheld_entry.connection_status.IsWired.Assign(1); | 370 | handheld_entry.connection_status.IsWired.Assign(1); |
diff --git a/src/core/hle/service/time/standard_network_system_clock_core.h b/src/core/hle/service/time/standard_network_system_clock_core.h index 3f505c37c..c993bdf79 100644 --- a/src/core/hle/service/time/standard_network_system_clock_core.h +++ b/src/core/hle/service/time/standard_network_system_clock_core.h | |||
| @@ -23,7 +23,7 @@ public: | |||
| 23 | standard_network_clock_sufficient_accuracy = value; | 23 | standard_network_clock_sufficient_accuracy = value; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) { | 26 | bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) const { |
| 27 | SystemClockContext context{}; | 27 | SystemClockContext context{}; |
| 28 | if (GetClockContext(system, context) != RESULT_SUCCESS) { | 28 | if (GetClockContext(system, context) != RESULT_SUCCESS) { |
| 29 | return {}; | 29 | return {}; |
diff --git a/src/core/hle/service/time/steady_clock_core.h b/src/core/hle/service/time/steady_clock_core.h index 84af3d105..d80a2385f 100644 --- a/src/core/hle/service/time/steady_clock_core.h +++ b/src/core/hle/service/time/steady_clock_core.h | |||
| @@ -16,6 +16,7 @@ namespace Service::Time::Clock { | |||
| 16 | class SteadyClockCore { | 16 | class SteadyClockCore { |
| 17 | public: | 17 | public: |
| 18 | SteadyClockCore() = default; | 18 | SteadyClockCore() = default; |
| 19 | virtual ~SteadyClockCore() = default; | ||
| 19 | 20 | ||
| 20 | const Common::UUID& GetClockSourceId() const { | 21 | const Common::UUID& GetClockSourceId() const { |
| 21 | return clock_source_id; | 22 | return clock_source_id; |
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h index 6260de6c3..2b0fa7e75 100644 --- a/src/core/hle/service/time/system_clock_context_update_callback.h +++ b/src/core/hle/service/time/system_clock_context_update_callback.h | |||
| @@ -20,7 +20,7 @@ namespace Service::Time::Clock { | |||
| 20 | class SystemClockContextUpdateCallback { | 20 | class SystemClockContextUpdateCallback { |
| 21 | public: | 21 | public: |
| 22 | SystemClockContextUpdateCallback(); | 22 | SystemClockContextUpdateCallback(); |
| 23 | ~SystemClockContextUpdateCallback(); | 23 | virtual ~SystemClockContextUpdateCallback(); |
| 24 | 24 | ||
| 25 | bool NeedUpdate(const SystemClockContext& value) const; | 25 | bool NeedUpdate(const SystemClockContext& value) const; |
| 26 | 26 | ||
diff --git a/src/core/hle/service/time/system_clock_core.cpp b/src/core/hle/service/time/system_clock_core.cpp index 1a3ab8cfa..d31d4e2ca 100644 --- a/src/core/hle/service/time/system_clock_core.cpp +++ b/src/core/hle/service/time/system_clock_core.cpp | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | namespace Service::Time::Clock { | 9 | namespace Service::Time::Clock { |
| 10 | 10 | ||
| 11 | SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core) | 11 | SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core) |
| 12 | : steady_clock_core{steady_clock_core}, is_initialized{} { | 12 | : steady_clock_core{steady_clock_core} { |
| 13 | context.steady_time_point.clock_source_id = steady_clock_core.GetClockSourceId(); | 13 | context.steady_time_point.clock_source_id = steady_clock_core.GetClockSourceId(); |
| 14 | } | 14 | } |
| 15 | 15 | ||
diff --git a/src/core/hle/service/time/system_clock_core.h b/src/core/hle/service/time/system_clock_core.h index 54407a6c5..608dd3b2e 100644 --- a/src/core/hle/service/time/system_clock_core.h +++ b/src/core/hle/service/time/system_clock_core.h | |||
| @@ -22,7 +22,7 @@ class SystemClockContextUpdateCallback; | |||
| 22 | class SystemClockCore { | 22 | class SystemClockCore { |
| 23 | public: | 23 | public: |
| 24 | explicit SystemClockCore(SteadyClockCore& steady_clock_core); | 24 | explicit SystemClockCore(SteadyClockCore& steady_clock_core); |
| 25 | ~SystemClockCore(); | 25 | virtual ~SystemClockCore(); |
| 26 | 26 | ||
| 27 | SteadyClockCore& GetSteadyClockCore() const { | 27 | SteadyClockCore& GetSteadyClockCore() const { |
| 28 | return steady_clock_core; | 28 | return steady_clock_core; |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 612ff9bf6..575330a86 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -37,7 +37,7 @@ static_assert(sizeof(MODHeader) == 0x1c, "MODHeader has incorrect size."); | |||
| 37 | 37 | ||
| 38 | std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data, | 38 | std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data, |
| 39 | const NSOSegmentHeader& header) { | 39 | const NSOSegmentHeader& header) { |
| 40 | const std::vector<u8> uncompressed_data = | 40 | std::vector<u8> uncompressed_data = |
| 41 | Common::Compression::DecompressDataLZ4(compressed_data, header.size); | 41 | Common::Compression::DecompressDataLZ4(compressed_data, header.size); |
| 42 | 42 | ||
| 43 | ASSERT_MSG(uncompressed_data.size() == header.size, "{} != {}", header.size, | 43 | ASSERT_MSG(uncompressed_data.size() == header.size, "{} != {}", header.size, |
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 713c14182..0b77afc71 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Tegra { | 13 | namespace Tegra { |
| 14 | 14 | ||
| 15 | DmaPusher::DmaPusher(GPU& gpu) : gpu(gpu) {} | 15 | DmaPusher::DmaPusher(Core::System& system, GPU& gpu) : gpu{gpu}, system{system} {} |
| 16 | 16 | ||
| 17 | DmaPusher::~DmaPusher() = default; | 17 | DmaPusher::~DmaPusher() = default; |
| 18 | 18 | ||
| @@ -26,7 +26,7 @@ void DmaPusher::DispatchCalls() { | |||
| 26 | 26 | ||
| 27 | dma_pushbuffer_subindex = 0; | 27 | dma_pushbuffer_subindex = 0; |
| 28 | 28 | ||
| 29 | while (Core::System::GetInstance().IsPoweredOn()) { | 29 | while (system.IsPoweredOn()) { |
| 30 | if (!Step()) { | 30 | if (!Step()) { |
| 31 | break; | 31 | break; |
| 32 | } | 32 | } |
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index 6ab06518f..d6188614a 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h | |||
| @@ -10,6 +10,10 @@ | |||
| 10 | #include "common/bit_field.h" | 10 | #include "common/bit_field.h" |
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | 12 | ||
| 13 | namespace Core { | ||
| 14 | class System; | ||
| 15 | } | ||
| 16 | |||
| 13 | namespace Tegra { | 17 | namespace Tegra { |
| 14 | 18 | ||
| 15 | enum class SubmissionMode : u32 { | 19 | enum class SubmissionMode : u32 { |
| @@ -56,7 +60,7 @@ using CommandList = std::vector<Tegra::CommandListHeader>; | |||
| 56 | */ | 60 | */ |
| 57 | class DmaPusher { | 61 | class DmaPusher { |
| 58 | public: | 62 | public: |
| 59 | explicit DmaPusher(GPU& gpu); | 63 | explicit DmaPusher(Core::System& system, GPU& gpu); |
| 60 | ~DmaPusher(); | 64 | ~DmaPusher(); |
| 61 | 65 | ||
| 62 | void Push(CommandList&& entries) { | 66 | void Push(CommandList&& entries) { |
| @@ -72,8 +76,6 @@ private: | |||
| 72 | 76 | ||
| 73 | void CallMethod(u32 argument) const; | 77 | void CallMethod(u32 argument) const; |
| 74 | 78 | ||
| 75 | GPU& gpu; | ||
| 76 | |||
| 77 | std::vector<CommandHeader> command_headers; ///< Buffer for list of commands fetched at once | 79 | std::vector<CommandHeader> command_headers; ///< Buffer for list of commands fetched at once |
| 78 | 80 | ||
| 79 | std::queue<CommandList> dma_pushbuffer; ///< Queue of command lists to be processed | 81 | std::queue<CommandList> dma_pushbuffer; ///< Queue of command lists to be processed |
| @@ -92,6 +94,9 @@ private: | |||
| 92 | 94 | ||
| 93 | GPUVAddr dma_mget{}; ///< main pushbuffer last read address | 95 | GPUVAddr dma_mget{}; ///< main pushbuffer last read address |
| 94 | bool ib_enable{true}; ///< IB mode enabled | 96 | bool ib_enable{true}; ///< IB mode enabled |
| 97 | |||
| 98 | GPU& gpu; | ||
| 99 | Core::System& system; | ||
| 95 | }; | 100 | }; |
| 96 | 101 | ||
| 97 | } // namespace Tegra | 102 | } // namespace Tegra |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 8acf2eda2..a606f4abd 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -27,7 +27,7 @@ GPU::GPU(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& render | |||
| 27 | : system{system}, renderer{std::move(renderer_)}, is_async{is_async} { | 27 | : system{system}, renderer{std::move(renderer_)}, is_async{is_async} { |
| 28 | auto& rasterizer{renderer->Rasterizer()}; | 28 | auto& rasterizer{renderer->Rasterizer()}; |
| 29 | memory_manager = std::make_unique<Tegra::MemoryManager>(system, rasterizer); | 29 | memory_manager = std::make_unique<Tegra::MemoryManager>(system, rasterizer); |
| 30 | dma_pusher = std::make_unique<Tegra::DmaPusher>(*this); | 30 | dma_pusher = std::make_unique<Tegra::DmaPusher>(system, *this); |
| 31 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, rasterizer, *memory_manager); | 31 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, rasterizer, *memory_manager); |
| 32 | fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer); | 32 | fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer); |
| 33 | kepler_compute = std::make_unique<Engines::KeplerCompute>(system, rasterizer, *memory_manager); | 33 | kepler_compute = std::make_unique<Engines::KeplerCompute>(system, rasterizer, *memory_manager); |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 9495f48a2..22242cce9 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1145,6 +1145,7 @@ private: | |||
| 1145 | return {"gl_FragCoord"s + GetSwizzle(element), Type::Float}; | 1145 | return {"gl_FragCoord"s + GetSwizzle(element), Type::Float}; |
| 1146 | default: | 1146 | default: |
| 1147 | UNREACHABLE(); | 1147 | UNREACHABLE(); |
| 1148 | return {"0", Type::Int}; | ||
| 1148 | } | 1149 | } |
| 1149 | case Attribute::Index::FrontColor: | 1150 | case Attribute::Index::FrontColor: |
| 1150 | return {"gl_Color"s + GetSwizzle(element), Type::Float}; | 1151 | return {"gl_Color"s + GetSwizzle(element), Type::Float}; |
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 89f0e04ef..2c0c77c28 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -191,6 +191,7 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode, | |||
| 191 | case Tegra::Texture::TextureMipmapFilter::Linear: | 191 | case Tegra::Texture::TextureMipmapFilter::Linear: |
| 192 | return GL_LINEAR_MIPMAP_LINEAR; | 192 | return GL_LINEAR_MIPMAP_LINEAR; |
| 193 | } | 193 | } |
| 194 | break; | ||
| 194 | } | 195 | } |
| 195 | case Tegra::Texture::TextureFilter::Nearest: { | 196 | case Tegra::Texture::TextureFilter::Nearest: { |
| 196 | switch (mip_filter_mode) { | 197 | switch (mip_filter_mode) { |
| @@ -201,6 +202,7 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode, | |||
| 201 | case Tegra::Texture::TextureMipmapFilter::Linear: | 202 | case Tegra::Texture::TextureMipmapFilter::Linear: |
| 202 | return GL_NEAREST_MIPMAP_LINEAR; | 203 | return GL_NEAREST_MIPMAP_LINEAR; |
| 203 | } | 204 | } |
| 205 | break; | ||
| 204 | } | 206 | } |
| 205 | } | 207 | } |
| 206 | LOG_ERROR(Render_OpenGL, "Unimplemented texture filter mode={}", static_cast<u32>(filter_mode)); | 208 | LOG_ERROR(Render_OpenGL, "Unimplemented texture filter mode={}", static_cast<u32>(filter_mode)); |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index dd590c38b..04532f8f8 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -42,7 +42,7 @@ | |||
| 42 | #include <vulkan/vulkan_win32.h> | 42 | #include <vulkan/vulkan_win32.h> |
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | #ifdef __linux__ | 45 | #if !defined(_WIN32) && !defined(__APPLE__) |
| 46 | #include <X11/Xlib.h> | 46 | #include <X11/Xlib.h> |
| 47 | #include <vulkan/vulkan_wayland.h> | 47 | #include <vulkan/vulkan_wayland.h> |
| 48 | #include <vulkan/vulkan_xlib.h> | 48 | #include <vulkan/vulkan_xlib.h> |
| @@ -119,7 +119,7 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc | |||
| 119 | extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); | 119 | extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); |
| 120 | break; | 120 | break; |
| 121 | #endif | 121 | #endif |
| 122 | #ifdef __linux__ | 122 | #if !defined(_WIN32) && !defined(__APPLE__) |
| 123 | case Core::Frontend::WindowSystemType::X11: | 123 | case Core::Frontend::WindowSystemType::X11: |
| 124 | extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); | 124 | extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); |
| 125 | break; | 125 | break; |
| @@ -345,7 +345,7 @@ bool RendererVulkan::CreateSurface() { | |||
| 345 | } | 345 | } |
| 346 | } | 346 | } |
| 347 | #endif | 347 | #endif |
| 348 | #ifdef __linux__ | 348 | #if !defined(_WIN32) && !defined(__APPLE__) |
| 349 | if (window_info.type == Core::Frontend::WindowSystemType::X11) { | 349 | if (window_info.type == Core::Frontend::WindowSystemType::X11) { |
| 350 | const VkXlibSurfaceCreateInfoKHR xlib_ci{ | 350 | const VkXlibSurfaceCreateInfoKHR xlib_ci{ |
| 351 | VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, nullptr, 0, | 351 | VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, nullptr, 0, |
diff --git a/src/video_core/renderer_vulkan/shaders/quad_indexed.comp b/src/video_core/renderer_vulkan/shaders/quad_indexed.comp new file mode 100644 index 000000000..5a472ba9b --- /dev/null +++ b/src/video_core/renderer_vulkan/shaders/quad_indexed.comp | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | /* | ||
| 6 | * Build instructions: | ||
| 7 | * $ glslangValidator -V quad_indexed.comp -o output.spv | ||
| 8 | * $ spirv-opt -O --strip-debug output.spv -o optimized.spv | ||
| 9 | * $ xxd -i optimized.spv | ||
| 10 | * | ||
| 11 | * Then copy that bytecode to the C++ file | ||
| 12 | */ | ||
| 13 | |||
| 14 | #version 460 core | ||
| 15 | |||
| 16 | layout (local_size_x = 1024) in; | ||
| 17 | |||
| 18 | layout (std430, set = 0, binding = 0) readonly buffer InputBuffer { | ||
| 19 | uint input_indexes[]; | ||
| 20 | }; | ||
| 21 | |||
| 22 | layout (std430, set = 0, binding = 1) writeonly buffer OutputBuffer { | ||
| 23 | uint output_indexes[]; | ||
| 24 | }; | ||
| 25 | |||
| 26 | layout (push_constant) uniform PushConstants { | ||
| 27 | uint base_vertex; | ||
| 28 | int index_shift; // 0: uint8, 1: uint16, 2: uint32 | ||
| 29 | }; | ||
| 30 | |||
| 31 | void main() { | ||
| 32 | int primitive = int(gl_GlobalInvocationID.x); | ||
| 33 | if (primitive * 6 >= output_indexes.length()) { | ||
| 34 | return; | ||
| 35 | } | ||
| 36 | |||
| 37 | int index_size = 8 << index_shift; | ||
| 38 | int flipped_shift = 2 - index_shift; | ||
| 39 | int mask = (1 << flipped_shift) - 1; | ||
| 40 | |||
| 41 | const int quad_swizzle[6] = int[](0, 1, 2, 0, 2, 3); | ||
| 42 | for (uint vertex = 0; vertex < 6; ++vertex) { | ||
| 43 | int offset = primitive * 4 + quad_swizzle[vertex]; | ||
| 44 | int int_offset = offset >> flipped_shift; | ||
| 45 | int bit_offset = (offset & mask) * index_size; | ||
| 46 | uint packed_input = input_indexes[int_offset]; | ||
| 47 | uint index = bitfieldExtract(packed_input, bit_offset, index_size); | ||
| 48 | output_indexes[primitive * 6 + vertex] = index + base_vertex; | ||
| 49 | } | ||
| 50 | } | ||
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 878a78755..7b0268033 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp | |||
| @@ -135,11 +135,11 @@ VkDescriptorUpdateTemplateEntryKHR BuildQuadArrayPassDescriptorUpdateTemplateEnt | |||
| 135 | return entry; | 135 | return entry; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | VkPushConstantRange BuildQuadArrayPassPushConstantRange() { | 138 | VkPushConstantRange BuildComputePushConstantRange(std::size_t size) { |
| 139 | VkPushConstantRange range; | 139 | VkPushConstantRange range; |
| 140 | range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; | 140 | range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; |
| 141 | range.offset = 0; | 141 | range.offset = 0; |
| 142 | range.size = sizeof(u32); | 142 | range.size = static_cast<u32>(size); |
| 143 | return range; | 143 | return range; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| @@ -220,7 +220,130 @@ constexpr u8 uint8_pass[] = { | |||
| 220 | 0xf9, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, | 220 | 0xf9, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, |
| 221 | 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00}; | 221 | 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00}; |
| 222 | 222 | ||
| 223 | std::array<VkDescriptorSetLayoutBinding, 2> BuildUint8PassDescriptorSetBindings() { | 223 | // Quad indexed SPIR-V module. Generated from the "shaders/" directory. |
| 224 | constexpr u8 QUAD_INDEXED_SPV[] = { | ||
| 225 | 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x08, 0x00, 0x7c, 0x00, 0x00, 0x00, | ||
| 226 | 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, | ||
| 227 | 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, | ||
| 228 | 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | ||
| 229 | 0x0f, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, | ||
| 230 | 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
| 231 | 0x11, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | ||
| 232 | 0x47, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, | ||
| 233 | 0x47, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
| 234 | 0x48, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, | ||
| 235 | 0x48, 0x00, 0x05, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, | ||
| 236 | 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, | ||
| 237 | 0x47, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 238 | 0x47, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | ||
| 239 | 0x48, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, | ||
| 240 | 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | ||
| 241 | 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x22, 0x00, 0x00, 0x00, | ||
| 242 | 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 243 | 0x04, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 244 | 0x18, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 245 | 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x57, 0x00, 0x00, 0x00, | ||
| 246 | 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, | ||
| 247 | 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, | ||
| 248 | 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, | ||
| 249 | 0x19, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, | ||
| 250 | 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 251 | 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, | ||
| 252 | 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, | ||
| 253 | 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, | ||
| 254 | 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, | ||
| 255 | 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, | ||
| 256 | 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, | ||
| 257 | 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, | ||
| 258 | 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 259 | 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x03, 0x00, 0x15, 0x00, 0x00, 0x00, | ||
| 260 | 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x16, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, | ||
| 261 | 0x20, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, | ||
| 262 | 0x3b, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, | ||
| 263 | 0x14, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 264 | 0x21, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, | ||
| 265 | 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, | ||
| 266 | 0x09, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, | ||
| 267 | 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 268 | 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, | ||
| 269 | 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 270 | 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, | ||
| 271 | 0x3b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 272 | 0x3f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x41, 0x00, 0x00, 0x00, | ||
| 273 | 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 274 | 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 275 | 0x43, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x09, 0x00, 0x41, 0x00, 0x00, 0x00, | ||
| 276 | 0x44, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, | ||
| 277 | 0x42, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, | ||
| 278 | 0x46, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x03, 0x00, | ||
| 279 | 0x56, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x57, 0x00, 0x00, 0x00, | ||
| 280 | 0x56, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, | ||
| 281 | 0x57, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, | ||
| 282 | 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, | ||
| 283 | 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, | ||
| 284 | 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, | ||
| 285 | 0x00, 0x04, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, | ||
| 286 | 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, | ||
| 287 | 0x70, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, | ||
| 288 | 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, | ||
| 289 | 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00, | ||
| 290 | 0x47, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x74, 0x00, 0x00, 0x00, | ||
| 291 | 0xf8, 0x00, 0x02, 0x00, 0x74, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x73, 0x00, 0x00, 0x00, | ||
| 292 | 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x75, 0x00, 0x00, 0x00, | ||
| 293 | 0xf8, 0x00, 0x02, 0x00, 0x75, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, | ||
| 294 | 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, | ||
| 295 | 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, | ||
| 296 | 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, | ||
| 297 | 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | ||
| 298 | 0x44, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, | ||
| 299 | 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, | ||
| 300 | 0x19, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, | ||
| 301 | 0x14, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, | ||
| 302 | 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, | ||
| 303 | 0x1e, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, | ||
| 304 | 0x73, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, | ||
| 305 | 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, | ||
| 306 | 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, | ||
| 307 | 0xc4, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, | ||
| 308 | 0x28, 0x00, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, | ||
| 309 | 0x2b, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 310 | 0x31, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00, | ||
| 311 | 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, | ||
| 312 | 0xf9, 0x00, 0x02, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x35, 0x00, 0x00, 0x00, | ||
| 313 | 0xf5, 0x00, 0x07, 0x00, 0x09, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, | ||
| 314 | 0x1e, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, | ||
| 315 | 0x1b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, | ||
| 316 | 0xf6, 0x00, 0x04, 0x00, 0x37, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 317 | 0xfa, 0x00, 0x04, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, | ||
| 318 | 0xf8, 0x00, 0x02, 0x00, 0x36, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 319 | 0x40, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, | ||
| 320 | 0x47, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, | ||
| 321 | 0x48, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, | ||
| 322 | 0x06, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, | ||
| 323 | 0x06, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, | ||
| 324 | 0xc3, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, | ||
| 325 | 0x2e, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, | ||
| 326 | 0x4a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
| 327 | 0x54, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, | ||
| 328 | 0x5b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, | ||
| 329 | 0x4e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, | ||
| 330 | 0x5c, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, | ||
| 331 | 0x5d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, | ||
| 332 | 0x09, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, | ||
| 333 | 0x09, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, | ||
| 334 | 0x41, 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, | ||
| 335 | 0x42, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, | ||
| 336 | 0x6a, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, | ||
| 337 | 0x62, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5b, 0x00, 0x00, 0x00, | ||
| 338 | 0x6d, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, | ||
| 339 | 0x3e, 0x00, 0x03, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, | ||
| 340 | 0x09, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, | ||
| 341 | 0xf9, 0x00, 0x02, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x37, 0x00, 0x00, 0x00, | ||
| 342 | 0xf9, 0x00, 0x02, 0x00, 0x73, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, 0x00, | ||
| 343 | 0xf9, 0x00, 0x02, 0x00, 0x74, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x73, 0x00, 0x00, 0x00, | ||
| 344 | 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00}; | ||
| 345 | |||
| 346 | std::array<VkDescriptorSetLayoutBinding, 2> BuildInputOutputDescriptorSetBindings() { | ||
| 224 | std::array<VkDescriptorSetLayoutBinding, 2> bindings; | 347 | std::array<VkDescriptorSetLayoutBinding, 2> bindings; |
| 225 | bindings[0].binding = 0; | 348 | bindings[0].binding = 0; |
| 226 | bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; | 349 | bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; |
| @@ -235,7 +358,7 @@ std::array<VkDescriptorSetLayoutBinding, 2> BuildUint8PassDescriptorSetBindings( | |||
| 235 | return bindings; | 358 | return bindings; |
| 236 | } | 359 | } |
| 237 | 360 | ||
| 238 | VkDescriptorUpdateTemplateEntryKHR BuildUint8PassDescriptorUpdateTemplateEntry() { | 361 | VkDescriptorUpdateTemplateEntryKHR BuildInputOutputDescriptorUpdateTemplate() { |
| 239 | VkDescriptorUpdateTemplateEntryKHR entry; | 362 | VkDescriptorUpdateTemplateEntryKHR entry; |
| 240 | entry.dstBinding = 0; | 363 | entry.dstBinding = 0; |
| 241 | entry.dstArrayElement = 0; | 364 | entry.dstArrayElement = 0; |
| @@ -337,14 +460,14 @@ QuadArrayPass::QuadArrayPass(const VKDevice& device, VKScheduler& scheduler, | |||
| 337 | VKUpdateDescriptorQueue& update_descriptor_queue) | 460 | VKUpdateDescriptorQueue& update_descriptor_queue) |
| 338 | : VKComputePass(device, descriptor_pool, BuildQuadArrayPassDescriptorSetLayoutBinding(), | 461 | : VKComputePass(device, descriptor_pool, BuildQuadArrayPassDescriptorSetLayoutBinding(), |
| 339 | BuildQuadArrayPassDescriptorUpdateTemplateEntry(), | 462 | BuildQuadArrayPassDescriptorUpdateTemplateEntry(), |
| 340 | BuildQuadArrayPassPushConstantRange(), std::size(quad_array), quad_array), | 463 | BuildComputePushConstantRange(sizeof(u32)), std::size(quad_array), quad_array), |
| 341 | scheduler{scheduler}, staging_buffer_pool{staging_buffer_pool}, | 464 | scheduler{scheduler}, staging_buffer_pool{staging_buffer_pool}, |
| 342 | update_descriptor_queue{update_descriptor_queue} {} | 465 | update_descriptor_queue{update_descriptor_queue} {} |
| 343 | 466 | ||
| 344 | QuadArrayPass::~QuadArrayPass() = default; | 467 | QuadArrayPass::~QuadArrayPass() = default; |
| 345 | 468 | ||
| 346 | std::pair<VkBuffer, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 first) { | 469 | std::pair<VkBuffer, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 first) { |
| 347 | const u32 num_triangle_vertices = num_vertices * 6 / 4; | 470 | const u32 num_triangle_vertices = (num_vertices / 4) * 6; |
| 348 | const std::size_t staging_size = num_triangle_vertices * sizeof(u32); | 471 | const std::size_t staging_size = num_triangle_vertices * sizeof(u32); |
| 349 | auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false); | 472 | auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false); |
| 350 | 473 | ||
| @@ -383,8 +506,8 @@ std::pair<VkBuffer, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 | |||
| 383 | Uint8Pass::Uint8Pass(const VKDevice& device, VKScheduler& scheduler, | 506 | Uint8Pass::Uint8Pass(const VKDevice& device, VKScheduler& scheduler, |
| 384 | VKDescriptorPool& descriptor_pool, VKStagingBufferPool& staging_buffer_pool, | 507 | VKDescriptorPool& descriptor_pool, VKStagingBufferPool& staging_buffer_pool, |
| 385 | VKUpdateDescriptorQueue& update_descriptor_queue) | 508 | VKUpdateDescriptorQueue& update_descriptor_queue) |
| 386 | : VKComputePass(device, descriptor_pool, BuildUint8PassDescriptorSetBindings(), | 509 | : VKComputePass(device, descriptor_pool, BuildInputOutputDescriptorSetBindings(), |
| 387 | BuildUint8PassDescriptorUpdateTemplateEntry(), {}, std::size(uint8_pass), | 510 | BuildInputOutputDescriptorUpdateTemplate(), {}, std::size(uint8_pass), |
| 388 | uint8_pass), | 511 | uint8_pass), |
| 389 | scheduler{scheduler}, staging_buffer_pool{staging_buffer_pool}, | 512 | scheduler{scheduler}, staging_buffer_pool{staging_buffer_pool}, |
| 390 | update_descriptor_queue{update_descriptor_queue} {} | 513 | update_descriptor_queue{update_descriptor_queue} {} |
| @@ -425,4 +548,70 @@ std::pair<VkBuffer, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer src_buff | |||
| 425 | return {*buffer.handle, 0}; | 548 | return {*buffer.handle, 0}; |
| 426 | } | 549 | } |
| 427 | 550 | ||
| 551 | QuadIndexedPass::QuadIndexedPass(const VKDevice& device, VKScheduler& scheduler, | ||
| 552 | VKDescriptorPool& descriptor_pool, | ||
| 553 | VKStagingBufferPool& staging_buffer_pool, | ||
| 554 | VKUpdateDescriptorQueue& update_descriptor_queue) | ||
| 555 | : VKComputePass(device, descriptor_pool, BuildInputOutputDescriptorSetBindings(), | ||
| 556 | BuildInputOutputDescriptorUpdateTemplate(), | ||
| 557 | BuildComputePushConstantRange(sizeof(u32) * 2), std::size(QUAD_INDEXED_SPV), | ||
| 558 | QUAD_INDEXED_SPV), | ||
| 559 | scheduler{scheduler}, staging_buffer_pool{staging_buffer_pool}, | ||
| 560 | update_descriptor_queue{update_descriptor_queue} {} | ||
| 561 | |||
| 562 | QuadIndexedPass::~QuadIndexedPass() = default; | ||
| 563 | |||
| 564 | std::pair<VkBuffer, u64> QuadIndexedPass::Assemble( | ||
| 565 | Tegra::Engines::Maxwell3D::Regs::IndexFormat index_format, u32 num_vertices, u32 base_vertex, | ||
| 566 | VkBuffer src_buffer, u64 src_offset) { | ||
| 567 | const u32 index_shift = [index_format] { | ||
| 568 | switch (index_format) { | ||
| 569 | case Tegra::Engines::Maxwell3D::Regs::IndexFormat::UnsignedByte: | ||
| 570 | return 0; | ||
| 571 | case Tegra::Engines::Maxwell3D::Regs::IndexFormat::UnsignedShort: | ||
| 572 | return 1; | ||
| 573 | case Tegra::Engines::Maxwell3D::Regs::IndexFormat::UnsignedInt: | ||
| 574 | return 2; | ||
| 575 | } | ||
| 576 | UNREACHABLE(); | ||
| 577 | return 2; | ||
| 578 | }(); | ||
| 579 | const u32 input_size = num_vertices << index_shift; | ||
| 580 | const u32 num_tri_vertices = (num_vertices / 4) * 6; | ||
| 581 | |||
| 582 | const std::size_t staging_size = num_tri_vertices * sizeof(u32); | ||
| 583 | auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false); | ||
| 584 | |||
| 585 | update_descriptor_queue.Acquire(); | ||
| 586 | update_descriptor_queue.AddBuffer(src_buffer, src_offset, input_size); | ||
| 587 | update_descriptor_queue.AddBuffer(*buffer.handle, 0, staging_size); | ||
| 588 | const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence()); | ||
| 589 | |||
| 590 | scheduler.RequestOutsideRenderPassOperationContext(); | ||
| 591 | scheduler.Record([layout = *layout, pipeline = *pipeline, buffer = *buffer.handle, set, | ||
| 592 | num_tri_vertices, base_vertex, index_shift](vk::CommandBuffer cmdbuf) { | ||
| 593 | static constexpr u32 dispatch_size = 1024; | ||
| 594 | const std::array push_constants = {base_vertex, index_shift}; | ||
| 595 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); | ||
| 596 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, layout, 0, set, {}); | ||
| 597 | cmdbuf.PushConstants(layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(push_constants), | ||
| 598 | &push_constants); | ||
| 599 | cmdbuf.Dispatch(Common::AlignUp(num_tri_vertices, dispatch_size) / dispatch_size, 1, 1); | ||
| 600 | |||
| 601 | VkBufferMemoryBarrier barrier; | ||
| 602 | barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; | ||
| 603 | barrier.pNext = nullptr; | ||
| 604 | barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; | ||
| 605 | barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; | ||
| 606 | barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; | ||
| 607 | barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; | ||
| 608 | barrier.buffer = buffer; | ||
| 609 | barrier.offset = 0; | ||
| 610 | barrier.size = static_cast<VkDeviceSize>(num_tri_vertices * sizeof(u32)); | ||
| 611 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, | ||
| 612 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, barrier, {}); | ||
| 613 | }); | ||
| 614 | return {*buffer.handle, 0}; | ||
| 615 | } | ||
| 616 | |||
| 428 | } // namespace Vulkan | 617 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.h b/src/video_core/renderer_vulkan/vk_compute_pass.h index ec80c8683..26bf834de 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.h +++ b/src/video_core/renderer_vulkan/vk_compute_pass.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <utility> | 8 | #include <utility> |
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "video_core/engines/maxwell_3d.h" | ||
| 11 | #include "video_core/renderer_vulkan/vk_descriptor_pool.h" | 12 | #include "video_core/renderer_vulkan/vk_descriptor_pool.h" |
| 12 | #include "video_core/renderer_vulkan/wrapper.h" | 13 | #include "video_core/renderer_vulkan/wrapper.h" |
| 13 | 14 | ||
| @@ -73,4 +74,22 @@ private: | |||
| 73 | VKUpdateDescriptorQueue& update_descriptor_queue; | 74 | VKUpdateDescriptorQueue& update_descriptor_queue; |
| 74 | }; | 75 | }; |
| 75 | 76 | ||
| 77 | class QuadIndexedPass final : public VKComputePass { | ||
| 78 | public: | ||
| 79 | explicit QuadIndexedPass(const VKDevice& device, VKScheduler& scheduler, | ||
| 80 | VKDescriptorPool& descriptor_pool, | ||
| 81 | VKStagingBufferPool& staging_buffer_pool, | ||
| 82 | VKUpdateDescriptorQueue& update_descriptor_queue); | ||
| 83 | ~QuadIndexedPass(); | ||
| 84 | |||
| 85 | std::pair<VkBuffer, u64> Assemble(Tegra::Engines::Maxwell3D::Regs::IndexFormat index_format, | ||
| 86 | u32 num_vertices, u32 base_vertex, VkBuffer src_buffer, | ||
| 87 | u64 src_offset); | ||
| 88 | |||
| 89 | private: | ||
| 90 | VKScheduler& scheduler; | ||
| 91 | VKStagingBufferPool& staging_buffer_pool; | ||
| 92 | VKUpdateDescriptorQueue& update_descriptor_queue; | ||
| 93 | }; | ||
| 94 | |||
| 76 | } // namespace Vulkan | 95 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 4ca0febb8..857bea19f 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -293,6 +293,7 @@ RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWind | |||
| 293 | update_descriptor_queue(device, scheduler), renderpass_cache(device), | 293 | update_descriptor_queue(device, scheduler), renderpass_cache(device), |
| 294 | quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 294 | quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), |
| 295 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 295 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), |
| 296 | quad_indexed_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | ||
| 296 | texture_cache(system, *this, device, resource_manager, memory_manager, scheduler, | 297 | texture_cache(system, *this, device, resource_manager, memory_manager, scheduler, |
| 297 | staging_pool), | 298 | staging_pool), |
| 298 | pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue, | 299 | pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue, |
| @@ -844,18 +845,26 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar | |||
| 844 | bool is_indexed) { | 845 | bool is_indexed) { |
| 845 | const auto& regs = system.GPU().Maxwell3D().regs; | 846 | const auto& regs = system.GPU().Maxwell3D().regs; |
| 846 | switch (regs.draw.topology) { | 847 | switch (regs.draw.topology) { |
| 847 | case Maxwell::PrimitiveTopology::Quads: | 848 | case Maxwell::PrimitiveTopology::Quads: { |
| 848 | if (params.is_indexed) { | 849 | if (!params.is_indexed) { |
| 849 | UNIMPLEMENTED(); | ||
| 850 | } else { | ||
| 851 | const auto [buffer, offset] = | 850 | const auto [buffer, offset] = |
| 852 | quad_array_pass.Assemble(params.num_vertices, params.base_vertex); | 851 | quad_array_pass.Assemble(params.num_vertices, params.base_vertex); |
| 853 | buffer_bindings.SetIndexBinding(buffer, offset, VK_INDEX_TYPE_UINT32); | 852 | buffer_bindings.SetIndexBinding(buffer, offset, VK_INDEX_TYPE_UINT32); |
| 854 | params.base_vertex = 0; | 853 | params.base_vertex = 0; |
| 855 | params.num_vertices = params.num_vertices * 6 / 4; | 854 | params.num_vertices = params.num_vertices * 6 / 4; |
| 856 | params.is_indexed = true; | 855 | params.is_indexed = true; |
| 856 | break; | ||
| 857 | } | 857 | } |
| 858 | const GPUVAddr gpu_addr = regs.index_array.IndexStart(); | ||
| 859 | auto [buffer, offset] = buffer_cache.UploadMemory(gpu_addr, CalculateIndexBufferSize()); | ||
| 860 | std::tie(buffer, offset) = quad_indexed_pass.Assemble( | ||
| 861 | regs.index_array.format, params.num_vertices, params.base_vertex, buffer, offset); | ||
| 862 | |||
| 863 | buffer_bindings.SetIndexBinding(buffer, offset, VK_INDEX_TYPE_UINT32); | ||
| 864 | params.num_vertices = (params.num_vertices / 4) * 6; | ||
| 865 | params.base_vertex = 0; | ||
| 858 | break; | 866 | break; |
| 867 | } | ||
| 859 | default: { | 868 | default: { |
| 860 | if (!is_indexed) { | 869 | if (!is_indexed) { |
| 861 | break; | 870 | break; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 46037860a..d9108f862 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -254,6 +254,7 @@ private: | |||
| 254 | VKUpdateDescriptorQueue update_descriptor_queue; | 254 | VKUpdateDescriptorQueue update_descriptor_queue; |
| 255 | VKRenderPassCache renderpass_cache; | 255 | VKRenderPassCache renderpass_cache; |
| 256 | QuadArrayPass quad_array_pass; | 256 | QuadArrayPass quad_array_pass; |
| 257 | QuadIndexedPass quad_indexed_pass; | ||
| 257 | Uint8Pass uint8_pass; | 258 | Uint8Pass uint8_pass; |
| 258 | 259 | ||
| 259 | VKTextureCache texture_cache; | 260 | VKTextureCache texture_cache; |
diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp index 224943ad9..513e9bf49 100644 --- a/src/video_core/shader/track.cpp +++ b/src/video_core/shader/track.cpp | |||
| @@ -76,12 +76,13 @@ std::tuple<Node, TrackSampler> ShaderIR::TrackBindlessSampler(Node tracked, cons | |||
| 76 | s64 cursor) { | 76 | s64 cursor) { |
| 77 | if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { | 77 | if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { |
| 78 | // Constant buffer found, test if it's an immediate | 78 | // Constant buffer found, test if it's an immediate |
| 79 | const auto offset = cbuf->GetOffset(); | 79 | const auto& offset = cbuf->GetOffset(); |
| 80 | if (const auto immediate = std::get_if<ImmediateNode>(&*offset)) { | 80 | if (const auto immediate = std::get_if<ImmediateNode>(&*offset)) { |
| 81 | auto track = | 81 | auto track = |
| 82 | MakeTrackSampler<BindlessSamplerNode>(cbuf->GetIndex(), immediate->GetValue()); | 82 | MakeTrackSampler<BindlessSamplerNode>(cbuf->GetIndex(), immediate->GetValue()); |
| 83 | return {tracked, track}; | 83 | return {tracked, track}; |
| 84 | } else if (const auto operation = std::get_if<OperationNode>(&*offset)) { | 84 | } |
| 85 | if (const auto operation = std::get_if<OperationNode>(&*offset)) { | ||
| 85 | const u32 bound_buffer = registry.GetBoundBuffer(); | 86 | const u32 bound_buffer = registry.GetBoundBuffer(); |
| 86 | if (bound_buffer != cbuf->GetIndex()) { | 87 | if (bound_buffer != cbuf->GetIndex()) { |
| 87 | return {}; | 88 | return {}; |
| @@ -94,12 +95,12 @@ std::tuple<Node, TrackSampler> ShaderIR::TrackBindlessSampler(Node tracked, cons | |||
| 94 | const auto offset_inm = std::get_if<ImmediateNode>(&*base_offset); | 95 | const auto offset_inm = std::get_if<ImmediateNode>(&*base_offset); |
| 95 | const auto& gpu_driver = registry.AccessGuestDriverProfile(); | 96 | const auto& gpu_driver = registry.AccessGuestDriverProfile(); |
| 96 | const u32 bindless_cv = NewCustomVariable(); | 97 | const u32 bindless_cv = NewCustomVariable(); |
| 97 | const Node op = | 98 | Node op = |
| 98 | Operation(OperationCode::UDiv, gpr, Immediate(gpu_driver.GetTextureHandlerSize())); | 99 | Operation(OperationCode::UDiv, gpr, Immediate(gpu_driver.GetTextureHandlerSize())); |
| 99 | 100 | ||
| 100 | const Node cv_node = GetCustomVariable(bindless_cv); | 101 | const Node cv_node = GetCustomVariable(bindless_cv); |
| 101 | Node amend_op = Operation(OperationCode::Assign, cv_node, std::move(op)); | 102 | Node amend_op = Operation(OperationCode::Assign, cv_node, std::move(op)); |
| 102 | const std::size_t amend_index = DeclareAmend(amend_op); | 103 | const std::size_t amend_index = DeclareAmend(std::move(amend_op)); |
| 103 | AmendNodeCv(amend_index, code[cursor]); | 104 | AmendNodeCv(amend_index, code[cursor]); |
| 104 | // TODO Implement Bindless Index custom variable | 105 | // TODO Implement Bindless Index custom variable |
| 105 | auto track = MakeTrackSampler<ArraySamplerNode>(cbuf->GetIndex(), | 106 | auto track = MakeTrackSampler<ArraySamplerNode>(cbuf->GetIndex(), |
| @@ -142,7 +143,7 @@ std::tuple<Node, u32, u32> ShaderIR::TrackCbuf(Node tracked, const NodeBlock& co | |||
| 142 | s64 cursor) const { | 143 | s64 cursor) const { |
| 143 | if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { | 144 | if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { |
| 144 | // Constant buffer found, test if it's an immediate | 145 | // Constant buffer found, test if it's an immediate |
| 145 | const auto offset = cbuf->GetOffset(); | 146 | const auto& offset = cbuf->GetOffset(); |
| 146 | if (const auto immediate = std::get_if<ImmediateNode>(&*offset)) { | 147 | if (const auto immediate = std::get_if<ImmediateNode>(&*offset)) { |
| 147 | return {tracked, cbuf->GetIndex(), immediate->GetValue()}; | 148 | return {tracked, cbuf->GetIndex(), immediate->GetValue()}; |
| 148 | } | 149 | } |
diff --git a/src/video_core/texture_cache/format_lookup_table.cpp b/src/video_core/texture_cache/format_lookup_table.cpp index e151c26c4..25d2ee2e8 100644 --- a/src/video_core/texture_cache/format_lookup_table.cpp +++ b/src/video_core/texture_cache/format_lookup_table.cpp | |||
| @@ -196,9 +196,9 @@ std::size_t FormatLookupTable::CalculateIndex(TextureFormat format, bool is_srgb | |||
| 196 | ComponentType alpha_component) noexcept { | 196 | ComponentType alpha_component) noexcept { |
| 197 | const auto format_index = static_cast<std::size_t>(format); | 197 | const auto format_index = static_cast<std::size_t>(format); |
| 198 | const auto red_index = static_cast<std::size_t>(red_component); | 198 | const auto red_index = static_cast<std::size_t>(red_component); |
| 199 | const auto green_index = static_cast<std::size_t>(red_component); | 199 | const auto green_index = static_cast<std::size_t>(green_component); |
| 200 | const auto blue_index = static_cast<std::size_t>(red_component); | 200 | const auto blue_index = static_cast<std::size_t>(blue_component); |
| 201 | const auto alpha_index = static_cast<std::size_t>(red_component); | 201 | const auto alpha_index = static_cast<std::size_t>(alpha_component); |
| 202 | const std::size_t srgb_index = is_srgb ? 1 : 0; | 202 | const std::size_t srgb_index = is_srgb ? 1 : 0; |
| 203 | 203 | ||
| 204 | return format_index * PerFormat + | 204 | return format_index * PerFormat + |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 2c8eb481d..05baec7e1 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -802,10 +802,6 @@ void GMainWindow::ConnectMenuEvents() { | |||
| 802 | connect(ui.action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder); | 802 | connect(ui.action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder); |
| 803 | connect(ui.action_Install_File_NAND, &QAction::triggered, this, | 803 | connect(ui.action_Install_File_NAND, &QAction::triggered, this, |
| 804 | &GMainWindow::OnMenuInstallToNAND); | 804 | &GMainWindow::OnMenuInstallToNAND); |
| 805 | connect(ui.action_Select_NAND_Directory, &QAction::triggered, this, | ||
| 806 | [this] { OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget::NAND); }); | ||
| 807 | connect(ui.action_Select_SDMC_Directory, &QAction::triggered, this, | ||
| 808 | [this] { OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget::SDMC); }); | ||
| 809 | connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); | 805 | connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); |
| 810 | connect(ui.action_Load_Amiibo, &QAction::triggered, this, &GMainWindow::OnLoadAmiibo); | 806 | connect(ui.action_Load_Amiibo, &QAction::triggered, this, &GMainWindow::OnLoadAmiibo); |
| 811 | 807 | ||
| @@ -940,16 +936,18 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 940 | default: | 936 | default: |
| 941 | if (static_cast<u32>(result) > | 937 | if (static_cast<u32>(result) > |
| 942 | static_cast<u32>(Core::System::ResultStatus::ErrorLoader)) { | 938 | static_cast<u32>(Core::System::ResultStatus::ErrorLoader)) { |
| 943 | LOG_CRITICAL(Frontend, "Failed to load ROM!"); | ||
| 944 | const u16 loader_id = static_cast<u16>(Core::System::ResultStatus::ErrorLoader); | 939 | const u16 loader_id = static_cast<u16>(Core::System::ResultStatus::ErrorLoader); |
| 945 | const u16 error_id = static_cast<u16>(result) - loader_id; | 940 | const u16 error_id = static_cast<u16>(result) - loader_id; |
| 941 | const std::string error_code = fmt::format("({:04X}-{:04X})", loader_id, error_id); | ||
| 942 | LOG_CRITICAL(Frontend, "Failed to load ROM! {}", error_code); | ||
| 946 | QMessageBox::critical( | 943 | QMessageBox::critical( |
| 947 | this, tr("Error while loading ROM!"), | 944 | this, |
| 945 | tr("Error while loading ROM! ").append(QString::fromStdString(error_code)), | ||
| 948 | QString::fromStdString(fmt::format( | 946 | QString::fromStdString(fmt::format( |
| 949 | "While attempting to load the ROM requested, an error occured. Please " | 947 | "{}<br>Please follow <a href='https://yuzu-emu.org/help/quickstart/'>the " |
| 950 | "refer to the yuzu wiki for more information or the yuzu discord for " | 948 | "yuzu quickstart guide</a> to redump your files.<br>You can refer " |
| 951 | "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", | 949 | "to the yuzu wiki</a> or the yuzu Discord</a> for help.", |
| 952 | loader_id, error_id, static_cast<Loader::ResultStatus>(error_id)))); | 950 | static_cast<Loader::ResultStatus>(error_id)))); |
| 953 | } else { | 951 | } else { |
| 954 | QMessageBox::critical( | 952 | QMessageBox::critical( |
| 955 | this, tr("Error while loading ROM!"), | 953 | this, tr("Error while loading ROM!"), |
| @@ -1663,28 +1661,6 @@ void GMainWindow::OnMenuInstallToNAND() { | |||
| 1663 | } | 1661 | } |
| 1664 | } | 1662 | } |
| 1665 | 1663 | ||
| 1666 | void GMainWindow::OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget target) { | ||
| 1667 | const auto res = QMessageBox::information( | ||
| 1668 | this, tr("Changing Emulated Directory"), | ||
| 1669 | tr("You are about to change the emulated %1 directory of the system. Please note " | ||
| 1670 | "that this does not also move the contents of the previous directory to the " | ||
| 1671 | "new one and you will have to do that yourself.") | ||
| 1672 | .arg(target == EmulatedDirectoryTarget::SDMC ? tr("SD card") : tr("NAND")), | ||
| 1673 | QMessageBox::StandardButtons{QMessageBox::Ok, QMessageBox::Cancel}); | ||
| 1674 | |||
| 1675 | if (res == QMessageBox::Cancel) | ||
| 1676 | return; | ||
| 1677 | |||
| 1678 | QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); | ||
| 1679 | if (!dir_path.isEmpty()) { | ||
| 1680 | FileUtil::GetUserPath(target == EmulatedDirectoryTarget::SDMC ? FileUtil::UserPath::SDMCDir | ||
| 1681 | : FileUtil::UserPath::NANDDir, | ||
| 1682 | dir_path.toStdString()); | ||
| 1683 | Core::System::GetInstance().GetFileSystemController().CreateFactories(*vfs); | ||
| 1684 | game_list->PopulateAsync(UISettings::values.game_dirs); | ||
| 1685 | } | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | void GMainWindow::OnMenuRecentFile() { | 1664 | void GMainWindow::OnMenuRecentFile() { |
| 1689 | QAction* action = qobject_cast<QAction*>(sender()); | 1665 | QAction* action = qobject_cast<QAction*>(sender()); |
| 1690 | assert(action); | 1666 | assert(action); |
| @@ -2095,27 +2071,25 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) { | |||
| 2095 | 2071 | ||
| 2096 | QString errors; | 2072 | QString errors; |
| 2097 | if (!pdm.HasFuses()) { | 2073 | if (!pdm.HasFuses()) { |
| 2098 | errors += tr("- Missing fuses - Cannot derive SBK\n"); | 2074 | errors += tr("Missing fuses"); |
| 2099 | } | 2075 | } |
| 2100 | if (!pdm.HasBoot0()) { | 2076 | if (!pdm.HasBoot0()) { |
| 2101 | errors += tr("- Missing BOOT0 - Cannot derive master keys\n"); | 2077 | errors += tr(" - Missing BOOT0"); |
| 2102 | } | 2078 | } |
| 2103 | if (!pdm.HasPackage2()) { | 2079 | if (!pdm.HasPackage2()) { |
| 2104 | errors += tr("- Missing BCPKG2-1-Normal-Main - Cannot derive general keys\n"); | 2080 | errors += tr(" - Missing BCPKG2-1-Normal-Main"); |
| 2105 | } | 2081 | } |
| 2106 | if (!pdm.HasProdInfo()) { | 2082 | if (!pdm.HasProdInfo()) { |
| 2107 | errors += tr("- Missing PRODINFO - Cannot derive title keys\n"); | 2083 | errors += tr(" - Missing PRODINFO"); |
| 2108 | } | 2084 | } |
| 2109 | if (!errors.isEmpty()) { | 2085 | if (!errors.isEmpty()) { |
| 2110 | QMessageBox::warning( | 2086 | QMessageBox::warning( |
| 2111 | this, tr("Warning Missing Derivation Components"), | 2087 | this, tr("Derivation Components Missing"), |
| 2112 | tr("The following are missing from your configuration that may hinder key " | 2088 | tr("Components are missing that may hinder key derivation from completing. " |
| 2113 | "derivation. It will be attempted but may not complete.<br><br>") + | 2089 | "<br>Please follow <a href='https://yuzu-emu.org/help/quickstart/'>the yuzu " |
| 2114 | errors + | 2090 | "quickstart guide</a> to get all your keys and " |
| 2115 | tr("<br><br>You can get all of these and dump all of your games easily by " | 2091 | "games.<br><br><small>(%1)</small>") |
| 2116 | "following <a href='https://yuzu-emu.org/help/quickstart/'>the " | 2092 | .arg(errors)); |
| 2117 | "quickstart guide</a>. Alternatively, you can use another method of dumping " | ||
| 2118 | "to obtain all of your keys.")); | ||
| 2119 | } | 2093 | } |
| 2120 | 2094 | ||
| 2121 | QProgressDialog prog; | 2095 | QProgressDialog prog; |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index a67125567..0b750689d 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -196,8 +196,6 @@ private slots: | |||
| 196 | void OnMenuLoadFile(); | 196 | void OnMenuLoadFile(); |
| 197 | void OnMenuLoadFolder(); | 197 | void OnMenuLoadFolder(); |
| 198 | void OnMenuInstallToNAND(); | 198 | void OnMenuInstallToNAND(); |
| 199 | /// Called whenever a user select the "File->Select -- Directory" where -- is NAND or SD Card | ||
| 200 | void OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget target); | ||
| 201 | void OnMenuRecentFile(); | 199 | void OnMenuRecentFile(); |
| 202 | void OnConfigure(); | 200 | void OnConfigure(); |
| 203 | void OnLoadAmiibo(); | 201 | void OnLoadAmiibo(); |
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index a2c9e4547..ae414241e 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui | |||
| @@ -64,8 +64,6 @@ | |||
| 64 | <addaction name="separator"/> | 64 | <addaction name="separator"/> |
| 65 | <addaction name="menu_recent_files"/> | 65 | <addaction name="menu_recent_files"/> |
| 66 | <addaction name="separator"/> | 66 | <addaction name="separator"/> |
| 67 | <addaction name="action_Select_NAND_Directory"/> | ||
| 68 | <addaction name="action_Select_SDMC_Directory"/> | ||
| 69 | <addaction name="separator"/> | 67 | <addaction name="separator"/> |
| 70 | <addaction name="action_Load_Amiibo"/> | 68 | <addaction name="action_Load_Amiibo"/> |
| 71 | <addaction name="separator"/> | 69 | <addaction name="separator"/> |
| @@ -217,22 +215,6 @@ | |||
| 217 | <string>Show Status Bar</string> | 215 | <string>Show Status Bar</string> |
| 218 | </property> | 216 | </property> |
| 219 | </action> | 217 | </action> |
| 220 | <action name="action_Select_NAND_Directory"> | ||
| 221 | <property name="text"> | ||
| 222 | <string>Select NAND Directory...</string> | ||
| 223 | </property> | ||
| 224 | <property name="toolTip"> | ||
| 225 | <string>Selects a folder to use as the root of the emulated NAND</string> | ||
| 226 | </property> | ||
| 227 | </action> | ||
| 228 | <action name="action_Select_SDMC_Directory"> | ||
| 229 | <property name="text"> | ||
| 230 | <string>Select SD Card Directory...</string> | ||
| 231 | </property> | ||
| 232 | <property name="toolTip"> | ||
| 233 | <string>Selects a folder to use as the root of the emulated SD card</string> | ||
| 234 | </property> | ||
| 235 | </action> | ||
| 236 | <action name="action_Fullscreen"> | 218 | <action name="action_Fullscreen"> |
| 237 | <property name="checkable"> | 219 | <property name="checkable"> |
| 238 | <bool>true</bool> | 220 | <bool>true</bool> |