Unify FastRunLoop for the hardware backends.

This commit is contained in:
Henrik Rydgård 2018-02-26 11:52:16 +01:00
parent 6a2f45c2e1
commit 78467d6092
10 changed files with 40 additions and 158 deletions

View File

@ -289,44 +289,6 @@ void GPU_D3D11::CopyDisplayToOutput() {
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
// Maybe should write this in ASM...
void GPU_D3D11::FastRunLoop(DisplayList &list) {
PROFILE_THIS_SCOPE("gpuloop");
const CommandInfo *cmdInfo = cmdInfo_;
int dc = downcount;
for (; dc > 0; --dc) {
// We know that display list PCs have the upper nibble == 0 - no need to mask the pointer
const u32 op = *(const u32 *)(Memory::base + list.pc);
const u32 cmd = op >> 24;
const CommandInfo &info = cmdInfo[cmd];
const u32 diff = op ^ gstate.cmdmem[cmd];
if (diff == 0) {
if (info.flags & FLAG_EXECUTE) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
}
} else {
uint64_t flags = info.flags;
if (flags & FLAG_FLUSHBEFOREONCHANGE) {
drawEngine_.Flush();
}
gstate.cmdmem[cmd] = op;
if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
} else {
uint64_t dirty = flags >> 8;
if (dirty)
gstate_c.Dirty(dirty);
}
}
list.pc += 4;
}
downcount = 0;
}
void GPU_D3D11::FinishDeferred() {
// This finishes reading any vertex data that is pending.
drawEngine_.FinishDeferred();

View File

@ -66,7 +66,6 @@ public:
void EndHostFrame() override;
protected:
void FastRunLoop(DisplayList &list) override;
void FinishDeferred() override;
private:

View File

@ -265,44 +265,6 @@ void GPU_DX9::CopyDisplayToOutput() {
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
// Maybe should write this in ASM...
void GPU_DX9::FastRunLoop(DisplayList &list) {
PROFILE_THIS_SCOPE("gpuloop");
const CommandInfo *cmdInfo = cmdInfo_;
int dc = downcount;
for (; dc > 0; --dc) {
// We know that display list PCs have the upper nibble == 0 - no need to mask the pointer
const u32 op = *(const u32 *)(Memory::base + list.pc);
const u32 cmd = op >> 24;
const CommandInfo &info = cmdInfo[cmd];
const u32 diff = op ^ gstate.cmdmem[cmd];
if (diff == 0) {
if (info.flags & FLAG_EXECUTE) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
}
} else {
uint64_t flags = info.flags;
if (flags & FLAG_FLUSHBEFOREONCHANGE) {
drawEngine_.Flush();
}
gstate.cmdmem[cmd] = op;
if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
} else {
uint64_t dirty = flags >> 8;
if (dirty)
gstate_c.Dirty(dirty);
}
}
list.pc += 4;
}
downcount = 0;
}
void GPU_DX9::FinishDeferred() {
// This finishes reading any vertex data that is pending.
drawEngine_.FinishDeferred();

View File

@ -66,7 +66,6 @@ public:
void BeginHostFrame() override;
protected:
void FastRunLoop(DisplayList &list) override;
void FinishDeferred() override;
private:

View File

@ -481,44 +481,6 @@ void GPU_GLES::CopyDisplayToOutput() {
#endif
}
// Maybe should write this in ASM...
void GPU_GLES::FastRunLoop(DisplayList &list) {
PROFILE_THIS_SCOPE("gpuloop");
const CommandInfo *cmdInfo = cmdInfo_;
int dc = downcount;
for (; dc > 0; --dc) {
// We know that display list PCs have the upper nibble == 0 - no need to mask the pointer
const u32 op = *(const u32 *)(Memory::base + list.pc);
const u32 cmd = op >> 24;
const CommandInfo &info = cmdInfo[cmd];
const u32 diff = op ^ gstate.cmdmem[cmd];
if (diff == 0) {
if (info.flags & FLAG_EXECUTE) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
}
} else {
uint64_t flags = info.flags;
if (flags & FLAG_FLUSHBEFOREONCHANGE) {
drawEngine_.Flush();
}
gstate.cmdmem[cmd] = op;
if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
} else {
uint64_t dirty = flags >> 8;
if (dirty)
gstate_c.Dirty(dirty);
}
}
list.pc += 4;
}
downcount = 0;
}
void GPU_GLES::FinishDeferred() {
// This finishes reading any vertex data that is pending.
drawEngine_.FinishDeferred();

View File

@ -71,7 +71,6 @@ public:
void EndHostFrame() override;
protected:
void FastRunLoop(DisplayList &list) override;
void FinishDeferred() override;
private:

View File

@ -965,6 +965,44 @@ bool GPUCommon::InterpretList(DisplayList &list) {
return gpuState == GPUSTATE_DONE || gpuState == GPUSTATE_ERROR;
}
// Maybe should write this in ASM...
void GPUCommon::FastRunLoop(DisplayList &list) {
PROFILE_THIS_SCOPE("gpuloop");
const CommandInfo *cmdInfo = cmdInfo_;
int dc = downcount;
for (; dc > 0; --dc) {
// We know that display list PCs have the upper nibble == 0 - no need to mask the pointer
const u32 op = *(const u32 *)(Memory::base + list.pc);
const u32 cmd = op >> 24;
const CommandInfo &info = cmdInfo[cmd];
const u32 diff = op ^ gstate.cmdmem[cmd];
if (diff == 0) {
if (info.flags & FLAG_EXECUTE) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
}
} else {
uint64_t flags = info.flags;
if (flags & FLAG_FLUSHBEFOREONCHANGE) {
drawEngineCommon_->DispatchFlush();
}
gstate.cmdmem[cmd] = op;
if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
} else {
uint64_t dirty = flags >> 8;
if (dirty)
gstate_c.Dirty(dirty);
}
}
list.pc += 4;
}
downcount = 0;
}
void GPUCommon::BeginFrame() {
immCount_ = 0;
if (dumpNextFrame_) {

View File

@ -265,8 +265,8 @@ protected:
void BeginFrame() override;
// To avoid virtual calls to PreExecuteOp().
virtual void FastRunLoop(DisplayList &list) = 0;
virtual void FastRunLoop(DisplayList &list);
void SlowRunLoop(DisplayList &list);
void UpdatePC(u32 currentPC, u32 newPC);
void UpdateState(GPURunState state);

View File

@ -376,44 +376,6 @@ void GPU_Vulkan::CopyDisplayToOutput() {
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
// Maybe should write this in ASM...
void GPU_Vulkan::FastRunLoop(DisplayList &list) {
PROFILE_THIS_SCOPE("gpuloop");
const CommandInfo *cmdInfo = cmdInfo_;
int dc = downcount;
for (; dc > 0; --dc) {
// We know that display list PCs have the upper nibble == 0 - no need to mask the pointer
const u32 op = *(const u32 *)(Memory::base + list.pc);
const u32 cmd = op >> 24;
const CommandInfo &info = cmdInfo[cmd];
const u32 diff = op ^ gstate.cmdmem[cmd];
if (diff == 0) {
if (info.flags & FLAG_EXECUTE) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
}
} else {
uint64_t flags = info.flags;
if (flags & FLAG_FLUSHBEFOREONCHANGE) {
drawEngine_.Flush();
}
gstate.cmdmem[cmd] = op;
if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) {
downcount = dc;
(this->*info.func)(op, diff);
dc = downcount;
} else {
uint64_t dirty = flags >> 8;
if (dirty)
gstate_c.Dirty(dirty);
}
}
list.pc += 4;
}
downcount = 0;
}
void GPU_Vulkan::FinishDeferred() {
drawEngine_.FinishDeferred();
}

View File

@ -71,7 +71,6 @@ public:
}
protected:
void FastRunLoop(DisplayList &list) override;
void FinishDeferred() override;
private: