Files
RenderFramework/Tools/VulkanWrapperGenerator/Program.cs
T

142 lines
6.6 KiB
C#
Raw Normal View History

2025-09-10 01:44:09 +03:00
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: <arg0>, " +
(sdk != null ? $"{sdk}\\share\\vulkan\\registry\\vk.xml, {sdk}\\Include\\vulkan\\vk.xml" : "<VULKAN_SDK unset>") +
", 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<SugarClassSpec>
{
new SugarClassSpec("Buffer")
{
Includes = { "<cstring>" },
Methods =
{
new SugarMethodSpec
{
Name = "uploadData",
ReturnType = "void",
Parameters = {
"const void* data",
"size_t size",
"IntrusivePtr<DeviceMemory> 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<CommandBuffer> 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 = { "<vector>", "<fstream>" },
Methods =
{
new SugarMethodSpec
{
Name = "createShaderModuleFromFile",
ReturnType = "IntrusivePtr<ShaderModule>",
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<uint32_t> code((sz + 3) / 4);",
"f.read(reinterpret_cast<char*>(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<ShaderModule>(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);
}
}