Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-12-17 15:51:38 +02:00
parent 59999f211d
commit a99233fcbe
10 changed files with 280 additions and 119 deletions

View File

@@ -0,0 +1,21 @@
#version 450
layout(location = 0) out vec4 out_color;
layout(push_constant) uniform PushConstants {
vec2 resolution;
} pc;
void main()
{
vec2 uv = (gl_FragCoord.xy + vec2(0.5)) / pc.resolution;
float v = sin(uv.x * 10.0) + cos(uv.y * 10.0);
float r = 0.5 + 0.5 * cos(6.2831 * (uv.x + v));
float g = 0.5 + 0.5 * cos(6.2831 * (uv.y + v + 0.33));
float b = 0.5 + 0.5 * cos(6.2831 * (uv.x - uv.y + 0.66));
out_color = vec4(r, g, b, 1.0);
}

View File

@@ -0,0 +1,13 @@
#version 450
void main()
{
vec2 positions[3] = vec2[](
vec2(-1.0, -1.0),
vec2( 3.0, -1.0),
vec2(-1.0, 3.0)
);
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
}

View File

@@ -14,7 +14,6 @@ else
endif
shader_sources = files(
'gradient.comp',
'triangle.frag',
'triangle.vert',
'triangle_mesh.frag',

View File

@@ -310,6 +310,8 @@ auto Application::run() -> void
ImGui::Render();
m_renderer->set_antialiasing(VulkanRenderer::AntiAliasingKind::MSAA_8X);
m_renderer->render([&](VulkanRenderer::GL &gl) {
auto view { smath::matrix_look_at(smath::Vec3 { 0.0f, 0.0f, 3.0f },
smath::Vec3 { 0.0f, 0.0f, 0.0f },

View File

@@ -79,9 +79,15 @@ auto GraphicsPipelineBuilder::set_cull_mode(VkCullModeFlags cull_mode,
auto GraphicsPipelineBuilder::set_multisampling_none()
-> GraphicsPipelineBuilder &
{
return set_multisampling(VK_SAMPLE_COUNT_1_BIT);
}
auto GraphicsPipelineBuilder::set_multisampling(VkSampleCountFlagBits samples)
-> GraphicsPipelineBuilder &
{
m_multisampling.sampleShadingEnable = VK_FALSE;
m_multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
m_multisampling.rasterizationSamples = samples;
m_multisampling.minSampleShading = 1.0f;
m_multisampling.pSampleMask = nullptr;
m_multisampling.alphaToCoverageEnable = VK_FALSE;

View File

@@ -25,6 +25,8 @@ struct GraphicsPipelineBuilder {
auto set_cull_mode(VkCullModeFlags cull_mode, VkFrontFace front_face)
-> GraphicsPipelineBuilder &;
auto set_multisampling_none() -> GraphicsPipelineBuilder &;
auto set_multisampling(VkSampleCountFlagBits samples)
-> GraphicsPipelineBuilder &;
auto disable_blending() -> GraphicsPipelineBuilder &;
auto enable_blending_additive() -> GraphicsPipelineBuilder &;
auto enable_blending_alpha_blend() -> GraphicsPipelineBuilder &;

View File

@@ -89,7 +89,7 @@ auto load_shader_module(std::span<uint8_t> spirv_data, vk::Device device)
namespace vkinit {
auto image_create_info(vk::Format format, vk::ImageUsageFlags usage_flags,
vk::Extent3D extent) -> vk::ImageCreateInfo
vk::Extent3D extent, vk::SampleCountFlagBits samples) -> vk::ImageCreateInfo
{
vk::ImageCreateInfo info {};
info.imageType = vk::ImageType::e2D;
@@ -97,7 +97,7 @@ auto image_create_info(vk::Format format, vk::ImageUsageFlags usage_flags,
info.extent = extent;
info.mipLevels = 1;
info.arrayLayers = 1;
info.samples = vk::SampleCountFlagBits::e1;
info.samples = samples;
info.tiling = vk::ImageTiling::eOptimal;
info.usage = usage_flags;
return info;

View File

@@ -52,7 +52,9 @@ auto load_shader_module(std::span<uint8_t> spirv_data, vk::Device device)
namespace vkinit {
auto image_create_info(vk::Format format, vk::ImageUsageFlags usage_flags,
vk::Extent3D extent) -> vk::ImageCreateInfo;
vk::Extent3D extent,
vk::SampleCountFlagBits samples = vk::SampleCountFlagBits::e1)
-> vk::ImageCreateInfo;
auto imageview_create_info(vk::Format format, vk::Image image,
vk::ImageAspectFlags aspect_flags) -> vk::ImageViewCreateInfo;
auto command_buffer_submit_info(vk::CommandBuffer cmd)

View File

@@ -56,8 +56,25 @@ auto VulkanRenderer::GL::begin_drawing(vk::CommandBuffer cmd,
m_color_target->extent.height,
};
auto color_att { vkinit::attachment_info(m_color_target->image_view,
nullptr, vk::ImageLayout::eColorAttachmentOptimal) };
vk::RenderingAttachmentInfo color_att {};
vk::ClearValue clear {};
clear.color = vk::ClearColorValue {
smath::Vec4 { Colors::DARK_SLATE_GRAY, 1.0f },
};
if (m_renderer.m_vk.msaa_samples != vk::SampleCountFlagBits::e1) {
assert(m_renderer.m_vk.msaa_color_image.image_view
&& "MSAA enabled but MSAA color image is missing");
color_att = vkinit::attachment_info(
m_renderer.m_vk.msaa_color_image.image_view, &clear,
vk::ImageLayout::eColorAttachmentOptimal);
color_att.resolveMode = vk::ResolveModeFlagBits::eAverage;
color_att.resolveImageView = m_color_target->image_view;
color_att.resolveImageLayout = vk::ImageLayout::eColorAttachmentOptimal;
color_att.storeOp = vk::AttachmentStoreOp::eDontCare;
} else {
color_att = vkinit::attachment_info(m_color_target->image_view, &clear,
vk::ImageLayout::eColorAttachmentOptimal);
}
std::optional<vk::RenderingAttachmentInfo> depth_att;
if (m_depth_target) {
depth_att = vkinit::depth_attachment_info(m_depth_target->image_view,
@@ -192,21 +209,21 @@ auto VulkanRenderer::GL::flush() -> void
| vk::BufferUsageFlagBits::eTransferDst,
VMA_MEMORY_USAGE_GPU_ONLY) };
m_renderer.immediate_submit([&](vk::CommandBuffer cmd) {
vk::BufferCopy vertex_copy {};
vertex_copy.srcOffset = 0;
vertex_copy.dstOffset = 0;
vertex_copy.size = vertex_data_size;
cmd.copyBuffer(
staging.buffer, vertex_buffer.buffer, 1, &vertex_copy);
m_renderer.immediate_submit(
[&](vk::CommandBuffer cmd) {
vk::BufferCopy vertex_copy {};
vertex_copy.srcOffset = 0;
vertex_copy.dstOffset = 0;
vertex_copy.size = vertex_data_size;
cmd.copyBuffer(
staging.buffer, vertex_buffer.buffer, 1, &vertex_copy);
vk::BufferCopy index_copy {};
index_copy.srcOffset = vertex_data_size;
index_copy.dstOffset = 0;
index_copy.size = index_data_size;
cmd.copyBuffer(
staging.buffer, index_buffer.buffer, 1, &index_copy);
},
vk::BufferCopy index_copy {};
index_copy.srcOffset = vertex_data_size;
index_copy.dstOffset = 0;
index_copy.size = index_data_size;
cmd.copyBuffer(staging.buffer, index_buffer.buffer, 1, &index_copy);
},
/*flush_frame_deletion_queue=*/false,
/*clear_frame_descriptors=*/false);
@@ -280,9 +297,8 @@ auto VulkanRenderer::GL::set_transform(smath::Mat4 const &transform) -> void
m_transform = transform;
}
auto VulkanRenderer::GL::draw_rectangle(
smath::Vec2 pos, smath::Vec2 size, smath::Vec4 rect_color, float rotation)
-> void
auto VulkanRenderer::GL::draw_rectangle(smath::Vec2 pos, smath::Vec2 size,
smath::Vec4 rect_color, float rotation) -> void
{
auto const half_size = size * 0.5f;
auto const center = pos + half_size;
@@ -293,10 +309,14 @@ auto VulkanRenderer::GL::draw_rectangle(
return smath::Vec2 { c * p.x() - s * p.y(), s * p.x() + c * p.y() };
};
auto const br = center + rotate(smath::Vec2 { half_size.x(), -half_size.y() });
auto const tr = center + rotate(smath::Vec2 { half_size.x(), half_size.y() });
auto const bl = center + rotate(smath::Vec2 { -half_size.x(), -half_size.y() });
auto const tl = center + rotate(smath::Vec2 { -half_size.x(), half_size.y() });
auto const br
= center + rotate(smath::Vec2 { half_size.x(), -half_size.y() });
auto const tr
= center + rotate(smath::Vec2 { half_size.x(), half_size.y() });
auto const bl
= center + rotate(smath::Vec2 { -half_size.x(), -half_size.y() });
auto const tl
= center + rotate(smath::Vec2 { -half_size.x(), half_size.y() });
begin(GeometryKind::Quads);
@@ -473,7 +493,6 @@ VulkanRenderer::~VulkanRenderer()
m_vk.imm_command_buffer.reset();
m_vk.imm_command_pool.reset();
m_vk.imm_fence.reset();
m_vk.gradient_pipeline.reset();
m_vk.triangle_pipeline.reset();
m_vk.mesh_pipeline.reset();
m_vk.default_sampler_linear.reset();
@@ -481,6 +500,7 @@ VulkanRenderer::~VulkanRenderer()
destroy_swapchain();
destroy_draw_image();
destroy_msaa_color_image();
destroy_depth_image();
m_vk.deletion_queue.flush();
@@ -505,6 +525,97 @@ auto VulkanRenderer::resize(uint32_t width, uint32_t height) -> void
recreate_swapchain(width, height);
}
auto VulkanRenderer::set_antialiasing(AntiAliasingKind kind) -> void
{
auto requested_samples = [&](AntiAliasingKind aa) {
switch (aa) {
case AntiAliasingKind::NONE:
return vk::SampleCountFlagBits::e1;
case AntiAliasingKind::MSAA_2X:
return vk::SampleCountFlagBits::e2;
case AntiAliasingKind::MSAA_4X:
return vk::SampleCountFlagBits::e4;
case AntiAliasingKind::MSAA_8X:
return vk::SampleCountFlagBits::e8;
}
return vk::SampleCountFlagBits::e1;
}(kind);
auto best_supported = [&](vk::SampleCountFlagBits requested) {
auto const supported = m_vk.supported_framebuffer_samples;
auto pick_if_supported = [&](vk::SampleCountFlagBits candidate) {
return (supported & candidate) == candidate;
};
if (requested >= vk::SampleCountFlagBits::e64
&& pick_if_supported(vk::SampleCountFlagBits::e64)) {
return vk::SampleCountFlagBits::e64;
}
if (requested >= vk::SampleCountFlagBits::e32
&& pick_if_supported(vk::SampleCountFlagBits::e32)) {
return vk::SampleCountFlagBits::e32;
}
if (requested >= vk::SampleCountFlagBits::e16
&& pick_if_supported(vk::SampleCountFlagBits::e16)) {
return vk::SampleCountFlagBits::e16;
}
if (requested >= vk::SampleCountFlagBits::e8
&& pick_if_supported(vk::SampleCountFlagBits::e8)) {
return vk::SampleCountFlagBits::e8;
}
if (requested >= vk::SampleCountFlagBits::e4
&& pick_if_supported(vk::SampleCountFlagBits::e4)) {
return vk::SampleCountFlagBits::e4;
}
if (requested >= vk::SampleCountFlagBits::e2
&& pick_if_supported(vk::SampleCountFlagBits::e2)) {
return vk::SampleCountFlagBits::e2;
}
return vk::SampleCountFlagBits::e1;
}(requested_samples);
auto kind_for_samples = [](vk::SampleCountFlagBits samples) {
switch (samples) {
case vk::SampleCountFlagBits::e2:
return AntiAliasingKind::MSAA_2X;
case vk::SampleCountFlagBits::e4:
return AntiAliasingKind::MSAA_4X;
case vk::SampleCountFlagBits::e8:
return AntiAliasingKind::MSAA_8X;
default:
return AntiAliasingKind::NONE;
}
};
auto const effective_kind = kind_for_samples(best_supported);
if (m_vk.antialiasing_kind == effective_kind
&& m_vk.msaa_samples == best_supported) {
return;
}
if (best_supported != requested_samples) {
m_logger.warn("Requested antialiasing {} but using {}",
static_cast<int>(kind), static_cast<int>(effective_kind));
}
m_vk.antialiasing_kind = effective_kind;
m_vk.msaa_samples = best_supported;
if (!m_vk.swapchain || m_vk.swapchain_extent.width == 0
|| m_vk.swapchain_extent.height == 0) {
return;
}
m_device.waitIdle();
create_msaa_color_image(
m_vk.swapchain_extent.width, m_vk.swapchain_extent.height);
create_depth_image(
m_vk.swapchain_extent.width, m_vk.swapchain_extent.height);
pipelines_init();
}
auto VulkanRenderer::immediate_submit(
std::function<void(vk::CommandBuffer cmd)> &&function,
bool flush_frame_deletion_queue, bool clear_frame_descriptors) -> void
@@ -637,6 +748,13 @@ auto VulkanRenderer::vk_init() -> void
m_logger.info("Chosen Vulkan physical device: {}",
m_vkb.phys_dev.properties.deviceName);
auto const props = m_physical_device.getProperties();
m_vk.supported_framebuffer_samples
= props.limits.framebufferColorSampleCounts
& props.limits.framebufferDepthSampleCounts;
m_vk.msaa_samples = vk::SampleCountFlagBits::e1;
m_vk.antialiasing_kind = AntiAliasingKind::NONE;
vkb::DeviceBuilder device_builder { m_vkb.phys_dev };
auto dev_ret { device_builder.build() };
if (!dev_ret) {
@@ -672,6 +790,7 @@ auto VulkanRenderer::swapchain_init() -> void
SDL_GetWindowSize(m_window, &w, &h);
create_swapchain(static_cast<uint32_t>(w), static_cast<uint32_t>(h));
create_draw_image(static_cast<uint32_t>(w), static_cast<uint32_t>(h));
create_msaa_color_image(static_cast<uint32_t>(w), static_cast<uint32_t>(h));
create_depth_image(static_cast<uint32_t>(w), static_cast<uint32_t>(h));
}
@@ -719,26 +838,7 @@ auto VulkanRenderer::sync_init() -> void
auto VulkanRenderer::descriptors_init() -> void
{
std::vector<DescriptorAllocator::PoolSizeRatio> sizes {
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 },
};
m_vk.descriptor_allocator.init_pool(m_vkb.dev.device, 10, sizes);
auto draw_layout_raw
= DescriptorLayoutBuilder()
.add_binding(0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
.build(m_logger, m_vkb.dev.device, VK_SHADER_STAGE_COMPUTE_BIT);
m_vk.draw_image_descriptor_layout
= vk::DescriptorSetLayout { draw_layout_raw };
m_vk.draw_image_descriptors = m_vk.descriptor_allocator.allocate(
m_logger, m_vkb.dev.device, m_vk.draw_image_descriptor_layout);
update_draw_image_descriptor();
m_vk.deletion_queue.emplace([&]() {
m_vk.descriptor_allocator.destroy_pool(m_vkb.dev.device);
m_device.destroyDescriptorSetLayout(m_vk.draw_image_descriptor_layout);
m_device.destroyDescriptorSetLayout(
m_vk.gpu_scene_data_descriptor_layout);
m_device.destroyDescriptorSetLayout(
@@ -780,34 +880,10 @@ auto VulkanRenderer::descriptors_init() -> void
auto VulkanRenderer::pipelines_init() -> void
{
background_pipelines_init();
triangle_pipeline_init();
mesh_pipeline_init();
}
auto VulkanRenderer::background_pipelines_init() -> void
{
Pipeline::Builder builder { m_device, m_logger };
std::array layout_handles { m_vk.draw_image_descriptor_layout };
builder.set_descriptor_set_layouts(layout_handles);
uint8_t compute_draw_shader_data[] {
#embed "gradient_comp.spv"
};
auto compute_draw_shader { vkutil::load_shader_module(
std::span<uint8_t>(
compute_draw_shader_data, sizeof(compute_draw_shader_data)),
m_device) };
if (!compute_draw_shader) {
m_logger.err("Failed to load gradient compute shader");
}
auto stage_ci { vkinit::pipeline_shader_stage(
vk::ShaderStageFlagBits::eCompute, compute_draw_shader.get()) };
m_vk.gradient_pipeline = builder.build_compute(stage_ci);
}
auto VulkanRenderer::triangle_pipeline_init() -> void
{
Pipeline::Builder builder { m_device, m_logger };
@@ -842,7 +918,8 @@ auto VulkanRenderer::triangle_pipeline_init() -> void
triangle_vert_shader.get(), triangle_frag_shader.get())
.set_input_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.set_polygon_mode(VK_POLYGON_MODE_FILL)
.set_multisampling_none()
.set_multisampling(
static_cast<VkSampleCountFlagBits>(m_vk.msaa_samples))
.enable_blending_additive()
.disable_depth_testing()
.set_color_attachment_format(
@@ -897,7 +974,8 @@ auto VulkanRenderer::mesh_pipeline_init() -> void
.set_input_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.set_polygon_mode(VK_POLYGON_MODE_FILL)
.set_cull_mode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE)
.set_multisampling_none()
.set_multisampling(
static_cast<VkSampleCountFlagBits>(m_vk.msaa_samples))
.disable_blending()
.enable_depth_testing()
.set_color_attachment_format(
@@ -1109,15 +1187,22 @@ auto VulkanRenderer::render(std::function<void(GL &)> const &record) -> void
vkBeginCommandBuffer(static_cast<VkCommandBuffer>(cmd),
reinterpret_cast<VkCommandBufferBeginInfo *>(&cmd_begin_info)));
vkutil::transition_image(cmd, m_vk.draw_image.image,
vk::ImageLayout::eUndefined, vk::ImageLayout::eGeneral);
bool const msaa_enabled = m_vk.msaa_samples != vk::SampleCountFlagBits::e1;
draw_background(cmd);
vkutil::transition_image(cmd, m_vk.draw_image.image, m_vk.draw_image_layout,
vk::ImageLayout::eColorAttachmentOptimal);
m_vk.draw_image_layout = vk::ImageLayout::eColorAttachmentOptimal;
if (msaa_enabled) {
vkutil::transition_image(cmd, m_vk.msaa_color_image.image,
m_vk.msaa_color_image_layout,
vk::ImageLayout::eColorAttachmentOptimal);
m_vk.msaa_color_image_layout = vk::ImageLayout::eColorAttachmentOptimal;
}
vkutil::transition_image(cmd, m_vk.draw_image.image,
vk::ImageLayout::eGeneral, vk::ImageLayout::eColorAttachmentOptimal);
vkutil::transition_image(cmd, m_vk.depth_image.image,
vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthAttachmentOptimal);
m_vk.depth_image_layout, vk::ImageLayout::eDepthAttachmentOptimal);
m_vk.depth_image_layout = vk::ImageLayout::eDepthAttachmentOptimal;
gl.begin_drawing(cmd, m_vk.draw_image, &m_vk.depth_image);
if (record) {
@@ -1125,9 +1210,9 @@ auto VulkanRenderer::render(std::function<void(GL &)> const &record) -> void
}
gl.end_drawing();
vkutil::transition_image(cmd, m_vk.draw_image.image,
vk::ImageLayout::eColorAttachmentOptimal,
vkutil::transition_image(cmd, m_vk.draw_image.image, m_vk.draw_image_layout,
vk::ImageLayout::eTransferSrcOptimal);
m_vk.draw_image_layout = vk::ImageLayout::eTransferSrcOptimal;
vkutil::transition_image(cmd, m_vk.swapchain_images.at(swapchain_image_idx),
vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal);
@@ -1180,18 +1265,6 @@ auto VulkanRenderer::render(std::function<void(GL &)> const &record) -> void
VK_CHECK(m_logger, present_result);
}
auto VulkanRenderer::draw_background(vk::CommandBuffer cmd) -> void
{
cmd.bindPipeline(
vk::PipelineBindPoint::eCompute, m_vk.gradient_pipeline.get());
auto compute_set = vk::DescriptorSet { m_vk.draw_image_descriptors };
cmd.bindDescriptorSets(vk::PipelineBindPoint::eCompute,
m_vk.gradient_pipeline.get_layout(), 0, compute_set, {});
cmd.dispatch(
static_cast<uint32_t>(std::ceil(m_vk.draw_extent.width / 16.0)),
static_cast<uint32_t>(std::ceil(m_vk.draw_extent.height / 16.0)), 1);
}
auto VulkanRenderer::draw_imgui(
vk::CommandBuffer cmd, vk::ImageView target_image_view) -> void
{
@@ -1260,10 +1333,26 @@ auto VulkanRenderer::create_draw_image(uint32_t width, uint32_t height) -> void
auto const flags { vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eTransferDst
| vk::ImageUsageFlagBits::eStorage
| vk::ImageUsageFlagBits::eSampled
| vk::ImageUsageFlagBits::eColorAttachment };
m_vk.draw_image = create_image(
{ width, height, 1 }, vk::Format::eR16G16B16A16Sfloat, flags);
m_vk.draw_image_layout = vk::ImageLayout::eUndefined;
}
auto VulkanRenderer::create_msaa_color_image(uint32_t width, uint32_t height)
-> void
{
destroy_msaa_color_image();
if (m_vk.msaa_samples == vk::SampleCountFlagBits::e1) {
return;
}
auto const flags { vk::ImageUsageFlagBits::eColorAttachment };
m_vk.msaa_color_image = create_image(
{ width, height, 1 }, m_vk.draw_image.format, flags, m_vk.msaa_samples);
m_vk.msaa_color_image_layout = vk::ImageLayout::eUndefined;
}
auto VulkanRenderer::create_depth_image(uint32_t width, uint32_t height) -> void
@@ -1273,8 +1362,9 @@ auto VulkanRenderer::create_depth_image(uint32_t width, uint32_t height) -> void
auto const flags { vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eTransferDst
| vk::ImageUsageFlagBits::eDepthStencilAttachment };
m_vk.depth_image
= create_image({ width, height, 1 }, vk::Format::eD32Sfloat, flags);
m_vk.depth_image = create_image(
{ width, height, 1 }, vk::Format::eD32Sfloat, flags, m_vk.msaa_samples);
m_vk.depth_image_layout = vk::ImageLayout::eUndefined;
}
auto VulkanRenderer::destroy_depth_image() -> void
@@ -1288,17 +1378,10 @@ auto VulkanRenderer::destroy_depth_image() -> void
m_vk.depth_image.image = vk::Image {};
m_vk.depth_image.allocation = nullptr;
m_vk.depth_image.extent = vk::Extent3D { 0, 0, 0 };
m_vk.depth_image_layout = vk::ImageLayout::eUndefined;
}
}
auto VulkanRenderer::update_draw_image_descriptor() -> void
{
DescriptorWriter()
.write_image(0, m_vk.draw_image.image_view, VK_NULL_HANDLE,
VK_IMAGE_LAYOUT_GENERAL, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
.update_set(m_vkb.dev.device, m_vk.draw_image_descriptors);
}
auto VulkanRenderer::destroy_draw_image() -> void
{
if (m_vk.draw_image.image) {
@@ -1310,6 +1393,22 @@ auto VulkanRenderer::destroy_draw_image() -> void
m_vk.draw_image.image = vk::Image {};
m_vk.draw_image.allocation = nullptr;
m_vk.draw_image.extent = vk::Extent3D { 0, 0, 0 };
m_vk.draw_image_layout = vk::ImageLayout::eUndefined;
}
}
auto VulkanRenderer::destroy_msaa_color_image() -> void
{
if (m_vk.msaa_color_image.image) {
m_device.destroyImageView(m_vk.msaa_color_image.image_view);
m_vk.msaa_color_image.image_view = vk::ImageView {};
vmaDestroyImage(m_vk.allocator,
static_cast<VkImage>(m_vk.msaa_color_image.image),
m_vk.msaa_color_image.allocation);
m_vk.msaa_color_image.image = vk::Image {};
m_vk.msaa_color_image.allocation = nullptr;
m_vk.msaa_color_image.extent = vk::Extent3D { 0, 0, 0 };
m_vk.msaa_color_image_layout = vk::ImageLayout::eUndefined;
}
}
@@ -1320,6 +1419,7 @@ auto VulkanRenderer::recreate_swapchain(uint32_t width, uint32_t height) -> void
if (width == 0 || height == 0) {
destroy_swapchain();
destroy_draw_image();
destroy_msaa_color_image();
destroy_depth_image();
m_vk.swapchain_extent = vk::Extent2D { 0, 0 };
return;
@@ -1327,12 +1427,13 @@ auto VulkanRenderer::recreate_swapchain(uint32_t width, uint32_t height) -> void
destroy_swapchain();
destroy_draw_image();
destroy_msaa_color_image();
destroy_depth_image();
create_swapchain(width, height);
create_draw_image(width, height);
create_msaa_color_image(width, height);
create_depth_image(width, height);
update_draw_image_descriptor();
}
auto VulkanRenderer::destroy_swapchain() -> void
@@ -1351,13 +1452,14 @@ auto VulkanRenderer::destroy_swapchain() -> void
}
auto VulkanRenderer::create_image(vk::Extent3D size, vk::Format format,
vk::ImageUsageFlags flags, bool mipmapped) -> AllocatedImage
vk::ImageUsageFlags flags, vk::SampleCountFlagBits samples, bool mipmapped)
-> AllocatedImage
{
AllocatedImage new_image;
new_image.format = format;
new_image.extent = size;
auto img_ci { vkinit::image_create_info(format, flags, size) };
auto img_ci { vkinit::image_create_info(format, flags, size, samples) };
if (mipmapped) {
img_ci.mipLevels = static_cast<uint32_t>(std::floor(
std::log2(std::max(size.width, size.height))))
@@ -1418,7 +1520,7 @@ auto VulkanRenderer::create_image(void const *data, vk::Extent3D size,
create_image(size, format,
flags | vk::ImageUsageFlagBits::eTransferDst
| vk::ImageUsageFlagBits::eTransferSrc,
mipmapped),
vk::SampleCountFlagBits::e1, mipmapped),
};
immediate_submit([&](vk::CommandBuffer cmd) {

View File

@@ -13,7 +13,6 @@
#include "Colors.h"
#include "DeletionQueue.h"
#include "DescriptorAllocator.h"
#include "Loader.h"
#include "Logger.h"
#include "Pipeline.h"
@@ -29,6 +28,13 @@ struct GPUDrawPushConstants {
constexpr unsigned FRAME_OVERLAP = 2;
struct VulkanRenderer {
enum class AntiAliasingKind {
NONE,
MSAA_2X,
MSAA_4X,
MSAA_8X,
};
struct GL {
enum class GeometryKind {
Triangles,
@@ -105,6 +111,11 @@ struct VulkanRenderer {
auto render(std::function<void(GL &)> const &record = {}) -> void;
auto resize(uint32_t width, uint32_t height) -> void;
auto set_antialiasing(AntiAliasingKind kind) -> void;
auto antialiasing() const -> AntiAliasingKind
{
return m_vk.antialiasing_kind;
}
auto immediate_submit(std::function<void(vk::CommandBuffer cmd)> &&function,
bool flush_frame_deletion_queue = true,
@@ -151,26 +162,27 @@ private:
auto sync_init() -> void;
auto descriptors_init() -> void;
auto pipelines_init() -> void;
auto background_pipelines_init() -> void;
auto triangle_pipeline_init() -> void;
auto mesh_pipeline_init() -> void;
auto imgui_init() -> void;
auto default_data_init() -> void;
auto draw_background(vk::CommandBuffer cmd) -> void;
auto draw_imgui(vk::CommandBuffer cmd, vk::ImageView target_image_view)
-> void;
auto create_swapchain(uint32_t width, uint32_t height) -> void;
auto create_draw_image(uint32_t width, uint32_t height) -> void;
auto update_draw_image_descriptor() -> void;
auto create_msaa_color_image(uint32_t width, uint32_t height) -> void;
auto destroy_draw_image() -> void;
auto create_depth_image(uint32_t width, uint32_t height) -> void;
auto destroy_depth_image() -> void;
auto destroy_msaa_color_image() -> void;
auto recreate_swapchain(uint32_t width, uint32_t height) -> void;
auto destroy_swapchain() -> void;
auto create_image(vk::Extent3D size, vk::Format format,
vk::ImageUsageFlags flags, bool mipmapped = false) -> AllocatedImage;
vk::ImageUsageFlags flags,
vk::SampleCountFlagBits samples = vk::SampleCountFlagBits::e1,
bool mipmapped = false) -> AllocatedImage;
auto create_image(void const *data, vk::Extent3D size, vk::Format format,
vk::ImageUsageFlags flags, bool mipmapped = false) -> AllocatedImage;
auto destroy_image(AllocatedImage const &img) -> void;
@@ -210,21 +222,23 @@ private:
std::array<FrameData, FRAME_OVERLAP> frames;
AllocatedImage draw_image {};
vk::ImageLayout draw_image_layout { vk::ImageLayout::eUndefined };
AllocatedImage msaa_color_image {};
vk::ImageLayout msaa_color_image_layout { vk::ImageLayout::eUndefined };
AllocatedImage depth_image {};
vk::ImageLayout depth_image_layout { vk::ImageLayout::eUndefined };
vk::Extent2D draw_extent {};
AntiAliasingKind antialiasing_kind { AntiAliasingKind::NONE };
vk::SampleCountFlagBits msaa_samples { vk::SampleCountFlagBits::e1 };
vk::SampleCountFlags supported_framebuffer_samples {};
VmaAllocator allocator;
DescriptorAllocator descriptor_allocator;
VkDescriptorSet draw_image_descriptors {};
vk::DescriptorSetLayout draw_image_descriptor_layout {};
GPUSceneData scene_data {};
vk::DescriptorSetLayout gpu_scene_data_descriptor_layout {};
vk::DescriptorSetLayout single_image_descriptor_layout {};
Pipeline gradient_pipeline;
Pipeline triangle_pipeline;
Pipeline mesh_pipeline;