working on generating rust code from vk.xml
authorJacob Lifshay <programmerjake@gmail.com>
Thu, 27 Sep 2018 08:56:45 +0000 (01:56 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Thu, 27 Sep 2018 08:56:45 +0000 (01:56 -0700)
Cargo.toml
vulkan-driver/Cargo.toml
vulkan-driver/build.rs
vulkan-driver/src/api_impl.rs

index 6b0d8e89d6e158590dffe6638af9e9c03e35e550..54e9f3e894da1207085f1582bf389e0433e2c9d1 100644 (file)
@@ -1,2 +1,4 @@
 [workspace]
-members = ["vulkan-driver"]
+members = [
+    "vulkan-driver",
+]
index 7a85b740e559fc5355a3ef324fa4ffd69a4ecc72..cad14ee9d94797f6d7fdc43170103909c51110cd 100644 (file)
@@ -12,3 +12,4 @@ xcb = "0.8"
 [build-dependencies]
 bindgen = "0.40"
 regex = "1"
+xmltree = "0.8"
index 00e3f95b9c4704891792b53360af17a48d09c3d3..7dc13796daeed3aa93b31e4831a40a7707d19658 100644 (file)
@@ -1,9 +1,17 @@
 extern crate bindgen;
 extern crate regex;
+extern crate xmltree;
 use std::env;
+use std::fmt;
 use std::fs;
 use std::io;
+use std::io::Write;
+use std::ops::Deref;
 use std::path::PathBuf;
+use std::str;
+use xmltree::Element;
+
+const VULKAN_HEADERS_INCLUDE_PATH: &'static str = "../external/Vulkan-Headers/include";
 
 fn detect_vulkan_calling_convention() -> io::Result<String> {
     let code = bindgen::builder()
@@ -22,7 +30,7 @@ VKAPI_ATTR void VKAPI_CALL detect_fn();
 "#,
         ).clang_arg("-target")
         .clang_arg(env::var("TARGET").unwrap())
-        .clang_arg("-I../external/Vulkan-Headers/include")
+        .clang_arg(format!("-I{}", VULKAN_HEADERS_INCLUDE_PATH))
         .whitelist_function("detect_fn")
         .generate()
         .map_err(|_| io::Error::new(io::ErrorKind::Other, "generate() failed"))?
@@ -38,61 +46,68 @@ VKAPI_ATTR void VKAPI_CALL detect_fn();
     }
 }
 
