rasterizer_cache: Use Common::Rectangle everywhere

* Make a nice alias for it and use it instead of having Rect2D/Region2D. Makes the new design less intrusive to the current cache
This commit is contained in:
emufan4568
2022-09-12 20:24:15 +03:00
committed by GPUCode
parent c71dbb5d19
commit f63653a5b9
6 changed files with 63 additions and 111 deletions

View File

@ -23,21 +23,27 @@ struct Rectangle {
constexpr Rectangle(T left, T top, T right, T bottom)
: left(left), top(top), right(right), bottom(bottom) {}
auto operator<=>(const Rectangle&) const = default;
constexpr auto operator<=>(const Rectangle&) const = default;
constexpr void operator*=(const T value) {
left *= value;
top *= value;
right *= value;
bottom *= value;
}
[[nodiscard]] T GetWidth() const {
[[nodiscard]] constexpr T GetWidth() const {
return std::abs(static_cast<std::make_signed_t<T>>(right - left));
}
[[nodiscard]] T GetHeight() const {
[[nodiscard]] constexpr T GetHeight() const {
return std::abs(static_cast<std::make_signed_t<T>>(bottom - top));
}
[[nodiscard]] Rectangle<T> TranslateX(const T x) const {
[[nodiscard]] constexpr Rectangle<T> TranslateX(const T x) const {
return Rectangle{left + x, top, right + x, bottom};
}
[[nodiscard]] Rectangle<T> TranslateY(const T y) const {
[[nodiscard]] constexpr Rectangle<T> TranslateY(const T y) const {
return Rectangle{left, top + y, right, bottom + y};
}
[[nodiscard]] Rectangle<T> Scale(const float s) const {
[[nodiscard]] constexpr Rectangle<T> Scale(const float s) const {
return Rectangle{left, top, static_cast<T>(left + GetWidth() * s),
static_cast<T>(top + GetHeight() * s)};
}

View File

@ -47,10 +47,10 @@ class RasterizerCache : NonCopyable {
public:
using TextureRuntime = typename T::Runtime;
using CachedSurface = typename T::Surface;
using Watcher = SurfaceWatcher<CachedSurface>;
/// Declare rasterizer interval types
using Surface = std::shared_ptr<CachedSurface>;
using Watcher = SurfaceWatcher<CachedSurface>;
using SurfaceSet = std::set<Surface>;
using SurfaceMap =
boost::icl::interval_map<PAddr, Surface, boost::icl::partial_absorber, std::less,
@ -165,15 +165,15 @@ private:
template <class T>
RasterizerCache<T>::RasterizerCache(VideoCore::RasterizerAccelerated& rasterizer, TextureRuntime& runtime)
: rasterizer(rasterizer), runtime{runtime} {
: rasterizer{rasterizer}, runtime{runtime} {
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
}
template <class T>
template <MatchFlags find_flags>
auto RasterizerCache<T>::FindMatch(const SurfaceCache& surface_cache, const SurfaceParams& params,
ScaleMatch match_scale_type,
std::optional<SurfaceInterval> validate_interval) -> Surface {
ScaleMatch match_scale_type,
std::optional<SurfaceInterval> validate_interval) -> Surface {
Surface match_surface = nullptr;
bool match_valid = false;
u32 match_scale = 0;
@ -273,14 +273,8 @@ bool RasterizerCache<T>::BlitSurfaces(const Surface& src_surface, Common::Rectan
.dst_level = 0,
.src_layer = 0,
.dst_layer = 0,
.src_region = Region2D{
.start = {src_rect.left, src_rect.bottom},
.end = {src_rect.right, src_rect.top}
},
.dst_region = Region2D{
.start = {dst_rect.left, dst_rect.bottom},
.end = {dst_rect.right, dst_rect.top}
}
.src_rect = src_rect,
.dst_rect = dst_rect
};
return runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit);
@ -295,10 +289,9 @@ void RasterizerCache<T>::CopySurface(const Surface& src_surface, const Surface&
SurfaceInterval copy_interval) {
MICROPROFILE_SCOPE(RasterizerCache_CopySurface);
SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
const SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
ASSERT(subrect_params.GetInterval() == copy_interval && src_surface != dst_surface);
const auto dst_rect = dst_surface->GetScaledSubRect(subrect_params);
if (src_surface->type == SurfaceType::Fill) {
// FillSurface needs a 4 bytes buffer
const u32 fill_offset =
@ -317,10 +310,7 @@ void RasterizerCache<T>::CopySurface(const Surface& src_surface, const Surface&
.surface_type = dst_surface->type,
.texture_format = dst_surface->pixel_format,
.texture_level = 0,
.rect = Rect2D{
.offset = {dst_rect.left, dst_rect.bottom},
.extent = {dst_rect.GetWidth(), dst_rect.GetHeight()}
}
.texture_rect = dst_surface->GetScaledSubRect(subrect_params)
};
runtime.ClearTexture(dst_surface->texture, clear_rect, clear_value);
@ -328,21 +318,14 @@ void RasterizerCache<T>::CopySurface(const Surface& src_surface, const Surface&
}
if (src_surface->CanSubRect(subrect_params)) {
const auto src_rect = src_surface->GetScaledSubRect(subrect_params);
const TextureBlit texture_blit = {
.surface_type = src_surface->type,
.src_level = 0,
.dst_level = 0,
.src_layer = 0,
.dst_layer = 0,
.src_region = Region2D{
.start = {src_rect.left, src_rect.bottom},
.end = {src_rect.right, src_rect.top}
},
.dst_region = Region2D{
.start = {dst_rect.left, dst_rect.bottom},
.end = {dst_rect.right, dst_rect.top}
}
.src_rect = src_surface->GetScaledSubRect(subrect_params),
.dst_rect = dst_surface->GetScaledSubRect(subrect_params)
};
runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit);
@ -567,22 +550,14 @@ auto RasterizerCache<T>::GetTextureSurface(const Pica::Texture::TextureInfo& inf
}
if (/*texture_filterer->IsNull()*/true) {
const auto src_rect = level_surface->GetScaledRect();
const auto dst_rect = surface_params.GetScaledRect();
const TextureBlit texture_blit = {
.surface_type = surface->type,
.src_level = 0,
.dst_level = level,
.src_layer = 0,
.dst_layer = 0,
.src_region = Region2D{
.start = {src_rect.left, src_rect.bottom},
.end = {src_rect.right, src_rect.top}
},
.dst_region = Region2D{
.start = {dst_rect.left, dst_rect.bottom},
.end = {dst_rect.right, dst_rect.top}
}
.src_rect = level_surface->GetScaledRect(),
.dst_rect = surface_params.GetScaledRect()
};
runtime.BlitTextures(level_surface->texture, surface->texture, texture_blit);
@ -648,8 +623,7 @@ auto RasterizerCache<T>::GetTextureCube(const TextureCubeConfig& config) -> cons
cube->texture = runtime.AllocateCubeMap(width, PixelFormatFromTextureFormat(config.format));
}
u32 scaled_size = cube->res_scale * config.width;
const u32 scaled_size = cube->res_scale * config.width;
for (std::size_t i = 0; i < faces.size(); i++) {
const Face& face = faces[i];
if (face.watcher && !face.watcher->IsValid()) {
@ -658,21 +632,14 @@ auto RasterizerCache<T>::GetTextureCube(const TextureCubeConfig& config) -> cons
ValidateSurface(surface, surface->addr, surface->size);
}
const auto src_rect = surface->GetScaledRect();
const TextureBlit texture_blit = {
.surface_type = SurfaceType::Color,
.src_level = 0,
.dst_level = 0,
.src_layer = 0,
.dst_layer = static_cast<u32>(i),
.src_region = Region2D{
.start = {src_rect.left, src_rect.bottom},
.end = {src_rect.right, src_rect.top}
},
.dst_region = Region2D{
.start = {0, 0},
.end = {scaled_size, scaled_size}
}
.src_rect = surface->GetScaledRect(),
.dst_rect = Rect2D{0, scaled_size, scaled_size, 0}
};
runtime.BlitTextures(surface->texture, cube->texture, texture_blit);

View File

@ -180,8 +180,8 @@ SurfaceInterval SurfaceBase<S>::GetCopyableInterval(const SurfaceParams& params)
template <class S>
auto SurfaceBase<S>::CreateWatcher() -> std::shared_ptr<Watcher> {
S* derived = reinterpret_cast<S*>(this);
auto watcher = std::make_shared<Watcher>(std::move(derived->weak_from_this()));
auto weak_ptr = reinterpret_cast<S*>(this)->weak_from_this();
auto watcher = std::make_shared<Watcher>(std::move(weak_ptr));
watchers[watcher_count++] = watcher;
return watcher;
}

View File

@ -3,12 +3,14 @@
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
#include "common/math_util.h"
#include "common/vector_math.h"
#include "video_core/rasterizer_cache/pixel_format.h"
namespace VideoCore {
using Rect2D = Common::Rectangle<u32>;
struct Offset {
constexpr auto operator<=>(const Offset&) const noexcept = default;
@ -23,20 +25,6 @@ struct Extent {
u32 height = 1;
};
struct Rect2D {
constexpr auto operator<=>(const Rect2D&) const noexcept = default;
Offset offset;
Extent extent;
};
struct Region2D {
constexpr auto operator<=>(const Region2D&) const noexcept = default;
Offset start;
Offset end;
};
union ClearValue {
Common::Vec4f color;
struct {
@ -49,7 +37,7 @@ struct TextureClear {
SurfaceType surface_type;
PixelFormat texture_format;
u32 texture_level;
Rect2D rect;
Rect2D texture_rect;
};
struct TextureCopy {
@ -67,8 +55,8 @@ struct TextureBlit {
u32 dst_level;
u32 src_layer;
u32 dst_layer;
Region2D src_region;
Region2D dst_region;
Rect2D src_rect;
Rect2D dst_rect;
};
struct BufferTextureCopy {
@ -77,9 +65,8 @@ struct BufferTextureCopy {
u32 buffer_row_length;
u32 buffer_height;
SurfaceType surface_type;
Rect2D texture_rect;
u32 texture_level;
Offset texture_offset;
Extent texture_extent;
};
struct BufferCopy {

View File

@ -187,11 +187,9 @@ void TextureRuntime::ReadTexture(OGLTexture& texture, const VideoCore::BufferTex
}
const FormatTuple& tuple = GetFormatTuple(format);
glReadPixels(copy.texture_offset.x, copy.texture_offset.y,
copy.texture_offset.x + copy.texture_extent.width,
copy.texture_offset.y + copy.texture_extent.height,
tuple.format, tuple.type,
reinterpret_cast<void*>(copy.buffer_offset));
glReadPixels(copy.texture_rect.left, copy.texture_rect.bottom,
copy.texture_rect.GetWidth(), copy.texture_rect.GetHeight(),
tuple.format, tuple.type, reinterpret_cast<void*>(copy.buffer_offset));
}
bool TextureRuntime::ClearTexture(OGLTexture& texture, const VideoCore::TextureClear& clear,
@ -202,10 +200,10 @@ bool TextureRuntime::ClearTexture(OGLTexture& texture, const VideoCore::TextureC
// Setup scissor rectangle according to the clear rectangle
OpenGLState state{};
state.scissor.enabled = true;
state.scissor.x = clear.rect.offset.x;
state.scissor.y = clear.rect.offset.y;
state.scissor.width = clear.rect.extent.width;
state.scissor.height = clear.rect.extent.height;
state.scissor.x = clear.texture_rect.left;
state.scissor.y = clear.texture_rect.bottom;
state.scissor.width = clear.texture_rect.GetWidth();
state.scissor.height = clear.texture_rect.GetHeight();
state.draw.draw_framebuffer = draw_fbo.handle;
state.Apply();
@ -308,10 +306,8 @@ bool TextureRuntime::BlitTextures(OGLTexture& source, OGLTexture& dest, const Vi
// inconsistent scale.
const GLbitfield buffer_mask = MakeBufferMask(blit.surface_type);
const GLenum filter = buffer_mask == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST;
glBlitFramebuffer(blit.src_region.start.x, blit.src_region.start.y,
blit.src_region.end.x, blit.src_region.end.y,
blit.dst_region.start.x, blit.dst_region.start.y,
blit.dst_region.end.x, blit.dst_region.end.y,
glBlitFramebuffer(blit.src_rect.left, blit.src_rect.bottom, blit.src_rect.right, blit.src_rect.top,
blit.dst_rect.left, blit.dst_rect.bottom, blit.dst_rect.right, blit.dst_rect.top,
buffer_mask, filter);
return true;
@ -354,11 +350,11 @@ void CachedSurface::UploadTexture(Common::Rectangle<u32> rect, const StagingBuff
target_tex = unscaled_tex.handle;
}
OpenGLState cur_state = OpenGLState::GetCurState();
OpenGLState prev_state = OpenGLState::GetCurState();
SCOPE_EXIT({ prev_state.Apply(); });
GLuint old_tex = cur_state.texture_units[0].texture_2d;
cur_state.texture_units[0].texture_2d = target_tex;
cur_state.Apply();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, target_tex);
// Ensure no bad interactions with GL_UNPACK_ALIGNMENT
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
@ -366,18 +362,13 @@ void CachedSurface::UploadTexture(Common::Rectangle<u32> rect, const StagingBuff
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, staging.buffer.handle);
glActiveTexture(GL_TEXTURE0);
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
reinterpret_cast<void*>(buffer_offset));
// Lock the staging buffer until glTexSubImage completes
staging.Lock();
cur_state.texture_units[0].texture_2d = old_tex;
cur_state.Apply();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@ -416,6 +407,7 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
MICROPROFILE_SCOPE(RasterizerCache_TextureDL);
const FormatTuple& tuple = runtime.GetFormatTuple(pixel_format);
const u32 buffer_offset = (rect.bottom * stride + rect.left) * GetBytesPerPixel(pixel_format);
OpenGLState state = OpenGLState::GetCurState();
OpenGLState prev_state = state;
@ -425,7 +417,6 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(stride));
glBindBuffer(GL_PIXEL_PACK_BUFFER, staging.buffer.handle);
const u32 buffer_offset = (rect.bottom * stride + rect.left) * GetBytesPerPixel(pixel_format);
// If not 1x scale, blit scaled texture to a new 1x texture and use that to flush
if (res_scale != 1) {
@ -441,14 +432,8 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
.surface_type = type,
.src_level = 0,
.dst_level = 0,
.src_region = VideoCore::Region2D{
.start = {scaled_rect.left, scaled_rect.bottom},
.end = {scaled_rect.right, scaled_rect.top}
},
.dst_region = VideoCore::Region2D{
.start = {0, 0},
.end = {rect.GetWidth(), rect.GetHeight()}
}
.src_rect = scaled_rect,
.dst_rect = VideoCore::Rect2D{0, rect.GetHeight(), rect.GetWidth(), 0}
};
// Blit scaled texture to the unscaled one
@ -475,9 +460,8 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
.buffer_row_length = stride,
.buffer_height = height,
.surface_type = type,
.texture_level = 0,
.texture_offset = {rect.bottom, rect.left},
.texture_extent = {rect.GetWidth(), rect.GetHeight()}
.texture_rect = rect,
.texture_level = 0
};
runtime.ReadTexture(texture, texture_download, pixel_format);
@ -487,4 +471,8 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
}
void CachedSurface::Scale() {
}
} // namespace OpenGL

View File

@ -112,6 +112,10 @@ public:
/// Downloads pixel data to staging from a rectangle region of the surface texture
void DownloadTexture(Common::Rectangle<u32> rect, const StagingBuffer& staging);
private:
/// Replaces the current texture with a scaled version according to res_scale
void Scale();
private:
TextureRuntime& runtime;