cg-tuwien / Auto-Vk

Afterburner for Vulkan development; Auto-Vk is a modern C++ low-level convenience and productivity layer atop Vulkan-Hpp.
MIT License
280 stars 19 forks source link

image_t layout is inconsistent #37

Open JakobPer opened 3 years ago

JakobPer commented 3 years ago

The image_t currentLayout and targetLayout is not always set to the actual current layouts, which makes it hard to perform pipeline barriers (image memory barrier) inside of a renderpass for example, as these layouts are likely undefinded in that case. (unless some previous step sets the layout correctly)

Layout tracking probably needs to be reworked to reflect the correct layout at the time of calling the getter.

Current workaround is to set the layout manually before making a call to the barrier or other functions that rely on the layout. Or you can always perform the direct Vulkan calls manually.

johannesugb commented 3 years ago

Could you post either example code or an overview of relevant steps that lead to bad layout handling (and where the layout must be set manually to fix it)?

JakobPer commented 3 years ago

Example

The problem already occurs when you try to perform an image barrier on a framebuffer image that is used in the current renderpass, as the layout of the attachment images is apparently not set when creating the attachment.

Perform the following patch to the framebuffer example and you'll get multiple validation errors, most are unrelated an can be ignored for now. The important validation error is the one talking about the image being in the wrong layout (cause the wrong layout got provided to the barrier call).

examples/framebuffer/source/framebuffer.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/examples/framebuffer/source/framebuffer.cpp b/examples/framebuffer/source/framebuffer.cpp
index 4653cc22..0dc32c4b 100644
--- a/examples/framebuffer/source/framebuffer.cpp
+++ b/examples/framebuffer/source/framebuffer.cpp
@@ -184,6 +184,10 @@ public: // v== xk::invokee overrides which will be invoked by the framework ==v
        cmdBfr->begin_render_pass_for_framebuffer(mPipeline->get_renderpass(), mOneFramebuffer);
        cmdBfr->handle().bindPipeline(vk::PipelineBindPoint::eGraphics, mPipeline->handle());
        cmdBfr->draw_indexed(avk::const_referenced(mIndexBuffer), avk::const_referenced(mVertexBuffers[inFlightIndex]));
+
+       cmdBfr->establish_image_memory_barrier_rw(mOneFramebuffer->image_at(1).get(), avk::pipeline_stage::color_attachment_output, avk::pipeline_stage::fragment_shader,
+           avk::memory_access::color_attachment_write_access, avk::memory_access::color_attachment_read_access);
+
        cmdBfr->end_render_pass();
        cmdBfr->end_recording();

The validation error is the following:

ERR:  Debug utils callback with Id[947939354|VUID-VkImageMemoryBarrier-newLayout-01198] and Message[Validation Error: [ VUID-VkImageMemoryBarrier-newLayout-01198 ] Object 0: handle = 0x11b9b9af378, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x3880681a | vkCmdPipelineBarrier(): Image Layout cannot be transitioned to UNDEFINED or PREINITIALIZED. The Vulkan spec states: newLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkImageMemoryBarrier-newLayout-01198)]

Proposed tasks/changes: