diff options
Diffstat (limited to 'src/graphics_permanent.rs')
| -rw-r--r-- | src/graphics_permanent.rs | 77 |
1 files changed, 71 insertions, 6 deletions
diff --git a/src/graphics_permanent.rs b/src/graphics_permanent.rs index b58e8a4..63e8994 100644 --- a/src/graphics_permanent.rs +++ b/src/graphics_permanent.rs @@ -62,6 +62,8 @@ pub struct PermanentGraphicsState { // follow Vulkan's lead and let it have a short variable name. pub device: Device, + pub sampler: vk::Sampler, + // Vulkan has a first-class concept of command queues. We have two of // them, one for graphics drawing commands and one for presentation. // @@ -88,6 +90,7 @@ pub struct QueueFamilyIndices { // for accidentally passing or returning one boolean as if it's another. struct EnablePortability(bool); struct EnableValidation(bool); +struct EnableAnisotropy(bool); pub struct EnableSwapchain(pub bool); @@ -123,14 +126,16 @@ impl PermanentGraphicsState { let (physical_device, device, indices, graphics_queue, presentation_queue, - enable_swapchain) + enable_anisotropy, enable_swapchain) = init_vulkan_device(&instance, &surface, enable_validation, enable_portability)?; + let sampler = init_sampler(&device, &enable_anisotropy)?; + let descriptor_set_layout = init_descriptor_set_layout(&device)?; Ok((PermanentGraphicsState { - window, entry, instance, debug_messager, surface, device, + window, entry, instance, debug_messager, surface, device, sampler, graphics_queue, presentation_queue }, GraphicsStateForReinit { physical_device, indices, descriptor_set_layout @@ -139,6 +144,8 @@ impl PermanentGraphicsState { #[allow(unsafe_code)] pub fn destroy(self) -> () { + unsafe { self.device.destroy_sampler(self.sampler, None) }; + unsafe { self.device.destroy_device(None) }; unsafe { self.instance.destroy_surface_khr(self.surface, None) }; @@ -415,7 +422,7 @@ fn init_vulkan_device(instance: &Instance, surface: &vk::SurfaceKHR, enable_validation: EnableValidation, enable_portability: EnablePortability) -> Result<(vk::PhysicalDevice, Device, QueueFamilyIndices, vk::Queue, - vk::Queue, EnableSwapchain)> + vk::Queue, EnableAnisotropy, EnableSwapchain)> { let (physical_device, indices) = pick_vulkan_device(instance, surface)?; @@ -433,7 +440,10 @@ fn init_vulkan_device(instance: &Instance, surface: &vk::SurfaceKHR, // Old versions of Vulkan want layers to be enabled at the device // level as well. Newer ones will ignore this and just use the instance // layers. - let features = vk::PhysicalDeviceFeatures::builder(); + let available_features = unsafe { + instance.get_physical_device_features(physical_device) + }; + let mut features = vk::PhysicalDeviceFeatures::builder(); let mut extensions = Vec::new(); let mut layers = Vec::new(); @@ -482,6 +492,16 @@ fn init_vulkan_device(instance: &Instance, surface: &vk::SurfaceKHR, EnableSwapchain(false) }; + let enable_anisotropy = if available_features.sampler_anisotropy + == vk::TRUE + { + features = features.sampler_anisotropy(true); + + EnableAnisotropy(true) + } else { + EnableAnisotropy(false) + }; + // We have one or more queue family indices; we don't know a priori // how many, because it's possible some of them are the same. We only // want to create one queue per distinct family, so we find the unique @@ -526,7 +546,39 @@ fn init_vulkan_device(instance: &Instance, surface: &vk::SurfaceKHR, Ok((physical_device, device, indices, graphics_queue, presentation_queue, - enable_swapchain)) + enable_anisotropy, enable_swapchain)) +} + + +#[allow(unsafe_code)] +fn init_sampler(device: &Device, enable_anisotropy: &EnableAnisotropy) + -> Result<vk::Sampler> +{ + let mut sampler_info = vk::SamplerCreateInfo::builder() + .mag_filter(vk::Filter::LINEAR) + .min_filter(vk::Filter::LINEAR) + .address_mode_u(vk::SamplerAddressMode::REPEAT) + .address_mode_v(vk::SamplerAddressMode::REPEAT) + .address_mode_w(vk::SamplerAddressMode::REPEAT) + .border_color(vk::BorderColor::INT_OPAQUE_BLACK) + .unnormalized_coordinates(false) + .compare_enable(false) + .compare_op(vk::CompareOp::ALWAYS) + .mipmap_mode(vk::SamplerMipmapMode::LINEAR) + .mip_lod_bias(0.0) + .min_lod(0.0) + .max_lod(0.0); + sampler_info = if enable_anisotropy.0 { + sampler_info.anisotropy_enable(true) + .max_anisotropy(16.0) + } else { + sampler_info.anisotropy_enable(false) + .max_anisotropy(1.0) + }; + + let sampler = unsafe { device.create_sampler(&sampler_info, None) }?; + + Ok(sampler) } @@ -540,7 +592,13 @@ fn init_descriptor_set_layout(device: &Device) .descriptor_count(1) .stage_flags(vk::ShaderStageFlags::VERTEX); - let bindings = [uniform_block_binding]; + let sampler_binding = vk::DescriptorSetLayoutBinding::builder() + .binding(1) + .descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER) + .descriptor_count(1) + .stage_flags(vk::ShaderStageFlags::FRAGMENT); + + let bindings = [uniform_block_binding, sampler_binding]; let descriptor_set_layout_info = vk::DescriptorSetLayoutCreateInfo::builder() .bindings(&bindings); @@ -698,6 +756,13 @@ fn score_vulkan_device(instance: &Instance, surface: &vk::SurfaceKHR, // selected. } + let features = unsafe { + instance.get_physical_device_features(*physical_device) + }; + if features.sampler_anisotropy == vk::TRUE { + score += 1; + } + Ok(Acceptable::Accepted((score, indices))) } |