merge asset resources / support arbitrary asset handles / make them RwLocked

This commit is contained in:
Carter Anderson 2020-04-15 12:48:04 -07:00
parent bcbddf8719
commit 1f5f432e6c
10 changed files with 120 additions and 138 deletions

View file

@ -3,7 +3,7 @@ use legion::prelude::*;
use crate::{
draw_target::DrawTarget,
mesh::Mesh,
mesh::{self, Mesh},
pass::RenderPass,
pipeline::{PipelineAssignments, PipelineDescriptor},
render_resource::{
@ -49,15 +49,15 @@ impl DrawTarget for AssignedMeshesDrawTarget {
continue;
}
let mesh = *world.get_component::<Handle<Mesh>>(*entity).unwrap();
let mesh_handle = *world.get_component::<Handle<Mesh>>(*entity).unwrap();
let render_context = render_pass.get_render_context();
let render_resources = render_context.resources();
if current_mesh_handle != Some(mesh) {
if current_mesh_handle != Some(mesh_handle) {
if let Some(vertex_buffer_resource) =
render_resources.get_mesh_vertices_resource(mesh)
render_resources.get_asset_resource(mesh_handle, mesh::VERTEX_BUFFER_ASSET_INDEX)
{
let index_buffer_resource =
render_resources.get_mesh_indices_resource(mesh).unwrap();
render_resources.get_asset_resource(mesh_handle, mesh::INDEX_BUFFER_ASSET_INDEX).unwrap();
render_resources.get_resource_info(
index_buffer_resource,
&mut |resource_info| match resource_info {
@ -71,7 +71,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0);
}
// TODO: Verify buffer format matches render pass
current_mesh_handle = Some(mesh);
current_mesh_handle = Some(mesh_handle);
}
// TODO: validate bind group properties against shader uniform properties at least once

View file

@ -1,6 +1,6 @@
use crate::{
draw_target::DrawTarget,
mesh::Mesh,
mesh::{self, Mesh},
pass::RenderPass,
pipeline::PipelineDescriptor,
render_resource::{resource_name, ResourceInfo},
@ -24,19 +24,19 @@ impl DrawTarget for MeshesDrawTarget {
let mut current_mesh_handle = None;
let mut current_mesh_index_len = 0;
let mesh_query = <(Read<Handle<Mesh>>, Read<Renderable>)>::query();
for (mesh, renderable) in mesh_query.iter(world) {
for (mesh_handle, renderable) in mesh_query.iter(world) {
if !renderable.is_visible || renderable.is_instanced {
continue;
}
let render_context = render_pass.get_render_context();
let render_resources = render_context.resources();
if current_mesh_handle != Some(*mesh) {
if current_mesh_handle != Some(*mesh_handle) {
if let Some(vertex_buffer_resource) =
render_resources.get_mesh_vertices_resource(*mesh)
render_resources.get_asset_resource(*mesh_handle, mesh::VERTEX_BUFFER_ASSET_INDEX)
{
let index_buffer_resource =
render_resources.get_mesh_indices_resource(*mesh).unwrap();
render_resources.get_asset_resource(*mesh_handle, mesh::INDEX_BUFFER_ASSET_INDEX).unwrap();
render_resources.get_resource_info(index_buffer_resource, &mut |resource_info| {
match resource_info {
Some(ResourceInfo::Buffer(buffer_info)) => {
@ -49,7 +49,7 @@ impl DrawTarget for MeshesDrawTarget {
render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0);
}
// TODO: Verify buffer format matches render pass
current_mesh_handle = Some(*mesh);
current_mesh_handle = Some(*mesh_handle);
}
// TODO: validate bind group properties against shader uniform properties at least once

View file

@ -3,6 +3,9 @@ use bevy_asset::{Asset, Handle};
use glam::*;
use legion::prelude::*;
pub const VERTEX_BUFFER_ASSET_INDEX: usize = 0;
pub const INDEX_BUFFER_ASSET_INDEX: usize = 1;
pub enum MeshType {
Cube,
Plane { size: f32 },

View file

@ -1,6 +1,3 @@
use crate::{mesh::Mesh, texture::Texture};
use bevy_asset::Handle;
use std::collections::HashMap;
use uuid::Uuid;
// TODO: Rename to RenderResourceId
@ -11,52 +8,4 @@ impl RenderResource {
pub fn new() -> Self {
RenderResource(Uuid::new_v4())
}
}
// TODO: consider scoping breaking these mappings up by type: Texture, Sampler, etc
// the overlap could cause accidents.
#[derive(Default, Clone)]
pub struct AssetResources {
texture_to_resource: HashMap<Handle<Texture>, RenderResource>,
texture_to_sampler_resource: HashMap<Handle<Texture>, RenderResource>,
mesh_to_vertices_resource: HashMap<Handle<Mesh>, RenderResource>,
mesh_to_indices_resource: HashMap<Handle<Mesh>, RenderResource>,
}
impl AssetResources {
pub fn set_texture_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) {
self.texture_to_resource.insert(texture, resource);
}
pub fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
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);
}
pub fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
self.texture_to_sampler_resource.get(&texture).cloned()
}
}
}

View file

@ -1,5 +1,5 @@
use crate::{
mesh::Mesh,
mesh::{self, Mesh},
pipeline::VertexBufferDescriptors,
render_resource::{
AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider,
@ -24,10 +24,10 @@ impl MeshResourceProvider {
) {
let render_resources = render_context.resources_mut();
let (vertex_buffer, index_buffer) =
if let Some(vertex_buffer) = render_resources.get_mesh_vertices_resource(handle) {
if let Some(vertex_buffer) = render_resources.get_asset_resource(handle, mesh::VERTEX_BUFFER_ASSET_INDEX) {
(
vertex_buffer,
render_resources.get_mesh_indices_resource(handle),
render_resources.get_asset_resource(handle, mesh::INDEX_BUFFER_ASSET_INDEX),
)
} else {
let mesh_asset = mesh_storage.get(&handle).unwrap();
@ -46,9 +46,8 @@ impl MeshResourceProvider {
mesh_asset.indices.as_bytes(),
);
let asset_resources = render_resources.asset_resources_mut();
asset_resources.set_mesh_vertices_resource(handle, vertex_buffer);
asset_resources.set_mesh_indices_resource(handle, index_buffer);
render_resources.set_asset_resource(handle, vertex_buffer, mesh::VERTEX_BUFFER_ASSET_INDEX);
render_resources.set_asset_resource(handle, index_buffer, mesh::INDEX_BUFFER_ASSET_INDEX);
(vertex_buffer, Some(index_buffer))
};

View file

@ -6,7 +6,7 @@ use crate::{
},
renderer_2::{RenderContext, RenderResourceContext},
shader::{AsUniforms, FieldBindType},
texture::{SamplerDescriptor, Texture, TextureDescriptor},
texture::{SamplerDescriptor, Texture, TextureDescriptor, self},
Renderable,
};
use bevy_asset::{AssetStorage, Handle};
@ -379,13 +379,13 @@ where
.unwrap();
let (texture_resource, sampler_resource) = match render_context
.resources()
.get_texture_resource(texture_handle)
.get_asset_resource(texture_handle, texture::TEXTURE_ASSET_INDEX)
{
Some(texture_resource) => (
texture_resource,
render_context
.resources()
.get_texture_sampler_resource(texture_handle)
.get_asset_resource(texture_handle, texture::SAMPLER_ASSET_INDEX)
.unwrap(),
),
None => {
@ -401,10 +401,9 @@ where
let sampler_resource =
render_resources.create_sampler(&sampler_descriptor);
let asset_resources = render_resources.asset_resources_mut();
asset_resources.set_texture_resource(texture_handle, texture_resource);
asset_resources
.set_texture_sampler_resource(texture_handle, sampler_resource);
render_resources.set_asset_resource(texture_handle, texture_resource, 0);
render_resources
.set_asset_resource(texture_handle, sampler_resource, 1);
(texture_resource, sampler_resource)
}
};

View file

@ -1,10 +1,9 @@
use crate::{
mesh::Mesh,
render_resource::{AssetResources, BufferInfo, RenderResource, ResourceInfo},
render_resource::{BufferInfo, RenderResource, ResourceInfo},
shader::Shader,
texture::{SamplerDescriptor, Texture, TextureDescriptor},
texture::{SamplerDescriptor, TextureDescriptor},
};
use bevy_asset::{AssetStorage, Handle};
use bevy_asset::{AssetStorage, Handle, HandleUntyped};
use bevy_window::{Window, WindowId};
use std::any::Any;
@ -55,11 +54,39 @@ pub trait RenderResourceContext: Any {
fn remove_buffer(&mut self, resource: RenderResource);
fn remove_texture(&mut self, resource: RenderResource);
fn remove_sampler(&mut self, resource: RenderResource);
fn get_resource_info(&self, resource: RenderResource, handle_info: &mut dyn FnMut(Option<&ResourceInfo>));
fn asset_resources(&self) -> &AssetResources;
fn asset_resources_mut(&mut self) -> &mut AssetResources;
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource>;
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource>;
fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource>;
fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource>;
fn get_resource_info(
&self,
resource: RenderResource,
handle_info: &mut dyn FnMut(Option<&ResourceInfo>),
);
fn set_asset_resource_untyped(
&mut self,
handle: HandleUntyped,
render_resource: RenderResource,
index: usize,
);
fn get_asset_resource_untyped(
&self,
handle: HandleUntyped,
index: usize,
) -> Option<RenderResource>;
}
impl dyn RenderResourceContext {
pub fn set_asset_resource<T>(
&mut self,
handle: Handle<T>,
render_resource: RenderResource,
index: usize,
) where
T: 'static,
{
self.set_asset_resource_untyped(handle.into(), render_resource, index);
}
pub fn get_asset_resource<T>(&self, handle: Handle<T>, index: usize) -> Option<RenderResource>
where
T: 'static,
{
self.get_asset_resource_untyped(handle.into(), index)
}
}

View file

@ -2,6 +2,8 @@ use crate::shader::ShaderDefSuffixProvider;
use bevy_asset::{Asset, Handle};
use std::fs::File;
pub const TEXTURE_ASSET_INDEX: usize = 0;
pub const SAMPLER_ASSET_INDEX: usize = 1;
pub enum TextureType {
Data(Vec<u8>, usize, usize),
Png(String), // TODO: please rethink this

View file

@ -1,17 +1,14 @@
use crate::WgpuResources;
use bevy_asset::{AssetStorage, Handle};
use bevy_asset::{AssetStorage, Handle, HandleUntyped};
use bevy_render::{
mesh::Mesh,
render_resource::{
AssetResources, BufferInfo, RenderResource, ResourceInfo,
},
render_resource::{BufferInfo, RenderResource, ResourceInfo},
renderer_2::RenderResourceContext,
shader::Shader,
texture::{SamplerDescriptor, Texture, TextureDescriptor},
texture::{SamplerDescriptor, TextureDescriptor},
};
use bevy_window::{Window, WindowId};
use std::sync::Arc;
use bevy_window::{WindowId, Window};
#[derive(Clone)]
pub struct WgpuRenderResourceContext {
@ -19,7 +16,6 @@ pub struct WgpuRenderResourceContext {
pub wgpu_resources: WgpuResources,
}
impl WgpuRenderResourceContext {
pub fn new(device: Arc<wgpu::Device>) -> Self {
WgpuRenderResourceContext {
@ -71,46 +67,27 @@ impl RenderResourceContext for WgpuRenderResourceContext {
self.wgpu_resources.remove_sampler(resource);
}
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
self.wgpu_resources
.asset_resources
.get_texture_resource(texture)
}
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
self.wgpu_resources
.asset_resources
.get_texture_sampler_resource(texture)
}
fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
self.wgpu_resources
.asset_resources
.get_mesh_vertices_resource(mesh)
}
fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
self.wgpu_resources
.asset_resources
.get_mesh_indices_resource(mesh)
}
fn get_resource_info(&self, resource: RenderResource, handle_info: &mut dyn FnMut(Option<&ResourceInfo>)) {
fn get_resource_info(
&self,
resource: RenderResource,
handle_info: &mut dyn FnMut(Option<&ResourceInfo>),
) {
self.wgpu_resources.get_resource_info(resource, handle_info);
}
fn asset_resources(&self) -> &AssetResources {
&self.wgpu_resources.asset_resources
}
fn asset_resources_mut(&mut self) -> &mut AssetResources {
&mut self.wgpu_resources.asset_resources
}
fn create_shader_module(
&mut self,
shader_handle: Handle<Shader>,
shader_storage: &AssetStorage<Shader>,
) {
if self.wgpu_resources.shader_modules.read().unwrap().get(&shader_handle).is_some() {
if self
.wgpu_resources
.shader_modules
.read()
.unwrap()
.get(&shader_handle)
.is_some()
{
return;
}
@ -119,7 +96,8 @@ impl RenderResourceContext for WgpuRenderResourceContext {
.create_shader_module(&self.device, shader_handle, shader);
}
fn create_swap_chain(&mut self, window: &Window) {
self.wgpu_resources.create_window_swap_chain(&self.device, window)
self.wgpu_resources
.create_window_swap_chain(&self.device, window)
}
fn next_swap_chain_texture(&mut self, window_id: bevy_window::WindowId) {
self.wgpu_resources.next_swap_chain_texture(window_id);
@ -127,4 +105,21 @@ impl RenderResourceContext for WgpuRenderResourceContext {
fn drop_swap_chain_texture(&mut self, window_id: WindowId) {
self.wgpu_resources.remove_swap_chain_texture(window_id);
}
fn set_asset_resource_untyped(
&mut self,
handle: HandleUntyped,
render_resource: RenderResource,
index: usize,
) {
self.wgpu_resources
.set_asset_resource_untyped(handle, render_resource, index);
}
fn get_asset_resource_untyped(
&self,
handle: HandleUntyped,
index: usize,
) -> Option<RenderResource> {
self.wgpu_resources
.get_asset_resource_untyped(handle, index)
}
}

View file

@ -1,9 +1,9 @@
use crate::{renderer_2::WgpuRenderResourceContext, wgpu_type_converter::WgpuInto};
use bevy_asset::Handle;
use bevy_asset::{HandleUntyped, Handle};
use bevy_render::{
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
render_resource::{
AssetResources, BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo,
BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo,
},
renderer_2::RenderResourceContext,
shader::Shader,
@ -74,7 +74,6 @@ pub struct WgpuResourceRefs<'a> {
#[derive(Default, Clone)]
pub struct WgpuResources {
// TODO: remove this from WgpuResources. it doesn't need to be here
pub asset_resources: AssetResources,
pub window_surfaces: Arc<RwLock<HashMap<WindowId, wgpu::Surface>>>,
pub window_swap_chains: Arc<RwLock<HashMap<WindowId, wgpu::SwapChain>>>,
pub swap_chain_outputs: Arc<RwLock<HashMap<WindowId, wgpu::SwapChainOutput>>>,
@ -86,6 +85,7 @@ pub struct WgpuResources {
pub render_pipelines: Arc<RwLock<HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>>>,
pub bind_groups: Arc<RwLock<HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>>>,
pub bind_group_layouts: Arc<RwLock<HashMap<BindGroupDescriptorId, wgpu::BindGroupLayout>>>,
pub asset_resources: Arc<RwLock<HashMap<(HandleUntyped, usize), RenderResource>>>,
}
impl WgpuResources {
@ -362,13 +362,21 @@ impl WgpuResources {
self.resource_info.write().unwrap().remove(&resource);
}
pub fn get_render_resources(&self) -> &AssetResources {
&self.asset_resources
}
pub fn set_asset_resource<T>(&mut self, handle: Handle<T>, render_resource: RenderResource, index: usize) where T: 'static {
self.asset_resources.write().unwrap().insert((handle.into(), index), render_resource);
}
pub fn get_render_resources_mut(&mut self) -> &mut AssetResources {
&mut self.asset_resources
}
pub fn get_asset_resource<T>(&mut self, handle: Handle<T>, index: usize) -> Option<RenderResource> where T: 'static {
self.asset_resources.write().unwrap().get(&(handle.into(), index)).cloned()
}
pub fn set_asset_resource_untyped(&mut self, handle: HandleUntyped, render_resource: RenderResource, index: usize) {
self.asset_resources.write().unwrap().insert((handle, index), render_resource);
}
pub fn get_asset_resource_untyped(&self, handle: HandleUntyped, index: usize) -> Option<RenderResource> {
self.asset_resources.write().unwrap().get(&(handle, index)).cloned()
}
pub fn create_bind_group_layout(
&self,