using System; using System.Collections.Generic; using System.IO; //using VulkanWrapperGenerator; class Program { static string ResolveVkXmlPath(string[] args) { // 1) Explicit path via arg if (args.Length > 0 && File.Exists(args[0])) return args[0]; // 2) VULKAN_SDK based locations var sdk = Environment.GetEnvironmentVariable("VULKAN_SDK"); if (!string.IsNullOrWhiteSpace(sdk)) { var p1 = Path.Combine(sdk, "share", "vulkan", "registry", "vk.xml"); if (File.Exists(p1)) return p1; var p2 = Path.Combine(sdk, "Include", "vulkan", "vk.xml"); if (File.Exists(p2)) return p2; } // 3) Typical Windows SDK layout (adjust if needed) var winShare = Path.Combine(@"C:\VulkanSDK", "1.4.313.0", "share", "vulkan", "registry", "vk.xml"); if (File.Exists(winShare)) return winShare; throw new FileNotFoundException( "vk.xml not found. Pass a path as the first argument or set VULKAN_SDK.\n" + "Searched: , " + (sdk != null ? $"{sdk}\\share\\vulkan\\registry\\vk.xml, {sdk}\\Include\\vulkan\\vk.xml" : "") + ", C:\\VulkanSDK\\1.4.313.0\\share\\vulkan\\registry\\vk.xml"); } static void Main(string[] args) { var xmlPath = ResolveVkXmlPath(args); var spec = VkSpec.Load(xmlPath); // External "sugar" methods you want to inject into wrappers var sugar = new List { new SugarClassSpec("Buffer") { Includes = { "" }, Methods = { new SugarMethodSpec { Name = "uploadData", ReturnType = "void", Parameters = { "const void* data", "size_t size", "IntrusivePtr memory", "VkDeviceSize offset = 0" }, RequiresFunctions = { "vkMapMemory", "vkUnmapMemory", "vkBindBufferMemory" }, BodyLines = { "void* _p = nullptr;", "auto _r = ${vk}.vkMapMemory(${owner0.handle}, ${memory.handle}, offset, size, 0, &_p);", "if (_r != VK_SUCCESS) throw std::runtime_error(\"vkMapMemory failed\");", "std::memcpy(_p, data, size);", "${vk}.vkUnmapMemory(${owner0.handle});", "(void)${vk}.vkBindBufferMemory(${owner0.handle}, ${handle}, ${memory.handle}, 0);" } } } }, new SugarClassSpec("Image") { Methods = { new SugarMethodSpec { Name = "transitionLayout", ReturnType = "void", Parameters = { "IntrusivePtr cmd", "VkImageLayout oldLayout", "VkImageLayout newLayout", "VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT" }, RequiresFunctions = { "vkCmdPipelineBarrier" }, RequiresExtensions = { "VK_KHR_synchronization2" }, // example of extension guard BodyLines = { "VkImageMemoryBarrier barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };", "barrier.oldLayout = oldLayout;", "barrier.newLayout = newLayout;", "barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;", "barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;", "barrier.image = ${handle};", "barrier.subresourceRange.aspectMask = aspect;", "barrier.subresourceRange.baseMipLevel = 0;", "barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;", "barrier.subresourceRange.baseArrayLayer = 0;", "barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;", "VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;", "VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;", "${vk}.vkCmdPipelineBarrier(${cmd.handle}, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);" } } } }, new SugarClassSpec("Device") { Includes = { "", "" }, Methods = { new SugarMethodSpec { Name = "createShaderModuleFromFile", ReturnType = "IntrusivePtr", Parameters = { "const char* path" }, RequiresFunctions = { "vkCreateShaderModule" }, BodyLines = { "std::ifstream f(path, std::ios::binary | std::ios::ate);", "if (!f) throw std::runtime_error(\"Can't open SPV file\");", "auto sz = (size_t)f.tellg(); f.seekg(0);", "std::vector code((sz + 3) / 4);", "f.read(reinterpret_cast(code.data()), sz);", "VkShaderModuleCreateInfo ci{ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO };", "ci.codeSize = sz;", "ci.pCode = code.data();", "VkShaderModule h = VK_NULL_HANDLE;", "auto r = ${vk}.vkCreateShaderModule(${handle}, &ci, nullptr, &h);", "if (r != VK_SUCCESS) throw std::runtime_error(\"vkCreateShaderModule failed\");", "return IntrusivePtr(new ShaderModule(${selfOwners}, h));" } } } } }; var outDir = "Generated"; Directory.CreateDirectory(outDir); var gen = new Generator(spec, outDir, sugar); gen.GenerateAll(); Console.WriteLine("✅ Generated into ./Generated"); Console.WriteLine("vk.xml used: " + xmlPath); } }