summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/rasterizer_interface.h11
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp42
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h9
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
619bool RasterizerOpenGL::AccelerateDisplayTransfer(const void* config) { 619bool 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
625bool 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
146static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ 168static 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
1070void 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
1048Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, 1090Surface 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
840private: 849private:
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);