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

#define DECL_SHADER_MODULE(name) \
    extern uint32_t spirv_##name[]; \
    extern size_t spirv_size_##name; \
    std::unique_ptr<Vk::ShaderModule> Vk::ShaderModule::name

#include <Vk/ShaderModule/ShaderModuleList.hpp>

Vk::ShaderModule::ShaderModule(std::shared_ptr<Device> device, const uint32_t *bytecode, size_t bytecodeSize) : m_device(device)
{
    VkShaderModuleCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
    createInfo.codeSize = bytecodeSize;
    createInfo.pCode = bytecode;

    if (vkCreateShaderModule(device->inner(), &createInfo, nullptr, &m_shaderModule) != VK_SUCCESS)
    {
        crash("Failed to create shader module!");
    }
}

Vk::ShaderModule::~ShaderModule()
{
    vkDestroyShaderModule(m_device->inner(), m_shaderModule, nullptr);
}

VkShaderModule Vk::ShaderModule::inner()
{
    return m_shaderModule;
}

void Vk::ShaderModule::createAll(std::shared_ptr<Vk::Device> device)
{
    #define DECL_SHADER_MODULE(name) name = std::make_unique<ShaderModule>(device, spirv_##name, spirv_size_##name)
    #include <Vk/ShaderModule/ShaderModuleList.hpp>
}