#ifndef DC_VULKAN_EXT_H
#define DC_VULKAN_EXT_H
// Vulkan extension loader for CLAS (VK_NV_cluster_acceleration_structure)
// and mesh shaders (VK_NV_mesh_shader).
//
// Loads VkDevice and extension function pointers from Godot's RenderingDevice
// via get_driver_resource() + dlsym(libvulkan.so).
//
// This is separate from Godot's rendering pipeline — we create our own
// command pool for acceleration structure operations.
#include <cstdint>
#include <vulkan/vulkan.h>
struct DCVulkanContext {
VkInstance instance = VK_NULL_HANDLE;
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
VkDevice device = VK_NULL_HANDLE;
VkQueue queue = VK_NULL_HANDLE;
uint32_t queue_family = 0;
VkCommandPool command_pool = VK_NULL_HANDLE;
// CLAS function pointers (VK_NV_cluster_acceleration_structure)
PFN_vkGetClusterAccelerationStructureBuildSizesNV
GetClusterAccelerationStructureBuildSizesNV = nullptr;
PFN_vkCmdBuildClusterAccelerationStructureIndirectNV
CmdBuildClusterAccelerationStructureIndirectNV = nullptr;
// KHR RT function pointers (VK_KHR_acceleration_structure)
PFN_vkCreateAccelerationStructureKHR CreateAccelerationStructureKHR = nullptr;
PFN_vkDestroyAccelerationStructureKHR DestroyAccelerationStructureKHR = nullptr;
PFN_vkGetAccelerationStructureDeviceAddressKHR GetAccelerationStructureDeviceAddressKHR = nullptr;
PFN_vkGetAccelerationStructureBuildSizesKHR GetAccelerationStructureBuildSizesKHR = nullptr;
PFN_vkCmdBuildAccelerationStructuresKHR CmdBuildAccelerationStructuresKHR = nullptr;
bool rt_supported = false;
// Core function pointers (loaded via dlsym)
PFN_vkAllocateCommandBuffers AllocateCommandBuffers = nullptr;
PFN_vkFreeCommandBuffers FreeCommandBuffers = nullptr;
PFN_vkBeginCommandBuffer BeginCommandBuffer = nullptr;
PFN_vkEndCommandBuffer EndCommandBuffer = nullptr;
PFN_vkQueueSubmit QueueSubmit = nullptr;
PFN_vkQueueWaitIdle QueueWaitIdle = nullptr;
PFN_vkCreateCommandPool CreateCommandPool = nullptr;
PFN_vkDestroyCommandPool DestroyCommandPool = nullptr;
PFN_vkCreateBuffer CreateBuffer = nullptr;
PFN_vkDestroyBuffer DestroyBuffer = nullptr;
PFN_vkAllocateMemory AllocateMemory = nullptr;
PFN_vkFreeMemory FreeMemory = nullptr;
PFN_vkBindBufferMemory BindBufferMemory = nullptr;
PFN_vkGetBufferMemoryRequirements GetBufferMemoryRequirements = nullptr;
PFN_vkGetBufferDeviceAddress GetBufferDeviceAddress = nullptr;
PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties = nullptr;
PFN_vkCmdPipelineBarrier CmdPipelineBarrier = nullptr;
PFN_vkMapMemory MapMemory = nullptr;
PFN_vkUnmapMemory UnmapMemory = nullptr;
PFN_vkDeviceWaitIdle DeviceWaitIdle = nullptr;
bool clas_supported = false;
// Initialize from Godot's RenderingDevice.
// Must be called from the main thread (before workers start).
bool initialize();
// Clean up command pool and any allocated resources.
void cleanup();
// Check if CLAS extension is available and loaded.
bool has_clas() const { return clas_supported; }
bool has_rt() const { return rt_supported; }
};
#endif // DC_VULKAN_EXT_H