Merge pull request #416 from bunnei/fake-dsp-interrupt
DSP: Signal (faked) interrupt on every frame.
This commit is contained in:
commit
4828d0b7af
3 changed files with 28 additions and 5 deletions
|
@ -12,9 +12,23 @@
|
||||||
|
|
||||||
namespace DSP_DSP {
|
namespace DSP_DSP {
|
||||||
|
|
||||||
static u32 read_pipe_count;
|
static u32 read_pipe_count = 0;
|
||||||
static Handle semaphore_event;
|
static Handle semaphore_event = 0;
|
||||||
static Handle interrupt_event;
|
static Handle interrupt_event = 0;
|
||||||
|
|
||||||
|
void SignalInterrupt() {
|
||||||
|
// TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
|
||||||
|
// application that a DSP interrupt occurred, without specifying which one. Since we do not
|
||||||
|
// emulate the DSP yet (and how it works is largely unknown), this is a work around to get games
|
||||||
|
// that check the DSP interrupt signal event to run. We should figure out the different types of
|
||||||
|
// DSP interrupts, and trigger them at the appropriate times.
|
||||||
|
|
||||||
|
if (interrupt_event == 0) {
|
||||||
|
LOG_WARNING(Service_DSP, "cannot signal interrupt until DSP event has been created!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Kernel::SignalEvent(interrupt_event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DSP_DSP::ConvertProcessAddressFromDspDram service function
|
* DSP_DSP::ConvertProcessAddressFromDspDram service function
|
||||||
|
@ -102,7 +116,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
|
||||||
void WriteReg0x10(Service::Interface* self) {
|
void WriteReg0x10(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
Kernel::SignalEvent(interrupt_event);
|
SignalInterrupt();
|
||||||
|
|
||||||
cmd_buff[1] = 0; // No error
|
cmd_buff[1] = 0; // No error
|
||||||
|
|
||||||
|
|
|
@ -20,4 +20,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Signals that a DSP interrupt has occurred to userland code
|
||||||
|
void SignalInterrupt();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "core/hle/hle.h"
|
#include "core/hle/hle.h"
|
||||||
#include "core/hle/service/gsp_gpu.h"
|
#include "core/hle/service/gsp_gpu.h"
|
||||||
|
#include "core/hle/service/dsp_dsp.h"
|
||||||
|
|
||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
|
|
||||||
|
@ -214,13 +215,18 @@ void Update() {
|
||||||
// - If frameskip == 0 (disabled), always swap buffers
|
// - If frameskip == 0 (disabled), always swap buffers
|
||||||
// - If frameskip == 1, swap buffers every other frame (starting from the first frame)
|
// - If frameskip == 1, swap buffers every other frame (starting from the first frame)
|
||||||
// - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame)
|
// - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame)
|
||||||
|
|
||||||
if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) ||
|
if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) ||
|
||||||
Settings::values.frame_skip == 0) {
|
Settings::values.frame_skip == 0) {
|
||||||
VideoCore::g_renderer->SwapBuffers();
|
VideoCore::g_renderer->SwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Signal to GSP that GPU interrupt has occurred
|
||||||
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1);
|
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1);
|
||||||
|
|
||||||
|
// TODO(bunnei): Fake a DSP interrupt on each frame. This does not belong here, but
|
||||||
|
// until we can emulate DSP interrupts, this is probably the only reasonable place to do
|
||||||
|
// this. Certain games expect this to be periodically signaled.
|
||||||
|
DSP_DSP::SignalInterrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue