summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2014-07-22 12:41:16 +0200
committerGravatar Tony Wasserka2014-07-23 00:44:31 +0200
commit9b0d0c81a006ebd9e054758bc2c973d67650ca70 (patch)
treec0827e78475e98070c42732328cab30480122d2e /src
parentRegisterSet: Simplify code by using structs for register definition instead o... (diff)
downloadyuzu-9b0d0c81a006ebd9e054758bc2c973d67650ca70.tar.gz
yuzu-9b0d0c81a006ebd9e054758bc2c973d67650ca70.tar.xz
yuzu-9b0d0c81a006ebd9e054758bc2c973d67650ca70.zip
GSP: Clean up GX command processing a lot and treat command id as a u8 rather than a u32.
Anonymous structs are not standard C++, hence don't use them.
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/debugger/graphics.cpp34
-rw-r--r--src/core/hle/service/gsp.cpp64
-rw-r--r--src/core/hle/service/gsp.h52
-rw-r--r--src/video_core/gpu_debugger.h5
4 files changed, 99 insertions, 56 deletions
diff --git a/src/citra_qt/debugger/graphics.cpp b/src/citra_qt/debugger/graphics.cpp
index 9aaade8f9..0f911a015 100644
--- a/src/citra_qt/debugger/graphics.cpp
+++ b/src/citra_qt/debugger/graphics.cpp
@@ -28,22 +28,24 @@ QVariant GPUCommandStreamItemModel::data(const QModelIndex& index, int role) con
28 const GSP_GPU::GXCommand& command = GetDebugger()->ReadGXCommandHistory(command_index); 28 const GSP_GPU::GXCommand& command = GetDebugger()->ReadGXCommandHistory(command_index);
29 if (role == Qt::DisplayRole) 29 if (role == Qt::DisplayRole)
30 { 30 {
31 std::map<GSP_GPU::GXCommandId, const char*> command_names; 31 std::map<GSP_GPU::GXCommandId, const char*> command_names = {
32 command_names[GSP_GPU::GXCommandId::REQUEST_DMA] = "REQUEST_DMA"; 32 { GSP_GPU::GXCommandId::REQUEST_DMA, "REQUEST_DMA" },
33 command_names[GSP_GPU::GXCommandId::SET_COMMAND_LIST_FIRST] = "SET_COMMAND_LIST_FIRST"; 33 { GSP_GPU::GXCommandId::SET_COMMAND_LIST_FIRST, "SET_COMMAND_LIST_FIRST" },
34 command_names[GSP_GPU::GXCommandId::SET_MEMORY_FILL] = "SET_MEMORY_FILL"; 34 { GSP_GPU::GXCommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL" },
35 command_names[GSP_GPU::GXCommandId::SET_DISPLAY_TRANSFER] = "SET_DISPLAY_TRANSFER"; 35 { GSP_GPU::GXCommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER" },
36 command_names[GSP_GPU::GXCommandId::SET_TEXTURE_COPY] = "SET_TEXTURE_COPY"; 36 { GSP_GPU::GXCommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY" },
37 command_names[GSP_GPU::GXCommandId::SET_COMMAND_LIST_LAST] = "SET_COMMAND_LIST_LAST"; 37 { GSP_GPU::GXCommandId::SET_COMMAND_LIST_LAST, "SET_COMMAND_LIST_LAST" }
38 QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9").arg(command_names[static_cast<GSP_GPU::GXCommandId>(command.id)]) 38 };
39 .arg(command.data[0], 8, 16, QLatin1Char('0')) 39 const u32* command_data = reinterpret_cast<const u32*>(&command);
40 .arg(command.data[1], 8, 16, QLatin1Char('0')) 40 QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9").arg(command_names[command.id])
41 .arg(command.data[2], 8, 16, QLatin1Char('0')) 41 .arg(command_data[0], 8, 16, QLatin1Char('0'))
42 .arg(command.data[3], 8, 16, QLatin1Char('0')) 42 .arg(command_data[1], 8, 16, QLatin1Char('0'))
43 .arg(command.data[4], 8, 16, QLatin1Char('0')) 43 .arg(command_data[2], 8, 16, QLatin1Char('0'))
44 .arg(command.data[5], 8, 16, QLatin1Char('0')) 44 .arg(command_data[3], 8, 16, QLatin1Char('0'))
45 .arg(command.data[6], 8, 16, QLatin1Char('0')) 45 .arg(command_data[4], 8, 16, QLatin1Char('0'))
46 .arg(command.data[7], 8, 16, QLatin1Char('0')); 46 .arg(command_data[5], 8, 16, QLatin1Char('0'))
47 .arg(command_data[6], 8, 16, QLatin1Char('0'))
48 .arg(command_data[7], 8, 16, QLatin1Char('0'));
47 return QVariant(str); 49 return QVariant(str);
48 } 50 }
49 else 51 else
diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp
index 053c7dd2c..05753fa2c 100644
--- a/src/core/hle/service/gsp.cpp
+++ b/src/core/hle/service/gsp.cpp
@@ -160,60 +160,72 @@ void TriggerCmdReqQueue(Service::Interface* self) {
160 }; 160 };
161 161
162 GX_CmdBufferHeader* header = (GX_CmdBufferHeader*)GX_GetCmdBufferPointer(g_thread_id); 162 GX_CmdBufferHeader* header = (GX_CmdBufferHeader*)GX_GetCmdBufferPointer(g_thread_id);
163 u32* cmd_buff = (u32*)GX_GetCmdBufferPointer(g_thread_id, 0x20 + (header->index * 0x20)); 163 auto& command = *(const GXCommand*)GX_GetCmdBufferPointer(g_thread_id, 0x20 + (header->index * 0x20));
164 164
165 switch (static_cast<GXCommandId>(cmd_buff[0])) { 165 switch (command.id) {
166 166
167 // GX request DMA - typically used for copying memory from GSP heap to VRAM 167 // GX request DMA - typically used for copying memory from GSP heap to VRAM
168 case GXCommandId::REQUEST_DMA: 168 case GXCommandId::REQUEST_DMA:
169 memcpy(Memory::GetPointer(cmd_buff[2]), Memory::GetPointer(cmd_buff[1]), cmd_buff[3]); 169 memcpy(Memory::GetPointer(command.dma_request.dest_address),
170 Memory::GetPointer(command.dma_request.source_address),
171 command.dma_request.size);
170 break; 172 break;
171 173
172 case GXCommandId::SET_COMMAND_LIST_LAST: 174 case GXCommandId::SET_COMMAND_LIST_LAST:
173 WriteGPURegister(GPU::Regs::CommandProcessor + 2, cmd_buff[1] >> 3); // command list data address 175 {
174 WriteGPURegister(GPU::Regs::CommandProcessor, cmd_buff[2] >> 3); // command list address 176 auto& params = command.set_command_list_last;
175 WriteGPURegister(GPU::Regs::CommandProcessor + 4, 1); // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though 177 WriteGPURegister(GPU::Regs::CommandProcessor + 2, params.address >> 3);
178 WriteGPURegister(GPU::Regs::CommandProcessor, params.size >> 3);
179 WriteGPURegister(GPU::Regs::CommandProcessor + 4, 1); // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though
176 180
177 // TODO: Move this to GPU 181 // TODO: Move this to GPU
178 // TODO: Not sure what units the size is measured in 182 // TODO: Not sure what units the size is measured in
179 g_debugger.CommandListCalled(cmd_buff[1], (u32*)Memory::GetPointer(cmd_buff[1]), cmd_buff[2]); 183 g_debugger.CommandListCalled(params.address,
184 (u32*)Memory::GetPointer(params.address),
185 params.size);
180 break; 186 break;
187 }
181 188
182 case GXCommandId::SET_MEMORY_FILL: 189 case GXCommandId::SET_MEMORY_FILL:
183 WriteGPURegister(GPU::Regs::MemoryFill, cmd_buff[1] >> 3); // Start 1 190 {
184 WriteGPURegister(GPU::Regs::MemoryFill + 1, cmd_buff[3] >> 3); // End 1 191 auto& params = command.memory_fill;
185 WriteGPURegister(GPU::Regs::MemoryFill + 2, cmd_buff[3] - cmd_buff[1]); // Size 1 192 WriteGPURegister(GPU::Regs::MemoryFill, params.start1 >> 3);
186 WriteGPURegister(GPU::Regs::MemoryFill + 3, cmd_buff[2]); // Value 1 193 WriteGPURegister(GPU::Regs::MemoryFill + 1, params.end1 >> 3);
187 194 WriteGPURegister(GPU::Regs::MemoryFill + 2, params.end1 - params.start1);
188 WriteGPURegister(GPU::Regs::MemoryFill + 4, cmd_buff[4] >> 3); // Start 2 195 WriteGPURegister(GPU::Regs::MemoryFill + 3, params.value1);
189 WriteGPURegister(GPU::Regs::MemoryFill + 5, cmd_buff[6] >> 3); // End 2 196
190 WriteGPURegister(GPU::Regs::MemoryFill + 6, cmd_buff[6] - cmd_buff[4]); // Size 2 197 WriteGPURegister(GPU::Regs::MemoryFill + 4, params.start2 >> 3);
191 WriteGPURegister(GPU::Regs::MemoryFill + 7, cmd_buff[5]); // Value 2 198 WriteGPURegister(GPU::Regs::MemoryFill + 5, params.end2 >> 3);
199 WriteGPURegister(GPU::Regs::MemoryFill + 6, params.end2 - params.start2);
200 WriteGPURegister(GPU::Regs::MemoryFill + 7, params.value2);
192 break; 201 break;
202 }
193 203
194 // TODO: Check if texture copies are implemented correctly.. 204 // TODO: Check if texture copies are implemented correctly..
195 case GXCommandId::SET_DISPLAY_TRANSFER: 205 case GXCommandId::SET_DISPLAY_TRANSFER:
196 case GXCommandId::SET_TEXTURE_COPY: 206 case GXCommandId::SET_TEXTURE_COPY:
197 WriteGPURegister(GPU::Regs::DisplayTransfer, cmd_buff[1] >> 3); // input buffer address 207 {
198 WriteGPURegister(GPU::Regs::DisplayTransfer + 1, cmd_buff[2] >> 3); // output buffer address 208 auto& params = command.image_copy;
199 WriteGPURegister(GPU::Regs::DisplayTransfer + 3, cmd_buff[3]); // input buffer size 209 WriteGPURegister(GPU::Regs::DisplayTransfer, params.in_buffer_address >> 3);
200 WriteGPURegister(GPU::Regs::DisplayTransfer + 2, cmd_buff[4]); // output buffer size 210 WriteGPURegister(GPU::Regs::DisplayTransfer + 1, params.out_buffer_address >> 3);
201 WriteGPURegister(GPU::Regs::DisplayTransfer + 4, cmd_buff[5]); // transfer flags 211 WriteGPURegister(GPU::Regs::DisplayTransfer + 3, params.in_buffer_size);
212 WriteGPURegister(GPU::Regs::DisplayTransfer + 2, params.out_buffer_size);
213 WriteGPURegister(GPU::Regs::DisplayTransfer + 4, params.flags);
202 214
203 // TODO: Should this only be ORed with 1 for texture copies? 215 // TODO: Should this only be ORed with 1 for texture copies?
204 WriteGPURegister(GPU::Regs::DisplayTransfer + 6, 1); // trigger transfer 216 // trigger transfer
217 WriteGPURegister(GPU::Regs::DisplayTransfer + 6, 1);
205 break; 218 break;
219 }
206 220
207 case GXCommandId::SET_COMMAND_LIST_FIRST: 221 case GXCommandId::SET_COMMAND_LIST_FIRST:
208 { 222 {
209 //u32* buf0_data = (u32*)Memory::GetPointer(cmd_buff[1]); 223 // TODO
210 //u32* buf1_data = (u32*)Memory::GetPointer(cmd_buff[3]);
211 //u32* buf2_data = (u32*)Memory::GetPointer(cmd_buff[5]);
212 break; 224 break;
213 } 225 }
214 226
215 default: 227 default:
216 ERROR_LOG(GSP, "unknown command 0x%08X", cmd_buff[0]); 228 ERROR_LOG(GSP, "unknown command 0x%08X", (int)command.id.Value());
217 } 229 }
218 230
219 GX_FinishCommand(g_thread_id); 231 GX_FinishCommand(g_thread_id);
diff --git a/src/core/hle/service/gsp.h b/src/core/hle/service/gsp.h
index fb50a928a..f36afb697 100644
--- a/src/core/hle/service/gsp.h
+++ b/src/core/hle/service/gsp.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/bit_field.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8 9
9//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -12,21 +13,50 @@
12namespace GSP_GPU { 13namespace GSP_GPU {
13 14
14enum class GXCommandId : u32 { 15enum class GXCommandId : u32 {
15 REQUEST_DMA = 0x00000000, 16 REQUEST_DMA = 0x00,
16 SET_COMMAND_LIST_LAST = 0x00000001, 17 SET_COMMAND_LIST_LAST = 0x01,
17 SET_MEMORY_FILL = 0x01000102, // TODO: Confirm? 18 SET_MEMORY_FILL = 0x02,
18 SET_DISPLAY_TRANSFER = 0x00000003, 19 SET_DISPLAY_TRANSFER = 0x03,
19 SET_TEXTURE_COPY = 0x00000004, 20 SET_TEXTURE_COPY = 0x04,
20 SET_COMMAND_LIST_FIRST = 0x00000005, 21 SET_COMMAND_LIST_FIRST = 0x05,
21}; 22};
22 23
23union GXCommand { 24struct GXCommand {
24 struct { 25 BitField<0, 8, GXCommandId> id;
25 GXCommandId id; 26
26 }; 27 union {
28 struct {
29 u32 source_address;
30 u32 dest_address;
31 u32 size;
32 } dma_request;
33
34 struct {
35 u32 address;
36 u32 size;
37 } set_command_list_last;
27 38
28 u32 data[0x20]; 39 struct {
40 u32 start1;
41 u32 value1;
42 u32 end1;
43 u32 start2;
44 u32 value2;
45 u32 end2;
46 } memory_fill;
47
48 struct {
49 u32 in_buffer_address;
50 u32 out_buffer_address;
51 u32 in_buffer_size;
52 u32 out_buffer_size;
53 u32 flags;
54 } image_copy;
55
56 u8 raw_data[0x1C];
57 };
29}; 58};
59static_assert(sizeof(GXCommand) == 0x20, "GXCommand struct has incorrect size");
30 60
31/// Interface to "srv:" service 61/// Interface to "srv:" service
32class Interface : public Service::Interface { 62class Interface : public Service::Interface {
diff --git a/src/video_core/gpu_debugger.h b/src/video_core/gpu_debugger.h
index ca1fb22d7..d92ceaa72 100644
--- a/src/video_core/gpu_debugger.h
+++ b/src/video_core/gpu_debugger.h
@@ -50,7 +50,7 @@ public:
50 virtual void GXCommandProcessed(int total_command_count) 50 virtual void GXCommandProcessed(int total_command_count)
51 { 51 {
52 const GSP_GPU::GXCommand& cmd = observed->ReadGXCommandHistory(total_command_count-1); 52 const GSP_GPU::GXCommand& cmd = observed->ReadGXCommandHistory(total_command_count-1);
53 ERROR_LOG(GSP, "Received command: id=%x", cmd.id); 53 ERROR_LOG(GSP, "Received command: id=%x", (int)cmd.id.Value());
54 } 54 }
55 55
56 /** 56 /**
@@ -84,8 +84,7 @@ public:
84 gx_command_history.push_back(GSP_GPU::GXCommand()); 84 gx_command_history.push_back(GSP_GPU::GXCommand());
85 GSP_GPU::GXCommand& cmd = gx_command_history[gx_command_history.size()-1]; 85 GSP_GPU::GXCommand& cmd = gx_command_history[gx_command_history.size()-1];
86 86
87 const int cmd_length = sizeof(GSP_GPU::GXCommand); 87 memcpy(&cmd, command_data, sizeof(GSP_GPU::GXCommand));
88 memcpy(cmd.data, command_data, cmd_length);
89 88
90 ForEachObserver([this](DebuggerObserver* observer) { 89 ForEachObserver([this](DebuggerObserver* observer) {
91 observer->GXCommandProcessed(this->gx_command_history.size()); 90 observer->GXCommandProcessed(this->gx_command_history.size());