upgrade wgpu. work around new wgpu lifetimes (this was painful)

This commit is contained in:
Carter Anderson 2020-03-05 00:44:53 -08:00
parent 8beed27c0e
commit 85c880e754
13 changed files with 220 additions and 190 deletions

View file

@ -7,7 +7,7 @@ edition = "2018"
[dependencies]
# Modified to use std::any::type_name instead of std::any::TypeId
legion = { path = "bevy_legion", features = ["serde-1"] }
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "4a0da16fe6764c4e1dc918a31cbd7467d404df51"}
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "2374b8ec9ddbc058dd0237856fc30d33e6ff8f93"}
glam = "0.8.4"
winit = "0.21.0"
zerocopy = "0.2"

View file

@ -150,6 +150,7 @@ impl AppBuilder {
.add_resource_provider(Box::new(Camera2dResourceProvider::default()))
.add_resource_provider(Box::new(LightResourceProvider::new(10)))
.add_resource_provider(Box::new(UiResourceProvider::new()))
.add_resource_provider(Box::new(MeshResourceProvider::new()))
.add_resource_provider(Box::new(UniformResourceProvider::<StandardMaterial>::new()))
.add_resource_provider(Box::new(UniformResourceProvider::<LocalToWorld>::new()))
.add_forward_pass()

View file

@ -1,25 +1,20 @@
use crate::{
asset::{AssetStorage, Handle, Mesh},
asset::{Handle, Mesh},
legion::prelude::*,
render::render_graph::{PipelineDescriptor, RenderPass, Renderable, ShaderPipelineAssignments},
render::render_graph::{PipelineDescriptor, RenderPass, Renderable, ShaderPipelineAssignments, ResourceInfo},
};
use zerocopy::AsBytes;
pub fn assigned_meshes_draw_target(
world: &World,
render_pass: &mut dyn RenderPass,
pipeline_handle: Handle<PipelineDescriptor>,
) {
let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
let shader_pipeline_assignments = world
.resources
.get_mut::<ShaderPipelineAssignments>()
.unwrap();
let mut current_mesh_id = None;
let mut current_mesh_vertex_buffer = None;
let mut current_mesh_index_buffer = None;
let mut current_mesh_index_length = 0;
let mut current_mesh_handle = None;
let mut current_mesh_index_len = 0;
let assigned_entities = shader_pipeline_assignments
.assignments
@ -29,56 +24,30 @@ pub fn assigned_meshes_draw_target(
for entity in assigned_entities.iter() {
// TODO: hopefully legion has better random access apis that are more like queries?
let renderable = world.get_component::<Renderable>(*entity).unwrap();
let mesh = world.get_component::<Handle<Mesh>>(*entity).unwrap();
let mesh = *world.get_component::<Handle<Mesh>>(*entity).unwrap();
if !renderable.is_visible {
continue;
}
let mut should_load_mesh = current_mesh_id == None;
if let Some(current) = current_mesh_id {
should_load_mesh = current != mesh.id;
}
if should_load_mesh {
if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
let renderer = render_pass.get_renderer();
if let Some(buffer) = current_mesh_vertex_buffer {
renderer.remove_buffer(buffer);
let renderer = render_pass.get_renderer();
let render_resources = renderer.get_render_resources();
if current_mesh_handle != Some(mesh) {
if let Some(vertex_buffer_resource) = render_resources.get_mesh_vertices_resource(mesh) {
let index_buffer_resource = render_resources.get_mesh_indices_resource(mesh).unwrap();
match renderer.get_resource_info(index_buffer_resource).unwrap() {
ResourceInfo::Buffer { size, ..} => current_mesh_index_len = (size / 2) as u32,
_ => panic!("expected a buffer type"),
}
if let Some(buffer) = current_mesh_index_buffer {
renderer.remove_buffer(buffer);
}
current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
mesh_asset.vertices.as_bytes(),
wgpu::BufferUsage::VERTEX,
));
current_mesh_index_buffer = Some(renderer.create_buffer_with_data(
mesh_asset.indices.as_bytes(),
wgpu::BufferUsage::INDEX,
));
// TODO: Verify buffer format matches render pass
render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0);
render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0);
current_mesh_id = Some(mesh.id);
current_mesh_index_length = mesh_asset.indices.len() as u32;
};
render_pass.set_index_buffer(index_buffer_resource, 0);
render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0);
}
// TODO: Verify buffer format matches render pass
current_mesh_handle = Some(mesh);
}
// TODO: validate bind group properties against shader uniform properties at least once
render_pass.setup_bind_groups(Some(&entity));
render_pass.draw_indexed(0..current_mesh_index_length, 0, 0..1);
}
// cleanup buffers
let renderer = render_pass.get_renderer();
if let Some(buffer) = current_mesh_vertex_buffer {
renderer.remove_buffer(buffer);
}
if let Some(buffer) = current_mesh_index_buffer {
renderer.remove_buffer(buffer);
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
}
}
}

