Set renderer multisample and depth-stencil state
This commit is contained in:
parent
da4bb4af5c
commit
74e9aa37a1
3 changed files with 80 additions and 43 deletions
|
@ -4,9 +4,9 @@ use glyphon::{
|
||||||
};
|
};
|
||||||
use wgpu::{
|
use wgpu::{
|
||||||
Backends, CommandEncoderDescriptor, CompositeAlphaMode, DeviceDescriptor, Features, Instance,
|
Backends, CommandEncoderDescriptor, CompositeAlphaMode, DeviceDescriptor, Features, Instance,
|
||||||
Limits, LoadOp, Operations, PresentMode, RenderPassColorAttachment, RenderPassDescriptor,
|
Limits, LoadOp, MultisampleState, Operations, PresentMode, RenderPassColorAttachment,
|
||||||
RequestAdapterOptions, SurfaceConfiguration, TextureFormat, TextureUsages,
|
RenderPassDescriptor, RequestAdapterOptions, SurfaceConfiguration, TextureFormat,
|
||||||
TextureViewDescriptor,
|
TextureUsages, TextureViewDescriptor,
|
||||||
};
|
};
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
|
@ -64,12 +64,13 @@ async fn run() {
|
||||||
surface.configure(&device, &config);
|
surface.configure(&device, &config);
|
||||||
|
|
||||||
// Set up text renderer
|
// Set up text renderer
|
||||||
let mut text_renderer = TextRenderer::new(&device, &queue);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
FONT_SYSTEM = Some(FontSystem::new());
|
FONT_SYSTEM = Some(FontSystem::new());
|
||||||
}
|
}
|
||||||
let mut cache = SwashCache::new(unsafe { FONT_SYSTEM.as_ref().unwrap() });
|
let mut cache = SwashCache::new(unsafe { FONT_SYSTEM.as_ref().unwrap() });
|
||||||
let mut atlas = TextAtlas::new(&device, &queue, swapchain_format);
|
let mut atlas = TextAtlas::new(&device, &queue, swapchain_format);
|
||||||
|
let mut text_renderer =
|
||||||
|
TextRenderer::new(&mut atlas, &device, MultisampleState::default(), None);
|
||||||
let mut buffer = Buffer::new(
|
let mut buffer = Buffer::new(
|
||||||
unsafe { FONT_SYSTEM.as_ref().unwrap() },
|
unsafe { FONT_SYSTEM.as_ref().unwrap() },
|
||||||
Metrics::new(30, 42),
|
Metrics::new(30, 42),
|
||||||
|
|
|
@ -5,11 +5,12 @@ use std::{borrow::Cow, mem::size_of, num::NonZeroU64, sync::Arc};
|
||||||
use wgpu::{
|
use wgpu::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayoutEntry, BindingResource,
|
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayoutEntry, BindingResource,
|
||||||
BindingType, BlendState, Buffer, BufferBindingType, BufferDescriptor, BufferUsages,
|
BindingType, BlendState, Buffer, BufferBindingType, BufferDescriptor, BufferUsages,
|
||||||
ColorTargetState, ColorWrites, Device, Extent3d, FilterMode, FragmentState, MultisampleState,
|
ColorTargetState, ColorWrites, DepthStencilState, Device, Extent3d, FilterMode, FragmentState,
|
||||||
PipelineLayoutDescriptor, PrimitiveState, Queue, RenderPipeline, RenderPipelineDescriptor,
|
MultisampleState, PipelineLayout, PipelineLayoutDescriptor, PrimitiveState, Queue,
|
||||||
SamplerBindingType, SamplerDescriptor, ShaderModuleDescriptor, ShaderSource, ShaderStages,
|
RenderPipeline, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, ShaderModule,
|
||||||
Texture, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages,
|
ShaderModuleDescriptor, ShaderSource, ShaderStages, Texture, TextureDescriptor,
|
||||||
TextureView, TextureViewDescriptor, TextureViewDimension, VertexFormat, VertexState,
|
TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureView,
|
||||||
|
TextureViewDescriptor, TextureViewDimension, VertexFormat, VertexState,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct InnerAtlas {
|
pub(crate) struct InnerAtlas {
|
||||||
|
@ -88,10 +89,18 @@ impl InnerAtlas {
|
||||||
pub struct TextAtlas {
|
pub struct TextAtlas {
|
||||||
pub(crate) params: Params,
|
pub(crate) params: Params,
|
||||||
pub(crate) params_buffer: Buffer,
|
pub(crate) params_buffer: Buffer,
|
||||||
pub(crate) pipeline: Arc<RenderPipeline>,
|
pub(crate) cached_pipelines: Vec<(
|
||||||
|
MultisampleState,
|
||||||
|
Option<DepthStencilState>,
|
||||||
|
Arc<RenderPipeline>,
|
||||||
|
)>,
|
||||||
pub(crate) bind_group: Arc<BindGroup>,
|
pub(crate) bind_group: Arc<BindGroup>,
|
||||||
pub(crate) color_atlas: InnerAtlas,
|
pub(crate) color_atlas: InnerAtlas,
|
||||||
pub(crate) mask_atlas: InnerAtlas,
|
pub(crate) mask_atlas: InnerAtlas,
|
||||||
|
pub(crate) pipeline_layout: PipelineLayout,
|
||||||
|
pub(crate) shader: ShaderModule,
|
||||||
|
pub(crate) vertex_buffers: [wgpu::VertexBufferLayout<'static>; 1],
|
||||||
|
pub(crate) format: TextureFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextAtlas {
|
impl TextAtlas {
|
||||||
|
@ -234,40 +243,17 @@ impl TextAtlas {
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
|
||||||
let pipeline = Arc::new(device.create_render_pipeline(&RenderPipelineDescriptor {
|
|
||||||
label: Some("glyphon pipeline"),
|
|
||||||
layout: Some(&pipeline_layout),
|
|
||||||
vertex: VertexState {
|
|
||||||
module: &shader,
|
|
||||||
entry_point: "vs_main",
|
|
||||||
buffers: &vertex_buffers,
|
|
||||||
},
|
|
||||||
fragment: Some(FragmentState {
|
|
||||||
module: &shader,
|
|
||||||
entry_point: "fs_main",
|
|
||||||
targets: &[Some(ColorTargetState {
|
|
||||||
format,
|
|
||||||
blend: Some(BlendState::ALPHA_BLENDING),
|
|
||||||
write_mask: ColorWrites::default(),
|
|
||||||
})],
|
|
||||||
}),
|
|
||||||
primitive: PrimitiveState::default(),
|
|
||||||
depth_stencil: None,
|
|
||||||
multisample: MultisampleState {
|
|
||||||
count: 1,
|
|
||||||
mask: !0,
|
|
||||||
alpha_to_coverage_enabled: false,
|
|
||||||
},
|
|
||||||
multiview: None,
|
|
||||||
}));
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
params,
|
params,
|
||||||
params_buffer,
|
params_buffer,
|
||||||
pipeline,
|
cached_pipelines: Vec::new(),
|
||||||
bind_group,
|
bind_group,
|
||||||
color_atlas,
|
color_atlas,
|
||||||
mask_atlas,
|
mask_atlas,
|
||||||
|
pipeline_layout,
|
||||||
|
shader,
|
||||||
|
vertex_buffers,
|
||||||
|
format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,4 +281,44 @@ impl TextAtlas {
|
||||||
ContentType::Mask => &mut self.mask_atlas,
|
ContentType::Mask => &mut self.mask_atlas,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_or_create_pipeline(
|
||||||
|
&mut self,
|
||||||
|
device: &Device,
|
||||||
|
multisample: MultisampleState,
|
||||||
|
depth_stencil: Option<DepthStencilState>,
|
||||||
|
) -> Arc<RenderPipeline> {
|
||||||
|
self.cached_pipelines
|
||||||
|
.iter()
|
||||||
|
.find(|(ms, ds, _)| ms == &multisample && ds == &depth_stencil)
|
||||||
|
.map(|(_, _, p)| Arc::clone(p))
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
let pipeline = Arc::new(device.create_render_pipeline(&RenderPipelineDescriptor {
|
||||||
|
label: Some("glyphon pipeline"),
|
||||||
|
layout: Some(&self.pipeline_layout),
|
||||||
|
vertex: VertexState {
|
||||||
|
module: &self.shader,
|
||||||
|
entry_point: "vs_main",
|
||||||
|
buffers: &self.vertex_buffers,
|
||||||
|
},
|
||||||
|
fragment: Some(FragmentState {
|
||||||
|
module: &self.shader,
|
||||||
|
entry_point: "fs_main",
|
||||||
|
targets: &[Some(ColorTargetState {
|
||||||
|
format: self.format,
|
||||||
|
blend: Some(BlendState::ALPHA_BLENDING),
|
||||||
|
write_mask: ColorWrites::default(),
|
||||||
|
})],
|
||||||
|
}),
|
||||||
|
primitive: PrimitiveState::default(),
|
||||||
|
depth_stencil: depth_stencil.clone(),
|
||||||
|
multisample,
|
||||||
|
multiview: None,
|
||||||
|
}));
|
||||||
|
|
||||||
|
self.cached_pipelines
|
||||||
|
.push((multisample, depth_stencil, pipeline.clone()));
|
||||||
|
pipeline
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@ use crate::{
|
||||||
CacheKey, Color, GlyphDetails, GlyphToRender, GpuCacheStatus, Params, PrepareError,
|
CacheKey, Color, GlyphDetails, GlyphToRender, GpuCacheStatus, Params, PrepareError,
|
||||||
RenderError, Resolution, SwashCache, SwashContent, TextArea, TextAtlas,
|
RenderError, Resolution, SwashCache, SwashContent, TextArea, TextAtlas,
|
||||||
};
|
};
|
||||||
use std::{collections::HashSet, iter, mem::size_of, num::NonZeroU32, slice};
|
use std::{collections::HashSet, iter, mem::size_of, num::NonZeroU32, slice, sync::Arc};
|
||||||
use wgpu::{
|
use wgpu::{
|
||||||
Buffer, BufferDescriptor, BufferUsages, Device, Extent3d, ImageCopyTexture, ImageDataLayout,
|
Buffer, BufferDescriptor, BufferUsages, DepthStencilState, Device, Extent3d, ImageCopyTexture,
|
||||||
IndexFormat, Origin3d, Queue, RenderPass, TextureAspect, COPY_BUFFER_ALIGNMENT,
|
ImageDataLayout, IndexFormat, MultisampleState, Origin3d, Queue, RenderPass, RenderPipeline,
|
||||||
|
TextureAspect, COPY_BUFFER_ALIGNMENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A text renderer that uses cached glyphs to render text into an existing render pass.
|
/// A text renderer that uses cached glyphs to render text into an existing render pass.
|
||||||
|
@ -17,11 +18,17 @@ pub struct TextRenderer {
|
||||||
vertices_to_render: u32,
|
vertices_to_render: u32,
|
||||||
glyphs_in_use: HashSet<CacheKey>,
|
glyphs_in_use: HashSet<CacheKey>,
|
||||||
screen_resolution: Resolution,
|
screen_resolution: Resolution,
|
||||||
|
pipeline: Arc<RenderPipeline>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextRenderer {
|
impl TextRenderer {
|
||||||
/// Creates a new `TextRenderer`.
|
/// Creates a new `TextRenderer`.
|
||||||
pub fn new(device: &Device, _queue: &Queue) -> Self {
|
pub fn new(
|
||||||
|
atlas: &mut TextAtlas,
|
||||||
|
device: &Device,
|
||||||
|
multisample: MultisampleState,
|
||||||
|
depth_stencil: Option<DepthStencilState>,
|
||||||
|
) -> Self {
|
||||||
let vertex_buffer_size = next_copy_buffer_size(4096);
|
let vertex_buffer_size = next_copy_buffer_size(4096);
|
||||||
let vertex_buffer = device.create_buffer(&BufferDescriptor {
|
let vertex_buffer = device.create_buffer(&BufferDescriptor {
|
||||||
label: Some("glyphon vertices"),
|
label: Some("glyphon vertices"),
|
||||||
|
@ -38,6 +45,8 @@ impl TextRenderer {
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let pipeline = atlas.get_or_create_pipeline(device, multisample, depth_stencil);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
vertex_buffer_size,
|
vertex_buffer_size,
|
||||||
|
@ -49,6 +58,7 @@ impl TextRenderer {
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
},
|
},
|
||||||
|
pipeline,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +430,7 @@ impl TextRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pass.set_pipeline(&atlas.pipeline);
|
pass.set_pipeline(&self.pipeline);
|
||||||
pass.set_bind_group(0, &atlas.bind_group, &[]);
|
pass.set_bind_group(0, &atlas.bind_group, &[]);
|
||||||
pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
||||||
pass.set_index_buffer(self.index_buffer.slice(..), IndexFormat::Uint32);
|
pass.set_index_buffer(self.index_buffer.slice(..), IndexFormat::Uint32);
|
||||||
|
|
Loading…
Reference in a new issue