more code

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-12-11 12:54:54 +02:00
parent f8aa685b8a
commit 872ce63358
2 changed files with 186 additions and 48 deletions

View File

@@ -352,6 +352,10 @@ auto VulkanRenderer::descriptors_init() -> void
.add_binding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
.build(m_logger, m_vkb.dev,
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
m_vk.deletion_queue.emplace([&]() {
vkDestroyDescriptorSetLayout(
m_vkb.dev, m_vk.gpu_scene_data_descriptor_layout, nullptr);
});
}
auto VulkanRenderer::pipelines_init() -> void
@@ -628,6 +632,59 @@ auto VulkanRenderer::default_data_init() -> void
destroy_buffer(m_vk.rectangle.index_buffer);
destroy_buffer(m_vk.rectangle.vertex_buffer);
});
{
// Solid color images
auto const white = smath::pack_unorm4x8(smath::Vec4 { 1, 1, 1, 1 });
m_vk.white_image = create_image(&white, VkExtent3D { 1, 1, 1 },
VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
auto const black = smath::pack_unorm4x8(smath::Vec4 { 0, 0, 0, 1 });
m_vk.black_image = create_image(&black, VkExtent3D { 1, 1, 1 },
VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
auto const gray
= smath::pack_unorm4x8(smath::Vec4 { 0.6f, 0.6f, 0.6f, 1 });
m_vk.gray_image = create_image(&gray, VkExtent3D { 1, 1, 1 },
VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
// Error checkerboard image
auto const magenta = smath::pack_unorm4x8(smath::Vec4 { 1, 0, 1, 1 });
std::array<uint32_t, 16 * 16> checkerboard;
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
checkerboard[y * 16 + x]
= ((x % 2) ^ (y % 2)) ? magenta : black;
}
}
m_vk.error_image
= create_image(checkerboard.data(), VkExtent3D { 16, 16, 1 },
VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
}
VkSamplerCreateInfo sampler_ci {};
sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
sampler_ci.pNext = nullptr;
sampler_ci.magFilter = VK_FILTER_NEAREST;
sampler_ci.minFilter = VK_FILTER_NEAREST;
vkCreateSampler(
m_vkb.dev, &sampler_ci, nullptr, &m_vk.default_sampler_nearest);
sampler_ci.magFilter = VK_FILTER_LINEAR;
sampler_ci.minFilter = VK_FILTER_LINEAR;
vkCreateSampler(
m_vkb.dev, &sampler_ci, nullptr, &m_vk.default_sampler_linear);
m_vk.deletion_queue.emplace([&]() {
vkDestroySampler(m_vkb.dev, m_vk.default_sampler_linear, nullptr);
vkDestroySampler(m_vkb.dev, m_vk.default_sampler_nearest, nullptr);
destroy_image(m_vk.error_image);
destroy_image(m_vk.gray_image);
destroy_image(m_vk.black_image);
destroy_image(m_vk.white_image);
});
}
auto VulkanRenderer::render() -> void
@@ -925,60 +982,22 @@ auto VulkanRenderer::create_draw_image(uint32_t width, uint32_t height) -> void
{
destroy_draw_image();
m_vk.draw_image.format = VK_FORMAT_R16G16B16A16_SFLOAT;
m_vk.draw_image.extent = {
width,
height,
1,
};
VkImageCreateInfo rimg_ci { vkinit::image_create_info(
m_vk.draw_image.format,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
m_vk.draw_image.extent) };
VmaAllocationCreateInfo rimg_alloci {};
rimg_alloci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
rimg_alloci.requiredFlags
= VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vmaCreateImage(m_vk.allocator, &rimg_ci, &rimg_alloci,
&m_vk.draw_image.image, &m_vk.draw_image.allocation, nullptr);
VkImageViewCreateInfo rview_ci
= vkinit::imageview_create_info(m_vk.draw_image.format,
m_vk.draw_image.image, VK_IMAGE_ASPECT_COLOR_BIT);
VK_CHECK(m_logger,
vkCreateImageView(
m_vkb.dev, &rview_ci, nullptr, &m_vk.draw_image.image_view));
auto const flags { VK_IMAGE_USAGE_TRANSFER_SRC_BIT
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT };
m_vk.draw_image = create_image(
{ width, height, 1 }, VK_FORMAT_R16G16B16A16_SFLOAT, flags);
}
auto VulkanRenderer::create_depth_image(uint32_t width, uint32_t height) -> void
{
destroy_depth_image();
m_vk.depth_image.format = VK_FORMAT_D32_SFLOAT;
m_vk.depth_image.extent = { width, height, 1 };
VkImageCreateInfo rimg_ci { vkinit::image_create_info(
m_vk.depth_image.format,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
m_vk.depth_image.extent) };
VmaAllocationCreateInfo rimg_alloci {};
rimg_alloci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
rimg_alloci.requiredFlags
= VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vmaCreateImage(m_vk.allocator, &rimg_ci, &rimg_alloci,
&m_vk.depth_image.image, &m_vk.depth_image.allocation, nullptr);
VkImageViewCreateInfo rview_ci
= vkinit::imageview_create_info(m_vk.depth_image.format,
m_vk.depth_image.image, VK_IMAGE_ASPECT_DEPTH_BIT);
VK_CHECK(m_logger,
vkCreateImageView(
m_vkb.dev, &rview_ci, nullptr, &m_vk.depth_image.image_view));
auto const flags { VK_IMAGE_USAGE_TRANSFER_SRC_BIT
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT };
m_vk.depth_image
= create_image({ width, height, 1 }, VK_FORMAT_D32_SFLOAT, flags);
}
auto VulkanRenderer::destroy_depth_image() -> void
@@ -1061,6 +1080,112 @@ auto VulkanRenderer::destroy_swapchain() -> void
m_vk.swapchain_extent = { 0, 0 };
}
auto VulkanRenderer::create_image(VkExtent3D size, VkFormat format,
VkImageUsageFlags flags, bool mipmapped) -> AllocatedImage
{
AllocatedImage new_image;
new_image.format = format;
new_image.extent = size;
auto img_ci { vkinit::image_create_info(format, flags, size) };
if (mipmapped) {
img_ci.mipLevels = static_cast<uint32_t>(std::floor(
std::log2(std::max(size.width, size.height))))
+ 1;
}
VmaAllocationCreateInfo alloc_ci {};
alloc_ci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
alloc_ci.requiredFlags
= VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VK_CHECK(m_logger,
vmaCreateImage(m_vk.allocator, &img_ci, &alloc_ci, &new_image.image,
&new_image.allocation, nullptr));
VkImageAspectFlags aspect_flag { VK_IMAGE_ASPECT_COLOR_BIT };
if (format == VK_FORMAT_D32_SFLOAT) {
aspect_flag = VK_IMAGE_ASPECT_DEPTH_BIT;
}
auto const view_ci { vkinit::imageview_create_info(
format, new_image.image, aspect_flag) };
VK_CHECK(m_logger,
vkCreateImageView(m_vkb.dev, &view_ci, nullptr, &new_image.image_view));
return new_image;
}
auto VulkanRenderer::create_image(void const *data, VkExtent3D size,
VkFormat format, VkImageUsageFlags flags, bool mipmapped) -> AllocatedImage
{
size_t data_size {
static_cast<uint32_t>(size.depth) * static_cast<uint32_t>(size.width)
* static_cast<uint32_t>(size.height) * 4,
};
auto const upload_buffer {
create_buffer(data_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VMA_MEMORY_USAGE_CPU_TO_GPU),
};
VmaAllocationInfo info {};
vmaGetAllocationInfo(m_vk.allocator, upload_buffer.allocation, &info);
void *mapped_data { reinterpret_cast<GPUSceneData *>(info.pMappedData) };
if (!mapped_data) {
VkResult res = vmaMapMemory(
m_vk.allocator, upload_buffer.allocation, (void **)&mapped_data);
assert(res == VK_SUCCESS);
}
defer({
if (info.pMappedData == nullptr) {
vmaUnmapMemory(m_vk.allocator, upload_buffer.allocation);
}
});
memcpy(mapped_data, data, data_size);
auto const new_image {
create_image(size, format,
flags | VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
mipmapped),
};
immediate_submit([&](VkCommandBuffer cmd) {
vkutil::transition_image(cmd, new_image.image,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkBufferImageCopy copy_region {};
copy_region.bufferOffset = 0;
copy_region.bufferRowLength = 0;
copy_region.bufferImageHeight = 0;
copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_region.imageSubresource.mipLevel = 0;
copy_region.imageSubresource.baseArrayLayer = 0;
copy_region.imageSubresource.layerCount = 1;
copy_region.imageExtent = size;
vkCmdCopyBufferToImage(cmd, upload_buffer.buffer, new_image.image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
vkutil::transition_image(cmd, new_image.image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
});
destroy_buffer(upload_buffer);
return new_image;
}
auto VulkanRenderer::destroy_image(AllocatedImage const &img) -> void
{
vkDestroyImageView(m_vkb.dev, img.image_view, nullptr);
vmaDestroyImage(m_vk.allocator, img.image, img.allocation);
}
auto VulkanRenderer::create_buffer(size_t alloc_size, VkBufferUsageFlags usage,
VmaMemoryUsage memory_usage) -> AllocatedBuffer
{

View File

@@ -63,6 +63,11 @@ private:
auto destroy_depth_image() -> void;
auto recreate_swapchain(uint32_t width, uint32_t height) -> void;
auto destroy_swapchain() -> void;
auto create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags flags,
bool mipmapped = false) -> AllocatedImage;
auto create_image(void const *data, VkExtent3D size, VkFormat format,
VkImageUsageFlags flags, bool mipmapped = false) -> AllocatedImage;
auto destroy_image(AllocatedImage const &img) -> void;
auto create_buffer(size_t alloc_size, VkBufferUsageFlags usage,
VmaMemoryUsage memory_usage) -> AllocatedBuffer;
@@ -129,6 +134,14 @@ private:
uint64_t frame_number { 0 };
std::vector<std::shared_ptr<Mesh>> test_meshes;
AllocatedImage white_image {};
AllocatedImage black_image {};
AllocatedImage gray_image {};
AllocatedImage error_image {};
VkSampler default_sampler_linear;
VkSampler default_sampler_nearest;
} m_vk;
SDL_Window *m_window { nullptr };