View file

@ -1,24 +1,19 @@
use crate::{
asset::{AssetStorage, Handle, Mesh},
asset::{Handle, Mesh},
legion::prelude::*,
render::{
render_graph::{PipelineDescriptor, RenderPass, Renderable},
render_graph::{PipelineDescriptor, RenderPass, Renderable, ResourceInfo},
Instanced,
},
};
use zerocopy::AsBytes;
pub fn meshes_draw_target(
world: &World,
render_pass: &mut dyn RenderPass,
_pipeline_handle: Handle<PipelineDescriptor>,
) {
let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
let mut current_mesh_id = None;
let mut current_mesh_vertex_buffer = None;
let mut current_mesh_index_buffer = None;
let mut current_mesh_index_length = 0;
let mut current_mesh_handle = None;
let mut current_mesh_index_len = 0;
let mesh_query =
<(Read<Handle<Mesh>>, Read<Renderable>)>::query().filter(!component::<Instanced>());
@ -27,51 +22,26 @@ pub fn meshes_draw_target(
continue;
}
let mut should_load_mesh = current_mesh_id == None;
if let Some(current) = current_mesh_id {
should_load_mesh = current != mesh.id;
}
if should_load_mesh {
if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
let renderer = render_pass.get_renderer();
if let Some(buffer) = current_mesh_vertex_buffer {
renderer.remove_buffer(buffer);
let renderer = render_pass.get_renderer();
let render_resources = renderer.get_render_resources();
if current_mesh_handle != Some(*mesh) {
if let Some(vertex_buffer_resource) = render_resources.get_mesh_vertices_resource(*mesh)
{
let index_buffer_resource =
render_resources.get_mesh_indices_resource(*mesh).unwrap();
match renderer.get_resource_info(index_buffer_resource).unwrap() {
ResourceInfo::Buffer { size, .. } => current_mesh_index_len = (size / 2) as u32,
_ => panic!("expected a buffer type"),
}
if let Some(buffer) = current_mesh_index_buffer {
renderer.remove_buffer(buffer);
}
current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
mesh_asset.vertices.as_bytes(),
wgpu::BufferUsage::VERTEX,
));
current_mesh_index_buffer = Some(renderer.create_buffer_with_data(
mesh_asset.indices.as_bytes(),
wgpu::BufferUsage::INDEX,
));
// TODO: Verify buffer format matches render pass
render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0);
render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0);
current_mesh_id = Some(mesh.id);
current_mesh_index_length = mesh_asset.indices.len() as u32;
};
render_pass.set_index_buffer(index_buffer_resource, 0);
render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0);
}
// TODO: Verify buffer format matches render pass
current_mesh_handle = Some(*mesh);
}
// TODO: validate bind group properties against shader uniform properties at least once
render_pass.setup_bind_groups(Some(&entity));
render_pass.draw_indexed(0..current_mesh_index_length, 0, 0..1);
}
// cleanup buffers
let renderer = render_pass.get_renderer();
if let Some(buffer) = current_mesh_vertex_buffer {
renderer.remove_buffer(buffer);
}
if let Some(buffer) = current_mesh_index_buffer {
renderer.remove_buffer(buffer);
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
}
}

View file

@ -11,66 +11,67 @@ pub fn ui_draw_target(
render_pass: &mut dyn RenderPass,
_pipeline_handle: Handle<PipelineDescriptor>,
) {
let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
let mut current_mesh_vertex_buffer = None;
let mut current_mesh_index_buffer = None;
let ui_instances_buffer = {
let renderer = render_pass.get_renderer();
match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) {
Some(buffer) => buffer,
None => return,
}
};
// NOTE: this is ugly and borrowing is stupid
let result = {
let renderer = render_pass.get_renderer();
let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) =
renderer.get_resource_info(ui_instances_buffer)
{
Some((*count, *mesh_id))
} else {
None
};
// TODO: re-add support for this
// let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
// let mut current_mesh_vertex_buffer = None;
// let mut current_mesh_index_buffer = None;
// let ui_instances_buffer = {
// let renderer = render_pass.get_renderer();
// match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) {
// Some(buffer) => buffer,
// None => return,
// }
// };
// // NOTE: this is ugly and borrowing is stupid
// let result = {
// let renderer = render_pass.get_renderer();
// let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) =
// renderer.get_resource_info(ui_instances_buffer)
// {
// Some((*count, *mesh_id))
// } else {
// None
// };
if let Some((instance_count, mesh_id)) = result {
if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) {
if let Some(buffer) = current_mesh_vertex_buffer {
renderer.remove_buffer(buffer);
}
// if let Some((instance_count, mesh_id)) = result {
// if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) {
// if let Some(buffer) = current_mesh_vertex_buffer {
// renderer.remove_buffer(buffer);
// }
if let Some(buffer) = current_mesh_index_buffer {
renderer.remove_buffer(buffer);
}
current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
mesh_asset.vertices.as_bytes(),
wgpu::BufferUsage::VERTEX,
));
current_mesh_index_buffer = Some(renderer.create_buffer_with_data(
mesh_asset.indices.as_bytes(),
wgpu::BufferUsage::INDEX,
));
Some((instance_count, mesh_asset.indices.len()))
} else {
None
}
} else {
None
}
};
if let Some((instance_count, indices_length)) = result {
render_pass.setup_bind_groups(None);
render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0);
render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0);
render_pass.set_vertex_buffer(1, ui_instances_buffer, 0);
render_pass.draw_indexed(0..indices_length as u32, 0, 0..(instance_count as u32));
}
// if let Some(buffer) = current_mesh_index_buffer {
// renderer.remove_buffer(buffer);
// }
// current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
// mesh_asset.vertices.as_bytes(),
// wgpu::BufferUsage::VERTEX,
// ));
// current_mesh_index_buffer = Some(renderer.create_buffer_with_data(
// mesh_asset.indices.as_bytes(),
// wgpu::BufferUsage::INDEX,
// ));
// Some((instance_count, mesh_asset.indices.len()))
// } else {
// None
// }
// } else {
// None
// }
// };
// if let Some((instance_count, indices_length)) = result {
// render_pass.setup_bind_groups(None);
// render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0);
// render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0);
// render_pass.set_vertex_buffer(1, ui_instances_buffer, 0);
// render_pass.draw_indexed(0..indices_length as u32, 0, 0..(instance_count as u32));
// }
let renderer = render_pass.get_renderer();
if let Some(buffer) = current_mesh_vertex_buffer {
renderer.remove_buffer(buffer);
}
// let renderer = render_pass.get_renderer();
// if let Some(buffer) = current_mesh_vertex_buffer {
// renderer.remove_buffer(buffer);
// }
if let Some(buffer) = current_mesh_index_buffer {
renderer.remove_buffer(buffer);
}
// if let Some(buffer) = current_mesh_index_buffer {
// renderer.remove_buffer(buffer);
// }
}

View file

