From 11366a2ded1ccaa7bbcc23b03b6b514f6b3efea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 14 Dec 2022 15:15:31 +0100 Subject: [PATCH] Don't refer directly to g_Config.iMultiSampleLevel, it can contain unsupported modes. --- Common/GPU/Vulkan/VulkanRenderManager.cpp | 6 ++++++ GPU/Common/FramebufferManagerCommon.cpp | 18 ++++++++---------- GPU/Common/FramebufferManagerCommon.h | 10 +++++++--- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GPUCommon.cpp | 16 +++++++++++++++- GPU/GPUCommon.h | 9 +++++++++ GPU/Vulkan/DrawEngineVulkan.cpp | 4 ++-- GPU/Vulkan/GPU_Vulkan.cpp | 7 ++++--- GPU/Vulkan/PipelineManagerVulkan.cpp | 2 +- 11 files changed, 55 insertions(+), 23 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index 1d3e9f93da..6eb24de9ef 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -48,6 +48,12 @@ bool VKRGraphicsPipeline::Create(VulkanContext *vulkan, VkRenderPass compatibleR return false; } + if (!compatibleRenderPass) { + ERROR_LOG(G3D, "Failed creating graphics pipeline - compatible render pass was null"); + // We're kinda screwed here? + return false; + } + uint32_t stageCount = 2; VkPipelineShaderStageCreateInfo ss[3]{}; ss[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 1fa20e2733..9a372da426 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -82,14 +82,14 @@ FramebufferManagerCommon::~FramebufferManagerCommon() { delete presentation_; } -void FramebufferManagerCommon::Init() { +void FramebufferManagerCommon::Init(int msaaLevel) { // We may need to override the render size if the shader is upscaling or SSAA. NotifyDisplayResized(); - NotifyRenderResized(); + NotifyRenderResized(msaaLevel); } -bool FramebufferManagerCommon::UpdateRenderSize() { - const bool newRender = renderWidth_ != (float)PSP_CoreParameter().renderWidth || renderHeight_ != (float)PSP_CoreParameter().renderHeight || msaaLevel_ != g_Config.iMultiSampleLevel; +bool FramebufferManagerCommon::UpdateRenderSize(int msaaLevel) { + const bool newRender = renderWidth_ != (float)PSP_CoreParameter().renderWidth || renderHeight_ != (float)PSP_CoreParameter().renderHeight || msaaLevel_ != msaaLevel; int effectiveBloomHack = g_Config.iBloomHack; if (PSP_CoreParameter().compat.flags().ForceLowerResolutionForEffectsOn) { @@ -104,7 +104,7 @@ bool FramebufferManagerCommon::UpdateRenderSize() { renderWidth_ = (float)PSP_CoreParameter().renderWidth; renderHeight_ = (float)PSP_CoreParameter().renderHeight; renderScaleFactor_ = (float)PSP_CoreParameter().renderScaleFactor; - msaaLevel_ = g_Config.iMultiSampleLevel; + msaaLevel_ = msaaLevel; bloomHack_ = effectiveBloomHack; useBufferedRendering_ = newBuffered; @@ -1670,9 +1670,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, char tag[128]; size_t len = FormatFramebufferName(vfb, tag, sizeof(tag)); - int msaaLevel = g_Config.iMultiSampleLevel; - - vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, GetFramebufferLayers(), msaaLevel, true, tag }); + vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, GetFramebufferLayers(), msaaLevel_, true, tag }); if (Memory::IsVRAMAddress(vfb->fb_address) && vfb->fb_stride != 0) { NotifyMemInfo(MemBlockFlags::ALLOC, vfb->fb_address, ColorBufferByteSize(vfb), tag, len); } @@ -2406,7 +2404,7 @@ void FramebufferManagerCommon::NotifyDisplayResized() { updatePostShaders_ = true; } -void FramebufferManagerCommon::NotifyRenderResized() { +void FramebufferManagerCommon::NotifyRenderResized(int msaaLevel) { gstate_c.skipDrawReason &= ~SKIPDRAW_NON_DISPLAYED_FB; int w, h, scaleFactor; @@ -2415,7 +2413,7 @@ void FramebufferManagerCommon::NotifyRenderResized() { PSP_CoreParameter().renderHeight = h; PSP_CoreParameter().renderScaleFactor = scaleFactor; - if (UpdateRenderSize()) { + if (UpdateRenderSize(msaaLevel)) { DestroyAllFBOs(); } diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 27380df454..b900104b7e 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -272,7 +272,7 @@ public: drawEngine_ = td; } - virtual void Init(); + void Init(int msaaLevel); virtual void BeginFrame(); void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format); void DestroyFramebuf(VirtualFramebuffer *v); @@ -398,7 +398,7 @@ public: } void SetSafeSize(u16 w, u16 h); - void NotifyRenderResized(); + void NotifyRenderResized(int msaaLevel); virtual void NotifyDisplayResized(); void NotifyConfigChanged(); @@ -445,6 +445,10 @@ public: void ReleasePipelines(); + int GetMSAALevel() const { + return msaaLevel_; + } + protected: virtual void ReadbackFramebufferSync(VirtualFramebuffer *vfb, int x, int y, int w, int h, RasterChannel channel); // Used for when a shader is required, such as GLES. @@ -457,7 +461,7 @@ protected: void CopyToColorFromOverlappingFramebuffers(VirtualFramebuffer *dest); void CopyToDepthFromOverlappingFramebuffers(VirtualFramebuffer *dest); - bool UpdateRenderSize(); + bool UpdateRenderSize(int msaaLevel); void FlushBeforeCopy(); virtual void DecimateFBOs(); // keeping it virtual to let D3D do a little extra diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 947a76af55..124171978f 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -70,7 +70,7 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) framebufferManagerD3D11_->SetTextureCache(textureCacheD3D11_); framebufferManagerD3D11_->SetShaderManager(shaderManagerD3D11_); framebufferManagerD3D11_->SetDrawEngine(&drawEngine_); - framebufferManagerD3D11_->Init(); + framebufferManagerD3D11_->Init(msaaLevel_); textureCacheD3D11_->SetFramebufferManager(framebufferManagerD3D11_); textureCacheD3D11_->SetShaderManager(shaderManagerD3D11_); diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index e60167db71..2026b70989 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -69,7 +69,7 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) framebufferManagerDX9_->SetTextureCache(textureCacheDX9_); framebufferManagerDX9_->SetShaderManager(shaderManagerDX9_); framebufferManagerDX9_->SetDrawEngine(&drawEngine_); - framebufferManagerDX9_->Init(); + framebufferManagerDX9_->Init(msaaLevel_); textureCacheDX9_->SetFramebufferManager(framebufferManagerDX9_); textureCacheDX9_->SetShaderManager(shaderManagerDX9_); diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 43ea2a97dc..17f0f79552 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -74,7 +74,7 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) framebufferManagerGL_->SetTextureCache(textureCacheGL_); framebufferManagerGL_->SetShaderManager(shaderManagerGL_); framebufferManagerGL_->SetDrawEngine(&drawEngine_); - framebufferManagerGL_->Init(); + framebufferManagerGL_->Init(msaaLevel_); textureCacheGL_->SetFramebufferManager(framebufferManagerGL_); textureCacheGL_->SetShaderManager(shaderManagerGL_); textureCacheGL_->SetDrawEngine(&drawEngine_); diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 6682c4b5d8..b95f969985 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -428,6 +428,8 @@ GPUCommon::GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : ResetMatrices(); PPGeSetDrawContext(draw); + + UpdateMSAALevel(draw); } GPUCommon::~GPUCommon() { @@ -484,6 +486,8 @@ void GPUCommon::BeginHostFrame() { gstate_c.Dirty(DIRTY_ALL); UpdateCmdInfo(); + + UpdateMSAALevel(draw_); CheckConfigChanged(); CheckDisplayResized(); CheckRenderResized(); @@ -659,7 +663,7 @@ void GPUCommon::CheckDisplayResized() { void GPUCommon::CheckRenderResized() { if (renderResized_) { - framebufferManager_->NotifyRenderResized(); + framebufferManager_->NotifyRenderResized(msaaLevel_); renderResized_ = false; } } @@ -3575,3 +3579,13 @@ u32 GPUCommon::CheckGPUFeaturesLate(u32 features) const { return features; } + +void GPUCommon::UpdateMSAALevel(Draw::DrawContext *draw) { + int level = g_Config.iMultiSampleLevel; + if (draw->GetDeviceCaps().multiSampleLevelsMask & (1 << level)) { + msaaLevel_ = level; + } else { + // Didn't support the configured level, so revert to 0. + msaaLevel_ = 0; + } +} diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 26442c09bd..28c09034ed 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -261,6 +261,10 @@ public: fullInfo = reportingFullInfo_; } + int MSAALevel() const { + return msaaLevel_; + } + protected: void DeviceLost() override; void DeviceRestore() override; @@ -319,6 +323,8 @@ protected: virtual void BuildReportingInfo() = 0; + void UpdateMSAALevel(Draw::DrawContext *draw); + FramebufferManagerCommon *framebufferManager_ = nullptr; TextureCacheCommon *textureCache_ = nullptr; DrawEngineCommon *drawEngineCommon_ = nullptr; @@ -405,6 +411,8 @@ protected: std::string reportingPrimaryInfo_; std::string reportingFullInfo_; + int msaaLevel_ = 0; + private: void CheckDepthUsage(VirtualFramebuffer *vfb); void DoExecuteCall(u32 target); @@ -415,6 +423,7 @@ private: // Debug stats. double timeSteppingStarted_; double timeSpentStepping_; + int lastVsync_ = -1; }; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index d79bcadacc..a8387e3720 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -788,7 +788,7 @@ void DrawEngineVulkan::DoFlush() { } _dbg_assert_msg_(vshader->UseHWTransform(), "Bad vshader"); - VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &dec_->decFmt, vshader, fshader, gshader, true, 0, g_Config.iMultiSampleLevel); + VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &dec_->decFmt, vshader, fshader, gshader, true, 0, framebufferManager_->GetMSAALevel()); if (!pipeline || !pipeline->pipeline) { // Already logged, let's bail out. return; @@ -917,7 +917,7 @@ void DrawEngineVulkan::DoFlush() { shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, true); _dbg_assert_msg_(!vshader->UseHWTransform(), "Bad vshader"); - VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &dec_->decFmt, vshader, fshader, gshader, false, 0, g_Config.iMultiSampleLevel); + VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &dec_->decFmt, vshader, fshader, gshader, false, 0, framebufferManager_->GetMSAALevel()); if (!pipeline || !pipeline->pipeline) { // Already logged, let's bail out. decodedVerts_ = 0; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index bda3c3844f..b3ad3c7689 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -76,7 +76,7 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) framebufferManagerVulkan_->SetTextureCache(textureCacheVulkan_); framebufferManagerVulkan_->SetDrawEngine(&drawEngine_); framebufferManagerVulkan_->SetShaderManager(shaderManagerVulkan_); - framebufferManagerVulkan_->Init(); + framebufferManagerVulkan_->Init(msaaLevel_); textureCacheVulkan_->SetFramebufferManager(framebufferManagerVulkan_); textureCacheVulkan_->SetShaderManager(shaderManagerVulkan_); textureCacheVulkan_->SetDrawEngine(&drawEngine_); @@ -140,9 +140,10 @@ void GPU_Vulkan::LoadCache(const Path &filename) { } if (result) { // WARNING: See comment in LoadPipelineCache if you are tempted to flip the second parameter to true. - result = pipelineManager_->LoadPipelineCache(f, false, shaderManagerVulkan_, draw_, drawEngine_.GetPipelineLayout(), g_Config.iMultiSampleLevel); + result = pipelineManager_->LoadPipelineCache(f, false, shaderManagerVulkan_, draw_, drawEngine_.GetPipelineLayout(), msaaLevel_); } fclose(f); + if (!result) { WARN_LOG(G3D, "Incompatible Vulkan pipeline cache - rebuilding."); // Bad cache file for this GPU/Driver/etc. Delete it. @@ -274,7 +275,7 @@ u32 GPU_Vulkan::CheckGPUFeatures() const { // We need to turn off framebuffer fetch through input attachments if MSAA is on for now. // This is fixable, just needs some shader generator work (subpassInputMS). - if (g_Config.iMultiSampleLevel != 0) { + if (msaaLevel_ != 0) { features &= ~GPU_USE_FRAMEBUFFER_FETCH; } diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 9d9b116e43..e8ae8d9db6 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -727,7 +727,7 @@ bool PipelineManagerVulkan::LoadPipelineCache(FILE *file, bool loadRawPipelineCa // Read the number of pipelines. bool failed = fread(&size, sizeof(size), 1, file) != 1; - NOTICE_LOG(G3D, "Creating %d pipelines from cache...", size); + NOTICE_LOG(G3D, "Creating %d pipelines from cache (%dx MSAA)...", size, (1 << multiSampleLevel)); int pipelineCreateFailCount = 0; int shaderFailCount = 0; for (uint32_t i = 0; i < size; i++) {