diff options
| author | 2018-10-05 23:39:03 -0400 | |
|---|---|---|
| committer | 2018-10-06 03:20:04 -0400 | |
| commit | 011cf77796aee57c23e97876aad65712efd6c92b (patch) | |
| tree | 5cbed5aec5c9bb649bb068ddbf0d7189bd135085 | |
| parent | gl_rasterizer_cache: Implement a simpler surface copy using glCopyImageSubData. (diff) | |
| download | yuzu-011cf77796aee57c23e97876aad65712efd6c92b.tar.gz yuzu-011cf77796aee57c23e97876aad65712efd6c92b.tar.xz yuzu-011cf77796aee57c23e97876aad65712efd6c92b.zip | |
gl_rasterizer: Add rasterizer cache code to handle accerated fermi copies.
| -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 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "video_core/engines/fermi_2d.h" | ||
| 8 | #include "video_core/gpu.h" | 9 | #include "video_core/gpu.h" |
| 9 | #include "video_core/memory_manager.h" | 10 | #include "video_core/memory_manager.h" |
| 10 | 11 | ||
| @@ -33,13 +34,9 @@ public: | |||
| 33 | /// and invalidated | 34 | /// and invalidated |
| 34 | virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; | 35 | virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; |
| 35 | 36 | ||
| 36 | /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0 | 37 | /// Attempt to use a faster method to perform a surface copy |
| 37 | virtual bool AccelerateDisplayTransfer(const void* config) { | 38 | virtual bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, |
| 38 | return false; | 39 | const Tegra::Engines::Fermi2D::Regs::Surface& dst) { |
| 39 | } | ||
| 40 | |||
| 41 | /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 1 | ||
| 42 | virtual bool AccelerateTextureCopy(const void* config) { | ||
| 43 | return false; | 40 | return false; |
| 44 | } | 41 | } |
| 45 | 42 | ||
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) { | |||
| 616 | InvalidateRegion(addr, size); | 616 | InvalidateRegion(addr, size); |
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | bool RasterizerOpenGL::AccelerateDisplayTransfer(const void* config) { | 619 | bool RasterizerOpenGL::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, |
| 620 | const Tegra::Engines::Fermi2D::Regs::Surface& dst) { | ||
| 620 | MICROPROFILE_SCOPE(OpenGL_Blits); | 621 | MICROPROFILE_SCOPE(OpenGL_Blits); |
| 621 | UNREACHABLE(); | 622 | res_cache.FermiCopySurface(src, dst); |
| 622 | return true; | ||
| 623 | } | ||
| 624 | |||
| 625 | bool RasterizerOpenGL::AccelerateTextureCopy(const void* config) { | ||
| 626 | UNREACHABLE(); | ||
| 627 | return true; | 623 | return true; |
| 628 | } | 624 | } |
| 629 | 625 | ||
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: | |||
| 52 | void FlushRegion(VAddr addr, u64 size) override; | 52 | void FlushRegion(VAddr addr, u64 size) override; |
| 53 | void InvalidateRegion(VAddr addr, u64 size) override; | 53 | void InvalidateRegion(VAddr addr, u64 size) override; |
| 54 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | 54 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; |
| 55 | bool AccelerateDisplayTransfer(const void* config) override; | 55 | bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, |
| 56 | bool AccelerateTextureCopy(const void* config) override; | 56 | const Tegra::Engines::Fermi2D::Regs::Surface& dst) override; |
| 57 | bool AccelerateFill(const void* config) override; | 57 | bool AccelerateFill(const void* config) override; |
| 58 | bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, | 58 | bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, |
| 59 | u32 pixel_stride) override; | 59 | 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) { | |||
| 143 | return params; | 143 | return params; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | /*static*/ SurfaceParams SurfaceParams::CreateForFermiCopySurface( | ||
| 147 | const Tegra::Engines::Fermi2D::Regs::Surface& config) { | ||
| 148 | SurfaceParams params{}; | ||
| 149 | params.addr = TryGetCpuAddr(config.Address()); | ||
| 150 | params.is_tiled = !config.linear; | ||
| 151 | params.block_height = params.is_tiled ? config.BlockHeight() : 0, | ||
| 152 | params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); | ||
| 153 | params.component_type = ComponentTypeFromRenderTarget(config.format); | ||
| 154 | params.type = GetFormatType(params.pixel_format); | ||
| 155 | params.width = config.width; | ||
| 156 | params.height = config.height; | ||
| 157 | params.unaligned_height = config.height; | ||
| 158 | params.target = SurfaceTarget::Texture2D; | ||
| 159 | params.depth = 1; | ||
| 160 | params.size_in_bytes_total = params.SizeInBytesTotal(); | ||
| 161 | params.size_in_bytes_2d = params.SizeInBytes2D(); | ||
| 162 | params.max_mip_level = 0; | ||
| 163 | params.rt = {}; | ||
| 164 | |||
| 165 | return params; | ||
| 166 | } | ||
| 167 | |||
| 146 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | 168 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ |
| 147 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U | 169 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U |
| 148 | {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S | 170 | {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S |
| @@ -1045,6 +1067,26 @@ Surface RasterizerCacheOpenGL::GetUncachedSurface(const SurfaceParams& params) { | |||
| 1045 | return surface; | 1067 | return surface; |
| 1046 | } | 1068 | } |
| 1047 | 1069 | ||
| 1070 | void RasterizerCacheOpenGL::FermiCopySurface( | ||
| 1071 | const Tegra::Engines::Fermi2D::Regs::Surface& src_config, | ||
| 1072 | const Tegra::Engines::Fermi2D::Regs::Surface& dst_config) { | ||
| 1073 | |||
| 1074 | const auto& src_params = SurfaceParams::CreateForFermiCopySurface(src_config); | ||
| 1075 | const auto& dst_params = SurfaceParams::CreateForFermiCopySurface(dst_config); | ||
| 1076 | |||
| 1077 | ASSERT(src_params.width == dst_params.width); | ||
| 1078 | ASSERT(src_params.height == dst_params.height); | ||
| 1079 | ASSERT(src_params.pixel_format == dst_params.pixel_format); | ||
| 1080 | ASSERT(src_params.block_height == dst_params.block_height); | ||
| 1081 | ASSERT(src_params.is_tiled == dst_params.is_tiled); | ||
| 1082 | ASSERT(src_params.depth == dst_params.depth); | ||
| 1083 | ASSERT(src_params.depth == 1); // Currently, FastCopySurface only works with 2D surfaces | ||
| 1084 | ASSERT(src_params.target == dst_params.target); | ||
| 1085 | ASSERT(src_params.rt.index == dst_params.rt.index); | ||
| 1086 | |||
| 1087 | FastCopySurface(GetSurface(src_params, true), GetSurface(dst_params, false)); | ||
| 1088 | } | ||
| 1089 | |||
| 1048 | Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, | 1090 | Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, |
| 1049 | const SurfaceParams& new_params) { | 1091 | const SurfaceParams& new_params) { |
| 1050 | // Verify surface is compatible for blitting | 1092 | // 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 @@ | |||
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "common/hash.h" | 14 | #include "common/hash.h" |
| 15 | #include "common/math_util.h" | 15 | #include "common/math_util.h" |
| 16 | #include "video_core/engines/fermi_2d.h" | ||
| 16 | #include "video_core/engines/maxwell_3d.h" | 17 | #include "video_core/engines/maxwell_3d.h" |
| 17 | #include "video_core/rasterizer_cache.h" | 18 | #include "video_core/rasterizer_cache.h" |
| 18 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 19 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| @@ -719,6 +720,10 @@ struct SurfaceParams { | |||
| 719 | Tegra::GPUVAddr zeta_address, | 720 | Tegra::GPUVAddr zeta_address, |
| 720 | Tegra::DepthFormat format); | 721 | Tegra::DepthFormat format); |
| 721 | 722 | ||
| 723 | /// Creates SurfaceParams for a Fermi2D surface copy | ||
| 724 | static SurfaceParams CreateForFermiCopySurface( | ||
| 725 | const Tegra::Engines::Fermi2D::Regs::Surface& config); | ||
| 726 | |||
| 722 | /// Checks if surfaces are compatible for caching | 727 | /// Checks if surfaces are compatible for caching |
| 723 | bool IsCompatibleSurface(const SurfaceParams& other) const { | 728 | bool IsCompatibleSurface(const SurfaceParams& other) const { |
| 724 | return std::tie(pixel_format, type, width, height, target, depth) == | 729 | return std::tie(pixel_format, type, width, height, target, depth) == |
| @@ -837,6 +842,10 @@ public: | |||
| 837 | /// Tries to find a framebuffer using on the provided CPU address | 842 | /// Tries to find a framebuffer using on the provided CPU address |
| 838 | Surface TryFindFramebufferSurface(VAddr addr) const; | 843 | Surface TryFindFramebufferSurface(VAddr addr) const; |
| 839 | 844 | ||
| 845 | /// Copies the contents of one surface to another | ||
| 846 | void FermiCopySurface(const Tegra::Engines::Fermi2D::Regs::Surface& src_config, | ||
| 847 | const Tegra::Engines::Fermi2D::Regs::Surface& dst_config); | ||
| 848 | |||
| 840 | private: | 849 | private: |
| 841 | void LoadSurface(const Surface& surface); | 850 | void LoadSurface(const Surface& surface); |
| 842 | Surface GetSurface(const SurfaceParams& params, bool preserve_contents = true); | 851 | Surface GetSurface(const SurfaceParams& params, bool preserve_contents = true); |