Adding vblank interrupt.
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/graphics_system.h>
|
||||
|
||||
|
||||
#include <xenia/cpu/processor.h>
|
||||
#include <xenia/gpu/ring_buffer_worker.h>
|
||||
|
||||
|
||||
@@ -16,7 +17,8 @@ using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
|
||||
|
||||
GraphicsSystem::GraphicsSystem(const CreationParams* params) {
|
||||
GraphicsSystem::GraphicsSystem(const CreationParams* params) :
|
||||
interrupt_callback_(0), interrupt_callback_data_(0) {
|
||||
memory_ = xe_memory_retain(params->memory);
|
||||
|
||||
worker_ = new RingBufferWorker(memory_);
|
||||
@@ -33,6 +35,21 @@ xe_memory_ref GraphicsSystem::memory() {
|
||||
return xe_memory_retain(memory_);
|
||||
}
|
||||
|
||||
shared_ptr<cpu::Processor> GraphicsSystem::processor() {
|
||||
return processor_;
|
||||
}
|
||||
|
||||
void GraphicsSystem::set_processor(shared_ptr<cpu::Processor> processor) {
|
||||
processor_ = processor;
|
||||
}
|
||||
|
||||
void GraphicsSystem::SetInterruptCallback(uint32_t callback,
|
||||
uint32_t user_data) {
|
||||
interrupt_callback_ = callback;
|
||||
interrupt_callback_data_ = user_data;
|
||||
XELOGGPU("SetInterruptCallback(%.4X, %.4X)", callback, user_data);
|
||||
}
|
||||
|
||||
void GraphicsSystem::InitializeRingBuffer(uint32_t ptr, uint32_t page_count) {
|
||||
worker_->Initialize(ptr, page_count);
|
||||
}
|
||||
@@ -44,6 +61,12 @@ void GraphicsSystem::EnableReadPointerWriteBack(uint32_t ptr,
|
||||
|
||||
uint64_t GraphicsSystem::ReadRegister(uint32_t r) {
|
||||
XELOGGPU("ReadRegister(%.4X)", r);
|
||||
|
||||
switch (r) {
|
||||
case 0x6544: // ? vblank pending?
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -60,3 +83,12 @@ void GraphicsSystem::WriteRegister(uint32_t r, uint64_t value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsSystem::DispatchInterruptCallback() {
|
||||
// NOTE: we may be executing in some random thread.
|
||||
if (!interrupt_callback_) {
|
||||
return;
|
||||
}
|
||||
processor_->ExecuteInterrupt(
|
||||
interrupt_callback_, 0, interrupt_callback_data_);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
#include <xenia/core.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
class Processor;
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
|
||||
@@ -32,19 +39,25 @@ public:
|
||||
virtual ~GraphicsSystem();
|
||||
|
||||
xe_memory_ref memory();
|
||||
shared_ptr<cpu::Processor> processor();
|
||||
void set_processor(shared_ptr<cpu::Processor> processor);
|
||||
|
||||
virtual void Initialize() = 0;
|
||||
void SetInterruptCallback(uint32_t callback, uint32_t user_data);
|
||||
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count);
|
||||
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size);
|
||||
|
||||
virtual uint64_t ReadRegister(uint32_t r);
|
||||
virtual void WriteRegister(uint32_t r, uint64_t value);
|
||||
|
||||
void DispatchInterruptCallback();
|
||||
|
||||
public:
|
||||
static uint64_t ReadRegisterThunk(GraphicsSystem* this_ptr, uint32_t r) {
|
||||
return this_ptr->ReadRegister(r);
|
||||
}
|
||||
static void WriteRegisterThunk(GraphicsSystem* this_ptr, uint32_t r, uint64_t value) {
|
||||
static void WriteRegisterThunk(GraphicsSystem* this_ptr, uint32_t r,
|
||||
uint64_t value) {
|
||||
this_ptr->WriteRegister(r, value);
|
||||
}
|
||||
|
||||
@@ -52,8 +65,12 @@ protected:
|
||||
GraphicsSystem(const CreationParams* params);
|
||||
|
||||
xe_memory_ref memory_;
|
||||
shared_ptr<cpu::Processor> processor_;
|
||||
|
||||
RingBufferWorker* worker_;
|
||||
|
||||
uint32_t interrupt_callback_;
|
||||
uint32_t interrupt_callback_data_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,12 +17,41 @@ using namespace xe::gpu;
|
||||
using namespace xe::gpu::nop;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void __stdcall NopGraphicsSystemVsyncCallback(NopGraphicsSystem* gs, BOOLEAN) {
|
||||
gs->DispatchInterruptCallback();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
NopGraphicsSystem::NopGraphicsSystem(const CreationParams* params) :
|
||||
GraphicsSystem(params) {
|
||||
GraphicsSystem(params),
|
||||
timer_queue_(NULL),
|
||||
vsync_timer_(NULL) {
|
||||
}
|
||||
|
||||
NopGraphicsSystem::~NopGraphicsSystem() {
|
||||
if (vsync_timer_) {
|
||||
DeleteTimerQueueTimer(timer_queue_, vsync_timer_, NULL);
|
||||
}
|
||||
if (timer_queue_) {
|
||||
DeleteTimerQueueEx(timer_queue_, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void NopGraphicsSystem::Initialize() {
|
||||
XEASSERTNULL(timer_queue_);
|
||||
XEASSERTNULL(vsync_timer_);
|
||||
|
||||
timer_queue_ = CreateTimerQueue();
|
||||
CreateTimerQueueTimer(
|
||||
&vsync_timer_,
|
||||
timer_queue_,
|
||||
(WAITORTIMERCALLBACK)NopGraphicsSystemVsyncCallback,
|
||||
this,
|
||||
16,
|
||||
100,
|
||||
WT_EXECUTEINTIMERTHREAD);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ public:
|
||||
virtual ~NopGraphicsSystem();
|
||||
|
||||
virtual void Initialize();
|
||||
|
||||
private:
|
||||
HANDLE timer_queue_;
|
||||
HANDLE vsync_timer_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user