surface_params: Cleanup
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <boost/icl/interval_map.hpp>
|
||||||
#include <boost/range/iterator_range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include "video_core/rasterizer_cache/surface_base.h"
|
#include "video_core/rasterizer_cache/surface_base.h"
|
||||||
#include "video_core/rasterizer_cache/surface_params.h"
|
#include "video_core/rasterizer_cache/surface_params.h"
|
||||||
|
@@ -3,95 +3,10 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
|
||||||
#include "video_core/rasterizer_cache/surface_params.h"
|
#include "video_core/rasterizer_cache/surface_params.h"
|
||||||
|
|
||||||
namespace VideoCore {
|
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<u32> 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<u32> 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<u32>(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<u32>(x0, y0 + sub_surface.height, x0 + sub_surface.width, y0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Common::Rectangle<u32> 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 {
|
bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const {
|
||||||
return std::tie(other_surface.addr, other_surface.width, other_surface.height,
|
return std::tie(other_surface.addr, other_surface.width, other_surface.height,
|
||||||
other_surface.stride, other_surface.pixel_format, other_surface.is_tiled) ==
|
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();
|
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
|
} // namespace VideoCore
|
||||||
|
@@ -4,12 +4,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <climits>
|
|
||||||
#include <boost/icl/interval_map.hpp>
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "common/math_util.h"
|
#include "video_core/rasterizer_cache/utils.h"
|
||||||
#include "video_core/rasterizer_cache/pixel_format.h"
|
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
|
|
||||||
@@ -17,64 +13,62 @@ using SurfaceInterval = boost::icl::right_open_interval<PAddr>;
|
|||||||
|
|
||||||
class SurfaceParams {
|
class SurfaceParams {
|
||||||
public:
|
public:
|
||||||
/// Surface match traits
|
/// Returns true if other_surface matches exactly params
|
||||||
bool ExactMatch(const SurfaceParams& other_surface) const;
|
bool ExactMatch(const SurfaceParams& other_surface) const;
|
||||||
|
|
||||||
|
/// Returns true if sub_surface is a subrect of params
|
||||||
bool CanSubRect(const SurfaceParams& sub_surface) const;
|
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;
|
bool CanExpand(const SurfaceParams& expanded_surface) const;
|
||||||
|
|
||||||
|
/// Returns true if params can be used for texcopy
|
||||||
bool CanTexCopy(const SurfaceParams& texcopy_params) const;
|
bool CanTexCopy(const SurfaceParams& texcopy_params) const;
|
||||||
|
|
||||||
Common::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const;
|
|
||||||
Common::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const;
|
|
||||||
|
|
||||||
/// Returns the outer rectangle containing "interval"
|
|
||||||
SurfaceParams FromInterval(SurfaceInterval interval) const;
|
|
||||||
SurfaceInterval GetSubRectInterval(Common::Rectangle<u32> unscaled_rect) const;
|
|
||||||
|
|
||||||
/// Updates remaining members from the already set addr, width, height and pixel_format
|
/// Updates remaining members from the already set addr, width, height and pixel_format
|
||||||
void UpdateParams() {
|
void UpdateParams();
|
||||||
if (stride == 0) {
|
|
||||||
stride = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = GetFormatType(pixel_format);
|
/// Returns the unscaled rectangle referenced by sub_surface
|
||||||
size = !is_tiled ? BytesInPixels(stride * (height - 1) + width)
|
Rect2D GetSubRect(const SurfaceParams& sub_surface) const;
|
||||||
: BytesInPixels(stride * 8 * (height / 8 - 1) + width * 8);
|
|
||||||
end = addr + size;
|
/// 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 {
|
[[nodiscard]] u32 GetFormatBpp() const noexcept {
|
||||||
return res_scale > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SurfaceInterval GetInterval() const {
|
|
||||||
return SurfaceInterval(addr, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GetFormatBpp() const {
|
|
||||||
return VideoCore::GetFormatBpp(pixel_format);
|
return VideoCore::GetFormatBpp(pixel_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetScaledWidth() const {
|
[[nodiscard]] u32 GetScaledWidth() const noexcept {
|
||||||
return width * res_scale;
|
return width * res_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetScaledHeight() const {
|
[[nodiscard]] u32 GetScaledHeight() const noexcept {
|
||||||
return height * res_scale;
|
return height * res_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Rectangle<u32> GetRect() const {
|
[[nodiscard]] Rect2D GetRect() const noexcept {
|
||||||
return {0, height, width, 0};
|
return Rect2D{0, height, width, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Rectangle<u32> GetScaledRect() const {
|
[[nodiscard]] Rect2D GetScaledRect() const noexcept {
|
||||||
return {0, GetScaledHeight(), GetScaledWidth(), 0};
|
return Rect2D{0, GetScaledHeight(), GetScaledWidth(), 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 PixelsInBytes(u32 size) const {
|
[[nodiscard]] u32 PixelsInBytes(u32 size) const noexcept {
|
||||||
return size * 8 / GetFormatBpp();
|
return size * 8 / GetFormatBpp();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 BytesInPixels(u32 pixels) const {
|
[[nodiscard]] u32 BytesInPixels(u32 pixels) const noexcept {
|
||||||
return pixels * GetFormatBpp() / 8;
|
return pixels * GetFormatBpp() / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +80,7 @@ public:
|
|||||||
u32 width = 0;
|
u32 width = 0;
|
||||||
u32 height = 0;
|
u32 height = 0;
|
||||||
u32 stride = 0;
|
u32 stride = 0;
|
||||||
|
u32 levels = 1;
|
||||||
u16 res_scale = 1;
|
u16 res_scale = 1;
|
||||||
|
|
||||||
bool is_tiled = false;
|
bool is_tiled = false;
|
||||||
|
Reference in New Issue
Block a user