diff options
Diffstat (limited to 'src')
25 files changed, 202 insertions, 194 deletions
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index c8fa912bf..e065e592f 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp @@ -8,13 +8,23 @@ namespace FileSys { -const std::array<const char*, 15> LANGUAGE_NAMES = { - "AmericanEnglish", "BritishEnglish", "Japanese", - "French", "German", "LatinAmericanSpanish", - "Spanish", "Italian", "Dutch", - "CanadianFrench", "Portugese", "Russian", - "Korean", "Taiwanese", "Chinese", -}; +const std::array<const char*, 15> LANGUAGE_NAMES{{ + "AmericanEnglish", + "BritishEnglish", + "Japanese", + "French", + "German", + "LatinAmericanSpanish", + "Spanish", + "Italian", + "Dutch", + "CanadianFrench", + "Portuguese", + "Russian", + "Korean", + "Taiwanese", + "Chinese", +}}; std::string LanguageEntry::GetApplicationName() const { return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(), diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index a3f8f2f73..07c3af64a 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -381,22 +381,22 @@ std::vector<RegisteredCacheEntry> RegisteredCache::ListEntriesFilter( return out; } -static std::shared_ptr<NCA> GetNCAFromNSPForID(std::shared_ptr<NSP> nsp, const NcaID& id) { - const auto file = nsp->GetFile(fmt::format("{}.nca", Common::HexArrayToString(id, false))); +static std::shared_ptr<NCA> GetNCAFromNSPForID(const NSP& nsp, const NcaID& id) { + const auto file = nsp.GetFile(fmt::format("{}.nca", Common::HexArrayToString(id, false))); if (file == nullptr) return nullptr; return std::make_shared<NCA>(file); } -InstallResult RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci, bool overwrite_if_exists, +InstallResult RegisteredCache::InstallEntry(const XCI& xci, bool overwrite_if_exists, const VfsCopyFunction& copy) { - return InstallEntry(xci->GetSecurePartitionNSP(), overwrite_if_exists, copy); + return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy); } -InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NSP> nsp, bool overwrite_if_exists, +InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists, const VfsCopyFunction& copy) { - const auto& ncas = nsp->GetNCAsCollapsed(); - const auto& meta_iter = std::find_if(ncas.begin(), ncas.end(), [](std::shared_ptr<NCA> nca) { + const auto ncas = nsp.GetNCAsCollapsed(); + const auto meta_iter = std::find_if(ncas.begin(), ncas.end(), [](const auto& nca) { return nca->GetType() == NCAContentType::Meta; }); @@ -410,7 +410,7 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NSP> nsp, bool overw const auto meta_id_raw = (*meta_iter)->GetName().substr(0, 32); const auto meta_id = Common::HexStringToArray<16>(meta_id_raw); - const auto res = RawInstallNCA(*meta_iter, copy, overwrite_if_exists, meta_id); + const auto res = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id); if (res != InstallResult::Success) return res; @@ -422,7 +422,7 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NSP> nsp, bool overw const auto nca = GetNCAFromNSPForID(nsp, record.nca_id); if (nca == nullptr) return InstallResult::ErrorCopyFailed; - const auto res2 = RawInstallNCA(nca, copy, overwrite_if_exists, record.nca_id); + const auto res2 = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id); if (res2 != InstallResult::Success) return res2; } @@ -431,21 +431,21 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NSP> nsp, bool overw return InstallResult::Success; } -InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NCA> nca, TitleType type, +InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type, bool overwrite_if_exists, const VfsCopyFunction& copy) { CNMTHeader header{ - nca->GetTitleId(), ///< Title ID - 0, ///< Ignore/Default title version - type, ///< Type - {}, ///< Padding - 0x10, ///< Default table offset - 1, ///< 1 Content Entry - 0, ///< No Meta Entries - {}, ///< Padding + nca.GetTitleId(), ///< Title ID + 0, ///< Ignore/Default title version + type, ///< Type + {}, ///< Padding + 0x10, ///< Default table offset + 1, ///< 1 Content Entry + 0, ///< No Meta Entries + {}, ///< Padding }; OptionalHeader opt_header{0, 0}; - ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca->GetType()), {}}; - const auto& data = nca->GetBaseFile()->ReadBytes(0x100000); + ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca.GetType()), {}}; + const auto& data = nca.GetBaseFile()->ReadBytes(0x100000); mbedtls_sha256(data.data(), data.size(), c_rec.hash.data(), 0); memcpy(&c_rec.nca_id, &c_rec.hash, 16); const CNMT new_cnmt(header, opt_header, {c_rec}, {}); @@ -454,10 +454,10 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NCA> nca, TitleType return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id); } -InstallResult RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy, +InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy, bool overwrite_if_exists, std::optional<NcaID> override_id) { - const auto in = nca->GetBaseFile(); + const auto in = nca.GetBaseFile(); Core::Crypto::SHA256Hash hash{}; // Calculate NcaID diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h index 6b89db8de..3b77af4e0 100644 --- a/src/core/file_sys/registered_cache.h +++ b/src/core/file_sys/registered_cache.h @@ -6,7 +6,6 @@ #include <array> #include <functional> -#include <map> #include <memory> #include <string> #include <vector> @@ -104,17 +103,16 @@ public: // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure // there is a meta NCA and all of them are accessible. - InstallResult InstallEntry(std::shared_ptr<XCI> xci, bool overwrite_if_exists = false, + InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false, const VfsCopyFunction& copy = &VfsRawCopy); - InstallResult InstallEntry(std::shared_ptr<NSP> nsp, bool overwrite_if_exists = false, + InstallResult InstallEntry(const NSP& nsp, bool overwrite_if_exists = false, const VfsCopyFunction& copy = &VfsRawCopy); // Due to the fact that we must use Meta-type NCAs to determine the existance of files, this // poses quite a challenge. Instead of creating a new meta NCA for this file, yuzu will create a // dir inside the NAND called 'yuzu_meta' and store the raw CNMT there. // TODO(DarkLordZach): Author real meta-type NCAs and install those. - InstallResult InstallEntry(std::shared_ptr<NCA> nca, TitleType type, - bool overwrite_if_exists = false, + InstallResult InstallEntry(const NCA& nca, TitleType type, bool overwrite_if_exists = false, const VfsCopyFunction& copy = &VfsRawCopy); private: @@ -128,7 +126,7 @@ private: std::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const; VirtualFile GetFileAtID(NcaID id) const; VirtualFile OpenFileOrDirectoryConcat(const VirtualDir& dir, std::string_view path) const; - InstallResult RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy, + InstallResult RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy, bool overwrite_if_exists, std::optional<NcaID> override_id = {}); bool RawInstallYuzuMeta(const CNMT& cnmt); diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 687dea409..e6b5171ee 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -282,7 +282,7 @@ static void FpuWrite(std::size_t id, u128 val, Kernel::Thread* thread = nullptr) if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) { thread_context.vector_registers[id - UC_ARM64_REG_Q0] = val; } else if (id == FPCR_REGISTER) { - thread_context.fpcr = val[0]; + thread_context.fpcr = static_cast<u32>(val[0]); } } diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index c629f9357..9521431bb 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -21,17 +21,6 @@ namespace Service::Account { -// TODO: RE this structure -struct UserData { - INSERT_PADDING_WORDS(1); - u32 icon_id; - u8 bg_color_id; - INSERT_PADDING_BYTES(0x7); - INSERT_PADDING_BYTES(0x10); - INSERT_PADDING_BYTES(0x60); -}; -static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); - // Smallest JPEG https://github.com/mathiasbynens/small/blob/master/jpeg.jpg // used as a backup should the one on disk not exist constexpr u32 backup_jpeg_size = 107; @@ -72,9 +61,11 @@ private: void Get(Kernel::HLERequestContext& ctx) { LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); ProfileBase profile_base{}; - std::array<u8, MAX_DATA> data{}; + ProfileData data{}; if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { - ctx.WriteBuffer(data); + std::array<u8, sizeof(ProfileData)> raw_data; + std::memcpy(raw_data.data(), &data, sizeof(ProfileData)); + ctx.WriteBuffer(raw_data); IPC::ResponseBuilder rb{ctx, 16}; rb.Push(RESULT_SUCCESS); rb.PushRaw(profile_base); diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 968263846..1316d0b07 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -18,7 +18,7 @@ struct UserRaw { UUID uuid2; u64 timestamp; ProfileUsername username; - INSERT_PADDING_BYTES(0x80); + ProfileData extra_data; }; static_assert(sizeof(UserRaw) == 0xC8, "UserRaw has incorrect size."); @@ -346,7 +346,7 @@ void ProfileManager::ParseUserSaveFile() { continue; } - AddUser({user.uuid, user.username, user.timestamp, {}, false}); + AddUser({user.uuid, user.username, user.timestamp, user.extra_data, false}); } std::stable_partition(profiles.begin(), profiles.end(), @@ -361,6 +361,7 @@ void ProfileManager::WriteUserSaveFile() { raw.users[i].uuid2 = profiles[i].user_uuid; raw.users[i].uuid = profiles[i].user_uuid; raw.users[i].timestamp = profiles[i].creation_time; + raw.users[i].extra_data = profiles[i].data; } const auto raw_path = diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index d2d8e6c6b..c4ce2e0b3 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -13,7 +13,6 @@ namespace Service::Account { constexpr std::size_t MAX_USERS = 8; -constexpr std::size_t MAX_DATA = 128; constexpr u128 INVALID_UUID{{0, 0}}; struct UUID { @@ -50,9 +49,20 @@ static_assert(sizeof(UUID) == 16, "UUID is an invalid size!"); constexpr std::size_t profile_username_size = 32; using ProfileUsername = std::array<u8, profile_username_size>; -using ProfileData = std::array<u8, MAX_DATA>; using UserIDArray = std::array<UUID, MAX_USERS>; +/// Contains extra data related to a user. +/// TODO: RE this structure +struct ProfileData { + INSERT_PADDING_WORDS(1); + u32 icon_id; + u8 bg_color_id; + INSERT_PADDING_BYTES(0x7); + INSERT_PADDING_BYTES(0x10); + INSERT_PADDING_BYTES(0x60); +}; +static_assert(sizeof(ProfileData) == 0x80, "ProfileData structure has incorrect size"); + /// This holds general information about a users profile. This is where we store all the information /// based on a specific user struct ProfileInfo { diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index ea8057b80..abff6544d 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -80,9 +80,9 @@ public: struct LedPattern { explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) { position1.Assign(light1); - position1.Assign(light2); - position1.Assign(light3); - position1.Assign(light4); + position2.Assign(light2); + position3.Assign(light3); + position4.Assign(light4); } union { u64 raw{}; diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index dbea5bb5e..80f70e332 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp @@ -73,13 +73,13 @@ void Fermi2D::HandleSurfaceCopy() { Texture::CopySwizzledData(regs.src.width, regs.src.height, regs.src.depth, src_bytes_per_pixel, dst_bytes_per_pixel, src_buffer, dst_buffer, true, regs.src.BlockHeight(), - regs.src.BlockDepth()); + regs.src.BlockDepth(), 0); } else { // If the input is linear and the output is tiled, swizzle the input and copy it over. Texture::CopySwizzledData(regs.src.width, regs.src.height, regs.src.depth, src_bytes_per_pixel, dst_bytes_per_pixel, dst_buffer, src_buffer, false, regs.dst.BlockHeight(), - regs.dst.BlockDepth()); + regs.dst.BlockDepth(), 0); } } } diff --git a/src/video_core/morton.cpp b/src/video_core/morton.cpp index f14abba7d..a310491a8 100644 --- a/src/video_core/morton.cpp +++ b/src/video_core/morton.cpp @@ -16,12 +16,12 @@ namespace VideoCore { using Surface::GetBytesPerPixel; using Surface::PixelFormat; -using MortonCopyFn = void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr); +using MortonCopyFn = void (*)(u32, u32, u32, u32, u32, u32, u8*, std::size_t, VAddr); using ConversionArray = std::array<MortonCopyFn, Surface::MaxPixelFormat>; template <bool morton_to_linear, PixelFormat format> static void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 depth, - u8* buffer, std::size_t buffer_size, VAddr addr) { + u32 tile_width_spacing, u8* buffer, std::size_t buffer_size, VAddr addr) { constexpr u32 bytes_per_pixel = GetBytesPerPixel(format); // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual @@ -31,12 +31,13 @@ static void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth if constexpr (morton_to_linear) { Tegra::Texture::UnswizzleTexture(buffer, addr, tile_size_x, tile_size_y, bytes_per_pixel, - stride, height, depth, block_height, block_depth); + stride, height, depth, block_height, block_depth, + tile_width_spacing); } else { - Tegra::Texture::CopySwizzledData((stride + tile_size_x - 1) / tile_size_x, - (height + tile_size_y - 1) / tile_size_y, depth, - bytes_per_pixel, bytes_per_pixel, Memory::GetPointer(addr), - buffer, false, block_height, block_depth); + Tegra::Texture::CopySwizzledData( + (stride + tile_size_x - 1) / tile_size_x, (height + tile_size_y - 1) / tile_size_y, + depth, bytes_per_pixel, bytes_per_pixel, Memory::GetPointer(addr), buffer, false, + block_height, block_depth, tile_width_spacing); } } @@ -183,13 +184,14 @@ static constexpr ConversionArray linear_to_morton_fns = { // clang-format on }; -constexpr MortonCopyFn GetSwizzleFunction(MortonSwizzleMode mode, Surface::PixelFormat format) { +static MortonCopyFn GetSwizzleFunction(MortonSwizzleMode mode, Surface::PixelFormat format) { switch (mode) { case MortonSwizzleMode::MortonToLinear: return morton_to_linear_fns[static_cast<std::size_t>(format)]; case MortonSwizzleMode::LinearToMorton: return linear_to_morton_fns[static_cast<std::size_t>(format)]; } + UNREACHABLE(); } /// 8x8 Z-Order coordinate from 2D coordinates @@ -325,11 +327,11 @@ static u32 GetMortonOffset128(u32 x, u32 y, u32 bytes_per_pixel) { } void MortonSwizzle(MortonSwizzleMode mode, Surface::PixelFormat format, u32 stride, - u32 block_height, u32 height, u32 block_depth, u32 depth, u8* buffer, - std::size_t buffer_size, VAddr addr) { + u32 block_height, u32 height, u32 block_depth, u32 depth, u32 tile_width_spacing, + u8* buffer, std::size_t buffer_size, VAddr addr) { - GetSwizzleFunction(mode, format)(stride, block_height, height, block_depth, depth, buffer, - buffer_size, addr); + GetSwizzleFunction(mode, format)(stride, block_height, height, block_depth, depth, + tile_width_spacing, buffer, buffer_size, addr); } void MortonCopyPixels128(u32 width, u32 height, u32 bytes_per_pixel, u32 linear_bytes_per_pixel, @@ -350,4 +352,4 @@ void MortonCopyPixels128(u32 width, u32 height, u32 bytes_per_pixel, u32 linear_ } } -} // namespace VideoCore
\ No newline at end of file +} // namespace VideoCore diff --git a/src/video_core/morton.h b/src/video_core/morton.h index b9b9eca86..065f59ce3 100644 --- a/src/video_core/morton.h +++ b/src/video_core/morton.h @@ -12,10 +12,10 @@ namespace VideoCore { enum class MortonSwizzleMode { MortonToLinear, LinearToMorton }; void MortonSwizzle(MortonSwizzleMode mode, VideoCore::Surface::PixelFormat format, u32 stride, - u32 block_height, u32 height, u32 block_depth, u32 depth, u8* buffer, - std::size_t buffer_size, VAddr addr); + u32 block_height, u32 height, u32 block_depth, u32 depth, u32 tile_width_spacing, + u8* buffer, std::size_t buffer_size, VAddr addr); void MortonCopyPixels128(u32 width, u32 height, u32 bytes_per_pixel, u32 linear_bytes_per_pixel, u8* morton_data, u8* linear_data, bool morton_to_linear); -} // namespace VideoCore
\ No newline at end of file +} // namespace VideoCore diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 98fb5a9aa..82b7a0649 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -668,7 +668,7 @@ void RasterizerOpenGL::DrawArrays() { bool invalidate = buffer_cache.Map(buffer_size); if (invalidate) { // As all cached buffers are invalidated, we need to recheck their state. - gpu.dirty_flags.vertex_attrib_format = 0xFFFFFFFF; + gpu.dirty_flags.vertex_array = 0xFFFFFFFF; } SetupVertexFormat(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index d458f77e4..dde2f468d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -97,6 +97,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only, params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0, params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0, params.block_depth = params.is_tiled ? config.tic.BlockDepth() : 0, + params.tile_width_spacing = params.is_tiled ? (1 << config.tic.tile_width_spacing.Value()) : 1; params.srgb_conversion = config.tic.IsSrgbConversionEnabled(); params.pixel_format = PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value(), params.srgb_conversion); @@ -162,6 +163,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only, params.block_width = 1 << config.memory_layout.block_width; params.block_height = 1 << config.memory_layout.block_height; params.block_depth = 1 << config.memory_layout.block_depth; + params.tile_width_spacing = 1; params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; @@ -197,6 +199,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only, params.block_width = 1 << std::min(block_width, 5U); params.block_height = 1 << std::min(block_height, 5U); params.block_depth = 1 << 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); @@ -223,6 +226,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only, params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0, params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0, params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 32U) : 0, + params.tile_width_spacing = 1; params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; @@ -387,8 +391,8 @@ void SwizzleFunc(const MortonSwizzleMode& mode, const SurfaceParams& params, for (u32 i = 0; i < params.depth; i++) { MortonSwizzle(mode, params.pixel_format, params.MipWidth(mip_level), params.MipBlockHeight(mip_level), params.MipHeight(mip_level), - params.MipBlockDepth(mip_level), 1, gl_buffer.data() + offset_gl, gl_size, - params.addr + offset); + params.MipBlockDepth(mip_level), params.tile_width_spacing, 1, + gl_buffer.data() + offset_gl, gl_size, params.addr + offset); offset += layer_size; offset_gl += gl_size; } @@ -396,8 +400,8 @@ void SwizzleFunc(const MortonSwizzleMode& mode, const SurfaceParams& params, const u64 offset = params.GetMipmapLevelOffset(mip_level); MortonSwizzle(mode, params.pixel_format, params.MipWidth(mip_level), params.MipBlockHeight(mip_level), params.MipHeight(mip_level), - params.MipBlockDepth(mip_level), depth, gl_buffer.data(), gl_buffer.size(), - params.addr + offset); + params.MipBlockDepth(mip_level), depth, params.tile_width_spacing, + gl_buffer.data(), gl_buffer.size(), params.addr + offset); } } diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 9ac79c5a4..c710aa245 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -196,9 +196,15 @@ struct SurfaceParams { /// Checks if surfaces are compatible for caching bool IsCompatibleSurface(const SurfaceParams& other) const { - return std::tie(pixel_format, type, width, height, target, depth) == - std::tie(other.pixel_format, other.type, other.width, other.height, other.target, - other.depth); + if (std::tie(pixel_format, type, width, height, target, depth, is_tiled) == + std::tie(other.pixel_format, other.type, other.width, other.height, other.target, + other.depth, other.is_tiled)) { + if (!is_tiled) + return true; + return std::tie(block_height, block_depth, tile_width_spacing) == + std::tie(other.block_height, other.block_depth, other.tile_width_spacing); + } + return false; } /// Initializes parameters for caching, should be called after everything has been initialized @@ -208,6 +214,7 @@ struct SurfaceParams { u32 block_width; u32 block_height; u32 block_depth; + u32 tile_width_spacing; PixelFormat pixel_format; ComponentType component_type; SurfaceType type; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 7c0935a4e..0c4524d5c 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -520,7 +520,7 @@ public: switch (attribute) { case Attribute::Index::ClipDistances0123: case Attribute::Index::ClipDistances4567: { - const u64 index = attribute == Attribute::Index::ClipDistances4567 ? 4 : 0 + elem; + const u64 index = (attribute == Attribute::Index::ClipDistances4567 ? 4 : 0) + elem; UNIMPLEMENTED_IF_MSG( ((header.vtg.clip_distances >> index) & 1) == 0, "Shader is setting gl_ClipDistance{} without enabling it in the header", index); diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 7eabd34f1..bbae9285f 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -127,7 +127,8 @@ void FastProcessBlock(u8* const swizzled_data, u8* const unswizzled_data, const template <bool fast> void SwizzledData(u8* const swizzled_data, u8* const unswizzled_data, const bool unswizzle, const u32 width, const u32 height, const u32 depth, const u32 bytes_per_pixel, - const u32 out_bytes_per_pixel, const u32 block_height, const u32 block_depth) { + const u32 out_bytes_per_pixel, const u32 block_height, const u32 block_depth, + const u32 width_spacing) { auto div_ceil = [](const u32 x, const u32 y) { return ((x + y - 1) / y); }; const u32 stride_x = width * out_bytes_per_pixel; const u32 layer_z = height * stride_x; @@ -137,7 +138,8 @@ void SwizzledData(u8* const swizzled_data, u8* const unswizzled_data, const bool const u32 block_x_elements = gob_elements_x; const u32 block_y_elements = gob_elements_y * block_height; const u32 block_z_elements = gob_elements_z * block_depth; - const u32 blocks_on_x = div_ceil(width, block_x_elements); + const u32 aligned_width = Common::AlignUp(width, gob_elements_x * width_spacing); + const u32 blocks_on_x = div_ceil(aligned_width, block_x_elements); const u32 blocks_on_y = div_ceil(height, block_y_elements); const u32 blocks_on_z = div_ceil(depth, block_z_elements); const u32 xy_block_size = gob_size * block_height; @@ -169,13 +171,15 @@ void SwizzledData(u8* const swizzled_data, u8* const unswizzled_data, const bool void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, u32 out_bytes_per_pixel, u8* const swizzled_data, u8* const unswizzled_data, - bool unswizzle, u32 block_height, u32 block_depth) { + bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing) { if (bytes_per_pixel % 3 != 0 && (width * bytes_per_pixel) % fast_swizzle_align == 0) { SwizzledData<true>(swizzled_data, unswizzled_data, unswizzle, width, height, depth, - bytes_per_pixel, out_bytes_per_pixel, block_height, block_depth); + bytes_per_pixel, out_bytes_per_pixel, block_height, block_depth, + width_spacing); } else { SwizzledData<false>(swizzled_data, unswizzled_data, unswizzle, width, height, depth, - bytes_per_pixel, out_bytes_per_pixel, block_height, block_depth); + bytes_per_pixel, out_bytes_per_pixel, block_height, block_depth, + width_spacing); } } @@ -228,19 +232,19 @@ u32 BytesPerPixel(TextureFormat format) { void UnswizzleTexture(u8* const unswizzled_data, VAddr address, u32 tile_size_x, u32 tile_size_y, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height, - u32 block_depth) { + u32 block_depth, u32 width_spacing) { CopySwizzledData((width + tile_size_x - 1) / tile_size_x, (height + tile_size_y - 1) / tile_size_y, depth, bytes_per_pixel, bytes_per_pixel, Memory::GetPointer(address), unswizzled_data, true, - block_height, block_depth); + block_height, block_depth, width_spacing); } std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size_x, u32 tile_size_y, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, - u32 block_height, u32 block_depth) { + u32 block_height, u32 block_depth, u32 width_spacing) { std::vector<u8> unswizzled_data(width * height * depth * bytes_per_pixel); UnswizzleTexture(unswizzled_data.data(), address, tile_size_x, tile_size_y, bytes_per_pixel, - width, height, depth, block_height, block_depth); + width, height, depth, block_height, block_depth, width_spacing); return unswizzled_data; } diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index f4ef7c73e..85b7e9f7b 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -22,19 +22,20 @@ inline std::size_t GetGOBSize() { void UnswizzleTexture(u8* unswizzled_data, VAddr address, u32 tile_size_x, u32 tile_size_y, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height = TICEntry::DefaultBlockHeight, - u32 block_depth = TICEntry::DefaultBlockHeight); + u32 block_depth = TICEntry::DefaultBlockHeight, u32 width_spacing = 0); /** * Unswizzles a swizzled texture without changing its format. */ std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size_x, u32 tile_size_y, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height = TICEntry::DefaultBlockHeight, - u32 block_depth = TICEntry::DefaultBlockHeight); + u32 block_depth = TICEntry::DefaultBlockHeight, + u32 width_spacing = 0); /// Copies texture data from a buffer and performs swizzling/unswizzling as necessary. void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, u32 out_bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, - bool unswizzle, u32 block_height, u32 block_depth); + bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing); /** * Decodes an unswizzled texture into a A8R8G8B8 texture. diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index ffa08f5c1..e7c78bee2 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -166,6 +166,8 @@ struct TICEntry { BitField<3, 3, u32> block_height; BitField<6, 3, u32> block_depth; + BitField<10, 3, u32> tile_width_spacing; + // High 16 bits of the pitch value BitField<0, 16, u32> pitch_high; BitField<26, 1, u32> use_header_opt_control; diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 7ee572761..ec46dc4e3 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -4,11 +4,9 @@ #include <algorithm> #include <memory> -#include <utility> -#include <QMenu> -#include <QMessageBox> + #include <QTimer> -#include "common/param_package.h" + #include "configuration/configure_touchscreen_advanced.h" #include "core/core.h" #include "core/hle/service/am/am.h" @@ -16,16 +14,25 @@ #include "core/hle/service/am/applet_oe.h" #include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/sm/sm.h" -#include "input_common/main.h" #include "ui_configure_input.h" #include "ui_configure_input_player.h" -#include "ui_configure_mouse_advanced.h" -#include "ui_configure_touchscreen_advanced.h" -#include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_input.h" #include "yuzu/configuration/configure_input_player.h" #include "yuzu/configuration/configure_mouse_advanced.h" +namespace { +template <typename Dialog, typename... Args> +void CallConfigureDialog(ConfigureInput& parent, Args&&... args) { + parent.applyConfiguration(); + Dialog dialog(&parent, std::forward<Args>(args)...); + + const auto res = dialog.exec(); + if (res == QDialog::Accepted) { + dialog.applyConfiguration(); + } +} +} // Anonymous namespace + ConfigureInput::ConfigureInput(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) { ui->setupUi(this); @@ -65,31 +72,20 @@ ConfigureInput::ConfigureInput(QWidget* parent) for (std::size_t i = 0; i < players_configure.size(); ++i) { connect(players_configure[i], &QPushButton::pressed, this, - [this, i]() { CallConfigureDialog<ConfigureInputPlayer>(i, false); }); + [this, i] { CallConfigureDialog<ConfigureInputPlayer>(*this, i, false); }); } connect(ui->handheld_configure, &QPushButton::pressed, this, - [this]() { CallConfigureDialog<ConfigureInputPlayer>(8, false); }); + [this] { CallConfigureDialog<ConfigureInputPlayer>(*this, 8, false); }); connect(ui->debug_configure, &QPushButton::pressed, this, - [this]() { CallConfigureDialog<ConfigureInputPlayer>(9, true); }); + [this] { CallConfigureDialog<ConfigureInputPlayer>(*this, 9, true); }); connect(ui->mouse_advanced, &QPushButton::pressed, this, - [this]() { CallConfigureDialog<ConfigureMouseAdvanced>(); }); + [this] { CallConfigureDialog<ConfigureMouseAdvanced>(*this); }); connect(ui->touchscreen_advanced, &QPushButton::pressed, this, - [this]() { CallConfigureDialog<ConfigureTouchscreenAdvanced>(); }); -} - -template <typename Dialog, typename... Args> -void ConfigureInput::CallConfigureDialog(Args&&... args) { - this->applyConfiguration(); - Dialog dialog(this, std::forward<Args>(args)...); - - const auto res = dialog.exec(); - if (res == QDialog::Accepted) { - dialog.applyConfiguration(); - } + [this] { CallConfigureDialog<ConfigureTouchscreenAdvanced>(*this); }); } void ConfigureInput::OnDockedModeChanged(bool last_state, bool new_state) { diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h index 29a8a03f8..e8723dfcb 100644 --- a/src/yuzu/configuration/configure_input.h +++ b/src/yuzu/configuration/configure_input.h @@ -5,20 +5,12 @@ #pragma once #include <array> -#include <functional> #include <memory> -#include <optional> -#include <string> -#include <unordered_map> #include <QKeyEvent> #include <QWidget> -#include "common/param_package.h" -#include "core/settings.h" -#include "input_common/main.h" #include "ui_configure_input.h" -#include "yuzu/configuration/config.h" class QPushButton; class QString; @@ -40,9 +32,6 @@ public: private: void updateUIEnabled(); - template <typename Dialog, typename... Args> - void CallConfigureDialog(Args&&... args); - void OnDockedModeChanged(bool last_state, bool new_state); /// Load configuration settings. diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index ba6e09368..7dadd83c1 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -25,13 +25,6 @@ const std::array<std::string, ConfigureInputPlayer::ANALOG_SUB_BUTTONS_NUM> "modifier", }}; -static void MoveGridElement(QGridLayout* grid, int row_old, int column_old, int row_new, - int column_new) { - const auto item = grid->itemAtPosition(row_old, column_old); - // grid->removeItem(item); - grid->addItem(item, row_new, column_new); -} - static void LayerGridElements(QGridLayout* grid, QWidget* item, QWidget* onTopOf) { const int index1 = grid->indexOf(item); const int index2 = grid->indexOf(onTopOf); @@ -111,11 +104,10 @@ static QString AnalogToText(const Common::ParamPackage& param, const std::string } }; -ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, u8 player_index, bool debug) - : QDialog(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), - timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()), - player_index(player_index), debug(debug) { - +ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index, bool debug) + : QDialog(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index(player_index), + debug(debug), timeout_timer(std::make_unique<QTimer>()), + poll_timer(std::make_unique<QTimer>()) { ui->setupUi(this); setFocusPolicy(Qt::ClickFocus); @@ -315,7 +307,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, u8 player_index, boo for (std::size_t i = 0; i < controller_color_buttons.size(); ++i) { connect(controller_color_buttons[i], &QPushButton::clicked, this, - std::bind(&ConfigureInputPlayer::OnControllerButtonClick, this, i)); + [this, i] { OnControllerButtonClick(static_cast<int>(i)); }); } this->loadConfiguration(); diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index b0e5550c5..7a53f6715 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h @@ -9,9 +9,10 @@ #include <memory> #include <optional> #include <string> -#include <unordered_map> + #include <QDialog> #include <QKeyEvent> + #include "common/param_package.h" #include "core/settings.h" #include "input_common/main.h" @@ -29,16 +30,39 @@ class ConfigureInputPlayer : public QDialog { Q_OBJECT public: - explicit ConfigureInputPlayer(QWidget* parent, u8 player_index, bool debug = false); + explicit ConfigureInputPlayer(QWidget* parent, std::size_t player_index, bool debug = false); ~ConfigureInputPlayer() override; /// Save all button configurations to settings file void applyConfiguration(); private: + void OnControllerButtonClick(int i); + + /// Load configuration settings. + void loadConfiguration(); + /// Restore all buttons to their default values. + void restoreDefaults(); + /// Clear all input configuration + void ClearAll(); + + /// Update UI to reflect current configuration. + void updateButtonLabels(); + + /// Called when the button was pressed. + void handleClick(QPushButton* button, + std::function<void(const Common::ParamPackage&)> new_input_setter, + InputCommon::Polling::DeviceType type); + + /// Finish polling and configure input using the input_setter + void setPollingResult(const Common::ParamPackage& params, bool abort); + + /// Handle key press events. + void keyPressEvent(QKeyEvent* event) override; + std::unique_ptr<Ui::ConfigureInputPlayer> ui; - u8 player_index; + std::size_t player_index; bool debug; std::unique_ptr<QTimer> timeout_timer; @@ -77,27 +101,4 @@ private: std::array<QPushButton*, 4> controller_color_buttons; std::array<QColor, 4> controller_colors; - - void OnControllerButtonClick(int i); - - /// Load configuration settings. - void loadConfiguration(); - /// Restore all buttons to their default values. - void restoreDefaults(); - /// Clear all input configuration - void ClearAll(); - - /// Update UI to reflect current configuration. - void updateButtonLabels(); - - /// Called when the button was pressed. - void handleClick(QPushButton* button, - std::function<void(const Common::ParamPackage&)> new_input_setter, - InputCommon::Polling::DeviceType type); - - /// Finish polling and configure input using the input_setter - void setPollingResult(const Common::ParamPackage& params, bool abort); - - /// Handle key press events. - void keyPressEvent(QKeyEvent* event) override; }; diff --git a/src/yuzu/configuration/configure_mouse_advanced.cpp b/src/yuzu/configuration/configure_mouse_advanced.cpp index dab58fbaa..ef857035e 100644 --- a/src/yuzu/configuration/configure_mouse_advanced.cpp +++ b/src/yuzu/configuration/configure_mouse_advanced.cpp @@ -4,11 +4,11 @@ #include <algorithm> #include <memory> -#include <utility> + #include <QKeyEvent> #include <QMenu> -#include <QMessageBox> #include <QTimer> + #include "common/assert.h" #include "common/param_package.h" #include "input_common/main.h" diff --git a/src/yuzu/configuration/configure_mouse_advanced.h b/src/yuzu/configuration/configure_mouse_advanced.h index 218df2bda..e04da4bf2 100644 --- a/src/yuzu/configuration/configure_mouse_advanced.h +++ b/src/yuzu/configuration/configure_mouse_advanced.h @@ -7,7 +7,7 @@ #include <memory> #include <optional> #include <QDialog> -#include <QWidget> + #include "core/settings.h" class QCheckBox; @@ -28,23 +28,6 @@ public: void applyConfiguration(); private: - std::unique_ptr<Ui::ConfigureMouseAdvanced> ui; - - /// This will be the the setting function when an input is awaiting configuration. - std::optional<std::function<void(const Common::ParamPackage&)>> input_setter; - - std::array<QPushButton*, Settings::NativeMouseButton::NumMouseButtons> button_map; - std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons> buttons_param; - - std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers; - - std::unique_ptr<QTimer> timeout_timer; - std::unique_ptr<QTimer> poll_timer; - - /// A flag to indicate if keyboard keys are okay when configuring an input. If this is false, - /// keyboard events are ignored. - bool want_keyboard_keys = false; - /// Load configuration settings. void loadConfiguration(); /// Restore all buttons to their default values. @@ -65,4 +48,21 @@ private: /// Handle key press events. void keyPressEvent(QKeyEvent* event) override; + + std::unique_ptr<Ui::ConfigureMouseAdvanced> ui; + + /// This will be the the setting function when an input is awaiting configuration. + std::optional<std::function<void(const Common::ParamPackage&)>> input_setter; + + std::array<QPushButton*, Settings::NativeMouseButton::NumMouseButtons> button_map; + std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons> buttons_param; + + std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers; + + std::unique_ptr<QTimer> timeout_timer; + std::unique_ptr<QTimer> poll_timer; + + /// A flag to indicate if keyboard keys are okay when configuring an input. If this is false, + /// keyboard events are ignored. + bool want_keyboard_keys = false; }; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 9c6d150a5..93bf117c8 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1105,14 +1105,14 @@ void GMainWindow::OnMenuInstallToNAND() { return; } const auto res = - Service::FileSystem::GetUserNANDContents()->InstallEntry(nsp, false, qt_raw_copy); + Service::FileSystem::GetUserNANDContents()->InstallEntry(*nsp, false, qt_raw_copy); if (res == FileSys::InstallResult::Success) { success(); } else { if (res == FileSys::InstallResult::ErrorAlreadyExists) { if (overwrite()) { const auto res2 = Service::FileSystem::GetUserNANDContents()->InstallEntry( - nsp, true, qt_raw_copy); + *nsp, true, qt_raw_copy); if (res2 == FileSys::InstallResult::Success) { success(); } else { @@ -1167,10 +1167,10 @@ void GMainWindow::OnMenuInstallToNAND() { FileSys::InstallResult res; if (index >= static_cast<size_t>(FileSys::TitleType::Application)) { res = Service::FileSystem::GetUserNANDContents()->InstallEntry( - nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy); + *nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy); } else { res = Service::FileSystem::GetSystemNANDContents()->InstallEntry( - nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy); + *nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy); } if (res == FileSys::InstallResult::Success) { @@ -1178,7 +1178,7 @@ void GMainWindow::OnMenuInstallToNAND() { } else if (res == FileSys::InstallResult::ErrorAlreadyExists) { if (overwrite()) { const auto res2 = Service::FileSystem::GetUserNANDContents()->InstallEntry( - nca, static_cast<FileSys::TitleType>(index), true, qt_raw_copy); + *nca, static_cast<FileSys::TitleType>(index), true, qt_raw_copy); if (res2 == FileSys::InstallResult::Success) { success(); } else { |