diff options
Diffstat (limited to 'src')
60 files changed, 711 insertions, 836 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 1111cfbad..8f2591d53 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -272,8 +272,10 @@ const char* GetLogClassName(Class log_class) { #undef CLS #undef SUB case Class::Count: - UNREACHABLE(); + break; } + UNREACHABLE(); + return "Invalid"; } const char* GetLevelName(Level log_level) { @@ -288,9 +290,11 @@ const char* GetLevelName(Level log_level) { LVL(Error); LVL(Critical); case Level::Count: - UNREACHABLE(); + break; } #undef LVL + UNREACHABLE(); + return "Invalid"; } void SetGlobalFilter(const Filter& filter) { diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4f6a87b0a..f2e774a6b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -522,6 +522,23 @@ add_library(core STATIC tools/freezer.h ) +if (MSVC) + target_compile_options(core PRIVATE + # 'expression' : signed/unsigned mismatch + /we4018 + # 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point) + /we4244 + # 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch + /we4245 + # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data + /we4254 + # 'var' : conversion from 'size_t' to 'type', possible loss of data + /we4267 + # 'context' : truncation from 'type1' to 'type2' + /we4305 + ) +endif() + create_target_directory_groups(core) target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 700c4afff..a0705b2b8 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -67,7 +67,7 @@ public: ARM_Interface::ThreadContext ctx; parent.SaveContext(ctx); parent.inner_unicorn.LoadContext(ctx); - parent.inner_unicorn.ExecuteInstructions(static_cast<int>(num_instructions)); + parent.inner_unicorn.ExecuteInstructions(num_instructions); parent.inner_unicorn.SaveContext(ctx); parent.LoadContext(ctx); num_interpreted_instructions += num_instructions; diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index d4f41bfc1..9698172db 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp @@ -67,10 +67,11 @@ ARM_Unicorn::ARM_Unicorn(System& system) : system{system} { CHECKED(uc_reg_write(uc, UC_ARM64_REG_CPACR_EL1, &fpv)); uc_hook hook{}; - CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, -1)); - CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0, -1)); + CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, UINT64_MAX)); + CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0, + UINT64_MAX)); if (GDBStub::IsServerEnabled()) { - CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, -1)); + CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, UINT64_MAX)); last_bkpt_hit = false; } } @@ -154,9 +155,10 @@ void ARM_Unicorn::SetTPIDR_EL0(u64 value) { void ARM_Unicorn::Run() { if (GDBStub::IsServerEnabled()) { - ExecuteInstructions(std::max(4000000, 0)); + ExecuteInstructions(std::max(4000000U, 0U)); } else { - ExecuteInstructions(std::max(system.CoreTiming().GetDowncount(), s64{0})); + ExecuteInstructions( + std::max(std::size_t(system.CoreTiming().GetDowncount()), std::size_t{0})); } } @@ -166,7 +168,7 @@ void ARM_Unicorn::Step() { MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64)); -void ARM_Unicorn::ExecuteInstructions(int num_instructions) { +void ARM_Unicorn::ExecuteInstructions(std::size_t num_instructions) { MICROPROFILE_SCOPE(ARM_Jit_Unicorn); CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions)); system.CoreTiming().AddTicks(num_instructions); diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index fe2ffd70c..b39426ea0 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h @@ -34,7 +34,7 @@ public: void LoadContext(const ThreadContext& ctx) override; void PrepareReschedule() override; void ClearExclusiveState() override; - void ExecuteInstructions(int num_instructions); + void ExecuteInstructions(std::size_t num_instructions); void Run() override; void Step() override; void ClearInstructionCache() override; diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 487b57053..87e6a1fd3 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -22,6 +22,7 @@ #include "common/file_util.h" #include "common/hex_util.h" #include "common/logging/log.h" +#include "common/string_util.h" #include "core/core.h" #include "core/crypto/aes_util.h" #include "core/crypto/key_manager.h" @@ -378,8 +379,9 @@ std::vector<Ticket> GetTicketblob(const FileUtil::IOFile& ticket_save) { template <size_t size> static std::array<u8, size> operator^(const std::array<u8, size>& lhs, const std::array<u8, size>& rhs) { - std::array<u8, size> out{}; - std::transform(lhs.begin(), lhs.end(), rhs.begin(), out.begin(), std::bit_xor<>()); + std::array<u8, size> out; + std::transform(lhs.begin(), lhs.end(), rhs.begin(), out.begin(), + [](u8 lhs, u8 rhs) { return u8(lhs ^ rhs); }); return out; } @@ -538,7 +540,7 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { Key128 key = Common::HexStringToArray<16>(out[1]); s128_keys[{S128KeyType::Titlekey, rights_id[1], rights_id[0]}] = key; } else { - std::transform(out[0].begin(), out[0].end(), out[0].begin(), ::tolower); + out[0] = Common::ToLower(out[0]); if (s128_file_id.find(out[0]) != s128_file_id.end()) { const auto index = s128_file_id.at(out[0]); Key128 key = Common::HexStringToArray<16>(out[1]); @@ -948,12 +950,10 @@ void KeyManager::DeriveETicket(PartitionDataManager& data) { return; } - Key128 rsa_oaep_kek{}; - std::transform(seed3.begin(), seed3.end(), mask0.begin(), rsa_oaep_kek.begin(), - std::bit_xor<>()); - - if (rsa_oaep_kek == Key128{}) + const Key128 rsa_oaep_kek = seed3 ^ mask0; + if (rsa_oaep_kek == Key128{}) { return; + } SetKey(S128KeyType::Source, rsa_oaep_kek, static_cast<u64>(SourceKeyType::RSAOaepKekGeneration)); diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index a4b09fd12..d64302f2e 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -204,11 +204,12 @@ static std::array<Key128, 0x20> FindEncryptedMasterKeyFromHex(const std::vector< FileSys::VirtualFile FindFileInDirWithNames(const FileSys::VirtualDir& dir, const std::string& name) { - auto upper = name; - std::transform(upper.begin(), upper.end(), upper.begin(), [](u8 c) { return std::toupper(c); }); + const auto upper = Common::ToUpper(name); + for (const auto& fname : {name, name + ".bin", upper, upper + ".BIN"}) { - if (dir->GetFile(fname) != nullptr) + if (dir->GetFile(fname) != nullptr) { return dir->GetFile(fname); + } } return nullptr; diff --git a/src/core/file_sys/kernel_executable.cpp b/src/core/file_sys/kernel_executable.cpp index 371300684..76313679d 100644 --- a/src/core/file_sys/kernel_executable.cpp +++ b/src/core/file_sys/kernel_executable.cpp @@ -147,7 +147,7 @@ std::vector<u32> KIP::GetKernelCapabilities() const { } s32 KIP::GetMainThreadPriority() const { - return header.main_thread_priority; + return static_cast<s32>(header.main_thread_priority); } u32 KIP::GetMainThreadStackSize() const { diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 7310b3602..1d6c30962 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp @@ -52,14 +52,14 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { } void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, - u8 main_thread_prio, u8 main_thread_core, + s32 main_thread_prio, u32 main_thread_core, u32 main_thread_stack_size, u64 title_id, u64 filesystem_permissions, KernelCapabilityDescriptors capabilities) { npdm_header.has_64_bit_instructions.Assign(is_64_bit); npdm_header.address_space_type.Assign(address_space); - npdm_header.main_thread_priority = main_thread_prio; - npdm_header.main_thread_cpu = main_thread_core; + npdm_header.main_thread_priority = static_cast<u8>(main_thread_prio); + npdm_header.main_thread_cpu = static_cast<u8>(main_thread_core); npdm_header.main_stack_size = main_thread_stack_size; aci_header.title_id = title_id; aci_file_access.permissions = filesystem_permissions; diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h index 88ec97d85..f8759a396 100644 --- a/src/core/file_sys/program_metadata.h +++ b/src/core/file_sys/program_metadata.h @@ -47,8 +47,8 @@ public: Loader::ResultStatus Load(VirtualFile file); // Load from parameters instead of NPDM file, used for KIP - void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, u8 main_thread_prio, - u8 main_thread_core, u32 main_thread_stack_size, u64 title_id, + void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio, + u32 main_thread_core, u32 main_thread_stack_size, u64 title_id, u64 filesystem_permissions, KernelCapabilityDescriptors capabilities); bool Is64BitProgram() const; diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index 4bd2e6183..418a39a7e 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -71,12 +71,12 @@ ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, if (res == nullptr) { // TODO(DarkLordZach): Find the right error code to use here - return ResultCode(-1); + return RESULT_UNKNOWN; } const auto romfs = res->GetRomFS(); if (romfs == nullptr) { // TODO(DarkLordZach): Find the right error code to use here - return ResultCode(-1); + return RESULT_UNKNOWN; } return MakeResult<VirtualFile>(romfs); } diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index e2a7eaf7b..f3def93ab 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -90,7 +90,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space, // Return an error if the save data doesn't actually exist. if (out == nullptr) { // TODO(DarkLordZach): Find out correct error code. - return ResultCode(-1); + return RESULT_UNKNOWN; } return MakeResult<VirtualDir>(std::move(out)); @@ -111,7 +111,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, // Return an error if the save data doesn't actually exist. if (out == nullptr) { // TODO(Subv): Find out correct error code. - return ResultCode(-1); + return RESULT_UNKNOWN; } return MakeResult<VirtualDir>(std::move(out)); diff --git a/src/core/file_sys/vfs_libzip.cpp b/src/core/file_sys/vfs_libzip.cpp index 8bdaa7e4a..11d1978ea 100644 --- a/src/core/file_sys/vfs_libzip.cpp +++ b/src/core/file_sys/vfs_libzip.cpp @@ -27,7 +27,7 @@ VirtualDir ExtractZIP(VirtualFile file) { std::shared_ptr<VectorVfsDirectory> out = std::make_shared<VectorVfsDirectory>(); - const auto num_entries = zip_get_num_entries(zip.get(), 0); + const auto num_entries = static_cast<std::size_t>(zip_get_num_entries(zip.get(), 0)); zip_stat_t stat{}; zip_stat_init(&stat); diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp index 7ca375791..86e06ccb9 100644 --- a/src/core/file_sys/xts_archive.cpp +++ b/src/core/file_sys/xts_archive.cpp @@ -7,12 +7,13 @@ #include <cstring> #include <regex> #include <string> + #include <mbedtls/md.h> #include <mbedtls/sha256.h> -#include "common/assert.h" + #include "common/file_util.h" #include "common/hex_util.h" -#include "common/logging/log.h" +#include "common/string_util.h" #include "core/crypto/aes_util.h" #include "core/crypto/xts_encryption_layer.h" #include "core/file_sys/partition_filesystem.h" @@ -53,11 +54,8 @@ NAX::NAX(VirtualFile file_) : header(std::make_unique<NAXHeader>()), file(std::m return; } - std::string two_dir = match[1]; - std::string nca_id = match[2]; - std::transform(two_dir.begin(), two_dir.end(), two_dir.begin(), ::toupper); - std::transform(nca_id.begin(), nca_id.end(), nca_id.begin(), ::tolower); - + const std::string two_dir = Common::ToUpper(match[1]); + const std::string nca_id = Common::ToLower(match[2]); status = Parse(fmt::format("/registered/{}/{}.nca", two_dir, nca_id)); } diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 20bb50868..54ed680db 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -468,7 +468,8 @@ static u8 ReadByte() { /// Calculate the checksum of the current command buffer. static u8 CalculateChecksum(const u8* buffer, std::size_t length) { - return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>())); + return static_cast<u8>(std::accumulate(buffer, buffer + length, u8{0}, + [](u8 lhs, u8 rhs) { return u8(lhs + rhs); })); } /** diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 0e2dbf13e..16e95381b 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -35,12 +35,12 @@ void GlobalScheduler::RemoveThread(const Thread* thread) { thread_list.end()); } -void GlobalScheduler::UnloadThread(s32 core) { +void GlobalScheduler::UnloadThread(std::size_t core) { Scheduler& sched = system.Scheduler(core); sched.UnloadThread(); } -void GlobalScheduler::SelectThread(u32 core) { +void GlobalScheduler::SelectThread(std::size_t core) { const auto update_thread = [](Thread* thread, Scheduler& sched) { if (thread != sched.selected_thread) { if (thread == nullptr) { @@ -77,9 +77,9 @@ void GlobalScheduler::SelectThread(u32 core) { // if we got a suggested thread, select it, else do a second pass. if (winner && winner->GetPriority() > 2) { if (winner->IsRunning()) { - UnloadThread(winner->GetProcessorID()); + UnloadThread(static_cast<u32>(winner->GetProcessorID())); } - TransferToCore(winner->GetPriority(), core, winner); + TransferToCore(winner->GetPriority(), static_cast<s32>(core), winner); update_thread(winner, sched); return; } @@ -91,9 +91,9 @@ void GlobalScheduler::SelectThread(u32 core) { Thread* thread_on_core = scheduled_queue[src_core].front(); Thread* to_change = *it; if (thread_on_core->IsRunning() || to_change->IsRunning()) { - UnloadThread(src_core); + UnloadThread(static_cast<u32>(src_core)); } - TransferToCore(thread_on_core->GetPriority(), core, thread_on_core); + TransferToCore(thread_on_core->GetPriority(), static_cast<s32>(core), thread_on_core); current_thread = thread_on_core; break; } @@ -154,9 +154,9 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { if (winner != nullptr) { if (winner != yielding_thread) { if (winner->IsRunning()) { - UnloadThread(winner->GetProcessorID()); + UnloadThread(static_cast<u32>(winner->GetProcessorID())); } - TransferToCore(winner->GetPriority(), core_id, winner); + TransferToCore(winner->GetPriority(), s32(core_id), winner); } } else { winner = next_thread; @@ -196,9 +196,9 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread if (winner != nullptr) { if (winner != yielding_thread) { if (winner->IsRunning()) { - UnloadThread(winner->GetProcessorID()); + UnloadThread(static_cast<u32>(winner->GetProcessorID())); } - TransferToCore(winner->GetPriority(), core_id, winner); + TransferToCore(winner->GetPriority(), static_cast<s32>(core_id), winner); } } else { winner = yielding_thread; @@ -248,7 +248,7 @@ void GlobalScheduler::PreemptThreads() { if (winner != nullptr) { if (winner->IsRunning()) { - UnloadThread(winner->GetProcessorID()); + UnloadThread(static_cast<u32>(winner->GetProcessorID())); } TransferToCore(winner->GetPriority(), s32(core_id), winner); current_thread = @@ -281,7 +281,7 @@ void GlobalScheduler::PreemptThreads() { if (winner != nullptr) { if (winner->IsRunning()) { - UnloadThread(winner->GetProcessorID()); + UnloadThread(static_cast<u32>(winner->GetProcessorID())); } TransferToCore(winner->GetPriority(), s32(core_id), winner); current_thread = winner; @@ -292,30 +292,30 @@ void GlobalScheduler::PreemptThreads() { } } -void GlobalScheduler::Suggest(u32 priority, u32 core, Thread* thread) { +void GlobalScheduler::Suggest(u32 priority, std::size_t core, Thread* thread) { suggested_queue[core].add(thread, priority); } -void GlobalScheduler::Unsuggest(u32 priority, u32 core, Thread* thread) { +void GlobalScheduler::Unsuggest(u32 priority, std::size_t core, Thread* thread) { suggested_queue[core].remove(thread, priority); } -void GlobalScheduler::Schedule(u32 priority, u32 core, Thread* thread) { +void GlobalScheduler::Schedule(u32 priority, std::size_t core, Thread* thread) { ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core."); scheduled_queue[core].add(thread, priority); } -void GlobalScheduler::SchedulePrepend(u32 priority, u32 core, Thread* thread) { +void GlobalScheduler::SchedulePrepend(u32 priority, std::size_t core, Thread* thread) { ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core."); scheduled_queue[core].add(thread, priority, false); } -void GlobalScheduler::Reschedule(u32 priority, u32 core, Thread* thread) { +void GlobalScheduler::Reschedule(u32 priority, std::size_t core, Thread* thread) { scheduled_queue[core].remove(thread, priority); scheduled_queue[core].add(thread, priority); } -void GlobalScheduler::Unschedule(u32 priority, u32 core, Thread* thread) { +void GlobalScheduler::Unschedule(u32 priority, std::size_t core, Thread* thread) { scheduled_queue[core].remove(thread, priority); } @@ -327,14 +327,14 @@ void GlobalScheduler::TransferToCore(u32 priority, s32 destination_core, Thread* } thread->SetProcessorID(destination_core); if (source_core >= 0) { - Unschedule(priority, source_core, thread); + Unschedule(priority, static_cast<u32>(source_core), thread); } if (destination_core >= 0) { - Unsuggest(priority, destination_core, thread); - Schedule(priority, destination_core, thread); + Unsuggest(priority, static_cast<u32>(destination_core), thread); + Schedule(priority, static_cast<u32>(destination_core), thread); } if (source_core >= 0) { - Suggest(priority, source_core, thread); + Suggest(priority, static_cast<u32>(source_core), thread); } } @@ -357,7 +357,7 @@ void GlobalScheduler::Shutdown() { thread_list.clear(); } -Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id) +Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id) : system(system), cpu_core(cpu_core), core_id(core_id) {} Scheduler::~Scheduler() = default; diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index f2d6311b8..311849dfb 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -42,41 +42,34 @@ public: * Add a thread to the suggested queue of a cpu core. Suggested threads may be * picked if no thread is scheduled to run on the core. */ - void Suggest(u32 priority, u32 core, Thread* thread); + void Suggest(u32 priority, std::size_t core, Thread* thread); /** * Remove a thread to the suggested queue of a cpu core. Suggested threads may be * picked if no thread is scheduled to run on the core. */ - void Unsuggest(u32 priority, u32 core, Thread* thread); + void Unsuggest(u32 priority, std::size_t core, Thread* thread); /** * Add a thread to the scheduling queue of a cpu core. The thread is added at the * back the queue in its priority level. */ - void Schedule(u32 priority, u32 core, Thread* thread); + void Schedule(u32 priority, std::size_t core, Thread* thread); /** * Add a thread to the scheduling queue of a cpu core. The thread is added at the * front the queue in its priority level. */ - void SchedulePrepend(u32 priority, u32 core, Thread* thread); + void SchedulePrepend(u32 priority, std::size_t core, Thread* thread); /// Reschedule an already scheduled thread based on a new priority - void Reschedule(u32 priority, u32 core, Thread* thread); + void Reschedule(u32 priority, std::size_t core, Thread* thread); /// Unschedules a thread. - void Unschedule(u32 priority, u32 core, Thread* thread); - - /** - * Transfers a thread into an specific core. If the destination_core is -1 - * it will be unscheduled from its source code and added into its suggested - * queue. - */ - void TransferToCore(u32 priority, s32 destination_core, Thread* thread); + void Unschedule(u32 priority, std::size_t core, Thread* thread); /// Selects a core and forces it to unload its current thread's context - void UnloadThread(s32 core); + void UnloadThread(std::size_t core); /** * Takes care of selecting the new scheduled thread in three steps: @@ -90,9 +83,9 @@ public: * 3. Third is no suggested thread is found, we do a second pass and pick a running * thread in another core and swap it with its current thread. */ - void SelectThread(u32 core); + void SelectThread(std::size_t core); - bool HaveReadyThreads(u32 core_id) const { + bool HaveReadyThreads(std::size_t core_id) const { return !scheduled_queue[core_id].empty(); } @@ -145,6 +138,13 @@ public: void Shutdown(); private: + /** + * Transfers a thread into an specific core. If the destination_core is -1 + * it will be unscheduled from its source code and added into its suggested + * queue. + */ + void TransferToCore(u32 priority, s32 destination_core, Thread* thread); + bool AskForReselectionOrMarkRedundant(Thread* current_thread, const Thread* winner); static constexpr u32 min_regular_priority = 2; @@ -163,7 +163,7 @@ private: class Scheduler final { public: - explicit Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id); + explicit Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id); ~Scheduler(); /// Returns whether there are any threads that are ready to run. @@ -220,7 +220,7 @@ private: Core::ARM_Interface& cpu_core; u64 last_context_switch_time = 0; u64 idle_selection_count = 0; - const u32 core_id; + const std::size_t core_id; bool is_context_switch_pending = false; }; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 538e47992..ab0e82ac2 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -77,18 +77,6 @@ void Thread::CancelWakeupTimer() { callback_handle); } -static std::optional<s32> GetNextProcessorId(u64 mask) { - for (s32 index = 0; index < Core::NUM_CPU_CORES; ++index) { - if (mask & (1ULL << index)) { - if (!Core::System::GetInstance().Scheduler(index).GetCurrentThread()) { - // Core is enabled and not running any threads, use this one - return index; - } - } - } - return {}; -} - void Thread::ResumeFromWait() { ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); @@ -176,7 +164,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) { LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); // TODO (bunnei): Find the correct error code to use here - return ResultCode(-1); + return RESULT_UNKNOWN; } auto& system = Core::System::GetInstance(); @@ -404,7 +392,7 @@ void Thread::SetCurrentPriority(u32 new_priority) { ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { const auto HighestSetCore = [](u64 mask, u32 max_cores) { - for (s32 core = max_cores - 1; core >= 0; core--) { + for (s32 core = static_cast<s32>(max_cores - 1); core >= 0; core--) { if (((mask >> core) & 1) != 0) { return core; } @@ -428,7 +416,7 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { if (old_affinity_mask != new_affinity_mask) { const s32 old_core = processor_id; if (processor_id >= 0 && ((affinity_mask >> processor_id) & 1) == 0) { - if (ideal_core < 0) { + if (static_cast<s32>(ideal_core) < 0) { processor_id = HighestSetCore(affinity_mask, GlobalScheduler::NUM_CPU_CORES); } else { processor_id = ideal_core; @@ -450,23 +438,23 @@ void Thread::AdjustSchedulingOnStatus(u32 old_flags) { ThreadSchedStatus::Runnable) { // In this case the thread was running, now it's pausing/exitting if (processor_id >= 0) { - scheduler.Unschedule(current_priority, processor_id, this); + scheduler.Unschedule(current_priority, static_cast<u32>(processor_id), this); } - for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { - if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { - scheduler.Unsuggest(current_priority, static_cast<u32>(core), this); + for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) { + scheduler.Unsuggest(current_priority, core, this); } } } else if (GetSchedulingStatus() == ThreadSchedStatus::Runnable) { // The thread is now set to running from being stopped if (processor_id >= 0) { - scheduler.Schedule(current_priority, processor_id, this); + scheduler.Schedule(current_priority, static_cast<u32>(processor_id), this); } - for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { - if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { - scheduler.Suggest(current_priority, static_cast<u32>(core), this); + for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) { + scheduler.Suggest(current_priority, core, this); } } } @@ -480,11 +468,11 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { } auto& scheduler = Core::System::GetInstance().GlobalScheduler(); if (processor_id >= 0) { - scheduler.Unschedule(old_priority, processor_id, this); + scheduler.Unschedule(old_priority, static_cast<u32>(processor_id), this); } for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { - if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { + if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) { scheduler.Unsuggest(old_priority, core, this); } } @@ -494,14 +482,14 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { if (processor_id >= 0) { if (current_thread == this) { - scheduler.SchedulePrepend(current_priority, processor_id, this); + scheduler.SchedulePrepend(current_priority, static_cast<u32>(processor_id), this); } else { - scheduler.Schedule(current_priority, processor_id, this); + scheduler.Schedule(current_priority, static_cast<u32>(processor_id), this); } } for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { - if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { + if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) { scheduler.Suggest(current_priority, core, this); } } @@ -518,7 +506,7 @@ void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) { for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (((old_affinity_mask >> core) & 1) != 0) { - if (core == old_core) { + if (core == static_cast<u32>(old_core)) { scheduler.Unschedule(current_priority, core, this); } else { scheduler.Unsuggest(current_priority, core, this); @@ -528,7 +516,7 @@ void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) { for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (((affinity_mask >> core) & 1) != 0) { - if (core == processor_id) { + if (core == static_cast<u32>(processor_id)) { scheduler.Schedule(current_priority, core, this); } else { scheduler.Suggest(current_priority, core, this); diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index c7af87073..e6eee09d7 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -167,7 +167,7 @@ ResultVal<VAddr> VMManager::FindFreeRegion(VAddr begin, VAddr end, u64 size) con if (vma_handle == vma_map.cend()) { // TODO(Subv): Find the correct error code here. - return ResultCode(-1); + return RESULT_UNKNOWN; } const VAddr target = std::max(begin, vma_handle->second.base); diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 8a3701151..450f61fea 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -147,6 +147,14 @@ constexpr bool operator!=(const ResultCode& a, const ResultCode& b) { constexpr ResultCode RESULT_SUCCESS(0); /** + * Placeholder result code used for unknown error codes. + * + * @note This should only be used when a particular error code + * is not known yet. + */ +constexpr ResultCode RESULT_UNKNOWN(UINT32_MAX); + +/** * This is an optional value type. It holds a `ResultCode` and, if that code is a success code, * also holds a result of type `T`. If the code is an error code then trying to access the inner * value fails, thus ensuring that the ResultCode of functions is always checked properly before @@ -183,7 +191,7 @@ class ResultVal { public: /// Constructs an empty `ResultVal` with the given error code. The code must not be a success /// code. - ResultVal(ResultCode error_code = ResultCode(-1)) : result_code(error_code) { + ResultVal(ResultCode error_code = RESULT_UNKNOWN) : result_code(error_code) { ASSERT(error_code.IsError()); } diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 0c0f7ed6e..7e3e311fb 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -84,7 +84,7 @@ protected: LOG_ERROR(Service_ACC, "Failed to get profile base and data for user={}", user_id.Format()); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code + rb.Push(RESULT_UNKNOWN); // TODO(ogniK): Get actual error code } } @@ -98,7 +98,7 @@ protected: } else { LOG_ERROR(Service_ACC, "Failed to get profile base for user={}", user_id.Format()); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code + rb.Push(RESULT_UNKNOWN); // TODO(ogniK): Get actual error code } } @@ -442,7 +442,7 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex const auto user_list = profile_manager->GetAllUsers(); if (std::all_of(user_list.begin(), user_list.end(), [](const auto& user) { return user.uuid == Common::INVALID_UUID; })) { - rb.Push(ResultCode(-1)); // TODO(ogniK): Find the correct error code + rb.Push(RESULT_UNKNOWN); // TODO(ogniK): Find the correct error code rb.PushRaw<u128>(Common::INVALID_UUID); return; } diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 8f9986326..3e756e59e 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -31,8 +31,8 @@ struct ProfileDataRaw { static_assert(sizeof(ProfileDataRaw) == 0x650, "ProfileDataRaw has incorrect size."); // TODO(ogniK): Get actual error codes -constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, -1); -constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, -2); +constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, u32(-1)); +constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, u32(-2)); constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/avators/"; diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index d52ec4387..701f05019 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -991,7 +991,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", static_cast<u32>(applet_id)); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } @@ -1027,7 +1027,7 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex if (transfer_mem == nullptr) { LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } @@ -1076,7 +1076,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"}, {101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"}, {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"}, - {110, nullptr, "QueryApplicationPlayStatistics"}, + {110, &IApplicationFunctions::QueryApplicationPlayStatistics, "QueryApplicationPlayStatistics"}, {111, &IApplicationFunctions::QueryApplicationPlayStatisticsByUid, "QueryApplicationPlayStatisticsByUid"}, {120, nullptr, "ExecuteProgram"}, {121, nullptr, "ClearUserChannel"}, @@ -1336,12 +1336,16 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) { } void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) { + struct Parameters { + FileSys::SaveDataType type; + u128 user_id; + u64 new_normal_size; + u64 new_journal_size; + }; + static_assert(sizeof(Parameters) == 40); + IPC::RequestParser rp{ctx}; - const auto type{rp.PopRaw<FileSys::SaveDataType>()}; - rp.Skip(1, false); - const auto user_id{rp.PopRaw<u128>()}; - const auto new_normal_size{rp.PopRaw<u64>()}; - const auto new_journal_size{rp.PopRaw<u64>()}; + const auto [type, user_id, new_normal_size, new_journal_size] = rp.PopRaw<Parameters>(); LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}, new_normal={:016X}, " @@ -1360,10 +1364,14 @@ void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) { } void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) { + struct Parameters { + FileSys::SaveDataType type; + u128 user_id; + }; + static_assert(sizeof(Parameters) == 24); + IPC::RequestParser rp{ctx}; - const auto type{rp.PopRaw<FileSys::SaveDataType>()}; - rp.Skip(1, false); - const auto user_id{rp.PopRaw<u128>()}; + const auto [type, user_id] = rp.PopRaw<Parameters>(); LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", static_cast<u8>(type), user_id[1], user_id[0]); @@ -1377,12 +1385,12 @@ void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) { rb.Push(size.journal); } -void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx) { +void IApplicationFunctions::QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2, 1}; + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(gpu_error_detected_event.readable); + rb.Push<u32>(0); } void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx) { @@ -1393,6 +1401,14 @@ void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLEReque rb.Push<u32>(0); } +void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(gpu_error_detected_event.readable); +} + void InstallInterfaces(SM::ServiceManager& service_manager, std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system) { auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel()); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index f64013ea0..06a65b5ed 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -255,8 +255,9 @@ private: void InitializeApplicationCopyrightFrameBuffer(Kernel::HLERequestContext& ctx); void SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx); void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx); - void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); + void QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx); void QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx); + void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); bool launch_popped_application_specific = false; bool launch_popped_account_preselect = false; diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index 32283e819..5546ef6e8 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp @@ -337,7 +337,7 @@ void WebBrowser::ExecuteInternal() { void WebBrowser::InitializeShop() { if (frontend_e_commerce == nullptr) { LOG_ERROR(Service_AM, "Missing ECommerce Applet frontend!"); - status = ResultCode(-1); + status = RESULT_UNKNOWN; return; } @@ -353,7 +353,7 @@ void WebBrowser::InitializeShop() { if (url == args.end()) { LOG_ERROR(Service_AM, "Missing EShop Arguments URL for initialization!"); - status = ResultCode(-1); + status = RESULT_UNKNOWN; return; } @@ -366,7 +366,7 @@ void WebBrowser::InitializeShop() { // Less is missing info, More is malformed if (split_query.size() != 2) { LOG_ERROR(Service_AM, "EShop Arguments has more than one question mark, malformed"); - status = ResultCode(-1); + status = RESULT_UNKNOWN; return; } @@ -390,7 +390,7 @@ void WebBrowser::InitializeShop() { if (scene == shop_query.end()) { LOG_ERROR(Service_AM, "No scene parameter was passed via shop query!"); - status = ResultCode(-1); + status = RESULT_UNKNOWN; return; } @@ -406,7 +406,7 @@ void WebBrowser::InitializeShop() { const auto target = target_map.find(scene->second); if (target == target_map.end()) { LOG_ERROR(Service_AM, "Scene for shop query is invalid! (scene={})", scene->second); - status = ResultCode(-1); + status = RESULT_UNKNOWN; return; } @@ -427,7 +427,7 @@ void WebBrowser::InitializeOffline() { if (args.find(WebArgTLVType::DocumentPath) == args.end() || args.find(WebArgTLVType::DocumentKind) == args.end() || args.find(WebArgTLVType::ApplicationID) == args.end()) { - status = ResultCode(-1); + status = RESULT_UNKNOWN; LOG_ERROR(Service_AM, "Missing necessary parameters for initialization!"); } @@ -476,7 +476,7 @@ void WebBrowser::InitializeOffline() { offline_romfs = GetApplicationRomFS(system, title_id, type); if (offline_romfs == nullptr) { - status = ResultCode(-1); + status = RESULT_UNKNOWN; LOG_ERROR(Service_AM, "Failed to find offline data for request!"); } @@ -496,7 +496,7 @@ void WebBrowser::ExecuteShop() { const auto check_optional_parameter = [this](const auto& p) { if (!p.has_value()) { LOG_ERROR(Service_AM, "Missing one or more necessary parameters for execution!"); - status = ResultCode(-1); + status = RESULT_UNKNOWN; return false; } diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index f36ccbc49..30076a53e 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp @@ -131,7 +131,7 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { if (out.size() < offset) { IPC::ResponseBuilder rb{ctx, 2}; // TODO(DarkLordZach): Find the correct error code. - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index cb4a1160d..cb839e4a2 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp @@ -80,7 +80,7 @@ private: LOG_ERROR(Audio, "Failed to decode opus data"); IPC::ResponseBuilder rb{ctx, 2}; // TODO(ogniK): Use correct error code - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } @@ -278,7 +278,7 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) { LOG_ERROR(Audio, "Failed to create Opus decoder (error={}).", error); IPC::ResponseBuilder rb{ctx, 2}; // TODO(ogniK): Use correct error code - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp index 1411a646f..67e39a5c4 100644 --- a/src/core/hle/service/bcat/backend/boxcat.cpp +++ b/src/core/hle/service/bcat/backend/boxcat.cpp @@ -114,7 +114,7 @@ void HandleDownloadDisplayResult(const AM::Applets::AppletManager& applet_manage const auto& frontend{applet_manager.GetAppletFrontendSet()}; frontend.error->ShowCustomErrorText( - ResultCode(-1), "There was an error while attempting to use Boxcat.", + RESULT_UNKNOWN, "There was an error while attempting to use Boxcat.", DOWNLOAD_RESULT_LOG_MESSAGES[static_cast<std::size_t>(res)], [] {}); } diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 11e5c56b7..102017d73 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -58,11 +58,11 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 auto file = dir->CreateFile(FileUtil::GetFilename(path)); if (file == nullptr) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } if (!file->Resize(size)) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; } @@ -80,7 +80,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) cons } if (!dir->DeleteFile(FileUtil::GetFilename(path))) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; @@ -94,7 +94,7 @@ ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) auto new_dir = dir->CreateSubdirectory(FileUtil::GetFilename(path)); if (new_dir == nullptr) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; } @@ -104,7 +104,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path_) auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); if (!dir->DeleteSubdirectory(FileUtil::GetFilename(path))) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; } @@ -114,7 +114,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); if (!dir->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path))) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; } @@ -125,7 +125,7 @@ ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::stri if (!dir->CleanSubdirectoryRecursive(FileUtil::GetFilename(sanitized_path))) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; @@ -142,7 +142,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, return FileSys::ERROR_PATH_NOT_FOUND; if (!src->Rename(FileUtil::GetFilename(dest_path))) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; } @@ -160,7 +160,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, if (!src->GetContainingDirectory()->DeleteFile(FileUtil::GetFilename(src_path))) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; @@ -177,7 +177,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa return FileSys::ERROR_PATH_NOT_FOUND; if (!src->Rename(FileUtil::GetFilename(dest_path))) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return RESULT_SUCCESS; } @@ -189,7 +189,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa src_path, dest_path); // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path_, @@ -287,7 +287,7 @@ ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFSCurrentProcess() if (romfs_factory == nullptr) { // TODO(bunnei): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return romfs_factory->OpenCurrentProcess(system.CurrentProcess()->GetTitleID()); @@ -300,7 +300,7 @@ ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFS( if (romfs_factory == nullptr) { // TODO(bunnei): Find a better error code for this - return ResultCode(-1); + return RESULT_UNKNOWN; } return romfs_factory->Open(title_id, storage_id, type); diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index cbd5466c1..92162d3e1 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -785,7 +785,7 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) { static_cast<u8>(type), title_id); IPC::ResponseBuilder rb{ctx, 2, 0, 0}; - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); } void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) { @@ -891,7 +891,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { // TODO (bunnei): Find the right error code to use here LOG_CRITICAL(Service_FS, "no file system interface available!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } @@ -928,7 +928,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) { "could not open data storage with title_id={:016X}, storage_id={:02X}", title_id, static_cast<u8>(storage_id)); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index 0b3923ad9..0ffc5009e 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp @@ -242,7 +242,7 @@ private: const auto index = db.IndexOf(uuid); if (index > MAX_MIIS) { // TODO(DarkLordZach): Find a better error code - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); rb.Push(index); } else { rb.Push(RESULT_SUCCESS); @@ -268,7 +268,7 @@ private: IPC::ResponseBuilder rb{ctx, 2}; // TODO(DarkLordZach): Find a better error code - rb.Push(success ? RESULT_SUCCESS : ResultCode(-1)); + rb.Push(success ? RESULT_SUCCESS : RESULT_UNKNOWN); } void AddOrReplace(Kernel::HLERequestContext& ctx) { @@ -282,7 +282,7 @@ private: IPC::ResponseBuilder rb{ctx, 2}; // TODO(DarkLordZach): Find a better error code - rb.Push(success ? RESULT_SUCCESS : ResultCode(-1)); + rb.Push(success ? RESULT_SUCCESS : RESULT_UNKNOWN); } void Delete(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 795d7b716..3bf753dee 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -16,10 +16,7 @@ #include "core/hle/service/nfp/nfp_user.h" namespace Service::NFP { - namespace ErrCodes { -[[maybe_unused]] constexpr ResultCode ERR_TAG_FAILED(ErrorModule::NFP, - -1); // TODO(ogniK): Find the actual error code constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152); } // namespace ErrCodes diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 15c156ce1..eeba0aa19 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp @@ -271,7 +271,7 @@ void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestC "output buffer is too small! (actual={:016X}, expected_min=0x4000)", size); IPC::ResponseBuilder rb{ctx, 2}; // TODO(DarkLordZach): Find a better error code for this. - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } @@ -291,7 +291,7 @@ void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestC 0x4000 + control.second->GetSize()); IPC::ResponseBuilder rb{ctx, 2}; // TODO(DarkLordZach): Find a better error code for this. - rb.Push(ResultCode(-1)); + rb.Push(RESULT_UNKNOWN); return; } diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 23477315f..db433305f 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -97,7 +97,7 @@ void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, const auto key = Common::swap32(EXPECTED_RESULT ^ EXPECTED_MAGIC); std::vector<u32> transformed_font(input.size() + 2); transformed_font[0] = Common::swap32(EXPECTED_MAGIC); - transformed_font[1] = Common::swap32(input.size() * sizeof(u32)) ^ key; + transformed_font[1] = Common::swap32(static_cast<u32>(input.size() * sizeof(u32))) ^ key; std::transform(input.begin(), input.end(), transformed_font.begin() + 2, [key](u32 in) { return in ^ key; }); std::memcpy(output.data() + offset, transformed_font.data(), diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 1b9ab8401..62efe021e 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -34,12 +34,12 @@ static void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time, additional_info = {}; return; } - calendar_time.year = tm->tm_year + 1900; - calendar_time.month = tm->tm_mon + 1; - calendar_time.day = tm->tm_mday; - calendar_time.hour = tm->tm_hour; - calendar_time.minute = tm->tm_min; - calendar_time.second = tm->tm_sec; + calendar_time.year = static_cast<u16_le>(tm->tm_year + 1900); + calendar_time.month = static_cast<u8>(tm->tm_mon + 1); + calendar_time.day = static_cast<u8>(tm->tm_mday); + calendar_time.hour = static_cast<u8>(tm->tm_hour); + calendar_time.minute = static_cast<u8>(tm->tm_min); + calendar_time.second = static_cast<u8>(tm->tm_sec); additional_info.day_of_week = tm->tm_wday; additional_info.day_of_year = tm->tm_yday; @@ -322,7 +322,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { if (tm == nullptr) { LOG_ERROR(Service_Time, "tm is a nullptr"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); // TODO(ogniK): Find appropriate error code + rb.Push(RESULT_UNKNOWN); // TODO(ogniK): Find appropriate error code return; } @@ -331,12 +331,12 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { const SteadyClockTimePoint steady_clock_time_point{static_cast<u64_le>(ms.count() / 1000), {}}; CalendarTime calendar_time{}; - calendar_time.year = tm->tm_year + 1900; - calendar_time.month = tm->tm_mon + 1; - calendar_time.day = tm->tm_mday; - calendar_time.hour = tm->tm_hour; - calendar_time.minute = tm->tm_min; - calendar_time.second = tm->tm_sec; + calendar_time.year = static_cast<u16_le>(tm->tm_year + 1900); + calendar_time.month = static_cast<u8>(tm->tm_mon + 1); + calendar_time.day = static_cast<u8>(tm->tm_mday); + calendar_time.hour = static_cast<u8>(tm->tm_hour); + calendar_time.minute = static_cast<u8>(tm->tm_min); + calendar_time.second = static_cast<u8>(tm->tm_sec); ClockSnapshot clock_snapshot{}; clock_snapshot.system_posix_time = time_since_epoch; diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 611cecc20..abfc3a801 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -541,7 +541,7 @@ private: } else { // Wait the current thread until a buffer becomes available ctx.SleepClientThread( - "IHOSBinderDriver::DequeueBuffer", -1, + "IHOSBinderDriver::DequeueBuffer", UINT64_MAX, [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { // Repeat TransactParcel DequeueBuffer when a buffer is available diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index d2c69d1a0..f1ae9d4df 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -81,7 +81,7 @@ double PerfStats::GetMeanFrametime() { return 0; } const double sum = std::accumulate(perf_history.begin() + IgnoreFrames, - perf_history.begin() + current_index, 0); + perf_history.begin() + current_index, 0.0); return sum / (current_index - IgnoreFrames); } diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 45d8eaf23..6f3f2aa9f 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -127,6 +127,8 @@ add_library(video_core STATIC shader/track.cpp surface.cpp surface.h + texture_cache/format_lookup_table.cpp + texture_cache/format_lookup_table.h texture_cache/surface_base.cpp texture_cache/surface_base.h texture_cache/surface_params.cpp diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 42ce49a4d..a44c09003 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -742,14 +742,6 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { Texture::TICEntry tic_entry; memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry)); - [[maybe_unused]] const auto r_type{tic_entry.r_type.Value()}; - [[maybe_unused]] const auto g_type{tic_entry.g_type.Value()}; - [[maybe_unused]] const auto b_type{tic_entry.b_type.Value()}; - [[maybe_unused]] const auto a_type{tic_entry.a_type.Value()}; - - // TODO(Subv): Different data types for separate components are not supported - DEBUG_ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); - return tic_entry; } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e43ba9d6b..05f8e511b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -257,10 +257,8 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { continue; } - const std::size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 - GLShader::MaxwellUniformData ubo{}; - ubo.SetFromRegs(gpu, stage); + ubo.SetFromRegs(gpu); const auto [buffer, offset] = buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment()); @@ -269,10 +267,11 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { Shader shader{shader_cache.GetStageProgram(program)}; - const auto stage_enum = static_cast<Maxwell::ShaderStage>(stage); - SetupDrawConstBuffers(stage_enum, shader); - SetupDrawGlobalMemory(stage_enum, shader); - const auto texture_buffer_usage{SetupDrawTextures(stage_enum, shader, base_bindings)}; + // Stage indices are 0 - 5 + const auto stage = static_cast<Maxwell::ShaderStage>(index == 0 ? 0 : index - 1); + SetupDrawConstBuffers(stage, shader); + SetupDrawGlobalMemory(stage, shader); + const auto texture_buffer_usage{SetupDrawTextures(stage, shader, base_bindings)}; const ProgramVariant variant{base_bindings, primitive_mode, texture_buffer_usage}; const auto [program_handle, next_bindings] = shader->GetProgramHandle(variant); @@ -1055,6 +1054,15 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { } state.depth_clamp.far_plane = regs.view_volume_clip_control.depth_clamp_far != 0; state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0; + + bool flip_y = false; + if (regs.viewport_transform[0].scale_y < 0.0) { + flip_y = !flip_y; + } + if (regs.screen_y_control.y_negate != 0) { + flip_y = !flip_y; + } + state.clip_control.origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT; } void RasterizerOpenGL::SyncClipEnabled( @@ -1077,28 +1085,14 @@ void RasterizerOpenGL::SyncClipCoef() { } void RasterizerOpenGL::SyncCullMode() { - auto& maxwell3d = system.GPU().Maxwell3D(); - - const auto& regs = maxwell3d.regs; + const auto& regs = system.GPU().Maxwell3D().regs; state.cull.enabled = regs.cull.enabled != 0; if (state.cull.enabled) { - state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face); state.cull.mode = MaxwellToGL::CullFace(regs.cull.cull_face); - - const bool flip_triangles{regs.screen_y_control.triangle_rast_flip == 0 || - regs.viewport_transform[0].scale_y < 0.0f}; - - // If the GPU is configured to flip the rasterized triangles, then we need to flip the - // notion of front and back. Note: We flip the triangles when the value of the register is 0 - // because OpenGL already does it for us. - if (flip_triangles) { - if (state.cull.front_face == GL_CCW) - state.cull.front_face = GL_CW; - else if (state.cull.front_face == GL_CW) - state.cull.front_face = GL_CCW; - } } + + state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face); } void RasterizerOpenGL::SyncPrimitiveRestart() { diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e56ed51de..4f2b49170 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1892,10 +1892,6 @@ private: Expression EmitVertex(Operation operation) { ASSERT_MSG(stage == ProgramType::Geometry, "EmitVertex is expected to be used in a geometry shader."); - - // If a geometry shader is attached, it will always flip (it's the last stage before - // fragment). For more info about flipping, refer to gl_shader_gen.cpp. - code.AddLine("gl_Position.xy *= viewport_flip.xy;"); code.AddLine("EmitVertex();"); return {}; } @@ -1903,14 +1899,12 @@ private: Expression EndPrimitive(Operation operation) { ASSERT_MSG(stage == ProgramType::Geometry, "EndPrimitive is expected to be used in a geometry shader."); - code.AddLine("EndPrimitive();"); return {}; } Expression YNegate(Operation operation) { - // Config pack's third value is Y_NEGATE's state. - return {"config_pack[2]", Type::Uint}; + return {"y_direction", Type::Float}; } template <u32 element> diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 0e22eede9..af17216bd 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -20,8 +20,7 @@ std::string GenerateVertexShader(const Device& device, const ShaderIR& ir, const std::string out = GetCommonDeclarations(); out += R"( layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config { - vec4 viewport_flip; - uvec4 config_pack; // instance_id, flip_stage, y_direction, padding + float y_direction; }; )"; @@ -35,23 +34,10 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config { void main() { execute_vertex(); )"; - if (ir_b) { out += " execute_vertex_b();"; } - - out += R"( - - // Set Position Y direction - gl_Position.y *= utof(config_pack[2]); - // Check if the flip stage is VertexB - // Config pack's second value is flip_stage - if (config_pack[1] == 1) { - // Viewport can be flipped, which is unsupported by glViewport - gl_Position.xy *= viewport_flip.xy; - } -} -)"; + out += "}\n"; return out; } @@ -59,8 +45,7 @@ std::string GenerateGeometryShader(const Device& device, const ShaderIR& ir) { std::string out = GetCommonDeclarations(); out += R"( layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config { - vec4 viewport_flip; - uvec4 config_pack; // instance_id, flip_stage, y_direction, padding + float y_direction; }; )"; @@ -87,8 +72,7 @@ layout (location = 6) out vec4 FragColor6; layout (location = 7) out vec4 FragColor7; layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config { - vec4 viewport_flip; - uvec4 config_pack; // instance_id, flip_stage, y_direction, padding + float y_direction; }; )"; diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index b05f90f20..75d3fac04 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -40,27 +40,11 @@ void ProgramManager::UpdatePipeline() { old_state = current_state; } -void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shader_stage) { +void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell) { const auto& regs = maxwell.regs; - const auto& state = maxwell.state; - - // TODO(bunnei): Support more than one viewport - viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; - viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; - - instance_id = state.current_instance; - - // Assign in which stage the position has to be flipped - // (the last stage before the fragment shader). - constexpr u32 geometry_index = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry); - if (maxwell.regs.shader_config[geometry_index].enable) { - flip_stage = geometry_index; - } else { - flip_stage = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::VertexB); - } // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value. - y_direction = regs.screen_y_control.y_negate == 0 ? 1.f : -1.f; + y_direction = regs.screen_y_control.y_negate == 0 ? 1.0f : -1.0f; } } // namespace OpenGL::GLShader diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 6961e702a..3703e7018 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h @@ -18,17 +18,12 @@ namespace OpenGL::GLShader { /// @note Always keep a vec4 at the end. The GL spec is not clear whether the alignment at /// the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. /// Not following that rule will cause problems on some AMD drivers. -struct MaxwellUniformData { - void SetFromRegs(const Tegra::Engines::Maxwell3D& maxwell, std::size_t shader_stage); - - alignas(16) GLvec4 viewport_flip; - struct alignas(16) { - GLuint instance_id; - GLuint flip_stage; - GLfloat y_direction; - }; +struct alignas(16) MaxwellUniformData { + void SetFromRegs(const Tegra::Engines::Maxwell3D& maxwell); + + GLfloat y_direction; }; -static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect"); +static_assert(sizeof(MaxwellUniformData) == 16, "MaxwellUniformData structure size is incorrect"); static_assert(sizeof(MaxwellUniformData) < 16384, "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index f25148362..ccbe5912e 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -410,6 +410,12 @@ void OpenGLState::ApplyAlphaTest() { } } +void OpenGLState::ApplyClipControl() { + if (UpdateValue(cur_state.clip_control.origin, clip_control.origin)) { + glClipControl(clip_control.origin, GL_NEGATIVE_ONE_TO_ONE); + } +} + void OpenGLState::ApplyTextures() { if (const auto update = UpdateArray(cur_state.textures, textures)) { glBindTextures(update->first, update->second, textures.data() + update->first); @@ -453,6 +459,7 @@ void OpenGLState::Apply() { ApplyImages(); ApplyPolygonOffset(); ApplyAlphaTest(); + ApplyClipControl(); } void OpenGLState::EmulateViewportWithScissor() { diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index cca25206b..eaff22bda 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -146,6 +146,10 @@ public: std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE + struct { + GLenum origin = GL_LOWER_LEFT; + } clip_control; + OpenGLState(); /// Get the currently active OpenGL state @@ -182,6 +186,7 @@ public: void ApplyDepthClamp(); void ApplyPolygonOffset(); void ApplyAlphaTest(); + void ApplyClipControl(); /// Resets any references to the given resource OpenGLState& UnbindTexture(GLuint handle); diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 55b3e58b2..4659e098f 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -23,7 +23,6 @@ namespace OpenGL { using Tegra::Texture::SwizzleSource; using VideoCore::MortonSwizzleMode; -using VideoCore::Surface::ComponentType; using VideoCore::Surface::PixelFormat; using VideoCore::Surface::SurfaceCompression; using VideoCore::Surface::SurfaceTarget; @@ -40,114 +39,95 @@ struct FormatTuple { GLint internal_format; GLenum format; GLenum type; - ComponentType component_type; bool compressed; }; constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{ - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U - {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S - {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false}, // ABGR8UI - {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5U - {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, ComponentType::UNorm, - false}, // A2B10G10R10U - {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ComponentType::UNorm, false}, // A1B5G5R5U - {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8U - {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false}, // R8UI - {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, ComponentType::Float, false}, // RGBA16F - {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RGBA16U - {GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RGBA16UI - {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, ComponentType::Float, - false}, // R11FG11FB10F - {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RGBA32UI - {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // DXT1 - {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // DXT23 - {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // DXT45 - {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1 - {GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // DXN2UNORM - {GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_INT, ComponentType::SNorm, true}, // DXN2SNORM - {GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // BC7U - {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, ComponentType::Float, - true}, // BC6H_UF16 - {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, ComponentType::Float, - true}, // BC6H_SF16 - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 - {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // BGRA8 - {GL_RGBA32F, GL_RGBA, GL_FLOAT, ComponentType::Float, false}, // RGBA32F - {GL_RG32F, GL_RG, GL_FLOAT, ComponentType::Float, false}, // RG32F - {GL_R32F, GL_RED, GL_FLOAT, ComponentType::Float, false}, // R32F - {GL_R16F, GL_RED, GL_HALF_FLOAT, ComponentType::Float, false}, // R16F - {GL_R16, GL_RED, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // R16U - {GL_R16_SNORM, GL_RED, GL_SHORT, ComponentType::SNorm, false}, // R16S - {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // R16UI - {GL_R16I, GL_RED_INTEGER, GL_SHORT, ComponentType::SInt, false}, // R16I - {GL_RG16, GL_RG, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RG16 - {GL_RG16F, GL_RG, GL_HALF_FLOAT, ComponentType::Float, false}, // RG16F - {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI - {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I - {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S - {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, - false}, // RGBA8_SRGB - {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // RG8U - {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // RG8S - {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RG32UI - {GL_RGB16F, GL_RGBA16, GL_HALF_FLOAT, ComponentType::Float, false}, // RGBX16F - {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // R32UI - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X8 - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X5 - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X4 - {GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // BGRA8 + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8U + {GL_RGBA8, GL_RGBA, GL_BYTE, false}, // ABGR8S + {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, false}, // ABGR8UI + {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false}, // B5G6R5U + {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10U + {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, false}, // A1B5G5R5U + {GL_R8, GL_RED, GL_UNSIGNED_BYTE, false}, // R8U + {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, false}, // R8UI + {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, false}, // RGBA16F + {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, false}, // RGBA16U + {GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, false}, // RGBA16UI + {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, false}, // R11FG11FB10F + {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, false}, // RGBA32UI + {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1 + {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23 + {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45 + {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, true}, // DXN1 + {GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_INT_8_8_8_8, true}, // DXN2UNORM + {GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_INT, true}, // DXN2SNORM + {GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // BC7U + {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // BC6H_UF16 + {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // BC6H_SF16 + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_4X4 + {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, false}, // BGRA8 + {GL_RGBA32F, GL_RGBA, GL_FLOAT, false}, // RGBA32F + {GL_RG32F, GL_RG, GL_FLOAT, false}, // RG32F + {GL_R32F, GL_RED, GL_FLOAT, false}, // R32F + {GL_R16F, GL_RED, GL_HALF_FLOAT, false}, // R16F + {GL_R16, GL_RED, GL_UNSIGNED_SHORT, false}, // R16U + {GL_R16_SNORM, GL_RED, GL_SHORT, false}, // R16S + {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, false}, // R16UI + {GL_R16I, GL_RED_INTEGER, GL_SHORT, false}, // R16I + {GL_RG16, GL_RG, GL_UNSIGNED_SHORT, false}, // RG16 + {GL_RG16F, GL_RG, GL_HALF_FLOAT, false}, // RG16F + {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, false}, // RG16UI + {GL_RG16I, GL_RG_INTEGER, GL_SHORT, false}, // RG16I + {GL_RG16_SNORM, GL_RG, GL_SHORT, false}, // RG16S + {GL_RGB32F, GL_RGB, GL_FLOAT, false}, // RGB32F + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // RGBA8_SRGB + {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, false}, // RG8U + {GL_RG8, GL_RG, GL_BYTE, false}, // RG8S + {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, false}, // RG32UI + {GL_RGB16F, GL_RGBA16, GL_HALF_FLOAT, false}, // RGBX16F + {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, false}, // R32UI + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X8 + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X5 + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_5X4 + {GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, false}, // BGRA8 // Compressed sRGB formats - {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // DXT1_SRGB - {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // DXT23_SRGB - {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // DXT45_SRGB - {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, - true}, // BC7U_SRGB - {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, ComponentType::UNorm, false}, // R4G4B4A4U - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4_SRGB - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X8_SRGB - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X5_SRGB - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X4_SRGB - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X5 - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X5_SRGB - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_10X8 - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_10X8_SRGB - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_6X6 - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_6X6_SRGB - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_10X10 - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_10X10_SRGB - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_12X12 - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_12X12_SRGB - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X6 - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X6_SRGB - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_6X5 - {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_6X5_SRGB - {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, ComponentType::Float, false}, // E5B9G9R9F + {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1_SRGB + {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23_SRGB + {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45_SRGB + {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // BC7U_SRGB + {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, false}, // R4G4B4A4U + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_4X4_SRGB + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X8_SRGB + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X5_SRGB + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_5X4_SRGB + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_5X5 + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_5X5_SRGB + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_10X8 + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_10X8_SRGB + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_6X6 + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_6X6_SRGB + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_10X10 + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_10X10_SRGB + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_12X12 + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_12X12_SRGB + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X6 + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_8X6_SRGB + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_6X5 + {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_6X5_SRGB + {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, false}, // E5B9G9R9F // Depth formats - {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F - {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, ComponentType::UNorm, - false}, // Z16 + {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false}, // Z32F + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, false}, // Z16 // DepthStencil formats - {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, - false}, // Z24S8 - {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, - false}, // S8Z24 - {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, - ComponentType::Float, false}, // Z32FS8 + {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false}, // Z24S8 + {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false}, // S8Z24 + {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, false}, // Z32FS8 }}; -const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { +const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { ASSERT(static_cast<std::size_t>(pixel_format) < tex_format_tuples.size()); const auto& format{tex_format_tuples[static_cast<std::size_t>(pixel_format)]}; return format; @@ -249,7 +229,7 @@ OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum inte CachedSurface::CachedSurface(const GPUVAddr gpu_addr, const SurfaceParams& params) : VideoCommon::SurfaceBase<View>(gpu_addr, params) { - const auto& tuple{GetFormatTuple(params.pixel_format, params.component_type)}; + const auto& tuple{GetFormatTuple(params.pixel_format)}; internal_format = tuple.internal_format; format = tuple.format; type = tuple.type; @@ -451,8 +431,7 @@ OGLTextureView CachedSurfaceView::CreateTextureView() const { texture_view.Create(); const GLuint handle{texture_view.handle}; - const FormatTuple& tuple{ - GetFormatTuple(owner_params.pixel_format, owner_params.component_type)}; + const FormatTuple& tuple{GetFormatTuple(owner_params.pixel_format)}; glTextureView(handle, target, surface.texture.handle, tuple.internal_format, params.base_level, params.num_levels, params.base_layer, params.num_layers); @@ -562,8 +541,8 @@ void TextureCacheOpenGL::BufferCopy(Surface& src_surface, Surface& dst_surface) const auto& dst_params = dst_surface->GetSurfaceParams(); UNIMPLEMENTED_IF(src_params.num_levels > 1 || dst_params.num_levels > 1); - const auto source_format = GetFormatTuple(src_params.pixel_format, src_params.component_type); - const auto dest_format = GetFormatTuple(dst_params.pixel_format, dst_params.component_type); + const auto source_format = GetFormatTuple(src_params.pixel_format); + const auto dest_format = GetFormatTuple(dst_params.pixel_format); const std::size_t source_size = src_surface->GetHostSizeInBytes(); const std::size_t dest_size = dst_surface->GetHostSizeInBytes(); diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 3c5acda3e..463ed43ae 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -95,83 +95,82 @@ vk::CompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compar } // namespace Sampler struct FormatTuple { - vk::Format format; ///< Vulkan format - ComponentType component_type; ///< Abstracted component type - bool attachable; ///< True when this format can be used as an attachment + vk::Format format; ///< Vulkan format + bool attachable; ///< True when this format can be used as an attachment }; static constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{ - {vk::Format::eA8B8G8R8UnormPack32, ComponentType::UNorm, true}, // ABGR8U - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ABGR8S - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ABGR8UI - {vk::Format::eB5G6R5UnormPack16, ComponentType::UNorm, false}, // B5G6R5U - {vk::Format::eA2B10G10R10UnormPack32, ComponentType::UNorm, true}, // A2B10G10R10U - {vk::Format::eUndefined, ComponentType::Invalid, false}, // A1B5G5R5U - {vk::Format::eR8Unorm, ComponentType::UNorm, true}, // R8U - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R8UI - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA16F - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA16U - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA16UI - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R11FG11FB10F - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA32UI - {vk::Format::eBc1RgbaUnormBlock, ComponentType::UNorm, false}, // DXT1 - {vk::Format::eBc2UnormBlock, ComponentType::UNorm, false}, // DXT23 - {vk::Format::eBc3UnormBlock, ComponentType::UNorm, false}, // DXT45 - {vk::Format::eBc4UnormBlock, ComponentType::UNorm, false}, // DXN1 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXN2UNORM - {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXN2SNORM - {vk::Format::eUndefined, ComponentType::Invalid, false}, // BC7U - {vk::Format::eUndefined, ComponentType::Invalid, false}, // BC6H_UF16 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // BC6H_SF16 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_4X4 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // BGRA8 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA32F - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG32F - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R32F - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16F - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16U - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16S - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16UI - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16I - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16F - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16UI - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16I - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16S - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGB32F - {vk::Format::eA8B8G8R8SrgbPack32, ComponentType::UNorm, true}, // RGBA8_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG8U - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG8S - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG32UI - {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBX16F - {vk::Format::eUndefined, ComponentType::Invalid, false}, // R32UI - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_8X8 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_8X5 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_5X4 + {vk::Format::eA8B8G8R8UnormPack32, true}, // ABGR8U + {vk::Format::eUndefined, false}, // ABGR8S + {vk::Format::eUndefined, false}, // ABGR8UI + {vk::Format::eB5G6R5UnormPack16, false}, // B5G6R5U + {vk::Format::eA2B10G10R10UnormPack32, true}, // A2B10G10R10U + {vk::Format::eUndefined, false}, // A1B5G5R5U + {vk::Format::eR8Unorm, true}, // R8U + {vk::Format::eUndefined, false}, // R8UI + {vk::Format::eUndefined, false}, // RGBA16F + {vk::Format::eUndefined, false}, // RGBA16U + {vk::Format::eUndefined, false}, // RGBA16UI + {vk::Format::eUndefined, false}, // R11FG11FB10F + {vk::Format::eUndefined, false}, // RGBA32UI + {vk::Format::eBc1RgbaUnormBlock, false}, // DXT1 + {vk::Format::eBc2UnormBlock, false}, // DXT23 + {vk::Format::eBc3UnormBlock, false}, // DXT45 + {vk::Format::eBc4UnormBlock, false}, // DXN1 + {vk::Format::eUndefined, false}, // DXN2UNORM + {vk::Format::eUndefined, false}, // DXN2SNORM + {vk::Format::eUndefined, false}, // BC7U + {vk::Format::eUndefined, false}, // BC6H_UF16 + {vk::Format::eUndefined, false}, // BC6H_SF16 + {vk::Format::eUndefined, false}, // ASTC_2D_4X4 + {vk::Format::eUndefined, false}, // BGRA8 + {vk::Format::eUndefined, false}, // RGBA32F + {vk::Format::eUndefined, false}, // RG32F + {vk::Format::eUndefined, false}, // R32F + {vk::Format::eUndefined, false}, // R16F + {vk::Format::eUndefined, false}, // R16U + {vk::Format::eUndefined, false}, // R16S + {vk::Format::eUndefined, false}, // R16UI + {vk::Format::eUndefined, false}, // R16I + {vk::Format::eUndefined, false}, // RG16 + {vk::Format::eUndefined, false}, // RG16F + {vk::Format::eUndefined, false}, // RG16UI + {vk::Format::eUndefined, false}, // RG16I + {vk::Format::eUndefined, false}, // RG16S + {vk::Format::eUndefined, false}, // RGB32F + {vk::Format::eA8B8G8R8SrgbPack32, true}, // RGBA8_SRGB + {vk::Format::eUndefined, false}, // RG8U + {vk::Format::eUndefined, false}, // RG8S + {vk::Format::eUndefined, false}, // RG32UI + {vk::Format::eUndefined, false}, // RGBX16F + {vk::Format::eUndefined, false}, // R32UI + {vk::Format::eUndefined, false}, // ASTC_2D_8X8 + {vk::Format::eUndefined, false}, // ASTC_2D_8X5 + {vk::Format::eUndefined, false}, // ASTC_2D_5X4 // Compressed sRGB formats - {vk::Format::eUndefined, ComponentType::Invalid, false}, // BGRA8_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXT1_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXT23_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXT45_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // BC7U_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_4X4_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_8X8_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_8X5_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_5X4_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_5X5 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_5X5_SRGB - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_10X8 - {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_10X8_SRGB + {vk::Format::eUndefined, false}, // BGRA8_SRGB + {vk::Format::eUndefined, false}, // DXT1_SRGB + {vk::Format::eUndefined, false}, // DXT23_SRGB + {vk::Format::eUndefined, false}, // DXT45_SRGB + {vk::Format::eUndefined, false}, // BC7U_SRGB + {vk::Format::eUndefined, false}, // ASTC_2D_4X4_SRGB + {vk::Format::eUndefined, false}, // ASTC_2D_8X8_SRGB + {vk::Format::eUndefined, false}, // ASTC_2D_8X5_SRGB + {vk::Format::eUndefined, false}, // ASTC_2D_5X4_SRGB + {vk::Format::eUndefined, false}, // ASTC_2D_5X5 + {vk::Format::eUndefined, false}, // ASTC_2D_5X5_SRGB + {vk::Format::eUndefined, false}, // ASTC_2D_10X8 + {vk::Format::eUndefined, false}, // ASTC_2D_10X8_SRGB // Depth formats - {vk::Format::eD32Sfloat, ComponentType::Float, true}, // Z32F - {vk::Format::eD16Unorm, ComponentType::UNorm, true}, // Z16 + {vk::Format::eD32Sfloat, true}, // Z32F + {vk::Format::eD16Unorm, true}, // Z16 // DepthStencil formats - {vk::Format::eD24UnormS8Uint, ComponentType::UNorm, true}, // Z24S8 - {vk::Format::eD24UnormS8Uint, ComponentType::UNorm, true}, // S8Z24 (emulated) - {vk::Format::eUndefined, ComponentType::Invalid, false}, // Z32FS8 + {vk::Format::eD24UnormS8Uint, true}, // Z24S8 + {vk::Format::eD24UnormS8Uint, true}, // S8Z24 (emulated) + {vk::Format::eUndefined, false}, // Z32FS8 }}; static constexpr bool IsZetaFormat(PixelFormat pixel_format) { @@ -180,14 +179,13 @@ static constexpr bool IsZetaFormat(PixelFormat pixel_format) { } std::pair<vk::Format, bool> SurfaceFormat(const VKDevice& device, FormatType format_type, - PixelFormat pixel_format, ComponentType component_type) { + PixelFormat pixel_format) { ASSERT(static_cast<std::size_t>(pixel_format) < tex_format_tuples.size()); const auto tuple = tex_format_tuples[static_cast<u32>(pixel_format)]; UNIMPLEMENTED_IF_MSG(tuple.format == vk::Format::eUndefined, - "Unimplemented texture format with pixel format={} and component type={}", - static_cast<u32>(pixel_format), static_cast<u32>(component_type)); - ASSERT_MSG(component_type == tuple.component_type, "Component type mismatch"); + "Unimplemented texture format with pixel format={}", + static_cast<u32>(pixel_format)); auto usage = vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eTransferDst | vk::FormatFeatureFlagBits::eTransferSrc; diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h index 4cadc0721..5b0ffd87a 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.h +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h @@ -16,7 +16,6 @@ namespace Vulkan::MaxwellToVK { using Maxwell = Tegra::Engines::Maxwell3D::Regs; using PixelFormat = VideoCore::Surface::PixelFormat; -using ComponentType = VideoCore::Surface::ComponentType; namespace Sampler { @@ -31,7 +30,7 @@ vk::CompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compar } // namespace Sampler std::pair<vk::Format, bool> SurfaceFormat(const VKDevice& device, FormatType format_type, - PixelFormat pixel_format, ComponentType component_type); + PixelFormat pixel_format); vk::ShaderStageFlagBits ShaderStage(Maxwell::ShaderStage stage); diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index 116b95f76..17cd45d3c 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp @@ -256,7 +256,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { break; } case OpCode::Id::DEPBAR: { - LOG_WARNING(HW_GPU, "DEPBAR instruction is stubbed"); + LOG_DEBUG(HW_GPU, "DEPBAR instruction is stubbed"); break; } default: diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 4b6846113..1655ccf16 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -168,311 +168,6 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) } } -PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format, - Tegra::Texture::ComponentType component_type, - bool is_srgb) { - // TODO(Subv): Properly implement this - switch (format) { - case Tegra::Texture::TextureFormat::A8R8G8B8: - if (is_srgb) { - return PixelFormat::RGBA8_SRGB; - } - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::ABGR8U; - case Tegra::Texture::ComponentType::SNORM: - return PixelFormat::ABGR8S; - case Tegra::Texture::ComponentType::UINT: - return PixelFormat::ABGR8UI; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::B5G6R5: - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::B5G6R5U; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::A2B10G10R10: - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::A2B10G10R10U; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::A1B5G5R5: - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::A1B5G5R5U; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::A4B4G4R4: - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::R4G4B4A4U; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::R8: - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::R8U; - case Tegra::Texture::ComponentType::UINT: - return PixelFormat::R8UI; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::G8R8: - // TextureFormat::G8R8 is actually ordered red then green, as such we can use - // PixelFormat::RG8U and PixelFormat::RG8S. This was tested with The Legend of Zelda: Breath - // of the Wild, which uses this format to render the hearts on the UI. - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::RG8U; - case Tegra::Texture::ComponentType::SNORM: - return PixelFormat::RG8S; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::R16_G16_B16_A16: - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::RGBA16U; - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::RGBA16F; - case Tegra::Texture::ComponentType::UINT: - return PixelFormat::RGBA16UI; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::BF10GF11RF11: - switch (component_type) { - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::R11FG11FB10F; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::R32_G32_B32_A32: - switch (component_type) { - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::RGBA32F; - case Tegra::Texture::ComponentType::UINT: - return PixelFormat::RGBA32UI; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::R32_G32: - switch (component_type) { - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::RG32F; - case Tegra::Texture::ComponentType::UINT: - return PixelFormat::RG32UI; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::R32_G32_B32: - switch (component_type) { - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::RGB32F; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::R16: - switch (component_type) { - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::R16F; - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::R16U; - case Tegra::Texture::ComponentType::SNORM: - return PixelFormat::R16S; - case Tegra::Texture::ComponentType::UINT: - return PixelFormat::R16UI; - case Tegra::Texture::ComponentType::SINT: - return PixelFormat::R16I; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::R32: - switch (component_type) { - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::R32F; - case Tegra::Texture::ComponentType::UINT: - return PixelFormat::R32UI; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::E5B9G9R9_SHAREDEXP: - switch (component_type) { - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::E5B9G9R9F; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::ZF32: - return PixelFormat::Z32F; - case Tegra::Texture::TextureFormat::Z16: - return PixelFormat::Z16; - case Tegra::Texture::TextureFormat::S8Z24: - return PixelFormat::S8Z24; - case Tegra::Texture::TextureFormat::ZF32_X24S8: - return PixelFormat::Z32FS8; - case Tegra::Texture::TextureFormat::DXT1: - return is_srgb ? PixelFormat::DXT1_SRGB : PixelFormat::DXT1; - case Tegra::Texture::TextureFormat::DXT23: - return is_srgb ? PixelFormat::DXT23_SRGB : PixelFormat::DXT23; - case Tegra::Texture::TextureFormat::DXT45: - return is_srgb ? PixelFormat::DXT45_SRGB : PixelFormat::DXT45; - case Tegra::Texture::TextureFormat::DXN1: - return PixelFormat::DXN1; - case Tegra::Texture::TextureFormat::DXN2: - switch (component_type) { - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::DXN2UNORM; - case Tegra::Texture::ComponentType::SNORM: - return PixelFormat::DXN2SNORM; - default: - break; - } - break; - case Tegra::Texture::TextureFormat::BC7U: - return is_srgb ? PixelFormat::BC7U_SRGB : PixelFormat::BC7U; - case Tegra::Texture::TextureFormat::BC6H_UF16: - return PixelFormat::BC6H_UF16; - case Tegra::Texture::TextureFormat::BC6H_SF16: - return PixelFormat::BC6H_SF16; - case Tegra::Texture::TextureFormat::ASTC_2D_4X4: - return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4; - case Tegra::Texture::TextureFormat::ASTC_2D_5X4: - return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4; - case Tegra::Texture::TextureFormat::ASTC_2D_5X5: - return is_srgb ? PixelFormat::ASTC_2D_5X5_SRGB : PixelFormat::ASTC_2D_5X5; - case Tegra::Texture::TextureFormat::ASTC_2D_8X8: - return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8; - case Tegra::Texture::TextureFormat::ASTC_2D_8X5: - return is_srgb ? PixelFormat::ASTC_2D_8X5_SRGB : PixelFormat::ASTC_2D_8X5; - case Tegra::Texture::TextureFormat::ASTC_2D_10X8: - return is_srgb ? PixelFormat::ASTC_2D_10X8_SRGB : PixelFormat::ASTC_2D_10X8; - case Tegra::Texture::TextureFormat::ASTC_2D_6X6: - return is_srgb ? PixelFormat::ASTC_2D_6X6_SRGB : PixelFormat::ASTC_2D_6X6; - case Tegra::Texture::TextureFormat::ASTC_2D_10X10: - return is_srgb ? PixelFormat::ASTC_2D_10X10_SRGB : PixelFormat::ASTC_2D_10X10; - case Tegra::Texture::TextureFormat::ASTC_2D_12X12: - return is_srgb ? PixelFormat::ASTC_2D_12X12_SRGB : PixelFormat::ASTC_2D_12X12; - case Tegra::Texture::TextureFormat::ASTC_2D_8X6: - return is_srgb ? PixelFormat::ASTC_2D_8X6_SRGB : PixelFormat::ASTC_2D_8X6; - case Tegra::Texture::TextureFormat::ASTC_2D_6X5: - return is_srgb ? PixelFormat::ASTC_2D_6X5_SRGB : PixelFormat::ASTC_2D_6X5; - case Tegra::Texture::TextureFormat::R16_G16: - switch (component_type) { - case Tegra::Texture::ComponentType::FLOAT: - return PixelFormat::RG16F; - case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::RG16; - case Tegra::Texture::ComponentType::SNORM: - return PixelFormat::RG16S; - case Tegra::Texture::ComponentType::UINT: - return PixelFormat::RG16UI; - case Tegra::Texture::ComponentType::SINT: - return PixelFormat::RG16I; - default: - break; - } - break; - default: - break; - } - LOG_CRITICAL(HW_GPU, "Unimplemented format={}, component_type={}", static_cast<u32>(format), - static_cast<u32>(component_type)); - UNREACHABLE(); - return PixelFormat::ABGR8U; -} - -ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { - // TODO(Subv): Implement more component types - switch (type) { - case Tegra::Texture::ComponentType::UNORM: - return ComponentType::UNorm; - case Tegra::Texture::ComponentType::FLOAT: - return ComponentType::Float; - case Tegra::Texture::ComponentType::SNORM: - return ComponentType::SNorm; - case Tegra::Texture::ComponentType::UINT: - return ComponentType::UInt; - case Tegra::Texture::ComponentType::SINT: - return ComponentType::SInt; - default: - LOG_CRITICAL(HW_GPU, "Unimplemented component type={}", static_cast<u32>(type)); - UNREACHABLE(); - return ComponentType::UNorm; - } -} - -ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format) { - // TODO(Subv): Implement more render targets - switch (format) { - case Tegra::RenderTargetFormat::RGBA8_UNORM: - case Tegra::RenderTargetFormat::RGBA8_SRGB: - case Tegra::RenderTargetFormat::BGRA8_UNORM: - case Tegra::RenderTargetFormat::BGRA8_SRGB: - case Tegra::RenderTargetFormat::RGB10_A2_UNORM: - case Tegra::RenderTargetFormat::R8_UNORM: - case Tegra::RenderTargetFormat::RG16_UNORM: - case Tegra::RenderTargetFormat::R16_UNORM: - case Tegra::RenderTargetFormat::B5G6R5_UNORM: - case Tegra::RenderTargetFormat::BGR5A1_UNORM: - case Tegra::RenderTargetFormat::RG8_UNORM: - case Tegra::RenderTargetFormat::RGBA16_UNORM: - return ComponentType::UNorm; - case Tegra::RenderTargetFormat::RGBA8_SNORM: - case Tegra::RenderTargetFormat::RG16_SNORM: - case Tegra::RenderTargetFormat::R16_SNORM: - case Tegra::RenderTargetFormat::RG8_SNORM: - return ComponentType::SNorm; - case Tegra::RenderTargetFormat::RGBA16_FLOAT: - case Tegra::RenderTargetFormat::RGBX16_FLOAT: - case Tegra::RenderTargetFormat::R11G11B10_FLOAT: - case Tegra::RenderTargetFormat::RGBA32_FLOAT: - case Tegra::RenderTargetFormat::RG32_FLOAT: - case Tegra::RenderTargetFormat::RG16_FLOAT: - case Tegra::RenderTargetFormat::R16_FLOAT: - case Tegra::RenderTargetFormat::R32_FLOAT: - return ComponentType::Float; - case Tegra::RenderTargetFormat::RGBA32_UINT: - case Tegra::RenderTargetFormat::RGBA16_UINT: - case Tegra::RenderTargetFormat::RG16_UINT: - case Tegra::RenderTargetFormat::R8_UINT: - case Tegra::RenderTargetFormat::R16_UINT: - case Tegra::RenderTargetFormat::RG32_UINT: - case Tegra::RenderTargetFormat::R32_UINT: - case Tegra::RenderTargetFormat::RGBA8_UINT: - return ComponentType::UInt; - case Tegra::RenderTargetFormat::RG16_SINT: - case Tegra::RenderTargetFormat::R16_SINT: - return ComponentType::SInt; - default: - LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); - UNREACHABLE(); - return ComponentType::UNorm; - } -} - PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { switch (format) { case Tegra::FramebufferConfig::PixelFormat::ABGR8: @@ -487,22 +182,6 @@ PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat } } -ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) { - switch (format) { - case Tegra::DepthFormat::Z16_UNORM: - case Tegra::DepthFormat::S8_Z24_UNORM: - case Tegra::DepthFormat::Z24_S8_UNORM: - return ComponentType::UNorm; - case Tegra::DepthFormat::Z32_FLOAT: - case Tegra::DepthFormat::Z32_S8_X24_FLOAT: - return ComponentType::Float; - default: - LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); - UNREACHABLE(); - return ComponentType::UNorm; - } -} - SurfaceType GetFormatType(PixelFormat pixel_format) { if (static_cast<std::size_t>(pixel_format) < static_cast<std::size_t>(PixelFormat::MaxColorFormat)) { diff --git a/src/video_core/surface.h b/src/video_core/surface.h index d3bcd38c5..0d17a93ed 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -106,18 +106,8 @@ enum class PixelFormat { Max = MaxDepthStencilFormat, Invalid = 255, }; - static constexpr std::size_t MaxPixelFormat = static_cast<std::size_t>(PixelFormat::Max); -enum class ComponentType { - Invalid = 0, - SNorm = 1, - UNorm = 2, - SInt = 3, - UInt = 4, - Float = 5, -}; - enum class SurfaceType { ColorTexture = 0, Depth = 1, @@ -609,18 +599,8 @@ PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format); PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format); -PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format, - Tegra::Texture::ComponentType component_type, - bool is_srgb); - -ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type); - -ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format); - PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format); -ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format); - SurfaceType GetFormatType(PixelFormat pixel_format); bool IsPixelFormatASTC(PixelFormat format); diff --git a/src/video_core/texture_cache/format_lookup_table.cpp b/src/video_core/texture_cache/format_lookup_table.cpp new file mode 100644 index 000000000..271e67533 --- /dev/null +++ b/src/video_core/texture_cache/format_lookup_table.cpp @@ -0,0 +1,208 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <array> +#include "common/common_types.h" +#include "common/logging/log.h" +#include "video_core/texture_cache/format_lookup_table.h" + +namespace VideoCommon { + +using Tegra::Texture::ComponentType; +using Tegra::Texture::TextureFormat; +using VideoCore::Surface::PixelFormat; + +namespace { + +constexpr auto SNORM = ComponentType::SNORM; +constexpr auto UNORM = ComponentType::UNORM; +constexpr auto SINT = ComponentType::SINT; +constexpr auto UINT = ComponentType::UINT; +constexpr auto SNORM_FORCE_FP16 = ComponentType::SNORM_FORCE_FP16; +constexpr auto UNORM_FORCE_FP16 = ComponentType::UNORM_FORCE_FP16; +constexpr auto FLOAT = ComponentType::FLOAT; +constexpr bool C = false; // Normal color +constexpr bool S = true; // Srgb + +struct Table { + constexpr Table(TextureFormat texture_format, bool is_srgb, ComponentType red_component, + ComponentType green_component, ComponentType blue_component, + ComponentType alpha_component, PixelFormat pixel_format) + : texture_format{texture_format}, pixel_format{pixel_format}, red_component{red_component}, + green_component{green_component}, blue_component{blue_component}, + alpha_component{alpha_component}, is_srgb{is_srgb} {} + + TextureFormat texture_format; + PixelFormat pixel_format; + ComponentType red_component; + ComponentType green_component; + ComponentType blue_component; + ComponentType alpha_component; + bool is_srgb; +}; +constexpr std::array<Table, 74> DefinitionTable = {{ + {TextureFormat::A8R8G8B8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ABGR8U}, + {TextureFormat::A8R8G8B8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::ABGR8S}, + {TextureFormat::A8R8G8B8, C, UINT, UINT, UINT, UINT, PixelFormat::ABGR8UI}, + {TextureFormat::A8R8G8B8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::RGBA8_SRGB}, + + {TextureFormat::B5G6R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::B5G6R5U}, + + {TextureFormat::A2B10G10R10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A2B10G10R10U}, + + {TextureFormat::A1B5G5R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A1B5G5R5U}, + + {TextureFormat::A4B4G4R4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R4G4B4A4U}, + + {TextureFormat::R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R8U}, + {TextureFormat::R8, C, UINT, UINT, UINT, UINT, PixelFormat::R8UI}, + + {TextureFormat::G8R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RG8U}, + {TextureFormat::G8R8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RG8S}, + + {TextureFormat::R16_G16_B16_A16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RGBA16U}, + {TextureFormat::R16_G16_B16_A16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGBA16F}, + {TextureFormat::R16_G16_B16_A16, C, UINT, UINT, UINT, UINT, PixelFormat::RGBA16UI}, + + {TextureFormat::R16_G16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RG16F}, + {TextureFormat::R16_G16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RG16}, + {TextureFormat::R16_G16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RG16S}, + {TextureFormat::R16_G16, C, UINT, UINT, UINT, UINT, PixelFormat::RG16UI}, + {TextureFormat::R16_G16, C, SINT, SINT, SINT, SINT, PixelFormat::RG16I}, + + {TextureFormat::R16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16F}, + {TextureFormat::R16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16U}, + {TextureFormat::R16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16S}, + {TextureFormat::R16, C, UINT, UINT, UINT, UINT, PixelFormat::R16UI}, + {TextureFormat::R16, C, SINT, SINT, SINT, SINT, PixelFormat::R16I}, + + {TextureFormat::BF10GF11RF11, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R11FG11FB10F}, + + {TextureFormat::R32_G32_B32_A32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGBA32F}, + {TextureFormat::R32_G32_B32_A32, C, UINT, UINT, UINT, UINT, PixelFormat::RGBA32UI}, + + {TextureFormat::R32_G32_B32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGB32F}, + + {TextureFormat::R32_G32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RG32F}, + {TextureFormat::R32_G32, C, UINT, UINT, UINT, UINT, PixelFormat::RG32UI}, + + {TextureFormat::R32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32F}, + {TextureFormat::R32, C, UINT, UINT, UINT, UINT, PixelFormat::R32UI}, + + {TextureFormat::E5B9G9R9_SHAREDEXP, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::E5B9G9R9F}, + + {TextureFormat::ZF32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::Z32F}, + {TextureFormat::Z16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::Z16}, + {TextureFormat::S8Z24, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8Z24}, + {TextureFormat::ZF32_X24S8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::Z32FS8}, + + {TextureFormat::DXT1, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT1}, + {TextureFormat::DXT1, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT1_SRGB}, + + {TextureFormat::DXT23, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT23}, + {TextureFormat::DXT23, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT23_SRGB}, + + {TextureFormat::DXT45, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT45}, + {TextureFormat::DXT45, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT45_SRGB}, + + // TODO: Use a different pixel format for SNORM + {TextureFormat::DXN1, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXN1}, + {TextureFormat::DXN1, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::DXN1}, + + {TextureFormat::DXN2, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXN2UNORM}, + {TextureFormat::DXN2, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::DXN2SNORM}, + + {TextureFormat::BC7U, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7U}, + {TextureFormat::BC7U, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7U_SRGB}, + + {TextureFormat::BC6H_SF16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_SF16}, + {TextureFormat::BC6H_UF16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_UF16}, + + {TextureFormat::ASTC_2D_4X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4}, + {TextureFormat::ASTC_2D_4X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4_SRGB}, + + {TextureFormat::ASTC_2D_5X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4}, + {TextureFormat::ASTC_2D_5X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4_SRGB}, + + {TextureFormat::ASTC_2D_5X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5}, + {TextureFormat::ASTC_2D_5X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5_SRGB}, + + {TextureFormat::ASTC_2D_8X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8}, + {TextureFormat::ASTC_2D_8X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8_SRGB}, + + {TextureFormat::ASTC_2D_8X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5}, + {TextureFormat::ASTC_2D_8X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5_SRGB}, + + {TextureFormat::ASTC_2D_10X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8}, + {TextureFormat::ASTC_2D_10X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8_SRGB}, + + {TextureFormat::ASTC_2D_6X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6}, + {TextureFormat::ASTC_2D_6X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6_SRGB}, + + {TextureFormat::ASTC_2D_10X10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10}, + {TextureFormat::ASTC_2D_10X10, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10_SRGB}, + + {TextureFormat::ASTC_2D_12X12, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12}, + {TextureFormat::ASTC_2D_12X12, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12_SRGB}, + + {TextureFormat::ASTC_2D_8X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6}, + {TextureFormat::ASTC_2D_8X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6_SRGB}, + + {TextureFormat::ASTC_2D_6X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5}, + {TextureFormat::ASTC_2D_6X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5_SRGB}, +}}; + +} // Anonymous namespace + +FormatLookupTable::FormatLookupTable() { + table.fill(static_cast<u8>(PixelFormat::Invalid)); + + for (const auto& entry : DefinitionTable) { + table[CalculateIndex(entry.texture_format, entry.is_srgb != 0, entry.red_component, + entry.green_component, entry.blue_component, entry.alpha_component)] = + static_cast<u8>(entry.pixel_format); + } +} + +PixelFormat FormatLookupTable::GetPixelFormat(TextureFormat format, bool is_srgb, + ComponentType red_component, + ComponentType green_component, + ComponentType blue_component, + ComponentType alpha_component) const noexcept { + const auto pixel_format = static_cast<PixelFormat>(table[CalculateIndex( + format, is_srgb, red_component, green_component, blue_component, alpha_component)]); + // [[likely]] + if (pixel_format != PixelFormat::Invalid) { + return pixel_format; + } + UNIMPLEMENTED_MSG("texture format={} srgb={} components={{{} {} {} {}}}", + static_cast<int>(format), is_srgb, static_cast<int>(red_component), + static_cast<int>(green_component), static_cast<int>(blue_component), + static_cast<int>(alpha_component)); + return PixelFormat::ABGR8U; +} + +void FormatLookupTable::Set(TextureFormat format, bool is_srgb, ComponentType red_component, + ComponentType green_component, ComponentType blue_component, + ComponentType alpha_component, PixelFormat pixel_format) {} + +std::size_t FormatLookupTable::CalculateIndex(TextureFormat format, bool is_srgb, + ComponentType red_component, + ComponentType green_component, + ComponentType blue_component, + ComponentType alpha_component) noexcept { + const auto format_index = static_cast<std::size_t>(format); + const auto red_index = static_cast<std::size_t>(red_component); + const auto green_index = static_cast<std::size_t>(red_component); + const auto blue_index = static_cast<std::size_t>(red_component); + const auto alpha_index = static_cast<std::size_t>(red_component); + const std::size_t srgb_index = is_srgb ? 1 : 0; + + return format_index * PerFormat + + srgb_index * PerComponent * PerComponent * PerComponent * PerComponent + + alpha_index * PerComponent * PerComponent * PerComponent + + blue_index * PerComponent * PerComponent + green_index * PerComponent + red_index; +} + +} // namespace VideoCommon diff --git a/src/video_core/texture_cache/format_lookup_table.h b/src/video_core/texture_cache/format_lookup_table.h new file mode 100644 index 000000000..aa77e0a5a --- /dev/null +++ b/src/video_core/texture_cache/format_lookup_table.h @@ -0,0 +1,51 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> +#include <limits> +#include "video_core/surface.h" +#include "video_core/textures/texture.h" + +namespace VideoCommon { + +class FormatLookupTable { +public: + explicit FormatLookupTable(); + + VideoCore::Surface::PixelFormat GetPixelFormat( + Tegra::Texture::TextureFormat format, bool is_srgb, + Tegra::Texture::ComponentType red_component, Tegra::Texture::ComponentType green_component, + Tegra::Texture::ComponentType blue_component, + Tegra::Texture::ComponentType alpha_component) const noexcept; + +private: + static_assert(VideoCore::Surface::MaxPixelFormat <= std::numeric_limits<u8>::max()); + + static constexpr std::size_t NumTextureFormats = 128; + + static constexpr std::size_t PerComponent = 8; + static constexpr std::size_t PerComponents2 = PerComponent * PerComponent; + static constexpr std::size_t PerComponents3 = PerComponents2 * PerComponent; + static constexpr std::size_t PerComponents4 = PerComponents3 * PerComponent; + static constexpr std::size_t PerFormat = PerComponents4 * 2; + + static std::size_t CalculateIndex(Tegra::Texture::TextureFormat format, bool is_srgb, + Tegra::Texture::ComponentType red_component, + Tegra::Texture::ComponentType green_component, + Tegra::Texture::ComponentType blue_component, + Tegra::Texture::ComponentType alpha_component) noexcept; + + void Set(Tegra::Texture::TextureFormat format, bool is_srgb, + Tegra::Texture::ComponentType red_component, + Tegra::Texture::ComponentType green_component, + Tegra::Texture::ComponentType blue_component, + Tegra::Texture::ComponentType alpha_component, + VideoCore::Surface::PixelFormat pixel_format); + + std::array<u8, NumTextureFormats * PerFormat> table; +}; + +} // namespace VideoCommon diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 1e4d3fb79..858e17e08 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -2,24 +2,23 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <map> +#include <algorithm> +#include <string> +#include <tuple> #include "common/alignment.h" #include "common/bit_util.h" #include "core/core.h" #include "video_core/engines/shader_bytecode.h" #include "video_core/surface.h" +#include "video_core/texture_cache/format_lookup_table.h" #include "video_core/texture_cache/surface_params.h" namespace VideoCommon { -using VideoCore::Surface::ComponentTypeFromDepthFormat; -using VideoCore::Surface::ComponentTypeFromRenderTarget; -using VideoCore::Surface::ComponentTypeFromTexture; using VideoCore::Surface::PixelFormat; using VideoCore::Surface::PixelFormatFromDepthFormat; using VideoCore::Surface::PixelFormatFromRenderTargetFormat; -using VideoCore::Surface::PixelFormatFromTextureFormat; using VideoCore::Surface::SurfaceTarget; using VideoCore::Surface::SurfaceTargetFromTextureType; using VideoCore::Surface::SurfaceType; @@ -69,7 +68,8 @@ constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) { } // Anonymous namespace -SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& tic, +SurfaceParams SurfaceParams::CreateForTexture(const FormatLookupTable& lookup_table, + const Tegra::Texture::TICEntry& tic, const VideoCommon::Shader::Sampler& entry) { SurfaceParams params; params.is_tiled = tic.IsTiled(); @@ -78,8 +78,8 @@ SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& ti params.block_height = params.is_tiled ? tic.BlockHeight() : 0, params.block_depth = params.is_tiled ? tic.BlockDepth() : 0, params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1; - params.pixel_format = - PixelFormatFromTextureFormat(tic.format, tic.r_type.Value(), params.srgb_conversion); + params.pixel_format = lookup_table.GetPixelFormat( + tic.format, params.srgb_conversion, tic.r_type, tic.g_type, tic.b_type, tic.a_type); params.type = GetFormatType(params.pixel_format); if (entry.IsShadow() && params.type == SurfaceType::ColorTexture) { switch (params.pixel_format) { @@ -99,7 +99,6 @@ SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& ti } params.type = GetFormatType(params.pixel_format); } - params.component_type = ComponentTypeFromTexture(tic.r_type.Value()); params.type = GetFormatType(params.pixel_format); // TODO: on 1DBuffer we should use the tic info. if (tic.IsBuffer()) { @@ -128,7 +127,8 @@ SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& ti return params; } -SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, +SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_table, + const Tegra::Texture::TICEntry& tic, const VideoCommon::Shader::Image& entry) { SurfaceParams params; params.is_tiled = tic.IsTiled(); @@ -137,10 +137,9 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, params.block_height = params.is_tiled ? tic.BlockHeight() : 0, params.block_depth = params.is_tiled ? tic.BlockDepth() : 0, params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1; - params.pixel_format = - PixelFormatFromTextureFormat(tic.format, tic.r_type.Value(), params.srgb_conversion); + params.pixel_format = lookup_table.GetPixelFormat( + tic.format, params.srgb_conversion, tic.r_type, tic.g_type, tic.b_type, tic.a_type); params.type = GetFormatType(params.pixel_format); - params.component_type = ComponentTypeFromTexture(tic.r_type.Value()); params.type = GetFormatType(params.pixel_format); params.target = ImageTypeToSurfaceTarget(entry.GetType()); // TODO: on 1DBuffer we should use the tic info. @@ -181,7 +180,6 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer( params.block_depth = std::min(block_depth, 5U); params.tile_width_spacing = 1; params.pixel_format = PixelFormatFromDepthFormat(format); - params.component_type = ComponentTypeFromDepthFormat(format); params.type = GetFormatType(params.pixel_format); params.width = zeta_width; params.height = zeta_height; @@ -206,7 +204,6 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz params.block_depth = config.memory_layout.block_depth; params.tile_width_spacing = 1; params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); - params.component_type = ComponentTypeFromRenderTarget(config.format); params.type = GetFormatType(params.pixel_format); if (params.is_tiled) { params.pitch = 0; @@ -236,7 +233,6 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 5U) : 0, params.tile_width_spacing = 1; params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); - params.component_type = ComponentTypeFromRenderTarget(config.format); params.type = GetFormatType(params.pixel_format); params.width = config.width; params.height = config.height; @@ -355,10 +351,10 @@ std::size_t SurfaceParams::GetInnerMipmapMemorySize(u32 level, bool as_host_size bool SurfaceParams::operator==(const SurfaceParams& rhs) const { return std::tie(is_tiled, block_width, block_height, block_depth, tile_width_spacing, width, - height, depth, pitch, num_levels, pixel_format, component_type, type, target) == + height, depth, pitch, num_levels, pixel_format, type, target) == std::tie(rhs.is_tiled, rhs.block_width, rhs.block_height, rhs.block_depth, rhs.tile_width_spacing, rhs.width, rhs.height, rhs.depth, rhs.pitch, - rhs.num_levels, rhs.pixel_format, rhs.component_type, rhs.type, rhs.target); + rhs.num_levels, rhs.pixel_format, rhs.type, rhs.target); } std::string SurfaceParams::TargetName() const { diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h index c58e7f8a4..709aa0dc2 100644 --- a/src/video_core/texture_cache/surface_params.h +++ b/src/video_core/texture_cache/surface_params.h @@ -16,16 +16,20 @@ namespace VideoCommon { +class FormatLookupTable; + using VideoCore::Surface::SurfaceCompression; class SurfaceParams { public: /// Creates SurfaceCachedParams from a texture configuration. - static SurfaceParams CreateForTexture(const Tegra::Texture::TICEntry& tic, + static SurfaceParams CreateForTexture(const FormatLookupTable& lookup_table, + const Tegra::Texture::TICEntry& tic, const VideoCommon::Shader::Sampler& entry); /// Creates SurfaceCachedParams from an image configuration. - static SurfaceParams CreateForImage(const Tegra::Texture::TICEntry& tic, + static SurfaceParams CreateForImage(const FormatLookupTable& lookup_table, + const Tegra::Texture::TICEntry& tic, const VideoCommon::Shader::Image& entry); /// Creates SurfaceCachedParams for a depth buffer configuration. @@ -248,7 +252,6 @@ public: u32 num_levels; u32 emulated_levels; VideoCore::Surface::PixelFormat pixel_format; - VideoCore::Surface::ComponentType component_type; VideoCore::Surface::SurfaceType type; VideoCore::Surface::SurfaceTarget target; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 6a92b22d3..41309ebea 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -29,6 +29,7 @@ #include "video_core/rasterizer_interface.h" #include "video_core/surface.h" #include "video_core/texture_cache/copy_params.h" +#include "video_core/texture_cache/format_lookup_table.h" #include "video_core/texture_cache/surface_base.h" #include "video_core/texture_cache/surface_params.h" #include "video_core/texture_cache/surface_view.h" @@ -96,7 +97,7 @@ public: if (!gpu_addr) { return {}; } - const auto params{SurfaceParams::CreateForTexture(tic, entry)}; + const auto params{SurfaceParams::CreateForTexture(format_lookup_table, tic, entry)}; const auto [surface, view] = GetSurface(gpu_addr, params, true, false); if (guard_samplers) { sampled_textures.push_back(surface); @@ -111,7 +112,7 @@ public: if (!gpu_addr) { return {}; } - const auto params{SurfaceParams::CreateForImage(tic, entry)}; + const auto params{SurfaceParams::CreateForImage(format_lookup_table, tic, entry)}; const auto [surface, view] = GetSurface(gpu_addr, params, true, false); if (guard_samplers) { sampled_textures.push_back(surface); @@ -485,15 +486,13 @@ private: GetSiblingFormat(cr_params.pixel_format) == params.pixel_format) { SurfaceParams new_params = params; new_params.pixel_format = cr_params.pixel_format; - new_params.component_type = cr_params.component_type; new_params.type = cr_params.type; new_surface = GetUncachedSurface(gpu_addr, new_params); } else { new_surface = GetUncachedSurface(gpu_addr, params); } const auto& final_params = new_surface->GetSurfaceParams(); - if (cr_params.type != final_params.type || - (cr_params.component_type != final_params.component_type)) { + if (cr_params.type != final_params.type) { BufferCopy(current_surface, new_surface); } else { std::vector<CopyParams> bricks = current_surface->BreakDown(final_params); @@ -835,12 +834,11 @@ private: } } - const auto inherit_format = ([](SurfaceParams& to, TSurface from) { + const auto inherit_format = [](SurfaceParams& to, TSurface from) { const SurfaceParams& params = from->GetSurfaceParams(); to.pixel_format = params.pixel_format; - to.component_type = params.component_type; to.type = params.type; - }); + }; // Now we got the cases where one or both is Depth and the other is not known if (!incomplete_src) { inherit_format(src_params, deduced_src.surface); @@ -956,6 +954,8 @@ private: VideoCore::RasterizerInterface& rasterizer; + FormatLookupTable format_lookup_table; + u64 ticks{}; // Guards the cache for protection conflicts. diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 160613ee1..867f8e913 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -817,6 +817,9 @@ QStringList GMainWindow::GetUnsupportedGLExtensions() { if (!GLAD_GL_ARB_multi_bind) { unsupported_ext.append(QStringLiteral("ARB_multi_bind")); } + if (!GLAD_GL_ARB_clip_control) { + unsupported_ext.append(QStringLiteral("ARB_clip_control")); + } // Extensions required to support some texture formats. if (!GLAD_GL_EXT_texture_compression_s3tc) { diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index a1ce3c0c3..21f422500 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -140,11 +140,6 @@ <string>Load Folder...</string> </property> </action> - <action name="action_Load_Symbol_Map"> - <property name="text"> - <string>Load Symbol Map...</string> - </property> - </action> <action name="action_Exit"> <property name="text"> <string>E&xit</string> @@ -221,14 +216,6 @@ <string>Show Status Bar</string> </property> </action> - <action name="action_Select_Game_List_Root"> - <property name="text"> - <string>Select Game Directory...</string> - </property> - <property name="toolTip"> - <string>Selects a folder to display in the game list</string> - </property> - </action> <action name="action_Select_NAND_Directory"> <property name="text"> <string>Select NAND Directory...</string> diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index f91b071bf..6fde694a2 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -50,7 +50,7 @@ private: }; bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { - std::vector<std::string> unsupported_ext; + std::vector<std::string_view> unsupported_ext; if (!GLAD_GL_ARB_buffer_storage) unsupported_ext.push_back("ARB_buffer_storage"); @@ -62,6 +62,8 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { unsupported_ext.push_back("ARB_texture_mirror_clamp_to_edge"); if (!GLAD_GL_ARB_multi_bind) unsupported_ext.push_back("ARB_multi_bind"); + if (!GLAD_GL_ARB_clip_control) + unsupported_ext.push_back("ARB_clip_control"); // Extensions required to support some texture formats. if (!GLAD_GL_EXT_texture_compression_s3tc) @@ -71,8 +73,8 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { if (!GLAD_GL_ARB_depth_buffer_float) unsupported_ext.push_back("ARB_depth_buffer_float"); - for (const std::string& ext : unsupported_ext) - LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext); + for (const auto& extension : unsupported_ext) + LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", extension); return unsupported_ext.empty(); } |