summaryrefslogtreecommitdiff
path: root/src/video_core/engines
diff options
context:
space:
mode:
authorGravatar bunnei2018-11-23 23:20:56 -0500
committerGravatar bunnei2018-11-26 23:14:01 -0500
commitabea6fa90c901d0b47487ed38d44511b18f0addf (patch)
tree65ba9fc6ff7609ea569ea1e3d05f91caa56ffa14 /src/video_core/engines
parentMerge pull request #1805 from lioncash/resource (diff)
downloadyuzu-abea6fa90c901d0b47487ed38d44511b18f0addf.tar.gz
yuzu-abea6fa90c901d0b47487ed38d44511b18f0addf.tar.xz
yuzu-abea6fa90c901d0b47487ed38d44511b18f0addf.zip
gpu: Rewrite GPU command list processing with DmaPusher class.
- More accurate impl., fixes Undertale (among other games).
Diffstat (limited to 'src/video_core/engines')
-rw-r--r--src/video_core/engines/fermi_2d.cpp8
-rw-r--r--src/video_core/engines/fermi_2d.h2
-rw-r--r--src/video_core/engines/kepler_memory.cpp10
-rw-r--r--src/video_core/engines/kepler_memory.h3
-rw-r--r--src/video_core/engines/maxwell_3d.cpp53
-rw-r--r--src/video_core/engines/maxwell_3d.h2
-rw-r--r--src/video_core/engines/maxwell_compute.cpp8
-rw-r--r--src/video_core/engines/maxwell_compute.h3
-rw-r--r--src/video_core/engines/maxwell_dma.cpp8
-rw-r--r--src/video_core/engines/maxwell_dma.h2
10 files changed, 52 insertions, 47 deletions
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp
index 8d0700d13..dbea5bb5e 100644
--- a/src/video_core/engines/fermi_2d.cpp
+++ b/src/video_core/engines/fermi_2d.cpp
@@ -14,13 +14,13 @@ namespace Tegra::Engines {
14Fermi2D::Fermi2D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager) 14Fermi2D::Fermi2D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager)
15 : memory_manager(memory_manager), rasterizer{rasterizer} {} 15 : memory_manager(memory_manager), rasterizer{rasterizer} {}
16 16
17void Fermi2D::WriteReg(u32 method, u32 value) { 17void Fermi2D::CallMethod(const GPU::MethodCall& method_call) {
18 ASSERT_MSG(method < Regs::NUM_REGS, 18 ASSERT_MSG(method_call.method < Regs::NUM_REGS,
19 "Invalid Fermi2D register, increase the size of the Regs structure"); 19 "Invalid Fermi2D register, increase the size of the Regs structure");
20 20
21 regs.reg_array[method] = value; 21 regs.reg_array[method_call.method] = method_call.argument;
22 22
23 switch (method) { 23 switch (method_call.method) {
24 case FERMI2D_REG_INDEX(trigger): { 24 case FERMI2D_REG_INDEX(trigger): {
25 HandleSurfaceCopy(); 25 HandleSurfaceCopy();
26 break; 26 break;
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h
index 2a6e8bbbb..50009bf75 100644
--- a/src/video_core/engines/fermi_2d.h
+++ b/src/video_core/engines/fermi_2d.h
@@ -27,7 +27,7 @@ public:
27 ~Fermi2D() = default; 27 ~Fermi2D() = default;
28 28
29 /// Write the value to the register identified by method. 29 /// Write the value to the register identified by method.
30 void WriteReg(u32 method, u32 value); 30 void CallMethod(const GPU::MethodCall& method_call);
31 31
32 struct Regs { 32 struct Regs {
33 static constexpr std::size_t NUM_REGS = 0x258; 33 static constexpr std::size_t NUM_REGS = 0x258;
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp
index 2adbc9eaf..4880191fc 100644
--- a/src/video_core/engines/kepler_memory.cpp
+++ b/src/video_core/engines/kepler_memory.cpp
@@ -17,19 +17,19 @@ KeplerMemory::KeplerMemory(VideoCore::RasterizerInterface& rasterizer,
17 17
18KeplerMemory::~KeplerMemory() = default; 18KeplerMemory::~KeplerMemory() = default;
19 19
20void KeplerMemory::WriteReg(u32 method, u32 value) { 20void KeplerMemory::CallMethod(const GPU::MethodCall& method_call) {
21 ASSERT_MSG(method < Regs::NUM_REGS, 21 ASSERT_MSG(method_call.method < Regs::NUM_REGS,
22 "Invalid KeplerMemory register, increase the size of the Regs structure"); 22 "Invalid KeplerMemory register, increase the size of the Regs structure");
23 23
24 regs.reg_array[method] = value; 24 regs.reg_array[method_call.method] = method_call.argument;
25 25
26 switch (method) { 26 switch (method_call.method) {
27 case KEPLERMEMORY_REG_INDEX(exec): { 27 case KEPLERMEMORY_REG_INDEX(exec): {
28 state.write_offset = 0; 28 state.write_offset = 0;
29 break; 29 break;
30 } 30 }
31 case KEPLERMEMORY_REG_INDEX(data): { 31 case KEPLERMEMORY_REG_INDEX(data): {
32 ProcessData(value); 32 ProcessData(method_call.argument);
33 break; 33 break;
34 } 34 }
35 } 35 }
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h
index bf4a13cff..fe9ebc5b9 100644
--- a/src/video_core/engines/kepler_memory.h
+++ b/src/video_core/engines/kepler_memory.h
@@ -9,6 +9,7 @@
9#include "common/bit_field.h" 9#include "common/bit_field.h"
10#include "common/common_funcs.h" 10#include "common/common_funcs.h"
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "video_core/gpu.h"
12#include "video_core/memory_manager.h" 13#include "video_core/memory_manager.h"
13 14
14namespace VideoCore { 15namespace VideoCore {
@@ -26,7 +27,7 @@ public:
26 ~KeplerMemory(); 27 ~KeplerMemory();
27 28
28 /// Write the value to the register identified by method. 29 /// Write the value to the register identified by method.
29 void WriteReg(u32 method, u32 value); 30 void CallMethod(const GPU::MethodCall& method_call);
30 31
31 struct Regs { 32 struct Regs {
32 static constexpr size_t NUM_REGS = 0x7F; 33 static constexpr size_t NUM_REGS = 0x7F;
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index f0a5470b9..b19b3a75a 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -97,71 +97,74 @@ void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
97 macro_interpreter.Execute(search->second, std::move(parameters)); 97 macro_interpreter.Execute(search->second, std::move(parameters));
98} 98}
99 99
100void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { 100void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
101 auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); 101 auto debug_context = Core::System::GetInstance().GetGPUDebugContext();
102 102
103 // It is an error to write to a register other than the current macro's ARG register before it 103 // It is an error to write to a register other than the current macro's ARG register before it
104 // has finished execution. 104 // has finished execution.
105 if (executing_macro != 0) { 105 if (executing_macro != 0) {
106 ASSERT(method == executing_macro + 1); 106 ASSERT(method_call.method == executing_macro + 1);
107 } 107 }
108 108
109 // Methods after 0xE00 are special, they're actually triggers for some microcode that was 109 // Methods after 0xE00 are special, they're actually triggers for some microcode that was
110 // uploaded to the GPU during initialization. 110 // uploaded to the GPU during initialization.
111 if (method >= MacroRegistersStart) { 111 if (method_call.method >= MacroRegistersStart) {
112 // We're trying to execute a macro 112 // We're trying to execute a macro
113 if (executing_macro == 0) { 113 if (executing_macro == 0) {
114 // A macro call must begin by writing the macro method's register, not its argument. 114 // A macro call must begin by writing the macro method's register, not its argument.
115 ASSERT_MSG((method % 2) == 0, 115 ASSERT_MSG((method_call.method % 2) == 0,
116 "Can't start macro execution by writing to the ARGS register"); 116 "Can't start macro execution by writing to the ARGS register");
117 executing_macro = method; 117 executing_macro = method_call.method;
118 } 118 }
119 119
120 macro_params.push_back(value); 120 macro_params.push_back(method_call.argument);
121 121
122 // Call the macro when there are no more parameters in the command buffer 122 // Call the macro when there are no more parameters in the command buffer
123 if (remaining_params == 0) { 123 if (method_call.IsLastCall()) {
124 CallMacroMethod(executing_macro, std::move(macro_params)); 124 CallMacroMethod(executing_macro, std::move(macro_params));
125 } 125 }
126 return; 126 return;
127 } 127 }
128 128
129 ASSERT_MSG(method < Regs::NUM_REGS, 129 ASSERT_MSG(method_call.method < Regs::NUM_REGS,
130 "Invalid Maxwell3D register, increase the size of the Regs structure"); 130 "Invalid Maxwell3D register, increase the size of the Regs structure");
131 131
132 if (debug_context) { 132 if (debug_context) {
133 debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); 133 debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr);
134 } 134 }
135 135
136 if (regs.reg_array[method] != value) { 136 if (regs.reg_array[method_call.method] != method_call.argument) {
137 regs.reg_array[method] = value; 137 regs.reg_array[method_call.method] = method_call.argument;
138 // Vertex format 138 // Vertex format
139 if (method >= MAXWELL3D_REG_INDEX(vertex_attrib_format) && 139 if (method_call.method >= MAXWELL3D_REG_INDEX(vertex_attrib_format) &&
140 method < MAXWELL3D_REG_INDEX(vertex_attrib_format) + regs.vertex_attrib_format.size()) { 140 method_call.method <
141 MAXWELL3D_REG_INDEX(vertex_attrib_format) + regs.vertex_attrib_format.size()) {
141 dirty_flags.vertex_attrib_format = true; 142 dirty_flags.vertex_attrib_format = true;
142 } 143 }
143 144
144 // Vertex buffer 145 // Vertex buffer
145 if (method >= MAXWELL3D_REG_INDEX(vertex_array) && 146 if (method_call.method >= MAXWELL3D_REG_INDEX(vertex_array) &&
146 method < MAXWELL3D_REG_INDEX(vertex_array) + 4 * 32) { 147 method_call.method < MAXWELL3D_REG_INDEX(vertex_array) + 4 * 32) {
147 dirty_flags.vertex_array |= 1u << ((method - MAXWELL3D_REG_INDEX(vertex_array)) >> 2);
148 } else if (method >= MAXWELL3D_REG_INDEX(vertex_array_limit) &&
149 method < MAXWELL3D_REG_INDEX(vertex_array_limit) + 2 * 32) {
150 dirty_flags.vertex_array |= 148 dirty_flags.vertex_array |=
151 1u << ((method - MAXWELL3D_REG_INDEX(vertex_array_limit)) >> 1); 149 1u << ((method_call.method - MAXWELL3D_REG_INDEX(vertex_array)) >> 2);
152 } else if (method >= MAXWELL3D_REG_INDEX(instanced_arrays) && 150 } else if (method_call.method >= MAXWELL3D_REG_INDEX(vertex_array_limit) &&
153 method < MAXWELL3D_REG_INDEX(instanced_arrays) + 32) { 151 method_call.method < MAXWELL3D_REG_INDEX(vertex_array_limit) + 2 * 32) {
154 dirty_flags.vertex_array |= 1u << (method - MAXWELL3D_REG_INDEX(instanced_arrays)); 152 dirty_flags.vertex_array |=
153 1u << ((method_call.method - MAXWELL3D_REG_INDEX(vertex_array_limit)) >> 1);
154 } else if (method_call.method >= MAXWELL3D_REG_INDEX(instanced_arrays) &&
155 method_call.method < MAXWELL3D_REG_INDEX(instanced_arrays) + 32) {
156 dirty_flags.vertex_array |=
157 1u << (method_call.method - MAXWELL3D_REG_INDEX(instanced_arrays));
155 } 158 }
156 } 159 }
157 160
158 switch (method) { 161 switch (method_call.method) {
159 case MAXWELL3D_REG_INDEX(macros.data): { 162 case MAXWELL3D_REG_INDEX(macros.data): {
160 ProcessMacroUpload(value); 163 ProcessMacroUpload(method_call.argument);
161 break; 164 break;
162 } 165 }
163 case MAXWELL3D_REG_INDEX(macros.bind): { 166 case MAXWELL3D_REG_INDEX(macros.bind): {
164 ProcessMacroBind(value); 167 ProcessMacroBind(method_call.argument);
165 break; 168 break;
166 } 169 }
167 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]): 170 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
@@ -180,7 +183,7 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
180 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]): 183 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
181 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]): 184 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
182 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): { 185 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): {
183 ProcessCBData(value); 186 ProcessCBData(method_call.argument);
184 break; 187 break;
185 } 188 }
186 case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): { 189 case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 9324d9710..84471f181 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1080,7 +1080,7 @@ public:
1080 u32 GetRegisterValue(u32 method) const; 1080 u32 GetRegisterValue(u32 method) const;
1081 1081
1082 /// Write the value to the register identified by method. 1082 /// Write the value to the register identified by method.
1083 void WriteReg(u32 method, u32 value, u32 remaining_params); 1083 void CallMethod(const GPU::MethodCall& method_call);
1084 1084
1085 /// Returns a list of enabled textures for the specified shader stage. 1085 /// Returns a list of enabled textures for the specified shader stage.
1086 std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; 1086 std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const;
diff --git a/src/video_core/engines/maxwell_compute.cpp b/src/video_core/engines/maxwell_compute.cpp
index 8b5f08351..656db6a61 100644
--- a/src/video_core/engines/maxwell_compute.cpp
+++ b/src/video_core/engines/maxwell_compute.cpp
@@ -8,13 +8,13 @@
8 8
9namespace Tegra::Engines { 9namespace Tegra::Engines {
10 10
11void MaxwellCompute::WriteReg(u32 method, u32 value) { 11void MaxwellCompute::CallMethod(const GPU::MethodCall& method_call) {
12 ASSERT_MSG(method < Regs::NUM_REGS, 12 ASSERT_MSG(method_call.method < Regs::NUM_REGS,
13 "Invalid MaxwellCompute register, increase the size of the Regs structure"); 13 "Invalid MaxwellCompute register, increase the size of the Regs structure");
14 14
15 regs.reg_array[method] = value; 15 regs.reg_array[method_call.method] = method_call.argument;
16 16
17 switch (method) { 17 switch (method_call.method) {
18 case MAXWELL_COMPUTE_REG_INDEX(compute): { 18 case MAXWELL_COMPUTE_REG_INDEX(compute): {
19 LOG_CRITICAL(HW_GPU, "Compute shaders are not implemented"); 19 LOG_CRITICAL(HW_GPU, "Compute shaders are not implemented");
20 UNREACHABLE(); 20 UNREACHABLE();
diff --git a/src/video_core/engines/maxwell_compute.h b/src/video_core/engines/maxwell_compute.h
index 6ea934fb9..1d71f11bd 100644
--- a/src/video_core/engines/maxwell_compute.h
+++ b/src/video_core/engines/maxwell_compute.h
@@ -9,6 +9,7 @@
9#include "common/bit_field.h" 9#include "common/bit_field.h"
10#include "common/common_funcs.h" 10#include "common/common_funcs.h"
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "video_core/gpu.h"
12 13
13namespace Tegra::Engines { 14namespace Tegra::Engines {
14 15
@@ -42,7 +43,7 @@ public:
42 "MaxwellCompute Regs has wrong size"); 43 "MaxwellCompute Regs has wrong size");
43 44
44 /// Write the value to the register identified by method. 45 /// Write the value to the register identified by method.
45 void WriteReg(u32 method, u32 value); 46 void CallMethod(const GPU::MethodCall& method_call);
46}; 47};
47 48
48#define ASSERT_REG_POSITION(field_name, position) \ 49#define ASSERT_REG_POSITION(field_name, position) \
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index a34e884fe..06462f570 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -14,16 +14,16 @@ namespace Tegra::Engines {
14MaxwellDMA::MaxwellDMA(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager) 14MaxwellDMA::MaxwellDMA(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager)
15 : memory_manager(memory_manager), rasterizer{rasterizer} {} 15 : memory_manager(memory_manager), rasterizer{rasterizer} {}
16 16
17void MaxwellDMA::WriteReg(u32 method, u32 value) { 17void MaxwellDMA::CallMethod(const GPU::MethodCall& method_call) {
18 ASSERT_MSG(method < Regs::NUM_REGS, 18 ASSERT_MSG(method_call.method < Regs::NUM_REGS,
19 "Invalid MaxwellDMA register, increase the size of the Regs structure"); 19 "Invalid MaxwellDMA register, increase the size of the Regs structure");
20 20
21 regs.reg_array[method] = value; 21 regs.reg_array[method_call.method] = method_call.argument;
22 22
23#define MAXWELLDMA_REG_INDEX(field_name) \ 23#define MAXWELLDMA_REG_INDEX(field_name) \
24 (offsetof(Tegra::Engines::MaxwellDMA::Regs, field_name) / sizeof(u32)) 24 (offsetof(Tegra::Engines::MaxwellDMA::Regs, field_name) / sizeof(u32))
25 25
26 switch (method) { 26 switch (method_call.method) {
27 case MAXWELLDMA_REG_INDEX(exec): { 27 case MAXWELLDMA_REG_INDEX(exec): {
28 HandleCopy(); 28 HandleCopy();
29 break; 29 break;
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h
index 5f3704f05..1f8cd65d2 100644
--- a/src/video_core/engines/maxwell_dma.h
+++ b/src/video_core/engines/maxwell_dma.h
@@ -24,7 +24,7 @@ public:
24 ~MaxwellDMA() = default; 24 ~MaxwellDMA() = default;
25 25
26 /// Write the value to the register identified by method. 26 /// Write the value to the register identified by method.
27 void WriteReg(u32 method, u32 value); 27 void CallMethod(const GPU::MethodCall& method_call);
28 28
29 struct Regs { 29 struct Regs {
30 static constexpr std::size_t NUM_REGS = 0x1D6; 30 static constexpr std::size_t NUM_REGS = 0x1D6;