Skip to content

Commit

Permalink
Merge pull request #16127 from hrydgard/silent-hill-fixes
Browse files Browse the repository at this point in the history
Fixes for Silent Hill: Origins (depth buffer reassignment, eliminate readback)
  • Loading branch information
hrydgard authored Sep 28, 2022
2 parents ef7900f + 8534b8d commit 7a4830e
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 11 deletions.
6 changes: 3 additions & 3 deletions Common/GPU/Vulkan/VulkanProfiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ void VulkanProfiler::BeginFrame(VulkanContext *vulkan, VkCommandBuffer firstComm
static const char * const indent[4] = { "", " ", " ", " " };

if (!scopes_.empty()) {
NOTICE_LOG(G3D, "Profiling events this frame:");
INFO_LOG(G3D, "Profiling events this frame:");
}

// Log it all out.
for (auto &scope : scopes_) {
if (scope.endQueryId == -1) {
NOTICE_LOG(G3D, "Unclosed scope: %s", scope.name.c_str());
WARN_LOG(G3D, "Unclosed scope: %s", scope.name.c_str());
continue;
}
uint64_t startTime = results[scope.startQueryId];
Expand All @@ -50,7 +50,7 @@ void VulkanProfiler::BeginFrame(VulkanContext *vulkan, VkCommandBuffer firstComm

double milliseconds = (double)delta * timestampConversionFactor;

NOTICE_LOG(G3D, "%s%s (%0.3f ms)", indent[scope.level & 3], scope.name.c_str(), milliseconds);
INFO_LOG(G3D, "%s%s (%0.3f ms)", indent[scope.level & 3], scope.name.c_str(), milliseconds);
}

scopes_.clear();
Expand Down
22 changes: 20 additions & 2 deletions Common/GPU/Vulkan/VulkanRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,34 @@ VKRFramebuffer::VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VKRRe
_dbg_assert_(tag);

CreateImage(vulkan_, initCmd, color, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true, tag);
vulkan_->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_color_%s", tag).c_str());
if (createDepthStencilBuffer) {
CreateImage(vulkan_, initCmd, depth, width, height, vulkan_->GetDeviceInfo().preferredDepthStencilFormat, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false, tag);
vulkan_->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_depth_%s", tag).c_str());
}

UpdateTag(tag);

// We create the actual framebuffer objects on demand, because some combinations might not make sense.
// Framebuffer objects are just pointers to a set of images, so no biggie.
}

void VKRFramebuffer::UpdateTag(const char *newTag) {
char name[128];
snprintf(name, sizeof(name), "fb_color_%s", tag_.c_str());
vulkan_->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, name);
vulkan_->SetDebugName(color.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, name);
if (depth.image) {
snprintf(name, sizeof(name), "fb_depth_%s", tag_.c_str());
vulkan_->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, name);
vulkan_->SetDebugName(depth.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, name);
}
for (int rpType = 0; rpType < RP_TYPE_COUNT; rpType++) {
if (framebuf[rpType]) {
snprintf(name, sizeof(name), "fb_%s", tag_.c_str());
vulkan_->SetDebugName(framebuf[(int)rpType], VK_OBJECT_TYPE_FRAMEBUFFER, name);
}
}
}

