From fdafdf99128044322127dc113931374c6b0263fe Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 3 Mar 2025 19:39:47 +0100 Subject: [PATCH 1/2] vulkan: separate images and samplers --- src/gfx_apis/vulkan/blend_buffer.rs | 27 ++--------- src/gfx_apis/vulkan/buffer_cache.rs | 9 ++-- src/gfx_apis/vulkan/descriptor.rs | 71 ++++++++++++++++++++++------ src/gfx_apis/vulkan/device.rs | 9 ++-- src/gfx_apis/vulkan/image.rs | 37 ++++++++++----- src/gfx_apis/vulkan/pipeline.rs | 11 ++--- src/gfx_apis/vulkan/renderer.rs | 48 ++++++++++++------- src/gfx_apis/vulkan/shaders/tex.frag | 5 +- src/gfx_apis/vulkan/shm_image.rs | 3 +- 9 files changed, 137 insertions(+), 83 deletions(-) diff --git a/src/gfx_apis/vulkan/blend_buffer.rs b/src/gfx_apis/vulkan/blend_buffer.rs index 298c6527..cc1213e8 100644 --- a/src/gfx_apis/vulkan/blend_buffer.rs +++ b/src/gfx_apis/vulkan/blend_buffer.rs @@ -10,9 +10,8 @@ use { utils::on_drop::OnDrop, }, ash::vk::{ - DescriptorDataEXT, DescriptorGetInfoEXT, DescriptorImageInfo, DescriptorType, Extent3D, - ImageAspectFlags, ImageCreateInfo, ImageLayout, ImageSubresourceRange, ImageTiling, - ImageType, ImageViewCreateInfo, ImageViewType, SampleCountFlags, SharingMode, + Extent3D, ImageAspectFlags, ImageCreateInfo, ImageLayout, ImageSubresourceRange, + ImageTiling, ImageType, ImageViewCreateInfo, ImageViewType, SampleCountFlags, SharingMode, }, gpu_alloc::UsageFlags, std::{any::Any, cell::Cell, collections::hash_map::Entry, rc::Rc}, @@ -24,9 +23,9 @@ impl VulkanRenderer { width: i32, height: i32, ) -> Result, VulkanError> { - let Some(db) = &self.device.descriptor_buffer else { + if self.device.descriptor_buffer.is_none() { return Err(VulkanError::NoDescriptorBuffer); - }; + } if width <= 0 || height <= 0 { return Err(VulkanError::NonPositiveImageSize); } @@ -90,21 +89,6 @@ impl VulkanRenderer { }; let view = view.map_err(VulkanError::CreateImageView)?; destroy_image.forget(); - let sampled_image_descriptor = { - let mut buf = vec![0; self.device.sampled_image_descriptor_size].into_boxed_slice(); - let image_info = DescriptorImageInfo::default() - .image_view(view) - .image_layout(ImageLayout::SHADER_READ_ONLY_OPTIMAL); - let info = DescriptorGetInfoEXT::default() - .ty(DescriptorType::SAMPLED_IMAGE) - .data(DescriptorDataEXT { - p_sampled_image: &image_info, - }); - unsafe { - db.get_descriptor(&info, &mut buf); - } - buf - }; let img = Rc::new(VulkanImage { renderer: self.clone(), format: BLEND_FORMAT, @@ -121,8 +105,7 @@ impl VulkanRenderer { }), ty: VulkanImageMemory::Blend(allocation), bridge: None, - shader_read_only_optimal_descriptor: Box::new([]), - sampled_image_descriptor, + sampled_image_descriptor: self.sampled_image_descriptor(view), descriptor_buffer_version: Default::default(), descriptor_buffer_offset: Default::default(), execution_version: Default::default(), diff --git a/src/gfx_apis/vulkan/buffer_cache.rs b/src/gfx_apis/vulkan/buffer_cache.rs index a95d426a..5f8439cf 100644 --- a/src/gfx_apis/vulkan/buffer_cache.rs +++ b/src/gfx_apis/vulkan/buffer_cache.rs @@ -52,12 +52,13 @@ impl VulkanBufferCache { pub fn for_descriptor_buffer( device: &Rc, allocator: &Rc, - has_sampler: bool, + for_sampler: bool, ) -> Rc { - let mut usage = BufferUsageFlags::RESOURCE_DESCRIPTOR_BUFFER_EXT - | BufferUsageFlags::SHADER_DEVICE_ADDRESS; - if has_sampler { + let mut usage = BufferUsageFlags::SHADER_DEVICE_ADDRESS; + if for_sampler { usage |= BufferUsageFlags::SAMPLER_DESCRIPTOR_BUFFER_EXT; + } else { + usage |= BufferUsageFlags::RESOURCE_DESCRIPTOR_BUFFER_EXT; } Self::new(device, allocator, usage) } diff --git a/src/gfx_apis/vulkan/descriptor.rs b/src/gfx_apis/vulkan/descriptor.rs index 8ccb725a..9f78e8d3 100644 --- a/src/gfx_apis/vulkan/descriptor.rs +++ b/src/gfx_apis/vulkan/descriptor.rs @@ -30,7 +30,7 @@ impl Drop for VulkanDescriptorSetLayout { } impl VulkanDevice { - pub(super) fn create_tex_descriptor_set_layout( + pub(super) fn create_tex_legacy_descriptor_set_layout( self: &Rc, sampler: &Rc, ) -> Result, VulkanError> { @@ -40,24 +40,40 @@ impl VulkanDevice { .immutable_samplers(&immutable_sampler) .descriptor_count(1) .descriptor_type(DescriptorType::COMBINED_IMAGE_SAMPLER); - let mut flags = DescriptorSetLayoutCreateFlags::empty(); - if self.descriptor_buffer.is_some() { - flags |= DescriptorSetLayoutCreateFlags::DESCRIPTOR_BUFFER_EXT; - } else { - flags |= DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR_KHR; - } let create_info = DescriptorSetLayoutCreateInfo::default() .bindings(slice::from_ref(&binding)) - .flags(flags); + .flags(DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR_KHR); let layout = unsafe { self.device.create_descriptor_set_layout(&create_info, None) }; let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?; - let mut size = 0; + Ok(Rc::new(VulkanDescriptorSetLayout { + device: self.clone(), + layout, + size: 0, + offsets: Default::default(), + _sampler: Some(sampler.clone()), + })) + } + + pub(super) fn create_tex_sampler_descriptor_set_layout( + self: &Rc, + sampler: &Rc, + ) -> Result, VulkanError> { + let immutable_sampler = [sampler.sampler]; + let binding = DescriptorSetLayoutBinding::default() + .stage_flags(ShaderStageFlags::FRAGMENT) + .immutable_samplers(&immutable_sampler) + .descriptor_count(1) + .descriptor_type(DescriptorType::SAMPLER); + let create_info = DescriptorSetLayoutCreateInfo::default() + .bindings(slice::from_ref(&binding)) + .flags(DescriptorSetLayoutCreateFlags::DESCRIPTOR_BUFFER_EXT); + let layout = unsafe { self.device.create_descriptor_set_layout(&create_info, None) }; + let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?; + let db = self.descriptor_buffer.as_ref().unwrap(); + let size = self.get_descriptor_set_size(db, layout); let mut offsets = ArrayVec::new(); - if let Some(db) = &self.descriptor_buffer { - size = self.get_descriptor_set_size(db, layout); - unsafe { - offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 0)); - } + unsafe { + offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 0)); } Ok(Rc::new(VulkanDescriptorSetLayout { device: self.clone(), @@ -68,6 +84,33 @@ impl VulkanDevice { })) } + pub(super) fn create_tex_resource_descriptor_set_layout( + self: &Rc, + ) -> Result, VulkanError> { + let binding = DescriptorSetLayoutBinding::default() + .stage_flags(ShaderStageFlags::FRAGMENT) + .descriptor_count(1) + .descriptor_type(DescriptorType::SAMPLED_IMAGE); + let create_info = DescriptorSetLayoutCreateInfo::default() + .bindings(slice::from_ref(&binding)) + .flags(DescriptorSetLayoutCreateFlags::DESCRIPTOR_BUFFER_EXT); + let layout = unsafe { self.device.create_descriptor_set_layout(&create_info, None) }; + let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?; + let db = self.descriptor_buffer.as_ref().unwrap(); + let size = self.get_descriptor_set_size(db, layout); + let mut offsets = ArrayVec::new(); + unsafe { + offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 0)); + } + Ok(Rc::new(VulkanDescriptorSetLayout { + device: self.clone(), + layout, + size, + offsets, + _sampler: None, + })) + } + pub(super) fn create_out_descriptor_set_layout( self: &Rc, db: &descriptor_buffer::Device, diff --git a/src/gfx_apis/vulkan/device.rs b/src/gfx_apis/vulkan/device.rs index 248995f9..fe1711e3 100644 --- a/src/gfx_apis/vulkan/device.rs +++ b/src/gfx_apis/vulkan/device.rs @@ -71,7 +71,7 @@ pub struct VulkanDevice { pub(super) distinct_transfer_queue_family_idx: Option, pub(super) transfer_granularity_mask: (u32, u32), pub(super) descriptor_buffer_offset_mask: DeviceSize, - pub(super) combined_image_sampler_descriptor_size: usize, + pub(super) sampler_descriptor_size: usize, pub(super) sampled_image_descriptor_size: usize, } @@ -366,7 +366,7 @@ impl VulkanInstance { let descriptor_buffer = supports_descriptor_buffer .then(|| descriptor_buffer::Device::new(&self.instance, &device)); let mut descriptor_buffer_offset_mask = 0; - let mut combined_image_sampler_descriptor_size = 0; + let mut sampler_descriptor_size = 0; let mut sampled_image_descriptor_size = 0; if supports_descriptor_buffer { let mut descriptor_buffer_props = @@ -382,8 +382,7 @@ impl VulkanInstance { .checked_next_power_of_two() .unwrap() - 1; - combined_image_sampler_descriptor_size = - descriptor_buffer_props.combined_image_sampler_descriptor_size; + sampler_descriptor_size = descriptor_buffer_props.sampler_descriptor_size; sampled_image_descriptor_size = descriptor_buffer_props.sampled_image_descriptor_size; } let memory_properties = @@ -422,7 +421,7 @@ impl VulkanInstance { distinct_transfer_queue_family_idx, transfer_granularity_mask, descriptor_buffer_offset_mask, - combined_image_sampler_descriptor_size, + sampler_descriptor_size, sampled_image_descriptor_size, blend_limits, })) diff --git a/src/gfx_apis/vulkan/image.rs b/src/gfx_apis/vulkan/image.rs index ec82f78a..8b269883 100644 --- a/src/gfx_apis/vulkan/image.rs +++ b/src/gfx_apis/vulkan/image.rs @@ -26,7 +26,8 @@ use { ImagePlaneMemoryRequirementsInfo, ImageSubresourceRange, ImageTiling, ImageType, ImageUsageFlags, ImageView, ImageViewCreateInfo, ImageViewType, ImportMemoryFdInfoKHR, MemoryAllocateInfo, MemoryDedicatedAllocateInfo, MemoryFdPropertiesKHR, - MemoryPropertyFlags, MemoryRequirements2, SampleCountFlags, SharingMode, SubresourceLayout, + MemoryPropertyFlags, MemoryRequirements2, SampleCountFlags, Sampler, SharingMode, + SubresourceLayout, }, gpu_alloc::UsageFlags, std::{ @@ -63,7 +64,6 @@ pub struct VulkanImage { pub(super) queue_state: Cell, pub(super) ty: VulkanImageMemory, pub(super) bridge: Option, - pub(super) shader_read_only_optimal_descriptor: Box<[u8]>, pub(super) sampled_image_descriptor: Box<[u8]>, pub(super) descriptor_buffer_version: Cell, pub(super) descriptor_buffer_offset: Cell, @@ -235,21 +235,37 @@ impl VulkanDevice { } } +impl VulkanDevice { + pub(super) fn create_sampler_descriptor(&self, sampler: Sampler) -> Box<[u8]> { + let Some(db) = &self.descriptor_buffer else { + return Box::new([]); + }; + let mut buf = vec![0; self.sampler_descriptor_size].into_boxed_slice(); + let info = DescriptorGetInfoEXT::default() + .ty(DescriptorType::SAMPLER) + .data(DescriptorDataEXT { + p_sampler: &sampler, + }); + unsafe { + db.get_descriptor(&info, &mut buf); + } + buf + } +} + impl VulkanRenderer { - pub(super) fn sampler_read_only_descriptor(&self, view: ImageView) -> Box<[u8]> { + pub(super) fn sampled_image_descriptor(&self, view: ImageView) -> Box<[u8]> { let Some(db) = &self.device.descriptor_buffer else { return Box::new([]); }; - let mut buf = - vec![0; self.device.combined_image_sampler_descriptor_size].into_boxed_slice(); + let mut buf = vec![0; self.device.sampled_image_descriptor_size].into_boxed_slice(); let image_info = DescriptorImageInfo::default() - .sampler(self.sampler.sampler) .image_view(view) .image_layout(ImageLayout::SHADER_READ_ONLY_OPTIMAL); let info = DescriptorGetInfoEXT::default() - .ty(DescriptorType::COMBINED_IMAGE_SAMPLER) + .ty(DescriptorType::SAMPLED_IMAGE) .data(DescriptorDataEXT { - p_combined_image_sampler: &image_info, + p_sampled_image: &image_info, }); unsafe { db.get_descriptor(&info, &mut buf); @@ -450,10 +466,7 @@ impl VulkanDmaBufImageTemplate { family: QueueFamily::Gfx, }), bridge, - shader_read_only_optimal_descriptor: self - .renderer - .sampler_read_only_descriptor(texture_view), - sampled_image_descriptor: Box::new([]), + sampled_image_descriptor: self.renderer.sampled_image_descriptor(texture_view), descriptor_buffer_version: Cell::new(0), descriptor_buffer_offset: Cell::new(0), execution_version: Cell::new(0), diff --git a/src/gfx_apis/vulkan/pipeline.rs b/src/gfx_apis/vulkan/pipeline.rs index b6701cf1..30804a47 100644 --- a/src/gfx_apis/vulkan/pipeline.rs +++ b/src/gfx_apis/vulkan/pipeline.rs @@ -29,7 +29,7 @@ pub(super) struct VulkanPipeline { pub(super) _frag: Rc, pub(super) pipeline_layout: PipelineLayout, pub(super) pipeline: Pipeline, - pub(super) _frag_descriptor_set_layout: Option>, + pub(super) _descriptor_set_layouts: ArrayVec, 2>, } pub(super) struct PipelineCreateInfo { @@ -41,7 +41,7 @@ pub(super) struct PipelineCreateInfo { pub(super) has_alpha_mult: bool, pub(super) eotf: u32, pub(super) oetf: u32, - pub(super) frag_descriptor_set_layout: Option>, + pub(super) descriptor_set_layouts: ArrayVec, 2>, } impl VulkanDevice { @@ -67,9 +67,8 @@ impl VulkanDevice { .size(push_size as u32), ); } - let mut descriptor_set_layouts = ArrayVec::<_, 1>::new(); - descriptor_set_layouts - .extend(info.frag_descriptor_set_layout.as_ref().map(|l| l.layout)); + let mut descriptor_set_layouts = ArrayVec::<_, 2>::new(); + descriptor_set_layouts.extend(info.descriptor_set_layouts.iter().map(|l| l.layout)); let create_info = PipelineLayoutCreateInfo::default() .push_constant_ranges(&push_constant_ranges) .set_layouts(&descriptor_set_layouts); @@ -175,7 +174,7 @@ impl VulkanDevice { _frag: info.frag, pipeline_layout, pipeline, - _frag_descriptor_set_layout: info.frag_descriptor_set_layout, + _descriptor_set_layouts: info.descriptor_set_layouts, })) } } diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index 4fda1a63..85b7aa2e 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -90,12 +90,13 @@ pub struct VulkanRenderer { pub(super) tex_frag_shader: Rc, pub(super) out_vert_shader: Rc, pub(super) out_frag_shader: Rc, - pub(super) tex_descriptor_set_layout: Rc, + pub(super) tex_descriptor_set_layouts: ArrayVec, 2>, pub(super) out_descriptor_set_layout: Option>, pub(super) defunct: Cell, pub(super) pending_cpu_jobs: CopyHashMap, pub(super) shm_allocator: Rc, - pub(super) sampler: Rc, + pub(super) _sampler: Rc, + pub(super) sampler_descriptor: Box<[u8]>, pub(super) sampler_descriptor_buffer_cache: Rc, pub(super) resource_descriptor_buffer_cache: Rc, pub(super) blend_buffers: RefCell>>, @@ -234,23 +235,28 @@ impl VulkanDevice { eng: &Rc, ring: &Rc, ) -> Result, VulkanError> { + let sampler = self.create_sampler()?; let fill_vert_shader; let fill_frag_shader; let tex_vert_shader; let tex_frag_shader; + let mut tex_descriptor_set_layouts = ArrayVec::new(); if self.descriptor_buffer.is_some() { tex_vert_shader = self.create_shader(TEX_VERT)?; tex_frag_shader = self.create_shader(TEX_FRAG)?; fill_vert_shader = self.create_shader(FILL_VERT)?; fill_frag_shader = self.create_shader(FILL_FRAG)?; + tex_descriptor_set_layouts + .push(self.create_tex_sampler_descriptor_set_layout(&sampler)?); + tex_descriptor_set_layouts.push(self.create_tex_resource_descriptor_set_layout()?); } else { tex_vert_shader = self.create_shader(LEGACY_TEX_VERT)?; tex_frag_shader = self.create_shader(LEGACY_TEX_FRAG)?; fill_vert_shader = self.create_shader(LEGACY_FILL_VERT)?; fill_frag_shader = self.create_shader(LEGACY_FILL_FRAG)?; + tex_descriptor_set_layouts + .push(self.create_tex_legacy_descriptor_set_layout(&sampler)?); } - let sampler = self.create_sampler()?; - let tex_descriptor_set_layout = self.create_tex_descriptor_set_layout(&sampler)?; let out_descriptor_set_layout = self .descriptor_buffer .as_ref() @@ -327,12 +333,13 @@ impl VulkanDevice { tex_frag_shader, out_vert_shader, out_frag_shader, - tex_descriptor_set_layout, + tex_descriptor_set_layouts, out_descriptor_set_layout, defunct: Cell::new(false), pending_cpu_jobs: Default::default(), shm_allocator, - sampler, + sampler_descriptor: self.create_sampler_descriptor(sampler.sampler), + _sampler: sampler, sampler_descriptor_buffer_cache, resource_descriptor_buffer_cache, blend_buffers: Default::default(), @@ -372,7 +379,7 @@ impl VulkanRenderer { has_alpha_mult: false, eotf, oetf, - frag_descriptor_set_layout: None, + descriptor_set_layouts: Default::default(), }; self.device.create_pipeline2(info, push_size) }; @@ -393,7 +400,7 @@ impl VulkanRenderer { has_alpha_mult, eotf, oetf, - frag_descriptor_set_layout: Some(self.tex_descriptor_set_layout.clone()), + descriptor_set_layouts: self.tex_descriptor_set_layouts.clone(), }; self.device.create_pipeline2(info, push_size) }; @@ -438,6 +445,13 @@ impl VulkanRenderer { let memory = &mut *self.memory.borrow_mut(); let sampler_writer = &mut memory.sampler_descriptor_buffer_writer; sampler_writer.clear(); + { + let mut writer = sampler_writer.add_set(&self.tex_descriptor_set_layouts[0]); + writer.write( + self.tex_descriptor_set_layouts[0].offsets[0], + &self.sampler_descriptor, + ); + } let resource_writer = &mut memory.resource_descriptor_buffer_writer; resource_writer.clear(); if let Some(bb) = bb { @@ -447,6 +461,7 @@ impl VulkanRenderer { let mut writer = resource_writer.add_set(layout); writer.write(layout.offsets[0], &bb.sampled_image_descriptor); } + let tex_descriptor_set_layout = &self.tex_descriptor_set_layouts[1]; for pass in RenderPass::variants() { for cmd in &memory.ops[pass] { let VulkanOp::Tex(c) = cmd else { @@ -456,12 +471,12 @@ impl VulkanRenderer { if tex.descriptor_buffer_version.replace(version) == version { continue; } - let offset = sampler_writer.next_offset(); + let offset = resource_writer.next_offset(); tex.descriptor_buffer_offset.set(offset); - let mut writer = sampler_writer.add_set(&self.tex_descriptor_set_layout); + let mut writer = resource_writer.add_set(tex_descriptor_set_layout); writer.write( - self.tex_descriptor_set_layout.offsets[0], - &tex.shader_read_only_optimal_descriptor, + tex_descriptor_set_layout.offsets[0], + &tex.sampled_image_descriptor, ); } } @@ -1018,8 +1033,8 @@ impl VulkanRenderer { PipelineBindPoint::GRAPHICS, pipeline.pipeline_layout, 0, - &[0], - &[tex.descriptor_buffer_offset.get()], + &[0, 1], + &[0, tex.descriptor_buffer_offset.get()], ); dev.cmd_push_constants( buf, @@ -1102,7 +1117,8 @@ impl VulkanRenderer { let pipeline = match self.out_pipelines.borrow_mut().entry(fb.format.vk_format) { Entry::Occupied(pipeline) => pipeline.get().clone(), Entry::Vacant(e) => { - let layout = self.out_descriptor_set_layout.as_ref().unwrap(); + let mut descriptor_set_layouts = ArrayVec::new(); + descriptor_set_layouts.push(self.out_descriptor_set_layout.clone().unwrap()); let out = self .device .create_pipeline::(PipelineCreateInfo { @@ -1114,7 +1130,7 @@ impl VulkanRenderer { has_alpha_mult: false, eotf: TF_LINEAR, oetf: TF_SRGB, - frag_descriptor_set_layout: Some(layout.clone()), + descriptor_set_layouts, })?; e.insert(out.clone()); out diff --git a/src/gfx_apis/vulkan/shaders/tex.frag b/src/gfx_apis/vulkan/shaders/tex.frag index 53f74e8c..f9b18731 100644 --- a/src/gfx_apis/vulkan/shaders/tex.frag +++ b/src/gfx_apis/vulkan/shaders/tex.frag @@ -4,12 +4,13 @@ #include "transfer_functions.glsl" #include "tex.common.glsl" -layout(set = 0, binding = 0) uniform sampler2D tex; +layout(set = 0, binding = 0) uniform sampler sam; +layout(set = 1, binding = 0) uniform texture2D tex; layout(location = 0) in vec2 tex_pos; layout(location = 0) out vec4 out_color; void main() { - vec4 c = textureLod(tex, tex_pos, 0); + vec4 c = textureLod(sampler2D(tex, sam), tex_pos, 0); if (eotf != oetf) { if (src_has_alpha) { c.rgb /= mix(c.a, 1.0, c.a == 0.0); diff --git a/src/gfx_apis/vulkan/shm_image.rs b/src/gfx_apis/vulkan/shm_image.rs index 987c9dcb..240d1e11 100644 --- a/src/gfx_apis/vulkan/shm_image.rs +++ b/src/gfx_apis/vulkan/shm_image.rs @@ -459,8 +459,7 @@ impl VulkanRenderer { }), ty: VulkanImageMemory::Internal(shm), bridge: None, - shader_read_only_optimal_descriptor: self.sampler_read_only_descriptor(view), - sampled_image_descriptor: Box::new([]), + sampled_image_descriptor: self.sampled_image_descriptor(view), descriptor_buffer_version: Cell::new(0), descriptor_buffer_offset: Cell::new(0), execution_version: Cell::new(0), From 70013db8db2b1df62a6fe0b3e3bbb67318e5be4f Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 3 Mar 2025 19:45:46 +0100 Subject: [PATCH 2/2] vulkan: don't create out shaders without descriptor buffers --- src/gfx_apis/vulkan/renderer.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index 85b7aa2e..0677db52 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -88,8 +88,8 @@ pub struct VulkanRenderer { pub(super) fill_frag_shader: Rc, pub(super) tex_vert_shader: Rc, pub(super) tex_frag_shader: Rc, - pub(super) out_vert_shader: Rc, - pub(super) out_frag_shader: Rc, + pub(super) out_vert_shader: Option>, + pub(super) out_frag_shader: Option>, pub(super) tex_descriptor_set_layouts: ArrayVec, 2>, pub(super) out_descriptor_set_layout: Option>, pub(super) defunct: Cell, @@ -240,12 +240,16 @@ impl VulkanDevice { let fill_frag_shader; let tex_vert_shader; let tex_frag_shader; + let out_vert_shader; + let out_frag_shader; let mut tex_descriptor_set_layouts = ArrayVec::new(); if self.descriptor_buffer.is_some() { tex_vert_shader = self.create_shader(TEX_VERT)?; tex_frag_shader = self.create_shader(TEX_FRAG)?; fill_vert_shader = self.create_shader(FILL_VERT)?; fill_frag_shader = self.create_shader(FILL_FRAG)?; + out_vert_shader = Some(self.create_shader(OUT_VERT)?); + out_frag_shader = Some(self.create_shader(OUT_FRAG)?); tex_descriptor_set_layouts .push(self.create_tex_sampler_descriptor_set_layout(&sampler)?); tex_descriptor_set_layouts.push(self.create_tex_resource_descriptor_set_layout()?); @@ -254,6 +258,8 @@ impl VulkanDevice { tex_frag_shader = self.create_shader(LEGACY_TEX_FRAG)?; fill_vert_shader = self.create_shader(LEGACY_FILL_VERT)?; fill_frag_shader = self.create_shader(LEGACY_FILL_FRAG)?; + out_vert_shader = None; + out_frag_shader = None; tex_descriptor_set_layouts .push(self.create_tex_legacy_descriptor_set_layout(&sampler)?); } @@ -262,8 +268,6 @@ impl VulkanDevice { .as_ref() .map(|db| self.create_out_descriptor_set_layout(db)) .transpose()?; - let out_vert_shader = self.create_shader(OUT_VERT)?; - let out_frag_shader = self.create_shader(OUT_FRAG)?; let gfx_command_buffers = self.create_command_pool(self.graphics_queue_idx)?; let transfer_command_buffers = self .distinct_transfer_queue_family_idx @@ -1123,8 +1127,8 @@ impl VulkanRenderer { .device .create_pipeline::(PipelineCreateInfo { format: fb.format.vk_format, - vert: self.out_vert_shader.clone(), - frag: self.out_frag_shader.clone(), + vert: self.out_vert_shader.clone().unwrap(), + frag: self.out_frag_shader.clone().unwrap(), blend: false, src_has_alpha: true, has_alpha_mult: false,