diff options
| -rw-r--r-- | src/video_core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/video_core/command_processor.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.cpp | 45 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.h | 90 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 3 |
6 files changed, 146 insertions, 0 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 65b5f57c3..4a79ce39c 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -5,6 +5,8 @@ add_library(video_core STATIC | |||
| 5 | debug_utils/debug_utils.h | 5 | debug_utils/debug_utils.h |
| 6 | engines/fermi_2d.cpp | 6 | engines/fermi_2d.cpp |
| 7 | engines/fermi_2d.h | 7 | engines/fermi_2d.h |
| 8 | engines/kepler_memory.cpp | ||
| 9 | engines/kepler_memory.h | ||
| 8 | engines/maxwell_3d.cpp | 10 | engines/maxwell_3d.cpp |
| 9 | engines/maxwell_3d.h | 11 | engines/maxwell_3d.h |
| 10 | engines/maxwell_compute.cpp | 12 | engines/maxwell_compute.cpp |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 2625ddfdc..f1aa6091b 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "core/tracer/recorder.h" | 14 | #include "core/tracer/recorder.h" |
| 15 | #include "video_core/command_processor.h" | 15 | #include "video_core/command_processor.h" |
| 16 | #include "video_core/engines/fermi_2d.h" | 16 | #include "video_core/engines/fermi_2d.h" |
| 17 | #include "video_core/engines/kepler_memory.h" | ||
| 17 | #include "video_core/engines/maxwell_3d.h" | 18 | #include "video_core/engines/maxwell_3d.h" |
| 18 | #include "video_core/engines/maxwell_compute.h" | 19 | #include "video_core/engines/maxwell_compute.h" |
| 19 | #include "video_core/engines/maxwell_dma.h" | 20 | #include "video_core/engines/maxwell_dma.h" |
| @@ -69,6 +70,9 @@ void GPU::ProcessCommandLists(const std::vector<CommandListHeader>& commands) { | |||
| 69 | case EngineID::MAXWELL_DMA_COPY_A: | 70 | case EngineID::MAXWELL_DMA_COPY_A: |
| 70 | maxwell_dma->WriteReg(method, value); | 71 | maxwell_dma->WriteReg(method, value); |
| 71 | break; | 72 | break; |
| 73 | case EngineID::KEPLER_INLINE_TO_MEMORY_B: | ||
| 74 | kepler_memory->WriteReg(method, value); | ||
| 75 | break; | ||
| 72 | default: | 76 | default: |
| 73 | UNIMPLEMENTED_MSG("Unimplemented engine"); | 77 | UNIMPLEMENTED_MSG("Unimplemented engine"); |
| 74 | } | 78 | } |
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp new file mode 100644 index 000000000..66ae6332d --- /dev/null +++ b/src/video_core/engines/kepler_memory.cpp | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "core/memory.h" | ||
| 7 | #include "video_core/engines/kepler_memory.h" | ||
| 8 | |||
| 9 | namespace Tegra::Engines { | ||
| 10 | |||
| 11 | KeplerMemory::KeplerMemory(MemoryManager& memory_manager) : memory_manager(memory_manager) {} | ||
| 12 | KeplerMemory::~KeplerMemory() = default; | ||
| 13 | |||
| 14 | void KeplerMemory::WriteReg(u32 method, u32 value) { | ||
| 15 | ASSERT_MSG(method < Regs::NUM_REGS, | ||
| 16 | "Invalid KeplerMemory register, increase the size of the Regs structure"); | ||
| 17 | |||
| 18 | regs.reg_array[method] = value; | ||
| 19 | |||
| 20 | switch (method) { | ||
| 21 | case KEPLERMEMORY_REG_INDEX(exec): { | ||
| 22 | state.write_offset = 0; | ||
| 23 | break; | ||
| 24 | } | ||
| 25 | case KEPLERMEMORY_REG_INDEX(data): { | ||
| 26 | ProcessData(value); | ||
| 27 | break; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | void KeplerMemory::ProcessData(u32 data) { | ||
| 33 | ASSERT_MSG(regs.exec.linear, "Non-linear uploads are not supported"); | ||
| 34 | ASSERT(regs.dest.x == 0 && regs.dest.y == 0 && regs.dest.z == 0); | ||
| 35 | |||
| 36 | GPUVAddr address = regs.dest.Address(); | ||
| 37 | VAddr dest_address = | ||
| 38 | *memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32)); | ||
| 39 | |||
| 40 | Memory::Write32(dest_address, data); | ||
| 41 | |||
| 42 | state.write_offset++; | ||
| 43 | } | ||
| 44 | |||
| 45 | } // namespace Tegra::Engines | ||
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h new file mode 100644 index 000000000..b0d0078cf --- /dev/null +++ b/src/video_core/engines/kepler_memory.h | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include "common/assert.h" | ||
| 9 | #include "common/bit_field.h" | ||
| 10 | #include "common/common_funcs.h" | ||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "video_core/memory_manager.h" | ||
| 13 | |||
| 14 | namespace Tegra::Engines { | ||
| 15 | |||
| 16 | #define KEPLERMEMORY_REG_INDEX(field_name) \ | ||
| 17 | (offsetof(Tegra::Engines::KeplerMemory::Regs, field_name) / sizeof(u32)) | ||
| 18 | |||
| 19 | class KeplerMemory final { | ||
| 20 | public: | ||
| 21 | KeplerMemory(MemoryManager& memory_manager); | ||
| 22 | ~KeplerMemory(); | ||
| 23 | |||
| 24 | /// Write the value to the register identified by method. | ||
| 25 | void WriteReg(u32 method, u32 value); | ||
| 26 | |||
| 27 | struct Regs { | ||
| 28 | static constexpr size_t NUM_REGS = 0x7F; | ||
| 29 | |||
| 30 | union { | ||
| 31 | struct { | ||
| 32 | INSERT_PADDING_WORDS(0x60); | ||
| 33 | |||
| 34 | u32 line_length_in; | ||
| 35 | u32 line_count; | ||
| 36 | |||
| 37 | struct { | ||
| 38 | u32 address_high; | ||
| 39 | u32 address_low; | ||
| 40 | u32 pitch; | ||
| 41 | u32 block_dimensions; | ||
| 42 | u32 width; | ||
| 43 | u32 height; | ||
| 44 | u32 depth; | ||
| 45 | u32 z; | ||
| 46 | u32 x; | ||
| 47 | u32 y; | ||
| 48 | |||
| 49 | GPUVAddr Address() const { | ||
| 50 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 51 | address_low); | ||
| 52 | } | ||
| 53 | } dest; | ||
| 54 | |||
| 55 | struct { | ||
| 56 | union { | ||
| 57 | BitField<0, 1, u32> linear; | ||
| 58 | }; | ||
| 59 | } exec; | ||
| 60 | |||
| 61 | u32 data; | ||
| 62 | |||
| 63 | INSERT_PADDING_WORDS(0x11); | ||
| 64 | }; | ||
| 65 | std::array<u32, NUM_REGS> reg_array; | ||
| 66 | }; | ||
| 67 | } regs{}; | ||
| 68 | |||
| 69 | struct { | ||
| 70 | u32 write_offset = 0; | ||
| 71 | } state{}; | ||
| 72 | |||
| 73 | private: | ||
| 74 | MemoryManager& memory_manager; | ||
| 75 | |||
| 76 | void ProcessData(u32 data); | ||
| 77 | }; | ||
| 78 | |||
| 79 | #define ASSERT_REG_POSITION(field_name, position) \ | ||
| 80 | static_assert(offsetof(KeplerMemory::Regs, field_name) == position * 4, \ | ||
| 81 | "Field " #field_name " has invalid position") | ||
| 82 | |||
| 83 | ASSERT_REG_POSITION(line_length_in, 0x60); | ||
| 84 | ASSERT_REG_POSITION(line_count, 0x61); | ||
| 85 | ASSERT_REG_POSITION(dest, 0x62); | ||
| 86 | ASSERT_REG_POSITION(exec, 0x6C); | ||
| 87 | ASSERT_REG_POSITION(data, 0x6D); | ||
| 88 | #undef ASSERT_REG_POSITION | ||
| 89 | |||
| 90 | } // namespace Tegra::Engines | ||
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 86a809f86..baa8b63b7 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/assert.h" | 5 | #include "common/assert.h" |
| 6 | #include "video_core/engines/fermi_2d.h" | 6 | #include "video_core/engines/fermi_2d.h" |
| 7 | #include "video_core/engines/kepler_memory.h" | ||
| 7 | #include "video_core/engines/maxwell_3d.h" | 8 | #include "video_core/engines/maxwell_3d.h" |
| 8 | #include "video_core/engines/maxwell_compute.h" | 9 | #include "video_core/engines/maxwell_compute.h" |
| 9 | #include "video_core/engines/maxwell_dma.h" | 10 | #include "video_core/engines/maxwell_dma.h" |
| @@ -27,6 +28,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) { | |||
| 27 | fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); | 28 | fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); |
| 28 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); | 29 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); |
| 29 | maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); | 30 | maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); |
| 31 | kepler_memory = std::make_unique<Engines::KeplerMemory>(*memory_manager); | ||
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | GPU::~GPU() = default; | 34 | GPU::~GPU() = default; |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 589a59b4f..7329ca766 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -102,6 +102,7 @@ class Fermi2D; | |||
| 102 | class Maxwell3D; | 102 | class Maxwell3D; |
| 103 | class MaxwellCompute; | 103 | class MaxwellCompute; |
| 104 | class MaxwellDMA; | 104 | class MaxwellDMA; |
| 105 | class KeplerMemory; | ||
| 105 | } // namespace Engines | 106 | } // namespace Engines |
| 106 | 107 | ||
| 107 | enum class EngineID { | 108 | enum class EngineID { |
| @@ -146,6 +147,8 @@ private: | |||
| 146 | std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; | 147 | std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; |
| 147 | /// DMA engine | 148 | /// DMA engine |
| 148 | std::unique_ptr<Engines::MaxwellDMA> maxwell_dma; | 149 | std::unique_ptr<Engines::MaxwellDMA> maxwell_dma; |
| 150 | /// Inline memory engine | ||
| 151 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; | ||
| 149 | }; | 152 | }; |
| 150 | 153 | ||
| 151 | } // namespace Tegra | 154 | } // namespace Tegra |