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::{
 | 
			
		||||
    Backends, CommandEncoderDescriptor, CompositeAlphaMode, DeviceDescriptor, Features, Instance,
 | 
			
		||||
    Limits, LoadOp, Operations, PresentMode, RenderPassColorAttachment, RenderPassDescriptor,
 | 
			
		||||
    RequestAdapterOptions, SurfaceConfiguration, TextureFormat, TextureUsages,
 | 
			
		||||
    TextureViewDescriptor,
 | 
			
		||||
    Limits, LoadOp, MultisampleState, Operations, PresentMode, RenderPassColorAttachment,
 | 
			
		||||
    RenderPassDescriptor, RequestAdapterOptions, SurfaceConfiguration, TextureFormat,
 | 
			
		||||
    TextureUsages, TextureViewDescriptor,
 | 
			
		||||
};
 | 
			
		||||
use winit::{
 | 
			
		||||
    dpi::LogicalSize,
 | 
			
		||||
| 
						 | 
				
			
			@ -64,12 +64,13 @@ async fn run() {
 | 
			
		|||
    surface.configure(&device, &config);
 | 
			
		||||
 | 
			
		||||
    // Set up text renderer
 | 
			
		||||
    let mut text_renderer = TextRenderer::new(&device, &queue);
 | 
			
		||||
    unsafe {
 | 
			
		||||
        FONT_SYSTEM = Some(FontSystem::new());
 | 
			
		||||
    }
 | 
			
		||||
    let mut cache = SwashCache::new(unsafe { FONT_SYSTEM.as_ref().unwrap() });
 | 
			
		||||
    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(
 | 
			
		||||
        unsafe { FONT_SYSTEM.as_ref().unwrap() },
 | 
			
		||||
        Metrics::new(30, 42),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,11 +5,12 @@ use std::{borrow::Cow, mem::size_of, num::NonZeroU64, sync::Arc};
 | 
			
		|||
use wgpu::{
 | 
			
		||||
    BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayoutEntry, BindingResource,
 | 
			
		||||
    BindingType, BlendState, Buffer, BufferBindingType, BufferDescriptor, BufferUsages,
 | 
			
		||||
    ColorTargetState, ColorWrites, Device, Extent3d, FilterMode, FragmentState, MultisampleState,
 | 
			
		||||
    PipelineLayoutDescriptor, PrimitiveState, Queue, RenderPipeline, RenderPipelineDescriptor,
 | 
			
		||||
    SamplerBindingType, SamplerDescriptor, ShaderModuleDescriptor, ShaderSource, ShaderStages,
 | 
			
		||||
    Texture, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages,
 | 
			
		||||
    TextureView, TextureViewDescriptor, TextureViewDimension, VertexFormat, VertexState,
 | 
			
		||||
    ColorTargetState, ColorWrites, DepthStencilState, Device, Extent3d, FilterMode, FragmentState,
 | 
			
		||||
    MultisampleState, PipelineLayout, PipelineLayoutDescriptor, PrimitiveState, Queue,
 | 
			
		||||
    RenderPipeline, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, ShaderModule,
 | 
			
		||||
    ShaderModuleDescriptor, ShaderSource, ShaderStages, Texture, TextureDescriptor,
 | 
			
		||||
    TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureView,
 | 
			
		||||
    TextureViewDescriptor, TextureViewDimension, VertexFormat, VertexState,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(crate) struct InnerAtlas {
 | 
			
		||||
| 
						 | 
				
			
			@ -88,10 +89,18 @@ impl InnerAtlas {
 | 
			
		|||
pub struct TextAtlas {
 | 
			
		||||
    pub(crate) params: Params,
 | 
			
		||||
    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) color_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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -234,40 +243,17 @@ impl TextAtlas {
 | 
			
		|||
            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 {
 | 
			
		||||
            params,
 | 
			
		||||
            params_buffer,
 | 
			
		||||
            pipeline,
 | 
			
		||||
            cached_pipelines: Vec::new(),
 | 
			
		||||
            bind_group,
 | 
			
		||||
            color_atlas,
 | 
			
		||||
            mask_atlas,
 | 
			
		||||
            pipeline_layout,
 | 
			
		||||
            shader,
 | 
			
		||||
            vertex_buffers,
 | 
			
		||||
            format,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -295,4 +281,44 @@ impl TextAtlas {
 | 
			
		|||
            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,
 | 
			
		||||
    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::{
 | 
			
		||||
    Buffer, BufferDescriptor, BufferUsages, Device, Extent3d, ImageCopyTexture, ImageDataLayout,
 | 
			
		||||
    IndexFormat, Origin3d, Queue, RenderPass, TextureAspect, COPY_BUFFER_ALIGNMENT,
 | 
			
		||||
    Buffer, BufferDescriptor, BufferUsages, DepthStencilState, Device, Extent3d, ImageCopyTexture,
 | 
			
		||||
    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.
 | 
			
		||||
| 
						 | 
				
			
			@ -17,11 +18,17 @@ pub struct TextRenderer {
 | 
			
		|||
    vertices_to_render: u32,
 | 
			
		||||
    glyphs_in_use: HashSet<CacheKey>,
 | 
			
		||||
    screen_resolution: Resolution,
 | 
			
		||||
    pipeline: Arc<RenderPipeline>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl 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 = device.create_buffer(&BufferDescriptor {
 | 
			
		||||
            label: Some("glyphon vertices"),
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +45,8 @@ impl TextRenderer {
 | 
			
		|||
            mapped_at_creation: false,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let pipeline = atlas.get_or_create_pipeline(device, multisample, depth_stencil);
 | 
			
		||||
 | 
			
		||||
        Self {
 | 
			
		||||
            vertex_buffer,
 | 
			
		||||
            vertex_buffer_size,
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +58,7 @@ impl TextRenderer {
 | 
			
		|||
                width: 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_vertex_buffer(0, self.vertex_buffer.slice(..));
 | 
			
		||||
        pass.set_index_buffer(self.index_buffer.slice(..), IndexFormat::Uint32);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue