Преглед изворни кода

fermi_2d: Implement simple copies with AccelerateSurfaceCopy.

bunnei пре 7 година
родитељ
комит
9aec85d39c
3 измењених фајлова са 36 додато и 24 уклоњено
  1. 28 22
      src/video_core/engines/fermi_2d.cpp
  2. 7 1
      src/video_core/engines/fermi_2d.h
  3. 1 1
      src/video_core/gpu.cpp

+ 28 - 22
src/video_core/engines/fermi_2d.cpp

@@ -4,11 +4,13 @@
 
 #include "core/memory.h"
 #include "video_core/engines/fermi_2d.h"
+#include "video_core/rasterizer_interface.h"
 #include "video_core/textures/decoders.h"
 
 namespace Tegra::Engines {
 
-Fermi2D::Fermi2D(MemoryManager& memory_manager) : memory_manager(memory_manager) {}
+Fermi2D::Fermi2D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager)
+    : memory_manager(memory_manager), rasterizer{rasterizer} {}
 
 void Fermi2D::WriteReg(u32 method, u32 value) {
     ASSERT_MSG(method < Regs::NUM_REGS,
@@ -44,27 +46,31 @@ void Fermi2D::HandleSurfaceCopy() {
     u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format);
     u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format);
 
-    if (regs.src.linear == regs.dst.linear) {
-        // If the input layout and the output layout are the same, just perform a raw copy.
-        ASSERT(regs.src.BlockHeight() == regs.dst.BlockHeight());
-        Memory::CopyBlock(dest_cpu, source_cpu,
-                          src_bytes_per_pixel * regs.dst.width * regs.dst.height);
-        return;
-    }
-
-    u8* src_buffer = Memory::GetPointer(source_cpu);
-    u8* dst_buffer = Memory::GetPointer(dest_cpu);
-
-    if (!regs.src.linear && regs.dst.linear) {
-        // If the input is tiled and the output is linear, deswizzle the input and copy it over.
-        Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel,
-                                  dst_bytes_per_pixel, src_buffer, dst_buffer, true,
-                                  regs.src.BlockHeight());
-    } else {
-        // If the input is linear and the output is tiled, swizzle the input and copy it over.
-        Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel,
-                                  dst_bytes_per_pixel, dst_buffer, src_buffer, false,
-                                  regs.dst.BlockHeight());
+    if (!rasterizer.AccelerateSurfaceCopy(regs.src, regs.dst)) {
+        // TODO(bunnei): The below implementation currently will not get hit, as
+        // AccelerateSurfaceCopy tries to always copy and will always return success. This should be
+        // changed once we properly support flushing.
+
+        if (regs.src.linear == regs.dst.linear) {
+            // If the input layout and the output layout are the same, just perform a raw copy.
+            ASSERT(regs.src.BlockHeight() == regs.dst.BlockHeight());
+            Memory::CopyBlock(dest_cpu, source_cpu,
+                              src_bytes_per_pixel * regs.dst.width * regs.dst.height);
+            return;
+        }
+        u8* src_buffer = Memory::GetPointer(source_cpu);
+        u8* dst_buffer = Memory::GetPointer(dest_cpu);
+        if (!regs.src.linear && regs.dst.linear) {
+            // If the input is tiled and the output is linear, deswizzle the input and copy it over.
+            Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel,
+                                      dst_bytes_per_pixel, src_buffer, dst_buffer, true,
+                                      regs.src.BlockHeight());
+        } else {
+            // If the input is linear and the output is tiled, swizzle the input and copy it over.
+            Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel,
+                                      dst_bytes_per_pixel, dst_buffer, src_buffer, false,
+                                      regs.dst.BlockHeight());
+        }
     }
 }
 

+ 7 - 1
src/video_core/engines/fermi_2d.h

@@ -12,6 +12,10 @@
 #include "video_core/gpu.h"
 #include "video_core/memory_manager.h"
 
+namespace VideoCore {
+class RasterizerInterface;
+}
+
 namespace Tegra::Engines {
 
 #define FERMI2D_REG_INDEX(field_name)                                                              \
@@ -19,7 +23,7 @@ namespace Tegra::Engines {
 
 class Fermi2D final {
 public:
-    explicit Fermi2D(MemoryManager& memory_manager);
+    explicit Fermi2D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager);
     ~Fermi2D() = default;
 
     /// Write the value to the register identified by method.
@@ -94,6 +98,8 @@ public:
     MemoryManager& memory_manager;
 
 private:
+    VideoCore::RasterizerInterface& rasterizer;
+
     /// Performs the copy from the source surface to the destination surface as configured in the
     /// registers.
     void HandleSurfaceCopy();

+ 1 - 1
src/video_core/gpu.cpp

@@ -25,7 +25,7 @@ u32 FramebufferConfig::BytesPerPixel(PixelFormat format) {
 GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
     memory_manager = std::make_unique<Tegra::MemoryManager>();
     maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
-    fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager);
+    fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager);
     maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
     maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager);
     kepler_memory = std::make_unique<Engines::KeplerMemory>(*memory_manager);