aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-07-26 14:42:46 +0200
committerGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-08-12 13:47:30 +0200
commit76a586de4952df6d8dd9db9d97716c00690cebdd (patch)
treead6a954780faa4ab7908780e4ab605952b7e400b
parent98ad16a45b9441a54d80e67425ac3ddee24f08dc (diff)
Pica: Add command processor.
-rw-r--r--src/citra_qt/debugger/graphics_cmdlists.cpp2
-rw-r--r--src/core/hw/gpu.cpp8
-rw-r--r--src/video_core/CMakeLists.txt7
-rw-r--r--src/video_core/command_processor.cpp60
-rw-r--r--src/video_core/command_processor.h31
-rw-r--r--src/video_core/gpu_debugger.h8
-rw-r--r--src/video_core/pica.h2
-rw-r--r--src/video_core/video_core.vcxproj2
-rw-r--r--src/video_core/video_core.vcxproj.filters2
9 files changed, 113 insertions, 9 deletions
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp
index 30b8b5da..e98560a1 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics_cmdlists.cpp
@@ -78,7 +78,7 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const
// index refers to a specific command
const GraphicsDebugger::PicaCommandList& cmdlist = command_lists[item->parent->index].second;
const GraphicsDebugger::PicaCommand& cmd = cmdlist[item->index];
- const Pica::CommandHeader& header = cmd.GetHeader();
+ const Pica::CommandProcessor::CommandHeader& header = cmd.GetHeader();
if (role == Qt::DisplayRole) {
QString content;
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 591997aa..87cf93ba 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -14,6 +14,7 @@
#include "core/hw/gpu.h"
+#include "video_core/command_processor.h"
#include "video_core/video_core.h"
@@ -143,14 +144,15 @@ inline void Write(u32 addr, const T data) {
break;
}
+ // Seems like writing to this register triggers processing
case GPU_REG_INDEX(command_processor_config.trigger):
{
const auto& config = g_regs.command_processor_config;
if (config.trigger & 1)
{
- // u32* buffer = (u32*)Memory::GetPointer(config.GetPhysicalAddress());
- ERROR_LOG(GPU, "Beginning 0x%08x bytes of commands from address 0x%08x", config.size, config.GetPhysicalAddress());
- // TODO: Process command list!
+ u32* buffer = (u32*)Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalAddress()));
+ u32 size = config.size << 3;
+ Pica::CommandProcessor::ProcessCommandList(buffer, size);
}
break;
}
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 2503b9d1..8977c8dc 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -1,11 +1,14 @@
-set(SRCS video_core.cpp
+set(SRCS command_processor.cpp
utils.cpp
+ video_core.cpp
renderer_opengl/renderer_opengl.cpp)
-set(HEADERS math.h
+set(HEADERS command_processor.h
+ math.h
utils.h
video_core.h
renderer_base.h
+ video_core.h
renderer_opengl/renderer_opengl.h)
add_library(video_core STATIC ${SRCS} ${HEADERS})
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
new file mode 100644
index 00000000..515c407e
--- /dev/null
+++ b/src/video_core/command_processor.cpp
@@ -0,0 +1,60 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include "pica.h"
+#include "command_processor.h"
+
+
+namespace Pica {
+
+Regs registers;
+
+namespace CommandProcessor {
+
+static inline void WritePicaReg(u32 id, u32 value) {
+ u32 old_value = registers[id];
+ registers[id] = value;
+
+ switch(id) {
+ // TODO: Perform actions for anything which requires special treatment here...
+
+ default:
+ break;
+ }
+}
+
+static std::ptrdiff_t ExecuteCommandBlock(const u32* first_command_word) {
+ const CommandHeader& header = *(const CommandHeader*)(&first_command_word[1]);
+
+ u32* read_pointer = (u32*)first_command_word;
+
+ // TODO: Take parameter mask into consideration!
+
+ WritePicaReg(header.cmd_id, *read_pointer);
+ read_pointer += 2;
+
+ for (int i = 1; i < 1+header.extra_data_length; ++i) {
+ u32 cmd = header.cmd_id + ((header.group_commands) ? i : 0);
+ WritePicaReg(cmd, *read_pointer);
+ ++read_pointer;
+ }
+
+ // align read pointer to 8 bytes
+ if ((first_command_word - read_pointer) % 2)
+ ++read_pointer;
+
+ return read_pointer - first_command_word;
+}
+
+void ProcessCommandList(const u32* list, u32 size) {
+ u32* read_pointer = (u32*)list;
+
+ while (read_pointer < list + size) {
+ read_pointer += ExecuteCommandBlock(read_pointer);
+ }
+}
+
+} // namespace
+
+} // namespace
diff --git a/src/video_core/command_processor.h b/src/video_core/command_processor.h
new file mode 100644
index 00000000..6b6241a2
--- /dev/null
+++ b/src/video_core/command_processor.h
@@ -0,0 +1,31 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/bit_field.h"
+#include "common/common_types.h"
+
+#include "pica.h"
+
+namespace Pica {
+
+namespace CommandProcessor {
+
+union CommandHeader {
+ u32 hex;
+
+ BitField< 0, 16, u32> cmd_id;
+ BitField<16, 4, u32> parameter_mask;
+ BitField<20, 11, u32> extra_data_length;
+ BitField<31, 1, u32> group_commands;
+};
+static_assert(std::is_standard_layout<CommandHeader>::value == true, "CommandHeader does not use standard layout");
+static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!");
+
+void ProcessCommandList(const u32* list, u32 size);
+
+} // namespace
+
+} // namespace
diff --git a/src/video_core/gpu_debugger.h b/src/video_core/gpu_debugger.h
index 5d85f90b..2ba87345 100644
--- a/src/video_core/gpu_debugger.h
+++ b/src/video_core/gpu_debugger.h
@@ -11,6 +11,8 @@
#include "common/log.h"
#include "core/hle/service/gsp.h"
+
+#include "command_processor.h"
#include "pica.h"
class GraphicsDebugger
@@ -20,10 +22,10 @@ public:
// A vector of commands represented by their raw byte sequence
struct PicaCommand : public std::vector<u32>
{
- const Pica::CommandHeader& GetHeader() const
+ const Pica::CommandProcessor::CommandHeader& GetHeader() const
{
const u32& val = at(1);
- return *(Pica::CommandHeader*)&val;
+ return *(Pica::CommandProcessor::CommandHeader*)&val;
}
};
@@ -99,7 +101,7 @@ public:
PicaCommandList cmdlist;
for (u32* parse_pointer = command_list; parse_pointer < command_list + size_in_words;)
{
- const Pica::CommandHeader header = static_cast<Pica::CommandHeader>(parse_pointer[1]);
+ const Pica::CommandProcessor::CommandHeader& header = *(Pica::CommandProcessor::CommandHeader*)(&parse_pointer[1]);
cmdlist.push_back(PicaCommand());
auto& cmd = cmdlist.back();
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 24b39a3a..0e231c6c 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -161,6 +161,8 @@ ASSERT_REG_POSITION(vertex_descriptor, 0x200);
// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value anyway.
static_assert(sizeof(Regs) == 0x300 * sizeof(u32), "Invalid total size of register set");
+extern Regs registers; // TODO: Not sure if we want to have one global instance for this
+
struct float24 {
static float24 FromFloat32(float val) {
diff --git a/src/video_core/video_core.vcxproj b/src/video_core/video_core.vcxproj
index 2dbfc68d..28eb2128 100644
--- a/src/video_core/video_core.vcxproj
+++ b/src/video_core/video_core.vcxproj
@@ -20,10 +20,12 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="renderer_opengl\renderer_opengl.cpp" />
+ <ClCompile Include="command_processor.cpp" />
<ClCompile Include="utils.cpp" />
<ClCompile Include="video_core.cpp" />
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="command_processor.h" />
<ClInclude Include="gpu_debugger.h" />
<ClInclude Include="math.h" />
<ClInclude Include="pica.h" />
diff --git a/src/video_core/video_core.vcxproj.filters b/src/video_core/video_core.vcxproj.filters
index b42823d2..713458fc 100644
--- a/src/video_core/video_core.vcxproj.filters
+++ b/src/video_core/video_core.vcxproj.filters
@@ -9,6 +9,7 @@
<ClCompile Include="renderer_opengl\renderer_opengl.cpp">
<Filter>renderer_opengl</Filter>
</ClCompile>
+ <ClCompile Include="command_processor.cpp" />
<ClCompile Include="utils.cpp" />
<ClCompile Include="video_core.cpp" />
</ItemGroup>
@@ -16,6 +17,7 @@
<ClInclude Include="renderer_opengl\renderer_opengl.h">
<Filter>renderer_opengl</Filter>
</ClInclude>
+ <ClInclude Include="command_processor.h" />
<ClInclude Include="gpu_debugger.h" />
<ClInclude Include="math.h" />
<ClInclude Include="pica.h" />