1
0
Fork 0
forked from wry/wry

Merge pull request #391 from mahkoh/jorth/separate-image-sampler

vulkan: separate images and samplers
This commit is contained in:
mahkoh 2025-03-03 19:49:19 +01:00 committed by GitHub
commit 3fa3b020c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 147 additions and 89 deletions

View file

@ -10,9 +10,8 @@ use {
utils::on_drop::OnDrop, utils::on_drop::OnDrop,
}, },
ash::vk::{ ash::vk::{
DescriptorDataEXT, DescriptorGetInfoEXT, DescriptorImageInfo, DescriptorType, Extent3D, Extent3D, ImageAspectFlags, ImageCreateInfo, ImageLayout, ImageSubresourceRange,
ImageAspectFlags, ImageCreateInfo, ImageLayout, ImageSubresourceRange, ImageTiling, ImageTiling, ImageType, ImageViewCreateInfo, ImageViewType, SampleCountFlags, SharingMode,
ImageType, ImageViewCreateInfo, ImageViewType, SampleCountFlags, SharingMode,
}, },
gpu_alloc::UsageFlags, gpu_alloc::UsageFlags,
std::{any::Any, cell::Cell, collections::hash_map::Entry, rc::Rc}, std::{any::Any, cell::Cell, collections::hash_map::Entry, rc::Rc},
@ -24,9 +23,9 @@ impl VulkanRenderer {
width: i32, width: i32,
height: i32, height: i32,
) -> Result<Rc<VulkanImage>, VulkanError> { ) -> Result<Rc<VulkanImage>, VulkanError> {
let Some(db) = &self.device.descriptor_buffer else { if self.device.descriptor_buffer.is_none() {
return Err(VulkanError::NoDescriptorBuffer); return Err(VulkanError::NoDescriptorBuffer);
}; }
if width <= 0 || height <= 0 { if width <= 0 || height <= 0 {
return Err(VulkanError::NonPositiveImageSize); return Err(VulkanError::NonPositiveImageSize);
} }
@ -90,21 +89,6 @@ impl VulkanRenderer {
}; };
let view = view.map_err(VulkanError::CreateImageView)?; let view = view.map_err(VulkanError::CreateImageView)?;
destroy_image.forget(); 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 { let img = Rc::new(VulkanImage {
renderer: self.clone(), renderer: self.clone(),
format: BLEND_FORMAT, format: BLEND_FORMAT,
@ -121,8 +105,7 @@ impl VulkanRenderer {
}), }),
ty: VulkanImageMemory::Blend(allocation), ty: VulkanImageMemory::Blend(allocation),
bridge: None, bridge: None,
shader_read_only_optimal_descriptor: Box::new([]), sampled_image_descriptor: self.sampled_image_descriptor(view),
sampled_image_descriptor,
descriptor_buffer_version: Default::default(), descriptor_buffer_version: Default::default(),
descriptor_buffer_offset: Default::default(), descriptor_buffer_offset: Default::default(),
execution_version: Default::default(), execution_version: Default::default(),

View file

