Adding vblank interrupt.

This commit is contained in:
Ben Vanik
2013-09-25 00:46:09 -07:00
parent 998467ce05
commit 91f62918f6
8 changed files with 116 additions and 7 deletions

View File

@@ -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_);
}

View File

@@ -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_;
};

View File

@@ -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);
}

View File

@@ -27,6 +27,10 @@ public:
virtual ~NopGraphicsSystem();
virtual void Initialize();
private:
HANDLE timer_queue_;
HANDLE vsync_timer_;
};