Pica: Add command processor.
This commit is contained in:
parent
98ad16a45b
commit
76a586de49
|
@ -78,7 +78,7 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const
|
||||||
// index refers to a specific command
|
// index refers to a specific command
|
||||||
const GraphicsDebugger::PicaCommandList& cmdlist = command_lists[item->parent->index].second;
|
const GraphicsDebugger::PicaCommandList& cmdlist = command_lists[item->parent->index].second;
|
||||||
const GraphicsDebugger::PicaCommand& cmd = cmdlist[item->index];
|
const GraphicsDebugger::PicaCommand& cmd = cmdlist[item->index];
|
||||||
const Pica::CommandHeader& header = cmd.GetHeader();
|
const Pica::CommandProcessor::CommandHeader& header = cmd.GetHeader();
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
QString content;
|
QString content;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
|
|
||||||
|
#include "video_core/command_processor.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,14 +144,15 @@ inline void Write(u32 addr, const T data) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seems like writing to this register triggers processing
|
||||||
case GPU_REG_INDEX(command_processor_config.trigger):
|
case GPU_REG_INDEX(command_processor_config.trigger):
|
||||||
{
|
{
|
||||||
const auto& config = g_regs.command_processor_config;
|
const auto& config = g_regs.command_processor_config;
|
||||||
if (config.trigger & 1)
|
if (config.trigger & 1)
|
||||||
{
|
{
|
||||||
// u32* buffer = (u32*)Memory::GetPointer(config.GetPhysicalAddress());
|
u32* buffer = (u32*)Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalAddress()));
|
||||||
ERROR_LOG(GPU, "Beginning 0x%08x bytes of commands from address 0x%08x", config.size, config.GetPhysicalAddress());
|
u32 size = config.size << 3;
|
||||||
// TODO: Process command list!
|
Pica::CommandProcessor::ProcessCommandList(buffer, size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
set(SRCS video_core.cpp
|
set(SRCS command_processor.cpp
|
||||||
utils.cpp
|
utils.cpp
|
||||||
|
video_core.cpp
|
||||||
renderer_opengl/renderer_opengl.cpp)
|
renderer_opengl/renderer_opengl.cpp)
|
||||||
|
|
||||||
set(HEADERS math.h
|
set(HEADERS command_processor.h
|
||||||
|
math.h
|
||||||
utils.h
|
utils.h
|
||||||
video_core.h
|
video_core.h
|
||||||
renderer_base.h
|
renderer_base.h
|
||||||
|
video_core.h
|
||||||
renderer_opengl/renderer_opengl.h)
|
renderer_opengl/renderer_opengl.h)
|
||||||
|
|
||||||
add_library(video_core STATIC ${SRCS} ${HEADERS})
|
add_library(video_core STATIC ${SRCS} ${HEADERS})
|
||||||
|
|
|
@ -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
|
|
@ -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 "common/log.h"
|
||||||
|
|
||||||
#include "core/hle/service/gsp.h"
|
#include "core/hle/service/gsp.h"
|
||||||
|
|
||||||
|
#include "command_processor.h"
|
||||||
#include "pica.h"
|
#include "pica.h"
|
||||||
|
|
||||||
class GraphicsDebugger
|
class GraphicsDebugger
|
||||||
|
@ -20,10 +22,10 @@ public:
|
||||||
// A vector of commands represented by their raw byte sequence
|
// A vector of commands represented by their raw byte sequence
|
||||||
struct PicaCommand : public std::vector<u32>
|
struct PicaCommand : public std::vector<u32>
|
||||||
{
|
{
|
||||||
const Pica::CommandHeader& GetHeader() const
|
const Pica::CommandProcessor::CommandHeader& GetHeader() const
|
||||||
{
|
{
|
||||||
const u32& val = at(1);
|
const u32& val = at(1);
|
||||||
return *(Pica::CommandHeader*)&val;
|
return *(Pica::CommandProcessor::CommandHeader*)&val;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ public:
|
||||||
PicaCommandList cmdlist;
|
PicaCommandList cmdlist;
|
||||||
for (u32* parse_pointer = command_list; parse_pointer < command_list + size_in_words;)
|
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());
|
cmdlist.push_back(PicaCommand());
|
||||||
auto& cmd = cmdlist.back();
|
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.
|
// 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");
|
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 {
|
struct float24 {
|
||||||
static float24 FromFloat32(float val) {
|
static float24 FromFloat32(float val) {
|
||||||
|
|
|
@ -20,10 +20,12 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="renderer_opengl\renderer_opengl.cpp" />
|
<ClCompile Include="renderer_opengl\renderer_opengl.cpp" />
|
||||||
|
<ClCompile Include="command_processor.cpp" />
|
||||||
<ClCompile Include="utils.cpp" />
|
<ClCompile Include="utils.cpp" />
|
||||||
<ClCompile Include="video_core.cpp" />
|
<ClCompile Include="video_core.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="command_processor.h" />
|
||||||
<ClInclude Include="gpu_debugger.h" />
|
<ClInclude Include="gpu_debugger.h" />
|
||||||
<ClInclude Include="math.h" />
|
<ClInclude Include="math.h" />
|
||||||
<ClInclude Include="pica.h" />
|
<ClInclude Include="pica.h" />
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<ClCompile Include="renderer_opengl\renderer_opengl.cpp">
|
<ClCompile Include="renderer_opengl\renderer_opengl.cpp">
|
||||||
<Filter>renderer_opengl</Filter>
|
<Filter>renderer_opengl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="command_processor.cpp" />
|
||||||
<ClCompile Include="utils.cpp" />
|
<ClCompile Include="utils.cpp" />
|
||||||
<ClCompile Include="video_core.cpp" />
|
<ClCompile Include="video_core.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
<ClInclude Include="renderer_opengl\renderer_opengl.h">
|
<ClInclude Include="renderer_opengl\renderer_opengl.h">
|
||||||
<Filter>renderer_opengl</Filter>
|
<Filter>renderer_opengl</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="command_processor.h" />
|
||||||
<ClInclude Include="gpu_debugger.h" />
|
<ClInclude Include="gpu_debugger.h" />
|
||||||
<ClInclude Include="math.h" />
|
<ClInclude Include="math.h" />
|
||||||
<ClInclude Include="pica.h" />
|
<ClInclude Include="pica.h" />
|
||||||
|
|
Loading…
Reference in New Issue