From 1ffd9f08af5f3af43c6683ce1670b1b0d7aa6934 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Thu, 9 Feb 2023 17:11:28 +0200 Subject: [PATCH] surface_params: Cleanup --- .../rasterizer_cache/rasterizer_cache_base.h | 1 + .../rasterizer_cache/surface_params.cpp | 172 +++++++++--------- .../rasterizer_cache/surface_params.h | 71 ++++---- 3 files changed, 121 insertions(+), 123 deletions(-) diff --git a/src/video_core/rasterizer_cache/rasterizer_cache_base.h b/src/video_core/rasterizer_cache/rasterizer_cache_base.h index eba74c0cd..8fb9f9d12 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache_base.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache_base.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "video_core/rasterizer_cache/surface_base.h" #include "video_core/rasterizer_cache/surface_params.h" diff --git a/src/video_core/rasterizer_cache/surface_params.cpp b/src/video_core/rasterizer_cache/surface_params.cpp index f91f85806..8b4820b78 100644 --- a/src/video_core/rasterizer_cache/surface_params.cpp +++ b/src/video_core/rasterizer_cache/surface_params.cpp @@ -3,95 +3,10 @@ // Refer to the license.txt file included. #include "common/alignment.h" -#include "video_core/rasterizer_cache/rasterizer_cache.h" #include "video_core/rasterizer_cache/surface_params.h" namespace VideoCore { -SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const { - SurfaceParams params = *this; - const u32 tiled_size = is_tiled ? 8 : 1; - const u32 stride_tiled_bytes = BytesInPixels(stride * tiled_size); - - PAddr aligned_start = - addr + Common::AlignDown(boost::icl::first(interval) - addr, stride_tiled_bytes); - PAddr aligned_end = - addr + Common::AlignUp(boost::icl::last_next(interval) - addr, stride_tiled_bytes); - - if (aligned_end - aligned_start > stride_tiled_bytes) { - params.addr = aligned_start; - params.height = (aligned_end - aligned_start) / BytesInPixels(stride); - } else { - // 1 row - ASSERT(aligned_end - aligned_start == stride_tiled_bytes); - const u32 tiled_alignment = BytesInPixels(is_tiled ? 8 * 8 : 1); - - aligned_start = - addr + Common::AlignDown(boost::icl::first(interval) - addr, tiled_alignment); - aligned_end = - addr + Common::AlignUp(boost::icl::last_next(interval) - addr, tiled_alignment); - - params.addr = aligned_start; - params.width = PixelsInBytes(aligned_end - aligned_start) / tiled_size; - params.stride = params.width; - params.height = tiled_size; - } - - params.UpdateParams(); - return params; -} - -SurfaceInterval SurfaceParams::GetSubRectInterval(Common::Rectangle unscaled_rect) const { - if (unscaled_rect.GetHeight() == 0 || unscaled_rect.GetWidth() == 0) { - return {}; - } - - if (is_tiled) { - unscaled_rect.left = Common::AlignDown(unscaled_rect.left, 8) * 8; - unscaled_rect.bottom = Common::AlignDown(unscaled_rect.bottom, 8) / 8; - unscaled_rect.right = Common::AlignUp(unscaled_rect.right, 8) * 8; - unscaled_rect.top = Common::AlignUp(unscaled_rect.top, 8) / 8; - } - - const u32 stride_tiled = !is_tiled ? stride : stride * 8; - - const u32 pixel_offset = - stride_tiled * (!is_tiled ? unscaled_rect.bottom : (height / 8) - unscaled_rect.top) + - unscaled_rect.left; - - const u32 pixels = (unscaled_rect.GetHeight() - 1) * stride_tiled + unscaled_rect.GetWidth(); - - return {addr + BytesInPixels(pixel_offset), addr + BytesInPixels(pixel_offset + pixels)}; -} - -Common::Rectangle SurfaceParams::GetSubRect(const SurfaceParams& sub_surface) const { - const u32 begin_pixel_index = PixelsInBytes(sub_surface.addr - addr); - - if (is_tiled) { - const int x0 = (begin_pixel_index % (stride * 8)) / 8; - const int y0 = (begin_pixel_index / (stride * 8)) * 8; - - // Top to bottom - return Common::Rectangle(x0, height - y0, x0 + sub_surface.width, - height - (y0 + sub_surface.height)); - } - - const int x0 = begin_pixel_index % stride; - const int y0 = begin_pixel_index / stride; - - // Bottom to top - return Common::Rectangle(x0, y0 + sub_surface.height, x0 + sub_surface.width, y0); -} - -Common::Rectangle SurfaceParams::GetScaledSubRect(const SurfaceParams& sub_surface) const { - auto rect = GetSubRect(sub_surface); - rect.left = rect.left * res_scale; - rect.right = rect.right * res_scale; - rect.top = rect.top * res_scale; - rect.bottom = rect.bottom * res_scale; - return rect; -} - bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const { return std::tie(other_surface.addr, other_surface.width, other_surface.height, other_surface.stride, other_surface.pixel_format, other_surface.is_tiled) == @@ -134,4 +49,91 @@ bool SurfaceParams::CanTexCopy(const SurfaceParams& texcopy_params) const { return FromInterval(texcopy_params.GetInterval()).GetInterval() == texcopy_params.GetInterval(); } +void SurfaceParams::UpdateParams() { + if (stride == 0) { + stride = width; + } + + type = GetFormatType(pixel_format); + size = !is_tiled ? BytesInPixels(stride * (height - 1) + width) + : BytesInPixels(stride * 8 * (height / 8 - 1) + width * 8); + + end = addr + size; +} + +Rect2D SurfaceParams::GetSubRect(const SurfaceParams& sub_surface) const { + const u32 begin_pixel_index = PixelsInBytes(sub_surface.addr - addr); + + if (is_tiled) { + const u32 x0 = (begin_pixel_index % (stride * 8)) / 8; + const u32 y0 = (begin_pixel_index / (stride * 8)) * 8; + // Top to bottom + return Rect2D(x0, height - y0, x0 + sub_surface.width, height - (y0 + sub_surface.height)); + } + + const u32 x0 = begin_pixel_index % stride; + const u32 y0 = begin_pixel_index / stride; + // Bottom to top + return Rect2D(x0, y0 + sub_surface.height, x0 + sub_surface.width, y0); +} + +Rect2D SurfaceParams::GetScaledSubRect(const SurfaceParams& sub_surface) const { + const Rect2D rect = GetSubRect(sub_surface); + return rect * res_scale; +} + +SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const { + SurfaceParams params = *this; + const u32 tiled_size = is_tiled ? 8 : 1; + const u32 stride_tiled_bytes = BytesInPixels(stride * tiled_size); + + PAddr aligned_start = + addr + Common::AlignDown(boost::icl::first(interval) - addr, stride_tiled_bytes); + PAddr aligned_end = + addr + Common::AlignUp(boost::icl::last_next(interval) - addr, stride_tiled_bytes); + + if (aligned_end - aligned_start > stride_tiled_bytes) { + params.addr = aligned_start; + params.height = (aligned_end - aligned_start) / BytesInPixels(stride); + } else { + // 1 row + ASSERT(aligned_end - aligned_start == stride_tiled_bytes); + const u32 tiled_alignment = BytesInPixels(is_tiled ? 8 * 8 : 1); + + aligned_start = + addr + Common::AlignDown(boost::icl::first(interval) - addr, tiled_alignment); + aligned_end = + addr + Common::AlignUp(boost::icl::last_next(interval) - addr, tiled_alignment); + + params.addr = aligned_start; + params.width = PixelsInBytes(aligned_end - aligned_start) / tiled_size; + params.stride = params.width; + params.height = tiled_size; + } + + params.UpdateParams(); + return params; +} + +SurfaceInterval SurfaceParams::GetSubRectInterval(Rect2D unscaled_rect) const { + if (unscaled_rect.GetHeight() == 0 || unscaled_rect.GetWidth() == 0) [[unlikely]] { + return {}; + } + + if (is_tiled) { + unscaled_rect.left = Common::AlignDown(unscaled_rect.left, 8) * 8; + unscaled_rect.bottom = Common::AlignDown(unscaled_rect.bottom, 8) / 8; + unscaled_rect.right = Common::AlignUp(unscaled_rect.right, 8) * 8; + unscaled_rect.top = Common::AlignUp(unscaled_rect.top, 8) / 8; + } + + const u32 stride_tiled = !is_tiled ? stride : stride * 8; + const u32 pixels = (unscaled_rect.GetHeight() - 1) * stride_tiled + unscaled_rect.GetWidth(); + const u32 pixel_offset = + stride_tiled * (!is_tiled ? unscaled_rect.bottom : (height / 8) - unscaled_rect.top) + + unscaled_rect.left; + + return {addr + BytesInPixels(pixel_offset), addr + BytesInPixels(pixel_offset + pixels)}; +} + } // namespace VideoCore diff --git a/src/video_core/rasterizer_cache/surface_params.h b/src/video_core/rasterizer_cache/surface_params.h index a89f888e9..3c96b419f 100644 --- a/src/video_core/rasterizer_cache/surface_params.h +++ b/src/video_core/rasterizer_cache/surface_params.h @@ -4,12 +4,8 @@ #pragma once -#include -#include -#include #include -#include "common/math_util.h" -#include "video_core/rasterizer_cache/pixel_format.h" +#include "video_core/rasterizer_cache/utils.h" namespace VideoCore { @@ -17,64 +13,62 @@ using SurfaceInterval = boost::icl::right_open_interval; class SurfaceParams { public: - /// Surface match traits + /// 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 params can be expanded to match expanded_surface bool CanExpand(const SurfaceParams& expanded_surface) const; + + /// Returns true if params can be used for texcopy bool CanTexCopy(const SurfaceParams& texcopy_params) const; - Common::Rectangle GetSubRect(const SurfaceParams& sub_surface) const; - Common::Rectangle GetScaledSubRect(const SurfaceParams& sub_surface) const; - - /// Returns the outer rectangle containing "interval" - SurfaceParams FromInterval(SurfaceInterval interval) const; - SurfaceInterval GetSubRectInterval(Common::Rectangle unscaled_rect) const; - /// Updates remaining members from the already set addr, width, height and pixel_format - void UpdateParams() { - if (stride == 0) { - stride = width; - } + void UpdateParams(); - type = GetFormatType(pixel_format); - size = !is_tiled ? BytesInPixels(stride * (height - 1) + width) - : BytesInPixels(stride * 8 * (height / 8 - 1) + width * 8); - end = addr + size; + /// Returns the unscaled rectangle referenced by sub_surface + Rect2D GetSubRect(const SurfaceParams& sub_surface) const; + + /// Returns the scaled rectangle referenced by sub_surface + Rect2D 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(Rect2D unscaled_rect) const; + + [[nodiscard]] SurfaceInterval GetInterval() const noexcept { + return SurfaceInterval{addr, end}; } - bool IsScaled() const { - return res_scale > 1; - } - - SurfaceInterval GetInterval() const { - return SurfaceInterval(addr, end); - } - - u32 GetFormatBpp() const { + [[nodiscard]] u32 GetFormatBpp() const noexcept { return VideoCore::GetFormatBpp(pixel_format); } - u32 GetScaledWidth() const { + [[nodiscard]] u32 GetScaledWidth() const noexcept { return width * res_scale; } - u32 GetScaledHeight() const { + [[nodiscard]] u32 GetScaledHeight() const noexcept { return height * res_scale; } - Common::Rectangle GetRect() const { - return {0, height, width, 0}; + [[nodiscard]] Rect2D GetRect() const noexcept { + return Rect2D{0, height, width, 0}; } - Common::Rectangle GetScaledRect() const { - return {0, GetScaledHeight(), GetScaledWidth(), 0}; + [[nodiscard]] Rect2D GetScaledRect() const noexcept { + return Rect2D{0, GetScaledHeight(), GetScaledWidth(), 0}; } - u32 PixelsInBytes(u32 size) const { + [[nodiscard]] u32 PixelsInBytes(u32 size) const noexcept { return size * 8 / GetFormatBpp(); } - u32 BytesInPixels(u32 pixels) const { + [[nodiscard]] u32 BytesInPixels(u32 pixels) const noexcept { return pixels * GetFormatBpp() / 8; } @@ -86,6 +80,7 @@ public: u32 width = 0; u32 height = 0; u32 stride = 0; + u32 levels = 1; u16 res_scale = 1; bool is_tiled = false;