Skip to content

Commit cbd31e5

Browse files
committed
WIP images
1 parent 19ba8ac commit cbd31e5

File tree

4 files changed

+108
-19
lines changed

4 files changed

+108
-19
lines changed

guide/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@
4242
- [Vertex Buffer](memory/vertex_buffer.md)
4343
- [Command Block](memory/command_block.md)
4444
- [Device Buffers](memory/device_buffers.md)
45+
- [Images](memory/images.md)

guide/src/memory/images.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Images
2+
3+
Images have a lot more properties and creation parameters than buffers. We shall constrain ourselves to just two kinds: sampled images (textures) for shaders, and depth images for rendering. For now add the foundation types and functions:
4+
5+
```cpp
6+
struct RawImage {
7+
auto operator==(RawImage const& rhs) const -> bool = default;
8+
9+
VmaAllocator allocator{};
10+
VmaAllocation allocation{};
11+
vk::Image image{};
12+
vk::Extent2D extent{};
13+
vk::Format format{};
14+
std::uint32_t levels{};
15+
};
16+
17+
struct ImageDeleter {
18+
void operator()(RawImage const& raw_image) const noexcept;
19+
};
20+
21+
using Image = Scoped<RawImage, ImageDeleter>;
22+
23+
struct ImageCreateInfo {
24+
VmaAllocator allocator;
25+
std::uint32_t queue_family;
26+
};
27+
28+
[[nodiscard]] auto create_image(ImageCreateInfo const& create_info,
29+
vk::ImageUsageFlags usage, std::uint32_t levels,
30+
vk::Format format, vk::Extent2D extent)
31+
-> Image;
32+
```
33+
34+
Implementation:
35+
36+
```cpp
37+
void ImageDeleter::operator()(RawImage const& raw_image) const noexcept {
38+
vmaDestroyImage(raw_image.allocator, raw_image.image, raw_image.allocation);
39+
}
40+
41+
// ...
42+
auto vma::create_image(ImageCreateInfo const& create_info,
43+
vk::ImageUsageFlags const usage,
44+
std::uint32_t const levels, vk::Format const format,
45+
vk::Extent2D const extent) -> Image {
46+
if (extent.width == 0 || extent.height == 0) {
47+
std::println(stderr, "Images cannot have 0 width or height");
48+
return {};
49+
}
50+
auto image_ci = vk::ImageCreateInfo{};
51+
image_ci.setImageType(vk::ImageType::e2D)
52+
.setExtent({extent.width, extent.height, 1})
53+
.setFormat(format)
54+
.setUsage(usage)
55+
.setArrayLayers(1)
56+
.setMipLevels(levels)
57+
.setSamples(vk::SampleCountFlagBits::e1)
58+
.setTiling(vk::ImageTiling::eOptimal)
59+
.setInitialLayout(vk::ImageLayout::eUndefined)
60+
.setQueueFamilyIndices(create_info.queue_family);
61+
auto const vk_image_ci = static_cast<VkImageCreateInfo>(image_ci);
62+
63+
auto allocation_ci = VmaAllocationCreateInfo{};
64+
allocation_ci.usage = VMA_MEMORY_USAGE_AUTO;
65+
VkImage image{};
66+
VmaAllocation allocation{};
67+
auto const result = vmaCreateImage(create_info.allocator, &vk_image_ci,
68+
&allocation_ci, &image, &allocation, {});
69+
if (result != VK_SUCCESS) {
70+
std::println(stderr, "Failed to create VMA Image");
71+
return {};
72+
}
73+
74+
return RawImage{
75+
.allocator = create_info.allocator,
76+
.allocation = allocation,
77+
.image = image,
78+
.extent = extent,
79+
.format = format,
80+
.levels = levels,
81+
};
82+
}
83+
```

