mirror of
https://github.com/PabloMK7/citra
synced 2024-11-14 20:58:23 +00:00
Fixup logic for GSP_GPU::TriggerCmdReqQueue (#177)
This commit is contained in:
parent
4780a7134d
commit
cc220928bd
2 changed files with 33 additions and 7 deletions
|
@ -71,7 +71,12 @@ struct CacheFlushCommand {
|
||||||
|
|
||||||
/// GSP command
|
/// GSP command
|
||||||
struct Command {
|
struct Command {
|
||||||
BitField<0, 8, CommandId> id;
|
union {
|
||||||
|
BitField<0, 8, CommandId> id;
|
||||||
|
BitField<8, 8, u32> unknown1;
|
||||||
|
BitField<16, 8, u32> stop;
|
||||||
|
BitField<24, 8, u32> unknown2;
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
DmaCommand dma_request;
|
DmaCommand dma_request;
|
||||||
SubmitCmdListCommand submit_gpu_cmdlist;
|
SubmitCmdListCommand submit_gpu_cmdlist;
|
||||||
|
@ -86,6 +91,8 @@ static_assert(sizeof(Command) == 0x20, "Command struct has incorrect size");
|
||||||
|
|
||||||
/// GSP shared memory GX command buffer header
|
/// GSP shared memory GX command buffer header
|
||||||
struct CommandBuffer {
|
struct CommandBuffer {
|
||||||
|
static constexpr u32 STATUS_STOPPED = 0x1;
|
||||||
|
static constexpr u32 STATUS_CMD_FAILED = 0x80;
|
||||||
union {
|
union {
|
||||||
u32 hex;
|
u32 hex;
|
||||||
|
|
||||||
|
@ -99,6 +106,11 @@ struct CommandBuffer {
|
||||||
// application when writing a command to shared memory, after increasing this value
|
// application when writing a command to shared memory, after increasing this value
|
||||||
// TriggerCmdReqQueue is only used if this field is value 1.
|
// TriggerCmdReqQueue is only used if this field is value 1.
|
||||||
BitField<8, 8, u32> number_commands;
|
BitField<8, 8, u32> number_commands;
|
||||||
|
|
||||||
|
// When any of the following flags are set to 1, the GSP module stops processing the
|
||||||
|
// commands in the command buffer.
|
||||||
|
BitField<16, 8, u32> status;
|
||||||
|
BitField<24, 8, u32> should_stop;
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 unk[7];
|
u32 unk[7];
|
||||||
|
|
|
@ -408,17 +408,31 @@ void GSP_GPU::SetLcdForceBlack(Kernel::HLERequestContext& ctx) {
|
||||||
void GSP_GPU::TriggerCmdReqQueue(Kernel::HLERequestContext& ctx) {
|
void GSP_GPU::TriggerCmdReqQueue(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx);
|
IPC::RequestParser rp(ctx);
|
||||||
|
|
||||||
// Iterate through each command.
|
|
||||||
auto* command_buffer = GetCommandBuffer(active_thread_id);
|
auto* command_buffer = GetCommandBuffer(active_thread_id);
|
||||||
auto& gpu = system.GPU();
|
auto& gpu = system.GPU();
|
||||||
for (u32 i = 0; i < command_buffer->number_commands; i++) {
|
while (command_buffer->number_commands) {
|
||||||
gpu.Debugger().GXCommandProcessed(command_buffer->commands[i]);
|
if (command_buffer->should_stop) {
|
||||||
|
command_buffer->status.Assign(CommandBuffer::STATUS_STOPPED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (command_buffer->status == CommandBuffer::STATUS_STOPPED) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command command = command_buffer->commands[command_buffer->index];
|
||||||
|
|
||||||
|
// Decrease the number of commands remaining and increase the current index
|
||||||
|
command_buffer->number_commands.Assign(command_buffer->number_commands - 1);
|
||||||
|
command_buffer->index.Assign((command_buffer->index + 1) % 0xF);
|
||||||
|
|
||||||
|
gpu.Debugger().GXCommandProcessed(command);
|
||||||
|
|
||||||
// Decode and execute command
|
// Decode and execute command
|
||||||
gpu.Execute(command_buffer->commands[i]);
|
gpu.Execute(command);
|
||||||
|
|
||||||
// Indicates that command has completed
|
if (command.stop) {
|
||||||
command_buffer->number_commands.Assign(command_buffer->number_commands - 1);
|
command_buffer->should_stop.Assign(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
|
Loading…
Reference in a new issue