+struct GeneratedCode(String);
+
+impl GeneratedCode {
+    fn new() -> Self {
+        GeneratedCode(String::new())
+    }
+}
+
+impl fmt::Display for GeneratedCode {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        const END_OF_LINE: &'static str = "\n";
+        let mut s: &str = &self.0;
+        if f.alternate() && s.ends_with(END_OF_LINE) {
+            s = &s[..s.len() - END_OF_LINE.len()];
+        }
+        f.write_str(s)
+    }
+}
+
+impl io::Write for GeneratedCode {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.0 += str::from_utf8(buf).unwrap();
+        Ok(buf.len())
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
 fn main() -> io::Result<()> {
-    println!("cargo:rerun-if-changed=vulkan-wrapper.h");
-    println!("cargo:rerun-if-changed=../external/Vulkan-Headers/include");
+    let vulkan_wrapper_header_path = "vulkan-wrapper.h";
+    let vulkan_vk_xml_path = "../external/Vulkan-Headers/registry/vk.xml";
+    println!("cargo:rerun-if-changed={}", vulkan_wrapper_header_path);
+    println!("cargo:rerun-if-changed={}", VULKAN_HEADERS_INCLUDE_PATH);
+    println!("cargo:rerun-if-changed={}", vulkan_vk_xml_path);
+    let parsed_xml = Element::parse(fs::File::open(&PathBuf::from(vulkan_vk_xml_path))?)
+        .map_err(|v| io::Error::new(io::ErrorKind::Other, format!("{}", v)))?;
+    let types = parsed_xml.get_child("types").unwrap();
     let vulkan_calling_convention = detect_vulkan_calling_convention()?;
     let match_calling_convention_regex = regex::Regex::new(r#"extern "([^"]+)""#).unwrap();
     let mut builder = bindgen::builder()
-        .header("vulkan-wrapper.h")
+        .header(vulkan_wrapper_header_path)
         .clang_arg("-target")
         .clang_arg(env::var("TARGET").unwrap())
-        .clang_arg("-I../external/Vulkan-Headers/include")
+        .clang_arg(format!("-I{}", VULKAN_HEADERS_INCLUDE_PATH))
         .prepend_enum_name(false)
         .layout_tests(false)
         .whitelist_var("VK_.*")
         .whitelist_var("ICD_LOADER_MAGIC");
-    for &t in &[
-        "VkInstance",
-        "VkPhysicalDevice",
-        "VkDevice",
-        "VkQueue",
-        "VkCommandBuffer",
-    ] {
-        builder = builder.blacklist_type(t).blacklist_type(format!("{}_T", t));
-    }
-    for &t in &[
-        "VkSemaphore",
-        "VkFence",
-        "VkDeviceMemory",
-        "VkBuffer",
-        "VkImage",
-        "VkEvent",
-        "VkQueryPool",
-        "VkBufferView",
-        "VkImageView",
-        "VkShaderModule",
-        "VkPipelineCache",
-        "VkPipelineLayout",
-        "VkRenderPass",
-        "VkPipeline",
-        "VkDescriptorSetLayout",
-        "VkSampler",
-        "VkDescriptorPool",
-        "VkDescriptorSet",
-        "VkFramebuffer",
-        "VkCommandPool",
-        "VkSamplerYcbcrConversion",
-        "VkDescriptorUpdateTemplate",
-        "VkSurfaceKHR",
-        "VkSwapchainKHR",
-        "VkDisplayKHR",
-        "VkDisplayModeKHR",
-        "VkDebugReportCallbackEXT",
-        "VkDebugUtilsMessengerEXT",
-        "VkValidationCacheEXT",
-    ] {
-        builder = builder.blacklist_type(t).blacklist_type(format!("{}_T", t));
+    for t in types
+        .children
+        .iter()
+        .filter(|v| v.attributes.get("category").map(|v| &**v) == Some("handle"))
+    {
+        let name = if let Some(name) = t.attributes.get("name") {
+            name
+        } else {
+            t.get_child("name").unwrap().text.as_ref().unwrap()
+        };
+        builder = builder
+            .blacklist_type(name)
+            .blacklist_type(format!("{}_T", name));
     }
     builder = builder
         .whitelist_type("PFN_.*")
@@ -121,5 +136,82 @@ fn main() -> io::Result<()> {
         PathBuf::from(env::var("OUT_DIR").unwrap()).join("vulkan-types.rs"),
         code,
     )?;
+    let mut extensions_enum = GeneratedCode::new();
+    let mut extensions_struct = GeneratedCode::new();
+    let mut extensions_default_init = GeneratedCode::new();
+    let mut extensions_get_dependencies = GeneratedCode::new();
+    for extension in parsed_xml.get_child("extensions").unwrap().children.iter() {
+        match &**extension.attributes.get("supported").unwrap() {
+            "vulkan" => {}
+            "disabled" => continue,
+            supported => panic!("unknown supported field: {:?}", supported),
+        }
+        let name = extension.attributes.get("name").unwrap();
+        let mut requires = extension
+            .attributes
+            .get("requires")
+            .map(Deref::deref)
+            .unwrap_or("")
+            .split(',')
+            .filter(|v| v != &"")
+            .peekable();
+        if requires.peek().is_some() {
+            writeln!(extensions_get_dependencies, "            {} => {{", name);
+            for require in requires {
+                writeln!(
+                    extensions_get_dependencies,
+                    "                retval.{} = true;",
+                    require
+                );
+            }
+            writeln!(extensions_get_dependencies, "            }}");
+        } else {
+            writeln!(extensions_get_dependencies, "            {} => {{}}", name);
+        }
+        writeln!(extensions_enum, "    {},", name)?;
+        writeln!(extensions_struct, "    {}: bool,", name)?;
+        writeln!(extensions_default_init, "            {}: false,", name)?;
+    }
+    let mut code = io::Cursor::new(Vec::new());
+    writeln!(
+        code,
+        r"/* automatically generated code */
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum Extension {{
+{extensions_enum:#}
+}}
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct Extensions {{
+{extensions_struct:#}
+}}
+
+impl Default for Extensions {{
+    fn default() -> Self {{
+        Self {{
+{extensions_default_init:#}
+        }}
+    }}
+}}
+
+impl Extension {{
+    pub fn get_dependencies(self) -> Extensions {{
+        let mut retval = Extensions::default();
+        match self {{
+{extensions_get_dependencies:#}
+        }}
+        retval
+    }}
+}}",
+        extensions_enum = extensions_enum,
+        extensions_struct = extensions_struct,
+        extensions_default_init = extensions_default_init,
+        extensions_get_dependencies = extensions_get_dependencies
+    )?;
+    fs::write(
+        PathBuf::from(env::var("OUT_DIR").unwrap()).join("vulkan-properties.rs"),
+        code.into_inner(),
+    )?;
     Ok(())
 }
index 400c05ce06c74659d7c45615ed83bb838ac1266e..c7504f983a98c3ceab0b6f72723dd61d17c3aba8 100644 (file)
@@ -32,11 +32,276 @@ impl ProcAddressScope {
     }
 }
 
-struct Extensions {}
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+#[repr(i32)]
+pub enum Extension {
+    VK_VERSION_1_0 = -1,
+    VK_VERSION_1_1 = -2,
+}
+
+struct Extensions {
+    VK_VERSION_1_0: bool,
+    VK_VERSION_1_1: bool,
+    VK_AMD_buffer_marker: bool,
+    VK_AMD_draw_indirect_count: bool,
+    VK_AMD_gcn_shader: bool,
+    VK_AMD_gpu_shader_half_float: bool,
+    VK_AMD_gpu_shader_int16: bool,
+    VK_AMD_mixed_attachment_samples: bool,
+    VK_AMD_negative_viewport_height: bool,
+    VK_AMD_rasterization_order: bool,
+    VK_AMD_shader_ballot: bool,
+    VK_AMD_shader_core_properties: bool,
+    VK_AMD_shader_explicit_vertex_parameter: bool,
+    VK_AMD_shader_fragment_mask: bool,
+    VK_AMD_shader_image_load_store_lod: bool,
+    VK_AMD_shader_info: bool,
+    VK_AMD_shader_trinary_minmax: bool,
+    VK_AMD_texture_gather_bias_lod: bool,
+    VK_ANDROID_external_memory_android_hardware_buffer: bool,
+    VK_EXT_acquire_xlib_display: bool,
+    VK_EXT_astc_decode_mode: bool,
+    VK_EXT_blend_operation_advanced: bool,
+    VK_EXT_conditional_rendering: bool,
+    VK_EXT_conservative_rasterization: bool,
+    VK_EXT_debug_marker: bool,
+    VK_EXT_debug_report: bool,
+    VK_EXT_debug_utils: bool,
+    VK_EXT_depth_range_unrestricted: bool,
+    VK_EXT_descriptor_indexing: bool,
+    VK_EXT_direct_mode_display: bool,
+    VK_EXT_discard_rectangles: bool,
+    VK_EXT_display_control: bool,
+    VK_EXT_display_surface_counter: bool,
+    VK_EXT_external_memory_dma_buf: bool,
+    VK_EXT_external_memory_host: bool,
+    VK_EXT_global_priority: bool,
+    VK_EXT_hdr_metadata: bool,
+    VK_EXT_inline_uniform_block: bool,
+    VK_EXT_post_depth_coverage: bool,
+    VK_EXT_queue_family_foreign: bool,
+    VK_EXT_sample_locations: bool,
+    VK_EXT_sampler_filter_minmax: bool,
+    VK_EXT_shader_stencil_export: bool,
+    VK_EXT_shader_subgroup_ballot: bool,
+    VK_EXT_shader_subgroup_vote: bool,
+    VK_EXT_shader_viewport_index_layer: bool,
+    VK_EXT_swapchain_colorspace: bool,
+    VK_EXT_validation_cache: bool,
+    VK_EXT_validation_flags: bool,
+    VK_EXT_vertex_attribute_divisor: bool,
+    VK_GOOGLE_display_timing: bool,
+    VK_IMG_filter_cubic: bool,
+    VK_IMG_format_pvrtc: bool,
+    VK_KHR_16bit_storage: bool,
+    VK_KHR_8bit_storage: bool,
+    VK_KHR_android_surface: bool,
+    VK_KHR_bind_memory2: bool,
+    VK_KHR_create_renderpass2: bool,
+    VK_KHR_dedicated_allocation: bool,
+    VK_KHR_descriptor_update_template: bool,
+    VK_KHR_device_group: bool,
+    VK_KHR_device_group_creation: bool,
+    VK_KHR_display: bool,
+    VK_KHR_display_swapchain: bool,
+    VK_KHR_draw_indirect_count: bool,
+    VK_KHR_external_fence: bool,
+    VK_KHR_external_fence_capabilities: bool,
+    VK_KHR_external_fence_fd: bool,
+    VK_KHR_external_fence_win32: bool,
+    VK_KHR_external_memory: bool,
+    VK_KHR_external_memory_capabilities: bool,
+    VK_KHR_external_memory_fd: bool,
+    VK_KHR_external_memory_win32: bool,
+    VK_KHR_external_semaphore: bool,
+    VK_KHR_external_semaphore_capabilities: bool,
+    VK_KHR_external_semaphore_fd: bool,
+    VK_KHR_external_semaphore_win32: bool,
+    VK_KHR_get_display_properties2: bool,
+    VK_KHR_get_memory_requirements2: bool,
+    VK_KHR_get_physical_device_properties2: bool,
+    VK_KHR_get_surface_capabilities2: bool,
+    VK_KHR_image_format_list: bool,
+    VK_KHR_incremental_present: bool,
+    VK_KHR_maintenance1: bool,
+    VK_KHR_maintenance2: bool,
+    VK_KHR_maintenance3: bool,
+    VK_KHR_mir_surface: bool,
+    VK_KHR_multiview: bool,
+    VK_KHR_push_descriptor: bool,
+    VK_KHR_relaxed_block_layout: bool,
+    VK_KHR_sampler_mirror_clamp_to_edge: bool,
+    VK_KHR_sampler_ycbcr_conversion: bool,
+    VK_KHR_shader_draw_parameters: bool,
+    VK_KHR_shared_presentable_image: bool,
+    VK_KHR_storage_buffer_storage_class: bool,
+    VK_KHR_surface: bool,
+    VK_KHR_swapchain: bool,
+    VK_KHR_variable_pointers: bool,
+    VK_KHR_vulkan_memory_model: bool,
+    VK_KHR_wayland_surface: bool,
+    VK_KHR_win32_keyed_mutex: bool,
+    VK_KHR_win32_surface: bool,
+    VK_KHR_xcb_surface: bool,
+    VK_KHR_xlib_surface: bool,
+    VK_NV_clip_space_w_scaling: bool,
+    VK_NV_compute_shader_derivatives: bool,
+    VK_NV_corner_sampled_image: bool,
+    VK_NV_dedicated_allocation: bool,
+    VK_NV_device_diagnostic_checkpoints: bool,
+    VK_NV_external_memory: bool,
+    VK_NV_external_memory_capabilities: bool,
+    VK_NV_external_memory_win32: bool,
+    VK_NV_fill_rectangle: bool,
+    VK_NV_fragment_coverage_to_color: bool,
+    VK_NV_fragment_shader_barycentric: bool,
+    VK_NV_framebuffer_mixed_samples: bool,
+    VK_NV_geometry_shader_passthrough: bool,
+    VK_NV_glsl_shader: bool,
+    VK_NV_mesh_shader: bool,
+    VK_NV_representative_fragment_test: bool,
+    VK_NV_sample_mask_override_coverage: bool,
+    VK_NV_scissor_exclusive: bool,
+    VK_NV_shader_image_footprint: bool,
+    VK_NV_shader_subgroup_partitioned: bool,
+    VK_NV_shading_rate_image: bool,
+    VK_NV_viewport_array2: bool,
+    VK_NV_viewport_swizzle: bool,
+    VK_NV_win32_keyed_mutex: bool,
+}
 
 impl Default for Extensions {
     fn default() -> Self {
-        Self {}
+        Self {
+            VK_VERSION_1_0: true,
+            VK_VERSION_1_1: false,
+            VK_AMD_buffer_marker: false,
+            VK_AMD_draw_indirect_count: false,
+            VK_AMD_gcn_shader: false,
+            VK_AMD_gpu_shader_half_float: false,
+            VK_AMD_gpu_shader_int16: false,
+            VK_AMD_mixed_attachment_samples: false,
+            VK_AMD_negative_viewport_height: false,
+            VK_AMD_rasterization_order: false,
+            VK_AMD_shader_ballot: false,
+            VK_AMD_shader_core_properties: false,
+            VK_AMD_shader_explicit_vertex_parameter: false,
+            VK_AMD_shader_fragment_mask: false,
+            VK_AMD_shader_image_load_store_lod: false,
+            VK_AMD_shader_info: false,
+            VK_AMD_shader_trinary_minmax: false,
+            VK_AMD_texture_gather_bias_lod: false,
+            VK_ANDROID_external_memory_android_hardware_buffer: false,
+            VK_EXT_acquire_xlib_display: false,
+            VK_EXT_astc_decode_mode: false,
+            VK_EXT_blend_operation_advanced: false,
+            VK_EXT_conditional_rendering: false,
+            VK_EXT_conservative_rasterization: false,
+            VK_EXT_debug_marker: false,
+            VK_EXT_debug_report: false,
+            VK_EXT_debug_utils: false,
+            VK_EXT_depth_range_unrestricted: false,
+            VK_EXT_descriptor_indexing: false,
+            VK_EXT_direct_mode_display: false,
+            VK_EXT_discard_rectangles: false,
+            VK_EXT_display_control: false,
+            VK_EXT_display_surface_counter: false,
+            VK_EXT_external_memory_dma_buf: false,
+            VK_EXT_external_memory_host: false,
+            VK_EXT_global_priority: false,
+            VK_EXT_hdr_metadata: false,
+            VK_EXT_inline_uniform_block: false,
+            VK_EXT_post_depth_coverage: false,
+            VK_EXT_queue_family_foreign: false,
+            VK_EXT_sample_locations: false,
+            VK_EXT_sampler_filter_minmax: false,
+            VK_EXT_shader_stencil_export: false,
+            VK_EXT_shader_subgroup_ballot: false,
+            VK_EXT_shader_subgroup_vote: false,
+            VK_EXT_shader_viewport_index_layer: false,
+            VK_EXT_swapchain_colorspace: false,
+            VK_EXT_validation_cache: false,
+            VK_EXT_validation_flags: false,
+            VK_EXT_vertex_attribute_divisor: false,
+            VK_GOOGLE_display_timing: false,
+            VK_IMG_filter_cubic: false,
+            VK_IMG_format_pvrtc: false,
+            VK_KHR_16bit_storage: false,
+            VK_KHR_8bit_storage: false,
+            VK_KHR_android_surface: false,
+            VK_KHR_bind_memory2: false,
+            VK_KHR_create_renderpass2: false,
+            VK_KHR_dedicated_allocation: false,
+            VK_KHR_descriptor_update_template: false,
+            VK_KHR_device_group: false,
+            VK_KHR_device_group_creation: false,
+            VK_KHR_display: false,
+            VK_KHR_display_swapchain: false,
+            VK_KHR_draw_indirect_count: false,
+            VK_KHR_external_fence: false,
+            VK_KHR_external_fence_capabilities: false,
+            VK_KHR_external_fence_fd: false,
+            VK_KHR_external_fence_win32: false,
+            VK_KHR_external_memory: false,
+            VK_KHR_external_memory_capabilities: false,
+            VK_KHR_external_memory_fd: false,
+            VK_KHR_external_memory_win32: false,
+            VK_KHR_external_semaphore: false,
+            VK_KHR_external_semaphore_capabilities: false,
+            VK_KHR_external_semaphore_fd: false,
+            VK_KHR_external_semaphore_win32: false,
+            VK_KHR_get_display_properties2: false,
+            VK_KHR_get_memory_requirements2: false,
+            VK_KHR_get_physical_device_properties2: false,
+            VK_KHR_get_surface_capabilities2: false,
+            VK_KHR_image_format_list: false,
+            VK_KHR_incremental_present: false,
+            VK_KHR_maintenance1: false,
+            VK_KHR_maintenance2: false,
+            VK_KHR_maintenance3: false,
+            VK_KHR_mir_surface: false,
+            VK_KHR_multiview: false,
+            VK_KHR_push_descriptor: false,
+            VK_KHR_relaxed_block_layout: false,
+            VK_KHR_sampler_mirror_clamp_to_edge: false,
+            VK_KHR_sampler_ycbcr_conversion: false,
+            VK_KHR_shader_draw_parameters: false,
+            VK_KHR_shared_presentable_image: false,
+            VK_KHR_storage_buffer_storage_class: false,
+            VK_KHR_surface: false,
+            VK_KHR_swapchain: false,
+            VK_KHR_variable_pointers: false,
+            VK_KHR_vulkan_memory_model: false,
+            VK_KHR_wayland_surface: false,
+            VK_KHR_win32_keyed_mutex: false,
+            VK_KHR_win32_surface: false,
+            VK_KHR_xcb_surface: false,
+            VK_KHR_xlib_surface: false,
+            VK_NV_clip_space_w_scaling: false,
+            VK_NV_compute_shader_derivatives: false,
+            VK_NV_corner_sampled_image: false,
+            VK_NV_dedicated_allocation: false,
+            VK_NV_device_diagnostic_checkpoints: false,
+            VK_NV_external_memory: false,
+            VK_NV_external_memory_capabilities: false,
+            VK_NV_external_memory_win32: false,
+            VK_NV_fill_rectangle: false,
+            VK_NV_fragment_coverage_to_color: false,
+            VK_NV_fragment_shader_barycentric: false,
+            VK_NV_framebuffer_mixed_samples: false,
+            VK_NV_geometry_shader_passthrough: false,
+            VK_NV_glsl_shader: false,
+            VK_NV_mesh_shader: false,
+            VK_NV_representative_fragment_test: false,
+            VK_NV_sample_mask_override_coverage: false,
+            VK_NV_scissor_exclusive: false,
+            VK_NV_shader_image_footprint: false,
+            VK_NV_shader_subgroup_partitioned: false,
+            VK_NV_shading_rate_image: false,
+            VK_NV_viewport_array2: false,
+            VK_NV_viewport_swizzle: false,
+            VK_NV_win32_keyed_mutex: false,
+        }
     }
 }
 
@@ -353,7 +618,6 @@ fn get_proc_address(
         proc_address!(vkUpdateDescriptorSetWithTemplate, PFN_vkUpdateDescriptorSetWithTemplate, unknown, unknown);
         proc_address!(vkUpdateDescriptorSetWithTemplateKHR, PFN_vkUpdateDescriptorSetWithTemplateKHR, unknown, unknown);
         proc_address!(vkUpdateDescriptorSets, PFN_vkUpdateDescriptorSets, unknown, unknown);
-        proc_address!(vkVoidFunction, PFN_vkVoidFunction, unknown, unknown);
         proc_address!(vkWaitForFences, PFN_vkWaitForFences, unknown, unknown);
     }
     None