From 9c69b4157473a340e15846fd3fe3948a403b4bb3 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 27 Sep 2018 01:56:45 -0700 Subject: [PATCH] working on generating rust code from vk.xml --- Cargo.toml | 4 +- vulkan-driver/Cargo.toml | 1 + vulkan-driver/build.rs | 184 +++++++++++++++++------ vulkan-driver/src/api_impl.rs | 270 +++++++++++++++++++++++++++++++++- 4 files changed, 409 insertions(+), 50 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6b0d8e8..54e9f3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,4 @@ [workspace] -members = ["vulkan-driver"] +members = [ + "vulkan-driver", +] diff --git a/vulkan-driver/Cargo.toml b/vulkan-driver/Cargo.toml index 7a85b74..cad14ee 100644 --- a/vulkan-driver/Cargo.toml +++ b/vulkan-driver/Cargo.toml @@ -12,3 +12,4 @@ xcb = "0.8" [build-dependencies] bindgen = "0.40" regex = "1" +xmltree = "0.8" diff --git a/vulkan-driver/build.rs b/vulkan-driver/build.rs index 00e3f95..7dc1379 100644 --- a/vulkan-driver/build.rs +++ b/vulkan-driver/build.rs @@ -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 { 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 { + 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(()) } diff --git a/vulkan-driver/src/api_impl.rs b/vulkan-driver/src/api_impl.rs index 400c05c..c7504f9 100644 --- a/vulkan-driver/src/api_impl.rs +++ b/vulkan-driver/src/api_impl.rs @@ -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 -- 2.30.2