@ -52,12 +52,13 @@ impl VulkanBufferCache {
pub fn for_descriptor_buffer( pub fn for_descriptor_buffer(
device: &Rc<VulkanDevice>, device: &Rc<VulkanDevice>,
allocator: &Rc<VulkanAllocator>, allocator: &Rc<VulkanAllocator>,
has_sampler: bool, for_sampler: bool,
) -> Rc<Self> { ) -> Rc<Self> {
let mut usage = BufferUsageFlags::RESOURCE_DESCRIPTOR_BUFFER_EXT let mut usage = BufferUsageFlags::SHADER_DEVICE_ADDRESS;
| BufferUsageFlags::SHADER_DEVICE_ADDRESS; if for_sampler {
if has_sampler {
usage |= BufferUsageFlags::SAMPLER_DESCRIPTOR_BUFFER_EXT; usage |= BufferUsageFlags::SAMPLER_DESCRIPTOR_BUFFER_EXT;
} else {
usage |= BufferUsageFlags::RESOURCE_DESCRIPTOR_BUFFER_EXT;
} }
Self::new(device, allocator, usage) Self::new(device, allocator, usage)
} }

View file

@ -30,7 +30,7 @@ impl Drop for VulkanDescriptorSetLayout {
} }
impl VulkanDevice { impl VulkanDevice {
pub(super) fn create_tex_descriptor_set_layout( pub(super) fn create_tex_legacy_descriptor_set_layout(
self: &Rc<Self>, self: &Rc<Self>,
sampler: &Rc<VulkanSampler>, sampler: &Rc<VulkanSampler>,
) -> Result<Rc<VulkanDescriptorSetLayout>, VulkanError> { ) -> Result<Rc<VulkanDescriptorSetLayout>, VulkanError> {
@ -40,24 +40,40 @@ impl VulkanDevice {
.immutable_samplers(&immutable_sampler) .immutable_samplers(&immutable_sampler)
.descriptor_count(1) .descriptor_count(1)
.descriptor_type(DescriptorType::COMBINED_IMAGE_SAMPLER); .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() let create_info = DescriptorSetLayoutCreateInfo::default()
.bindings(slice::from_ref(&binding)) .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 = unsafe { self.device.create_descriptor_set_layout(&create_info, None) };
let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?; 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<Self>,
sampler: &Rc<VulkanSampler>,
) -> Result<Rc<VulkanDescriptorSetLayout>, 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(); let mut offsets = ArrayVec::new();
if let Some(db) = &self.descriptor_buffer { unsafe {
size = self.get_descriptor_set_size(db, layout); 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 { Ok(Rc::new(VulkanDescriptorSetLayout {
device: self.clone(), device: self.clone(),
@ -68,6 +84,33 @@ impl VulkanDevice {
})) }))
} }
pub(super) fn create_tex_resource_descriptor_set_layout(
self: &Rc<Self>,
) -> Result<Rc<VulkanDescriptorSetLayout>, 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( pub(super) fn create_out_descriptor_set_layout(
self: &Rc<Self>, self: &Rc<Self>,
db: &descriptor_buffer::Device, db: &descriptor_buffer::Device,

View file

@ -71,7 +71,7 @@ pub struct VulkanDevice {
pub(super) distinct_transfer_queue_family_idx: Option<u32>, pub(super) distinct_transfer_queue_family_idx: Option<u32>,
pub(super) transfer_granularity_mask: (u32, u32), pub(super) transfer_granularity_mask: (u32, u32),
pub(super) descriptor_buffer_offset_mask: DeviceSize, 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, pub(super) sampled_image_descriptor_size: usize,
} }
@ -366,7 +366,7 @@ impl VulkanInstance {
let descriptor_buffer = supports_descriptor_buffer let descriptor_buffer = supports_descriptor_buffer
.then(|| descriptor_buffer::Device::new(&self.instance, &device)); .then(|| descriptor_buffer::Device::new(&self.instance, &device));
let mut descriptor_buffer_offset_mask = 0; 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; let mut sampled_image_descriptor_size = 0;
if supports_descriptor_buffer { if supports_descriptor_buffer {
let mut descriptor_buffer_props = let mut descriptor_buffer_props =
@ -382,8 +382,7 @@ impl VulkanInstance {
.checked_next_power_of_two() .checked_next_power_of_two()
.unwrap() .unwrap()
- 1; - 1;
combined_image_sampler_descriptor_size = sampler_descriptor_size = descriptor_buffer_props.sampler_descriptor_size;
descriptor_buffer_props.combined_image_sampler_descriptor_size;
sampled_image_descriptor_size = descriptor_buffer_props.sampled_image_descriptor_size; sampled_image_descriptor_size = descriptor_buffer_props.sampled_image_descriptor_size;
} }
let memory_properties = let memory_properties =
@ -422,7 +421,7 @@ impl VulkanInstance {
distinct_transfer_queue_family_idx, distinct_transfer_queue_family_idx,
transfer_granularity_mask, transfer_granularity_mask,
descriptor_buffer_offset_mask, descriptor_buffer_offset_mask,
combined_image_sampler_descriptor_size, sampler_descriptor_size,
sampled_image_descriptor_size, sampled_image_descriptor_size,
blend_limits, blend_limits,
})) }))

View file

@ -26,7 +26,8 @@ use {
ImagePlaneMemoryRequirementsInfo, ImageSubresourceRange, ImageTiling, ImageType, ImagePlaneMemoryRequirementsInfo, ImageSubresourceRange, ImageTiling, ImageType,
ImageUsageFlags, ImageView, ImageViewCreateInfo, ImageViewType, ImportMemoryFdInfoKHR, ImageUsageFlags, ImageView, ImageViewCreateInfo, ImageViewType, ImportMemoryFdInfoKHR,
MemoryAllocateInfo, MemoryDedicatedAllocateInfo, MemoryFdPropertiesKHR, MemoryAllocateInfo, MemoryDedicatedAllocateInfo, MemoryFdPropertiesKHR,
MemoryPropertyFlags, MemoryRequirements2, SampleCountFlags, SharingMode, SubresourceLayout, MemoryPropertyFlags, MemoryRequirements2, SampleCountFlags, Sampler, SharingMode,
SubresourceLayout,
}, },
gpu_alloc::UsageFlags, gpu_alloc::UsageFlags,
std::{ std::{
@ -63,7 +64,6 @@ pub struct VulkanImage {
pub(super) queue_state: Cell<QueueState>, pub(super) queue_state: Cell<QueueState>,
pub(super) ty: VulkanImageMemory, pub(super) ty: VulkanImageMemory,
pub(super) bridge: Option<VulkanFramebufferBridge>, pub(super) bridge: Option<VulkanFramebufferBridge>,
pub(super) shader_read_only_optimal_descriptor: Box<[u8]>,
pub(super) sampled_image_descriptor: Box<[u8]>, pub(super) sampled_image_descriptor: Box<[u8]>,
pub(super) descriptor_buffer_version: Cell<u64>, pub(super) descriptor_buffer_version: Cell<u64>,
pub(super) descriptor_buffer_offset: Cell<DeviceSize>, pub(super) descriptor_buffer_offset: Cell<DeviceSize>,
@ -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 { 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 { let Some(db) = &self.device.descriptor_buffer else {
return Box::new([]); return Box::new([]);
}; };
let mut buf = let mut buf = vec![0; self.device.sampled_image_descriptor_size].into_boxed_slice();
vec![0; self.device.combined_image_sampler_descriptor_size].into_boxed_slice();
let image_info = DescriptorImageInfo::default() let image_info = DescriptorImageInfo::default()
.sampler(self.sampler.sampler)
.image_view(view) .image_view(view)
.image_layout(ImageLayout::SHADER_READ_ONLY_OPTIMAL); .image_layout(ImageLayout::SHADER_READ_ONLY_OPTIMAL);
let info = DescriptorGetInfoEXT::default() let info = DescriptorGetInfoEXT::default()
.ty(DescriptorType::COMBINED_IMAGE_SAMPLER) .ty(DescriptorType::SAMPLED_IMAGE)
.data(DescriptorDataEXT { .data(DescriptorDataEXT {
p_combined_image_sampler: &image_info, p_sampled_image: &image_info,
}); });
unsafe { unsafe {
db.get_descriptor(&info, &mut buf); db.get_descriptor(&info, &mut buf);
@ -450,10 +466,7 @@ impl VulkanDmaBufImageTemplate {
family: QueueFamily::Gfx, family: QueueFamily::Gfx,
}), }),
bridge, bridge,
shader_read_only_optimal_descriptor: self sampled_image_descriptor: self.renderer.sampled_image_descriptor(texture_view),
.renderer
.sampler_read_only_descriptor(texture_view),
sampled_image_descriptor: Box::new([]),
descriptor_buffer_version: Cell::new(0), descriptor_buffer_version: Cell::new(0),
descriptor_buffer_offset: Cell::new(0), descriptor_buffer_offset: Cell::new(0),
execution_version: Cell::new(0), execution_version: Cell::new(0),

View file

@ -29,7 +29,7 @@ pub(super) struct VulkanPipeline {
pub(super) _frag: Rc<VulkanShader>, pub(super) _frag: Rc<VulkanShader>,
pub(super) pipeline_layout: PipelineLayout, pub(super) pipeline_layout: PipelineLayout,
pub(super) pipeline: Pipeline, pub(super) pipeline: Pipeline,
pub(super) _frag_descriptor_set_layout: Option<Rc<VulkanDescriptorSetLayout>>, pub(super) _descriptor_set_layouts: ArrayVec<Rc<VulkanDescriptorSetLayout>, 2>,
} }
pub(super) struct PipelineCreateInfo { pub(super) struct PipelineCreateInfo {
@ -41,7 +41,7 @@ pub(super) struct PipelineCreateInfo {
pub(super) has_alpha_mult: bool, pub(super) has_alpha_mult: bool,
pub(super) eotf: u32, pub(super) eotf: u32,
pub(super) oetf: u32, pub(super) oetf: u32,
pub(super) frag_descriptor_set_layout: Option<Rc<VulkanDescriptorSetLayout>>, pub(super) descriptor_set_layouts: ArrayVec<Rc<VulkanDescriptorSetLayout>, 2>,
} }
impl VulkanDevice { impl VulkanDevice {
@ -67,9 +67,8 @@ impl VulkanDevice {
.size(push_size as u32), .size(push_size as u32),
); );
} }
let mut descriptor_set_layouts = ArrayVec::<_, 1>::new(); let mut descriptor_set_layouts = ArrayVec::<_, 2>::new();
descriptor_set_layouts descriptor_set_layouts.extend(info.descriptor_set_layouts.iter().map(|l| l.layout));
.extend(info.frag_descriptor_set_layout.as_ref().map(|l| l.layout));
let create_info = PipelineLayoutCreateInfo::default() let create_info = PipelineLayoutCreateInfo::default()
.push_constant_ranges(&push_constant_ranges) .push_constant_ranges(&push_constant_ranges)
.set_layouts(&descriptor_set_layouts); .set_layouts(&descriptor_set_layouts);
@ -175,7 +174,7 @@ impl VulkanDevice {
_frag: info.frag, _frag: info.frag,
pipeline_layout, pipeline_layout,
pipeline, pipeline,
_frag_descriptor_set_layout: info.frag_descriptor_set_layout, _descriptor_set_layouts: info.descriptor_set_layouts,
})) }))
} }
} }

