From 28b58ca05d188b81df2a247195fd35b54aef20a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 00:49:17 +0200 Subject: [PATCH 1/8] More asserts --- Common/Vulkan/VulkanContext.cpp | 1 + Common/Vulkan/VulkanContext.h | 31 ++++++++++++++++--------------- GPU/Vulkan/DrawEngineVulkan.cpp | 9 ++++++--- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 2cb47926f0..b659681a73 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -1,4 +1,5 @@ #define __STDC_LIMIT_MACROS + #include #include #include diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 17509f6c72..fa12d26d79 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -5,6 +5,7 @@ #include #include +#include "Common/Log.h" #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanDebug.h" @@ -66,21 +67,21 @@ class VulkanDeleteList { public: // NOTE: These all take reference handles so they can zero the input value. - void QueueDeleteCommandPool(VkCommandPool &pool) { cmdPools_.push_back(pool); pool = VK_NULL_HANDLE; } - void QueueDeleteDescriptorPool(VkDescriptorPool &pool) { descPools_.push_back(pool); pool = VK_NULL_HANDLE; } - void QueueDeleteShaderModule(VkShaderModule &module) { modules_.push_back(module); module = VK_NULL_HANDLE; } - void QueueDeleteBuffer(VkBuffer &buffer) { buffers_.push_back(buffer); buffer = VK_NULL_HANDLE; } - void QueueDeleteBufferView(VkBufferView &bufferView) { bufferViews_.push_back(bufferView); bufferView = VK_NULL_HANDLE; } - void QueueDeleteImage(VkImage &image) { images_.push_back(image); image = VK_NULL_HANDLE; } - void QueueDeleteImageView(VkImageView &imageView) { imageViews_.push_back(imageView); imageView = VK_NULL_HANDLE; } - void QueueDeleteDeviceMemory(VkDeviceMemory &deviceMemory) { deviceMemory_.push_back(deviceMemory); deviceMemory = VK_NULL_HANDLE; } - void QueueDeleteSampler(VkSampler &sampler) { samplers_.push_back(sampler); sampler = VK_NULL_HANDLE; } - void QueueDeletePipeline(VkPipeline &pipeline) { pipelines_.push_back(pipeline); pipeline = VK_NULL_HANDLE; } - void QueueDeletePipelineCache(VkPipelineCache &pipelineCache) { pipelineCaches_.push_back(pipelineCache); pipelineCache = VK_NULL_HANDLE; } - void QueueDeleteRenderPass(VkRenderPass &renderPass) { renderPasses_.push_back(renderPass); renderPass = VK_NULL_HANDLE; } - void QueueDeleteFramebuffer(VkFramebuffer &framebuffer) { framebuffers_.push_back(framebuffer); framebuffer = VK_NULL_HANDLE; } - void QueueDeletePipelineLayout(VkPipelineLayout &pipelineLayout) { pipelineLayouts_.push_back(pipelineLayout); pipelineLayout = VK_NULL_HANDLE; } - void QueueDeleteDescriptorSetLayout(VkDescriptorSetLayout &descSetLayout) { descSetLayouts_.push_back(descSetLayout); descSetLayout = VK_NULL_HANDLE; } + void QueueDeleteCommandPool(VkCommandPool &pool) { _dbg_assert_(pool != VK_NULL_HANDLE); cmdPools_.push_back(pool); pool = VK_NULL_HANDLE; } + void QueueDeleteDescriptorPool(VkDescriptorPool &pool) { _dbg_assert_(pool != VK_NULL_HANDLE); descPools_.push_back(pool); pool = VK_NULL_HANDLE; } + void QueueDeleteShaderModule(VkShaderModule &module) { _dbg_assert_(module != VK_NULL_HANDLE); modules_.push_back(module); module = VK_NULL_HANDLE; } + void QueueDeleteBuffer(VkBuffer &buffer) { _dbg_assert_(buffer != VK_NULL_HANDLE); buffers_.push_back(buffer); buffer = VK_NULL_HANDLE; } + void QueueDeleteBufferView(VkBufferView &bufferView) { _dbg_assert_(bufferView != VK_NULL_HANDLE); bufferViews_.push_back(bufferView); bufferView = VK_NULL_HANDLE; } + void QueueDeleteImage(VkImage &image) { _dbg_assert_(image != VK_NULL_HANDLE); images_.push_back(image); image = VK_NULL_HANDLE; } + void QueueDeleteImageView(VkImageView &imageView) { _dbg_assert_(imageView != VK_NULL_HANDLE); imageViews_.push_back(imageView); imageView = VK_NULL_HANDLE; } + void QueueDeleteDeviceMemory(VkDeviceMemory &deviceMemory) { _dbg_assert_(deviceMemory != VK_NULL_HANDLE); deviceMemory_.push_back(deviceMemory); deviceMemory = VK_NULL_HANDLE; } + void QueueDeleteSampler(VkSampler &sampler) { _dbg_assert_(sampler != VK_NULL_HANDLE); samplers_.push_back(sampler); sampler = VK_NULL_HANDLE; } + void QueueDeletePipeline(VkPipeline &pipeline) { _dbg_assert_(pipeline != VK_NULL_HANDLE); pipelines_.push_back(pipeline); pipeline = VK_NULL_HANDLE; } + void QueueDeletePipelineCache(VkPipelineCache &pipelineCache) { _dbg_assert_(pipelineCache != VK_NULL_HANDLE); pipelineCaches_.push_back(pipelineCache); pipelineCache = VK_NULL_HANDLE; } + void QueueDeleteRenderPass(VkRenderPass &renderPass) { _dbg_assert_(renderPass != VK_NULL_HANDLE); renderPasses_.push_back(renderPass); renderPass = VK_NULL_HANDLE; } + void QueueDeleteFramebuffer(VkFramebuffer &framebuffer) { _dbg_assert_(framebuffer != VK_NULL_HANDLE); framebuffers_.push_back(framebuffer); framebuffer = VK_NULL_HANDLE; } + void QueueDeletePipelineLayout(VkPipelineLayout &pipelineLayout) { _dbg_assert_(pipelineLayout != VK_NULL_HANDLE); pipelineLayouts_.push_back(pipelineLayout); pipelineLayout = VK_NULL_HANDLE; } + void QueueDeleteDescriptorSetLayout(VkDescriptorSetLayout &descSetLayout) { _dbg_assert_(descSetLayout != VK_NULL_HANDLE); descSetLayouts_.push_back(descSetLayout); descSetLayout = VK_NULL_HANDLE; } void QueueCallback(void(*func)(void *userdata), void *userdata) { callbacks_.push_back(Callback(func, userdata)); } void Take(VulkanDeleteList &del); diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 4ac47d392e..f6c07886b3 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -388,6 +388,10 @@ VkResult DrawEngineVulkan::RecreateDescriptorPool(FrameData &frame, int newSize) } VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone, bool tess) { + _dbg_assert_(base != VK_NULL_HANDLE); + _dbg_assert_(light != VK_NULL_HANDLE); + _dbg_assert_(bone != VK_NULL_HANDLE); + DescriptorSetKey key; key.imageView_ = imageView; key.sampler_ = sampler; @@ -396,9 +400,6 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView key.base_ = base; key.light_ = light; key.bone_ = bone; - _dbg_assert_(base != VK_NULL_HANDLE); - _dbg_assert_(light != VK_NULL_HANDLE); - _dbg_assert_(bone != VK_NULL_HANDLE); FrameData &frame = frame_[vulkan_->GetCurFrame()]; // See if we already have this descriptor set cached. @@ -443,6 +444,8 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView int n = 0; VkDescriptorImageInfo tex[3]{}; if (imageView) { + _dbg_assert_(sampler != VK_NULL_HANDLE); + #ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR tex[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL; #else From 608d082e49e041fb5a67b0aaf395e9875ab958d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 18:54:17 +0200 Subject: [PATCH 2/8] FPURegCache: The invariant checking is very slow in debug mode. Let's only turn it on when we need it. --- Core/MIPS/x86/RegCacheFPU.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/MIPS/x86/RegCacheFPU.cpp b/Core/MIPS/x86/RegCacheFPU.cpp index 26e1e0dd55..e217bfc9e7 100644 --- a/Core/MIPS/x86/RegCacheFPU.cpp +++ b/Core/MIPS/x86/RegCacheFPU.cpp @@ -901,8 +901,8 @@ OpArg FPURegCache::GetDefaultLocation(int reg) const { } void FPURegCache::Invariant() const { -#ifdef _DEBUG - _dbg_assert_msg_(SanityCheck() == 0, "Sanity check failed: %d", SanityCheck()); +#if 0 + _assert_msg_(SanityCheck() == 0, "Sanity check failed: %d", SanityCheck()); #endif } From 181ddd842a4d6aeac3a1a190066ee7b6336db6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 19:18:32 +0200 Subject: [PATCH 3/8] Unify some GPU_SUPPORT* bits --- GPU/Common/FramebufferManagerCommon.cpp | 8 ++++++++ GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/GLES/FramebufferManagerGLES.cpp | 5 ++--- GPU/GLES/GPU_GLES.cpp | 10 ++-------- GPU/GLES/StencilBufferGLES.cpp | 2 +- GPU/GPUState.h | 4 +--- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- 7 files changed, 16 insertions(+), 17 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 08972e868a..d26d635a86 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -347,6 +347,14 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame vfb->fb_stride = params.fb_stride; vfb->z_address = params.z_address; vfb->z_stride = params.z_stride; + + if (vfb->z_address == vfb->fb_address) { + // Probably indicates that the game doesn't care about Z for this VFB. + // Let's avoid matching it for Z copies. + // vfb->z_address = 0; + // vfb->z_stride = 0; + } + vfb->width = drawing_width; vfb->height = drawing_height; vfb->newWidth = drawing_width; diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 552d303555..cb053da7b0 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -150,7 +150,7 @@ void GPU_D3D11::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_FLOAT; features |= GPU_SUPPORTS_INSTANCE_RENDERING; features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; - features |= GPU_SUPPORTS_FBO; + features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; uint32_t fmt4444 = draw_->GetDataFormatSupport(Draw::DataFormat::A4R4G4B4_UNORM_PACK16); uint32_t fmt1555 = draw_->GetDataFormatSupport(Draw::DataFormat::A1R5G5B5_UNORM_PACK16); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 51bd76da3d..50c5fce743 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -272,7 +272,7 @@ void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, Virtu int w = std::min(src->renderWidth, dst->renderWidth); int h = std::min(src->renderHeight, dst->renderHeight); - if (gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT)) { + if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { // Let's only do this if not clearing depth. draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); dst->last_frame_depth_updated = gpuStats.numFlips; @@ -330,8 +330,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, return; } - bool useBlit = gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT); - bool useNV = useBlit && !gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT); + bool useBlit = gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT); float srcXFactor = useBlit ? (float)src->renderWidth / (float)src->bufferWidth : 1.0f; float srcYFactor = useBlit ? (float)src->renderHeight / (float)src->bufferHeight : 1.0f; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index e1de25d4e5..743682e369 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -182,14 +182,8 @@ void GPU_GLES::CheckGPUFeatures() { } } - if (gl_extensions.ARB_framebuffer_object || gl_extensions.EXT_framebuffer_object || gl_extensions.IsGLES) { - features |= GPU_SUPPORTS_FBO; - } - if (gl_extensions.ARB_framebuffer_object || gl_extensions.GLES3) { - features |= GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT; - } - if (gl_extensions.NV_framebuffer_blit) { - features |= GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT; + if (gl_extensions.ARB_framebuffer_object || gl_extensions.NV_framebuffer_blit || gl_extensions.GLES3) { + features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; } if (gl_extensions.ARB_vertex_array_object && gl_extensions.IsCoreContext) { features |= GPU_SUPPORTS_VAO; diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 8ca12e5c09..d9e7fadbf1 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -158,7 +158,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo shaderManagerGL_->DirtyLastShader(); - bool useBlit = gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT); + bool useBlit = gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT); // Our fragment shader (and discard) is slow. Since the source is 1x, we can stencil to 1x. // Then after we're done, we'll just blit it across and stretch it there. diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 2eac6bcef1..9ecf84bba2 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -489,9 +489,7 @@ enum { GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT = FLAG_BIT(22), GPU_ROUND_DEPTH_TO_16BIT = FLAG_BIT(23), // Can be disabled either per game or if we use a real 16-bit depth buffer GPU_SUPPORTS_TEXTURE_LOD_CONTROL = FLAG_BIT(24), - GPU_SUPPORTS_FBO = FLAG_BIT(25), - GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT = FLAG_BIT(26), - GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT = FLAG_BIT(27), + GPU_SUPPORTS_FRAMEBUFFER_BLIT = FLAG_BIT(26), GPU_SUPPORTS_OES_TEXTURE_NPOT = FLAG_BIT(28), GPU_NEEDS_Z_EQUAL_W_HACK = FLAG_BIT(29), GPU_PREFER_CPU_DOWNLOAD = FLAG_BIT(30), diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index c24afc5f69..f6e63a7a30 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -224,7 +224,7 @@ void GPU_Vulkan::CheckGPUFeatures() { // Mandatory features on Vulkan, which may be checked in "centralized" code features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; - features |= GPU_SUPPORTS_FBO; + features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; features |= GPU_SUPPORTS_BLEND_MINMAX; features |= GPU_SUPPORTS_ANY_COPY_IMAGE; features |= GPU_SUPPORTS_OES_TEXTURE_NPOT; From d0f7b1e30f58bf2611e8eaf657cb212a94b67528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:23:04 +0200 Subject: [PATCH 4/8] Make the implementations of CopyFramebufferDepth more similar. Also avoid matching framebuffers with bad z for copies. --- GPU/Common/FramebufferManagerCommon.cpp | 4 ++-- GPU/D3D11/FramebufferManagerD3D11.cpp | 7 ++++--- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/Directx9/FramebufferManagerDX9.cpp | 7 ++++++- GPU/GLES/FramebufferManagerGLES.cpp | 14 ++++++-------- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GPUState.h | 2 +- GPU/Vulkan/FramebufferManagerVulkan.cpp | 13 ++++--------- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- ext/native/thin3d/thin3d_d3d9.cpp | 4 +++- 10 files changed, 29 insertions(+), 28 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index d26d635a86..44162893bf 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -351,8 +351,8 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame if (vfb->z_address == vfb->fb_address) { // Probably indicates that the game doesn't care about Z for this VFB. // Let's avoid matching it for Z copies. - // vfb->z_address = 0; - // vfb->z_stride = 0; + vfb->z_address = 0; + vfb->z_stride = 0; } vfb->width = drawing_width; diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 74ded8bc75..93648cbcbb 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -318,10 +318,11 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; - bool matchingRenderSize = src->renderWidth == dst->renderWidth && src->renderHeight == dst->renderHeight; - if (matchingDepthBuffer && matchingSize && matchingRenderSize) { + if (matchingDepthBuffer && matchingSize) { + int w = std::min(src->renderWidth, dst->renderWidth); + int h = std::min(src->renderHeight, dst->renderHeight); // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); dst->last_frame_depth_updated = gpuStats.numFlips; } diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index cb053da7b0..fcd579f5ed 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -146,7 +146,7 @@ void GPU_D3D11::CheckGPUFeatures() { features |= GPU_SUPPORTS_DUALSOURCE_BLEND; if (draw_->GetDeviceCaps().depthClampSupported) features |= GPU_SUPPORTS_DEPTH_CLAMP; - features |= GPU_SUPPORTS_ANY_COPY_IMAGE; + features |= GPU_SUPPORTS_COPY_IMAGE; features |= GPU_SUPPORTS_TEXTURE_FLOAT; features |= GPU_SUPPORTS_INSTANCE_RENDERING; features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 012846f25c..3575ed82e9 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -309,7 +309,12 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; if (matchingDepthBuffer && matchingSize) { - // Should use StretchRect here? Note: should only copy depth and NOT copy stencil. See #9740. + // Should use StretchRect here? Note: should only copy depth and ideally NOT copy stencil. See #9740. + int w = std::min(src->renderWidth, dst->renderWidth); + int h = std::min(src->renderHeight, dst->renderHeight); + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); + dst->last_frame_depth_updated = gpuStats.numFlips; } } diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 50c5fce743..e030effb22 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -268,15 +268,13 @@ void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, Virtu bool matchingSize = src->width == dst->width && src->height == dst->height; // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. - if (matchingDepthBuffer && matchingSize) { + if (matchingDepthBuffer && matchingSize && gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { int w = std::min(src->renderWidth, dst->renderWidth); int h = std::min(src->renderHeight, dst->renderHeight); - - if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { - // Let's only do this if not clearing depth. - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } + // Let's only do this if not clearing depth. + draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + dst->last_frame_depth_updated = gpuStats.numFlips; } } @@ -360,7 +358,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, return; } - if (gstate_c.Supports(GPU_SUPPORTS_ANY_COPY_IMAGE)) { + if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) { // glBlitFramebuffer can clip, but glCopyImageSubData is more restricted. // In case the src goes outside, we just skip the optimization in that case. const bool sameSize = dstX2 - dstX1 == srcX2 - srcX1 && dstY2 - dstY1 == srcY2 - srcY1; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 743682e369..2ba4922a2c 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -214,7 +214,7 @@ void GPU_GLES::CheckGPUFeatures() { features |= GPU_SUPPORTS_BLEND_MINMAX; if (gl_extensions.OES_copy_image || gl_extensions.NV_copy_image || gl_extensions.EXT_copy_image || gl_extensions.ARB_copy_image) - features |= GPU_SUPPORTS_ANY_COPY_IMAGE; + features |= GPU_SUPPORTS_COPY_IMAGE; if (!gl_extensions.IsGLES) features |= GPU_SUPPORTS_LOGIC_OP; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 9ecf84bba2..f012e023bc 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -483,7 +483,7 @@ enum { // Free bit: 16 GPU_SUPPORTS_ACCURATE_DEPTH = FLAG_BIT(17), GPU_SUPPORTS_VAO = FLAG_BIT(18), - GPU_SUPPORTS_ANY_COPY_IMAGE = FLAG_BIT(19), + GPU_SUPPORTS_COPY_IMAGE = FLAG_BIT(19), GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH = FLAG_BIT(20), GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT = FLAG_BIT(21), GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT = FLAG_BIT(22), diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 9d57f8b85e..8a39fdc85e 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -273,17 +273,12 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, void FramebufferManagerVulkan::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; - bool matchingRenderSize = src->renderWidth == dst->renderWidth && src->renderHeight == dst->renderHeight; - if (matchingDepthBuffer && matchingRenderSize && matchingSize) { - // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } else if (matchingDepthBuffer && matchingSize) { - /* + if (matchingDepthBuffer && matchingSize) { int w = std::min(src->renderWidth, dst->renderWidth); int h = std::min(src->renderHeight, dst->renderHeight); - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST); - */ + // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + dst->last_frame_depth_updated = gpuStats.numFlips; } } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index f6e63a7a30..9c7f36afe7 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -226,7 +226,7 @@ void GPU_Vulkan::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; features |= GPU_SUPPORTS_BLEND_MINMAX; - features |= GPU_SUPPORTS_ANY_COPY_IMAGE; + features |= GPU_SUPPORTS_COPY_IMAGE; features |= GPU_SUPPORTS_OES_TEXTURE_NPOT; features |= GPU_SUPPORTS_INSTANCE_RENDERING; features |= GPU_SUPPORTS_VERTEX_TEXTURE_FETCH; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 9843af9358..8a97cbd26e 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -526,7 +526,9 @@ public: void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override; - void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) override {} + void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) override { + // Not implemented + } bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) override; // These functions should be self explanatory. From d6d72db0a9717b8eefa874a0fc9806bf83a00c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:31:40 +0200 Subject: [PATCH 5/8] Unify BlitFramebufferDepth. --- GPU/Common/FramebufferManagerCommon.cpp | 20 ++++++++++++++++++++ GPU/Common/FramebufferManagerCommon.h | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 13 ------------- GPU/D3D11/FramebufferManagerD3D11.h | 2 -- GPU/Directx9/FramebufferManagerDX9.cpp | 13 ------------- GPU/Directx9/FramebufferManagerDX9.h | 2 -- GPU/GLES/FramebufferManagerGLES.cpp | 15 --------------- GPU/GLES/FramebufferManagerGLES.h | 2 -- GPU/Vulkan/FramebufferManagerVulkan.cpp | 13 ------------- GPU/Vulkan/FramebufferManagerVulkan.h | 2 -- 10 files changed, 21 insertions(+), 63 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 44162893bf..5776bc4919 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -469,6 +469,26 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { delete v; } +void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { + bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; + bool matchingSize = src->width == dst->width && src->height == dst->height; + + // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. + if (matchingDepthBuffer && matchingSize) { + int w = std::min(src->renderWidth, dst->renderWidth); + int h = std::min(src->renderHeight, dst->renderHeight); + // Let's only do this if not clearing depth. + if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { + draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + } else if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) { + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + } + dst->last_frame_depth_updated = gpuStats.numFlips; + } +} + void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) { if (!useBufferedRendering_) { // Let's ignore rendering to targets that have not (yet) been displayed. diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index ff43f6d504..05a2a787b6 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -339,7 +339,7 @@ protected: void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth); virtual void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) = 0; - virtual void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) = 0; + void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst); void ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, int h, bool force = false, bool skipCopy = false); void ShowScreenResolution(); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 93648cbcbb..4440ebf4b3 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -315,19 +315,6 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { } } -void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - void FramebufferManagerD3D11::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { ID3D11ShaderResourceView *view = nullptr; diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index a1683c299c..e951e277a1 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -45,8 +45,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 3575ed82e9..be7f751eda 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -305,19 +305,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { } } - void FramebufferManagerDX9::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - // Should use StretchRect here? Note: should only copy depth and ideally NOT copy stencil. See #9740. - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } - } - LPDIRECT3DSURFACE9 FramebufferManagerDX9::GetOffscreenSurface(LPDIRECT3DSURFACE9 similarSurface, VirtualFramebuffer *vfb) { D3DSURFACE_DESC desc = {}; HRESULT hr = similarSurface->GetDesc(&desc); diff --git a/GPU/Directx9/FramebufferManagerDX9.h b/GPU/Directx9/FramebufferManagerDX9.h index b164a9b0e7..3a8578599a 100644 --- a/GPU/Directx9/FramebufferManagerDX9.h +++ b/GPU/Directx9/FramebufferManagerDX9.h @@ -50,8 +50,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index e030effb22..f2709663cf 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -263,21 +263,6 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE } } -void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - - // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. - if (matchingDepthBuffer && matchingSize && gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // Let's only do this if not clearing depth. - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); - RebindFramebuffer("BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - void FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { render_->BindTexture(stage, nullptr); diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 12a3eb85c5..9177b62767 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -49,8 +49,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - // For use when texturing from a framebuffer. May create a duplicate if target. void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 8a39fdc85e..293ff77be5 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -269,19 +269,6 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, } } -// Except for a missing rebind and silly scissor enables, identical copy of the same function in GPU_GLES - tricky parts are in thin3d. -void FramebufferManagerVulkan::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; diff --git a/GPU/Vulkan/FramebufferManagerVulkan.h b/GPU/Vulkan/FramebufferManagerVulkan.h index b66eeb6033..a09f6ef755 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.h +++ b/GPU/Vulkan/FramebufferManagerVulkan.h @@ -54,8 +54,6 @@ public: int GetLineWidth(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; VkImageView BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); From d71ec8d82c8a60c9dc6b6389718eda98b3823840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:33:19 +0200 Subject: [PATCH 6/8] The new asserts found something. --- ext/native/thin3d/VulkanQueueRunner.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index b97a9a0f4a..991374fb92 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -89,8 +89,12 @@ void VulkanQueueRunner::ResizeReadbackBuffer(VkDeviceSize requiredSize) { void VulkanQueueRunner::DestroyDeviceObjects() { INFO_LOG(G3D, "VulkanQueueRunner::DestroyDeviceObjects"); - vulkan_->Delete().QueueDeleteDeviceMemory(readbackMemory_); - vulkan_->Delete().QueueDeleteBuffer(readbackBuffer_); + if (readbackMemory_) { + vulkan_->Delete().QueueDeleteDeviceMemory(readbackMemory_); + } + if (readbackBuffer_) { + vulkan_->Delete().QueueDeleteBuffer(readbackBuffer_); + } readbackBufferSize_ = 0; renderPasses_.Iterate([&](const RPKey &rpkey, VkRenderPass rp) { From 277f0e4ec6fd08523f0911808c025c37bca14690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:47:22 +0200 Subject: [PATCH 7/8] Fix bug in GLES texture filter setup --- GPU/GLES/TextureCacheGLES.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 292fa20ba1..de6852d556 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -124,10 +124,10 @@ void TextureCacheGLES::ApplySamplingParams(const SamplerCacheKey &key) { } float aniso = 0.0f; - int magKey = ((int)key.mipEnable << 2) | ((int)key.mipFilt << 1) | ((int)key.magFilt); + int minKey = ((int)key.mipEnable << 2) | ((int)key.mipFilt << 1) | ((int)key.minFilt); render_->SetTextureSampler(0, key.sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, key.tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, - MagFiltGL[magKey], key.minFilt ? GL_LINEAR : GL_NEAREST, aniso); + key.magFilt ? GL_LINEAR : GL_NEAREST, MinFiltGL[minKey], aniso); } static void ConvertColors(void *dstBuf, const void *srcBuf, Draw::DataFormat dstFmt, int numPixels) { From 7c76f4e65ca3dd9a27dc8033cd651253c3eb8e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:48:24 +0200 Subject: [PATCH 8/8] Minor improvement to gl_debug_log.h --- ext/native/gfx/gl_debug_log.cpp | 4 +++- ext/native/gfx/gl_debug_log.h | 4 ++-- ext/native/thin3d/GLQueueRunner.cpp | 4 ++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ext/native/gfx/gl_debug_log.cpp b/ext/native/gfx/gl_debug_log.cpp index 078b4ed843..fc66ccf1dd 100644 --- a/ext/native/gfx/gl_debug_log.cpp +++ b/ext/native/gfx/gl_debug_log.cpp @@ -34,9 +34,11 @@ std::string GLEnumToString(uint16_t value) { } } -void CheckGLError(const char *file, int line) { +bool CheckGLError(const char *file, int line) { GLenum err = glGetError(); if (err != GL_NO_ERROR) { ERROR_LOG(G3D, "GL error %s on %s:%d", GLEnumToString(err).c_str(), file, line); + return false; } + return true; } diff --git a/ext/native/gfx/gl_debug_log.h b/ext/native/gfx/gl_debug_log.h index ae22ab1700..d6d37c4271 100644 --- a/ext/native/gfx/gl_debug_log.h +++ b/ext/native/gfx/gl_debug_log.h @@ -10,8 +10,8 @@ #if defined(DEBUG_OPENGL) -void CheckGLError(const char *file, int line); -#define CHECK_GL_ERROR_IF_DEBUG() CheckGLError(__FILE__, __LINE__) +bool CheckGLError(const char *file, int line); +#define CHECK_GL_ERROR_IF_DEBUG() if (!CheckGLError(__FILE__, __LINE__)) __debugbreak(); #else diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 9c380ee622..c5da0e4c21 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -1146,6 +1146,7 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last if (!tex) { break; } + CHECK_GL_ERROR_IF_DEBUG(); if (tex->canWrap) { if (tex->wrapS != c.textureSampler.wrapS) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c.textureSampler.wrapS); @@ -1156,14 +1157,17 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last tex->wrapT = c.textureSampler.wrapT; } } + CHECK_GL_ERROR_IF_DEBUG(); if (tex->magFilter != c.textureSampler.magFilter) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, c.textureSampler.magFilter); tex->magFilter = c.textureSampler.magFilter; } + CHECK_GL_ERROR_IF_DEBUG(); if (tex->minFilter != c.textureSampler.minFilter) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c.textureSampler.minFilter); tex->minFilter = c.textureSampler.minFilter; } + CHECK_GL_ERROR_IF_DEBUG(); if (tex->anisotropy != c.textureSampler.anisotropy) { if (c.textureSampler.anisotropy != 0.0f) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, c.textureSampler.anisotropy);