Pica: Add command processor.
This commit is contained in:
		@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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})
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								src/video_core/command_processor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/video_core/command_processor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										31
									
								
								src/video_core/command_processor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/video_core/command_processor.h
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
@@ -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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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" />
 | 
			
		||||
 
 | 
			
		||||
@@ -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" />
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user