// Copyright 2022 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include "common/math_util.h" #include "video_core/custom_textures/custom_format.h" #include "video_core/rasterizer_cache/pixel_format.h" namespace VideoCore { using SurfaceInterval = boost::icl::right_open_interval; constexpr std::size_t MAX_PICA_LEVELS = 8; class SurfaceParams { public: /// Returns true if other_surface matches exactly params bool ExactMatch(const SurfaceParams& other_surface) const; /// Returns true if sub_surface is a subrect of params bool CanSubRect(const SurfaceParams& sub_surface) const; /// Returns true if other_surface can be used for reinterpretion. bool CanReinterpret(const SurfaceParams& other_surface); /// Returns true if params can be used for texcopy bool CanTexCopy(const SurfaceParams& texcopy_params) const; /// Updates remaining members from the already set addr, width, height and pixel_format void UpdateParams(); /// Returns the unscaled rectangle referenced by sub_surface Common::Rectangle GetSubRect(const SurfaceParams& sub_surface) const; /// Returns the scaled rectangle referenced by sub_surface Common::Rectangle GetScaledSubRect(const SurfaceParams& sub_surface) const; /// Returns the outer rectangle containing interval SurfaceParams FromInterval(SurfaceInterval interval) const; /// Returns the address interval referenced by unscaled_rect SurfaceInterval GetSubRectInterval(Common::Rectangle unscaled_rect, u32 level = 0) const; /// Return the address interval of the provided level SurfaceInterval LevelInterval(u32 level) const; /// Returns the level of the provided address u32 LevelOf(PAddr addr) const; /// Returns a string identifier of the params object std::string DebugName(bool scaled, bool custom = false) const noexcept; bool operator==(const SurfaceParams& other) const noexcept; [[nodiscard]] SurfaceInterval GetInterval() const noexcept { return SurfaceInterval{addr, end}; } [[nodiscard]] u32 GetFormatBpp() const noexcept { return VideoCore::GetFormatBpp(pixel_format); } [[nodiscard]] u32 GetScaledWidth() const noexcept { return width * res_scale; } [[nodiscard]] u32 GetScaledHeight() const noexcept { return height * res_scale; } [[nodiscard]] Common::Rectangle GetRect(u32 level = 0) const noexcept { return {0, height >> level, width >> level, 0}; } [[nodiscard]] Common::Rectangle GetScaledRect(u32 level = 0) const noexcept { return {0, GetScaledHeight() >> level, GetScaledWidth() >> level, 0}; } [[nodiscard]] u32 PixelsInBytes(u32 size) const noexcept { return size * 8 / GetFormatBpp(); } [[nodiscard]] u32 BytesInPixels(u32 pixels) const noexcept { return pixels * GetFormatBpp() / 8; } private: /// Computes the offset of each mipmap level void CalculateMipLevelOffsets(); /// Calculates total surface size taking mipmaps into account u32 CalculateSurfaceSize() const; public: PAddr addr = 0; PAddr end = 0; u32 size = 0; u32 width = 0; u32 height = 0; u32 stride = 0; u32 levels = 1; u32 res_scale = 1; bool is_tiled = false; TextureType texture_type = TextureType::Texture2D; PixelFormat pixel_format = PixelFormat::Invalid; CustomPixelFormat custom_format = CustomPixelFormat::Invalid; SurfaceType type = SurfaceType::Invalid; std::array mipmap_offsets{}; }; } // namespace VideoCore