Repository: google/filament
File: filament/backend/src/vulkan/platform/VulkanPlatform.cpp (C++)

Code before:
    return ret;
}

fvkutils::VkFormatList findBlittableDepthStencilFormats(VkPhysicalDevice device) {
    std::vector<VkFormat> selectedFormats;
    constexpr VkFormatFeatureFlags required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
            VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
    for (VkFormat format : fvkutils::ALL_VK_FORMATS) {
        if (fvkutils::isVkDepthFormat(format)) {
            VkFormatProperties props;
            vkGetPhysicalDeviceFormatProperties(device, format, &props);
            if ((props.optimalTilingFeatures & required) == required) {
                selectedFormats.push_back(format);
            }
        }
    }
    fvkutils::VkFormatList ret(selectedFormats.size());
    std::copy(selectedFormats.begin(), selectedFormats.end(), ret.begin());
    return ret;
}

/**
 *  Check if the GPU has a unified memory architecture.
 */
bool hasUnifiedMemoryArchitecture(VkPhysicalDevice device) noexcept {
    VkPhysicalDeviceMemoryProperties memoryProperties;
    vkGetPhysicalDeviceMemoryProperties(device, &memoryProperties);

    // Try to identify if the platform is running on a Unified Memory Architecture by inspecting the
    // memory heap flags, if they are all VK_MEMORY_HEAP_DEVICE_LOCAL_BIT it's UMA, otherwise not
    // enough information to make a decision, so default to false.
    for (uint32_t i = 0; i < memoryProperties.memoryHeapCount; ++i) {
        if ((memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0) {
            return false;
        }
    }
    return true;
}

}// anonymous namespace

using SwapChainPtr = VulkanPlatform::SwapChainPtr;

struct VulkanPlatformPrivate {
    VkInstance mInstance = VK_NULL_HANDLE;
    VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
    VkDevice mDevice = VK_NULL_HANDLE;
    uint32_t mGraphicsQueueFamilyIndex = INVALID_VK_INDEX;
    uint32_t mGraphicsQueueIndex = INVALID_VK_INDEX;
    VkQueue mGraphicsQueue = VK_NULL_HANDLE;
    uint32_t mProtectedGraphicsQueueFamilyIndex = INVALID_VK_INDEX;

Review comment (bug):
Is it possible to reuse VulkanContext::mMemoryProperties?

I would also look at how `VulkanContext::mDebugUtilsSupported` is used for a similar mechanism? 

Code after:
    return ret;
}

fvkutils::VkFormatList findBlittableDepthStencilFormats(VkPhysicalDevice device) {
    std::vector<VkFormat> selectedFormats;
    constexpr VkFormatFeatureFlags required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
            VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
    for (VkFormat format : fvkutils::ALL_VK_FORMATS) {
        if (fvkutils::isVkDepthFormat(format)) {
            VkFormatProperties props;
            vkGetPhysicalDeviceFormatProperties(device, format, &props);
            if ((props.optimalTilingFeatures & required) == required) {
                selectedFormats.push_back(format);
            }
        }
    }
    fvkutils::VkFormatList ret(selectedFormats.size());
    std::copy(selectedFormats.begin(), selectedFormats.end(), ret.begin());
    return ret;
}

/**
 *  Check if the GPU has a unified memory architecture.
 */
bool hasUnifiedMemoryArchitecture(VkPhysicalDeviceMemoryProperties memoryProperties) noexcept {
    // Try to identify if the platform is running on a Unified Memory Architecture by inspecting the
    // memory heap flags, if they are all VK_MEMORY_HEAP_DEVICE_LOCAL_BIT it's UMA, otherwise not
    // enough information to make a decision, so default to false.
    for (uint32_t i = 0; i < memoryProperties.memoryHeapCount; ++i) {
        if ((memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0) {
            return false;
        }
    }
    return true;
}

}// anonymous namespace

using SwapChainPtr = VulkanPlatform::SwapChainPtr;

struct VulkanPlatformPrivate {
    VkInstance mInstance = VK_NULL_HANDLE;
    VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
    VkDevice mDevice = VK_NULL_HANDLE;
    uint32_t mGraphicsQueueFamilyIndex = INVALID_VK_INDEX;
    uint32_t mGraphicsQueueIndex = INVALID_VK_INDEX;
    VkQueue mGraphicsQueue = VK_NULL_HANDLE;
    uint32_t mProtectedGraphicsQueueFamilyIndex = INVALID_VK_INDEX;
    uint32_t mProtectedGraphicsQueueIndex = INVALID_VK_INDEX;
    VkQueue mProtectedGraphicsQueue = VK_NULL_HANDLE;
    VulkanContext mContext = {};