Skip to content

Commit

Permalink
Vulkan: Improve the Metal Gear Acid 2 performance hack.
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Aug 8, 2019
1 parent 6e78ec9 commit ebe64c6
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 12 deletions.
26 changes: 14 additions & 12 deletions assets/compat.ini
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,13 @@ NPJH50036 = true

# Burnout games have problems with this on Mali, and have no use for it
# Legends
ULES00125 = true
ULUS10025 = true
ULJM05228 = true
NPJH50305 = true
ULJM05049 = true
ULKS46027 = true
ULAS42019 = true
#ULES00125 = true
#ULUS10025 = true
#ULJM05228 = true
#NPJH50305 = true
#ULJM05049 = true
#ULKS46027 = true
#ULAS42019 = true

# Dominator
ULUS10236 = true
Expand Down Expand Up @@ -441,15 +441,17 @@ ULES01376 = true
ULUS10466 = true

[MGS2AcidHack]
ULUS10006 = true # Metal Gear Acid
ULES00008 = true
ULJM05001 = true
ULAS42007 = true
ULJM08001 = true
ULUS10077 = true # Metal Gear Acid 2
ULAS42035 = true
ULES00284 = true
ULJM05047 = true
ULKS46065 = true
ULJM08001 = true
ULJM05001 = true
ULAS42007 = true
ULUS10006 = true
ULUS10077 = true
ULJM08011 = true

[SonicRivalsHack]
ULES00622 = true # SR1
Expand Down
74 changes: 74 additions & 0 deletions ext/native/thin3d/VulkanQueueRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,8 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
}

void VulkanQueueRunner::ApplyMGSHack(std::vector<VKRStep *> &steps) {
// Really need a sane way to express transforms of steps.

// We want to turn a sequence of copy,render(1),copy,render(1),copy,render(1) to copy,copy,copy,render(n).

for (int i = 0; i < (int)steps.size() - 3; i++) {
Expand Down Expand Up @@ -530,6 +532,78 @@ void VulkanQueueRunner::ApplyMGSHack(std::vector<VKRStep *> &steps) {
break;
}
}

// There's also a post processing effect using depals that's just brutal in some parts
// of the game.
for (int i = 0; i < (int)steps.size() - 3; i++) {
int last = -1;
if (!(steps[i]->stepType == VKRStepType::RENDER &&
steps[i + 1]->stepType == VKRStepType::RENDER &&
steps[i + 2]->stepType == VKRStepType::RENDER &&
steps[i]->render.numDraws == 1 &&
steps[i + 1]->render.numDraws == 1 &&
steps[i + 2]->render.numDraws == 1 &&
steps[i]->render.color == VKRRenderPassAction::DONT_CARE &&
steps[i + 1]->render.color == VKRRenderPassAction::KEEP &&
steps[i + 2]->render.color == VKRRenderPassAction::DONT_CARE))
continue;
VKRFramebuffer *depalFramebuffer = steps[i]->render.framebuffer;
VKRFramebuffer *targetFramebuffer = steps[i + 1]->render.framebuffer;
// OK, found the start of a post-process sequence. Let's scan until we find the end.
for (int j = i; j < steps.size() - 3; j++) {
if (((j - i) & 1) == 0) {
// This should be a depal draw.
if (steps[j]->render.numDraws != 1)
break;
if (steps[j]->render.color != VKRRenderPassAction::DONT_CARE)
break;
if (steps[j]->render.framebuffer != depalFramebuffer)
break;
last = j;
} else {
// This should be a target draw.
if (steps[j]->render.numDraws != 1)
break;
if (steps[j]->render.color != VKRRenderPassAction::KEEP)
break;
if (steps[j]->render.framebuffer != targetFramebuffer)
break;
last = j;
}
}

if (last == -1)
continue;

// Combine the depal renders.
for (int j = i + 2; j <= last + 1; j += 2) {
for (int k = 0; k < (int)steps[j]->commands.size(); k++) {
switch (steps[j]->commands[k].cmd) {
case VKRRenderCommand::DRAW:
case VKRRenderCommand::DRAW_INDEXED:
steps[i]->commands.push_back(steps[j]->commands[k]);
break;
}
}
steps[j]->stepType = VKRStepType::RENDER_SKIP;
}

// Combine the target renders.
for (int j = i + 3; j <= last; j += 2) {
for (int k = 0; k < (int)steps[j]->commands.size(); k++) {
switch (steps[j]->commands[k].cmd) {
case VKRRenderCommand::DRAW:
case VKRRenderCommand::DRAW_INDEXED:
steps[i + 1]->commands.push_back(steps[j]->commands[k]);
break;
}
}
steps[j]->stepType = VKRStepType::RENDER_SKIP;
}

// We're done - we only expect one of these sequences per frame.
break;
}
}

void VulkanQueueRunner::ApplySonicHack(std::vector<VKRStep *> &steps) {
Expand Down

0 comments on commit ebe64c6

Please sign in to comment.