flag UPDATE_AFTER_BIND descriptor sets to fix validation

This commit is contained in:
galister
2025-09-28 23:00:29 +09:00
parent 0d251e9351
commit 8c41eaa048
12 changed files with 161 additions and 99 deletions

View File

@@ -7,29 +7,30 @@ use std::{marker::PhantomData, slice::Iter, sync::Arc};
use cmd::{GfxCommandBuffer, XferCommandBuffer};
use pipeline::WGfxPipeline;
use vulkano::{
DeviceSize,
buffer::{Buffer, BufferContents, BufferCreateInfo, BufferUsage, IndexBuffer, Subbuffer},
command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage,
allocator::{StandardCommandBufferAllocator, StandardCommandBufferAllocatorCreateInfo},
AutoCommandBufferBuilder, CommandBufferUsage,
},
descriptor_set::allocator::{StandardDescriptorSetAllocator, StandardDescriptorSetAllocatorCreateInfo},
device::{Device, Queue},
format::Format,
image::{Image, ImageCreateInfo, ImageType, ImageUsage, sampler::Filter},
image::{sampler::Filter, Image, ImageCreateInfo, ImageType, ImageUsage},
instance::Instance,
memory::{
MemoryPropertyFlags,
allocator::{AllocationCreateInfo, GenericMemoryAllocatorCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
MemoryPropertyFlags,
},
pipeline::graphics::{
color_blend::{AttachmentBlend, BlendFactor, BlendOp},
input_assembly::PrimitiveTopology,
vertex_input::Vertex,
},
shader::ShaderModule,
DeviceSize,
};
use crate::gfx::pipeline::WPipelineCreateInfo;
pub const BLEND_ALPHA: AttachmentBlend = AttachmentBlend {
src_color_blend_factor: BlendFactor::SrcAlpha,
dst_color_blend_factor: BlendFactor::OneMinusSrcAlpha,
@@ -90,7 +91,10 @@ impl WGfx {
));
let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new(
device.clone(),
StandardDescriptorSetAllocatorCreateInfo::default(),
StandardDescriptorSetAllocatorCreateInfo {
update_after_bind: true,
..Default::default()
},
));
let quality_filter = if device.enabled_extensions().img_filter_cubic {
@@ -166,10 +170,7 @@ impl WGfx {
self: &Arc<Self>,
vert: &Arc<ShaderModule>,
frag: &Arc<ShaderModule>,
format: Format,
blend: Option<AttachmentBlend>,
topology: PrimitiveTopology,
instanced: bool,
info: WPipelineCreateInfo,
) -> anyhow::Result<Arc<WGfxPipeline<V>>>
where
V: BufferContents + Vertex,
@@ -178,10 +179,7 @@ impl WGfx {
self.clone(),
vert,
frag,
format,
blend,
topology,
instanced,
info,
)?))
}

View File

