Merge pull request #19490 from hrydgard/misc-fixes

Fix Z-buffer issue in Socom Fireteam Bravo character customizer, plus a couple of minor things
This commit is contained in:
Henrik Rydgård 2024-09-26 00:43:12 +02:00 committed by GitHub
commit 62b674e8f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 35 additions and 25 deletions

View file

@ -874,6 +874,7 @@ void FramebufferManagerCommon::CopyToColorFromOverlappingFramebuffers(VirtualFra
if (source.channel == RASTER_COLOR) {
Draw2DPipeline *pipeline = nullptr;
const char *pass_name = "N/A";
float scaleFactorX = 1.0f;
if (src->fb_format == dst->fb_format) {
gpuStats.numColorCopies++;
pipeline = Get2DPipeline(DRAW2D_COPY_COLOR);
@ -888,7 +889,6 @@ void FramebufferManagerCommon::CopyToColorFromOverlappingFramebuffers(VirtualFra
src->fb_address, GeBufferFormatToString(src->fb_format),
dst->fb_address, GeBufferFormatToString(dst->fb_format));
float scaleFactorX = 1.0f;
pipeline = GetReinterpretPipeline(src->fb_format, dst->fb_format, &scaleFactorX);
dstX1 *= scaleFactorX;
dstX2 *= scaleFactorX;
@ -904,6 +904,11 @@ void FramebufferManagerCommon::CopyToColorFromOverlappingFramebuffers(VirtualFra
BlitUsingRaster(src->fbo, 0.0f, 0.0f, srcWidth, srcHeight,
dst->fbo, dstX1, dstY1, dstX2, dstY2, false, dst->renderScaleFactor, pipeline, pass_name);
}
if (scaleFactorX == 1.0f && dst->z_address == src->z_address && dst->z_stride == src->z_stride) {
// We should also copy the depth buffer in this case!
BlitFramebufferDepth(src, dst, true);
}
}
}
@ -966,7 +971,7 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) {
delete v;
}
void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) {
void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst, bool allowSizeMismatch) {
_dbg_assert_(src && dst);
_dbg_assert_(src != dst);
@ -974,7 +979,7 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir
// Check that the depth address is even the same before actually blitting.
bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0;
bool matchingSize = (src->width == dst->width || (src->width == 512 && dst->width == 480) || (src->width == 480 && dst->width == 512)) && src->height == dst->height;
if (!matchingDepthBuffer || !matchingSize) {
if (!matchingDepthBuffer || (!matchingSize && !allowSizeMismatch)) {
return;
}

View file

@ -516,7 +516,7 @@ protected:
static void NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb);
void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth);
void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst);
void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst, bool allowSizeMismatch = false);
void ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, int h, bool force = false, bool skipCopy = false);

View file

