#include <Vk/QueryPool/QueryPool.hpp>
#include <Utilities/Utilities.hpp>

Vk::QueryPool::QueryPool(std::shared_ptr<Vk::Device> device, int count) : device(device)
{
    VkQueryPoolCreateInfo queryPoolInfo = {};
    queryPoolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
    queryPoolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
    queryPoolInfo.queryCount = count;

    if (vkCreateQueryPool(device->inner(), &queryPoolInfo, nullptr, &innerQueryPool) != VK_SUCCESS)
    {
        crash("Failed to create query pool!");
    }
}

Vk::QueryPool::~QueryPool()
{
    vkDestroyQueryPool(device->inner(), innerQueryPool, nullptr);
}

VkQueryPool Vk::QueryPool::inner()
{
    return innerQueryPool;
}

double Vk::QueryPool::getDeltaTimeMS(uint32_t startIndex, uint32_t endIndex)
{
    uint64_t timestamps[2];
    vkGetQueryPoolResults(
        device->inner(),
        innerQueryPool,
        startIndex,
        1,
        sizeof(uint64_t),
        &timestamps[0],
        sizeof(uint64_t),
        VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT
    );
    vkGetQueryPoolResults(
        device->inner(),
        innerQueryPool,
        endIndex,
        1,
        sizeof(uint64_t),
        &timestamps[1],
        sizeof(uint64_t),
        VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT
    );

    return (double) (timestamps[1] - timestamps[0]) * (double) device->properties.limits.timestampPeriod * 1e-6;
}