@ -1,4 +1,4 @@
use crate::asset::{Handle, Texture};
use crate::asset::{Handle, Texture, Mesh};
use std::collections::HashMap;
#[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)]
@ -11,6 +11,8 @@ pub struct RenderResources {
pub name_to_resource: HashMap<String, RenderResource>,
pub texture_to_resource: HashMap<Handle<Texture>, RenderResource>,
pub texture_to_sampler_resource: HashMap<Handle<Texture>, RenderResource>,
pub mesh_to_vertices_resource: HashMap<Handle<Mesh>, RenderResource>,
pub mesh_to_indices_resource: HashMap<Handle<Mesh>, RenderResource>,
pub resource_index: u64,
}
@ -31,6 +33,22 @@ impl RenderResources {
self.texture_to_resource.get(&texture).cloned()
}
pub fn set_mesh_vertices_resource(&mut self, mesh: Handle<Mesh>, resource: RenderResource) {
self.mesh_to_vertices_resource.insert(mesh, resource);
}
pub fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
self.mesh_to_vertices_resource.get(&mesh).cloned()
}
pub fn set_mesh_indices_resource(&mut self, mesh: Handle<Mesh>, resource: RenderResource) {
self.mesh_to_indices_resource.insert(mesh, resource);
}
pub fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
self.mesh_to_indices_resource.get(&mesh).cloned()
}
pub fn set_texture_sampler_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) {
self.texture_to_sampler_resource.insert(texture, resource);
}

View file