@ -27,6 +27,7 @@
#include "Common/GPU/thin3d.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/TimeUtil.h"
#include "Common/MemoryUtil.h"
#include "Common/StringUtils.h"
#include "Common/GPU/Vulkan/VulkanContext.h"
@ -213,16 +214,16 @@ ShaderManagerVulkan::ShaderManagerVulkan(Draw::DrawContext *draw)
codeBuffer_ = new char[CODE_BUFFER_SIZE];
VulkanContext *vulkan = (VulkanContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
uboAlignment_ = vulkan->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment;
memset(&ub_base, 0, sizeof(ub_base));
memset(&ub_lights, 0, sizeof(ub_lights));
memset(&ub_bones, 0, sizeof(ub_bones));
static_assert(sizeof(ub_base) <= 512, "ub_base grew too big");
static_assert(sizeof(ub_lights) <= 512, "ub_lights grew too big");
static_assert(sizeof(ub_bones) <= 384, "ub_bones grew too big");
uniforms_ = (Uniforms *)AllocateAlignedMemory(sizeof(Uniforms), 16);
static_assert(sizeof(uniforms_->ub_base) <= 512, "ub_base grew too big");
static_assert(sizeof(uniforms_->ub_lights) <= 512, "ub_lights grew too big");
static_assert(sizeof(uniforms_->ub_bones) <= 384, "ub_bones grew too big");
}
ShaderManagerVulkan::~ShaderManagerVulkan() {
FreeAlignedMemory(uniforms_);
Clear();
delete[] codeBuffer_;
}
@ -278,11 +279,11 @@ uint64_t ShaderManagerVulkan::UpdateUniforms(bool useBufferedRendering) {
uint64_t dirty = gstate_c.GetDirtyUniforms();
if (dirty != 0) {
if (dirty & DIRTY_BASE_UNIFORMS)
BaseUpdateUniforms(&ub_base, dirty, false, useBufferedRendering);
BaseUpdateUniforms(&uniforms_->ub_base, dirty, false, useBufferedRendering);
if (dirty & DIRTY_LIGHT_UNIFORMS)
LightUpdateUniforms(&ub_lights, dirty);
LightUpdateUniforms(&uniforms_->ub_lights, dirty);
if (dirty & DIRTY_BONE_UNIFORMS)
BoneUpdateUniforms(&ub_bones, dirty);
BoneUpdateUniforms(&uniforms_->ub_bones, dirty);
}
gstate_c.CleanUniforms();
return dirty;

View file

@ -103,6 +103,13 @@ protected:
GShaderID id_;
};
struct Uniforms {
// Uniform block scratchpad. These (the relevant ones) are copied to the current pushbuffer at draw time.
UB_VS_FS_Base ub_base{};
UB_VS_Lights ub_lights{};
UB_VS_Bones ub_bones{};
};
class ShaderManagerVulkan : public ShaderManagerCommon {
public:
ShaderManagerVulkan(Draw::DrawContext *draw);
@ -139,15 +146,15 @@ public:
bool IsLightDirty() { return true; }
bool IsBoneDirty() { return true; }
uint32_t PushBaseBuffer(VulkanPushPool *dest, VkBuffer *buf) {
return dest->Push(&ub_base, sizeof(ub_base), uboAlignment_, buf);
uint32_t PushBaseBuffer(VulkanPushPool *dest, VkBuffer *buf) const {
return dest->Push(&uniforms_->ub_base, sizeof(uniforms_->ub_base), uboAlignment_, buf);
}
uint32_t PushLightBuffer(VulkanPushPool *dest, VkBuffer *buf) {
return dest->Push(&ub_lights, sizeof(ub_lights), uboAlignment_, buf);
uint32_t PushLightBuffer(VulkanPushPool *dest, VkBuffer *buf) const {
return dest->Push(&uniforms_->ub_lights, sizeof(uniforms_->ub_lights), uboAlignment_, buf);
}
// TODO: Only push half the bone buffer if we only have four bones.
uint32_t PushBoneBuffer(VulkanPushPool *dest, VkBuffer *buf) {
return dest->Push(&ub_bones, sizeof(ub_bones), uboAlignment_, buf);
uint32_t PushBoneBuffer(VulkanPushPool *dest, VkBuffer *buf) const {
return dest->Push(&uniforms_->ub_bones, sizeof(uniforms_->ub_bones), uboAlignment_, buf);
}
static bool LoadCacheFlags(FILE *f, DrawEngineVulkan *drawEngine);
@ -171,10 +178,8 @@ private:
char *codeBuffer_;
uint64_t uboAlignment_;
// Uniform block scratchpad. These (the relevant ones) are copied to the current pushbuffer at draw time.
UB_VS_FS_Base ub_base;
UB_VS_Lights ub_lights;
UB_VS_Bones ub_bones;
Uniforms *uniforms_;
VulkanFragmentShader *lastFShader_ = nullptr;
VulkanVertexShader *lastVShader_ = nullptr;

View file

@ -344,7 +344,6 @@ void GameButton::Draw(UIContext &dc) {
dc.PushScissor(bounds_);
const std::string currentTitle = ginfo->GetTitle();
if (!currentTitle.empty()) {
title_ = ReplaceAll(currentTitle + discNumInfo, "&", "&&");
title_ = ReplaceAll(title_, "\n", " ");
}

View file

@ -489,7 +489,7 @@ void StoreScreen::ParseListing(const std::string &json) {
e.type = ENTRY_PBPZIP;
e.name = GetTranslatedString(game, "name");
e.description = GetTranslatedString(game, "description", "");
e.author = ReplaceAll(game.getStringOr("author", "?"), "&&", "&"); // Can't remove && in the JSON source data due to old app versions
e.author = ReplaceAll(game.getStringOr("author", "?"), "&&", "&"); // Can't remove && in the JSON source data due to old app versions, so we do the opposite replacement here.
e.size = game.getInt("size");
e.downloadURL = game.getStringOr("download-url", "");
e.iconURL = game.getStringOr("icon-url", "");