VkFramebuffer VKRFramebuffer::Get(VKRRenderPass *compatibleRenderPass, RenderPassType rpType) {
if (framebuf[(int)rpType]) {
return framebuf[(int)rpType];
Expand Down
2 changes: 2 additions & 0 deletions Common/GPU/Vulkan/VulkanRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class VKRFramebuffer {
return tag_.c_str();
}

void UpdateTag(const char *newTag);

// TODO: Hide.
VulkanContext *vulkan_;
private:
Expand Down
3 changes: 3 additions & 0 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,9 @@ class VKFramebuffer : public Framebuffer {
buf_ = nullptr;
}
VKRFramebuffer *GetFB() const { return buf_; }
void UpdateTag(const char *newTag) override {
buf_->UpdateTag(newTag);
}
private:
VKRFramebuffer *buf_;
};
Expand Down
1 change: 1 addition & 0 deletions Common/GPU/thin3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ class Framebuffer : public RefCountedObject {
public:
int Width() { return width_; }
int Height() { return height_; }
virtual void UpdateTag(const char *tag) {}
protected:
int width_ = -1, height_ = -1;
};
Expand Down
25 changes: 19 additions & 6 deletions GPU/Common/FramebufferManagerCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
#include "GPU/GPUInterface.h"
#include "GPU/GPUState.h"

static size_t FormatFramebufferName(VirtualFramebuffer *vfb, char *tag, size_t len) {
return snprintf(tag, len, "FB_%08x_%08x_%dx%d_%s", vfb->fb_address, vfb->z_address, vfb->bufferWidth, vfb->bufferHeight, GeBufferFormatToString(vfb->fb_format));
}

FramebufferManagerCommon::FramebufferManagerCommon(Draw::DrawContext *draw)
: draw_(draw), draw2D_(draw_) {
presentation_ = new PresentationCommon(draw);
Expand Down Expand Up @@ -551,6 +555,19 @@ void FramebufferManagerCommon::SetDepthFrameBuffer(bool isClearingDepth) {
bool newlyUsingDepth = (currentRenderVfb_->usageFlags & FB_USAGE_RENDER_DEPTH) == 0;
currentRenderVfb_->usageFlags |= FB_USAGE_RENDER_DEPTH;

uint32_t boundDepthBuffer = gstate.getDepthBufAddress() & 0x3FFFFFFF;
if (currentRenderVfb_->z_address != boundDepthBuffer) {
WARN_LOG_N_TIMES(z_reassign, 5, G3D, "Framebuffer at %08x/%d has switched associated depth buffer from %08x to %08x, updating.",
currentRenderVfb_->fb_address, currentRenderVfb_->fb_stride, currentRenderVfb_->z_address, boundDepthBuffer);

// Technically, here we should copy away the depth buffer to another framebuffer that uses that z_address, or maybe
// even write it back to RAM. However, this is rare. Silent Hill is one example, see #16126.
currentRenderVfb_->z_address = boundDepthBuffer;
char tag[128];
FormatFramebufferName(currentRenderVfb_, tag, sizeof(tag));
currentRenderVfb_->fbo->UpdateTag(tag);
}

// If this first draw call is anything other than a clear, "resolve" the depth buffer,
// by copying from any overlapping buffers with fresher content.
if (!isClearingDepth && useBufferedRendering_) {
Expand Down Expand Up @@ -1486,10 +1503,6 @@ void FramebufferManagerCommon::DecimateFBOs() {
}
}

static size_t FormatFramebufferName(VirtualFramebuffer *vfb, char *tag, size_t len) {
return snprintf(tag, len, "FB_%08x_%08x_%dx%d_%s", vfb->fb_address, vfb->z_address, vfb->bufferWidth, vfb->bufferHeight, GeBufferFormatToString(vfb->fb_format));
}

// Requires width/height to be set already.
void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, int h, bool force, bool skipCopy) {
_dbg_assert_(w > 0);
Expand Down Expand Up @@ -1541,9 +1554,9 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w,

bool creating = old.bufferWidth == 0;
if (creating) {
WARN_LOG(FRAMEBUF, "Creating %s FBO at %08x/%d %dx%d (force=%d)", GeBufferFormatToString(vfb->fb_format), vfb->fb_address, vfb->fb_stride, vfb->bufferWidth, vfb->bufferHeight, (int)force);
WARN_LOG(FRAMEBUF, "Creating %s FBO at %08x/%08x stride=%d %dx%d (force=%d)", GeBufferFormatToString(vfb->fb_format), vfb->fb_address, vfb->z_address, vfb->fb_stride, vfb->bufferWidth, vfb->bufferHeight, (int)force);
} else {
WARN_LOG(FRAMEBUF, "Resizing %s FBO at %08x/%d from %dx%d to %dx%d (force=%d, skipCopy=%d)", GeBufferFormatToString(vfb->fb_format), vfb->fb_address, vfb->fb_stride, old.bufferWidth, old.bufferHeight, vfb->bufferWidth, vfb->bufferHeight, (int)force, (int)skipCopy);
WARN_LOG(FRAMEBUF, "Resizing %s FBO at %08x/%08x stride=%d from %dx%d to %dx%d (force=%d, skipCopy=%d)", GeBufferFormatToString(vfb->fb_format), vfb->fb_address, vfb->z_address, vfb->fb_stride, old.bufferWidth, old.bufferHeight, vfb->bufferWidth, vfb->bufferHeight, (int)force, (int)skipCopy);
}

// During hardware rendering, we always render at full color depth even if the game wouldn't on real hardware.
Expand Down
8 changes: 8 additions & 0 deletions assets/compat.ini
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,14 @@ ULUS10428 = true
ULES01375 = true
ULUS10429 = true

# Silent Hill: Origins
# Avoids readback.
ULES00869 = true
ULUS10285 = true
ULKS46161 = true
ULJM05281 = true
NPJH50051 = true

[IntraVRAMBlockTransferAllowCreateFB]
# Final Fantasy - Type 0
ULJM05900 = true
Expand Down

0 comments on commit 7a4830e

Please sign in to comment.