diff options
-rw-r--r-- | src/citra_qt/debugger/graphics_cmdlists.cpp | 2 | ||||
-rw-r--r-- | src/core/hw/gpu.cpp | 8 | ||||
-rw-r--r-- | src/video_core/CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/video_core/command_processor.cpp | 60 | ||||
-rw-r--r-- | src/video_core/command_processor.h | 31 | ||||
-rw-r--r-- | src/video_core/gpu_debugger.h | 8 | ||||
-rw-r--r-- | src/video_core/pica.h | 2 | ||||
-rw-r--r-- | src/video_core/video_core.vcxproj | 2 | ||||
-rw-r--r-- | src/video_core/video_core.vcxproj.filters | 2 |
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 30b8b5dae..e98560a19 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 591997aa3..87cf93bac 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 2503b9d18..8977c8dca 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 000000000..515c407ea --- /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 000000000..6b6241a25 --- /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 5d85f90b9..2ba873457 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 24b39a3ad..0e231c6c9 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 2dbfc68dd..28eb21284 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 b42823d2a..713458fcf 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" /> |