SilkCommunity / SilkyNvg

NanoVectorGraphicsExceptItUsesSilkNETNowWooHoo (Thank KoziLord for the name)
MIT License
26 stars 7 forks source link

Exceptions when recreating Nvg with the Vulkan renderer #11

Open raphaelschmitz00 opened 1 month ago

raphaelschmitz00 commented 1 month ago

I currently have a situation where on view resizing, I'm recreating the RenderPass. That means I also have to recreate Nvg in order to pass the new RenderPass to it. This causes errors for me.

I'm using 2 frames in flight. I'm using one RenderPass with 2 Subpasses, the second one being for SilkyNvg (to draw a UI over the stuff rendered in the first subpass).

Nvg creation code:

public Nvg Create(RenderPass renderPass) =>
    Nvg.Create(
        new VulkanRenderer(
            CreateFlags.Debug,
            new VulkanRendererParams
            {
                PhysicalDevice = vulkanDevice.PhysicalDevice,
                Device = vulkanDevice.Device,
                FrameCount = 2,
                AdvanceFrameIndexAutomatically = true,
                RenderPass = renderPass,
                SubpassIndex = 1,
                ImageQueueFamily = vulkanDevice.QueueFamilyIndices.GraphicsFamily!.Value,
                ImageQueueFamilyIndex = 0
            },
            vulkanDevice.Vk
        )
    );

Error for disposing and immediately recreating:

fail: VulkanEngine.Contexts.VulkanLogger[0]
      Validation Error: [ VUID-vkCmdBindPipeline-pipeline-parameter ] Object 0: handle = 0x2af04147a80, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0xe3212cd6 | vkCmdBindPipeline(): pipeline Invalid VkPipeline Object 0xdb987f00000000b6. The Vulkan spec states: pipeline must be a valid VkPipeline handle (https://vulkan.lunarg.com/doc/view/1.3.280.0/windows/1.3-extensions/vkspec.html#VUID-vkCmdBindPipeline-pipeline-parameter)

         at SilkyNvg.Rendering.Vulkan.CallFatal error. s.ConvexFillCall.Run(Frame frame, CommandBuffer cmd)
         at SilkyNvg.Rendering.Vulkan.Calls.CallQueue.Run(Frame frame, CommandBuffer commandBuffer)
         at SilkyNvg.Rendering.Vulkan.VulkanRenderer.Flush()

Error for disposing and waiting a couple of frames before (these calls repeat a couple of times, actually):

fail: VulkanEngine.Contexts.VulkanLogger[0]
      Validation Error: [ VUID-vkDestroyPipeline-pipeline-parameter ] Object 0: handle = 0x1f403b1e270, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0xaeb3d1a6 | vkDestroyPipeline(): pipeline Invalid VkPipeline Object 0xdb987f0
0000000b6. The Vulkan spec states: If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle (https://vulkan.lunarg.com/doc/view/1.3.280.0/windows/1.3-extensions/vkspec.html#VUID-vkDestroyPipeline-pipeline-parameter)

         at Silk.NET.Vulkan.Vk.DestroyPipeline(Device device, Pipeline pipeline, AllocationCallbacks* pAllocator)
         at SilkyNvg.Rendering.Vulkan.Pipelines.Pipeline.Dispose()
         at SilkyNvg.Rendering.Vulkan.Pipelines.Pipeline.DestroyAll()
         at SilkyNvg.Rendering.Vulkan.VulkanRenderer.Dispose()
         at SilkyNvg.Nvg.Dispose()

fail: VulkanEngine.Contexts.VulkanLogger[0]
      Validation Error: [ UNASSIGNED-Threading-Info ] Object 0: handle = 0xdb987f00000000b6, type = VK_OBJECT_TYPE_PIPELINE; | MessageID = 0x5d6b67e2 | vkDestroyPipeline():  Couldn't find VkPipeline Object 0xdb987f00000000b6. This should not happen and may indicate a bug in the application.

         at Silk.NET.Vulkan.Vk.DestroyPipeline(Device device, Pipeline pipeline, AllocationCallbacks* pAllocator)
         at SilkyNvg.Rendering.Vulkan.Pipelines.Pipeline.Dispose()
         at SilkyNvg.Rendering.Vulkan.Pipelines.Pipeline.DestroyAll()
         at SilkyNvg.Rendering.Vulkan.VulkanRenderer.Dispose()
         at SilkyNvg.Nvg.Dispose()
MatijaBrown commented 1 month ago

Noted - this is because the Vulkan renderer is currently utter garbage. Will be reworking it completely in the future anyway. Thank you for the info though - this will be considered then!

raphaelschmitz00 commented 1 month ago

Yes, understandable.

Especially since window resizing is comparatively complex in Vulkan, I had no delusion that this would be quickly fixed. But for documentation purposes, this issue is here now.

MatijaBrown commented 1 month ago

Exactly; and as I mentioned in the discord - you can probably get away with keeping the render pass because it remains compatible from re-sizing. In cases it doesn't (if you change more than window size) you can just GC the nvgobject and make a new one, then it might work. Should not happen to often and thus have manageable performance impact.