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:
@ -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)};
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user