Skip to content

Commit

Permalink
implement base swapchain image acquire
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthapz committed Feb 21, 2024
1 parent 5d30e93 commit eb135bf
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 20 deletions.
16 changes: 12 additions & 4 deletions modules/stormkit/Engine/Renderer.mpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ export {
struct Tag {};

public:
struct Frame {};
struct Frame {
core::UInt32 current_frame;
core::UInt32 image_index;

core::NakedRef<const gpu::Semaphore> image_available;
core::NakedRef<const gpu::Semaphore> render_finished;
core::NakedRef<gpu::Fence> in_flight;
};

RenderSurface(const gpu::Instance& instance,
const gpu::Device& device,
Expand All @@ -48,16 +55,17 @@ export {
const wsi::Window& window) noexcept
-> gpu::Expected<std::unique_ptr<RenderSurface>>;

[[nodiscard]] auto acquireNextFrame() -> gpu::Expected<Frame>;
auto present(const Frame& frame) -> void;
[[nodiscard]] auto beginFrame() -> gpu::Expected<Frame>;
auto presentFrame(const Frame& frame) -> void;

private:
core::DeferInit<gpu::Surface> m_surface;
core::DeferInit<gpu::Swapchain> m_swapchain;
std::optional<gpu::Swapchain> m_old_swapchain;

core::RangeExtent m_current_frame = 0;
std::vector<gpu::Semaphore> m_image_availables;
std::vector<gpu::Semaphore> m_render_finished;
std::vector<gpu::Semaphore> m_render_finisheds;
std::vector<gpu::Fence> m_in_flight_fences;

bool m_need_recreate;
Expand Down
2 changes: 2 additions & 0 deletions modules/stormkit/Gpu/Resource/Swapchain.mpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export namespace stormkit::gpu {
-> Expected<std::unique_ptr<Swapchain>>;

[[nodiscard]] auto images() const noexcept -> const std::vector<Image>&;
[[nodiscard]] auto acquireNextImage(std::chrono::nanoseconds wait, const Semaphore &image_available) const noexcept
-> Expected<std::pair<gpu::Result, core::UInt32>>;

[[nodiscard]] auto vkHandle() const noexcept -> const vk::raii::SwapchainKHR&;

Expand Down
8 changes: 3 additions & 5 deletions src/Engine/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,7 @@ namespace stormkit::engine {
.and_then(
core::curry(gpu::Queue::create, std::cref(*m_device), m_device->rasterQueueEntry()))
.transform(core::monadic::set(m_raster_queue))
.and_then([this, window = std::move(window)] {
return doInitRenderSurface(std::move(window));
});
.and_then(core::curry(&Renderer::doInitRenderSurface, this, std::move(window)));
}

/////////////////////////////////////
Expand Down Expand Up @@ -254,8 +252,8 @@ namespace stormkit::engine {
for (;;) {
if (token.stop_requested()) return;

m_surface->acquireNextFrame()
.transform([this](auto&& frame) { m_surface->present(frame); })
m_surface->beginFrame()
.transform([this](auto&& frame) { m_surface->presentFrame(frame); })
.transform_error(core::expectsWithMessage("Failed to acquire frame"));
}

Expand Down
41 changes: 32 additions & 9 deletions src/Engine/Renderer/RenderSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import stormkit.Gpu;

import :Renderer;

using namespace std::chrono_literals;

namespace stormkit::engine {
/////////////////////////////////////
/////////////////////////////////////
Expand Down Expand Up @@ -36,7 +38,7 @@ namespace stormkit::engine {
gpu::Semaphore::create(device)
.transform(emplaceTo(m_image_availables))
.and_then(curry(gpu::Semaphore::create, std::cref(device)))
.transform(emplaceTo(m_render_finished))
.transform(emplaceTo(m_render_finisheds))
.and_then(curry(gpu::Fence::createSignaled, std::cref(device)))
.transform(emplaceTo(m_in_flight_fences))
.transform_error(map(narrow<gpu::Result>(), throwError()));
Expand All @@ -50,16 +52,17 @@ namespace stormkit::engine {
auto transition_command_buffers =
command_pool.createCommandBuffers(std::size(m_swapchain->images()));

for(auto i : core::range(std::size(transition_command_buffers))) {
auto &&image = m_swapchain->images()[i];
auto &&transition_command_buffer = transition_command_buffers[i];
for (auto i : core::range(std::size(transition_command_buffers))) {
auto&& image = m_swapchain->images()[i];
auto&& transition_command_buffer = transition_command_buffers[i];

transition_command_buffer.begin(true);
transition_command_buffer.transitionImageLayout(image, gpu::ImageLayout::Undefined, gpu::ImageLayout::Present_Src);
transition_command_buffer.transitionImageLayout(image,
gpu::ImageLayout::Undefined,
gpu::ImageLayout::Present_Src);
transition_command_buffer.end();
}


auto fence = gpu::Fence::create(device)
.transform_error(map(narrow<gpu::Result>(), throwError()))
.value();
Expand All @@ -72,12 +75,32 @@ namespace stormkit::engine {

/////////////////////////////////////
/////////////////////////////////////
auto RenderSurface::acquireNextFrame() -> gpu::Expected<Frame> {
return {};
auto RenderSurface::beginFrame() -> gpu::Expected<Frame> {
core::expects(m_surface.initialized());
core::expects(m_swapchain.initialized());

const auto& image_available = m_image_availables[m_current_frame];
const auto& render_finished = m_render_finisheds[m_current_frame];
auto& in_flight = m_in_flight_fences[m_current_frame];

return in_flight.wait(std::chrono::milliseconds { 1000 })
.transform([&in_flight](auto&& result) { in_flight.reset(); })
.and_then(core::curry(&gpu::Swapchain::acquireNextImage,
&(m_swapchain.get()),
1000ns,
std::cref(image_available)))
.transform([&, this](auto&& _result) noexcept {
auto&& [result, image_index] = _result; // TODO handle result
return Frame { .current_frame = core::narrow<core::UInt32>(m_current_frame),
.image_index = image_index,
.image_available = image_available,
.render_finished = render_finished,
.in_flight = in_flight };
});
}

/////////////////////////////////////
/////////////////////////////////////
auto RenderSurface::present(const Frame& frame) -> void {
auto RenderSurface::presentFrame(const Frame& frame) -> void {
}
} // namespace stormkit::engine
20 changes: 18 additions & 2 deletions src/Gpu/Resource/Swapchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ namespace stormkit::gpu {
const auto& physical_device = device.physicalDevice();
const auto capabilities =
physical_device.vkHandle().getSurfaceCapabilitiesKHR(*surface.vkHandle());
const auto formats = physical_device.vkHandle().getSurfaceFormatsKHR(*(surface.vkHandle()));
const auto present_modes = physical_device.vkHandle().getSurfacePresentModesKHR(*(surface.vkHandle()));
const auto formats = physical_device.vkHandle().getSurfaceFormatsKHR(*(surface.vkHandle()));
const auto present_modes =
physical_device.vkHandle().getSurfacePresentModesKHR(*(surface.vkHandle()));

const auto format = chooseSwapSurfaceFormat(formats);
const auto present_mode = chooseSwapPresentMode(present_modes);
Expand Down Expand Up @@ -128,4 +129,19 @@ namespace stormkit::gpu {
m_pixel_format = core::narrow<PixelFormat>(format.format);
m_extent = as<core::math::ExtentU>(swapchain_extent);
}

/////////////////////////////////////
/////////////////////////////////////
auto Swapchain::acquireNextImage(std::chrono::nanoseconds wait,
const Semaphore& image_available) const noexcept
-> Expected<std::pair<gpu::Result, core::UInt32>> {
auto&& [result, index] =
m_vk_swapchain->acquireNextImage(wait.count(), toVkHandle()(image_available));

if (result != vk::Result::eSuccess | result != vk::Result::eErrorOutOfDateKHR |
result != vk::Result::eSuboptimalKHR)
return std::unexpected { core::narrow<gpu::Result>(result) };

return std::make_pair(core::narrow<gpu::Result>(result), index);
}
} // namespace stormkit::gpu

0 comments on commit eb135bf

Please sign in to comment.