Better handling of non allocated descriptor sets
Stops editor from crashing when resizing too fast
This commit is contained in:
parent
90ae1ad614
commit
c92054e31b
1 changed files with 36 additions and 28 deletions
|
@ -4,6 +4,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "gfx_vulkan_buffer.hpp"
|
#include "gfx_vulkan_buffer.hpp"
|
||||||
#include "gfx_vulkan_pipeline.hpp"
|
#include "gfx_vulkan_pipeline.hpp"
|
||||||
|
@ -895,6 +896,23 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
|
||||||
uint64_t lastDescriptorHash = 0;
|
uint64_t lastDescriptorHash = 0;
|
||||||
VkIndexType currentIndexType = VK_INDEX_TYPE_UINT32;
|
VkIndexType currentIndexType = VK_INDEX_TYPE_UINT32;
|
||||||
|
|
||||||
|
const auto try_bind_descriptor = [cmd, this, ¤tPipeline, &lastDescriptorHash]() -> bool {
|
||||||
|
if (lastDescriptorHash != getDescriptorHash(currentPipeline)) {
|
||||||
|
if (!currentPipeline->cachedDescriptorSets.count(getDescriptorHash(currentPipeline)))
|
||||||
|
cacheDescriptorState(currentPipeline, currentPipeline->descriptorLayout);
|
||||||
|
|
||||||
|
auto& descriptor_set = currentPipeline->cachedDescriptorSets[getDescriptorHash(currentPipeline)];
|
||||||
|
if (descriptor_set == VK_NULL_HANDLE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, &descriptor_set, 0, nullptr);
|
||||||
|
|
||||||
|
lastDescriptorHash = getDescriptorHash(currentPipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
for (auto command : command_buffer->commands) {
|
for (auto command : command_buffer->commands) {
|
||||||
switch (command.type) {
|
switch (command.type) {
|
||||||
case GFXCommandType::SetRenderPass:
|
case GFXCommandType::SetRenderPass:
|
||||||
|
@ -1037,37 +1055,13 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
|
||||||
break;
|
break;
|
||||||
case GFXCommandType::Draw:
|
case GFXCommandType::Draw:
|
||||||
{
|
{
|
||||||
if (lastDescriptorHash != getDescriptorHash(currentPipeline)) {
|
if(try_bind_descriptor())
|
||||||
if (!currentPipeline->cachedDescriptorSets.count(getDescriptorHash(currentPipeline)))
|
|
||||||
cacheDescriptorState(currentPipeline, currentPipeline->descriptorLayout);
|
|
||||||
|
|
||||||
for (auto [texture, trans] : currentPipeline->expectedTransisitions) {
|
|
||||||
inlineTransitionImageLayout(cmd, texture->handle, texture->format, texture->aspect, trans.oldLayout, trans.newLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, ¤tPipeline->cachedDescriptorSets[getDescriptorHash(currentPipeline)], 0, nullptr);
|
|
||||||
|
|
||||||
lastDescriptorHash = getDescriptorHash(currentPipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkCmdDraw(cmd, command.data.draw.vertex_count, command.data.draw.instance_count, command.data.draw.vertex_offset, command.data.draw.base_instance);
|
vkCmdDraw(cmd, command.data.draw.vertex_count, command.data.draw.instance_count, command.data.draw.vertex_offset, command.data.draw.base_instance);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GFXCommandType::DrawIndexed:
|
case GFXCommandType::DrawIndexed:
|
||||||
{
|
{
|
||||||
if (lastDescriptorHash != getDescriptorHash(currentPipeline)) {
|
if(try_bind_descriptor())
|
||||||
if (!currentPipeline->cachedDescriptorSets.count(getDescriptorHash(currentPipeline)))
|
|
||||||
cacheDescriptorState(currentPipeline, currentPipeline->descriptorLayout);
|
|
||||||
|
|
||||||
for (auto [texture, trans] : currentPipeline->expectedTransisitions) {
|
|
||||||
inlineTransitionImageLayout(cmd, texture->handle, texture->format, texture->aspect, trans.oldLayout, trans.newLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, ¤tPipeline->cachedDescriptorSets[getDescriptorHash(currentPipeline)], 0, nullptr);
|
|
||||||
|
|
||||||
lastDescriptorHash = getDescriptorHash(currentPipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkCmdDrawIndexed(cmd, command.data.draw_indexed.index_count, 1, command.data.draw_indexed.first_index, command.data.draw_indexed.vertex_offset, 0);
|
vkCmdDrawIndexed(cmd, command.data.draw_indexed.index_count, 1, command.data.draw_indexed.first_index, command.data.draw_indexed.vertex_offset, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1384,6 +1378,15 @@ void GFXVulkan::createSwapchain(VkSwapchainKHR oldSwapchain) {
|
||||||
colorAttachmentRef.attachment = 0;
|
colorAttachmentRef.attachment = 0;
|
||||||
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDependency dependency = {};
|
||||||
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependency.dstSubpass = 0;
|
||||||
|
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependency.srcAccessMask = 0;
|
||||||
|
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
dependency.dependencyFlags = 0;
|
||||||
|
|
||||||
VkSubpassDescription subpass = {};
|
VkSubpassDescription subpass = {};
|
||||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
subpass.colorAttachmentCount = 1;
|
subpass.colorAttachmentCount = 1;
|
||||||
|
@ -1395,6 +1398,8 @@ void GFXVulkan::createSwapchain(VkSwapchainKHR oldSwapchain) {
|
||||||
renderPassInfo.pAttachments = &colorAttachment;
|
renderPassInfo.pAttachments = &colorAttachment;
|
||||||
renderPassInfo.subpassCount = 1;
|
renderPassInfo.subpassCount = 1;
|
||||||
renderPassInfo.pSubpasses = &subpass;
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
|
renderPassInfo.dependencyCount = 1;
|
||||||
|
renderPassInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
vkCreateRenderPass(device, &renderPassInfo, nullptr, &swapchainRenderPass);
|
vkCreateRenderPass(device, &renderPassInfo, nullptr, &swapchainRenderPass);
|
||||||
|
|
||||||
|
@ -1497,6 +1502,9 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSe
|
||||||
|
|
||||||
name_object(device, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)descriptorSet, pipeline->label);
|
name_object(device, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)descriptorSet, pipeline->label);
|
||||||
|
|
||||||
|
if (descriptorSet == VK_NULL_HANDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
// update set
|
// update set
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto& buffer : boundShaderBuffers) {
|
for (auto& buffer : boundShaderBuffers) {
|
||||||
|
|
Reference in a new issue