diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/fermi_2d.cpp | 54 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.h | 5 |
2 files changed, 59 insertions, 0 deletions
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 87634da21..9019f2504 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -2,7 +2,9 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/memory.h" | ||
| 5 | #include "video_core/engines/fermi_2d.h" | 6 | #include "video_core/engines/fermi_2d.h" |
| 7 | #include "video_core/textures/decoders.h" | ||
| 6 | 8 | ||
| 7 | namespace Tegra { | 9 | namespace Tegra { |
| 8 | namespace Engines { | 10 | namespace Engines { |
| @@ -12,6 +14,58 @@ Fermi2D::Fermi2D(MemoryManager& memory_manager) : memory_manager(memory_manager) | |||
| 12 | void Fermi2D::WriteReg(u32 method, u32 value) { | 14 | void Fermi2D::WriteReg(u32 method, u32 value) { |
| 13 | ASSERT_MSG(method < Regs::NUM_REGS, | 15 | ASSERT_MSG(method < Regs::NUM_REGS, |
| 14 | "Invalid Fermi2D register, increase the size of the Regs structure"); | 16 | "Invalid Fermi2D register, increase the size of the Regs structure"); |
| 17 | |||
| 18 | regs.reg_array[method] = value; | ||
| 19 | |||
| 20 | switch (method) { | ||
| 21 | case FERMI2D_REG_INDEX(trigger): { | ||
| 22 | HandleSurfaceCopy(); | ||
| 23 | break; | ||
| 24 | } | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | void Fermi2D::HandleSurfaceCopy() { | ||
| 29 | NGLOG_WARNING(HW_GPU, "Requested a surface copy with operation {}", | ||
| 30 | static_cast<u32>(regs.operation)); | ||
| 31 | |||
| 32 | const GPUVAddr source = regs.src.Address(); | ||
| 33 | const GPUVAddr dest = regs.dst.Address(); | ||
| 34 | |||
| 35 | // TODO(Subv): Only same-format and same-size copies are allowed for now. | ||
| 36 | ASSERT(regs.src.format == regs.dst.format); | ||
| 37 | ASSERT(regs.src.width * regs.src.height == regs.dst.width * regs.dst.height); | ||
| 38 | |||
| 39 | // TODO(Subv): Only raw copies are implemented. | ||
| 40 | ASSERT(regs.operation == Regs::Operation::SrcCopy); | ||
| 41 | |||
| 42 | const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source); | ||
| 43 | const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest); | ||
| 44 | |||
| 45 | u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format); | ||
| 46 | u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format); | ||
| 47 | |||
| 48 | if (regs.src.linear == regs.dst.linear) { | ||
| 49 | // If the input layout and the output layout are the same, just perform a raw copy. | ||
| 50 | Memory::CopyBlock(dest_cpu, source_cpu, | ||
| 51 | src_bytes_per_pixel * regs.dst.width * regs.dst.height); | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | |||
| 55 | u8* src_buffer = Memory::GetPointer(source_cpu); | ||
| 56 | u8* dst_buffer = Memory::GetPointer(dest_cpu); | ||
| 57 | |||
| 58 | if (!regs.src.linear && regs.dst.linear) { | ||
| 59 | // If the input is tiled and the output is linear, deswizzle the input and copy it over. | ||
| 60 | Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel, | ||
| 61 | dst_bytes_per_pixel, src_buffer, dst_buffer, true, | ||
| 62 | regs.src.block_height); | ||
| 63 | } else { | ||
| 64 | // If the input is linear and the output is tiled, swizzle the input and copy it over. | ||
| 65 | Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel, | ||
| 66 | dst_bytes_per_pixel, dst_buffer, src_buffer, false, | ||
| 67 | regs.dst.block_height); | ||
| 68 | } | ||
| 15 | } | 69 | } |
| 16 | 70 | ||
| 17 | } // namespace Engines | 71 | } // namespace Engines |
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 78d06218f..0c5b413cc 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -88,6 +88,11 @@ public: | |||
| 88 | } regs{}; | 88 | } regs{}; |
| 89 | 89 | ||
| 90 | MemoryManager& memory_manager; | 90 | MemoryManager& memory_manager; |
| 91 | |||
| 92 | private: | ||
| 93 | /// Performs the copy from the source surface to the destination surface as configured in the | ||
| 94 | /// registers. | ||
| 95 | void HandleSurfaceCopy(); | ||
| 91 | }; | 96 | }; |
| 92 | 97 | ||
| 93 | #define ASSERT_REG_POSITION(field_name, position) \ | 98 | #define ASSERT_REG_POSITION(field_name, position) \ |