DSP: Signal (faked) interrupt on every frame.
- Hack to work around games checking that the DSP event has been signaled by a real DSP interrupt.
This commit is contained in:
		
							parent
							
								
									cc23269ff4
								
							
						
					
					
						commit
						e9650f1c61
					
				@ -12,9 +12,23 @@
 | 
			
		||||
 | 
			
		||||
namespace DSP_DSP {
 | 
			
		||||
 | 
			
		||||
static u32 read_pipe_count;
 | 
			
		||||
static Handle semaphore_event;
 | 
			
		||||
static Handle interrupt_event;
 | 
			
		||||
static u32 read_pipe_count    = 0;
 | 
			
		||||
static Handle semaphore_event = 0;
 | 
			
		||||
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
 | 
			
		||||
@ -102,7 +116,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
 | 
			
		||||
void WriteReg0x10(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
 | 
			
		||||
    Kernel::SignalEvent(interrupt_event);
 | 
			
		||||
    SignalInterrupt();
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = 0; // No error
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -20,4 +20,7 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Signals that a DSP interrupt has occurred to userland code
 | 
			
		||||
void SignalInterrupt();
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@
 | 
			
		||||
 | 
			
		||||
#include "core/hle/hle.h"
 | 
			
		||||
#include "core/hle/service/gsp_gpu.h"
 | 
			
		||||
#include "core/hle/service/dsp_dsp.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hw/gpu.h"
 | 
			
		||||
 | 
			
		||||
@ -214,13 +215,18 @@ void Update() {
 | 
			
		||||
            //  - 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 frameskip^n frames (starting from the second frame)
 | 
			
		||||
 | 
			
		||||
            if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) || 
 | 
			
		||||
                   Settings::values.frame_skip == 0) {
 | 
			
		||||
                VideoCore::g_renderer->SwapBuffers();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Signal to GSP that GPU interrupt has occurred
 | 
			
		||||
            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 New Issue
	
	Block a user