diff --git a/src/render/shaders/mod.rs b/src/render/shaders/mod.rs index 5240c17f..17495153 100644 --- a/src/render/shaders/mod.rs +++ b/src/render/shaders/mod.rs @@ -65,33 +65,53 @@ impl VertexShaderState { pub mod tile { use crate::platform::COLOR_TEXTURE_FORMAT; - use crate::render::shader_ffi::GpuVertexUniform; + use crate::render::shader_ffi::{GpuVertexUniform, TileUniform}; use super::{FragmentShaderState, VertexShaderState}; pub const VERTEX: VertexShaderState = VertexShaderState::new( include_str!("tile.vertex.wgsl"), - &[wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() as u64, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &[ - wgpu::VertexAttribute { - offset: 0, - format: wgpu::VertexFormat::Float32x2, - shader_location: 0, - }, - wgpu::VertexAttribute { - offset: wgpu::VertexFormat::Float32x2.size(), - format: wgpu::VertexFormat::Float32x2, - shader_location: 1, - }, - wgpu::VertexAttribute { - offset: 2 * wgpu::VertexFormat::Float32x2.size(), - format: wgpu::VertexFormat::Uint32, - shader_location: 2, - }, - ], - }], + &[ + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as u64, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + offset: 0, + format: wgpu::VertexFormat::Float32x2, + shader_location: 0, + }, + wgpu::VertexAttribute { + offset: wgpu::VertexFormat::Float32x2.size(), + format: wgpu::VertexFormat::Float32x2, + shader_location: 1, + }, + wgpu::VertexAttribute { + offset: 2 * wgpu::VertexFormat::Float32x2.size(), + format: wgpu::VertexFormat::Uint32, + shader_location: 2, + }, + ], + }, + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as u64, + step_mode: wgpu::VertexStepMode::Instance, + attributes: &[ + // color + wgpu::VertexAttribute { + offset: 0, + format: wgpu::VertexFormat::Float32x4, + shader_location: 3, + }, + // translate + wgpu::VertexAttribute { + offset: wgpu::VertexFormat::Float32x4.size(), + format: wgpu::VertexFormat::Float32x2, + shader_location: 4, + }, + ], + }, + ], ); pub const FRAGMENT: FragmentShaderState = FragmentShaderState::new( diff --git a/src/render/shaders/tile.vertex.wgsl b/src/render/shaders/tile.vertex.wgsl index 44dc9fd9..50d6cedb 100644 --- a/src/render/shaders/tile.vertex.wgsl +++ b/src/render/shaders/tile.vertex.wgsl @@ -15,12 +15,7 @@ struct TileUniform { pad2: i32; }; -struct Tiles { - tiles: [[stride(32)]] array; -}; - [[group(0), binding(0)]] var globals: GlobalsUniform; -[[group(0), binding(1)]] var tiles: Tiles; struct VertexOutput { [[location(0)]] v_color: vec4; @@ -32,14 +27,15 @@ fn main( [[location(0)]] position: vec2, [[location(1)]] normal: vec2, [[location(2)]] tile_id: u32, + [[location(3)]] color: vec4, + [[location(4)]] translate: vec2, [[builtin(instance_index)]] instance_idx: u32 // instance_index is used when we have multiple instances of the same "object" ) -> VertexOutput { - let tile = tiles.tiles[instance_idx]; let z = 0.0; - let world_pos = position + tile.translate + normal; + let world_pos = position + translate + normal; let position = globals.camera.view_proj * vec4(world_pos, z, 1.0); - return VertexOutput(tile.color, position); + return VertexOutput(color, position); } diff --git a/src/render/state.rs b/src/render/state.rs index 0115e7fe..55e85ab5 100644 --- a/src/render/state.rs +++ b/src/render/state.rs @@ -6,15 +6,13 @@ use std::ops::Range; use log::{trace, warn}; use lyon::tessellation::VertexBuffers; use wgpu::util::DeviceExt; -use wgpu::{Buffer, Limits, Queue}; +use wgpu::{Buffer, BufferAddress, Limits, Queue}; use winit::dpi::PhysicalSize; use winit::event::{ DeviceEvent, ElementState, KeyboardInput, MouseButton, TouchPhase, WindowEvent, }; use winit::window::Window; -use vector_tile::parse_tile_reader; - use crate::fps_meter::FPSMeter; use crate::io::cache::Cache; use crate::io::{static_database, TileCoords}; @@ -190,7 +188,7 @@ impl State { let tiles_uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor { label: Some("Tiles ubo"), size: tiles_uniform_buffer_size, - usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, mapped_at_creation: false, }); @@ -203,47 +201,27 @@ impl State { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: Some("Bind group layout"), - entries: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: wgpu::BufferSize::new(globals_buffer_byte_size), - }, - count: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: wgpu::BufferSize::new(globals_buffer_byte_size), }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStages::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: wgpu::BufferSize::new(tiles_uniform_buffer_size), - }, - count: None, - }, - ], + count: None, + }], }); let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { label: Some("Bind group"), layout: &bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Buffer( - globals_uniform_buffer.as_entire_buffer_binding(), - ), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Buffer( - tiles_uniform_buffer.as_entire_buffer_binding(), - ), - }, - ], + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Buffer( + globals_uniform_buffer.as_entire_buffer_binding(), + ), + }], }); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { @@ -327,7 +305,7 @@ impl State { sample_count, scene: SceneParams::new(), globals_uniform_buffer, - tiles_uniform_buffer: tiles_uniform_buffer, + tiles_uniform_buffer, fps_meter: FPSMeter::new(), tile_mask_instances, camera, @@ -507,16 +485,20 @@ impl State { .vertices() .slice(entry.vertices_buffer_range()), ); + let id = entry.id as BufferAddress; + pass.set_vertex_buffer( + 1, + self.tiles_uniform_buffer.slice( + std::mem::size_of::() as u64 * id + ..std::mem::size_of::() as u64 * (id + 1), + ), + ); /* if !self.tile_fill_range.is_empty() { pass.draw_indexed(self.tile_fill_range.clone(), 0, 0..1); }*/ trace!("current buffer_pool index {:?}", self.buffer_pool.index); // FIXME: Custom Instance index possibly breaks on Metal - pass.draw_indexed( - entry.indices_range(), - 0, - entry.id as u32..(entry.id + 1) as u32, - ); + pass.draw_indexed(entry.indices_range(), 0, 0..1); } } }