@ -86,7 +86,7 @@ pub trait Renderer {
pub trait RenderPass {
// TODO: consider using static dispatch for the renderer: Renderer<WgpuBackend>. compare compile times
fn get_renderer(&mut self) -> &mut dyn Renderer;
fn get_renderer(&mut self) -> &dyn Renderer;
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor;
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64);

View file

@ -18,7 +18,6 @@ pub struct WgpuResources {
pub buffers: HashMap<RenderResource, wgpu::Buffer>,
pub textures: HashMap<RenderResource, wgpu::TextureView>,
pub samplers: HashMap<RenderResource, wgpu::Sampler>,
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
pub resource_info: HashMap<RenderResource, ResourceInfo>,
pub bind_groups: HashMap<u64, BindGroupInfo>,
pub bind_group_layouts: HashMap<u64, wgpu::BindGroupLayout>,
@ -32,7 +31,6 @@ pub struct WgpuResources {
impl WgpuResources {
pub fn new() -> Self {
WgpuResources {
render_pipelines: HashMap::new(),
buffers: HashMap::new(),
textures: HashMap::new(),
samplers: HashMap::new(),
@ -455,6 +453,7 @@ pub struct WgpuRenderer {
pub surface: Option<wgpu::Surface>,
pub encoder: Option<wgpu::CommandEncoder>,
pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
pub wgpu_resources: WgpuResources,
}
@ -490,6 +489,7 @@ impl WgpuRenderer {
encoder: None,
swap_chain_descriptor,
wgpu_resources: WgpuResources::new(),
render_pipelines: HashMap::new(),
}
}
@ -620,7 +620,7 @@ impl WgpuRenderer {
}
pub fn create_render_pass<'a>(
wgpu_resources: &WgpuResources,
wgpu_resources: &'a WgpuResources,
pass_descriptor: &PassDescriptor,
encoder: &'a mut wgpu::CommandEncoder,
frame: &'a wgpu::SwapChainOutput,
@ -686,7 +686,7 @@ impl WgpuRenderer {
wgpu_resources: &'a WgpuResources,
depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor,
frame: &'a wgpu::SwapChainOutput,
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<&'a wgpu::TextureView> {
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> {
let attachment = match depth_stencil_attachment_descriptor.attachment.as_str() {
resource_name::texture::SWAP_CHAIN => &frame.view,
_ => {
@ -828,7 +828,6 @@ impl Renderer for WgpuRenderer {
.unwrap();
// create pipelines
if !self
.wgpu_resources
.render_pipelines
.contains_key(pipeline_descriptor_handle)
{
@ -849,7 +848,7 @@ impl Renderer for WgpuRenderer {
vertex_shader,
fragment_shader,
);
self.wgpu_resources.render_pipelines
self.render_pipelines
.insert(*pipeline_descriptor_handle, render_pipeline);
}
@ -862,22 +861,23 @@ impl Renderer for WgpuRenderer {
for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() {
// run passes
let mut render_pass = Self::create_render_pass(&mut self.wgpu_resources, pass_descriptor, &mut encoder, &frame);
let mut render_pass = Self::create_render_pass(&self.wgpu_resources, pass_descriptor, &mut encoder, &frame);
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
for pass_pipeline in pass_pipelines.iter() {
let pipeline_descriptor = pipeline_storage.get(pass_pipeline).unwrap();
let render_pipeline = self.wgpu_resources.render_pipelines.get(pass_pipeline).unwrap();
let render_pipeline = self.render_pipelines.get(pass_pipeline).unwrap();
render_pass.set_pipeline(render_pipeline);
let mut render_pass = WgpuRenderPass {
let mut wgpu_render_pass = WgpuRenderPass {
render_pass: &mut render_pass,
renderer: self,
pipeline_descriptor,
wgpu_resources: &self.wgpu_resources,
renderer: &self
};
for draw_target_name in pipeline_descriptor.draw_targets.iter() {
let draw_target = render_graph.draw_targets.get(draw_target_name).unwrap();
draw_target(world, &mut render_pass, pass_pipeline.clone());
draw_target(world, &mut wgpu_render_pass, *pass_pipeline);
}
}
}
@ -1018,11 +1018,12 @@ impl Renderer for WgpuRenderer {
pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
pub render_pass: &'b mut wgpu::RenderPass<'a>,
pub pipeline_descriptor: &'c PipelineDescriptor,
pub renderer: &'d mut WgpuRenderer,
pub wgpu_resources: &'a WgpuResources,
pub renderer: &'d WgpuRenderer,
}
impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
fn get_renderer(&mut self) -> &mut dyn Renderer {
fn get_renderer(&mut self) -> &dyn Renderer {
self.renderer
}
@ -1031,13 +1032,13 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
}
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64) {
let buffer = self.renderer.wgpu_resources.buffers.get(&resource).unwrap();
let buffer = self.wgpu_resources.buffers.get(&resource).unwrap();
self.render_pass
.set_vertex_buffers(start_slot, &[(&buffer, offset)]);
}
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64) {
let buffer = self.renderer.wgpu_resources.buffers.get(&resource).unwrap();
let buffer = self.wgpu_resources.buffers.get(&resource).unwrap();
self.render_pass.set_index_buffer(&buffer, offset);
}
@ -1055,17 +1056,18 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
let pipeline_layout = self.pipeline_descriptor.get_layout().unwrap();
for bind_group in pipeline_layout.bind_groups.iter() {
let bind_group_id = bind_group.get_hash().unwrap();
let bind_group_info = match self.renderer.wgpu_resources.bind_groups.get(&bind_group_id) {
let bind_group_info = match self.wgpu_resources.bind_groups.get(&bind_group_id) {
// if there is a "global" bind group, use that
Some(bind_group_info) => bind_group_info,
// otherwise try to get an entity-specific bind group
None => {
if let Some(entity) = entity {
if let None = self.renderer.wgpu_resources.get_entity_bind_group(*entity, bind_group_id) {
self.renderer.wgpu_resources.create_entity_bind_group(&self.renderer.device, bind_group, *entity);
if let None = self.wgpu_resources.get_entity_bind_group(*entity, bind_group_id) {
// TODO: Uncomment this
// self.wgpu_resources.create_entity_bind_group(&self.renderer.device, bind_group, *entity);
}
self.renderer.wgpu_resources
self.wgpu_resources
.get_entity_bind_group(*entity, bind_group_id)
.unwrap()
} else {
@ -1082,14 +1084,13 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
}
if let Some(resource) = self
.renderer
.wgpu_resources
.render_resources
.get_named_resource(&binding.name)
{
// PERF: This hashmap get is pretty expensive (10 fps for 10000 entities)
if let Some(dynamic_uniform_buffer_info) =
self.renderer.wgpu_resources.dynamic_uniform_buffer_info.get(&resource)
self.wgpu_resources.dynamic_uniform_buffer_info.get(&resource)
{
let index = dynamic_uniform_buffer_info
.offsets

View file

@ -1,8 +1,4 @@
pub enum ResourceInfo {
BufferMapped {
size: u64,
buffer_usage: wgpu::BufferUsage,
},
Buffer {
size: u64,
buffer_usage: wgpu::BufferUsage,

View file

@ -0,0 +1,72 @@
use crate::{
asset::{AssetStorage, Handle, Mesh},
prelude::Renderable,
render::render_graph::{Renderer, ResourceProvider},
};
use legion::{filter::*, prelude::*};
use zerocopy::AsBytes;
pub struct MeshResourceProvider {
pub mesh_query: Query<
(Read<Handle<Mesh>>, Read<Renderable>),
EntityFilterTuple<
And<(
ComponentFilter<Handle<Mesh>>,
ComponentFilter<Renderable>,
ComponentFilter<Handle<Mesh>>,
)>,
And<(Passthrough, Passthrough)>,
And<(
Passthrough,
Passthrough,
ComponentChangedFilter<Handle<Mesh>>,
)>,
>,
>,
}
impl MeshResourceProvider {
pub fn new() -> Self {
MeshResourceProvider {
mesh_query: <(Read<Handle<Mesh>>, Read<Renderable>)>::query()
.filter(changed::<Handle<Mesh>>()),
}
}
}
impl ResourceProvider for MeshResourceProvider {
fn initialize(&mut self, _renderer: &mut dyn Renderer, _world: &mut World) {}
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World) {
let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
for (mesh_handle, _renderable) in self.mesh_query.iter(world) {
if let None = renderer
.get_render_resources()
.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 render_resources = renderer.get_render_resources_mut();
render_resources.set_mesh_vertices_resource(*mesh_handle, vertex_buffer);
render_resources.set_mesh_indices_resource(*mesh_handle, index_buffer);
}
}
}
fn resize(
&mut self,
_renderer: &mut dyn Renderer,
_world: &mut World,
_width: u32,
_height: u32,
) {
}
}

View file

@ -4,6 +4,7 @@ mod frame_texture_resource_provider;
mod light_resource_provider;
mod ui_resource_provider;
mod uniform_resource_provider;
mod mesh_resource_provider;
pub use camera2d_resource_provider::*;
pub use camera_resource_provider::*;
@ -11,3 +12,4 @@ pub use frame_texture_resource_provider::*;
pub use light_resource_provider::*;
pub use ui_resource_provider::*;
pub use uniform_resource_provider::*;
pub use mesh_resource_provider::*;

View file

@ -63,7 +63,7 @@ where
.insert(uniform_info.name.to_string(), (None, 0, HashSet::new()));
}
let (resource, counts, entities) = self.uniform_buffer_info_resources.get_mut(uniform_info.name).unwrap();
let (_resource, counts, entities) = self.uniform_buffer_info_resources.get_mut(uniform_info.name).unwrap();
entities.insert(entity);
*counts += 1;
}
@ -112,7 +112,7 @@ where
}
// allocate uniform buffers
for (name, (resource, count, entities)) in self.uniform_buffer_info_resources.iter_mut() {
for (name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() {
let count = *count as u64;
if let Some(resource) = resource {
let mut info = renderer
@ -158,7 +158,7 @@ where
// TODO: check if index has changed. if it has, then entity should be updated
// TODO: only mem-map entities if their data has changed
// PERF: These hashmap inserts are pretty expensive (10 fps for 10000 entities)
info.offsets.insert(entity, offset as u64);
info.offsets.insert(entity, offset as u32);
// TODO: try getting ref first
offset += alignment;
}

View file

@ -171,7 +171,7 @@ pub struct UniformInfo<'a> {
}
pub struct DynamicUniformBufferInfo {
pub offsets: HashMap<Entity, u64>,
pub offsets: HashMap<Entity, u32>,
pub capacity: u64,
pub count: u64,
}