src/vma.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ void BufferDeleter::operator()(RawBuffer const& raw_buffer) const noexcept {
1313
vmaDestroyBuffer(raw_buffer.allocator, raw_buffer.buffer,
1414
raw_buffer.allocation);
1515
}
16+
17+
void ImageDeleter::operator()(RawImage const& raw_image) const noexcept {
18+
vmaDestroyImage(raw_image.allocator, raw_image.image, raw_image.allocation);
19+
}
1620
} // namespace vma
1721

1822
auto vma::create_allocator(vk::Instance const instance,
@@ -130,19 +134,21 @@ auto vma::create_device_buffer(BufferCreateInfo const& create_info,
130134
return ret;
131135
}
132136

133-
auto vma::create_image(VmaAllocator allocator,
134-
ImageCreateInfo const& create_info) -> Image {
135-
if (create_info.extent.width == 0 || create_info.extent.height == 0) {
137+
auto vma::create_image(ImageCreateInfo const& create_info,
138+
vk::ImageUsageFlags const usage,
139+
std::uint32_t const levels, vk::Format const format,
140+
vk::Extent2D const extent) -> Image {
141+
if (extent.width == 0 || extent.height == 0) {
136142
std::println(stderr, "Images cannot have 0 width or height");
137143
return {};
138144
}
139145
auto image_ci = vk::ImageCreateInfo{};
140146
image_ci.setImageType(vk::ImageType::e2D)
141-
.setExtent({create_info.extent.width, create_info.extent.height, 1})
142-
.setFormat(create_info.format)
143-
.setUsage(create_info.usage)
147+
.setExtent({extent.width, extent.height, 1})
148+
.setFormat(format)
149+
.setUsage(usage)
144150
.setArrayLayers(1)
145-
.setMipLevels(create_info.levels)
151+
.setMipLevels(levels)
146152
.setSamples(vk::SampleCountFlagBits::e1)
147153
.setTiling(vk::ImageTiling::eOptimal)
148154
.setInitialLayout(vk::ImageLayout::eUndefined)
@@ -153,20 +159,20 @@ auto vma::create_image(VmaAllocator allocator,
153159
allocation_ci.usage = VMA_MEMORY_USAGE_AUTO;
154160
VkImage image{};
155161
VmaAllocation allocation{};
156-
auto const result = vmaCreateImage(allocator, &vk_image_ci, &allocation_ci,
157-
&image, &allocation, {});
162+
auto const result = vmaCreateImage(create_info.allocator, &vk_image_ci,
163+
&allocation_ci, &image, &allocation, {});
158164
if (result != VK_SUCCESS) {
159165
std::println(stderr, "Failed to create VMA Image");
160166
return {};
161167
}
162168

163169
return RawImage{
164-
.allocator = allocator,
170+
.allocator = create_info.allocator,
165171
.allocation = allocation,
166172
.image = image,
167-
.extent = create_info.extent,
168-
.format = create_info.format,
169-
.levels = create_info.levels,
173+
.extent = extent,
174+
.format = format,
175+
.levels = levels,
170176
};
171177
}
172178
} // namespace lvk

src/vma.hpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,12 @@ struct ImageDeleter {
7373
using Image = Scoped<RawImage, ImageDeleter>;
7474

7575
struct ImageCreateInfo {
76+
VmaAllocator allocator;
7677
std::uint32_t queue_family;
77-
vk::ImageUsageFlags usage;
78-
vk::Format format;
79-
vk::Extent2D extent;
80-
std::uint32_t levels;
8178
};
8279

83-
[[nodiscard]] auto create_image(VmaAllocator allocator,
84-
ImageCreateInfo const& create_info) -> Image;
80+
[[nodiscard]] auto create_image(ImageCreateInfo const& create_info,
81+
vk::ImageUsageFlags usage, std::uint32_t levels,
82+
vk::Format format, vk::Extent2D extent)
83+
-> Image;
8584
} // namespace lvk::vma

0 commit comments

Comments
 (0)