7#include "gfx_pipeline_vulkan_intf.hpp"
8#include "../container/container.hpp"
9#include "../geometry/geometry.hpp"
10#include "../image/image.hpp"
11#include "../codec/codec.hpp"
12#include "../macros.hpp"
13#include <vulkan/vulkan.hpp>
14#include <vma/vk_mem_alloc.h>
16hi_export_module(hikogui.GFX : gfx_pipeline_image_intf);
18hi_export
namespace hi {
inline namespace v1 {
28 struct alignas(16) vertex {
44 static vk::VertexInputBindingDescription inputBindingDescription()
46 return {0,
sizeof(
vertex), vk::VertexInputRate::eVertex};
52 {0, 0, vk::Format::eR32G32B32A32Sfloat, offsetof(vertex,
position)},
54 {2, 0, vk::Format::eR32G32B32A32Sfloat, offsetof(vertex,
atlas_position)},
60 sfloat_rg32 windowExtent =
extent2{0.0, 0.0};
61 sfloat_rg32 viewportScale =
scale2{0.0, 0.0};
62 sfloat_rg32 atlasExtent =
extent2{0.0, 0.0};
63 sfloat_rg32 atlasScale =
scale2{0.0, 0.0};
67 return {{vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment, 0,
sizeof(
push_constants)}};
73 VmaAllocation allocation = {};
76 vk::ImageLayout layout = vk::ImageLayout::eUndefined;
78 void transitionLayout(
const gfx_device& device, vk::Format format, vk::ImageLayout nextLayout);
84 enum class state_type { uninitialized, drawing, uploaded };
89 gfx_device *device =
nullptr;
95 constexpr paged_image()
noexcept =
default;
96 paged_image(paged_image&&
other)
noexcept;
97 paged_image& operator=(paged_image&&
other)
noexcept;
98 paged_image(paged_image
const&
other) =
delete;
99 paged_image& operator=(paged_image
const&
other) =
delete;
108 paged_image(gfx_surface
const *surface,
png const& image)
noexcept;
110 [[nodiscard]]
constexpr explicit operator bool()
const noexcept
112 return device !=
nullptr;
115 [[nodiscard]]
constexpr extent2 size()
const noexcept
122 auto const num_columns = (width + page_size - 1) / page_size;
123 auto const num_rows = (height + page_size - 1) / page_size;
124 return {num_columns, num_rows};
127 [[nodiscard]]
constexpr extent2 size_in_float_pages()
const noexcept
131 return extent2{size / page_size_};
143 struct device_shared {
144 constexpr static std::size_t atlas_num_pages_per_axis = 8;
145 constexpr static std::size_t atlas_num_pages_per_image = atlas_num_pages_per_axis * atlas_num_pages_per_axis;
146 constexpr static std::size_t atlas_image_axis_size = atlas_num_pages_per_axis * (paged_image::page_size + 2);
147 constexpr static std::size_t atlas_maximum_num_images = 64;
148 constexpr static std::size_t staging_image_width = 1024;
149 constexpr static std::size_t staging_image_height = 1024;
151 gfx_device
const& device;
153 vk::ShaderModule vertex_shader_module;
154 vk::ShaderModule fragment_shader_module;
161 vk::Sampler atlas_sampler;
162 vk::DescriptorImageInfo atlas_sampler_descriptor_image_info;
164 device_shared(gfx_device
const& device);
167 device_shared(device_shared
const&) =
delete;
168 device_shared& operator=(device_shared
const&) =
delete;
169 device_shared(device_shared&&) =
delete;
170 device_shared& operator=(device_shared&&) =
delete;
175 void destroy(gfx_device
const *vulkanDevice);
185 void draw_in_command_buffer(vk::CommandBuffer
const& commandBuffer);
206 vector_span<vertex>& vertices,
209 paged_image
const& image)
noexcept;
225 void make_staging_border_transparent(
aarectangle border_rectangle)
noexcept;
232 void clear_staging_between_border_and_upload(
aarectangle border_rectangle,
aarectangle upload_rectangle)
noexcept;
244 void prepare_staging_for_upload(paged_image
const& image)
noexcept;
248 void update_atlas_with_staging_pixmap(paged_image
const& image)
noexcept;
250 void build_shaders();
251 void teardown_shaders(gfx_device
const *device);
252 void add_atlas_image();
254 void teardown_atlas(gfx_device
const *device);
259 vector_span<vertex> vertexBufferData;
261 ~gfx_pipeline_image() =
default;
262 gfx_pipeline_image(
const gfx_pipeline_image&) =
delete;
263 gfx_pipeline_image& operator=(
const gfx_pipeline_image&) =
delete;
264 gfx_pipeline_image(gfx_pipeline_image&&) =
delete;
265 gfx_pipeline_image& operator=(gfx_pipeline_image&&) =
delete;
267 gfx_pipeline_image(gfx_surface *surface) : gfx_pipeline(surface) {}
269 void draw_in_command_buffer(vk::CommandBuffer commandBuffer,
draw_context const& context)
override;
272 push_constants pushConstants;
273 int numberOfAtlasImagesInDescriptor = 0;
275 vk::Buffer vertexBuffer;
276 VmaAllocation vertexBufferAllocation;
281 [[nodiscard]]
size_t getDescriptorSetVersion()
const override;
283 [[nodiscard]] vk::VertexInputBindingDescription createVertexInputBindingDescription()
const override;
287 void build_vertex_buffers()
override;
288 void teardown_vertex_buffers()
override;
@ other
The gui_event does not have associated data.
Definition gui_event_variant.hpp:24
The HikoGUI namespace.
Definition array_generic.hpp:21
The HikoGUI API version 1.
Definition array_generic.hpp:22
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:378
Class which represents an axis-aligned rectangle.
Definition aarectangle.hpp:33
A high-level geometric extent.
Definition extent2.hpp:32
Draw context for drawing using the HikoGUI shaders.
Definition draw_context_intf.hpp:209
Definition gfx_pipeline_image_vulkan_intf.hpp:23
Definition gfx_pipeline_image_vulkan_intf.hpp:28
sfloat_rgba32 atlas_position
The x, y coordinate inside the texture-atlas, z is used as an index in the texture-atlas array.
Definition gfx_pipeline_image_vulkan_intf.hpp:37
sfloat_rgba32 position
The pixel-coordinates where the origin is located relative to the bottom-left corner of the window.
Definition gfx_pipeline_image_vulkan_intf.hpp:30
sfloat_rgba32 clipping_rectangle
Definition gfx_pipeline_image_vulkan_intf.hpp:34
Definition gfx_pipeline_image_vulkan_intf.hpp:59
Definition gfx_pipeline_image_vulkan_intf.hpp:71
void upload(pixmap_span< sfloat_rgba16 const > image) noexcept
Upload image to atlas.
Definition gfx_pipeline_image_vulkan_impl.hpp:243
void destroy(gfx_device const *vulkanDevice)
Definition gfx_pipeline_image_vulkan_impl.hpp:268
void place_vertices(vector_span< vertex > &vertices, aarectangle const &clipping_rectangle, quad const &box, paged_image const &image) noexcept
Place vertices for a single image.
Definition gfx_pipeline_image_vulkan_impl.hpp:626
std::vector< std::size_t > allocate_pages(std::size_t num_pages) noexcept
Allocate pages from the atlas.
Definition gfx_pipeline_image_vulkan_impl.hpp:275
void prepare_atlas_for_rendering()
Prepare the atlas so that it can be used as a texture map by the shaders.
Definition gfx_pipeline_image_vulkan_impl.hpp:463
hi::pixmap_span< sfloat_rgba16 > get_staging_pixmap()
Get the full staging pixel map excluding border.
Definition gfx_pipeline_image_vulkan_impl.hpp:295
void free_pages(std::vector< std::size_t > const &pages) noexcept
Deallocate pages back to the atlas.
Definition gfx_pipeline_image_vulkan_impl.hpp:290
A non-owning 2D pixel-based image.
Definition pixmap_span.hpp:34
A 2D pixel-based image.
Definition pixmap.hpp:38