diff --git a/Cargo.toml b/Cargo.toml index f6cebaf56e..56f114173f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" # Modified to use std::any::type_name instead of std::any::TypeId legion = { path = "bevy_legion", features = ["serialize"] } wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "a7b0d5ae5bc0934439ef559ed145e93f0117c39a"} +bitflags = "1.0" glam = "0.8.6" winit = "0.22.0" zerocopy = "0.3" diff --git a/src/asset/mesh.rs b/src/asset/mesh.rs index eea89f8392..58c533a92c 100644 --- a/src/asset/mesh.rs +++ b/src/asset/mesh.rs @@ -1,6 +1,4 @@ use crate::{asset::Asset, math::*, render::Vertex}; -use wgpu::{Buffer, Device}; -use zerocopy::AsBytes; pub enum MeshType { Cube, @@ -18,26 +16,6 @@ pub enum MeshType { pub struct Mesh { pub vertices: Vec, pub indices: Vec, - - // TODO: remove me - pub vertex_buffer: Option, - pub index_buffer: Option, -} - -impl Mesh { - pub fn setup_buffers(&mut self, device: &Device) { - if let None = self.vertex_buffer { - self.vertex_buffer = Some( - device.create_buffer_with_data(self.vertices.as_bytes(), wgpu::BufferUsage::VERTEX), - ); - } - - if let None = self.index_buffer { - self.index_buffer = Some( - device.create_buffer_with_data(self.indices.as_bytes(), wgpu::BufferUsage::INDEX), - ); - } - } } impl Asset for Mesh { @@ -53,12 +31,7 @@ impl Asset for Mesh { } => create_quad(north_west, north_east, south_west, south_east), }; - Mesh { - vertices, - indices, - vertex_buffer: None, - index_buffer: None, - } + Mesh { vertices, indices } } } diff --git a/src/render/color.rs b/src/render/color.rs index 6e16f2f585..e3be1cc9d9 100644 --- a/src/render/color.rs +++ b/src/render/color.rs @@ -5,52 +5,74 @@ use crate::{ render::shader::ShaderDefSuffixProvider, }; use std::ops::Add; +use zerocopy::AsBytes; -#[derive(Debug, Default, Clone, Copy, PartialEq)] -pub struct Color(Vec4); +#[repr(C)] +#[derive(Debug, Default, Clone, Copy, PartialEq, AsBytes)] +pub struct Color { + pub r: f32, + pub g: f32, + pub b: f32, + pub a: f32, +} impl Color { pub fn rgb(r: f32, g: f32, b: f32) -> Color { - Color(Vec4::new(r, g, b, 1.0)) + Color { r, g, b, a: 1.0 } } pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Color { - Color(Vec4::new(r, g, b, a)) + Color { r, g, b, a } } } impl Add for Color { type Output = Color; fn add(self, rhs: Color) -> Self::Output { - Color(self.0 + rhs.0) + Color { + r: self.r + rhs.r, + g: self.g + rhs.g, + b: self.b + rhs.b, + a: self.a + rhs.a, + } } } impl Add for Color { type Output = Color; fn add(self, rhs: Vec4) -> Self::Output { - Color(self.0 + rhs) + Color { + r: self.r + rhs.x(), + g: self.g + rhs.y(), + b: self.b + rhs.z(), + a: self.a + rhs.w(), + } } } impl From for Color { fn from(vec4: Vec4) -> Self { - Color(vec4) + Color { + r: vec4.x(), + g: vec4.y(), + b: vec4.z(), + a: vec4.w(), + } } } impl Into<[f32; 4]> for Color { fn into(self) -> [f32; 4] { - self.0.into() + [self.r, self.g, self.b, self.a] } } impl GetBytes for Color { fn get_bytes(&self) -> Vec { - self.0.get_bytes() + self.as_bytes().iter().map(|v| *v).collect::>() } fn get_bytes_ref(&self) -> Option<&[u8]> { - self.0.get_bytes_ref() + Some(self.as_bytes()) } } diff --git a/src/render/draw_target/draw_targets/ui_draw_target.rs b/src/render/draw_target/draw_targets/ui_draw_target.rs index 3455d09248..cbbb460361 100644 --- a/src/render/draw_target/draw_targets/ui_draw_target.rs +++ b/src/render/draw_target/draw_targets/ui_draw_target.rs @@ -4,7 +4,7 @@ use crate::{ render::{ draw_target::DrawTarget, pipeline::PipelineDescriptor, - render_resource::{resource_name, RenderResource, ResourceInfo}, + render_resource::{resource_name, BufferUsage, RenderResource, ResourceInfo}, renderer::{RenderPass, Renderer}, }, }; @@ -85,14 +85,15 @@ impl DrawTarget for UiDrawTarget { { let mesh_storage = resources.get_mut::>().unwrap(); if let Some(mesh_asset) = mesh_storage.get_id(*mesh_id) { - self.mesh_vertex_buffer = Some(renderer.create_buffer_with_data( - mesh_asset.vertices.as_bytes(), - wgpu::BufferUsage::VERTEX, - )); - self.mesh_index_buffer = Some(renderer.create_buffer_with_data( - mesh_asset.indices.as_bytes(), - wgpu::BufferUsage::INDEX, - )); + self.mesh_vertex_buffer = + Some(renderer.create_buffer_with_data( + mesh_asset.vertices.as_bytes(), + BufferUsage::VERTEX, + )); + self.mesh_index_buffer = Some( + renderer + .create_buffer_with_data(mesh_asset.indices.as_bytes(), BufferUsage::INDEX), + ); self.mesh_index_length = mesh_asset.indices.len(); }; } diff --git a/src/render/pass/mod.rs b/src/render/pass/mod.rs index 06cae0c6bf..089526ef95 100644 --- a/src/render/pass/mod.rs +++ b/src/render/pass/mod.rs @@ -1,4 +1,6 @@ +mod ops; mod pass; pub mod passes; +pub use ops::*; pub use pass::*; diff --git a/src/render/pass/ops.rs b/src/render/pass/ops.rs new file mode 100644 index 0000000000..e70d7bd0d7 --- /dev/null +++ b/src/render/pass/ops.rs @@ -0,0 +1,13 @@ +#[repr(C)] +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub enum LoadOp { + Clear = 0, + Load = 1, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub enum StoreOp { + Clear = 0, + Store = 1, +} diff --git a/src/render/pass/pass.rs b/src/render/pass/pass.rs index ffc320093b..4c88a0fb24 100644 --- a/src/render/pass/pass.rs +++ b/src/render/pass/pass.rs @@ -1,3 +1,6 @@ +use super::{LoadOp, StoreOp}; +use crate::prelude::Color; + pub struct RenderPassColorAttachmentDescriptor { /// The actual color attachment. pub attachment: String, @@ -6,22 +9,22 @@ pub struct RenderPassColorAttachmentDescriptor { pub resolve_target: Option, /// The beginning-of-pass load operation for this color attachment. - pub load_op: wgpu::LoadOp, + pub load_op: LoadOp, /// The end-of-pass store operation for this color attachment. - pub store_op: wgpu::StoreOp, + pub store_op: StoreOp, /// The color that will be assigned to every pixel of this attachment when cleared. - pub clear_color: wgpu::Color, + pub clear_color: Color, } pub struct RenderPassDepthStencilAttachmentDescriptor { pub attachment: String, - pub depth_load_op: wgpu::LoadOp, - pub depth_store_op: wgpu::StoreOp, + pub depth_load_op: LoadOp, + pub depth_store_op: StoreOp, pub clear_depth: f32, - pub stencil_load_op: wgpu::LoadOp, - pub stencil_store_op: wgpu::StoreOp, + pub stencil_load_op: LoadOp, + pub stencil_store_op: StoreOp, pub clear_stencil: u32, } diff --git a/src/render/pass/passes/forward.rs b/src/render/pass/passes/forward.rs index b5b5b225cb..00922d82ed 100644 --- a/src/render/pass/passes/forward.rs +++ b/src/render/pass/passes/forward.rs @@ -1,11 +1,12 @@ use crate::render::{ pass::{ - PassDescriptor, RenderPassColorAttachmentDescriptor, - RenderPassDepthStencilAttachmentDescriptor, + LoadOp, PassDescriptor, RenderPassColorAttachmentDescriptor, + RenderPassDepthStencilAttachmentDescriptor, StoreOp, }, render_graph::RenderGraphBuilder, render_resource::{resource_name, resource_providers::FrameTextureResourceProvider}, texture::{TextureDescriptor, TextureDimension}, + Color, }; pub trait ForwardPassBuilder { @@ -36,21 +37,16 @@ impl ForwardPassBuilder for RenderGraphBuilder { color_attachments: vec![RenderPassColorAttachmentDescriptor { attachment: resource_name::texture::SWAP_CHAIN.to_string(), resolve_target: None, - load_op: wgpu::LoadOp::Clear, - store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color { - r: 0.3, - g: 0.4, - b: 0.5, - a: 1.0, - }, + load_op: LoadOp::Clear, + store_op: StoreOp::Store, + clear_color: Color::rgb(0.3, 0.4, 0.5), }], depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor { attachment: resource_name::texture::DEPTH.to_string(), - depth_load_op: wgpu::LoadOp::Clear, - depth_store_op: wgpu::StoreOp::Store, - stencil_load_op: wgpu::LoadOp::Clear, - stencil_store_op: wgpu::StoreOp::Store, + depth_load_op: LoadOp::Clear, + depth_store_op: StoreOp::Store, + stencil_load_op: LoadOp::Clear, + stencil_store_op: StoreOp::Store, clear_depth: 1.0, clear_stencil: 0, }), diff --git a/src/render/pipeline/mod.rs b/src/render/pipeline/mod.rs index 0f6bcb6bcf..0848591fc4 100644 --- a/src/render/pipeline/mod.rs +++ b/src/render/pipeline/mod.rs @@ -3,8 +3,10 @@ mod binding; mod pipeline; mod pipeline_layout; pub mod pipelines; +mod vertex_buffer_descriptor; pub use bind_group::*; pub use binding::*; pub use pipeline::*; pub use pipeline_layout::*; +pub use vertex_buffer_descriptor::*; diff --git a/src/render/pipeline/pipeline.rs b/src/render/pipeline/pipeline.rs index 3451a83868..068a13c9e1 100644 --- a/src/render/pipeline/pipeline.rs +++ b/src/render/pipeline/pipeline.rs @@ -1,4 +1,4 @@ -use super::{BindGroup, PipelineLayout}; +use super::{BindGroup, PipelineLayout, VertexBufferDescriptor}; use crate::{ asset::{AssetStorage, Handle}, render::{ @@ -8,23 +8,6 @@ use crate::{ }, }; -#[derive(Clone, Debug)] -pub struct VertexBufferDescriptor { - pub stride: wgpu::BufferAddress, - pub step_mode: wgpu::InputStepMode, - pub attributes: Vec, -} - -impl<'a> Into> for &'a VertexBufferDescriptor { - fn into(self) -> wgpu::VertexBufferDescriptor<'a> { - wgpu::VertexBufferDescriptor { - step_mode: self.step_mode, - stride: self.stride, - attributes: &self.attributes, - } - } -} - #[derive(Clone, Debug)] pub enum PipelineLayoutType { Manual(PipelineLayout), diff --git a/src/render/pipeline/pipelines/ui/mod.rs b/src/render/pipeline/pipelines/ui/mod.rs index cefa4a33b8..d120b9fc09 100644 --- a/src/render/pipeline/pipelines/ui/mod.rs +++ b/src/render/pipeline/pipelines/ui/mod.rs @@ -1,7 +1,10 @@ use crate::{ asset::AssetStorage, render::{ - pipeline::{PipelineDescriptor, VertexBufferDescriptor}, + pipeline::{ + InputStepMode, PipelineDescriptor, VertexAttributeDescriptor, VertexBufferDescriptor, + VertexFormat, + }, render_graph::RenderGraphBuilder, render_resource::{resource_name, resource_providers::RectData}, shader::{Shader, ShaderStage}, @@ -65,25 +68,25 @@ impl UiPipelineBuilder for RenderGraphBuilder { .add_vertex_buffer_descriptor(Vertex::get_vertex_buffer_descriptor()) .add_vertex_buffer_descriptor(VertexBufferDescriptor { stride: std::mem::size_of::() as u64, - step_mode: wgpu::InputStepMode::Instance, + step_mode: InputStepMode::Instance, attributes: vec![ - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float2, + VertexAttributeDescriptor { + format: VertexFormat::Float2, offset: 0, shader_location: 3, }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float2, + VertexAttributeDescriptor { + format: VertexFormat::Float2, offset: 2 * 4, shader_location: 4, }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float4, + VertexAttributeDescriptor { + format: VertexFormat::Float4, offset: 4 * 4, shader_location: 5, }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float, + VertexAttributeDescriptor { + format: VertexFormat::Float, offset: 8 * 4, shader_location: 6, }, diff --git a/src/render/pipeline/vertex_buffer_descriptor.rs b/src/render/pipeline/vertex_buffer_descriptor.rs new file mode 100644 index 0000000000..e134a47548 --- /dev/null +++ b/src/render/pipeline/vertex_buffer_descriptor.rs @@ -0,0 +1,53 @@ +#[derive(Clone, Debug)] +pub struct VertexBufferDescriptor { + pub stride: u64, + pub step_mode: InputStepMode, + pub attributes: Vec, +} + +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub enum VertexFormat { + Uchar2 = 1, + Uchar4 = 3, + Char2 = 5, + Char4 = 7, + Uchar2Norm = 9, + Uchar4Norm = 11, + Char2Norm = 14, + Char4Norm = 16, + Ushort2 = 18, + Ushort4 = 20, + Short2 = 22, + Short4 = 24, + Ushort2Norm = 26, + Ushort4Norm = 28, + Short2Norm = 30, + Short4Norm = 32, + Half2 = 34, + Half4 = 36, + Float = 37, + Float2 = 38, + Float3 = 39, + Float4 = 40, + Uint = 41, + Uint2 = 42, + Uint3 = 43, + Uint4 = 44, + Int = 45, + Int2 = 46, + Int3 = 47, + Int4 = 48, +} + +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub enum InputStepMode { + Vertex = 0, + Instance = 1, +} + +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub struct VertexAttributeDescriptor { + pub offset: u64, + pub format: VertexFormat, + pub shader_location: u32, +} diff --git a/src/render/render_resource/buffer.rs b/src/render/render_resource/buffer.rs new file mode 100644 index 0000000000..5a82a0cbfc --- /dev/null +++ b/src/render/render_resource/buffer.rs @@ -0,0 +1,27 @@ +bitflags::bitflags! { + #[repr(transparent)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct BufferUsage: u32 { + const MAP_READ = 1; + const MAP_WRITE = 2; + const COPY_SRC = 4; + const COPY_DST = 8; + const INDEX = 16; + const VERTEX = 32; + const UNIFORM = 64; + const STORAGE = 128; + const INDIRECT = 256; + const STORAGE_READ = 512; + const NONE = 0; + /// The combination of all read-only usages. + const READ_ALL = Self::MAP_READ.bits | Self::COPY_SRC.bits | + Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits | + Self::STORAGE_READ.bits | Self::INDIRECT.bits; + /// The combination of all write-only and read-write usages. + const WRITE_ALL = Self::MAP_WRITE.bits | Self::COPY_DST.bits | Self::STORAGE.bits; + /// The combination of all usages that the are guaranteed to be be ordered by the hardware. + /// If a usage is not ordered, then even if it doesn't change between draw calls, there + /// still need to be pipeline barriers inserted for synchronization. + const ORDERED = Self::READ_ALL.bits; + } +} diff --git a/src/render/render_resource/mod.rs b/src/render/render_resource/mod.rs index cb5b22e31c..a1f3699ed2 100644 --- a/src/render/render_resource/mod.rs +++ b/src/render/render_resource/mod.rs @@ -1,9 +1,11 @@ +mod buffer; mod render_resource; mod resource_info; pub mod resource_name; mod resource_provider; pub mod resource_providers; +pub use buffer::*; pub use render_resource::*; pub use resource_info::*; pub use resource_provider::*; diff --git a/src/render/render_resource/resource_providers/camera2d_resource_provider.rs b/src/render/render_resource/resource_providers/camera2d_resource_provider.rs index e6dd4367c8..bb998bdeef 100644 --- a/src/render/render_resource/resource_providers/camera2d_resource_provider.rs +++ b/src/render/render_resource/resource_providers/camera2d_resource_provider.rs @@ -1,5 +1,5 @@ use crate::render::{ - render_resource::{resource_name, RenderResource, ResourceProvider}, + render_resource::{resource_name, BufferUsage, RenderResource, ResourceProvider}, renderer::Renderer, ActiveCamera2d, Camera, }; @@ -21,7 +21,7 @@ impl ResourceProvider for Camera2dResourceProvider { ) { let buffer = renderer.create_buffer( std::mem::size_of::<[[f32; 4]; 4]>() as u64, - wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::UNIFORM, + BufferUsage::COPY_DST | BufferUsage::UNIFORM, ); renderer @@ -51,7 +51,7 @@ impl ResourceProvider for Camera2dResourceProvider { self.tmp_buffer = Some(renderer.create_buffer_mapped( matrix_size, - wgpu::BufferUsage::COPY_SRC, + BufferUsage::COPY_SRC, &mut |data| { data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes()); }, diff --git a/src/render/render_resource/resource_providers/camera_resource_provider.rs b/src/render/render_resource/resource_providers/camera_resource_provider.rs index 7c16fe05c0..bea0f9ea76 100644 --- a/src/render/render_resource/resource_providers/camera_resource_provider.rs +++ b/src/render/render_resource/resource_providers/camera_resource_provider.rs @@ -1,5 +1,5 @@ use crate::render::{ - render_resource::{resource_name, RenderResource, ResourceProvider}, + render_resource::{resource_name, BufferUsage, RenderResource, ResourceProvider}, renderer::Renderer, ActiveCamera, Camera, }; @@ -22,7 +22,7 @@ impl ResourceProvider for CameraResourceProvider { ) { let buffer = renderer.create_buffer( std::mem::size_of::<[[f32; 4]; 4]>() as u64, - wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::UNIFORM, + BufferUsage::COPY_DST | BufferUsage::UNIFORM, ); renderer @@ -55,7 +55,7 @@ impl ResourceProvider for CameraResourceProvider { self.tmp_buffer = Some(renderer.create_buffer_mapped( matrix_size, - wgpu::BufferUsage::COPY_SRC, + BufferUsage::COPY_SRC, &mut |data| { data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes()); }, diff --git a/src/render/render_resource/resource_providers/light_resource_provider.rs b/src/render/render_resource/resource_providers/light_resource_provider.rs index 1add2fd486..c8543f099c 100644 --- a/src/render/render_resource/resource_providers/light_resource_provider.rs +++ b/src/render/render_resource/resource_providers/light_resource_provider.rs @@ -1,5 +1,5 @@ use crate::render::{ - render_resource::{resource_name, RenderResource, ResourceProvider}, + render_resource::{resource_name, BufferUsage, RenderResource, ResourceProvider}, renderer::Renderer, Light, LightRaw, }; @@ -46,7 +46,7 @@ impl ResourceProvider for LightResourceProvider { let buffer = renderer.create_buffer( light_uniform_size, - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::COPY_DST, + BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST, ); renderer .get_render_resources_mut() @@ -78,7 +78,7 @@ impl ResourceProvider for LightResourceProvider { self.tmp_light_buffer = Some(renderer.create_buffer_mapped( total_size, - wgpu::BufferUsage::COPY_SRC, + BufferUsage::COPY_SRC, &mut |data| { for ((light, local_to_world, translation), slot) in light_query.iter(world).zip(data.chunks_exact_mut(size)) @@ -91,7 +91,7 @@ impl ResourceProvider for LightResourceProvider { )); self.tmp_count_buffer = Some(renderer.create_buffer_mapped( light_count_size, - wgpu::BufferUsage::COPY_SRC, + BufferUsage::COPY_SRC, &mut |data| { data.copy_from_slice([light_count as u32, 0, 0, 0].as_bytes()); }, diff --git a/src/render/render_resource/resource_providers/mesh_resource_provider.rs b/src/render/render_resource/resource_providers/mesh_resource_provider.rs index 6a14dfc18e..7cb2fbe24a 100644 --- a/src/render/render_resource/resource_providers/mesh_resource_provider.rs +++ b/src/render/render_resource/resource_providers/mesh_resource_provider.rs @@ -1,7 +1,10 @@ use crate::{ asset::{AssetStorage, Handle, Mesh}, prelude::Renderable, - render::{render_resource::ResourceProvider, renderer::Renderer}, + render::{ + render_resource::{BufferUsage, ResourceProvider}, + renderer::Renderer, + }, }; use legion::{filter::*, prelude::*}; use zerocopy::AsBytes; @@ -51,14 +54,10 @@ impl ResourceProvider for MeshResourceProvider { .get_mesh_vertices_resource(*mesh_handle) { let mesh_asset = mesh_storage.get(&mesh_handle).unwrap(); - let vertex_buffer = renderer.create_buffer_with_data( - mesh_asset.vertices.as_bytes(), - wgpu::BufferUsage::VERTEX, - ); - let index_buffer = renderer.create_buffer_with_data( - mesh_asset.indices.as_bytes(), - wgpu::BufferUsage::INDEX, - ); + let vertex_buffer = renderer + .create_buffer_with_data(mesh_asset.vertices.as_bytes(), BufferUsage::VERTEX); + let index_buffer = renderer + .create_buffer_with_data(mesh_asset.indices.as_bytes(), BufferUsage::INDEX); let render_resources = renderer.get_render_resources_mut(); render_resources.set_mesh_vertices_resource(*mesh_handle, vertex_buffer); diff --git a/src/render/render_resource/resource_providers/ui_resource_provider.rs b/src/render/render_resource/resource_providers/ui_resource_provider.rs index 2d6fa1fb96..6042c798b9 100644 --- a/src/render/render_resource/resource_providers/ui_resource_provider.rs +++ b/src/render/render_resource/resource_providers/ui_resource_provider.rs @@ -3,7 +3,7 @@ use crate::{ ecs, math, prelude::Node, render::{ - render_resource::{resource_name, RenderResource, ResourceProvider}, + render_resource::{resource_name, BufferUsage, RenderResource, ResourceProvider}, renderer::Renderer, }, }; @@ -82,7 +82,7 @@ impl UiResourceProvider { data.as_bytes(), size, data.len(), - wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::VERTEX, + BufferUsage::COPY_SRC | BufferUsage::VERTEX, ); renderer diff --git a/src/render/render_resource/resource_providers/uniform_resource_provider.rs b/src/render/render_resource/resource_providers/uniform_resource_provider.rs index 889f958d81..4a5dd431d9 100644 --- a/src/render/render_resource/resource_providers/uniform_resource_provider.rs +++ b/src/render/render_resource/resource_providers/uniform_resource_provider.rs @@ -2,7 +2,7 @@ use crate::{ asset::{AssetStorage, Texture}, render::{ pipeline::BindType, - render_resource::{RenderResource, ResourceProvider}, + render_resource::{BufferUsage, RenderResource, ResourceProvider}, renderer::Renderer, shader::{AsUniforms, DynamicUniformBufferInfo, UniformInfoIter}, texture::{SamplerDescriptor, TextureDescriptor}, @@ -151,10 +151,8 @@ where // allocate enough space for twice as many entities as there are currently; let capacity = count * 2; let size = wgpu::BIND_BUFFER_ALIGNMENT * capacity; - let created_resource = renderer.create_buffer( - size, - wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::UNIFORM, - ); + let created_resource = + renderer.create_buffer(size, BufferUsage::COPY_DST | BufferUsage::UNIFORM); let mut info = DynamicUniformBufferInfo::new(); info.count = count; @@ -193,7 +191,7 @@ where let mapped_buffer_resource = renderer.create_buffer_mapped( size as usize, - wgpu::BufferUsage::COPY_SRC, + BufferUsage::COPY_SRC, &mut |mapped| { let alignment = wgpu::BIND_BUFFER_ALIGNMENT as usize; let mut offset = 0usize; diff --git a/src/render/renderer/renderer.rs b/src/render/renderer/renderer.rs index 7505247adb..a74ca45d7d 100644 --- a/src/render/renderer/renderer.rs +++ b/src/render/renderer/renderer.rs @@ -3,7 +3,7 @@ use crate::{ render::{ pipeline::PipelineDescriptor, render_graph::RenderGraph, - render_resource::{RenderResource, RenderResources, ResourceInfo}, + render_resource::{BufferUsage, RenderResource, RenderResources, ResourceInfo}, shader::DynamicUniformBufferInfo, texture::{SamplerDescriptor, TextureDescriptor}, }, @@ -31,12 +31,8 @@ pub trait Renderer { world: &mut World, resources: &mut Resources, ); - // TODO: swap out wgpu::BufferUsage for non-wgpu type - fn create_buffer_with_data( - &mut self, - data: &[u8], - buffer_usage: wgpu::BufferUsage, - ) -> RenderResource; + fn create_buffer_with_data(&mut self, data: &[u8], buffer_usage: BufferUsage) + -> RenderResource; fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource; fn create_texture( &mut self, @@ -57,13 +53,13 @@ pub trait Renderer { resource: RenderResource, info: DynamicUniformBufferInfo, ); - fn create_buffer(&mut self, size: u64, buffer_usage: wgpu::BufferUsage) -> RenderResource; + fn create_buffer(&mut self, size: u64, buffer_usage: BufferUsage) -> RenderResource; fn create_instance_buffer( &mut self, mesh_id: usize, size: usize, count: usize, - buffer_usage: wgpu::BufferUsage, + buffer_usage: BufferUsage, ) -> RenderResource; fn create_instance_buffer_with_data( &mut self, @@ -71,12 +67,12 @@ pub trait Renderer { data: &[u8], size: usize, count: usize, - buffer_usage: wgpu::BufferUsage, + buffer_usage: BufferUsage, ) -> RenderResource; fn create_buffer_mapped( &mut self, size: usize, - buffer_usage: wgpu::BufferUsage, + buffer_usage: BufferUsage, func: &mut dyn FnMut(&mut [u8]), ) -> RenderResource; fn remove_buffer(&mut self, resource: RenderResource); diff --git a/src/render/renderer/renderers/wgpu_renderer/mod.rs b/src/render/renderer/renderers/wgpu_renderer/mod.rs index 141ea54a57..a4ed42cd63 100644 --- a/src/render/renderer/renderers/wgpu_renderer/mod.rs +++ b/src/render/renderer/renderers/wgpu_renderer/mod.rs @@ -1,6 +1,7 @@ mod wgpu_render_pass; mod wgpu_renderer; mod wgpu_resources; +mod wgpu_type_converter; pub use wgpu_render_pass::*; pub use wgpu_renderer::*; diff --git a/src/render/renderer/renderers/wgpu_renderer/wgpu_renderer.rs b/src/render/renderer/renderers/wgpu_renderer/wgpu_renderer.rs index 0d2e888a0a..c2bb4b3b88 100644 --- a/src/render/renderer/renderers/wgpu_renderer/wgpu_renderer.rs +++ b/src/render/renderer/renderers/wgpu_renderer/wgpu_renderer.rs @@ -1,4 +1,4 @@ -use super::{WgpuRenderPass, WgpuResources}; +use super::{wgpu_type_converter::OwnedWgpuVertexBufferDescriptor, WgpuRenderPass, WgpuResources}; use crate::{ asset::{AssetStorage, Handle}, legion::prelude::*, @@ -9,7 +9,9 @@ use crate::{ }, pipeline::{BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType}, render_graph::RenderGraph, - render_resource::{resource_name, RenderResource, RenderResources, ResourceInfo}, + render_resource::{ + resource_name, BufferUsage, RenderResource, RenderResources, ResourceInfo, + }, renderer::Renderer, shader::{DynamicUniformBufferInfo, Shader}, texture::{SamplerDescriptor, TextureDescriptor}, @@ -159,6 +161,12 @@ impl WgpuRenderer { bind_group_layouts: bind_group_layouts.as_slice(), }); + let owned_vertex_buffer_descriptors = pipeline_descriptor + .vertex_buffer_descriptors + .iter() + .map(|v| v.into()) + .collect::>(); + let mut render_pipeline_descriptor = wgpu::RenderPipelineDescriptor { layout: &pipeline_layout, vertex_stage: wgpu::ProgrammableStageDescriptor { @@ -177,8 +185,7 @@ impl WgpuRenderer { color_states: &pipeline_descriptor.color_states, depth_stencil_state: pipeline_descriptor.depth_stencil_state.clone(), index_format: pipeline_descriptor.index_format, - vertex_buffers: &pipeline_descriptor - .vertex_buffer_descriptors + vertex_buffers: &owned_vertex_buffer_descriptors .iter() .map(|v| v.into()) .collect::>(), @@ -247,9 +254,9 @@ impl WgpuRenderer { }; wgpu::RenderPassColorAttachmentDescriptor { - store_op: color_attachment_descriptor.store_op, - load_op: color_attachment_descriptor.load_op, - clear_color: color_attachment_descriptor.clear_color, + store_op: color_attachment_descriptor.store_op.into(), + load_op: color_attachment_descriptor.load_op.into(), + clear_color: color_attachment_descriptor.clear_color.into(), attachment, resolve_target, } @@ -280,10 +287,10 @@ impl WgpuRenderer { attachment, clear_depth: depth_stencil_attachment_descriptor.clear_depth, clear_stencil: depth_stencil_attachment_descriptor.clear_stencil, - depth_load_op: depth_stencil_attachment_descriptor.depth_load_op, - depth_store_op: depth_stencil_attachment_descriptor.depth_store_op, - stencil_load_op: depth_stencil_attachment_descriptor.stencil_load_op, - stencil_store_op: depth_stencil_attachment_descriptor.stencil_store_op, + depth_load_op: depth_stencil_attachment_descriptor.depth_load_op.into(), + depth_store_op: depth_stencil_attachment_descriptor.depth_store_op.into(), + stencil_load_op: depth_stencil_attachment_descriptor.stencil_load_op.into(), + stencil_store_op: depth_stencil_attachment_descriptor.stencil_store_op.into(), } } @@ -500,15 +507,15 @@ impl Renderer for WgpuRenderer { fn create_buffer_with_data( &mut self, data: &[u8], - buffer_usage: wgpu::BufferUsage, + buffer_usage: BufferUsage, ) -> RenderResource { self.wgpu_resources - .create_buffer_with_data(&self.device, data, buffer_usage) + .create_buffer_with_data(&self.device, data, buffer_usage.into()) } - fn create_buffer(&mut self, size: u64, buffer_usage: wgpu::BufferUsage) -> RenderResource { + fn create_buffer(&mut self, size: u64, buffer_usage: BufferUsage) -> RenderResource { self.wgpu_resources - .create_buffer(&self.device, size, buffer_usage) + .create_buffer(&self.device, size, buffer_usage.into()) } fn create_instance_buffer( @@ -516,10 +523,15 @@ impl Renderer for WgpuRenderer { mesh_id: usize, size: usize, count: usize, - buffer_usage: wgpu::BufferUsage, + buffer_usage: BufferUsage, ) -> RenderResource { - self.wgpu_resources - .create_instance_buffer(&self.device, mesh_id, size, count, buffer_usage) + self.wgpu_resources.create_instance_buffer( + &self.device, + mesh_id, + size, + count, + buffer_usage.into(), + ) } fn create_instance_buffer_with_data( @@ -528,7 +540,7 @@ impl Renderer for WgpuRenderer { data: &[u8], size: usize, count: usize, - buffer_usage: wgpu::BufferUsage, + buffer_usage: BufferUsage, ) -> RenderResource { self.wgpu_resources.create_instance_buffer_with_data( &self.device, @@ -536,7 +548,7 @@ impl Renderer for WgpuRenderer { data, size, count, - buffer_usage, + buffer_usage.into(), ) } @@ -551,11 +563,15 @@ impl Renderer for WgpuRenderer { fn create_buffer_mapped( &mut self, size: usize, - buffer_usage: wgpu::BufferUsage, + buffer_usage: BufferUsage, setup_data: &mut dyn FnMut(&mut [u8]), ) -> RenderResource { - self.wgpu_resources - .create_buffer_mapped(&self.device, size, buffer_usage, setup_data) + self.wgpu_resources.create_buffer_mapped( + &self.device, + size, + buffer_usage.into(), + setup_data, + ) } fn copy_buffer_to_buffer( diff --git a/src/render/renderer/renderers/wgpu_renderer/wgpu_type_converter.rs b/src/render/renderer/renderers/wgpu_renderer/wgpu_type_converter.rs new file mode 100644 index 0000000000..c317d0e427 --- /dev/null +++ b/src/render/renderer/renderers/wgpu_renderer/wgpu_type_converter.rs @@ -0,0 +1,133 @@ +use crate::{ + prelude::Color, + render::{ + pass::{LoadOp, StoreOp}, + pipeline::{ + InputStepMode, VertexAttributeDescriptor, VertexBufferDescriptor, VertexFormat, + }, + render_resource::BufferUsage, + }, +}; + +impl From for wgpu::VertexFormat { + fn from(val: VertexFormat) -> Self { + match val { + VertexFormat::Uchar2 => wgpu::VertexFormat::Uchar2, + VertexFormat::Uchar4 => wgpu::VertexFormat::Uchar4, + VertexFormat::Char2 => wgpu::VertexFormat::Char2, + VertexFormat::Char4 => wgpu::VertexFormat::Char4, + VertexFormat::Uchar2Norm => wgpu::VertexFormat::Uchar2Norm, + VertexFormat::Uchar4Norm => wgpu::VertexFormat::Uchar4Norm, + VertexFormat::Char2Norm => wgpu::VertexFormat::Char2Norm, + VertexFormat::Char4Norm => wgpu::VertexFormat::Char4Norm, + VertexFormat::Ushort2 => wgpu::VertexFormat::Ushort2, + VertexFormat::Ushort4 => wgpu::VertexFormat::Ushort4, + VertexFormat::Short2 => wgpu::VertexFormat::Short2, + VertexFormat::Short4 => wgpu::VertexFormat::Short4, + VertexFormat::Ushort2Norm => wgpu::VertexFormat::Ushort2Norm, + VertexFormat::Ushort4Norm => wgpu::VertexFormat::Ushort4Norm, + VertexFormat::Short2Norm => wgpu::VertexFormat::Short2Norm, + VertexFormat::Short4Norm => wgpu::VertexFormat::Short4Norm, + VertexFormat::Half2 => wgpu::VertexFormat::Half2, + VertexFormat::Half4 => wgpu::VertexFormat::Half4, + VertexFormat::Float => wgpu::VertexFormat::Float, + VertexFormat::Float2 => wgpu::VertexFormat::Float2, + VertexFormat::Float3 => wgpu::VertexFormat::Float3, + VertexFormat::Float4 => wgpu::VertexFormat::Float4, + VertexFormat::Uint => wgpu::VertexFormat::Uint, + VertexFormat::Uint2 => wgpu::VertexFormat::Uint2, + VertexFormat::Uint3 => wgpu::VertexFormat::Uint3, + VertexFormat::Uint4 => wgpu::VertexFormat::Uint4, + VertexFormat::Int => wgpu::VertexFormat::Int, + VertexFormat::Int2 => wgpu::VertexFormat::Int2, + VertexFormat::Int3 => wgpu::VertexFormat::Int3, + VertexFormat::Int4 => wgpu::VertexFormat::Int4, + } + } +} + +impl From<&VertexAttributeDescriptor> for wgpu::VertexAttributeDescriptor { + fn from(val: &VertexAttributeDescriptor) -> Self { + wgpu::VertexAttributeDescriptor { + format: val.format.into(), + offset: val.offset, + shader_location: val.shader_location, + } + } +} + +impl From for wgpu::InputStepMode { + fn from(val: InputStepMode) -> Self { + match val { + InputStepMode::Vertex => wgpu::InputStepMode::Vertex, + InputStepMode::Instance => wgpu::InputStepMode::Instance, + } + } +} + +#[derive(Clone, Debug)] +pub struct OwnedWgpuVertexBufferDescriptor { + pub stride: wgpu::BufferAddress, + pub step_mode: wgpu::InputStepMode, + pub attributes: Vec, +} + +impl From<&VertexBufferDescriptor> for OwnedWgpuVertexBufferDescriptor { + fn from(val: &VertexBufferDescriptor) -> OwnedWgpuVertexBufferDescriptor { + let attributes = val + .attributes + .iter() + .map(|a| a.into()) + .collect::>(); + OwnedWgpuVertexBufferDescriptor { + step_mode: val.step_mode.into(), + stride: val.stride, + attributes, + } + } +} + +impl<'a> From<&'a OwnedWgpuVertexBufferDescriptor> for wgpu::VertexBufferDescriptor<'a> { + fn from(val: &'a OwnedWgpuVertexBufferDescriptor) -> Self { + wgpu::VertexBufferDescriptor { + attributes: &val.attributes, + step_mode: val.step_mode, + stride: val.stride, + } + } +} + +impl From for wgpu::Color { + fn from(color: Color) -> Self { + wgpu::Color { + r: color.r as f64, + g: color.g as f64, + b: color.b as f64, + a: color.a as f64, + } + } +} + +impl From for wgpu::BufferUsage { + fn from(val: BufferUsage) -> Self { + wgpu::BufferUsage::from_bits(val.bits()).unwrap() + } +} + +impl From for wgpu::LoadOp { + fn from(val: LoadOp) -> Self { + match val { + LoadOp::Clear => wgpu::LoadOp::Clear, + LoadOp::Load => wgpu::LoadOp::Load, + } + } +} + +impl From for wgpu::StoreOp { + fn from(val: StoreOp) -> Self { + match val { + StoreOp::Clear => wgpu::StoreOp::Clear, + StoreOp::Store => wgpu::StoreOp::Store, + } + } +} diff --git a/src/render/vertex.rs b/src/render/vertex.rs index 0c7d194b89..32e0fb31a1 100644 --- a/src/render/vertex.rs +++ b/src/render/vertex.rs @@ -1,4 +1,5 @@ -use super::pipeline::VertexBufferDescriptor; +use super::pipeline::{InputStepMode, VertexBufferDescriptor, VertexFormat}; +use crate::render::pipeline::VertexAttributeDescriptor; use std::convert::From; use zerocopy::{AsBytes, FromBytes}; @@ -11,24 +12,23 @@ pub struct Vertex { } impl Vertex { - // TODO: generate from macro pub fn get_vertex_buffer_descriptor() -> VertexBufferDescriptor { VertexBufferDescriptor { stride: std::mem::size_of::() as u64, - step_mode: wgpu::InputStepMode::Vertex, + step_mode: InputStepMode::Vertex, attributes: vec![ - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float4, + VertexAttributeDescriptor { + format: VertexFormat::Float4, offset: 0, shader_location: 0, }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float4, + VertexAttributeDescriptor { + format: VertexFormat::Float4, offset: 4 * 4, shader_location: 1, }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float2, + VertexAttributeDescriptor { + format: VertexFormat::Float2, offset: 8 * 4, shader_location: 2, },