Skip to content

Commit

Permalink
Merge pull request #254 from rbrich/fix-vk-sync
Browse files Browse the repository at this point in the history
[graphics] Fix Vulkan validation error on vkAcquireNextImageKHR
  • Loading branch information
rbrich authored Nov 29, 2024
2 parents f1ecdfe + 6f61199 commit 57470ce
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 43 deletions.
8 changes: 1 addition & 7 deletions src/xci/graphics/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,7 @@ bool Renderer::create_instance(SDL_Window* window)
};

std::vector<const char *> extensions;
{
unsigned int sdlExtensionCount = 0;
SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, nullptr);
extensions.resize(sdlExtensionCount);
SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, extensions.data());
extensions.resize(sdlExtensionCount);
}
vk_get_vector(extensions, SDL_Vulkan_GetInstanceExtensions, window);

#ifdef XCI_DEBUG_VULKAN
// enable validation layers
Expand Down
14 changes: 7 additions & 7 deletions src/xci/graphics/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,13 @@ void Window::resize_framebuffer()

void Window::draw()
{
VK_TRY("vkWaitForFences",
vkWaitForFences(m_renderer.vk_device(),
1, &m_cmd_buf_fences[m_current_cmd_buf], VK_TRUE, UINT64_MAX));
VK_TRY("vkResetFences",
vkResetFences(m_renderer.vk_device(),
1, &m_cmd_buf_fences[m_current_cmd_buf]));

uint32_t image_index;
auto rc = vkAcquireNextImageKHR(m_renderer.vk_device(),
m_renderer.vk_swapchain(), UINT64_MAX,
Expand All @@ -530,13 +537,6 @@ void Window::draw()
}

{
VK_TRY("vkWaitForFences",
vkWaitForFences(m_renderer.vk_device(),
1, &m_cmd_buf_fences[m_current_cmd_buf], VK_TRUE, UINT64_MAX));
VK_TRY("vkResetFences",
vkResetFences(m_renderer.vk_device(),
1, &m_cmd_buf_fences[m_current_cmd_buf]));

m_command_buffers[m_current_cmd_buf].release_resources();

auto& cmd_buf = m_command_buffers[m_current_cmd_buf];
Expand Down
21 changes: 10 additions & 11 deletions src/xci/graphics/vulkan/Framebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ VkDeviceSize Framebuffer::create_image(const ImageCreateInfo& image_ci, VkImage&
void Framebuffer::create(const Attachments& attachments, VkExtent2D size, uint32_t image_count,
VkImage* swapchain_images)
{
if (m_framebuffers[0])
if (!m_framebuffers.empty())
destroy();

struct BindImage {
Expand All @@ -45,21 +45,20 @@ void Framebuffer::create(const Attachments& attachments, VkExtent2D size, uint32
deferred_bind.push_back({image, offset});
};

m_image_count = image_count;
const auto device = m_renderer.vk_device();

// Prepare color buffers
for (const auto& color : attachments.color_attachments()) {
if (swapchain_images) {
m_borrowed_count = m_image_count;
for (unsigned i = 0; i < m_image_count; i++) {
m_borrowed_count = image_count;
for (unsigned i = 0; i < image_count; i++) {
auto* image = m_images.emplace_back(swapchain_images[i]);
deferred_views.push_back({image, color.format, VK_IMAGE_ASPECT_COLOR_BIT});
}
swapchain_images = nullptr;
continue;
}
for (unsigned i = 0; i < m_image_count; i++) {
for (unsigned i = 0; i < image_count; i++) {
ImageCreateInfo image_ci{{size.width, size.height}, color.format,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
color.usage};
Expand Down Expand Up @@ -108,12 +107,13 @@ void Framebuffer::create(const Attachments& attachments, VkExtent2D size, uint32
}

// Create framebuffers
for (size_t i = 0; i < m_image_count; i++) {
m_framebuffers.resize(image_count);
for (size_t i = 0; i < image_count; i++) {
std::vector<VkImageView> attachment_views;
uint32_t base = 0;
for (uint32_t a = 0; a != attachments.color_attachment_count(); ++a) {
attachment_views.push_back(m_image_views[base + i].vk());
base += m_image_count;
base += image_count;
}
if (attachments.has_depth_stencil()) {
attachment_views.push_back(m_image_views[base].vk());
Expand Down Expand Up @@ -149,11 +149,10 @@ void Framebuffer::destroy()
VkDevice device = m_renderer.vk_device();
if (device == VK_NULL_HANDLE)
return;
for (uint32_t i = 0; i != m_image_count; ++i) {
vkDestroyFramebuffer(device, m_framebuffers[i], nullptr);
m_framebuffers[i] = VK_NULL_HANDLE;
for (const auto fb : m_framebuffers) {
vkDestroyFramebuffer(device, fb, nullptr);
}
m_image_count = 0;
m_framebuffers.clear();
for (auto& image_view : m_image_views) {
image_view.destroy(device);
}
Expand Down
13 changes: 6 additions & 7 deletions src/xci/graphics/vulkan/Framebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,29 @@ class Attachments;

class Framebuffer {
public:
static constexpr uint32_t max_image_count = 8;

explicit Framebuffer(Renderer& renderer)
: m_renderer(renderer), m_image_memory(renderer) {}
~Framebuffer() { destroy(); }

/// \param image_count - Number of color buffers
void create(const Attachments& attachments, VkExtent2D size, uint32_t image_count,
VkImage* swapchain_images = nullptr);
void destroy();

VkImage color_image(uint32_t buffer, uint32_t image_index) const { return m_images[buffer * m_image_count + image_index]; }
VkImageView color_image_view(uint32_t buffer, uint32_t image_index) const { return m_image_views[buffer * m_image_count + image_index].vk(); }
uint32_t color_image_count() const { return m_framebuffers.size(); }
VkImage color_image(uint32_t buffer, uint32_t image_index) const { return m_images[buffer * m_framebuffers.size() + image_index]; }
VkImageView color_image_view(uint32_t buffer, uint32_t image_index) const { return m_image_views[buffer * m_framebuffers.size() + image_index].vk(); }

VkFramebuffer vk_framebuffer(uint32_t index) const { return m_framebuffers[index]; }
VkFramebuffer operator[](uint32_t index) const { return m_framebuffers[index]; }

Renderer& renderer() { return m_renderer; }
Renderer& renderer() const { return m_renderer; }

private:
VkDeviceSize create_image(const ImageCreateInfo& image_ci, VkImage& image);

Renderer& m_renderer;
VkFramebuffer m_framebuffers[max_image_count] {};
std::vector<VkFramebuffer> m_framebuffers;
DeviceMemory m_image_memory;

// Images in following order and counts:
Expand All @@ -52,7 +52,6 @@ class Framebuffer {
std::vector<VkImage> m_images;
std::vector<ImageView> m_image_views;

uint32_t m_image_count = 0; // <= max_image_count
uint32_t m_borrowed_count = 0; // number of borrowed swapchain images (at beginning of m_images)
};

Expand Down
11 changes: 3 additions & 8 deletions src/xci/graphics/vulkan/Swapchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,8 @@ void Swapchain::create()
destroy();
m_swapchain = new_swapchain;

TRACE("Vulkan: swapchain image count: {}", m_image_count);
vkGetSwapchainImagesKHR(device, m_swapchain, &m_image_count, nullptr);

if (m_image_count > Framebuffer::max_image_count)
VK_THROW("vulkan: too many swapchain images");

vkGetSwapchainImagesKHR(device, m_swapchain, &m_image_count, m_images);
vk_get_vector(m_images, vkGetSwapchainImagesKHR, device, m_swapchain);
TRACE("Vulkan: swapchain image count: {}", m_images.size());
}


Expand All @@ -102,7 +97,7 @@ void Swapchain::destroy()

void Swapchain::create_framebuffers()
{
m_framebuffer.create(m_attachments, m_extent, m_image_count, m_images);
m_framebuffer.create(m_attachments, m_extent, m_images.size(), m_images.data());
}


Expand Down
5 changes: 3 additions & 2 deletions src/xci/graphics/vulkan/Swapchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "Attachments.h"

#include <vulkan/vulkan.h>
#include <vector>

namespace xci::graphics {

Expand Down Expand Up @@ -72,13 +73,13 @@ class Swapchain {

Attachments m_attachments;

VkImage m_images[Framebuffer::max_image_count] {};
std::vector<VkImage> m_images;
Framebuffer m_framebuffer;

// create info
VkSurfaceFormatKHR m_surface_format {};
VkExtent2D m_extent {};
uint32_t m_image_count = 0; // <= max_image_count
uint32_t m_image_count = 0; // recommended image count according to surface capabilities
PresentMode m_present_mode = PresentMode::Fifo;
};

Expand Down
14 changes: 13 additions & 1 deletion src/xci/graphics/vulkan/VulkanError.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// vulkan_error.h created on 2019-12-05 as part of xcikit project
// https://github.com/rbrich/xcikit
//
// Copyright 2019–2023 Radek Brich
// Copyright 2019–2024 Radek Brich
// Licensed under the Apache License, Version 2.0 (see LICENSE file)

#include <vulkan/vulkan_core.h> // VkResult
Expand Down Expand Up @@ -107,6 +107,18 @@ inline void vk_log_error(std::string_view msg, enum VkResult vk_res)
#endif


/// Utility function to get vector data from Vulkan API
template <typename VecT, typename F, typename... Args>
auto vk_get_vector(VecT& res, F&& f, Args&&... args) {
uint32_t count;
f(args..., &count, nullptr);
res.resize(count);
const auto r = f(args..., &count, res.data());
res.resize(count);
return r;
}


} // namespace xci::graphics

#endif // include guard
4 changes: 4 additions & 0 deletions xcikit-config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ find_dependency(Threads)
find_dependency(fmt)
find_dependency(pegtl)

if (NOT EMSCRIPTEN AND (@XCI_DATA@ OR @XCI_VFS@))
find_dependency(ZLIB)
endif()

if (@XCI_GRAPHICS@ OR @XCI_SCRIPT@)
find_dependency(range-v3)
endif()
Expand Down

0 comments on commit 57470ce

Please sign in to comment.