summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/engines/maxwell_3d.cpp57
-rw-r--r--src/video_core/engines/maxwell_3d.h19
-rw-r--r--src/video_core/gpu.cpp21
-rw-r--r--src/video_core/gpu.h18
5 files changed, 105 insertions, 11 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index ed87f8ff1..2f946e7be 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -7,6 +7,7 @@ add_library(video_core STATIC
7 engines/maxwell_3d.h 7 engines/maxwell_3d.h
8 engines/maxwell_compute.cpp 8 engines/maxwell_compute.cpp
9 engines/maxwell_compute.h 9 engines/maxwell_compute.h
10 gpu.cpp
10 gpu.h 11 gpu.h
11 memory_manager.cpp 12 memory_manager.cpp
12 memory_manager.h 13 memory_manager.h
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 49a138c1d..3a4e88e4e 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -13,6 +13,7 @@ constexpr u32 MacroRegistersStart = 0xE00;
13 13
14const std::unordered_map<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers = { 14const std::unordered_map<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers = {
15 {0xE24, {"SetShader", 5, &Maxwell3D::SetShader}}, 15 {0xE24, {"SetShader", 5, &Maxwell3D::SetShader}},
16 {0xE2A, {"BindStorageBuffer", 1, &Maxwell3D::BindStorageBuffer}},
16}; 17};
17 18
18Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} 19Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {}
@@ -83,6 +84,25 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
83 ASSERT_MSG(regs.code_address.CodeAddress() == 0, "Unexpected CODE_ADDRESS register value."); 84 ASSERT_MSG(regs.code_address.CodeAddress() == 0, "Unexpected CODE_ADDRESS register value.");
84 break; 85 break;
85 } 86 }
87 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
88 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]):
89 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]):
90 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]):
91 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]):
92 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]):
93 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]):
94 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]):
95 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]):
96 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]):
97 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]):
98 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]):
99 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]):
100 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
101 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
102 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): {
103 ProcessCBData(value);
104 break;
105 }
86 case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): { 106 case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): {
87 ProcessCBBind(Regs::ShaderStage::Vertex); 107 ProcessCBBind(Regs::ShaderStage::Vertex);
88 break; 108 break;
@@ -181,6 +201,26 @@ void Maxwell3D::SetShader(const std::vector<u32>& parameters) {
181 ProcessCBBind(shader_stage); 201 ProcessCBBind(shader_stage);
182} 202}
183 203
204void Maxwell3D::BindStorageBuffer(const std::vector<u32>& parameters) {
205 /**
206 * Parameters description:
207 * [0] = Buffer offset >> 2
208 */
209
210 u32 buffer_offset = parameters[0] << 2;
211
212 // Perform the same operations as the real macro code.
213 // Note: This value is hardcoded in the macro's code.
214 static constexpr u32 DefaultCBSize = 0x5F00;
215 regs.const_buffer.cb_size = DefaultCBSize;
216
217 GPUVAddr address = regs.ssbo_info.BufferAddress();
218 regs.const_buffer.cb_address_high = address >> 32;
219 regs.const_buffer.cb_address_low = address & 0xFFFFFFFF;
220
221 regs.const_buffer.cb_pos = buffer_offset;
222}
223
184void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { 224void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) {
185 // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. 225 // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage.
186 auto& shader = state.shader_stages[static_cast<size_t>(stage)]; 226 auto& shader = state.shader_stages[static_cast<size_t>(stage)];
@@ -194,5 +234,22 @@ void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) {
194 buffer.size = regs.const_buffer.cb_size; 234 buffer.size = regs.const_buffer.cb_size;
195} 235}
196 236
237void Maxwell3D::ProcessCBData(u32 value) {
238 // Write the input value to the current const buffer at the current position.
239 GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
240 ASSERT(buffer_address != 0);
241
242 // Don't allow writing past the end of the buffer.
243 ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size);
244
245 VAddr address =
246 memory_manager.PhysicalToVirtualAddress(buffer_address + regs.const_buffer.cb_pos);
247
248 Memory::Write32(address, value);
249
250 // Increment the current buffer position.
251 regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;
252}
253
197} // namespace Engines 254} // namespace Engines
198} // namespace Tegra 255} // namespace Tegra
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 05820a21e..3e97d9045 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -166,7 +166,19 @@ public:
166 166
167 u32 tex_cb_index; 167 u32 tex_cb_index;
168 168
169 INSERT_PADDING_WORDS(0x4B3); 169 INSERT_PADDING_WORDS(0x395);
170
171 struct {
172 /// Compressed address of a buffer that holds information about bound SSBOs.
173 /// This address is usually bound to c0 in the shaders.
174 u32 buffer_address;
175
176 GPUVAddr BufferAddress() const {
177 return static_cast<GPUVAddr>(buffer_address) << 8;
178 }
179 } ssbo_info;
180
181 INSERT_PADDING_WORDS(0x11D);
170 }; 182 };
171 std::array<u32, NUM_REGS> reg_array; 183 std::array<u32, NUM_REGS> reg_array;
172 }; 184 };
@@ -218,6 +230,9 @@ private:
218 /// Handles a write to the QUERY_GET register. 230 /// Handles a write to the QUERY_GET register.
219 void ProcessQueryGet(); 231 void ProcessQueryGet();
220 232
233 /// Handles a write to the CB_DATA[i] register.
234 void ProcessCBData(u32 value);
235
221 /// Handles a write to the CB_BIND register. 236 /// Handles a write to the CB_BIND register.
222 void ProcessCBBind(Regs::ShaderStage stage); 237 void ProcessCBBind(Regs::ShaderStage stage);
223 238
@@ -226,6 +241,7 @@ private:
226 241
227 /// Method call handlers 242 /// Method call handlers
228 void SetShader(const std::vector<u32>& parameters); 243 void SetShader(const std::vector<u32>& parameters);
244 void BindStorageBuffer(const std::vector<u32>& parameters);
229 245
230 struct MethodInfo { 246 struct MethodInfo {
231 const char* name; 247 const char* name;
@@ -249,6 +265,7 @@ ASSERT_REG_POSITION(shader_config[0], 0x800);
249ASSERT_REG_POSITION(const_buffer, 0x8E0); 265ASSERT_REG_POSITION(const_buffer, 0x8E0);
250ASSERT_REG_POSITION(cb_bind[0], 0x904); 266ASSERT_REG_POSITION(cb_bind[0], 0x904);
251ASSERT_REG_POSITION(tex_cb_index, 0x982); 267ASSERT_REG_POSITION(tex_cb_index, 0x982);
268ASSERT_REG_POSITION(ssbo_info, 0xD18);
252 269
253#undef ASSERT_REG_POSITION 270#undef ASSERT_REG_POSITION
254 271
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
new file mode 100644
index 000000000..c384d236e
--- /dev/null
+++ b/src/video_core/gpu.cpp
@@ -0,0 +1,21 @@
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 "video_core/engines/fermi_2d.h"
6#include "video_core/engines/maxwell_3d.h"
7#include "video_core/engines/maxwell_compute.h"
8#include "video_core/gpu.h"
9
10namespace Tegra {
11
12GPU::GPU() {
13 memory_manager = std::make_unique<MemoryManager>();
14 maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager);
15 fermi_2d = std::make_unique<Engines::Fermi2D>();
16 maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
17}
18
19GPU::~GPU() = default;
20
21} // namespace Tegra
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index d2e4ff52d..2a9064ba3 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -8,13 +8,16 @@
8#include <unordered_map> 8#include <unordered_map>
9#include <vector> 9#include <vector>
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "video_core/engines/fermi_2d.h"
12#include "video_core/engines/maxwell_3d.h"
13#include "video_core/engines/maxwell_compute.h"
14#include "video_core/memory_manager.h" 11#include "video_core/memory_manager.h"
15 12
16namespace Tegra { 13namespace Tegra {
17 14
15namespace Engines {
16class Fermi2D;
17class Maxwell3D;
18class MaxwellCompute;
19} // namespace Engines
20
18enum class EngineID { 21enum class EngineID {
19 FERMI_TWOD_A = 0x902D, // 2D Engine 22 FERMI_TWOD_A = 0x902D, // 2D Engine
20 MAXWELL_B = 0xB197, // 3D Engine 23 MAXWELL_B = 0xB197, // 3D Engine
@@ -25,13 +28,8 @@ enum class EngineID {
25 28
26class GPU final { 29class GPU final {
27public: 30public:
28 GPU() { 31 GPU();
29 memory_manager = std::make_unique<MemoryManager>(); 32 ~GPU();
30 maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager);
31 fermi_2d = std::make_unique<Engines::Fermi2D>();
32 maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
33 }
34 ~GPU() = default;
35 33
36 /// Processes a command list stored at the specified address in GPU memory. 34 /// Processes a command list stored at the specified address in GPU memory.
37 void ProcessCommandList(GPUVAddr address, u32 size); 35 void ProcessCommandList(GPUVAddr address, u32 size);