summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/command_processor.cpp4
-rw-r--r--src/video_core/engines/kepler_memory.cpp45
-rw-r--r--src/video_core/engines/kepler_memory.h90
-rw-r--r--src/video_core/gpu.cpp2
-rw-r--r--src/video_core/gpu.h3
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
9namespace Tegra::Engines {
10
11KeplerMemory::KeplerMemory(MemoryManager& memory_manager) : memory_manager(memory_manager) {}
12KeplerMemory::~KeplerMemory() = default;
13
14void 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
32void 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
14namespace Tegra::Engines {
15
16#define KEPLERMEMORY_REG_INDEX(field_name) \
17 (offsetof(Tegra::Engines::KeplerMemory::Regs, field_name) / sizeof(u32))
18
19class KeplerMemory final {
20public:
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
73private:
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
83ASSERT_REG_POSITION(line_length_in, 0x60);
84ASSERT_REG_POSITION(line_count, 0x61);
85ASSERT_REG_POSITION(dest, 0x62);
86ASSERT_REG_POSITION(exec, 0x6C);
87ASSERT_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
32GPU::~GPU() = default; 34GPU::~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;
102class Maxwell3D; 102class Maxwell3D;
103class MaxwellCompute; 103class MaxwellCompute;
104class MaxwellDMA; 104class MaxwellDMA;
105class KeplerMemory;
105} // namespace Engines 106} // namespace Engines
106 107
107enum class EngineID { 108enum 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