@@ -13,12 +13,12 @@ use vulkano::{
view::ImageView,
},
pipeline::{
Pipeline, PipelineBindPoint,
graphics::{self, vertex_input::Vertex, viewport::Viewport},
Pipeline, PipelineBindPoint,
},
};
use super::{WGfx, pipeline::WGfxPipeline};
use super::{pipeline::WGfxPipeline, WGfx};
pub struct WGfxPass<V> {
pub command_buffer: Arc<SecondaryAutoCommandBuffer>,

View File

@@ -1,12 +1,15 @@
use std::{marker::PhantomData, ops::Range, sync::Arc};
use smallvec::smallvec;
use smallvec::{smallvec, SmallVec};
use vulkano::{
buffer::{
BufferContents, BufferUsage, Subbuffer,
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
BufferContents, BufferUsage, Subbuffer,
},
descriptor_set::{
layout::{DescriptorBindingFlags, DescriptorSetLayoutCreateFlags},
DescriptorSet, WriteDescriptorSet,
},
descriptor_set::{DescriptorSet, WriteDescriptorSet},
format::Format,
image::{
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
@@ -14,9 +17,8 @@ use vulkano::{
},
memory::allocator::MemoryTypeFilter,
pipeline::{
DynamicState, GraphicsPipeline, Pipeline, PipelineLayout,
graphics::{
self, GraphicsPipelineCreateInfo,
self,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
@@ -24,13 +26,15 @@ use vulkano::{
subpass::PipelineRenderingCreateInfo,
vertex_input::{Vertex, VertexDefinition, VertexInputState},
viewport::ViewportState,
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
DynamicState, GraphicsPipeline, Pipeline, PipelineLayout,
},
shader::{EntryPoint, ShaderModule},
};
use super::{WGfx, pass::WGfxPass};
use super::{pass::WGfxPass, WGfx};
pub struct WGfxPipeline<V> {
pub graphics: Arc<WGfx>,
@@ -51,16 +55,27 @@ where
vert_entry_point: EntryPoint,
frag_entry_point: EntryPoint,
vertex_input_state: Option<VertexInputState>,
updatable_sets: &[usize],
) -> anyhow::Result<Self> {
let stages = smallvec![
vulkano::pipeline::PipelineShaderStageCreateInfo::new(vert_entry_point),
vulkano::pipeline::PipelineShaderStageCreateInfo::new(frag_entry_point),
];
let mut layout_info = PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages);
for (idx_l, l) in layout_info.set_layouts.iter_mut().enumerate() {
if updatable_sets.contains(&idx_l) {
// mark all bindings in the set as UAB
l.flags |= DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND_POOL;
for b in l.bindings.values_mut() {
b.binding_flags |= DescriptorBindingFlags::UPDATE_AFTER_BIND;
}
}
}
let layout = PipelineLayout::new(
graphics.device.clone(),
PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages)
.into_pipeline_layout_create_info(graphics.device.clone())?,
layout_info.into_pipeline_layout_create_info(graphics.device.clone())?,
)?;
let subpass = PipelineRenderingCreateInfo {
@@ -173,6 +188,46 @@ where
}
}
pub struct WPipelineCreateInfo {
format: Format,
blend: Option<AttachmentBlend>,
topology: PrimitiveTopology,
instanced: bool,
updatable_sets: SmallVec<[usize; 8]>,
}
impl WPipelineCreateInfo {
pub fn new(format: Format) -> Self {
Self {
format,
blend: None,
topology: PrimitiveTopology::TriangleStrip,
instanced: false,
updatable_sets: smallvec![],
}
}
pub fn use_blend(mut self, blend: AttachmentBlend) -> Self {
self.blend = Some(blend);
self
}
pub fn use_topology(mut self, topology: PrimitiveTopology) -> Self {
self.topology = topology;
self
}
pub fn use_instanced(mut self) -> Self {
self.instanced = true;
self
}
pub fn use_updatable_descriptors(mut self, updatable_sets: SmallVec<[usize; 8]>) -> Self {
self.updatable_sets = updatable_sets;
self
}
}
impl<V> WGfxPipeline<V>
where
V: BufferContents + Vertex,
@@ -181,15 +236,12 @@ where
graphics: Arc<WGfx>,
vert: &Arc<ShaderModule>,
frag: &Arc<ShaderModule>,
format: Format,
blend: Option<AttachmentBlend>,
topology: PrimitiveTopology,
instanced: bool,
info: WPipelineCreateInfo,
) -> anyhow::Result<Self> {
let vert_entry_point = vert.entry_point("main").unwrap(); // want panic
let frag_entry_point = frag.entry_point("main").unwrap(); // want panic
let vertex_input_state = Some(if instanced {
let vertex_input_state = Some(if info.instanced {
V::per_instance().definition(&vert_entry_point)?
} else {
V::per_vertex().definition(&vert_entry_point)?
@@ -197,12 +249,13 @@ where
Self::new_from_stages(
graphics,
format,
blend,
topology,
info.format,
info.blend,
info.topology,
vert_entry_point,
frag_entry_point,
vertex_input_state,
&info.updatable_sets,
)
}

View File

@@ -4,12 +4,17 @@ use glam::Mat4;
use vulkano::{
buffer::{BufferContents, BufferUsage, Subbuffer},
format::Format,
pipeline::graphics::{self, input_assembly::PrimitiveTopology, vertex_input::Vertex},
pipeline::graphics::{self, vertex_input::Vertex},
};
use crate::{
drawing::{Boundary, Rectangle},
gfx::{BLEND_ALPHA, WGfx, cmd::GfxCommandBuffer, pass::WGfxPass, pipeline::WGfxPipeline},
gfx::{
cmd::GfxCommandBuffer,
pass::WGfxPass,
pipeline::{WGfxPipeline, WPipelineCreateInfo},
WGfx, BLEND_ALPHA,
},
renderer_vk::model_buffer::ModelBuffer,
};
@@ -47,10 +52,7 @@ impl RectPipeline {
let color_rect = gfx.create_pipeline::<RectVertex>(
&vert,
&frag,
format,
Some(BLEND_ALPHA),
PrimitiveTopology::TriangleStrip,
true,
WPipelineCreateInfo::new(format).use_blend(BLEND_ALPHA).use_instanced(),
)?;
Ok(Self { gfx, color_rect })

View File

@@ -1,5 +1,5 @@
use cosmic_text::{FontSystem, SwashCache};
use etagere::{Allocation, BucketedAtlasAllocator, size2};
use etagere::{size2, Allocation, BucketedAtlasAllocator};
use lru::LruCache;
use rustc_hash::FxHasher;
use std::{collections::HashSet, hash::BuildHasherDefault, sync::Arc};
@@ -8,18 +8,21 @@ use vulkano::{
command_buffer::CommandBufferUsage,
descriptor_set::DescriptorSet,
format::Format,
image::{Image, ImageCreateInfo, ImageType, ImageUsage, view::ImageView},
image::{view::ImageView, Image, ImageCreateInfo, ImageType, ImageUsage},
memory::allocator::AllocationCreateInfo,
pipeline::graphics::{input_assembly::PrimitiveTopology, vertex_input::Vertex},
pipeline::graphics::vertex_input::Vertex,
};
use super::{
GlyphDetails, GpuCacheStatus,
custom_glyph::ContentType,
shaders::{frag_atlas, vert_atlas},
text_renderer::GlyphonCacheKey,
GlyphDetails, GpuCacheStatus,
};
use crate::gfx::{
pipeline::{WGfxPipeline, WPipelineCreateInfo},
WGfx, BLEND_ALPHA,
};
use crate::gfx::{BLEND_ALPHA, WGfx, pipeline::WGfxPipeline};
/// Pipeline & shaders to be reused between `TextRenderer` instances
#[derive(Clone)]
@@ -36,10 +39,7 @@ impl TextPipeline {
let pipeline = gfx.create_pipeline::<GlyphVertex>(
&vert,
&frag,
format,
Some(BLEND_ALPHA),
PrimitiveTopology::TriangleStrip,
true,
WPipelineCreateInfo::new(format).use_blend(BLEND_ALPHA).use_instanced(),
)?;
Ok(Self { gfx, inner: pipeline })