From 76a586de4952df6d8dd9db9d97716c00690cebdd Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 26 Jul 2014 14:42:46 +0200 Subject: Pica: Add command processor. --- src/video_core/CMakeLists.txt | 7 ++-- src/video_core/command_processor.cpp | 60 +++++++++++++++++++++++++++++++ src/video_core/command_processor.h | 31 ++++++++++++++++ src/video_core/gpu_debugger.h | 8 +++-- src/video_core/pica.h | 2 ++ src/video_core/video_core.vcxproj | 2 ++ src/video_core/video_core.vcxproj.filters | 2 ++ 7 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 src/video_core/command_processor.cpp create mode 100644 src/video_core/command_processor.h (limited to 'src/video_core') 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::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 { - 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(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 @@ + + 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 @@ renderer_opengl + @@ -16,6 +17,7 @@ renderer_opengl + -- cgit v1.2.3