diff options
Diffstat (limited to 'src')
32 files changed, 256 insertions, 115 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 850ce8006..5639021d3 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -91,6 +91,8 @@ add_library(common STATIC | |||
| 91 | logging/log.h | 91 | logging/log.h |
| 92 | logging/text_formatter.cpp | 92 | logging/text_formatter.cpp |
| 93 | logging/text_formatter.h | 93 | logging/text_formatter.h |
| 94 | lz4_compression.cpp | ||
| 95 | lz4_compression.h | ||
| 94 | math_util.h | 96 | math_util.h |
| 95 | memory_hook.cpp | 97 | memory_hook.cpp |
| 96 | memory_hook.h | 98 | memory_hook.h |
| @@ -136,3 +138,4 @@ endif() | |||
| 136 | create_target_directory_groups(common) | 138 | create_target_directory_groups(common) |
| 137 | 139 | ||
| 138 | target_link_libraries(common PUBLIC Boost::boost fmt microprofile) | 140 | target_link_libraries(common PUBLIC Boost::boost fmt microprofile) |
| 141 | target_link_libraries(common PRIVATE lz4_static) | ||
diff --git a/src/common/lz4_compression.cpp b/src/common/lz4_compression.cpp new file mode 100644 index 000000000..ade6759bb --- /dev/null +++ b/src/common/lz4_compression.cpp | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <lz4hc.h> | ||
| 7 | |||
| 8 | #include "common/assert.h" | ||
| 9 | #include "common/lz4_compression.h" | ||
| 10 | |||
| 11 | namespace Common::Compression { | ||
| 12 | |||
| 13 | std::vector<u8> CompressDataLZ4(const u8* source, std::size_t source_size) { | ||
| 14 | ASSERT_MSG(source_size <= LZ4_MAX_INPUT_SIZE, "Source size exceeds LZ4 maximum input size"); | ||
| 15 | |||
| 16 | const auto source_size_int = static_cast<int>(source_size); | ||
| 17 | const int max_compressed_size = LZ4_compressBound(source_size_int); | ||
| 18 | std::vector<u8> compressed(max_compressed_size); | ||
| 19 | |||
| 20 | const int compressed_size = LZ4_compress_default(reinterpret_cast<const char*>(source), | ||
| 21 | reinterpret_cast<char*>(compressed.data()), | ||
| 22 | source_size_int, max_compressed_size); | ||
| 23 | |||
| 24 | if (compressed_size <= 0) { | ||
| 25 | // Compression failed | ||
| 26 | return {}; | ||
| 27 | } | ||
| 28 | |||
| 29 | compressed.resize(compressed_size); | ||
| 30 | |||
| 31 | return compressed; | ||
| 32 | } | ||
| 33 | |||
| 34 | std::vector<u8> CompressDataLZ4HC(const u8* source, std::size_t source_size, | ||
| 35 | s32 compression_level) { | ||
| 36 | ASSERT_MSG(source_size <= LZ4_MAX_INPUT_SIZE, "Source size exceeds LZ4 maximum input size"); | ||
| 37 | |||
| 38 | compression_level = std::clamp(compression_level, LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX); | ||
| 39 | |||
| 40 | const auto source_size_int = static_cast<int>(source_size); | ||
| 41 | const int max_compressed_size = LZ4_compressBound(source_size_int); | ||
| 42 | std::vector<u8> compressed(max_compressed_size); | ||
| 43 | |||
| 44 | const int compressed_size = LZ4_compress_HC( | ||
| 45 | reinterpret_cast<const char*>(source), reinterpret_cast<char*>(compressed.data()), | ||
| 46 | source_size_int, max_compressed_size, compression_level); | ||
| 47 | |||
| 48 | if (compressed_size <= 0) { | ||
| 49 | // Compression failed | ||
| 50 | return {}; | ||
| 51 | } | ||
| 52 | |||
| 53 | compressed.resize(compressed_size); | ||
| 54 | |||
| 55 | return compressed; | ||
| 56 | } | ||
| 57 | |||
| 58 | std::vector<u8> CompressDataLZ4HCMax(const u8* source, std::size_t source_size) { | ||
| 59 | return CompressDataLZ4HC(source, source_size, LZ4HC_CLEVEL_MAX); | ||
| 60 | } | ||
| 61 | |||
| 62 | std::vector<u8> DecompressDataLZ4(const std::vector<u8>& compressed, | ||
| 63 | std::size_t uncompressed_size) { | ||
| 64 | std::vector<u8> uncompressed(uncompressed_size); | ||
| 65 | const int size_check = LZ4_decompress_safe(reinterpret_cast<const char*>(compressed.data()), | ||
| 66 | reinterpret_cast<char*>(uncompressed.data()), | ||
| 67 | static_cast<int>(compressed.size()), | ||
| 68 | static_cast<int>(uncompressed.size())); | ||
| 69 | if (static_cast<int>(uncompressed_size) != size_check) { | ||
| 70 | // Decompression failed | ||
| 71 | return {}; | ||
| 72 | } | ||
| 73 | return uncompressed; | ||
| 74 | } | ||
| 75 | |||
| 76 | } // namespace Common::Compression | ||
diff --git a/src/common/lz4_compression.h b/src/common/lz4_compression.h new file mode 100644 index 000000000..fe2231a6c --- /dev/null +++ b/src/common/lz4_compression.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <vector> | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | namespace Common::Compression { | ||
| 10 | |||
| 11 | /** | ||
| 12 | * Compresses a source memory region with LZ4 and returns the compressed data in a vector. | ||
| 13 | * | ||
| 14 | * @param source the uncompressed source memory region. | ||
| 15 | * @param source_size the size in bytes of the uncompressed source memory region. | ||
| 16 | * | ||
| 17 | * @return the compressed data. | ||
| 18 | */ | ||
| 19 | std::vector<u8> CompressDataLZ4(const u8* source, std::size_t source_size); | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Utilizes the LZ4 subalgorithm LZ4HC with the specified compression level. Higher compression | ||
| 23 | * levels result in a smaller compressed size, but require more CPU time for compression. The | ||
| 24 | * compression level has almost no impact on decompression speed. Data compressed with LZ4HC can | ||
| 25 | * also be decompressed with the default LZ4 decompression. | ||
| 26 | * | ||
| 27 | * @param source the uncompressed source memory region. | ||
| 28 | * @param source_size the size in bytes of the uncompressed source memory region. | ||
| 29 | * @param compression_level the used compression level. Should be between 3 and 12. | ||
| 30 | * | ||
| 31 | * @return the compressed data. | ||
| 32 | */ | ||
| 33 | std::vector<u8> CompressDataLZ4HC(const u8* source, std::size_t source_size, s32 compression_level); | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Utilizes the LZ4 subalgorithm LZ4HC with the highest possible compression level. | ||
| 37 | * | ||
| 38 | * @param source the uncompressed source memory region. | ||
| 39 | * @param source_size the size in bytes of the uncompressed source memory region. | ||
| 40 | * | ||
| 41 | * @return the compressed data. | ||
| 42 | */ | ||
| 43 | std::vector<u8> CompressDataLZ4HCMax(const u8* source, std::size_t source_size); | ||
| 44 | |||
| 45 | /** | ||
| 46 | * Decompresses a source memory region with LZ4 and returns the uncompressed data in a vector. | ||
| 47 | * | ||
| 48 | * @param compressed the compressed source memory region. | ||
| 49 | * @param uncompressed_size the size in bytes of the uncompressed data. | ||
| 50 | * | ||
| 51 | * @return the decompressed data. | ||
| 52 | */ | ||
| 53 | std::vector<u8> DecompressDataLZ4(const std::vector<u8>& compressed, std::size_t uncompressed_size); | ||
| 54 | |||
| 55 | } // namespace Common::Compression \ No newline at end of file | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9e23afe85..c59107102 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -458,7 +458,7 @@ add_library(core STATIC | |||
| 458 | create_target_directory_groups(core) | 458 | create_target_directory_groups(core) |
| 459 | 459 | ||
| 460 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) | 460 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) |
| 461 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static mbedtls opus unicorn open_source_archives) | 461 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt mbedtls opus unicorn open_source_archives) |
| 462 | if (ENABLE_WEB_SERVICE) | 462 | if (ENABLE_WEB_SERVICE) |
| 463 | target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE) | 463 | target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE) |
| 464 | target_link_libraries(core PRIVATE web_service) | 464 | target_link_libraries(core PRIVATE web_service) |
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index 217144efc..10431e94c 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp | |||
| @@ -24,7 +24,6 @@ bool Object::IsWaitable() const { | |||
| 24 | case HandleType::WritableEvent: | 24 | case HandleType::WritableEvent: |
| 25 | case HandleType::SharedMemory: | 25 | case HandleType::SharedMemory: |
| 26 | case HandleType::TransferMemory: | 26 | case HandleType::TransferMemory: |
| 27 | case HandleType::AddressArbiter: | ||
| 28 | case HandleType::ResourceLimit: | 27 | case HandleType::ResourceLimit: |
| 29 | case HandleType::ClientPort: | 28 | case HandleType::ClientPort: |
| 30 | case HandleType::ClientSession: | 29 | case HandleType::ClientSession: |
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 3f6baa094..332876c27 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h | |||
| @@ -25,7 +25,6 @@ enum class HandleType : u32 { | |||
| 25 | TransferMemory, | 25 | TransferMemory, |
| 26 | Thread, | 26 | Thread, |
| 27 | Process, | 27 | Process, |
| 28 | AddressArbiter, | ||
| 29 | ResourceLimit, | 28 | ResourceLimit, |
| 30 | ClientPort, | 29 | ClientPort, |
| 31 | ServerPort, | 30 | ServerPort, |
diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp index 23228e1b5..26c4e5e67 100644 --- a/src/core/hle/kernel/transfer_memory.cpp +++ b/src/core/hle/kernel/transfer_memory.cpp | |||
| @@ -14,8 +14,8 @@ namespace Kernel { | |||
| 14 | TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {} | 14 | TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {} |
| 15 | TransferMemory::~TransferMemory() = default; | 15 | TransferMemory::~TransferMemory() = default; |
| 16 | 16 | ||
| 17 | SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, | 17 | SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, u64 size, |
| 18 | size_t size, MemoryPermission permissions) { | 18 | MemoryPermission permissions) { |
| 19 | SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)}; | 19 | SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)}; |
| 20 | 20 | ||
| 21 | transfer_memory->base_address = base_address; | 21 | transfer_memory->base_address = base_address; |
| @@ -26,7 +26,15 @@ SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_ | |||
| 26 | return transfer_memory; | 26 | return transfer_memory; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermission permissions) { | 29 | const u8* TransferMemory::GetPointer() const { |
| 30 | return backing_block.get()->data(); | ||
| 31 | } | ||
| 32 | |||
| 33 | u64 TransferMemory::GetSize() const { | ||
| 34 | return memory_size; | ||
| 35 | } | ||
| 36 | |||
| 37 | ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission permissions) { | ||
| 30 | if (memory_size != size) { | 38 | if (memory_size != size) { |
| 31 | return ERR_INVALID_SIZE; | 39 | return ERR_INVALID_SIZE; |
| 32 | } | 40 | } |
| @@ -39,13 +47,13 @@ ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermissio | |||
| 39 | return ERR_INVALID_STATE; | 47 | return ERR_INVALID_STATE; |
| 40 | } | 48 | } |
| 41 | 49 | ||
| 50 | backing_block = std::make_shared<std::vector<u8>>(size); | ||
| 51 | |||
| 42 | const auto map_state = owner_permissions == MemoryPermission::None | 52 | const auto map_state = owner_permissions == MemoryPermission::None |
| 43 | ? MemoryState::TransferMemoryIsolated | 53 | ? MemoryState::TransferMemoryIsolated |
| 44 | : MemoryState::TransferMemory; | 54 | : MemoryState::TransferMemory; |
| 45 | auto& vm_manager = owner_process->VMManager(); | 55 | auto& vm_manager = owner_process->VMManager(); |
| 46 | const auto map_result = vm_manager.MapMemoryBlock( | 56 | const auto map_result = vm_manager.MapMemoryBlock(address, backing_block, 0, size, map_state); |
| 47 | address, std::make_shared<std::vector<u8>>(size), 0, size, map_state); | ||
| 48 | |||
| 49 | if (map_result.Failed()) { | 57 | if (map_result.Failed()) { |
| 50 | return map_result.Code(); | 58 | return map_result.Code(); |
| 51 | } | 59 | } |
| @@ -54,7 +62,7 @@ ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermissio | |||
| 54 | return RESULT_SUCCESS; | 62 | return RESULT_SUCCESS; |
| 55 | } | 63 | } |
| 56 | 64 | ||
| 57 | ResultCode TransferMemory::UnmapMemory(VAddr address, size_t size) { | 65 | ResultCode TransferMemory::UnmapMemory(VAddr address, u64 size) { |
| 58 | if (memory_size != size) { | 66 | if (memory_size != size) { |
| 59 | return ERR_INVALID_SIZE; | 67 | return ERR_INVALID_SIZE; |
| 60 | } | 68 | } |
diff --git a/src/core/hle/kernel/transfer_memory.h b/src/core/hle/kernel/transfer_memory.h index ec294951e..a140b1e2b 100644 --- a/src/core/hle/kernel/transfer_memory.h +++ b/src/core/hle/kernel/transfer_memory.h | |||
| @@ -4,6 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 7 | #include "core/hle/kernel/object.h" | 10 | #include "core/hle/kernel/object.h" |
| 8 | 11 | ||
| 9 | union ResultCode; | 12 | union ResultCode; |
| @@ -25,7 +28,7 @@ class TransferMemory final : public Object { | |||
| 25 | public: | 28 | public: |
| 26 | static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; | 29 | static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; |
| 27 | 30 | ||
| 28 | static SharedPtr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, size_t size, | 31 | static SharedPtr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, u64 size, |
| 29 | MemoryPermission permissions); | 32 | MemoryPermission permissions); |
| 30 | 33 | ||
| 31 | TransferMemory(const TransferMemory&) = delete; | 34 | TransferMemory(const TransferMemory&) = delete; |
| @@ -46,6 +49,12 @@ public: | |||
| 46 | return HANDLE_TYPE; | 49 | return HANDLE_TYPE; |
| 47 | } | 50 | } |
| 48 | 51 | ||
| 52 | /// Gets a pointer to the backing block of this instance. | ||
| 53 | const u8* GetPointer() const; | ||
| 54 | |||
| 55 | /// Gets the size of the memory backing this instance in bytes. | ||
| 56 | u64 GetSize() const; | ||
| 57 | |||
| 49 | /// Attempts to map transfer memory with the given range and memory permissions. | 58 | /// Attempts to map transfer memory with the given range and memory permissions. |
| 50 | /// | 59 | /// |
| 51 | /// @param address The base address to being mapping memory at. | 60 | /// @param address The base address to being mapping memory at. |
| @@ -56,7 +65,7 @@ public: | |||
| 56 | /// the same values that were given when creating the transfer memory | 65 | /// the same values that were given when creating the transfer memory |
| 57 | /// instance. | 66 | /// instance. |
| 58 | /// | 67 | /// |
| 59 | ResultCode MapMemory(VAddr address, size_t size, MemoryPermission permissions); | 68 | ResultCode MapMemory(VAddr address, u64 size, MemoryPermission permissions); |
| 60 | 69 | ||
| 61 | /// Unmaps the transfer memory with the given range | 70 | /// Unmaps the transfer memory with the given range |
| 62 | /// | 71 | /// |
| @@ -66,17 +75,20 @@ public: | |||
| 66 | /// @pre The given address and size must be the same as the ones used | 75 | /// @pre The given address and size must be the same as the ones used |
| 67 | /// to create the transfer memory instance. | 76 | /// to create the transfer memory instance. |
| 68 | /// | 77 | /// |
| 69 | ResultCode UnmapMemory(VAddr address, size_t size); | 78 | ResultCode UnmapMemory(VAddr address, u64 size); |
| 70 | 79 | ||
| 71 | private: | 80 | private: |
| 72 | explicit TransferMemory(KernelCore& kernel); | 81 | explicit TransferMemory(KernelCore& kernel); |
| 73 | ~TransferMemory() override; | 82 | ~TransferMemory() override; |
| 74 | 83 | ||
| 84 | /// Memory block backing this instance. | ||
| 85 | std::shared_ptr<std::vector<u8>> backing_block; | ||
| 86 | |||
| 75 | /// The base address for the memory managed by this instance. | 87 | /// The base address for the memory managed by this instance. |
| 76 | VAddr base_address = 0; | 88 | VAddr base_address = 0; |
| 77 | 89 | ||
| 78 | /// Size of the memory, in bytes, that this instance manages. | 90 | /// Size of the memory, in bytes, that this instance manages. |
| 79 | size_t memory_size = 0; | 91 | u64 memory_size = 0; |
| 80 | 92 | ||
| 81 | /// The memory permissions that are applied to this instance. | 93 | /// The memory permissions that are applied to this instance. |
| 82 | MemoryPermission owner_permissions{}; | 94 | MemoryPermission owner_permissions{}; |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index d31ab7970..a13433bcf 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/process.h" | 14 | #include "core/hle/kernel/process.h" |
| 15 | #include "core/hle/kernel/readable_event.h" | 15 | #include "core/hle/kernel/readable_event.h" |
| 16 | #include "core/hle/kernel/shared_memory.h" | 16 | #include "core/hle/kernel/transfer_memory.h" |
| 17 | #include "core/hle/kernel/writable_event.h" | 17 | #include "core/hle/kernel/writable_event.h" |
| 18 | #include "core/hle/service/acc/profile_manager.h" | 18 | #include "core/hle/service/acc/profile_manager.h" |
| 19 | #include "core/hle/service/am/am.h" | 19 | #include "core/hle/service/am/am.h" |
| @@ -931,19 +931,19 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex | |||
| 931 | rp.SetCurrentOffset(3); | 931 | rp.SetCurrentOffset(3); |
| 932 | const auto handle{rp.Pop<Kernel::Handle>()}; | 932 | const auto handle{rp.Pop<Kernel::Handle>()}; |
| 933 | 933 | ||
| 934 | const auto shared_mem = | 934 | const auto transfer_mem = |
| 935 | Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get<Kernel::SharedMemory>( | 935 | Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>( |
| 936 | handle); | 936 | handle); |
| 937 | 937 | ||
| 938 | if (shared_mem == nullptr) { | 938 | if (transfer_mem == nullptr) { |
| 939 | LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle); | 939 | LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle); |
| 940 | IPC::ResponseBuilder rb{ctx, 2}; | 940 | IPC::ResponseBuilder rb{ctx, 2}; |
| 941 | rb.Push(ResultCode(-1)); | 941 | rb.Push(ResultCode(-1)); |
| 942 | return; | 942 | return; |
| 943 | } | 943 | } |
| 944 | 944 | ||
| 945 | const u8* mem_begin = shared_mem->GetPointer(); | 945 | const u8* const mem_begin = transfer_mem->GetPointer(); |
| 946 | const u8* mem_end = mem_begin + shared_mem->GetSize(); | 946 | const u8* const mem_end = mem_begin + transfer_mem->GetSize(); |
| 947 | std::vector<u8> memory{mem_begin, mem_end}; | 947 | std::vector<u8> memory{mem_begin, mem_end}; |
| 948 | 948 | ||
| 949 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 949 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index babc7e646..ffe2eea8a 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -4,11 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #include <cinttypes> | 5 | #include <cinttypes> |
| 6 | #include <vector> | 6 | #include <vector> |
| 7 | #include <lz4.h> | 7 | |
| 8 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 9 | #include "common/file_util.h" | 9 | #include "common/file_util.h" |
| 10 | #include "common/hex_util.h" | 10 | #include "common/hex_util.h" |
| 11 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 12 | #include "common/lz4_compression.h" | ||
| 12 | #include "common/swap.h" | 13 | #include "common/swap.h" |
| 13 | #include "core/core.h" | 14 | #include "core/core.h" |
| 14 | #include "core/file_sys/patch_manager.h" | 15 | #include "core/file_sys/patch_manager.h" |
| @@ -35,15 +36,11 @@ static_assert(sizeof(MODHeader) == 0x1c, "MODHeader has incorrect size."); | |||
| 35 | 36 | ||
| 36 | std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data, | 37 | std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data, |
| 37 | const NSOSegmentHeader& header) { | 38 | const NSOSegmentHeader& header) { |
| 38 | std::vector<u8> uncompressed_data(header.size); | 39 | const std::vector<u8> uncompressed_data = |
| 39 | const int bytes_uncompressed = | 40 | Common::Compression::DecompressDataLZ4(compressed_data, header.size); |
| 40 | LZ4_decompress_safe(reinterpret_cast<const char*>(compressed_data.data()), | 41 | |
| 41 | reinterpret_cast<char*>(uncompressed_data.data()), | 42 | ASSERT_MSG(uncompressed_data.size() == static_cast<int>(header.size), "{} != {}", header.size, |
| 42 | static_cast<int>(compressed_data.size()), header.size); | 43 | uncompressed_data.size()); |
| 43 | |||
| 44 | ASSERT_MSG(bytes_uncompressed == static_cast<int>(header.size) && | ||
| 45 | bytes_uncompressed == static_cast<int>(uncompressed_data.size()), | ||
| 46 | "{} != {} != {}", bytes_uncompressed, header.size, uncompressed_data.size()); | ||
| 47 | 44 | ||
| 48 | return uncompressed_data; | 45 | return uncompressed_data; |
| 49 | } | 46 | } |
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 44c761d3e..242a0d1cd 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -139,4 +139,4 @@ endif() | |||
| 139 | create_target_directory_groups(video_core) | 139 | create_target_directory_groups(video_core) |
| 140 | 140 | ||
| 141 | target_link_libraries(video_core PUBLIC common core) | 141 | target_link_libraries(video_core PUBLIC common core) |
| 142 | target_link_libraries(video_core PRIVATE glad lz4_static) | 142 | target_link_libraries(video_core PRIVATE glad) |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index fd091c84c..7989ec11b 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | 7 | ||
| 8 | #include "common/alignment.h" | 8 | #include "common/alignment.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/memory.h" | ||
| 11 | #include "video_core/renderer_opengl/gl_buffer_cache.h" | 10 | #include "video_core/renderer_opengl/gl_buffer_cache.h" |
| 12 | #include "video_core/renderer_opengl/gl_rasterizer.h" | 11 | #include "video_core/renderer_opengl/gl_rasterizer.h" |
| 13 | 12 | ||
diff --git a/src/video_core/renderer_opengl/gl_global_cache.cpp b/src/video_core/renderer_opengl/gl_global_cache.cpp index da9326253..5842d6213 100644 --- a/src/video_core/renderer_opengl/gl_global_cache.cpp +++ b/src/video_core/renderer_opengl/gl_global_cache.cpp | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #include <glad/glad.h> | 5 | #include <glad/glad.h> |
| 6 | 6 | ||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 9 | #include "core/core.h" | 8 | #include "core/core.h" |
| 10 | #include "video_core/renderer_opengl/gl_global_cache.h" | 9 | #include "video_core/renderer_opengl/gl_global_cache.h" |
diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp index 2bcbd3da2..c3e94d917 100644 --- a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp +++ b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/memory.h" | 10 | #include "video_core/memory_manager.h" |
| 11 | #include "video_core/renderer_opengl/gl_buffer_cache.h" | 11 | #include "video_core/renderer_opengl/gl_buffer_cache.h" |
| 12 | #include "video_core/renderer_opengl/gl_primitive_assembler.h" | 12 | #include "video_core/renderer_opengl/gl_primitive_assembler.h" |
| 13 | 13 | ||
diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.h b/src/video_core/renderer_opengl/gl_primitive_assembler.h index 0e2e7dc36..4e87ce4d6 100644 --- a/src/video_core/renderer_opengl/gl_primitive_assembler.h +++ b/src/video_core/renderer_opengl/gl_primitive_assembler.h | |||
| @@ -4,11 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <vector> | ||
| 8 | #include <glad/glad.h> | 7 | #include <glad/glad.h> |
| 9 | 8 | ||
| 10 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 11 | #include "video_core/memory_manager.h" | ||
| 12 | 10 | ||
| 13 | namespace OpenGL { | 11 | namespace OpenGL { |
| 14 | 12 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 046fc935b..7ff1e6737 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include "common/microprofile.h" | 17 | #include "common/microprofile.h" |
| 18 | #include "common/scope_exit.h" | 18 | #include "common/scope_exit.h" |
| 19 | #include "core/core.h" | 19 | #include "core/core.h" |
| 20 | #include "core/frontend/emu_window.h" | ||
| 21 | #include "core/hle/kernel/process.h" | 20 | #include "core/hle/kernel/process.h" |
| 22 | #include "core/settings.h" | 21 | #include "core/settings.h" |
| 23 | #include "video_core/engines/maxwell_3d.h" | 22 | #include "video_core/engines/maxwell_3d.h" |
| @@ -26,7 +25,6 @@ | |||
| 26 | #include "video_core/renderer_opengl/gl_shader_gen.h" | 25 | #include "video_core/renderer_opengl/gl_shader_gen.h" |
| 27 | #include "video_core/renderer_opengl/maxwell_to_gl.h" | 26 | #include "video_core/renderer_opengl/maxwell_to_gl.h" |
| 28 | #include "video_core/renderer_opengl/renderer_opengl.h" | 27 | #include "video_core/renderer_opengl/renderer_opengl.h" |
| 29 | #include "video_core/video_core.h" | ||
| 30 | 28 | ||
| 31 | namespace OpenGL { | 29 | namespace OpenGL { |
| 32 | 30 | ||
| @@ -318,7 +316,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 318 | const std::size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 | 316 | const std::size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 |
| 319 | 317 | ||
| 320 | GLShader::MaxwellUniformData ubo{}; | 318 | GLShader::MaxwellUniformData ubo{}; |
| 321 | ubo.SetFromRegs(gpu.state.shader_stages[stage]); | 319 | ubo.SetFromRegs(gpu, stage); |
| 322 | const GLintptr offset = buffer_cache.UploadHostMemory( | 320 | const GLintptr offset = buffer_cache.UploadHostMemory( |
| 323 | &ubo, sizeof(ubo), static_cast<std::size_t>(uniform_buffer_alignment)); | 321 | &ubo, sizeof(ubo), static_cast<std::size_t>(uniform_buffer_alignment)); |
| 324 | 322 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 4de565321..54fbf48aa 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -12,15 +12,12 @@ | |||
| 12 | #include <optional> | 12 | #include <optional> |
| 13 | #include <tuple> | 13 | #include <tuple> |
| 14 | #include <utility> | 14 | #include <utility> |
| 15 | #include <vector> | ||
| 16 | 15 | ||
| 17 | #include <boost/icl/interval_map.hpp> | 16 | #include <boost/icl/interval_map.hpp> |
| 18 | #include <boost/range/iterator_range.hpp> | ||
| 19 | #include <glad/glad.h> | 17 | #include <glad/glad.h> |
| 20 | 18 | ||
| 21 | #include "common/common_types.h" | 19 | #include "common/common_types.h" |
| 22 | #include "video_core/engines/maxwell_3d.h" | 20 | #include "video_core/engines/maxwell_3d.h" |
| 23 | #include "video_core/memory_manager.h" | ||
| 24 | #include "video_core/rasterizer_cache.h" | 21 | #include "video_core/rasterizer_cache.h" |
| 25 | #include "video_core/rasterizer_interface.h" | 22 | #include "video_core/rasterizer_interface.h" |
| 26 | #include "video_core/renderer_opengl/gl_buffer_cache.h" | 23 | #include "video_core/renderer_opengl/gl_buffer_cache.h" |
| @@ -29,10 +26,8 @@ | |||
| 29 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" | 26 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" |
| 30 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 27 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 31 | #include "video_core/renderer_opengl/gl_shader_cache.h" | 28 | #include "video_core/renderer_opengl/gl_shader_cache.h" |
| 32 | #include "video_core/renderer_opengl/gl_shader_gen.h" | ||
| 33 | #include "video_core/renderer_opengl/gl_shader_manager.h" | 29 | #include "video_core/renderer_opengl/gl_shader_manager.h" |
| 34 | #include "video_core/renderer_opengl/gl_state.h" | 30 | #include "video_core/renderer_opengl/gl_state.h" |
| 35 | #include "video_core/renderer_opengl/gl_stream_buffer.h" | ||
| 36 | 31 | ||
| 37 | namespace Core { | 32 | namespace Core { |
| 38 | class System; | 33 | class System; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index aba6ce731..7a3280620 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include "common/scope_exit.h" | 13 | #include "common/scope_exit.h" |
| 14 | #include "core/core.h" | 14 | #include "core/core.h" |
| 15 | #include "core/hle/kernel/process.h" | 15 | #include "core/hle/kernel/process.h" |
| 16 | #include "core/memory.h" | ||
| 17 | #include "core/settings.h" | 16 | #include "core/settings.h" |
| 18 | #include "video_core/engines/maxwell_3d.h" | 17 | #include "video_core/engines/maxwell_3d.h" |
| 19 | #include "video_core/morton.h" | 18 | #include "video_core/morton.h" |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index e8073579f..ad4fd3ad2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -5,10 +5,9 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <map> | ||
| 9 | #include <memory> | 8 | #include <memory> |
| 10 | #include <string> | 9 | #include <string> |
| 11 | #include <unordered_set> | 10 | #include <tuple> |
| 12 | #include <vector> | 11 | #include <vector> |
| 13 | 12 | ||
| 14 | #include "common/alignment.h" | 13 | #include "common/alignment.h" |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 290e654bc..7030db365 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -6,13 +6,11 @@ | |||
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/hash.h" | 7 | #include "common/hash.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/memory.h" | ||
| 10 | #include "video_core/engines/maxwell_3d.h" | 9 | #include "video_core/engines/maxwell_3d.h" |
| 11 | #include "video_core/renderer_opengl/gl_rasterizer.h" | 10 | #include "video_core/renderer_opengl/gl_rasterizer.h" |
| 12 | #include "video_core/renderer_opengl/gl_shader_cache.h" | 11 | #include "video_core/renderer_opengl/gl_shader_cache.h" |
| 13 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | 12 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" |
| 14 | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" | 13 | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" |
| 15 | #include "video_core/renderer_opengl/gl_shader_manager.h" | ||
| 16 | #include "video_core/renderer_opengl/utils.h" | 14 | #include "video_core/renderer_opengl/utils.h" |
| 17 | #include "video_core/shader/shader_ir.h" | 15 | #include "video_core/shader/shader_ir.h" |
| 18 | 16 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index fd1c85115..0cf8e0b3d 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -5,21 +5,20 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <atomic> | ||
| 8 | #include <memory> | 9 | #include <memory> |
| 9 | #include <set> | 10 | #include <set> |
| 10 | #include <tuple> | 11 | #include <tuple> |
| 11 | #include <unordered_map> | 12 | #include <unordered_map> |
| 13 | #include <vector> | ||
| 12 | 14 | ||
| 13 | #include <glad/glad.h> | 15 | #include <glad/glad.h> |
| 14 | 16 | ||
| 15 | #include "common/assert.h" | ||
| 16 | #include "common/common_types.h" | 17 | #include "common/common_types.h" |
| 17 | #include "video_core/rasterizer_cache.h" | 18 | #include "video_core/rasterizer_cache.h" |
| 18 | #include "video_core/renderer_base.h" | ||
| 19 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 19 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 20 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | 20 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" |
| 21 | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" | 21 | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" |
| 22 | #include "video_core/renderer_opengl/gl_shader_gen.h" | ||
| 23 | 22 | ||
| 24 | namespace Core { | 23 | namespace Core { |
| 25 | class System; | 24 | class System; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h index 72aca4938..4e04ab2f8 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.h +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <set> | ||
| 9 | #include <string> | 8 | #include <string> |
| 10 | #include <utility> | 9 | #include <utility> |
| 11 | #include <vector> | 10 | #include <vector> |
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index 82fc4d44b..d2d979997 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | |||
| @@ -4,13 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include <fmt/format.h> | 6 | #include <fmt/format.h> |
| 7 | #include <lz4.h> | ||
| 8 | 7 | ||
| 9 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 10 | #include "common/common_paths.h" | 9 | #include "common/common_paths.h" |
| 11 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 12 | #include "common/file_util.h" | 11 | #include "common/file_util.h" |
| 13 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 13 | #include "common/lz4_compression.h" | ||
| 14 | #include "common/scm_rev.h" | 14 | #include "common/scm_rev.h" |
| 15 | 15 | ||
| 16 | #include "core/core.h" | 16 | #include "core/core.h" |
| @@ -49,39 +49,6 @@ ShaderCacheVersionHash GetShaderCacheVersionHash() { | |||
| 49 | return hash; | 49 | return hash; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | template <typename T> | ||
| 53 | std::vector<u8> CompressData(const T* source, std::size_t source_size) { | ||
| 54 | if (source_size > LZ4_MAX_INPUT_SIZE) { | ||
| 55 | // Source size exceeds LZ4 maximum input size | ||
| 56 | return {}; | ||
| 57 | } | ||
| 58 | const auto source_size_int = static_cast<int>(source_size); | ||
| 59 | const int max_compressed_size = LZ4_compressBound(source_size_int); | ||
| 60 | std::vector<u8> compressed(max_compressed_size); | ||
| 61 | const int compressed_size = LZ4_compress_default(reinterpret_cast<const char*>(source), | ||
| 62 | reinterpret_cast<char*>(compressed.data()), | ||
| 63 | source_size_int, max_compressed_size); | ||
| 64 | if (compressed_size <= 0) { | ||
| 65 | // Compression failed | ||
| 66 | return {}; | ||
| 67 | } | ||
| 68 | compressed.resize(compressed_size); | ||
| 69 | return compressed; | ||
| 70 | } | ||
| 71 | |||
| 72 | std::vector<u8> DecompressData(const std::vector<u8>& compressed, std::size_t uncompressed_size) { | ||
| 73 | std::vector<u8> uncompressed(uncompressed_size); | ||
| 74 | const int size_check = LZ4_decompress_safe(reinterpret_cast<const char*>(compressed.data()), | ||
| 75 | reinterpret_cast<char*>(uncompressed.data()), | ||
| 76 | static_cast<int>(compressed.size()), | ||
| 77 | static_cast<int>(uncompressed.size())); | ||
| 78 | if (static_cast<int>(uncompressed_size) != size_check) { | ||
| 79 | // Decompression failed | ||
| 80 | return {}; | ||
| 81 | } | ||
| 82 | return uncompressed; | ||
| 83 | } | ||
| 84 | |||
| 85 | } // namespace | 52 | } // namespace |
| 86 | 53 | ||
| 87 | ShaderDiskCacheRaw::ShaderDiskCacheRaw(u64 unique_identifier, Maxwell::ShaderProgram program_type, | 54 | ShaderDiskCacheRaw::ShaderDiskCacheRaw(u64 unique_identifier, Maxwell::ShaderProgram program_type, |
| @@ -292,7 +259,7 @@ ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) { | |||
| 292 | return {}; | 259 | return {}; |
| 293 | } | 260 | } |
| 294 | 261 | ||
| 295 | dump.binary = DecompressData(compressed_binary, binary_length); | 262 | dump.binary = Common::Compression::DecompressDataLZ4(compressed_binary, binary_length); |
| 296 | if (dump.binary.empty()) { | 263 | if (dump.binary.empty()) { |
| 297 | return {}; | 264 | return {}; |
| 298 | } | 265 | } |
| @@ -321,7 +288,7 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn | |||
| 321 | return {}; | 288 | return {}; |
| 322 | } | 289 | } |
| 323 | 290 | ||
| 324 | const std::vector<u8> code = DecompressData(compressed_code, code_size); | 291 | const std::vector<u8> code = Common::Compression::DecompressDataLZ4(compressed_code, code_size); |
| 325 | if (code.empty()) { | 292 | if (code.empty()) { |
| 326 | return {}; | 293 | return {}; |
| 327 | } | 294 | } |
| @@ -507,7 +474,8 @@ void ShaderDiskCacheOpenGL::SaveDecompiled(u64 unique_identifier, const std::str | |||
| 507 | if (!IsUsable()) | 474 | if (!IsUsable()) |
| 508 | return; | 475 | return; |
| 509 | 476 | ||
| 510 | const std::vector<u8> compressed_code{CompressData(code.data(), code.size())}; | 477 | const std::vector<u8> compressed_code{Common::Compression::CompressDataLZ4HC( |
| 478 | reinterpret_cast<const u8*>(code.data()), code.size(), 9)}; | ||
| 511 | if (compressed_code.empty()) { | 479 | if (compressed_code.empty()) { |
| 512 | LOG_ERROR(Render_OpenGL, "Failed to compress GLSL code - skipping shader {:016x}", | 480 | LOG_ERROR(Render_OpenGL, "Failed to compress GLSL code - skipping shader {:016x}", |
| 513 | unique_identifier); | 481 | unique_identifier); |
| @@ -537,7 +505,9 @@ void ShaderDiskCacheOpenGL::SaveDump(const ShaderDiskCacheUsage& usage, GLuint p | |||
| 537 | std::vector<u8> binary(binary_length); | 505 | std::vector<u8> binary(binary_length); |
| 538 | glGetProgramBinary(program, binary_length, nullptr, &binary_format, binary.data()); | 506 | glGetProgramBinary(program, binary_length, nullptr, &binary_format, binary.data()); |
| 539 | 507 | ||
| 540 | const std::vector<u8> compressed_binary = CompressData(binary.data(), binary.size()); | 508 | const std::vector<u8> compressed_binary = |
| 509 | Common::Compression::CompressDataLZ4HC(binary.data(), binary.size(), 9); | ||
| 510 | |||
| 541 | if (compressed_binary.empty()) { | 511 | if (compressed_binary.empty()) { |
| 542 | LOG_ERROR(Render_OpenGL, "Failed to compress binary program in shader={:016x}", | 512 | LOG_ERROR(Render_OpenGL, "Failed to compress binary program in shader={:016x}", |
| 543 | usage.unique_identifier); | 513 | usage.unique_identifier); |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 7d96649af..8763d9c71 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.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 <fmt/format.h> | 5 | #include <fmt/format.h> |
| 6 | #include "common/assert.h" | ||
| 7 | #include "video_core/engines/maxwell_3d.h" | 6 | #include "video_core/engines/maxwell_3d.h" |
| 8 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | 7 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" |
| 9 | #include "video_core/renderer_opengl/gl_shader_gen.h" | 8 | #include "video_core/renderer_opengl/gl_shader_gen.h" |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h index fba8e681b..fad346b48 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.h +++ b/src/video_core/renderer_opengl/gl_shader_gen.h | |||
| @@ -4,12 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 8 | #include <string> | ||
| 9 | #include <vector> | 7 | #include <vector> |
| 10 | 8 | ||
| 11 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 12 | #include "video_core/engines/shader_bytecode.h" | ||
| 13 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | 10 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" |
| 14 | #include "video_core/shader/shader_ir.h" | 11 | #include "video_core/shader/shader_ir.h" |
| 15 | 12 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 6a30c28d2..eaf3e03a0 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp | |||
| @@ -2,15 +2,15 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "video_core/renderer_opengl/gl_shader_manager.h" | 5 | #include "video_core/renderer_opengl/gl_shader_manager.h" |
| 7 | 6 | ||
| 8 | namespace OpenGL::GLShader { | 7 | namespace OpenGL::GLShader { |
| 9 | 8 | ||
| 10 | void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) { | 9 | using Tegra::Engines::Maxwell3D; |
| 11 | const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); | 10 | |
| 12 | const auto& regs = gpu.regs; | 11 | void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shader_stage) { |
| 13 | const auto& state = gpu.state; | 12 | const auto& regs = maxwell.regs; |
| 13 | const auto& state = maxwell.state; | ||
| 14 | 14 | ||
| 15 | // TODO(bunnei): Support more than one viewport | 15 | // TODO(bunnei): Support more than one viewport |
| 16 | viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; | 16 | viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; |
| @@ -18,7 +18,7 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& sh | |||
| 18 | 18 | ||
| 19 | u32 func = static_cast<u32>(regs.alpha_test_func); | 19 | u32 func = static_cast<u32>(regs.alpha_test_func); |
| 20 | // Normalize the gl variants of opCompare to be the same as the normal variants | 20 | // Normalize the gl variants of opCompare to be the same as the normal variants |
| 21 | u32 op_gl_variant_base = static_cast<u32>(Tegra::Engines::Maxwell3D::Regs::ComparisonOp::Never); | 21 | const u32 op_gl_variant_base = static_cast<u32>(Maxwell3D::Regs::ComparisonOp::Never); |
| 22 | if (func >= op_gl_variant_base) { | 22 | if (func >= op_gl_variant_base) { |
| 23 | func = func - op_gl_variant_base + 1U; | 23 | func = func - op_gl_variant_base + 1U; |
| 24 | } | 24 | } |
| @@ -31,8 +31,9 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& sh | |||
| 31 | 31 | ||
| 32 | // Assign in which stage the position has to be flipped | 32 | // Assign in which stage the position has to be flipped |
| 33 | // (the last stage before the fragment shader). | 33 | // (the last stage before the fragment shader). |
| 34 | if (gpu.regs.shader_config[static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry)].enable) { | 34 | constexpr u32 geometry_index = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry); |
| 35 | flip_stage = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry); | 35 | if (maxwell.regs.shader_config[geometry_index].enable) { |
| 36 | flip_stage = geometry_index; | ||
| 36 | } else { | 37 | } else { |
| 37 | flip_stage = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::VertexB); | 38 | flip_stage = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::VertexB); |
| 38 | } | 39 | } |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 4970aafed..8eef2a920 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -12,14 +12,13 @@ | |||
| 12 | 12 | ||
| 13 | namespace OpenGL::GLShader { | 13 | namespace OpenGL::GLShader { |
| 14 | 14 | ||
| 15 | using Tegra::Engines::Maxwell3D; | ||
| 16 | |||
| 17 | /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned | 15 | /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned |
| 18 | // NOTE: Always keep a vec4 at the end. The GL spec is not clear whether the alignment at | 16 | /// @note Always keep a vec4 at the end. The GL spec is not clear whether the alignment at |
| 19 | // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. | 17 | /// the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. |
| 20 | // Not following that rule will cause problems on some AMD drivers. | 18 | /// Not following that rule will cause problems on some AMD drivers. |
| 21 | struct MaxwellUniformData { | 19 | struct MaxwellUniformData { |
| 22 | void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); | 20 | void SetFromRegs(const Tegra::Engines::Maxwell3D& maxwell, std::size_t shader_stage); |
| 21 | |||
| 23 | alignas(16) GLvec4 viewport_flip; | 22 | alignas(16) GLvec4 viewport_flip; |
| 24 | struct alignas(16) { | 23 | struct alignas(16) { |
| 25 | GLuint instance_id; | 24 | GLuint instance_id; |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index a01efeb05..d69cba9c3 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <cstddef> | 6 | #include <cstddef> |
| 7 | #include <cstdlib> | 7 | #include <cstdlib> |
| 8 | #include <cstring> | ||
| 9 | #include <memory> | 8 | #include <memory> |
| 10 | #include <glad/glad.h> | 9 | #include <glad/glad.h> |
| 11 | #include "common/assert.h" | 10 | #include "common/assert.h" |
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index c0e3c5fa9..4422a572b 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -329,6 +329,8 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { | |||
| 329 | QMenu context_menu; | 329 | QMenu context_menu; |
| 330 | QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location")); | 330 | QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location")); |
| 331 | QAction* open_lfs_location = context_menu.addAction(tr("Open Mod Data Location")); | 331 | QAction* open_lfs_location = context_menu.addAction(tr("Open Mod Data Location")); |
| 332 | QAction* open_transferable_shader_cache = | ||
| 333 | context_menu.addAction(tr("Open Transferable Shader Cache")); | ||
| 332 | context_menu.addSeparator(); | 334 | context_menu.addSeparator(); |
| 333 | QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS")); | 335 | QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS")); |
| 334 | QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); | 336 | QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); |
| @@ -344,6 +346,8 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { | |||
| 344 | [&]() { emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData); }); | 346 | [&]() { emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData); }); |
| 345 | connect(open_lfs_location, &QAction::triggered, | 347 | connect(open_lfs_location, &QAction::triggered, |
| 346 | [&]() { emit OpenFolderRequested(program_id, GameListOpenTarget::ModData); }); | 348 | [&]() { emit OpenFolderRequested(program_id, GameListOpenTarget::ModData); }); |
| 349 | connect(open_transferable_shader_cache, &QAction::triggered, | ||
| 350 | [&]() { emit OpenTransferableShaderCacheRequested(program_id); }); | ||
| 347 | connect(dump_romfs, &QAction::triggered, [&]() { emit DumpRomFSRequested(program_id, path); }); | 351 | connect(dump_romfs, &QAction::triggered, [&]() { emit DumpRomFSRequested(program_id, path); }); |
| 348 | connect(copy_tid, &QAction::triggered, [&]() { emit CopyTIDRequested(program_id); }); | 352 | connect(copy_tid, &QAction::triggered, [&]() { emit CopyTIDRequested(program_id); }); |
| 349 | connect(navigate_to_gamedb_entry, &QAction::triggered, | 353 | connect(navigate_to_gamedb_entry, &QAction::triggered, |
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index b317eb2fc..8ea5cbaaa 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h | |||
| @@ -66,6 +66,7 @@ signals: | |||
| 66 | void GameChosen(QString game_path); | 66 | void GameChosen(QString game_path); |
| 67 | void ShouldCancelWorker(); | 67 | void ShouldCancelWorker(); |
| 68 | void OpenFolderRequested(u64 program_id, GameListOpenTarget target); | 68 | void OpenFolderRequested(u64 program_id, GameListOpenTarget target); |
| 69 | void OpenTransferableShaderCacheRequested(u64 program_id); | ||
| 69 | void DumpRomFSRequested(u64 program_id, const std::string& game_path); | 70 | void DumpRomFSRequested(u64 program_id, const std::string& game_path); |
| 70 | void CopyTIDRequested(u64 program_id); | 71 | void CopyTIDRequested(u64 program_id); |
| 71 | void NavigateToGamedbEntryRequested(u64 program_id, | 72 | void NavigateToGamedbEntryRequested(u64 program_id, |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 41ba3c4c6..2b9db69a3 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -37,14 +37,20 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual | |||
| 37 | #include <glad/glad.h> | 37 | #include <glad/glad.h> |
| 38 | 38 | ||
| 39 | #define QT_NO_OPENGL | 39 | #define QT_NO_OPENGL |
| 40 | #include <QClipboard> | ||
| 41 | #include <QDesktopServices> | ||
| 40 | #include <QDesktopWidget> | 42 | #include <QDesktopWidget> |
| 41 | #include <QDialogButtonBox> | 43 | #include <QDialogButtonBox> |
| 42 | #include <QFile> | 44 | #include <QFile> |
| 43 | #include <QFileDialog> | 45 | #include <QFileDialog> |
| 46 | #include <QInputDialog> | ||
| 44 | #include <QMessageBox> | 47 | #include <QMessageBox> |
| 48 | #include <QProgressBar> | ||
| 49 | #include <QProgressDialog> | ||
| 50 | #include <QShortcut> | ||
| 51 | #include <QStatusBar> | ||
| 45 | #include <QtConcurrent/QtConcurrent> | 52 | #include <QtConcurrent/QtConcurrent> |
| 46 | #include <QtGui> | 53 | |
| 47 | #include <QtWidgets> | ||
| 48 | #include <fmt/format.h> | 54 | #include <fmt/format.h> |
| 49 | #include "common/common_paths.h" | 55 | #include "common/common_paths.h" |
| 50 | #include "common/detached_tasks.h" | 56 | #include "common/detached_tasks.h" |
| @@ -55,11 +61,9 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual | |||
| 55 | #include "common/microprofile.h" | 61 | #include "common/microprofile.h" |
| 56 | #include "common/scm_rev.h" | 62 | #include "common/scm_rev.h" |
| 57 | #include "common/scope_exit.h" | 63 | #include "common/scope_exit.h" |
| 58 | #include "common/string_util.h" | ||
| 59 | #include "common/telemetry.h" | 64 | #include "common/telemetry.h" |
| 60 | #include "core/core.h" | 65 | #include "core/core.h" |
| 61 | #include "core/crypto/key_manager.h" | 66 | #include "core/crypto/key_manager.h" |
| 62 | #include "core/file_sys/bis_factory.h" | ||
| 63 | #include "core/file_sys/card_image.h" | 67 | #include "core/file_sys/card_image.h" |
| 64 | #include "core/file_sys/content_archive.h" | 68 | #include "core/file_sys/content_archive.h" |
| 65 | #include "core/file_sys/control_metadata.h" | 69 | #include "core/file_sys/control_metadata.h" |
| @@ -71,7 +75,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual | |||
| 71 | #include "core/frontend/applets/software_keyboard.h" | 75 | #include "core/frontend/applets/software_keyboard.h" |
| 72 | #include "core/hle/kernel/process.h" | 76 | #include "core/hle/kernel/process.h" |
| 73 | #include "core/hle/service/filesystem/filesystem.h" | 77 | #include "core/hle/service/filesystem/filesystem.h" |
| 74 | #include "core/hle/service/filesystem/fsp_ldr.h" | ||
| 75 | #include "core/hle/service/nfp/nfp.h" | 78 | #include "core/hle/service/nfp/nfp.h" |
| 76 | #include "core/hle/service/sm/sm.h" | 79 | #include "core/hle/service/sm/sm.h" |
| 77 | #include "core/loader/loader.h" | 80 | #include "core/loader/loader.h" |
| @@ -648,6 +651,8 @@ void GMainWindow::RestoreUIState() { | |||
| 648 | void GMainWindow::ConnectWidgetEvents() { | 651 | void GMainWindow::ConnectWidgetEvents() { |
| 649 | connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile); | 652 | connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile); |
| 650 | connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder); | 653 | connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder); |
| 654 | connect(game_list, &GameList::OpenTransferableShaderCacheRequested, this, | ||
| 655 | &GMainWindow::OnTransferableShaderCacheOpenFile); | ||
| 651 | connect(game_list, &GameList::DumpRomFSRequested, this, &GMainWindow::OnGameListDumpRomFS); | 656 | connect(game_list, &GameList::DumpRomFSRequested, this, &GMainWindow::OnGameListDumpRomFS); |
| 652 | connect(game_list, &GameList::CopyTIDRequested, this, &GMainWindow::OnGameListCopyTID); | 657 | connect(game_list, &GameList::CopyTIDRequested, this, &GMainWindow::OnGameListCopyTID); |
| 653 | connect(game_list, &GameList::NavigateToGamedbEntryRequested, this, | 658 | connect(game_list, &GameList::NavigateToGamedbEntryRequested, this, |
| @@ -1082,6 +1087,39 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 1082 | QDesktopServices::openUrl(QUrl::fromLocalFile(qpath)); | 1087 | QDesktopServices::openUrl(QUrl::fromLocalFile(qpath)); |
| 1083 | } | 1088 | } |
| 1084 | 1089 | ||
| 1090 | void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) { | ||
| 1091 | ASSERT(program_id != 0); | ||
| 1092 | |||
| 1093 | const QString tranferable_shader_cache_folder_path = | ||
| 1094 | QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir)) + "opengl" + | ||
| 1095 | DIR_SEP + "transferable"; | ||
| 1096 | |||
| 1097 | const QString transferable_shader_cache_file_path = | ||
| 1098 | tranferable_shader_cache_folder_path + DIR_SEP + | ||
| 1099 | QString::fromStdString(fmt::format("{:016X}.bin", program_id)); | ||
| 1100 | |||
| 1101 | if (!QFile::exists(transferable_shader_cache_file_path)) { | ||
| 1102 | QMessageBox::warning(this, tr("Error Opening Transferable Shader Cache"), | ||
| 1103 | tr("A shader cache for this title does not exist.")); | ||
| 1104 | return; | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | // Windows supports opening a folder with selecting a specified file in explorer. On every other | ||
| 1108 | // OS we just open the transferable shader cache folder without preselecting the transferable | ||
| 1109 | // shader cache file for the selected game. | ||
| 1110 | #if defined(Q_OS_WIN) | ||
| 1111 | const QString explorer = QStringLiteral("explorer"); | ||
| 1112 | QStringList param; | ||
| 1113 | if (!QFileInfo(transferable_shader_cache_file_path).isDir()) { | ||
| 1114 | param << QStringLiteral("/select,"); | ||
| 1115 | } | ||
| 1116 | param << QDir::toNativeSeparators(transferable_shader_cache_file_path); | ||
| 1117 | QProcess::startDetached(explorer, param); | ||
| 1118 | #else | ||
| 1119 | QDesktopServices::openUrl(QUrl::fromLocalFile(tranferable_shader_cache_folder_path)); | ||
| 1120 | #endif | ||
| 1121 | } | ||
| 1122 | |||
| 1085 | static std::size_t CalculateRomFSEntrySize(const FileSys::VirtualDir& dir, bool full) { | 1123 | static std::size_t CalculateRomFSEntrySize(const FileSys::VirtualDir& dir, bool full) { |
| 1086 | std::size_t out = 0; | 1124 | std::size_t out = 0; |
| 1087 | 1125 | ||
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index e07c892cf..7f3aa998e 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -176,6 +176,7 @@ private slots: | |||
| 176 | /// Called whenever a user selects a game in the game list widget. | 176 | /// Called whenever a user selects a game in the game list widget. |
| 177 | void OnGameListLoadFile(QString game_path); | 177 | void OnGameListLoadFile(QString game_path); |
| 178 | void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target); | 178 | void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target); |
| 179 | void OnTransferableShaderCacheOpenFile(u64 program_id); | ||
| 179 | void OnGameListDumpRomFS(u64 program_id, const std::string& game_path); | 180 | void OnGameListDumpRomFS(u64 program_id, const std::string& game_path); |
| 180 | void OnGameListCopyTID(u64 program_id); | 181 | void OnGameListCopyTID(u64 program_id); |
| 181 | void OnGameListNavigateToGamedbEntry(u64 program_id, | 182 | void OnGameListNavigateToGamedbEntry(u64 program_id, |