diff options
Diffstat (limited to 'src')
24 files changed, 182 insertions, 54 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 2cfae18df..29983b9b4 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -14,6 +14,9 @@ #include "core/core.h" #include "core/core_cpu.h" #include "core/core_timing.h" +#include "core/file_sys/mode.h" +#include "core/file_sys/vfs_concat.h" +#include "core/file_sys/vfs_real.h" #include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/kernel.h" @@ -27,8 +30,6 @@ #include "core/perf_stats.h" #include "core/settings.h" #include "core/telemetry_session.h" -#include "file_sys/vfs_concat.h" -#include "file_sys/vfs_real.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/gpu.h" #include "video_core/renderer_base.h" diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index dacf8568b..fe5d36930 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -5,9 +5,9 @@ #include <regex> #include <mbedtls/sha256.h> #include "common/assert.h" +#include "common/file_util.h" #include "common/hex_util.h" #include "common/logging/log.h" -#include "core/crypto/encryption_layer.h" #include "core/file_sys/card_image.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/registered_cache.h" diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 2b8ac7103..89b101145 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp @@ -8,6 +8,7 @@ #include <utility> #include "common/assert.h" #include "common/common_paths.h" +#include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/vfs_real.h" @@ -39,6 +40,7 @@ static std::string ModeFlagsToString(Mode mode) { } RealVfsFilesystem::RealVfsFilesystem() : VfsFilesystem(nullptr) {} +RealVfsFilesystem::~RealVfsFilesystem() = default; std::string RealVfsFilesystem::GetName() const { return "Real"; @@ -219,6 +221,8 @@ RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::shared_ptr<FileUtil::IOF parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)), perms(perms_) {} +RealVfsFile::~RealVfsFile() = default; + std::string RealVfsFile::GetName() const { return path_components.back(); } @@ -312,6 +316,8 @@ RealVfsDirectory::RealVfsDirectory(RealVfsFilesystem& base_, const std::string& FileUtil::CreateDir(path); } +RealVfsDirectory::~RealVfsDirectory() = default; + std::shared_ptr<VfsFile> RealVfsDirectory::GetFileRelative(std::string_view path) const { const auto full_path = FileUtil::SanitizePath(this->path + DIR_SEP + std::string(path)); if (!FileUtil::Exists(full_path) || FileUtil::IsDirectory(full_path)) diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h index 989803d43..7db86691f 100644 --- a/src/core/file_sys/vfs_real.h +++ b/src/core/file_sys/vfs_real.h @@ -6,15 +6,19 @@ #include <string_view> #include <boost/container/flat_map.hpp> -#include "common/file_util.h" #include "core/file_sys/mode.h" #include "core/file_sys/vfs.h" +namespace FileUtil { +class IOFile; +} + namespace FileSys { class RealVfsFilesystem : public VfsFilesystem { public: RealVfsFilesystem(); + ~RealVfsFilesystem() override; std::string GetName() const override; bool IsReadable() const override; @@ -40,10 +44,9 @@ class RealVfsFile : public VfsFile { friend class RealVfsDirectory; friend class RealVfsFilesystem; - RealVfsFile(RealVfsFilesystem& base, std::shared_ptr<FileUtil::IOFile> backing, - const std::string& path, Mode perms = Mode::Read); - public: + ~RealVfsFile() override; + std::string GetName() const override; size_t GetSize() const override; bool Resize(size_t new_size) override; @@ -55,6 +58,9 @@ public: bool Rename(std::string_view name) override; private: + RealVfsFile(RealVfsFilesystem& base, std::shared_ptr<FileUtil::IOFile> backing, + const std::string& path, Mode perms = Mode::Read); + bool Close(); RealVfsFilesystem& base; @@ -70,9 +76,9 @@ private: class RealVfsDirectory : public VfsDirectory { friend class RealVfsFilesystem; - RealVfsDirectory(RealVfsFilesystem& base, const std::string& path, Mode perms = Mode::Read); - public: + ~RealVfsDirectory() override; + std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override; std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override; std::shared_ptr<VfsFile> GetFile(std::string_view name) const override; @@ -97,6 +103,8 @@ protected: bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; private: + RealVfsDirectory(RealVfsFilesystem& base, const std::string& path, Mode perms = Mode::Read); + template <typename T, typename R> std::vector<std::shared_ptr<R>> IterateEntries() const; diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp index 552835738..4dbc25c55 100644 --- a/src/core/file_sys/xts_archive.cpp +++ b/src/core/file_sys/xts_archive.cpp @@ -10,6 +10,7 @@ #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 "core/crypto/aes_util.h" diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 615d7901a..7902c2882 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -13,6 +13,7 @@ #include "core/core.h" #include "core/core_timing.h" +#include "core/hle/kernel/client_port.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" @@ -124,6 +125,8 @@ struct KernelCore::Impl { timer_callback_handle_table.Clear(); timer_callback_event_type = nullptr; + + named_ports.clear(); } void InitializeResourceLimits(KernelCore& kernel) { @@ -217,6 +220,10 @@ struct KernelCore::Impl { // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, // allowing us to simply use a pool index or similar. Kernel::HandleTable thread_wakeup_callback_handle_table; + + /// Map of named ports managed by the kernel, which can be retrieved using + /// the ConnectToPort SVC. + NamedPortTable named_ports; }; KernelCore::KernelCore() : impl{std::make_unique<Impl>()} {} @@ -257,6 +264,23 @@ void KernelCore::AppendNewProcess(SharedPtr<Process> process) { impl->process_list.push_back(std::move(process)); } +void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) { + impl->named_ports.emplace(std::move(name), std::move(port)); +} + +KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) { + return impl->named_ports.find(name); +} + +KernelCore::NamedPortTable::const_iterator KernelCore::FindNamedPort( + const std::string& name) const { + return impl->named_ports.find(name); +} + +bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { + return port != impl->named_ports.cend(); +} + u32 KernelCore::CreateNewObjectID() { return impl->next_object_id++; } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 089e959ac..ab2e9bffa 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -4,6 +4,8 @@ #pragma once +#include <string> +#include <unordered_map> #include "core/hle/kernel/object.h" template <typename T> @@ -15,6 +17,7 @@ struct EventType; namespace Kernel { +class ClientPort; class HandleTable; class Process; class ResourceLimit; @@ -25,6 +28,9 @@ enum class ResourceLimitCategory : u8; /// Represents a single instance of the kernel. class KernelCore { +private: + using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>; + public: KernelCore(); ~KernelCore(); @@ -59,6 +65,18 @@ public: /// Adds the given shared pointer to an internal list of active processes. void AppendNewProcess(SharedPtr<Process> process); + /// Adds a port to the named port table + void AddNamedPort(std::string name, SharedPtr<ClientPort> port); + + /// Finds a port within the named port table with the given name. + NamedPortTable::iterator FindNamedPort(const std::string& name); + + /// Finds a port within the named port table with the given name. + NamedPortTable::const_iterator FindNamedPort(const std::string& name) const; + + /// Determines whether or not the given port is a valid named port. + bool IsValidNamedPort(NamedPortTable::const_iterator port) const; + private: friend class Object; friend class Process; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5da71cff0..1c9373ed8 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -68,19 +68,22 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { /// Connect to an OS service given the port name, returns the handle to the port to out static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) { - if (!Memory::IsValidVirtualAddress(port_name_address)) + if (!Memory::IsValidVirtualAddress(port_name_address)) { return ERR_NOT_FOUND; + } static constexpr std::size_t PortNameMaxLength = 11; // Read 1 char beyond the max allowed port name to detect names that are too long. std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); - if (port_name.size() > PortNameMaxLength) + if (port_name.size() > PortNameMaxLength) { return ERR_PORT_NAME_TOO_LONG; + } LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); - auto it = Service::g_kernel_named_ports.find(port_name); - if (it == Service::g_kernel_named_ports.end()) { + auto& kernel = Core::System::GetInstance().Kernel(); + auto it = kernel.FindNamedPort(port_name); + if (!kernel.IsValidNamedPort(it)) { LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name); return ERR_NOT_FOUND; } @@ -91,7 +94,6 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address CASCADE_RESULT(client_session, client_port->Connect()); // Return the client session - auto& kernel = Core::System::GetInstance().Kernel(); CASCADE_RESULT(*out_handle, kernel.HandleTable().Create(client_session)); return RESULT_SUCCESS; } diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 881c39e31..a4426af96 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -60,17 +60,20 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const { std::string path(FileUtil::SanitizePath(path_)); - auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); if (path.empty()) { // TODO(DarkLordZach): Why do games call this and what should it do? Works as is but... return RESULT_SUCCESS; } - if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr) + + auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); + if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr) { return FileSys::ERROR_PATH_NOT_FOUND; + } if (!dir->DeleteFile(FileUtil::GetFilename(path))) { // TODO(DarkLordZach): Find a better error code for this return ResultCode(-1); } + return RESULT_SUCCESS; } diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 5759299fe..3f8ff67e8 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -26,6 +26,17 @@ namespace Service::FileSystem { +enum class FileSystemType : u8 { + Invalid0 = 0, + Invalid1 = 1, + Logo = 2, + ContentControl = 3, + ContentManual = 4, + ContentMeta = 5, + ContentData = 6, + ApplicationPackage = 7, +}; + class IStorage final : public ServiceFramework<IStorage> { public: explicit IStorage(FileSys::VirtualFile backend_) @@ -420,7 +431,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { {0, nullptr, "MountContent"}, {1, &FSP_SRV::Initialize, "Initialize"}, {2, nullptr, "OpenDataFileSystemByCurrentProcess"}, - {7, nullptr, "OpenFileSystemWithPatch"}, + {7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"}, {8, nullptr, "OpenFileSystemWithId"}, {9, nullptr, "OpenDataFileSystemByApplicationId"}, {11, nullptr, "OpenBisFileSystem"}, @@ -444,7 +455,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { {34, nullptr, "GetCacheStorageSize"}, {51, &FSP_SRV::MountSaveData, "MountSaveData"}, {52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"}, - {53, nullptr, "OpenReadOnlySaveDataFileSystem"}, + {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"}, {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, {58, nullptr, "ReadSaveDataFileSystemExtraData"}, {59, nullptr, "WriteSaveDataFileSystemExtraData"}, @@ -516,6 +527,16 @@ void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } +void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto type = rp.PopRaw<FileSystemType>(); + const auto title_id = rp.PopRaw<u64>(); + + IPC::ResponseBuilder rb{ctx, 2, 0, 0}; + rb.Push(ResultCode(-1)); +} + void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called"); @@ -563,6 +584,11 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { rb.PushIpcInterface<IFileSystem>(std::move(filesystem)); } +void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); + MountSaveData(ctx); +} + void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_FS, "(STUBBED) called"); diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index f073ac523..2b5c21abb 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h @@ -20,9 +20,11 @@ public: private: void Initialize(Kernel::HLERequestContext& ctx); + void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx); void MountSdCard(Kernel::HLERequestContext& ctx); void CreateSaveData(Kernel::HLERequestContext& ctx); void MountSaveData(Kernel::HLERequestContext& ctx); + void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx); void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 8fb907072..9d804652e 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -12,6 +12,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/thread.h" @@ -114,7 +115,7 @@ void ServiceFrameworkBase::InstallAsNamedPort() { std::tie(server_port, client_port) = ServerPort::CreatePortPair(kernel, max_sessions, service_name); server_port->SetHleHandler(shared_from_this()); - AddNamedPort(service_name, std::move(client_port)); + kernel.AddNamedPort(service_name, std::move(client_port)); } Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() { @@ -197,11 +198,6 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co //////////////////////////////////////////////////////////////////////////////////////////////////// // Module interface -// TODO(yuriks): Move to kernel -void AddNamedPort(std::string name, SharedPtr<ClientPort> port) { - g_kernel_named_ports.emplace(std::move(name), std::move(port)); -} - /// Initialize ServiceManager void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesystem& rfs) { // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it @@ -264,7 +260,6 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesys /// Shutdown ServiceManager void Shutdown() { - g_kernel_named_ports.clear(); LOG_DEBUG(Service, "shutdown OK"); } } // namespace Service diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index cd9c74f3d..7a051523e 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -6,7 +6,6 @@ #include <cstddef> #include <string> -#include <unordered_map> #include <boost/container/flat_map.hpp> #include "common/common_types.h" #include "core/hle/kernel/hle_ipc.h" @@ -187,10 +186,4 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, /// Shutdown ServiceManager void Shutdown(); -/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC. -extern std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> g_kernel_named_ports; - -/// Adds a port to the named port table -void AddNamedPort(std::string name, Kernel::SharedPtr<Kernel::ClientPort> port); - } // namespace Service diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index c13fb49b8..5980cdb25 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -5,9 +5,9 @@ #include <memory> #include <ostream> #include <string> +#include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" -#include "core/file_sys/vfs_real.h" #include "core/hle/kernel/process.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/elf.h" @@ -144,6 +144,9 @@ std::ostream& operator<<(std::ostream& os, ResultStatus status) { return os; } +AppLoader::AppLoader(FileSys::VirtualFile file) : file(std::move(file)) {} +AppLoader::~AppLoader() = default; + /** * Get a loader for a file with a specific type * @param file The file to load diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 885fee84c..5a8540b0e 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -4,7 +4,6 @@ #pragma once -#include <algorithm> #include <iosfwd> #include <memory> #include <string> @@ -12,7 +11,6 @@ #include <vector> #include <boost/optional.hpp> #include "common/common_types.h" -#include "common/file_util.h" #include "core/file_sys/vfs.h" #include "core/hle/kernel/object.h" @@ -114,8 +112,8 @@ std::ostream& operator<<(std::ostream& os, ResultStatus status); /// Interface for loading an application class AppLoader : NonCopyable { public: - explicit AppLoader(FileSys::VirtualFile file) : file(std::move(file)) {} - virtual ~AppLoader() {} + explicit AppLoader(FileSys::VirtualFile file); + virtual ~AppLoader(); /** * Returns the type of this file diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 68ff1e86b..e63ad4d46 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -5,6 +5,7 @@ #include <cinttypes> #include "common/assert.h" #include "core/core.h" +#include "core/core_timing.h" #include "core/memory.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/engines/maxwell_3d.h" @@ -194,8 +195,8 @@ void Maxwell3D::ProcessQueryGet() { // wait queues. LongQueryResult query_result{}; query_result.value = result; - // TODO(Subv): Generate a real GPU timestamp and write it here instead of 0 - query_result.timestamp = 0; + // TODO(Subv): Generate a real GPU timestamp and write it here instead of CoreTiming + query_result.timestamp = CoreTiming::GetTicks(); Memory::WriteBlock(*address, &query_result, sizeof(query_result)); } break; diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 3e4efbe0c..a7daea766 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -243,7 +243,8 @@ enum class TextureType : u64 { TextureCube = 3, }; -enum class IpaMode : u64 { Pass = 0, None = 1, Constant = 2, Sc = 3 }; +enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; +enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; union Instruction { Instruction& operator=(const Instruction& instr) { @@ -328,10 +329,16 @@ union Instruction { } alu; union { - BitField<54, 3, IpaMode> mode; + BitField<51, 1, u64> saturate; + BitField<52, 2, IpaSampleMode> sample_mode; + BitField<54, 2, IpaInterpMode> interp_mode; } ipa; union { + BitField<39, 2, u64> tab5cb8_2; + BitField<41, 3, u64> tab5c68_1; + BitField<44, 2, u64> tab5c68_0; + BitField<47, 1, u64> cc; BitField<48, 1, u64> negate_b; } fmul; @@ -399,8 +406,11 @@ union Instruction { } flow; union { + BitField<47, 1, u64> cc; BitField<48, 1, u64> negate_b; BitField<49, 1, u64> negate_c; + BitField<51, 2, u64> tab5980_1; + BitField<53, 2, u64> tab5980_0; } ffma; union { @@ -509,6 +519,7 @@ union Instruction { union { BitField<0, 8, Register> gpr0; BitField<28, 8, Register> gpr28; + BitField<49, 1, u64> nodep; BitField<50, 3, u64> component_mask_selector; BitField<53, 4, u64> texture_info; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 391c92d47..c4e7e1e3b 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -887,6 +887,8 @@ private: // TEXS has two destination registers and a swizzle. The first two elements in the swizzle // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 + ASSERT_MSG(instr.texs.nodep == 0, "TEXS nodep not implemented"); + size_t written_components = 0; for (u32 component = 0; component < 4; ++component) { if (!instr.texs.IsComponentEnabled(component)) { @@ -1038,6 +1040,15 @@ private: case OpCode::Id::FMUL_R: case OpCode::Id::FMUL_IMM: { // FMUL does not have 'abs' bits and only the second operand has a 'neg' bit. + ASSERT_MSG(instr.fmul.tab5cb8_2 == 0, "FMUL tab5cb8_2({}) is not implemented", + instr.fmul.tab5cb8_2.Value()); + ASSERT_MSG(instr.fmul.tab5c68_1 == 0, "FMUL tab5cb8_1({}) is not implemented", + instr.fmul.tab5c68_1.Value()); + ASSERT_MSG(instr.fmul.tab5c68_0 == 1, "FMUL tab5cb8_0({}) is not implemented", + instr.fmul.tab5c68_0 + .Value()); // SMO typical sends 1 here which seems to be the default + ASSERT_MSG(instr.fmul.cc == 0, "FMUL cc is not implemented"); + op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b); regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " * " + op_b, 1, 1, instr.alu.saturate_d); @@ -1436,6 +1447,12 @@ private: std::string op_b = instr.ffma.negate_b ? "-" : ""; std::string op_c = instr.ffma.negate_c ? "-" : ""; + ASSERT_MSG(instr.ffma.cc == 0, "FFMA cc not implemented"); + ASSERT_MSG(instr.ffma.tab5980_0 == 1, "FFMA tab5980_0({}) not implemented", + instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO + ASSERT_MSG(instr.ffma.tab5980_1 == 0, "FFMA tab5980_1({}) not implemented", + instr.ffma.tab5980_1.Value()); + switch (opcode->GetId()) { case OpCode::Id::FFMA_CR: { op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, @@ -2110,8 +2127,12 @@ private: case OpCode::Id::IPA: { const auto& attribute = instr.attribute.fmt28; const auto& reg = instr.gpr0; - switch (instr.ipa.mode) { - case Tegra::Shader::IpaMode::Pass: + ASSERT_MSG(instr.ipa.sample_mode == Tegra::Shader::IpaSampleMode::Default, + "Unhandled IPA sample mode: {}", + static_cast<u32>(instr.ipa.sample_mode.Value())); + ASSERT_MSG(instr.ipa.saturate == 0, "IPA saturate not implemented"); + switch (instr.ipa.interp_mode) { + case Tegra::Shader::IpaInterpMode::Linear: if (stage == Maxwell3D::Regs::ShaderStage::Fragment && attribute.index == Attribute::Index::Position) { switch (attribute.element) { @@ -2132,12 +2153,12 @@ private: regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); } break; - case Tegra::Shader::IpaMode::None: + case Tegra::Shader::IpaInterpMode::Perspective: regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); break; default: LOG_CRITICAL(HW_GPU, "Unhandled IPA mode: {}", - static_cast<u32>(instr.ipa.mode.Value())); + static_cast<u32>(instr.ipa.interp_mode.Value())); UNREACHABLE(); regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); } diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index d15242d59..a3f4d9421 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -16,8 +16,9 @@ #include <boost/container/flat_map.hpp> #include <fmt/format.h> #include "common/common_paths.h" +#include "common/common_types.h" +#include "common/file_util.h" #include "common/logging/log.h" -#include "common/string_util.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/control_metadata.h" #include "core/file_sys/registered_cache.h" diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 6a5c2f5f8..84731464a 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -20,6 +20,8 @@ #include <QVBoxLayout> #include <QWidget> +#include "common/common_types.h" + class GameListWorker; class GMainWindow; diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index 3624cb21a..4ddd8cd88 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -4,18 +4,23 @@ #pragma once +#include <algorithm> #include <array> #include <atomic> #include <map> #include <memory> +#include <string> #include <unordered_map> #include <utility> + #include <QCoreApplication> #include <QImage> #include <QObject> #include <QRunnable> #include <QStandardItem> #include <QString> + +#include "common/common_types.h" #include "common/logging/log.h" #include "common/string_util.h" #include "yuzu/ui_settings.h" diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e11ba7854..fd73b8541 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -18,6 +18,7 @@ #include <QtWidgets> #include <fmt/format.h> #include "common/common_paths.h" +#include "common/file_util.h" #include "common/logging/backend.h" #include "common/logging/filter.h" #include "common/logging/log.h" @@ -419,7 +420,7 @@ void GMainWindow::OnDisplayTitleBars(bool show) { } } -bool GMainWindow::SupportsRequiredGLExtensions() { +QStringList GMainWindow::GetUnsupportedGLExtensions() { QStringList unsupported_ext; if (!GLAD_GL_ARB_program_interface_query) @@ -446,7 +447,7 @@ bool GMainWindow::SupportsRequiredGLExtensions() { for (const QString& ext : unsupported_ext) LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext.toStdString()); - return unsupported_ext.empty(); + return unsupported_ext; } bool GMainWindow::LoadROM(const QString& filename) { @@ -464,11 +465,13 @@ bool GMainWindow::LoadROM(const QString& filename) { return false; } - if (!SupportsRequiredGLExtensions()) { - QMessageBox::critical( - this, tr("Error while initializing OpenGL Core!"), - tr("Your GPU may not support one or more required OpenGL extensions. Please " - "ensure you have the latest graphics driver. See the log for more details.")); + QStringList unsupported_gl_extensions = GetUnsupportedGLExtensions(); + if (!unsupported_gl_extensions.empty()) { + QMessageBox::critical(this, tr("Error while initializing OpenGL Core!"), + tr("Your GPU may not support one or more required OpenGL" + "extensions. Please ensure you have the latest graphics " + "driver.<br><br>Unsupported extensions:<br>") + + unsupported_gl_extensions.join("<br>")); return false; } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 0b97e8220..29bc6e004 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -6,8 +6,11 @@ #include <memory> #include <unordered_map> + #include <QMainWindow> #include <QTimer> + +#include "common/common_types.h" #include "core/core.h" #include "ui_main.h" #include "yuzu/hotkeys.h" @@ -85,7 +88,7 @@ private: void ConnectWidgetEvents(); void ConnectMenuEvents(); - bool SupportsRequiredGLExtensions(); + QStringList GetUnsupportedGLExtensions(); bool LoadROM(const QString& filename); void BootGame(const QString& filename); void ShutdownGame(); diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 41e7da897..173ac0e0f 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -10,6 +10,7 @@ #include <fmt/ostream.h> #include "common/common_paths.h" +#include "common/file_util.h" #include "common/logging/backend.h" #include "common/logging/filter.h" #include "common/logging/log.h" |