#pragma once #include #include #include namespace orange { template uint32_t VkEnumerate(Func function, OutArray& outArray, Args&&... arguments) { uint32_t count = 0; function(arguments..., &count, nullptr); outArray.resize(count); if (!count) return 0; function(Forward(arguments)..., &count, outArray.data()); return count; } static constexpr VkImageSubresourceRange FirstColorMipSubresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1, }; static constexpr VkImageSubresourceRange FirstDepthMipSubresourceRange = { .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1, }; constexpr VkFormat FormatToSrgbFormat(VkFormat format) { switch (format) { case VK_FORMAT_R8G8B8A8_UNORM: return VK_FORMAT_R8G8B8A8_SRGB; case VK_FORMAT_B8G8R8A8_UNORM: return VK_FORMAT_B8G8R8A8_SRGB; default: return format; } } template Result FindSupportedFormat(VkPhysicalDevice physicalDevice, VkImageTiling tiling, VkFormatFeatureFlags features, Formats... formats) { for (auto& format : {formats...}) { VkFormatProperties props; vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props); if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) return Result::Success(format); if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) return Result::Success(format); } return Result::Error(BasicErrorCode::NotFound); } inline Result FindDepthFormat(VkPhysicalDevice physicalDevice) { return FindSupportedFormat(physicalDevice, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT); } }