From 2de13f3a872668a9fe24162ca55e0a2e7ea827a7 Mon Sep 17 00:00:00 2001 From: Imbris Date: Sun, 28 Feb 2021 02:40:53 -0500 Subject: [PATCH] Try out using storage buffer for sprite vertices --- assets/voxygen/shaders/sprite-vert.glsl | 14 ++++--- voxygen/src/render/mod.rs | 3 +- voxygen/src/render/pipelines/sprite.rs | 56 +++++++++++++++++-------- voxygen/src/render/renderer.rs | 5 ++- voxygen/src/render/renderer/binding.rs | 4 +- voxygen/src/scene/terrain.rs | 18 ++++---- 6 files changed, 64 insertions(+), 36 deletions(-) diff --git a/assets/voxygen/shaders/sprite-vert.glsl b/assets/voxygen/shaders/sprite-vert.glsl index 5c250d0ad9..5565ffc48f 100644 --- a/assets/voxygen/shaders/sprite-vert.glsl +++ b/assets/voxygen/shaders/sprite-vert.glsl @@ -30,8 +30,11 @@ layout(location = 7) in float inst_glow; layout(location = 8) in float model_wind_sway; // NOTE: this only varies per model layout(location = 9) in float model_z_scale; // NOTE: this only varies per model -layout(set = 0, binding = 12) uniform utexture2D t_sprite_verts; -layout(set = 0, binding = 13) uniform sampler s_sprite_verts; +//layout(set = 0, binding = 12) uniform utexture2D t_sprite_verts; +//layout(set = 0, binding = 13) uniform sampler s_sprite_verts; +layout(set = 0, binding = 12) restrict readonly buffer sprite_verts { + uvec2 verts[]; +}; layout (std140, set = 2, binding = 0) uniform u_terrain_locals { @@ -69,9 +72,10 @@ void main() { // Index of the vertex data in the 1D vertex texture int vertex_index = int(gl_VertexIndex % VERT_PAGE_SIZE + inst_vert_page * VERT_PAGE_SIZE); - const int WIDTH = 8192; // TODO: temp - ivec2 tex_coords = ivec2(vertex_index % WIDTH, vertex_index / WIDTH); - uvec2 pos_atlas_pos_norm_ao = texelFetch(usampler2D(t_sprite_verts, s_sprite_verts), tex_coords, 0).xy; + //const int WIDTH = 8192; // TODO: temp + //ivec2 tex_coords = ivec2(vertex_index % WIDTH, vertex_index / WIDTH); + //uvec2 pos_atlas_pos_norm_ao = texelFetch(usampler2D(t_sprite_verts, s_sprite_verts), tex_coords, 0).xy; + uvec2 pos_atlas_pos_norm_ao = verts[vertex_index]; uint v_pos_norm = pos_atlas_pos_norm_ao.x; uint v_atlas_pos = pos_atlas_pos_norm_ao.y; diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index c27632a110..c6dc1bf601 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -14,6 +14,7 @@ pub mod texture; // Reexports pub use self::{ bound::Bound, + buffer::Buffer, consts::Consts, error::RenderError, instances::Instances, @@ -32,7 +33,7 @@ pub use self::{ shadow::{Locals as ShadowLocals, PointLightMatrix}, skybox::{create_mesh as create_skybox_mesh, Vertex as SkyboxVertex}, sprite::{ - create_verts_texture as create_sprite_verts_texture, Instance as SpriteInstance, + create_verts_buffer as create_sprite_verts_buffer, Instance as SpriteInstance, SpriteGlobalsBindGroup, Vertex as SpriteVertex, VERT_PAGE_SIZE as SPRITE_VERT_PAGE_SIZE, }, diff --git a/voxygen/src/render/pipelines/sprite.rs b/voxygen/src/render/pipelines/sprite.rs index 15682e3cae..21dd521405 100644 --- a/voxygen/src/render/pipelines/sprite.rs +++ b/voxygen/src/render/pipelines/sprite.rs @@ -1,7 +1,7 @@ use super::{ super::{ - AaMode, Bound, Consts, GlobalsLayouts, Mesh, Renderer, TerrainLayout, Texture, - Vertex as VertexTrait, + buffer::Buffer, AaMode, Bound, Consts, GlobalsLayouts, Mesh, Renderer, TerrainLayout, + Texture, Vertex as VertexTrait, }, lod_terrain, GlobalModel, }; @@ -88,24 +88,24 @@ impl VertexTrait for Vertex { const STRIDE: wgpu::BufferAddress = mem::size_of::() as wgpu::BufferAddress; } -pub fn create_verts_texture(renderer: &mut Renderer, mut mesh: Mesh) -> Texture { +pub fn create_verts_buffer(renderer: &mut Renderer, mut mesh: Mesh) -> Buffer { renderer.ensure_sufficient_index_length::(VERT_PAGE_SIZE as usize); // TODO: type buffer by Usage - /*Buffer::new( + Buffer::new( &renderer.device, wgpu::BufferUsage::STORAGE, mesh.vertices(), - )*/ - let mut verts = mesh.vertices_mut_vec(); - let format = wgpu::TextureFormat::Rg32Uint; + ) + //let mut verts = mesh.vertices_mut_vec(); + //let format = wgpu::TextureFormat::Rg32Uint; // TODO: temp - const WIDTH: u32 = 8192; - let height = verts.len() as u32 / WIDTH; + //const WIDTH: u32 = 8192; + //let height = verts.len() as u32 / WIDTH; // Fill in verts to full texture size - verts.resize_with(height as usize * WIDTH as usize, Vertex::default); + //verts.resize_with(height as usize * WIDTH as usize, Vertex::default); - let texture_info = wgpu::TextureDescriptor { + /*let texture_info = wgpu::TextureDescriptor { label: Some("Sprite verts"), size: wgpu::Extent3d { width: WIDTH, @@ -146,7 +146,7 @@ pub fn create_verts_texture(renderer: &mut Renderer, mut mesh: Mesh) -> &view_info, &sampler_info, bytemuck::cast_slice(verts), - ) + )*/ } #[repr(C)] @@ -263,8 +263,21 @@ impl SpriteLayout { let mut entries = GlobalsLayouts::base_globals_layout(); debug_assert_eq!(12, entries.len()); // To remember to adjust the bindings below entries.extend_from_slice(&[ - // sprite verts (t_sprite_verts) + // sprite_verts wgpu::BindGroupLayoutEntry { + binding: 12, + visibility: wgpu::ShaderStage::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Storage { read_only: true }, + has_dynamic_offset: false, + min_binding_size: core::num::NonZeroU64::new( + core::mem::size_of::() as u64 + ), + }, + count: None, + }, + /* sprite verts (t_sprite_verts) */ + /*wgpu::BindGroupLayoutEntry { binding: 12, visibility: wgpu::ShaderStage::VERTEX, ty: wgpu::BindingType::Texture { @@ -282,7 +295,7 @@ impl SpriteLayout { comparison: false, }, count: None, - }, + },*/ ]); Self { @@ -323,20 +336,26 @@ impl SpriteLayout { global_model: &GlobalModel, lod_data: &lod_terrain::LodData, noise: &Texture, - sprite_verts: &Texture, + //sprite_verts: &Texture, + sprite_verts: &Buffer, ) -> wgpu::BindGroup { let mut entries = GlobalsLayouts::bind_base_globals(global_model, lod_data, noise); entries.extend_from_slice(&[ - // sprite verts (t_sprite_verts) + // sprite_verts wgpu::BindGroupEntry { + binding: 12, + resource: sprite_verts.buf.as_entire_binding(), + }, + /* sprite verts (t_sprite_verts) */ + /*wgpu::BindGroupEntry { binding: 12, resource: wgpu::BindingResource::TextureView(&sprite_verts.view), }, wgpu::BindGroupEntry { binding: 13, resource: wgpu::BindingResource::Sampler(&sprite_verts.sampler), - }, + },*/ ]); device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -352,7 +371,8 @@ impl SpriteLayout { global_model: &GlobalModel, lod_data: &lod_terrain::LodData, noise: &Texture, - sprite_verts: &Texture, + //sprite_verts: &Texture, + sprite_verts: &Buffer, ) -> SpriteGlobalsBindGroup { let bind_group = self.bind_globals_inner(device, global_model, lod_data, noise, sprite_verts); diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index da32f86875..a767c20520 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -90,7 +90,8 @@ struct Shadow { /// GPU, along with pipeline state objects (PSOs) needed to renderer different /// kinds of models to the screen. pub struct Renderer { - device: wgpu::Device, + // TODO: remove pub(super) + pub(super) device: wgpu::Device, queue: wgpu::Queue, surface: wgpu::Surface, swap_chain: wgpu::SwapChain, @@ -1975,7 +1976,7 @@ fn create_pipelines( let mut compiler = Compiler::new().ok_or(RenderError::ErrorInitializingCompiler)?; let mut options = CompileOptions::new().ok_or(RenderError::ErrorInitializingCompiler)?; options.set_optimization_level(OptimizationLevel::Performance); - options.set_forced_version_profile(420, shaderc::GlslProfile::Core); + options.set_forced_version_profile(430, shaderc::GlslProfile::Core); options.set_include_callback(move |name, _, shader_name, _| { Ok(ResolvedInclude { resolved_name: name.to_string(), diff --git a/voxygen/src/render/renderer/binding.rs b/voxygen/src/render/renderer/binding.rs index ab2c9a623d..e76a2d9807 100644 --- a/voxygen/src/render/renderer/binding.rs +++ b/voxygen/src/render/renderer/binding.rs @@ -1,5 +1,6 @@ use super::{ super::{ + buffer::Buffer, pipelines::{ figure, fluid, lod_terrain, shadow, sprite, terrain, ui, ColLights, GlobalModel, GlobalsBindGroup, @@ -24,7 +25,8 @@ impl Renderer { &self, global_model: &GlobalModel, lod_data: &lod_terrain::LodData, - sprite_verts: &Texture, + //sprite_verts: &Texture, + sprite_verts: &Buffer, ) -> sprite::SpriteGlobalsBindGroup { self.layouts.sprite.bind_globals( &self.device, diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 10adc6cae5..e1cec482e8 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -9,12 +9,12 @@ use crate::{ terrain::{generate_mesh, SUNLIGHT}, }, render::{ - create_sprite_verts_texture, + create_sprite_verts_buffer, pipelines::{self, ColLights}, - ColLightInfo, Consts, Drawer, FirstPassDrawer, FluidVertex, FluidWaves, GlobalModel, - Instances, LodData, Mesh, Model, RenderError, Renderer, SpriteGlobalsBindGroup, - SpriteInstance, SpriteVertex, TerrainLocals, TerrainShadowDrawer, TerrainVertex, Texture, - SPRITE_VERT_PAGE_SIZE, + Buffer, ColLightInfo, Consts, Drawer, FirstPassDrawer, FluidVertex, FluidWaves, + GlobalModel, Instances, LodData, Mesh, Model, RenderError, Renderer, + SpriteGlobalsBindGroup, SpriteInstance, SpriteVertex, TerrainLocals, TerrainShadowDrawer, + TerrainVertex, Texture, SPRITE_VERT_PAGE_SIZE, }, }; @@ -381,7 +381,7 @@ pub struct SpriteRenderContext { // Maps sprite kind + variant to data detailing how to render it sprite_data: Arc>, sprite_col_lights: Arc>, - sprite_verts_texture: Arc, + sprite_verts_buffer: Arc>, } pub type SpriteRenderContextLazy = Box SpriteRenderContext>; @@ -550,14 +550,14 @@ impl SpriteRenderContext { let sprite_col_lights = renderer.sprite_bind_col_light(sprite_col_lights); // Write sprite model to a 1D texture - let sprite_verts_texture = create_sprite_verts_texture(renderer, sprite_mesh); + let sprite_verts_buffer = create_sprite_verts_buffer(renderer, sprite_mesh); Self { // TODO: this are all Arcs, would it makes sense to factor out the Arc? sprite_config: Arc::clone(&sprite_config), sprite_data: Arc::new(sprite_data), sprite_col_lights: Arc::new(sprite_col_lights), - sprite_verts_texture: Arc::new(sprite_verts_texture), + sprite_verts_buffer: Arc::new(sprite_verts_buffer), } }; Box::new(move |renderer| init.get_or_init(|| closure(renderer)).clone()) @@ -593,7 +593,7 @@ impl Terrain { sprite_globals: renderer.bind_sprite_globals( global_model, lod_data, - &sprite_render_context.sprite_verts_texture, + &sprite_render_context.sprite_verts_buffer, ), col_lights: Arc::new(col_lights), waves: {