diff options
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 42 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 9 | 
5 files changed, 60 insertions, 16 deletions
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index cd819d69f..06fc59dbe 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -5,6 +5,7 @@  #pragma once  #include "common/common_types.h" +#include "video_core/engines/fermi_2d.h"  #include "video_core/gpu.h"  #include "video_core/memory_manager.h" @@ -33,13 +34,9 @@ public:      /// and invalidated      virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; -    /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0 -    virtual bool AccelerateDisplayTransfer(const void* config) { -        return false; -    } - -    /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 1 -    virtual bool AccelerateTextureCopy(const void* config) { +    /// Attempt to use a faster method to perform a surface copy +    virtual bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, +                                       const Tegra::Engines::Fermi2D::Regs::Surface& dst) {          return false;      } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 60dcdc184..a3a14efd9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -616,14 +616,10 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {      InvalidateRegion(addr, size);  } -bool RasterizerOpenGL::AccelerateDisplayTransfer(const void* config) { +bool RasterizerOpenGL::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, +                                             const Tegra::Engines::Fermi2D::Regs::Surface& dst) {      MICROPROFILE_SCOPE(OpenGL_Blits); -    UNREACHABLE(); -    return true; -} - -bool RasterizerOpenGL::AccelerateTextureCopy(const void* config) { -    UNREACHABLE(); +    res_cache.FermiCopySurface(src, dst);      return true;  } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index bf954bb5d..8b6b62241 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -52,8 +52,8 @@ public:      void FlushRegion(VAddr addr, u64 size) override;      void InvalidateRegion(VAddr addr, u64 size) override;      void FlushAndInvalidateRegion(VAddr addr, u64 size) override; -    bool AccelerateDisplayTransfer(const void* config) override; -    bool AccelerateTextureCopy(const void* config) override; +    bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, +                               const Tegra::Engines::Fermi2D::Regs::Surface& dst) override;      bool AccelerateFill(const void* config) override;      bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,                             u32 pixel_stride) override; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 5fe6befe1..56ff83eff 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -143,6 +143,28 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {      return params;  } +/*static*/ SurfaceParams SurfaceParams::CreateForFermiCopySurface( +    const Tegra::Engines::Fermi2D::Regs::Surface& config) { +    SurfaceParams params{}; +    params.addr = TryGetCpuAddr(config.Address()); +    params.is_tiled = !config.linear; +    params.block_height = params.is_tiled ? config.BlockHeight() : 0, +    params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); +    params.component_type = ComponentTypeFromRenderTarget(config.format); +    params.type = GetFormatType(params.pixel_format); +    params.width = config.width; +    params.height = config.height; +    params.unaligned_height = config.height; +    params.target = SurfaceTarget::Texture2D; +    params.depth = 1; +    params.size_in_bytes_total = params.SizeInBytesTotal(); +    params.size_in_bytes_2d = params.SizeInBytes2D(); +    params.max_mip_level = 0; +    params.rt = {}; + +    return params; +} +  static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{      {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U      {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false},                     // ABGR8S @@ -1045,6 +1067,26 @@ Surface RasterizerCacheOpenGL::GetUncachedSurface(const SurfaceParams& params) {      return surface;  } +void RasterizerCacheOpenGL::FermiCopySurface( +    const Tegra::Engines::Fermi2D::Regs::Surface& src_config, +    const Tegra::Engines::Fermi2D::Regs::Surface& dst_config) { + +    const auto& src_params = SurfaceParams::CreateForFermiCopySurface(src_config); +    const auto& dst_params = SurfaceParams::CreateForFermiCopySurface(dst_config); + +    ASSERT(src_params.width == dst_params.width); +    ASSERT(src_params.height == dst_params.height); +    ASSERT(src_params.pixel_format == dst_params.pixel_format); +    ASSERT(src_params.block_height == dst_params.block_height); +    ASSERT(src_params.is_tiled == dst_params.is_tiled); +    ASSERT(src_params.depth == dst_params.depth); +    ASSERT(src_params.depth == 1); // Currently, FastCopySurface only works with 2D surfaces +    ASSERT(src_params.target == dst_params.target); +    ASSERT(src_params.rt.index == dst_params.rt.index); + +    FastCopySurface(GetSurface(src_params, true), GetSurface(dst_params, false)); +} +  Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,                                                 const SurfaceParams& new_params) {      // Verify surface is compatible for blitting diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 49025a3fe..0b4940b3c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -13,6 +13,7 @@  #include "common/common_types.h"  #include "common/hash.h"  #include "common/math_util.h" +#include "video_core/engines/fermi_2d.h"  #include "video_core/engines/maxwell_3d.h"  #include "video_core/rasterizer_cache.h"  #include "video_core/renderer_opengl/gl_resource_manager.h" @@ -719,6 +720,10 @@ struct SurfaceParams {                                                Tegra::GPUVAddr zeta_address,                                                Tegra::DepthFormat format); +    /// Creates SurfaceParams for a Fermi2D surface copy +    static SurfaceParams CreateForFermiCopySurface( +        const Tegra::Engines::Fermi2D::Regs::Surface& config); +      /// Checks if surfaces are compatible for caching      bool IsCompatibleSurface(const SurfaceParams& other) const {          return std::tie(pixel_format, type, width, height, target, depth) == @@ -837,6 +842,10 @@ public:      /// Tries to find a framebuffer using on the provided CPU address      Surface TryFindFramebufferSurface(VAddr addr) const; +    /// Copies the contents of one surface to another +    void FermiCopySurface(const Tegra::Engines::Fermi2D::Regs::Surface& src_config, +                          const Tegra::Engines::Fermi2D::Regs::Surface& dst_config); +  private:      void LoadSurface(const Surface& surface);      Surface GetSurface(const SurfaceParams& params, bool preserve_contents = true);  | 
