mirror of
https://github.com/PabloMK7/citra.git
synced 2024-11-19 22:16:36 +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
|
||||
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 {
|
||||
DmaCommand dma_request;
|
||||
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
|
||||
struct CommandBuffer {
|
||||
static constexpr u32 STATUS_STOPPED = 0x1;
|
||||
static constexpr u32 STATUS_CMD_FAILED = 0x80;
|
||||
union {
|
||||
u32 hex;
|
||||
|
||||
|
@ -99,6 +106,11 @@ struct CommandBuffer {
|
|||
// application when writing a command to shared memory, after increasing this value
|
||||
// TriggerCmdReqQueue is only used if this field is value 1.
|
||||
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];
|
||||
|
|
|
@ -408,17 +408,31 @@ void GSP_GPU::SetLcdForceBlack(Kernel::HLERequestContext& ctx) {
|
|||
void GSP_GPU::TriggerCmdReqQueue(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx);
|
||||
|
||||
// Iterate through each command.
|
||||
auto* command_buffer = GetCommandBuffer(active_thread_id);
|
||||
auto& gpu = system.GPU();
|
||||
for (u32 i = 0; i < command_buffer->number_commands; i++) {
|
||||
gpu.Debugger().GXCommandProcessed(command_buffer->commands[i]);
|
||||
while (command_buffer->number_commands) {
|
||||
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
|
||||
gpu.Execute(command_buffer->commands[i]);
|
||||
gpu.Execute(command);
|
||||
|
||||
// Indicates that command has completed
|
||||
command_buffer->number_commands.Assign(command_buffer->number_commands - 1);
|
||||
if (command.stop) {
|
||||
command_buffer->should_stop.Assign(1);
|
||||
}
|
||||
}
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
|
|
Loading…
Reference in a new issue