View file

@ -88,14 +88,15 @@ pub struct VulkanRenderer {
pub(super) fill_frag_shader: Rc<VulkanShader>, pub(super) fill_frag_shader: Rc<VulkanShader>,
pub(super) tex_vert_shader: Rc<VulkanShader>, pub(super) tex_vert_shader: Rc<VulkanShader>,
pub(super) tex_frag_shader: Rc<VulkanShader>, pub(super) tex_frag_shader: Rc<VulkanShader>,
pub(super) out_vert_shader: Rc<VulkanShader>, pub(super) out_vert_shader: Option<Rc<VulkanShader>>,
pub(super) out_frag_shader: Rc<VulkanShader>, pub(super) out_frag_shader: Option<Rc<VulkanShader>>,
pub(super) tex_descriptor_set_layout: Rc<VulkanDescriptorSetLayout>, pub(super) tex_descriptor_set_layouts: ArrayVec<Rc<VulkanDescriptorSetLayout>, 2>,
pub(super) out_descriptor_set_layout: Option<Rc<VulkanDescriptorSetLayout>>, pub(super) out_descriptor_set_layout: Option<Rc<VulkanDescriptorSetLayout>>,
pub(super) defunct: Cell<bool>, pub(super) defunct: Cell<bool>,
pub(super) pending_cpu_jobs: CopyHashMap<u64, PendingJob>, pub(super) pending_cpu_jobs: CopyHashMap<u64, PendingJob>,
pub(super) shm_allocator: Rc<VulkanThreadedAllocator>, pub(super) shm_allocator: Rc<VulkanThreadedAllocator>,
pub(super) sampler: Rc<VulkanSampler>, pub(super) _sampler: Rc<VulkanSampler>,
pub(super) sampler_descriptor: Box<[u8]>,
pub(super) sampler_descriptor_buffer_cache: Rc<VulkanBufferCache>, pub(super) sampler_descriptor_buffer_cache: Rc<VulkanBufferCache>,
pub(super) resource_descriptor_buffer_cache: Rc<VulkanBufferCache>, pub(super) resource_descriptor_buffer_cache: Rc<VulkanBufferCache>,
pub(super) blend_buffers: RefCell<AHashMap<(u32, u32), Weak<VulkanImage>>>, pub(super) blend_buffers: RefCell<AHashMap<(u32, u32), Weak<VulkanImage>>>,
@ -234,30 +235,39 @@ impl VulkanDevice {
eng: &Rc<AsyncEngine>, eng: &Rc<AsyncEngine>,
ring: &Rc<IoUring>, ring: &Rc<IoUring>,
) -> Result<Rc<VulkanRenderer>, VulkanError> { ) -> Result<Rc<VulkanRenderer>, VulkanError> {
let sampler = self.create_sampler()?;
let fill_vert_shader; let fill_vert_shader;
let fill_frag_shader; let fill_frag_shader;
let tex_vert_shader; let tex_vert_shader;
let tex_frag_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() { if self.descriptor_buffer.is_some() {
tex_vert_shader = self.create_shader(TEX_VERT)?; tex_vert_shader = self.create_shader(TEX_VERT)?;
tex_frag_shader = self.create_shader(TEX_FRAG)?; tex_frag_shader = self.create_shader(TEX_FRAG)?;
fill_vert_shader = self.create_shader(FILL_VERT)?; fill_vert_shader = self.create_shader(FILL_VERT)?;
fill_frag_shader = self.create_shader(FILL_FRAG)?; 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()?);
} else { } else {
tex_vert_shader = self.create_shader(LEGACY_TEX_VERT)?; tex_vert_shader = self.create_shader(LEGACY_TEX_VERT)?;
tex_frag_shader = self.create_shader(LEGACY_TEX_FRAG)?; tex_frag_shader = self.create_shader(LEGACY_TEX_FRAG)?;
fill_vert_shader = self.create_shader(LEGACY_FILL_VERT)?; fill_vert_shader = self.create_shader(LEGACY_FILL_VERT)?;
fill_frag_shader = self.create_shader(LEGACY_FILL_FRAG)?; 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)?);
} }
let sampler = self.create_sampler()?;
let tex_descriptor_set_layout = self.create_tex_descriptor_set_layout(&sampler)?;
let out_descriptor_set_layout = self let out_descriptor_set_layout = self
.descriptor_buffer .descriptor_buffer
.as_ref() .as_ref()
.map(|db| self.create_out_descriptor_set_layout(db)) .map(|db| self.create_out_descriptor_set_layout(db))
.transpose()?; .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 gfx_command_buffers = self.create_command_pool(self.graphics_queue_idx)?;
let transfer_command_buffers = self let transfer_command_buffers = self
.distinct_transfer_queue_family_idx .distinct_transfer_queue_family_idx
@ -327,12 +337,13 @@ impl VulkanDevice {
tex_frag_shader, tex_frag_shader,
out_vert_shader, out_vert_shader,
out_frag_shader, out_frag_shader,
tex_descriptor_set_layout, tex_descriptor_set_layouts,
out_descriptor_set_layout, out_descriptor_set_layout,
defunct: Cell::new(false), defunct: Cell::new(false),
pending_cpu_jobs: Default::default(), pending_cpu_jobs: Default::default(),
shm_allocator, shm_allocator,
sampler, sampler_descriptor: self.create_sampler_descriptor(sampler.sampler),
_sampler: sampler,
sampler_descriptor_buffer_cache, sampler_descriptor_buffer_cache,
resource_descriptor_buffer_cache, resource_descriptor_buffer_cache,
blend_buffers: Default::default(), blend_buffers: Default::default(),
@ -372,7 +383,7 @@ impl VulkanRenderer {
has_alpha_mult: false, has_alpha_mult: false,
eotf, eotf,
oetf, oetf,
frag_descriptor_set_layout: None, descriptor_set_layouts: Default::default(),
}; };
self.device.create_pipeline2(info, push_size) self.device.create_pipeline2(info, push_size)
}; };
@ -393,7 +404,7 @@ impl VulkanRenderer {
has_alpha_mult, has_alpha_mult,
eotf, eotf,
oetf, 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) self.device.create_pipeline2(info, push_size)
}; };
@ -438,6 +449,13 @@ impl VulkanRenderer {
let memory = &mut *self.memory.borrow_mut(); let memory = &mut *self.memory.borrow_mut();
let sampler_writer = &mut memory.sampler_descriptor_buffer_writer; let sampler_writer = &mut memory.sampler_descriptor_buffer_writer;
sampler_writer.clear(); 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; let resource_writer = &mut memory.resource_descriptor_buffer_writer;
resource_writer.clear(); resource_writer.clear();
if let Some(bb) = bb { if let Some(bb) = bb {
@ -447,6 +465,7 @@ impl VulkanRenderer {
let mut writer = resource_writer.add_set(layout); let mut writer = resource_writer.add_set(layout);
writer.write(layout.offsets[0], &bb.sampled_image_descriptor); 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 pass in RenderPass::variants() {
for cmd in &memory.ops[pass] { for cmd in &memory.ops[pass] {
let VulkanOp::Tex(c) = cmd else { let VulkanOp::Tex(c) = cmd else {
@ -456,12 +475,12 @@ impl VulkanRenderer {
if tex.descriptor_buffer_version.replace(version) == version { if tex.descriptor_buffer_version.replace(version) == version {
continue; continue;
} }
let offset = sampler_writer.next_offset(); let offset = resource_writer.next_offset();
tex.descriptor_buffer_offset.set(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( writer.write(
self.tex_descriptor_set_layout.offsets[0], tex_descriptor_set_layout.offsets[0],
&tex.shader_read_only_optimal_descriptor, &tex.sampled_image_descriptor,
); );
} }
} }
@ -1018,8 +1037,8 @@ impl VulkanRenderer {
PipelineBindPoint::GRAPHICS, PipelineBindPoint::GRAPHICS,
pipeline.pipeline_layout, pipeline.pipeline_layout,
0, 0,
&[0], &[0, 1],
&[tex.descriptor_buffer_offset.get()], &[0, tex.descriptor_buffer_offset.get()],
); );
dev.cmd_push_constants( dev.cmd_push_constants(
buf, buf,
@ -1102,19 +1121,20 @@ impl VulkanRenderer {
let pipeline = match self.out_pipelines.borrow_mut().entry(fb.format.vk_format) { let pipeline = match self.out_pipelines.borrow_mut().entry(fb.format.vk_format) {
Entry::Occupied(pipeline) => pipeline.get().clone(), Entry::Occupied(pipeline) => pipeline.get().clone(),
Entry::Vacant(e) => { 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 let out = self
.device .device
.create_pipeline::<OutPushConstants>(PipelineCreateInfo { .create_pipeline::<OutPushConstants>(PipelineCreateInfo {
format: fb.format.vk_format, format: fb.format.vk_format,
vert: self.out_vert_shader.clone(), vert: self.out_vert_shader.clone().unwrap(),
frag: self.out_frag_shader.clone(), frag: self.out_frag_shader.clone().unwrap(),
blend: false, blend: false,
src_has_alpha: true, src_has_alpha: true,
has_alpha_mult: false, has_alpha_mult: false,
eotf: TF_LINEAR, eotf: TF_LINEAR,
oetf: TF_SRGB, oetf: TF_SRGB,
frag_descriptor_set_layout: Some(layout.clone()), descriptor_set_layouts,
})?; })?;
e.insert(out.clone()); e.insert(out.clone());
out out

View file

@ -4,12 +4,13 @@
#include "transfer_functions.glsl" #include "transfer_functions.glsl"
#include "tex.common.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) in vec2 tex_pos;
layout(location = 0) out vec4 out_color; layout(location = 0) out vec4 out_color;
void main() { void main() {
vec4 c = textureLod(tex, tex_pos, 0); vec4 c = textureLod(sampler2D(tex, sam), tex_pos, 0);
if (eotf != oetf) { if (eotf != oetf) {
if (src_has_alpha) { if (src_has_alpha) {
c.rgb /= mix(c.a, 1.0, c.a == 0.0); c.rgb /= mix(c.a, 1.0, c.a == 0.0);

View file

@ -459,8 +459,7 @@ impl VulkanRenderer {
}), }),
ty: VulkanImageMemory::Internal(shm), ty: VulkanImageMemory::Internal(shm),
bridge: None, bridge: None,
shader_read_only_optimal_descriptor: self.sampler_read_only_descriptor(view), sampled_image_descriptor: self.sampled_image_descriptor(view),
sampled_image_descriptor: Box::new([]),
descriptor_buffer_version: Cell::new(0), descriptor_buffer_version: Cell::new(0),
descriptor_buffer_offset: Cell::new(0), descriptor_buffer_offset: Cell::new(0),
execution_version: Cell::new(0), execution_version: Cell::new(0),