Designated initializers are a C++20 feature that makes initialization code more readable. In addition it enforces that the order of initialization is the same as the order of declaration in the struct. Compare those two code parts:
There are some code parts where I decided not to use them though, because while we could make the following struct const by introducing lambdas, it would maybe make the code harder to read:
// This struct is not const, and not all members are set in here because some are set depending on certain conditions
// See code below
auto barrier = make_info<VkImageMemoryBarrier>({
.oldLayout = old_layout,
.newLayout = new_layout,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange = subres_range,
});
// This could be part of the struct by using lambdas, but will it make it easier to read?
switch (old_layout) {
case VK_IMAGE_LAYOUT_UNDEFINED:
barrier.srcAccessMask = 0;
break;
case VK_IMAGE_LAYOUT_PREINITIALIZED:
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
break;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
break;
default:
break;
}
switch (new_layout) {
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
barrier.dstAccessMask = barrier.dstAccessMask | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
if (barrier.srcAccessMask == 0) {
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
}
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
break;
default:
break;
}
Introduction
Designated initializers are a C++20 feature that makes initialization code more readable. In addition it enforces that the order of initialization is the same as the order of declaration in the struct. Compare those two code parts:
Old code:
New code with designated initializers:
This code example uses the following
make_info
template:Summary
Designated initializers
const
:)Notes
static_cast
.const
by introducing lambdas, it would maybe make the code harder to read: