From 8e59ed754e8f409bec32433e43e172cafcf1b28c Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 29 Oct 2021 22:22:28 +0200 Subject: [PATCH] Fix vulkan validation errors for wrong image transitions and buffers used after destroyed --- .../vulkan/renderer/vk_renderbuffers.cpp | 7 +------ .../rendering/vulkan/system/vk_buffers.cpp | 21 +++++++++++++++++-- .../rendering/vulkan/system/vk_device.cpp | 7 +++++-- .../vulkan/textures/vk_hwtexture.cpp | 11 ++++++---- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp b/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp index 75288a4f2..34e44096d 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp +++ b/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp @@ -239,13 +239,8 @@ void VkRenderBuffers::CreateShadowmap() ImageBuilder builder; builder.setSize(gl_shadowmap_quality, 1024); - builder.setFormat(SceneNormalFormat); + builder.setFormat(VK_FORMAT_R32_SFLOAT); builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); - if (!builder.isFormatSupported(fb->device, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) - { - SceneNormalFormat = VK_FORMAT_R8G8B8A8_UNORM; - builder.setFormat(SceneNormalFormat); - } Shadowmap.Image = builder.create(fb->device); Shadowmap.Image->SetDebugName("VkRenderBuffers.Shadowmap"); diff --git a/src/common/rendering/vulkan/system/vk_buffers.cpp b/src/common/rendering/vulkan/system/vk_buffers.cpp index 96835419f..ce1ac503d 100644 --- a/src/common/rendering/vulkan/system/vk_buffers.cpp +++ b/src/common/rendering/vulkan/system/vk_buffers.cpp @@ -46,8 +46,13 @@ VKBuffer::~VKBuffer() mBuffer->Unmap(); auto fb = GetVulkanFrameBuffer(); - if (fb && mBuffer) - fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + if (fb) + { + if (mBuffer) + fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + if (mStaging) + fb->FrameDeleteList.Buffers.push_back(std::move(mStaging)); + } } void VKBuffer::ResetAll() @@ -70,6 +75,18 @@ void VKBuffer::SetData(size_t size, const void *data, BufferUsageType usage) size_t bufsize = std::max(size, (size_t)16); // For supporting zero byte buffers + // If SetData is called multiple times we have to keep the old buffers alive as there might still be draw commands referencing them + if (mBuffer) + { + fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + mBuffer = {}; + } + if (mStaging) + { + fb->FrameDeleteList.Buffers.push_back(std::move(mStaging)); + mStaging = {}; + } + if (usage == BufferUsageType::Static || usage == BufferUsageType::Stream) { // Note: we could recycle buffers here for the stream usage type to improve performance diff --git a/src/common/rendering/vulkan/system/vk_device.cpp b/src/common/rendering/vulkan/system/vk_device.cpp index f6ce072af..be83d8937 100644 --- a/src/common/rendering/vulkan/system/vk_device.cpp +++ b/src/common/rendering/vulkan/system/vk_device.cpp @@ -377,9 +377,11 @@ VkBool32 VulkanDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess seenMessages.insert(msg); const char *typestr; + bool showcallstack = false; if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { typestr = "vulkan error"; + showcallstack = true; } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { @@ -398,11 +400,12 @@ VkBool32 VulkanDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess typestr = "vulkan"; } - Printf("\n"); + if (showcallstack) + Printf("\n"); Printf(TEXTCOLOR_RED "[%s] ", typestr); Printf(TEXTCOLOR_WHITE "%s\n", msg.GetChars()); - if (vk_debug_callstack) + if (vk_debug_callstack && showcallstack) { FString callstack = JitCaptureStackTrace(0, true); if (!callstack.IsEmpty()) diff --git a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp index 276f9fd09..dce6dcb6f 100644 --- a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp @@ -400,14 +400,16 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state) WriteDescriptors update; MaterialLayerInfo *layer; auto systex = static_cast(GetLayer(0, state.mTranslation, &layer)); - update.addCombinedImageSampler(descriptor.get(), 0, systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout); + auto systeximage = systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags); + update.addCombinedImageSampler(descriptor.get(), 0, systeximage->View.get(), sampler, systeximage->Layout); if (!(layer->scaleFlags & CTF_Indexed)) { for (int i = 1; i < numLayers; i++) { auto systex = static_cast(GetLayer(i, 0, &layer)); - update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer->layerTexture, 0, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout); + auto systeximage = systex->GetImage(layer->layerTexture, 0, layer->scaleFlags); + update.addCombinedImageSampler(descriptor.get(), i, systeximage->View.get(), sampler, systeximage->Layout); } } else @@ -415,7 +417,8 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state) for (int i = 1; i < 3; i++) { auto systex = static_cast(GetLayer(i, translation, &layer)); - update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer->layerTexture, 0, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout); + auto systeximage = systex->GetImage(layer->layerTexture, 0, layer->scaleFlags); + update.addCombinedImageSampler(descriptor.get(), i, systeximage->View.get(), sampler, systeximage->Layout); } numLayers = 3; } @@ -423,7 +426,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state) auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView(); for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++) { - update.addCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, systex->mImage.Layout); + update.addCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } update.updateSets(fb->device);