From f63653a5b919e81b3346f92ad77b704f59f5ff7c Mon Sep 17 00:00:00 2001 From: emufan4568 Date: Mon, 12 Sep 2022 20:24:15 +0300 Subject: [PATCH] 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 --- src/common/math_util.h | 18 ++++-- .../rasterizer_cache/rasterizer_cache.h | 63 +++++-------------- .../rasterizer_cache/surface_base.h | 4 +- src/video_core/rasterizer_cache/types.h | 27 +++----- .../renderer_opengl/gl_texture_runtime.cpp | 58 +++++++---------- .../renderer_opengl/gl_texture_runtime.h | 4 ++ 6 files changed, 63 insertions(+), 111 deletions(-) diff --git a/src/common/math_util.h b/src/common/math_util.h index d7cb94a82..3c7e7642d 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h @@ -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>(right - left)); } - [[nodiscard]] T GetHeight() const { + [[nodiscard]] constexpr T GetHeight() const { return std::abs(static_cast>(bottom - top)); } - [[nodiscard]] Rectangle TranslateX(const T x) const { + [[nodiscard]] constexpr Rectangle TranslateX(const T x) const { return Rectangle{left + x, top, right + x, bottom}; } - [[nodiscard]] Rectangle TranslateY(const T y) const { + [[nodiscard]] constexpr Rectangle TranslateY(const T y) const { return Rectangle{left, top + y, right, bottom + y}; } - [[nodiscard]] Rectangle Scale(const float s) const { + [[nodiscard]] constexpr Rectangle Scale(const float s) const { return Rectangle{left, top, static_cast(left + GetWidth() * s), static_cast(top + GetHeight() * s)}; } diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.h b/src/video_core/rasterizer_cache/rasterizer_cache.h index 35154e80e..35126640c 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache.h @@ -47,10 +47,10 @@ class RasterizerCache : NonCopyable { public: using TextureRuntime = typename T::Runtime; using CachedSurface = typename T::Surface; - using Watcher = SurfaceWatcher; /// Declare rasterizer interval types using Surface = std::shared_ptr; + using Watcher = SurfaceWatcher; using SurfaceSet = std::set; using SurfaceMap = boost::icl::interval_map RasterizerCache::RasterizerCache(VideoCore::RasterizerAccelerated& rasterizer, TextureRuntime& runtime) - : rasterizer(rasterizer), runtime{runtime} { + : rasterizer{rasterizer}, runtime{runtime} { resolution_scale_factor = VideoCore::GetResolutionScaleFactor(); } template template auto RasterizerCache::FindMatch(const SurfaceCache& surface_cache, const SurfaceParams& params, - ScaleMatch match_scale_type, - std::optional validate_interval) -> Surface { + ScaleMatch match_scale_type, + std::optional validate_interval) -> Surface { Surface match_surface = nullptr; bool match_valid = false; u32 match_scale = 0; @@ -273,14 +273,8 @@ bool RasterizerCache::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::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::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::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::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::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::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(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); diff --git a/src/video_core/rasterizer_cache/surface_base.h b/src/video_core/rasterizer_cache/surface_base.h index afe629e98..27336354c 100644 --- a/src/video_core/rasterizer_cache/surface_base.h +++ b/src/video_core/rasterizer_cache/surface_base.h @@ -180,8 +180,8 @@ SurfaceInterval SurfaceBase::GetCopyableInterval(const SurfaceParams& params) template auto SurfaceBase::CreateWatcher() -> std::shared_ptr { - S* derived = reinterpret_cast(this); - auto watcher = std::make_shared(std::move(derived->weak_from_this())); + auto weak_ptr = reinterpret_cast(this)->weak_from_this(); + auto watcher = std::make_shared(std::move(weak_ptr)); watchers[watcher_count++] = watcher; return watcher; } diff --git a/src/video_core/rasterizer_cache/types.h b/src/video_core/rasterizer_cache/types.h index 60b8ca025..6938b4c71 100644 --- a/src/video_core/rasterizer_cache/types.h +++ b/src/video_core/rasterizer_cache/types.h @@ -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; + 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 { diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.cpp b/src/video_core/renderer_opengl/gl_texture_runtime.cpp index 2c731982f..d21a0bd14 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.cpp +++ b/src/video_core/renderer_opengl/gl_texture_runtime.cpp @@ -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(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(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 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 rect, const StagingBuff glBindBuffer(GL_PIXEL_UNPACK_BUFFER, staging.buffer.handle); - glActiveTexture(GL_TEXTURE0); glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), tuple.format, tuple.type, reinterpret_cast(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 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 rect, const StagingBu ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0); glPixelStorei(GL_PACK_ROW_LENGTH, static_cast(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 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 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 rect, const StagingBu glPixelStorei(GL_PACK_ROW_LENGTH, 0); } +void CachedSurface::Scale() { + +} + } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.h b/src/video_core/renderer_opengl/gl_texture_runtime.h index 7eaf5efa4..846267883 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.h +++ b/src/video_core/renderer_opengl/gl_texture_runtime.h @@ -112,6 +112,10 @@ public: /// Downloads pixel data to staging from a rectangle region of the surface texture void DownloadTexture(Common::Rectangle rect, const StagingBuffer& staging); +private: + /// Replaces the current texture with a scaled version according to res_scale + void Scale(); + private: TextureRuntime& runtime;