Fix vulkan validation errors for wrong image transitions and buffers used after destroyed

This commit is contained in:
Magnus Norddahl 2021-10-29 22:22:28 +02:00 committed by Christoph Oelckers
parent c2b3600981
commit 8e59ed754e
4 changed files with 32 additions and 14 deletions

View file

@ -239,13 +239,8 @@ void VkRenderBuffers::CreateShadowmap()
ImageBuilder builder; ImageBuilder builder;
builder.setSize(gl_shadowmap_quality, 1024); 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); 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 = builder.create(fb->device);
Shadowmap.Image->SetDebugName("VkRenderBuffers.Shadowmap"); Shadowmap.Image->SetDebugName("VkRenderBuffers.Shadowmap");

View file

@ -46,8 +46,13 @@ VKBuffer::~VKBuffer()
mBuffer->Unmap(); mBuffer->Unmap();
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
if (fb && mBuffer) if (fb)
fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); {
if (mBuffer)
fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer));
if (mStaging)
fb->FrameDeleteList.Buffers.push_back(std::move(mStaging));
}
} }
void VKBuffer::ResetAll() 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 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) if (usage == BufferUsageType::Static || usage == BufferUsageType::Stream)
{ {
// Note: we could recycle buffers here for the stream usage type to improve performance // Note: we could recycle buffers here for the stream usage type to improve performance

View file

@ -377,9 +377,11 @@ VkBool32 VulkanDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess
seenMessages.insert(msg); seenMessages.insert(msg);
const char *typestr; const char *typestr;
bool showcallstack = false;
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
{ {
typestr = "vulkan error"; typestr = "vulkan error";
showcallstack = true;
} }
else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
{ {
@ -398,11 +400,12 @@ VkBool32 VulkanDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess
typestr = "vulkan"; typestr = "vulkan";
} }
Printf("\n"); if (showcallstack)
Printf("\n");
Printf(TEXTCOLOR_RED "[%s] ", typestr); Printf(TEXTCOLOR_RED "[%s] ", typestr);
Printf(TEXTCOLOR_WHITE "%s\n", msg.GetChars()); Printf(TEXTCOLOR_WHITE "%s\n", msg.GetChars());
if (vk_debug_callstack) if (vk_debug_callstack && showcallstack)
{ {
FString callstack = JitCaptureStackTrace(0, true); FString callstack = JitCaptureStackTrace(0, true);
if (!callstack.IsEmpty()) if (!callstack.IsEmpty())

View file

@ -400,14 +400,16 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
WriteDescriptors update; WriteDescriptors update;
MaterialLayerInfo *layer; MaterialLayerInfo *layer;
auto systex = static_cast<VkHardwareTexture*>(GetLayer(0, state.mTranslation, &layer)); auto systex = static_cast<VkHardwareTexture*>(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)) if (!(layer->scaleFlags & CTF_Indexed))
{ {
for (int i = 1; i < numLayers; i++) for (int i = 1; i < numLayers; i++)
{ {
auto systex = static_cast<VkHardwareTexture*>(GetLayer(i, 0, &layer)); auto systex = static_cast<VkHardwareTexture*>(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 else
@ -415,7 +417,8 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
for (int i = 1; i < 3; i++) for (int i = 1; i < 3; i++)
{ {
auto systex = static_cast<VkHardwareTexture*>(GetLayer(i, translation, &layer)); auto systex = static_cast<VkHardwareTexture*>(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; numLayers = 3;
} }
@ -423,7 +426,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView(); auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();
for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++) 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); update.updateSets(fb->device);