partially working rwlock implementation (blocked on lifetime issues)
This commit is contained in:
parent
537d75bbce
commit
b53f198b99
@ -239,7 +239,7 @@ impl PipelineAssignments {
|
|||||||
// TODO: make this a system
|
// TODO: make this a system
|
||||||
pub fn update_shader_assignments(
|
pub fn update_shader_assignments(
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &mut Resources,
|
resources: &Resources,
|
||||||
render_context: &dyn RenderContext,
|
render_context: &dyn RenderContext,
|
||||||
) {
|
) {
|
||||||
// PERF: this seems like a lot of work for things that don't change that often.
|
// PERF: this seems like a lot of work for things that don't change that often.
|
||||||
|
|||||||
@ -17,25 +17,13 @@ impl RenderResource {
|
|||||||
// the overlap could cause accidents.
|
// the overlap could cause accidents.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct AssetResources {
|
pub struct AssetResources {
|
||||||
pub texture_to_resource: HashMap<Handle<Texture>, RenderResource>,
|
texture_to_resource: HashMap<Handle<Texture>, RenderResource>,
|
||||||
pub texture_to_sampler_resource: HashMap<Handle<Texture>, RenderResource>,
|
texture_to_sampler_resource: HashMap<Handle<Texture>, RenderResource>,
|
||||||
pub mesh_to_vertices_resource: HashMap<Handle<Mesh>, RenderResource>,
|
mesh_to_vertices_resource: HashMap<Handle<Mesh>, RenderResource>,
|
||||||
pub mesh_to_indices_resource: HashMap<Handle<Mesh>, RenderResource>,
|
mesh_to_indices_resource: HashMap<Handle<Mesh>, RenderResource>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AssetResources {
|
impl AssetResources {
|
||||||
pub fn consume(&mut self, render_resources: AssetResources) {
|
|
||||||
// TODO: this is brittle. consider a single change-stream-based approach instead?
|
|
||||||
self.texture_to_resource
|
|
||||||
.extend(render_resources.texture_to_resource);
|
|
||||||
self.texture_to_sampler_resource
|
|
||||||
.extend(render_resources.texture_to_sampler_resource);
|
|
||||||
self.mesh_to_vertices_resource
|
|
||||||
.extend(render_resources.mesh_to_vertices_resource);
|
|
||||||
self.mesh_to_indices_resource
|
|
||||||
.extend(render_resources.mesh_to_indices_resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_texture_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) {
|
pub fn set_texture_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) {
|
||||||
self.texture_to_resource.insert(texture, resource);
|
self.texture_to_resource.insert(texture, resource);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,13 +6,33 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
use bevy_window::{Window, WindowId};
|
use bevy_window::{Window, WindowId};
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
pub struct GlobalRenderResourceContext {
|
pub struct GlobalRenderResourceContext {
|
||||||
pub context: Box<dyn RenderResourceContext + Send + Sync + 'static>,
|
pub context: Box<dyn RenderResourceContext + Send + Sync + 'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GlobalRenderResourceContext {
|
||||||
|
pub fn new<T>(context: T) -> GlobalRenderResourceContext
|
||||||
|
where
|
||||||
|
T: RenderResourceContext + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
GlobalRenderResourceContext {
|
||||||
|
context: Box::new(context),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn render_resources_mut(&mut self) -> &dyn RenderResourceContext {
|
||||||
|
// (&mut self.context).downcast_mut::<dyn RenderResourceContext>()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn downcast_mut(&self) -> &dyn RenderResourceContext {
|
||||||
|
// self.context.downcast_ref::<RenderResourceContext>()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Rename to RenderResources after cleaning up AssetResources rename
|
// TODO: Rename to RenderResources after cleaning up AssetResources rename
|
||||||
pub trait RenderResourceContext {
|
pub trait RenderResourceContext: Any {
|
||||||
fn create_swap_chain(&mut self, window: &Window);
|
fn create_swap_chain(&mut self, window: &Window);
|
||||||
fn next_swap_chain_texture(&mut self, window_id: WindowId);
|
fn next_swap_chain_texture(&mut self, window_id: WindowId);
|
||||||
fn drop_swap_chain_texture(&mut self, window_id: WindowId);
|
fn drop_swap_chain_texture(&mut self, window_id: WindowId);
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
mod systems;
|
mod systems;
|
||||||
mod wgpu_render_context;
|
mod wgpu_render_context;
|
||||||
mod wgpu_render_resource_context;
|
mod wgpu_render_resource_context;
|
||||||
mod wgpu_transactional_render_resource_context;
|
|
||||||
|
|
||||||
pub use systems::*;
|
pub use systems::*;
|
||||||
pub use wgpu_render_context::*;
|
pub use wgpu_render_context::*;
|
||||||
pub use wgpu_render_resource_context::*;
|
pub use wgpu_render_resource_context::*;
|
||||||
pub use wgpu_transactional_render_resource_context::*;
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use super::WgpuRenderResourceContextTrait;
|
use super::WgpuRenderResourceContext;
|
||||||
use crate::{
|
use crate::{
|
||||||
wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto},
|
wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto},
|
||||||
WgpuRenderPass,
|
WgpuRenderPass,
|
||||||
@ -21,7 +21,7 @@ use bevy_window::WindowId;
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct LazyCommandEncoder {
|
pub struct LazyCommandEncoder {
|
||||||
command_encoder: Option<wgpu::CommandEncoder>,
|
command_encoder: Option<wgpu::CommandEncoder>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,22 +55,16 @@ impl LazyCommandEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WgpuRenderContext<T>
|
pub struct WgpuRenderContext {
|
||||||
where
|
|
||||||
T: RenderResourceContext,
|
|
||||||
{
|
|
||||||
pub device: Arc<wgpu::Device>,
|
pub device: Arc<wgpu::Device>,
|
||||||
// TODO: remove this
|
// TODO: remove this
|
||||||
pub primary_window: Option<WindowId>,
|
pub primary_window: Option<WindowId>,
|
||||||
command_encoder: LazyCommandEncoder,
|
pub command_encoder: LazyCommandEncoder,
|
||||||
pub render_resources: T,
|
pub render_resources: WgpuRenderResourceContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> WgpuRenderContext<T>
|
impl WgpuRenderContext {
|
||||||
where
|
pub fn new(device: Arc<wgpu::Device>, resources: WgpuRenderResourceContext) -> Self {
|
||||||
T: RenderResourceContext,
|
|
||||||
{
|
|
||||||
pub fn new(device: Arc<wgpu::Device>, resources: T) -> Self {
|
|
||||||
WgpuRenderContext {
|
WgpuRenderContext {
|
||||||
device,
|
device,
|
||||||
primary_window: None,
|
primary_window: None,
|
||||||
@ -81,34 +75,25 @@ where
|
|||||||
|
|
||||||
/// Consume this context, finalize the current CommandEncoder (if it exists), and take the current WgpuResources.
|
/// Consume this context, finalize the current CommandEncoder (if it exists), and take the current WgpuResources.
|
||||||
/// This is intended to be called from a worker thread right before synchronizing with the main thread.
|
/// This is intended to be called from a worker thread right before synchronizing with the main thread.
|
||||||
pub fn finish(mut self) -> (Option<wgpu::CommandBuffer>, T) {
|
pub fn finish(&mut self) -> Option<wgpu::CommandBuffer> {
|
||||||
(
|
|
||||||
self.command_encoder.take().map(|encoder| encoder.finish()),
|
|
||||||
self.render_resources,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consume this context, finalize the current CommandEncoder (if it exists), and take the current WgpuResources.
|
|
||||||
/// This is intended to be called from a worker thread right before synchronizing with the main thread.
|
|
||||||
pub fn finish_encoder(&mut self) -> Option<wgpu::CommandBuffer> {
|
|
||||||
self.command_encoder.take().map(|encoder| encoder.finish())
|
self.command_encoder.take().map(|encoder| encoder.finish())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> RenderContext for WgpuRenderContext<T>
|
impl RenderContext for WgpuRenderContext {
|
||||||
where
|
|
||||||
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
|
||||||
{
|
|
||||||
fn create_texture_with_data(
|
fn create_texture_with_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
texture_descriptor: &TextureDescriptor,
|
texture_descriptor: &TextureDescriptor,
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
) -> RenderResource {
|
) -> RenderResource {
|
||||||
self.render_resources.create_texture_with_data(
|
self.render_resources
|
||||||
self.command_encoder.get_or_create(&self.device),
|
.wgpu_resources
|
||||||
texture_descriptor,
|
.create_texture_with_data(
|
||||||
bytes,
|
&self.device,
|
||||||
)
|
self.command_encoder.get_or_create(&self.device),
|
||||||
|
texture_descriptor,
|
||||||
|
bytes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
fn copy_buffer_to_buffer(
|
fn copy_buffer_to_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -119,15 +104,11 @@ where
|
|||||||
size: u64,
|
size: u64,
|
||||||
) {
|
) {
|
||||||
let command_encoder = self.command_encoder.get_or_create(&self.device);
|
let command_encoder = self.command_encoder.get_or_create(&self.device);
|
||||||
let source = self.render_resources.get_buffer(source_buffer).unwrap();
|
self.render_resources.wgpu_resources.copy_buffer_to_buffer(
|
||||||
let destination = self
|
command_encoder,
|
||||||
.render_resources
|
source_buffer,
|
||||||
.get_buffer(destination_buffer)
|
|
||||||
.unwrap();
|
|
||||||
command_encoder.copy_buffer_to_buffer(
|
|
||||||
source,
|
|
||||||
source_offset,
|
source_offset,
|
||||||
destination,
|
destination_buffer,
|
||||||
destination_offset,
|
destination_offset,
|
||||||
size,
|
size,
|
||||||
);
|
);
|
||||||
@ -148,6 +129,7 @@ where
|
|||||||
{
|
{
|
||||||
if let None = self
|
if let None = self
|
||||||
.render_resources
|
.render_resources
|
||||||
|
.wgpu_resources
|
||||||
.get_bind_group(bind_group_descriptor.id, *render_resource_set_id)
|
.get_bind_group(bind_group_descriptor.id, *render_resource_set_id)
|
||||||
{
|
{
|
||||||
log::trace!(
|
log::trace!(
|
||||||
@ -155,6 +137,19 @@ where
|
|||||||
render_resource_set_id
|
render_resource_set_id
|
||||||
);
|
);
|
||||||
let wgpu_bind_group = {
|
let wgpu_bind_group = {
|
||||||
|
let textures = self
|
||||||
|
.render_resources
|
||||||
|
.wgpu_resources
|
||||||
|
.textures
|
||||||
|
.read()
|
||||||
|
.unwrap();
|
||||||
|
let samplers = self
|
||||||
|
.render_resources
|
||||||
|
.wgpu_resources
|
||||||
|
.samplers
|
||||||
|
.read()
|
||||||
|
.unwrap();
|
||||||
|
let buffers = self.render_resources.wgpu_resources.buffers.read().unwrap();
|
||||||
let bindings = bind_group_descriptor
|
let bindings = bind_group_descriptor
|
||||||
.bindings
|
.bindings
|
||||||
.iter()
|
.iter()
|
||||||
@ -174,10 +169,7 @@ where
|
|||||||
resource: match &binding.bind_type {
|
resource: match &binding.bind_type {
|
||||||
BindType::SampledTexture { .. } => {
|
BindType::SampledTexture { .. } => {
|
||||||
if let ResourceInfo::Texture = resource_info {
|
if let ResourceInfo::Texture = resource_info {
|
||||||
let texture = self
|
let texture = textures.get(&resource).unwrap();
|
||||||
.render_resources
|
|
||||||
.get_texture(resource)
|
|
||||||
.unwrap();
|
|
||||||
wgpu::BindingResource::TextureView(texture)
|
wgpu::BindingResource::TextureView(texture)
|
||||||
} else {
|
} else {
|
||||||
panic!("expected a Texture resource");
|
panic!("expected a Texture resource");
|
||||||
@ -185,10 +177,7 @@ where
|
|||||||
}
|
}
|
||||||
BindType::Sampler { .. } => {
|
BindType::Sampler { .. } => {
|
||||||
if let ResourceInfo::Sampler = resource_info {
|
if let ResourceInfo::Sampler = resource_info {
|
||||||
let sampler = self
|
let sampler = samplers.get(&resource).unwrap();
|
||||||
.render_resources
|
|
||||||
.get_sampler(resource)
|
|
||||||
.unwrap();
|
|
||||||
wgpu::BindingResource::Sampler(sampler)
|
wgpu::BindingResource::Sampler(sampler)
|
||||||
} else {
|
} else {
|
||||||
panic!("expected a Sampler resource");
|
panic!("expected a Sampler resource");
|
||||||
@ -197,10 +186,7 @@ where
|
|||||||
BindType::Uniform { .. } => {
|
BindType::Uniform { .. } => {
|
||||||
if let ResourceInfo::Buffer(buffer_info) = resource_info
|
if let ResourceInfo::Buffer(buffer_info) = resource_info
|
||||||
{
|
{
|
||||||
let buffer = self
|
let buffer = buffers.get(&resource).unwrap();
|
||||||
.render_resources
|
|
||||||
.get_buffer(resource)
|
|
||||||
.unwrap();
|
|
||||||
wgpu::BindingResource::Buffer {
|
wgpu::BindingResource::Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
range: 0..buffer_info.size as u64,
|
range: 0..buffer_info.size as u64,
|
||||||
@ -221,19 +207,26 @@ where
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<wgpu::Binding>>();
|
.collect::<Vec<wgpu::Binding>>();
|
||||||
let bind_group_layout = self
|
let bind_group_layouts = self
|
||||||
.render_resources
|
.render_resources
|
||||||
.get_bind_group_layout(bind_group_descriptor.id)
|
.wgpu_resources
|
||||||
|
.bind_group_layouts
|
||||||
|
.read()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let bind_group_layout =
|
||||||
|
bind_group_layouts.get(&bind_group_descriptor.id).unwrap();
|
||||||
let wgpu_bind_group_descriptor = wgpu::BindGroupDescriptor {
|
let wgpu_bind_group_descriptor = wgpu::BindGroupDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
layout: bind_group_layout,
|
layout: bind_group_layout,
|
||||||
bindings: bindings.as_slice(),
|
bindings: bindings.as_slice(),
|
||||||
};
|
};
|
||||||
self.render_resources
|
self.render_resources.wgpu_resources.create_bind_group(
|
||||||
.create_bind_group(*render_resource_set_id, &wgpu_bind_group_descriptor)
|
&self.device,
|
||||||
|
*render_resource_set_id,
|
||||||
|
&wgpu_bind_group_descriptor,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
self.render_resources.set_bind_group(
|
self.render_resources.wgpu_resources.set_bind_group(
|
||||||
bind_group_descriptor.id,
|
bind_group_descriptor.id,
|
||||||
*render_resource_set_id,
|
*render_resource_set_id,
|
||||||
wgpu_bind_group,
|
wgpu_bind_group,
|
||||||
@ -250,13 +243,27 @@ where
|
|||||||
pipeline_descriptor: &mut PipelineDescriptor,
|
pipeline_descriptor: &mut PipelineDescriptor,
|
||||||
shader_storage: &AssetStorage<Shader>,
|
shader_storage: &AssetStorage<Shader>,
|
||||||
) {
|
) {
|
||||||
if let Some(_) = self.render_resources.get_pipeline(pipeline_handle) {
|
if let Some(_) = self
|
||||||
|
.render_resources
|
||||||
|
.wgpu_resources
|
||||||
|
.render_pipelines
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(&pipeline_handle)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let layout = pipeline_descriptor.get_layout().unwrap();
|
let layout = pipeline_descriptor.get_layout().unwrap();
|
||||||
for bind_group in layout.bind_groups.iter() {
|
for bind_group in layout.bind_groups.iter() {
|
||||||
if let None = self.render_resources.get_bind_group_layout(bind_group.id) {
|
if let None = self
|
||||||
|
.render_resources
|
||||||
|
.wgpu_resources
|
||||||
|
.bind_group_layouts
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(&bind_group.id)
|
||||||
|
{
|
||||||
let bind_group_layout_binding = bind_group
|
let bind_group_layout_binding = bind_group
|
||||||
.bindings
|
.bindings
|
||||||
.iter()
|
.iter()
|
||||||
@ -266,32 +273,37 @@ where
|
|||||||
ty: (&binding.bind_type).wgpu_into(),
|
ty: (&binding.bind_type).wgpu_into(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<wgpu::BindGroupLayoutEntry>>();
|
.collect::<Vec<wgpu::BindGroupLayoutEntry>>();
|
||||||
self.render_resources.create_bind_group_layout(
|
self.render_resources
|
||||||
bind_group.id,
|
.wgpu_resources
|
||||||
&wgpu::BindGroupLayoutDescriptor {
|
.create_bind_group_layout(
|
||||||
bindings: bind_group_layout_binding.as_slice(),
|
&self.device,
|
||||||
label: None,
|
bind_group.id,
|
||||||
},
|
&wgpu::BindGroupLayoutDescriptor {
|
||||||
);
|
bindings: bind_group_layout_binding.as_slice(),
|
||||||
|
label: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup and collect bind group layouts
|
let pipeline_layout = {
|
||||||
let bind_group_layouts = layout
|
let bind_group_layouts = self
|
||||||
.bind_groups
|
.render_resources
|
||||||
.iter()
|
.wgpu_resources
|
||||||
.map(|bind_group| {
|
.bind_group_layouts
|
||||||
self.render_resources
|
.read()
|
||||||
.get_bind_group_layout(bind_group.id)
|
.unwrap();
|
||||||
.unwrap()
|
// setup and collect bind group layouts
|
||||||
})
|
let bind_group_layouts = layout
|
||||||
.collect::<Vec<&wgpu::BindGroupLayout>>();
|
.bind_groups
|
||||||
|
.iter()
|
||||||
let pipeline_layout = self
|
.map(|bind_group| bind_group_layouts.get(&bind_group.id).unwrap())
|
||||||
.device
|
.collect::<Vec<&wgpu::BindGroupLayout>>();
|
||||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
self.device
|
||||||
bind_group_layouts: bind_group_layouts.as_slice(),
|
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
});
|
bind_group_layouts: bind_group_layouts.as_slice(),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
let owned_vertex_buffer_descriptors = layout
|
let owned_vertex_buffer_descriptors = layout
|
||||||
.vertex_buffer_descriptors
|
.vertex_buffer_descriptors
|
||||||
@ -305,32 +317,46 @@ where
|
|||||||
.map(|c| c.wgpu_into())
|
.map(|c| c.wgpu_into())
|
||||||
.collect::<Vec<wgpu::ColorStateDescriptor>>();
|
.collect::<Vec<wgpu::ColorStateDescriptor>>();
|
||||||
|
|
||||||
if let None = self
|
if self
|
||||||
.render_resources
|
.render_resources
|
||||||
.get_shader_module(pipeline_descriptor.shader_stages.vertex)
|
.wgpu_resources
|
||||||
|
.shader_modules
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||||
|
.is_none()
|
||||||
{
|
{
|
||||||
self.render_resources
|
self.render_resources
|
||||||
.create_shader_module(pipeline_descriptor.shader_stages.vertex, shader_storage);
|
.create_shader_module(pipeline_descriptor.shader_stages.vertex, shader_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment {
|
if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment {
|
||||||
if let None = self.render_resources.get_shader_module(fragment_handle) {
|
if self
|
||||||
|
.render_resources
|
||||||
|
.wgpu_resources
|
||||||
|
.shader_modules
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(&fragment_handle)
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
self.render_resources
|
self.render_resources
|
||||||
.create_shader_module(fragment_handle, shader_storage);
|
.create_shader_module(fragment_handle, shader_storage);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let wgpu_pipeline = {
|
let wgpu_pipeline = {
|
||||||
let vertex_shader_module = self
|
let shader_modules = self
|
||||||
.render_resources
|
.render_resources
|
||||||
.get_shader_module(pipeline_descriptor.shader_stages.vertex)
|
.wgpu_resources
|
||||||
|
.shader_modules
|
||||||
|
.read()
|
||||||
|
.unwrap();
|
||||||
|
let vertex_shader_module = shader_modules
|
||||||
|
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
|
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
|
||||||
Some(fragment_handle) => Some(
|
Some(fragment_handle) => Some(shader_modules.get(&fragment_handle).unwrap()),
|
||||||
self.render_resources
|
|
||||||
.get_shader_module(fragment_handle)
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -370,9 +396,11 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.render_resources
|
self.render_resources
|
||||||
.create_render_pipeline(&render_pipeline_descriptor)
|
.wgpu_resources
|
||||||
|
.create_render_pipeline(&self.device, &render_pipeline_descriptor)
|
||||||
};
|
};
|
||||||
self.render_resources
|
self.render_resources
|
||||||
|
.wgpu_resources
|
||||||
.set_render_pipeline(pipeline_handle, wgpu_pipeline);
|
.set_render_pipeline(pipeline_handle, wgpu_pipeline);
|
||||||
}
|
}
|
||||||
fn begin_pass(
|
fn begin_pass(
|
||||||
@ -406,15 +434,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_render_pass<'a, 'b, T>(
|
pub fn create_render_pass<'a, 'b>(
|
||||||
render_context: &'a WgpuRenderContext<T>,
|
render_context: &'a WgpuRenderContext,
|
||||||
pass_descriptor: &PassDescriptor,
|
pass_descriptor: &PassDescriptor,
|
||||||
global_render_resource_assignments: &'b RenderResourceAssignments,
|
global_render_resource_assignments: &'b RenderResourceAssignments,
|
||||||
encoder: &'a mut wgpu::CommandEncoder,
|
encoder: &'a mut wgpu::CommandEncoder,
|
||||||
) -> wgpu::RenderPass<'a>
|
) -> wgpu::RenderPass<'a> {
|
||||||
where
|
|
||||||
T: WgpuRenderResourceContextTrait + RenderResourceContext,
|
|
||||||
{
|
|
||||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
color_attachments: &pass_descriptor
|
color_attachments: &pass_descriptor
|
||||||
.color_attachments
|
.color_attachments
|
||||||
@ -437,19 +462,20 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_view<'a, T>(
|
fn get_texture_view<'a>(
|
||||||
render_context: &'a WgpuRenderContext<T>,
|
render_context: &'a WgpuRenderContext,
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
global_render_resource_assignments: &RenderResourceAssignments,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> &'a wgpu::TextureView
|
) -> &'a wgpu::TextureView {
|
||||||
where
|
|
||||||
T: WgpuRenderResourceContextTrait + RenderResourceContext,
|
|
||||||
{
|
|
||||||
match name {
|
match name {
|
||||||
resource_name::texture::SWAP_CHAIN => {
|
resource_name::texture::SWAP_CHAIN => {
|
||||||
if let Some(primary_swap_chain) = render_context
|
if let Some(primary_swap_chain) = render_context
|
||||||
.render_resources
|
.render_resources
|
||||||
.get_swap_chain_output(render_context.primary_window.as_ref().unwrap())
|
.wgpu_resources
|
||||||
|
.swap_chain_outputs
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(render_context.primary_window.as_ref().unwrap())
|
||||||
.map(|output| &output.view)
|
.map(|output| &output.view)
|
||||||
{
|
{
|
||||||
primary_swap_chain
|
primary_swap_chain
|
||||||
@ -460,7 +486,11 @@ where
|
|||||||
_ => match global_render_resource_assignments.get(name) {
|
_ => match global_render_resource_assignments.get(name) {
|
||||||
Some(resource) => render_context
|
Some(resource) => render_context
|
||||||
.render_resources
|
.render_resources
|
||||||
.get_texture(resource)
|
.wgpu_resources
|
||||||
|
.textures
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(&resource)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
None => {
|
None => {
|
||||||
// if let Some(swap_chain_output) = swap_chain_outputs.get(name) {
|
// if let Some(swap_chain_output) = swap_chain_outputs.get(name) {
|
||||||
@ -473,14 +503,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_wgpu_color_attachment_descriptor<'a, T>(
|
fn create_wgpu_color_attachment_descriptor<'a>(
|
||||||
render_context: &'a WgpuRenderContext<T>,
|
render_context: &'a WgpuRenderContext,
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
global_render_resource_assignments: &RenderResourceAssignments,
|
||||||
color_attachment_descriptor: &RenderPassColorAttachmentDescriptor,
|
color_attachment_descriptor: &RenderPassColorAttachmentDescriptor,
|
||||||
) -> wgpu::RenderPassColorAttachmentDescriptor<'a>
|
) -> wgpu::RenderPassColorAttachmentDescriptor<'a> {
|
||||||
where
|
|
||||||
T: WgpuRenderResourceContextTrait + RenderResourceContext,
|
|
||||||
{
|
|
||||||
let attachment = get_texture_view(
|
let attachment = get_texture_view(
|
||||||
render_context,
|
render_context,
|
||||||
global_render_resource_assignments,
|
global_render_resource_assignments,
|
||||||
@ -507,14 +534,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_wgpu_depth_stencil_attachment_descriptor<'a, T>(
|
fn create_wgpu_depth_stencil_attachment_descriptor<'a>(
|
||||||
render_context: &'a WgpuRenderContext<T>,
|
render_context: &'a WgpuRenderContext,
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
global_render_resource_assignments: &RenderResourceAssignments,
|
||||||
depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor,
|
depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor,
|
||||||
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a>
|
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> {
|
||||||
where
|
|
||||||
T: WgpuRenderResourceContextTrait + RenderResourceContext,
|
|
||||||
{
|
|
||||||
let attachment = get_texture_view(
|
let attachment = get_texture_view(
|
||||||
render_context,
|
render_context,
|
||||||
global_render_resource_assignments,
|
global_render_resource_assignments,
|
||||||
|
|||||||
@ -3,9 +3,8 @@ use crate::WgpuResources;
|
|||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
|
||||||
render_resource::{
|
render_resource::{
|
||||||
AssetResources, BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo,
|
AssetResources, BufferInfo, RenderResource, ResourceInfo,
|
||||||
},
|
},
|
||||||
renderer_2::RenderResourceContext,
|
renderer_2::RenderResourceContext,
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
@ -14,158 +13,18 @@ use bevy_render::{
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use bevy_window::{WindowId, Window};
|
use bevy_window::{WindowId, Window};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct WgpuRenderResourceContext {
|
pub struct WgpuRenderResourceContext {
|
||||||
pub device: Arc<wgpu::Device>,
|
pub device: Arc<wgpu::Device>,
|
||||||
pub wgpu_resources: WgpuResources,
|
pub wgpu_resources: Arc<WgpuResources>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make this name not terrible
|
|
||||||
pub trait WgpuRenderResourceContextTrait {
|
|
||||||
fn create_texture_with_data(
|
|
||||||
&mut self,
|
|
||||||
command_encoder: &mut wgpu::CommandEncoder,
|
|
||||||
texture_descriptor: &TextureDescriptor,
|
|
||||||
bytes: &[u8],
|
|
||||||
) -> RenderResource;
|
|
||||||
|
|
||||||
fn create_bind_group(
|
|
||||||
&self,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
descriptor: &wgpu::BindGroupDescriptor,
|
|
||||||
) -> wgpu::BindGroup;
|
|
||||||
fn set_bind_group(
|
|
||||||
&mut self,
|
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
bind_group: wgpu::BindGroup,
|
|
||||||
);
|
|
||||||
fn create_bind_group_layout(
|
|
||||||
&mut self,
|
|
||||||
bind_group_id: BindGroupDescriptorId,
|
|
||||||
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
|
||||||
);
|
|
||||||
fn create_render_pipeline(
|
|
||||||
&self,
|
|
||||||
descriptor: &wgpu::RenderPipelineDescriptor,
|
|
||||||
) -> wgpu::RenderPipeline;
|
|
||||||
fn set_render_pipeline(
|
|
||||||
&mut self,
|
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
|
||||||
pipeline: wgpu::RenderPipeline,
|
|
||||||
);
|
|
||||||
fn get_bind_group(
|
|
||||||
&self,
|
|
||||||
bind_group_id: BindGroupDescriptorId,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
) -> Option<&wgpu::BindGroup>;
|
|
||||||
fn get_bind_group_layout(
|
|
||||||
&self,
|
|
||||||
bind_group_id: BindGroupDescriptorId,
|
|
||||||
) -> Option<&wgpu::BindGroupLayout>;
|
|
||||||
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer>;
|
|
||||||
fn get_swap_chain_output(&self, window_id: &WindowId) -> Option<&wgpu::SwapChainOutput>;
|
|
||||||
fn get_texture(&self, render_resource: RenderResource) -> Option<&wgpu::TextureView>;
|
|
||||||
fn get_sampler(&self, render_resource: RenderResource) -> Option<&wgpu::Sampler>;
|
|
||||||
fn get_pipeline(&self, pipeline: Handle<PipelineDescriptor>) -> Option<&wgpu::RenderPipeline>;
|
|
||||||
fn get_shader_module(&self, shader: Handle<Shader>) -> Option<&wgpu::ShaderModule>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WgpuRenderResourceContextTrait for WgpuRenderResourceContext {
|
|
||||||
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer> {
|
|
||||||
self.wgpu_resources.buffers.get(&render_resource)
|
|
||||||
}
|
|
||||||
fn create_texture_with_data(
|
|
||||||
&mut self,
|
|
||||||
command_encoder: &mut wgpu::CommandEncoder,
|
|
||||||
texture_descriptor: &TextureDescriptor,
|
|
||||||
bytes: &[u8],
|
|
||||||
) -> RenderResource {
|
|
||||||
self.wgpu_resources.create_texture_with_data(
|
|
||||||
&self.device,
|
|
||||||
command_encoder,
|
|
||||||
texture_descriptor,
|
|
||||||
bytes,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn create_bind_group(
|
|
||||||
&self,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
descriptor: &wgpu::BindGroupDescriptor,
|
|
||||||
) -> wgpu::BindGroup {
|
|
||||||
self.wgpu_resources
|
|
||||||
.create_bind_group(&self.device, render_resource_set_id, descriptor)
|
|
||||||
}
|
|
||||||
fn create_bind_group_layout(
|
|
||||||
&mut self,
|
|
||||||
bind_group_id: BindGroupDescriptorId,
|
|
||||||
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
|
||||||
) {
|
|
||||||
self.wgpu_resources
|
|
||||||
.create_bind_group_layout(&self.device, bind_group_id, descriptor);
|
|
||||||
}
|
|
||||||
fn create_render_pipeline(
|
|
||||||
&self,
|
|
||||||
descriptor: &wgpu::RenderPipelineDescriptor,
|
|
||||||
) -> wgpu::RenderPipeline {
|
|
||||||
self.wgpu_resources
|
|
||||||
.create_render_pipeline(&self.device, descriptor)
|
|
||||||
}
|
|
||||||
fn get_bind_group(
|
|
||||||
&self,
|
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
) -> Option<&wgpu::BindGroup> {
|
|
||||||
self.wgpu_resources
|
|
||||||
.get_bind_group(bind_group_descriptor_id, render_resource_set_id)
|
|
||||||
}
|
|
||||||
fn get_bind_group_layout(
|
|
||||||
&self,
|
|
||||||
bind_group_id: BindGroupDescriptorId,
|
|
||||||
) -> Option<&wgpu::BindGroupLayout> {
|
|
||||||
self.wgpu_resources.bind_group_layouts.get(&bind_group_id)
|
|
||||||
}
|
|
||||||
fn get_texture(&self, render_resource: RenderResource) -> Option<&wgpu::TextureView> {
|
|
||||||
self.wgpu_resources.textures.get(&render_resource)
|
|
||||||
}
|
|
||||||
fn get_sampler(&self, render_resource: RenderResource) -> Option<&wgpu::Sampler> {
|
|
||||||
self.wgpu_resources.samplers.get(&render_resource)
|
|
||||||
}
|
|
||||||
fn get_pipeline(&self, pipeline: Handle<PipelineDescriptor>) -> Option<&wgpu::RenderPipeline> {
|
|
||||||
self.wgpu_resources.render_pipelines.get(&pipeline)
|
|
||||||
}
|
|
||||||
fn get_shader_module(&self, shader: Handle<Shader>) -> Option<&wgpu::ShaderModule> {
|
|
||||||
self.wgpu_resources.shader_modules.get(&shader)
|
|
||||||
}
|
|
||||||
fn set_bind_group(
|
|
||||||
&mut self,
|
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
bind_group: wgpu::BindGroup,
|
|
||||||
) {
|
|
||||||
self.wgpu_resources.set_bind_group(
|
|
||||||
bind_group_descriptor_id,
|
|
||||||
render_resource_set_id,
|
|
||||||
bind_group,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
fn set_render_pipeline(
|
|
||||||
&mut self,
|
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
|
||||||
pipeline: wgpu::RenderPipeline,
|
|
||||||
) {
|
|
||||||
self.wgpu_resources
|
|
||||||
.set_render_pipeline(pipeline_handle, pipeline);
|
|
||||||
}
|
|
||||||
fn get_swap_chain_output(&self, window_id: &WindowId) -> Option<&wgpu::SwapChainOutput> {
|
|
||||||
self.wgpu_resources.swap_chain_outputs.get(window_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WgpuRenderResourceContext {
|
impl WgpuRenderResourceContext {
|
||||||
pub fn new(device: Arc<wgpu::Device>) -> Self {
|
pub fn new(device: Arc<wgpu::Device>) -> Self {
|
||||||
WgpuRenderResourceContext {
|
WgpuRenderResourceContext {
|
||||||
device,
|
device,
|
||||||
wgpu_resources: WgpuResources::default(),
|
wgpu_resources: Arc::new(WgpuResources::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,7 +110,7 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
|||||||
shader_handle: Handle<Shader>,
|
shader_handle: Handle<Shader>,
|
||||||
shader_storage: &AssetStorage<Shader>,
|
shader_storage: &AssetStorage<Shader>,
|
||||||
) {
|
) {
|
||||||
if self.get_shader_module(shader_handle).is_some() {
|
if self.wgpu_resources.shader_modules.read().unwrap().get(&shader_handle).is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,307 +0,0 @@
|
|||||||
use crate::WgpuResources;
|
|
||||||
|
|
||||||
use super::WgpuRenderResourceContextTrait;
|
|
||||||
use bevy_asset::Handle;
|
|
||||||
use bevy_render::{
|
|
||||||
mesh::Mesh,
|
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
|
||||||
render_resource::{
|
|
||||||
AssetResources, BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo,
|
|
||||||
},
|
|
||||||
renderer_2::RenderResourceContext,
|
|
||||||
shader::Shader,
|
|
||||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
|
||||||
};
|
|
||||||
use bevy_window::{WindowId, Window};
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub struct WgpuTransactionalRenderResourceContext<'a> {
|
|
||||||
pub device: Arc<wgpu::Device>,
|
|
||||||
pub local_resources: WgpuResources,
|
|
||||||
pub parent_resources: &'a WgpuResources,
|
|
||||||
removed_resources: Vec<RenderResource>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> WgpuRenderResourceContextTrait for WgpuTransactionalRenderResourceContext<'a> {
|
|
||||||
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer> {
|
|
||||||
let local = self.local_resources.buffers.get(&render_resource);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.parent_resources.buffers.get(&render_resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_texture_with_data(
|
|
||||||
&mut self,
|
|
||||||
command_encoder: &mut wgpu::CommandEncoder,
|
|
||||||
texture_descriptor: &TextureDescriptor,
|
|
||||||
bytes: &[u8],
|
|
||||||
) -> RenderResource {
|
|
||||||
self.local_resources.create_texture_with_data(
|
|
||||||
&self.device,
|
|
||||||
command_encoder,
|
|
||||||
texture_descriptor,
|
|
||||||
bytes,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn create_bind_group(
|
|
||||||
&self,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
descriptor: &wgpu::BindGroupDescriptor,
|
|
||||||
) -> wgpu::BindGroup {
|
|
||||||
self.local_resources
|
|
||||||
.create_bind_group(&self.device, render_resource_set_id, descriptor)
|
|
||||||
}
|
|
||||||
fn create_bind_group_layout(
|
|
||||||
&mut self,
|
|
||||||
bind_group_id: BindGroupDescriptorId,
|
|
||||||
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
|
||||||
) {
|
|
||||||
self.local_resources
|
|
||||||
.create_bind_group_layout(&self.device, bind_group_id, descriptor);
|
|
||||||
}
|
|
||||||
fn create_render_pipeline(
|
|
||||||
&self,
|
|
||||||
descriptor: &wgpu::RenderPipelineDescriptor,
|
|
||||||
) -> wgpu::RenderPipeline {
|
|
||||||
self.local_resources
|
|
||||||
.create_render_pipeline(&self.device, descriptor)
|
|
||||||
}
|
|
||||||
fn get_bind_group(
|
|
||||||
&self,
|
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
) -> Option<&wgpu::BindGroup> {
|
|
||||||
let local = self
|
|
||||||
.local_resources
|
|
||||||
.get_bind_group(bind_group_descriptor_id, render_resource_set_id);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
self.parent_resources
|
|
||||||
.get_bind_group(bind_group_descriptor_id, render_resource_set_id)
|
|
||||||
}
|
|
||||||
fn get_bind_group_layout(
|
|
||||||
&self,
|
|
||||||
bind_group_id: BindGroupDescriptorId,
|
|
||||||
) -> Option<&wgpu::BindGroupLayout> {
|
|
||||||
let local = self.local_resources.bind_group_layouts.get(&bind_group_id);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
self.parent_resources.bind_group_layouts.get(&bind_group_id)
|
|
||||||
}
|
|
||||||
fn get_texture(&self, render_resource: RenderResource) -> Option<&wgpu::TextureView> {
|
|
||||||
let local = self.local_resources.textures.get(&render_resource);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
self.parent_resources.textures.get(&render_resource)
|
|
||||||
}
|
|
||||||
fn get_sampler(&self, render_resource: RenderResource) -> Option<&wgpu::Sampler> {
|
|
||||||
let local = self.local_resources.samplers.get(&render_resource);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
self.parent_resources.samplers.get(&render_resource)
|
|
||||||
}
|
|
||||||
fn get_pipeline(&self, pipeline: Handle<PipelineDescriptor>) -> Option<&wgpu::RenderPipeline> {
|
|
||||||
let local = self.local_resources.render_pipelines.get(&pipeline);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
self.parent_resources.render_pipelines.get(&pipeline)
|
|
||||||
}
|
|
||||||
fn get_shader_module(&self, shader: Handle<Shader>) -> Option<&wgpu::ShaderModule> {
|
|
||||||
let local = self.local_resources.shader_modules.get(&shader);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
self.parent_resources.shader_modules.get(&shader)
|
|
||||||
}
|
|
||||||
fn set_bind_group(
|
|
||||||
&mut self,
|
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
|
||||||
render_resource_set_id: RenderResourceSetId,
|
|
||||||
bind_group: wgpu::BindGroup,
|
|
||||||
) {
|
|
||||||
self.local_resources.set_bind_group(
|
|
||||||
bind_group_descriptor_id,
|
|
||||||
render_resource_set_id,
|
|
||||||
bind_group,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
fn set_render_pipeline(
|
|
||||||
&mut self,
|
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
|
||||||
pipeline: wgpu::RenderPipeline,
|
|
||||||
) {
|
|
||||||
self.local_resources
|
|
||||||
.set_render_pipeline(pipeline_handle, pipeline);
|
|
||||||
}
|
|
||||||
fn get_swap_chain_output(
|
|
||||||
&self,
|
|
||||||
window_id: &bevy_window::WindowId,
|
|
||||||
) -> Option<&wgpu::SwapChainOutput> {
|
|
||||||
let local = self.local_resources.swap_chain_outputs.get(window_id);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
self.parent_resources.swap_chain_outputs.get(window_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> WgpuTransactionalRenderResourceContext<'a> {
|
|
||||||
pub fn new(device: Arc<wgpu::Device>, parent_resources: &'a WgpuResources) -> Self {
|
|
||||||
WgpuTransactionalRenderResourceContext {
|
|
||||||
device,
|
|
||||||
local_resources: WgpuResources::default(),
|
|
||||||
parent_resources,
|
|
||||||
removed_resources: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> RenderResourceContext for WgpuTransactionalRenderResourceContext<'a> {
|
|
||||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
|
|
||||||
self.local_resources
|
|
||||||
.create_sampler(&self.device, sampler_descriptor)
|
|
||||||
}
|
|
||||||
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource {
|
|
||||||
self.local_resources
|
|
||||||
.create_texture(&self.device, texture_descriptor)
|
|
||||||
}
|
|
||||||
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource {
|
|
||||||
self.local_resources
|
|
||||||
.create_buffer(&self.device, buffer_info)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: clean this up
|
|
||||||
fn create_buffer_mapped(
|
|
||||||
&mut self,
|
|
||||||
buffer_info: BufferInfo,
|
|
||||||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext),
|
|
||||||
) -> RenderResource {
|
|
||||||
let buffer = WgpuResources::begin_create_buffer_mapped_transactional_render_context(
|
|
||||||
&buffer_info,
|
|
||||||
self,
|
|
||||||
setup_data,
|
|
||||||
);
|
|
||||||
self.local_resources.assign_buffer(buffer, buffer_info)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource {
|
|
||||||
self.local_resources
|
|
||||||
.create_buffer_with_data(&self.device, buffer_info, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_buffer(&mut self, resource: RenderResource) {
|
|
||||||
self.local_resources.remove_buffer(resource);
|
|
||||||
self.removed_resources.push(resource);
|
|
||||||
}
|
|
||||||
fn remove_texture(&mut self, resource: RenderResource) {
|
|
||||||
self.local_resources.remove_texture(resource);
|
|
||||||
self.removed_resources.push(resource);
|
|
||||||
}
|
|
||||||
fn remove_sampler(&mut self, resource: RenderResource) {
|
|
||||||
self.local_resources.remove_sampler(resource);
|
|
||||||
self.removed_resources.push(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
|
|
||||||
let local = self
|
|
||||||
.local_resources
|
|
||||||
.asset_resources
|
|
||||||
.get_texture_resource(texture);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.parent_resources
|
|
||||||
.asset_resources
|
|
||||||
.get_texture_resource(texture)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
|
|
||||||
let local = self
|
|
||||||
.local_resources
|
|
||||||
.asset_resources
|
|
||||||
.get_texture_sampler_resource(texture);
|
|
||||||
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.parent_resources
|
|
||||||
.asset_resources
|
|
||||||
.get_texture_sampler_resource(texture)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
|
|
||||||
let local = self
|
|
||||||
.local_resources
|
|
||||||
.asset_resources
|
|
||||||
.get_mesh_vertices_resource(mesh);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.parent_resources
|
|
||||||
.asset_resources
|
|
||||||
.get_mesh_vertices_resource(mesh)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
|
|
||||||
let local = self
|
|
||||||
.local_resources
|
|
||||||
.asset_resources
|
|
||||||
.get_mesh_indices_resource(mesh);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.parent_resources
|
|
||||||
.asset_resources
|
|
||||||
.get_mesh_indices_resource(mesh)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
|
|
||||||
let local = self.local_resources.get_resource_info(resource);
|
|
||||||
if local.is_some() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.parent_resources.get_resource_info(resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn asset_resources(&self) -> &AssetResources {
|
|
||||||
&self.local_resources.asset_resources
|
|
||||||
}
|
|
||||||
fn asset_resources_mut(&mut self) -> &mut AssetResources {
|
|
||||||
&mut self.local_resources.asset_resources
|
|
||||||
}
|
|
||||||
fn create_shader_module(
|
|
||||||
&mut self,
|
|
||||||
shader_handle: Handle<Shader>,
|
|
||||||
shader_storage: &bevy_asset::AssetStorage<Shader>,
|
|
||||||
) {
|
|
||||||
if self.get_shader_module(shader_handle).is_some() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let shader = shader_storage.get(&shader_handle).unwrap();
|
|
||||||
self.local_resources
|
|
||||||
.create_shader_module(&self.device, shader_handle, shader);
|
|
||||||
}
|
|
||||||
fn create_swap_chain(&mut self, window: &Window) {
|
|
||||||
self.local_resources
|
|
||||||
.create_window_swap_chain(&self.device, window)
|
|
||||||
}
|
|
||||||
fn next_swap_chain_texture(&mut self, window_id: bevy_window::WindowId) {
|
|
||||||
self.local_resources.next_swap_chain_texture(window_id);
|
|
||||||
}
|
|
||||||
fn drop_swap_chain_texture(&mut self, window_id: WindowId) {
|
|
||||||
self.local_resources.remove_swap_chain_texture(window_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +1,48 @@
|
|||||||
use crate::renderer_2::{WgpuRenderContext, WgpuRenderResourceContextTrait};
|
use crate::renderer_2::WgpuRenderContext;
|
||||||
|
use bevy_asset::Handle;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pass::RenderPass,
|
pass::RenderPass,
|
||||||
pipeline::PipelineDescriptor,
|
pipeline::PipelineDescriptor,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo,
|
RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo,
|
||||||
},
|
},
|
||||||
renderer_2::{RenderContext, RenderResourceContext},
|
renderer_2::RenderContext,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, ops::Range};
|
use std::{collections::HashMap, ops::Range};
|
||||||
|
|
||||||
pub struct WgpuRenderPass<'a, T>
|
pub struct WgpuRenderPass<'a> {
|
||||||
where
|
|
||||||
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
|
||||||
{
|
|
||||||
pub render_pass: wgpu::RenderPass<'a>,
|
pub render_pass: wgpu::RenderPass<'a>,
|
||||||
pub render_context: &'a WgpuRenderContext<T>,
|
pub render_context: &'a WgpuRenderContext,
|
||||||
pub bound_bind_groups: HashMap<u32, RenderResourceSetId>,
|
pub bound_bind_groups: HashMap<u32, RenderResourceSetId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> RenderPass for WgpuRenderPass<'a, T>
|
impl<'a> RenderPass for WgpuRenderPass<'a> {
|
||||||
where
|
|
||||||
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
|
||||||
{
|
|
||||||
fn get_render_context(&self) -> &dyn RenderContext {
|
fn get_render_context(&self) -> &dyn RenderContext {
|
||||||
self.render_context
|
self.render_context
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64) {
|
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64) {
|
||||||
let buffer = self
|
let buffers = self
|
||||||
.render_context
|
.render_context
|
||||||
.render_resources
|
.render_resources
|
||||||
.get_buffer(resource)
|
.wgpu_resources
|
||||||
|
.buffers
|
||||||
|
.read()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let buffer = buffers.get(&resource).unwrap();
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_vertex_buffer(start_slot, &buffer, offset, 0);
|
.set_vertex_buffer(start_slot, &buffer, offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64) {
|
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64) {
|
||||||
let buffer = self
|
let buffers = self
|
||||||
.render_context
|
.render_context
|
||||||
.render_resources
|
.render_resources
|
||||||
.get_buffer(resource)
|
.wgpu_resources
|
||||||
|
.buffers
|
||||||
|
.read()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let buffer = buffers.get(&resource).unwrap();
|
||||||
self.render_pass.set_index_buffer(&buffer, offset, 0);
|
self.render_pass.set_index_buffer(&buffer, offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +56,7 @@ where
|
|||||||
pipeline_descriptor: &PipelineDescriptor,
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
) -> Option<Range<u32>> {
|
) -> Option<Range<u32>> {
|
||||||
let pipeline_layout = pipeline_descriptor.get_layout()
|
let pipeline_layout = pipeline_descriptor.get_layout().unwrap();
|
||||||
.unwrap();
|
|
||||||
// PERF: vertex buffer lookup comes at a cost when vertex buffers aren't in render_resource_assignments. iterating over render_resource_assignment vertex buffers
|
// PERF: vertex buffer lookup comes at a cost when vertex buffers aren't in render_resource_assignments. iterating over render_resource_assignment vertex buffers
|
||||||
// would likely be faster
|
// would likely be faster
|
||||||
let mut indices = None;
|
let mut indices = None;
|
||||||
@ -102,6 +102,7 @@ where
|
|||||||
if let Some(wgpu_bind_group) = self
|
if let Some(wgpu_bind_group) = self
|
||||||
.render_context
|
.render_context
|
||||||
.render_resources
|
.render_resources
|
||||||
|
.wgpu_resources
|
||||||
.get_bind_group(bind_group.id, *render_resource_set_id)
|
.get_bind_group(bind_group.id, *render_resource_set_id)
|
||||||
{
|
{
|
||||||
const EMPTY: &'static [u32] = &[];
|
const EMPTY: &'static [u32] = &[];
|
||||||
@ -148,8 +149,17 @@ where
|
|||||||
|
|
||||||
indices
|
indices
|
||||||
}
|
}
|
||||||
fn set_pipeline(&mut self, pipeline_handle: bevy_asset::Handle<PipelineDescriptor>) {
|
fn set_pipeline(&mut self, pipeline_handle: Handle<PipelineDescriptor>) {
|
||||||
let pipeline = self.render_context.render_resources.get_pipeline(pipeline_handle).expect("Attempted to use a pipeline that does not exist in this RenderPass's RenderContext");
|
let render_pipelines = self
|
||||||
|
.render_context
|
||||||
|
.render_resources
|
||||||
|
.wgpu_resources
|
||||||
|
.render_pipelines
|
||||||
|
.read()
|
||||||
|
.unwrap();
|
||||||
|
let pipeline = render_pipelines.get(&pipeline_handle).expect(
|
||||||
|
"Attempted to use a pipeline that does not exist in this RenderPass's RenderContext",
|
||||||
|
);
|
||||||
self.render_pass.set_pipeline(pipeline);
|
self.render_pass.set_pipeline(pipeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
use super::WgpuResources;
|
|
||||||
use crate::renderer_2::{
|
use crate::renderer_2::{
|
||||||
render_resource_sets_system, WgpuRenderContext, WgpuRenderResourceContext,
|
render_resource_sets_system, WgpuRenderContext, WgpuRenderResourceContext,
|
||||||
WgpuTransactionalRenderResourceContext,
|
|
||||||
};
|
};
|
||||||
use bevy_app::{EventReader, Events};
|
use bevy_app::{EventReader, Events};
|
||||||
use bevy_asset::AssetStorage;
|
use bevy_asset::AssetStorage;
|
||||||
@ -9,14 +7,14 @@ use bevy_render::{
|
|||||||
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
|
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
|
||||||
render_graph::RenderGraph,
|
render_graph::RenderGraph,
|
||||||
render_resource::RenderResourceAssignments,
|
render_resource::RenderResourceAssignments,
|
||||||
renderer_2::{RenderContext, RenderResourceContext},
|
renderer_2::{GlobalRenderResourceContext, RenderContext, RenderResourceContext},
|
||||||
};
|
};
|
||||||
use bevy_window::{WindowCreated, WindowResized, Windows};
|
use bevy_window::{WindowCreated, WindowResized, Windows};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
use std::{collections::HashSet, ops::Deref, sync::Arc};
|
use std::{any::Any, collections::HashSet, ops::Deref, sync::Arc};
|
||||||
|
|
||||||
pub struct WgpuRenderer {
|
pub struct WgpuRenderer {
|
||||||
pub global_context: WgpuRenderContext<WgpuRenderResourceContext>,
|
pub device: Arc<wgpu::Device>,
|
||||||
pub queue: wgpu::Queue,
|
pub queue: wgpu::Queue,
|
||||||
pub window_resized_event_reader: EventReader<WindowResized>,
|
pub window_resized_event_reader: EventReader<WindowResized>,
|
||||||
pub window_created_event_reader: EventReader<WindowCreated>,
|
pub window_created_event_reader: EventReader<WindowCreated>,
|
||||||
@ -48,10 +46,7 @@ impl WgpuRenderer {
|
|||||||
.await;
|
.await;
|
||||||
let device = Arc::new(device);
|
let device = Arc::new(device);
|
||||||
WgpuRenderer {
|
WgpuRenderer {
|
||||||
global_context: WgpuRenderContext::new(
|
device,
|
||||||
device.clone(),
|
|
||||||
WgpuRenderResourceContext::new(device),
|
|
||||||
),
|
|
||||||
queue,
|
queue,
|
||||||
window_resized_event_reader,
|
window_resized_event_reader,
|
||||||
window_created_event_reader,
|
window_created_event_reader,
|
||||||
@ -61,8 +56,8 @@ impl WgpuRenderer {
|
|||||||
|
|
||||||
pub fn initialize_resource_providers(
|
pub fn initialize_resource_providers(
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &mut Resources,
|
resources: &Resources,
|
||||||
render_context: &mut WgpuRenderContext<WgpuRenderResourceContext>,
|
render_context: &mut WgpuRenderContext,
|
||||||
) {
|
) {
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||||
@ -74,8 +69,8 @@ impl WgpuRenderer {
|
|||||||
world: &World,
|
world: &World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
device: Arc<wgpu::Device>,
|
device: Arc<wgpu::Device>,
|
||||||
global_wgpu_resources: &WgpuResources,
|
render_resource_context: &WgpuRenderResourceContext,
|
||||||
) -> (Vec<wgpu::CommandBuffer>, Vec<WgpuResources>) {
|
) -> Vec<wgpu::CommandBuffer> {
|
||||||
let max_thread_count = 8;
|
let max_thread_count = 8;
|
||||||
let (sender, receiver) = crossbeam_channel::bounded(max_thread_count);
|
let (sender, receiver) = crossbeam_channel::bounded(max_thread_count);
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
@ -86,21 +81,15 @@ impl WgpuRenderer {
|
|||||||
crossbeam_utils::thread::scope(|s| {
|
crossbeam_utils::thread::scope(|s| {
|
||||||
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
||||||
let device = device.clone();
|
let device = device.clone();
|
||||||
let resource_device = device.clone();
|
|
||||||
let sender = sender.clone();
|
let sender = sender.clone();
|
||||||
let global_wgpu_resources = &*global_wgpu_resources;
|
|
||||||
let world = &*world;
|
let world = &*world;
|
||||||
let resources = &*resources;
|
let resources = &*resources;
|
||||||
actual_thread_count += 1;
|
actual_thread_count += 1;
|
||||||
// println!("spawn {}", resource_provider_chunk.len());
|
// println!("spawn {}", resource_provider_chunk.len());
|
||||||
|
let render_resource_context = render_resource_context.clone();
|
||||||
s.spawn(move |_| {
|
s.spawn(move |_| {
|
||||||
let mut render_context = WgpuRenderContext::new(
|
let mut render_context =
|
||||||
device,
|
WgpuRenderContext::new(device, render_resource_context);
|
||||||
WgpuTransactionalRenderResourceContext::new(
|
|
||||||
resource_device,
|
|
||||||
global_wgpu_resources,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
for resource_provider in resource_provider_chunk.iter_mut() {
|
for resource_provider in resource_provider_chunk.iter_mut() {
|
||||||
resource_provider.update(&mut render_context, world, resources);
|
resource_provider.update(&mut render_context, world, resources);
|
||||||
}
|
}
|
||||||
@ -111,37 +100,28 @@ impl WgpuRenderer {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut command_buffers = Vec::new();
|
let mut command_buffers = Vec::new();
|
||||||
let mut local_resources = Vec::new();
|
|
||||||
for _i in 0..actual_thread_count {
|
for _i in 0..actual_thread_count {
|
||||||
let (command_buffer, render_resources) = receiver.recv().unwrap();
|
let command_buffer = receiver.recv().unwrap();
|
||||||
if let Some(command_buffer) = command_buffer {
|
if let Some(command_buffer) = command_buffer {
|
||||||
command_buffers.push(command_buffer);
|
command_buffers.push(command_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
local_resources.push(render_resources.local_resources);
|
|
||||||
|
|
||||||
// println!("got {}", i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(command_buffers, local_resources)
|
command_buffers
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_resource_providers(
|
pub fn update_resource_providers(
|
||||||
|
&mut self,
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &mut Resources,
|
resources: &Resources,
|
||||||
queue: &mut wgpu::Queue,
|
render_resource_context: &WgpuRenderResourceContext,
|
||||||
device: Arc<wgpu::Device>,
|
|
||||||
global_wgpu_resources: &mut WgpuResources,
|
|
||||||
) {
|
) {
|
||||||
let (mut command_buffers, local_resources) = Self::parallel_resource_provider_update(
|
let mut command_buffers = Self::parallel_resource_provider_update(
|
||||||
world,
|
world,
|
||||||
resources,
|
resources,
|
||||||
device.clone(),
|
self.device.clone(),
|
||||||
global_wgpu_resources,
|
render_resource_context,
|
||||||
);
|
);
|
||||||
for local_resource in local_resources {
|
|
||||||
global_wgpu_resources.consume(local_resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
@ -150,15 +130,13 @@ impl WgpuRenderer {
|
|||||||
// crossbeam_utils::thread::scope(|s| {
|
// crossbeam_utils::thread::scope(|s| {
|
||||||
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
||||||
// TODO: try to unify this Device usage
|
// TODO: try to unify this Device usage
|
||||||
let device = device.clone();
|
let device = self.device.clone();
|
||||||
let resource_device = device.clone();
|
let resource_device = device.clone();
|
||||||
// let sender = sender.clone();
|
// let sender = sender.clone();
|
||||||
// s.spawn(|_| {
|
// s.spawn(|_| {
|
||||||
// TODO: replace WgpuResources with Global+Local resources
|
// TODO: replace WgpuResources with Global+Local resources
|
||||||
let mut render_context = WgpuRenderContext::new(
|
let mut render_context =
|
||||||
device,
|
WgpuRenderContext::new(device, render_resource_context.clone());
|
||||||
WgpuTransactionalRenderResourceContext::new(resource_device, global_wgpu_resources),
|
|
||||||
);
|
|
||||||
for resource_provider in resource_provider_chunk.iter_mut() {
|
for resource_provider in resource_provider_chunk.iter_mut() {
|
||||||
resource_provider.finish_update(&mut render_context, world, resources);
|
resource_provider.finish_update(&mut render_context, world, resources);
|
||||||
}
|
}
|
||||||
@ -168,42 +146,37 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
// });
|
// });
|
||||||
|
|
||||||
let mut local_resources = Vec::new();
|
for command_buffer in results {
|
||||||
for (command_buffer, render_resources) in results {
|
|
||||||
// for i in 0..thread_count {
|
// for i in 0..thread_count {
|
||||||
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap();
|
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap();
|
||||||
if let Some(command_buffer) = command_buffer {
|
if let Some(command_buffer) = command_buffer {
|
||||||
command_buffers.push(command_buffer);
|
command_buffers.push(command_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
local_resources.push(render_resources.local_resources);
|
|
||||||
// println!("got {}", i);
|
// println!("got {}", i);
|
||||||
}
|
}
|
||||||
for local_resource in local_resources {
|
|
||||||
global_wgpu_resources.consume(local_resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
queue.submit(&command_buffers);
|
self.queue.submit(&command_buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_queued_textures(&mut self, resources: &mut Resources) {
|
pub fn create_queued_textures(
|
||||||
|
&mut self,
|
||||||
|
resources: &Resources,
|
||||||
|
global_render_resources: &mut WgpuRenderResourceContext,
|
||||||
|
) {
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
let mut render_resource_assignments =
|
let mut render_resource_assignments =
|
||||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||||
for (name, texture_descriptor) in render_graph.queued_textures.drain(..) {
|
for (name, texture_descriptor) in render_graph.queued_textures.drain(..) {
|
||||||
let resource = self
|
let resource = global_render_resources.create_texture(&texture_descriptor);
|
||||||
.global_context
|
|
||||||
.resources_mut()
|
|
||||||
.create_texture(&texture_descriptor);
|
|
||||||
render_resource_assignments.set(&name, resource);
|
render_resource_assignments.set(&name, resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_window_resized_events(
|
pub fn handle_window_resized_events(
|
||||||
resources: &mut Resources,
|
&mut self,
|
||||||
device: &wgpu::Device,
|
resources: &Resources,
|
||||||
wgpu_resources: &mut WgpuResources,
|
global_render_resources: &mut WgpuRenderResourceContext,
|
||||||
window_resized_event_reader: &mut EventReader<WindowResized>,
|
|
||||||
) {
|
) {
|
||||||
let windows = resources.get::<Windows>().unwrap();
|
let windows = resources.get::<Windows>().unwrap();
|
||||||
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
||||||
@ -211,7 +184,7 @@ impl WgpuRenderer {
|
|||||||
// iterate in reverse order so we can handle the latest window resize event first for each window.
|
// iterate in reverse order so we can handle the latest window resize event first for each window.
|
||||||
// we skip earlier events for the same window because it results in redundant work
|
// we skip earlier events for the same window because it results in redundant work
|
||||||
for window_resized_event in window_resized_events
|
for window_resized_event in window_resized_events
|
||||||
.iter(window_resized_event_reader)
|
.iter(&mut self.window_resized_event_reader)
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
if handled_windows.contains(&window_resized_event.id) {
|
if handled_windows.contains(&window_resized_event.id) {
|
||||||
@ -223,21 +196,22 @@ impl WgpuRenderer {
|
|||||||
.expect("Received window resized event for non-existent window");
|
.expect("Received window resized event for non-existent window");
|
||||||
|
|
||||||
// TODO: consider making this a WgpuRenderContext method
|
// TODO: consider making this a WgpuRenderContext method
|
||||||
wgpu_resources.create_window_swap_chain(device, window);
|
global_render_resources.create_swap_chain(window);
|
||||||
|
|
||||||
handled_windows.insert(window_resized_event.id);
|
handled_windows.insert(window_resized_event.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_window_created_events(
|
pub fn handle_window_created_events(
|
||||||
resources: &mut Resources,
|
&mut self,
|
||||||
device: &wgpu::Device,
|
resources: &Resources,
|
||||||
wgpu_resources: &mut WgpuResources,
|
global_render_resource_context: &mut WgpuRenderResourceContext,
|
||||||
window_created_event_reader: &mut EventReader<WindowCreated>,
|
|
||||||
) {
|
) {
|
||||||
let windows = resources.get::<Windows>().unwrap();
|
let windows = resources.get::<Windows>().unwrap();
|
||||||
let window_created_events = resources.get::<Events<WindowCreated>>().unwrap();
|
let window_created_events = resources.get::<Events<WindowCreated>>().unwrap();
|
||||||
for window_created_event in window_created_events.iter(window_created_event_reader) {
|
for window_created_event in
|
||||||
|
window_created_events.iter(&mut self.window_created_event_reader)
|
||||||
|
{
|
||||||
let window = windows
|
let window = windows
|
||||||
.get(window_created_event.id)
|
.get(window_created_event.id)
|
||||||
.expect("Received window created event for non-existent window");
|
.expect("Received window created event for non-existent window");
|
||||||
@ -246,49 +220,81 @@ impl WgpuRenderer {
|
|||||||
let winit_windows = resources.get::<bevy_winit::WinitWindows>().unwrap();
|
let winit_windows = resources.get::<bevy_winit::WinitWindows>().unwrap();
|
||||||
let primary_winit_window = winit_windows.get_window(window.id).unwrap();
|
let primary_winit_window = winit_windows.get_window(window.id).unwrap();
|
||||||
let surface = wgpu::Surface::create(primary_winit_window.deref());
|
let surface = wgpu::Surface::create(primary_winit_window.deref());
|
||||||
wgpu_resources.set_window_surface(window.id, surface);
|
global_render_resource_context
|
||||||
wgpu_resources.create_window_swap_chain(device, window);
|
.wgpu_resources
|
||||||
|
.set_window_surface(window.id, surface);
|
||||||
|
global_render_resource_context.create_swap_chain(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_global_render_resource_context(&self, resources: &mut Resources) {
|
||||||
|
resources.insert(GlobalRenderResourceContext::new(
|
||||||
|
WgpuRenderResourceContext::new(self.device.clone()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
||||||
Self::handle_window_created_events(
|
|
||||||
resources,
|
|
||||||
&self.global_context.device,
|
|
||||||
&mut self.global_context.render_resources.wgpu_resources,
|
|
||||||
&mut self.window_created_event_reader,
|
|
||||||
);
|
|
||||||
Self::handle_window_resized_events(
|
|
||||||
resources,
|
|
||||||
&self.global_context.device,
|
|
||||||
&mut self.global_context.render_resources.wgpu_resources,
|
|
||||||
&mut self.window_resized_event_reader,
|
|
||||||
);
|
|
||||||
if !self.intialized {
|
if !self.intialized {
|
||||||
Self::initialize_resource_providers(world, resources, &mut self.global_context);
|
self.create_global_render_resource_context(resources);
|
||||||
let buffer = self.global_context.finish_encoder();
|
|
||||||
if let Some(buffer) = buffer {
|
|
||||||
self.queue.submit(&[buffer]);
|
|
||||||
}
|
|
||||||
self.intialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::update_resource_providers(
|
let mut encoder = {
|
||||||
world,
|
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
|
||||||
resources,
|
let mut any_context = (&mut global_context.context) as &mut dyn Any;
|
||||||
&mut self.queue,
|
// let mut any_context = (&mut global_context.context);
|
||||||
self.global_context.device.clone(),
|
// println!("{}", std::any::type_name_of_val(any_context));
|
||||||
&mut self.global_context.render_resources.wgpu_resources,
|
let mut render_resource_context = any_context
|
||||||
);
|
.downcast_mut::<WgpuRenderResourceContext>()
|
||||||
|
.unwrap();
|
||||||
|
panic!("ahh");
|
||||||
|
|
||||||
update_shader_assignments(world, resources, &self.global_context);
|
// let mut render_resource_context = any_context
|
||||||
self.create_queued_textures(resources);
|
// .downcast_mut::<WgpuRenderResourceContext>()
|
||||||
|
// .unwrap();
|
||||||
|
self.handle_window_created_events(resources, render_resource_context);
|
||||||
|
|
||||||
|
self.handle_window_resized_events(resources, render_resource_context);
|
||||||
|
let mut render_context =
|
||||||
|
WgpuRenderContext::new(self.device.clone(), render_resource_context.clone());
|
||||||
|
if !self.intialized {
|
||||||
|
Self::initialize_resource_providers(world, resources, &mut render_context);
|
||||||
|
let buffer = render_context.finish();
|
||||||
|
if let Some(buffer) = buffer {
|
||||||
|
self.queue.submit(&[buffer]);
|
||||||
|
}
|
||||||
|
self.intialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.update_resource_providers(
|
||||||
|
world,
|
||||||
|
resources,
|
||||||
|
render_resource_context,
|
||||||
|
);
|
||||||
|
|
||||||
|
update_shader_assignments(world, resources, &render_context);
|
||||||
|
self.create_queued_textures(resources, &mut render_context.render_resources);
|
||||||
|
render_context.command_encoder.take()
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: add to POST_UPDATE and remove redundant global_context
|
||||||
render_resource_sets_system().run(world, resources);
|
render_resource_sets_system().run(world, resources);
|
||||||
|
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
|
||||||
|
let mut any_context = (&mut global_context.context) as &mut dyn Any;
|
||||||
|
// let mut any_context = (&mut global_context.context);
|
||||||
|
// println!("{}", std::any::type_name_of_val(any_context));
|
||||||
|
let mut render_resource_context = any_context
|
||||||
|
.downcast_mut::<WgpuRenderResourceContext>()
|
||||||
|
.unwrap();
|
||||||
|
let mut render_context =
|
||||||
|
WgpuRenderContext::new(self.device.clone(), render_resource_context.clone());
|
||||||
|
if let Some(command_encoder) = encoder.take() {
|
||||||
|
render_context.command_encoder.set(command_encoder);
|
||||||
|
}
|
||||||
|
|
||||||
// setup draw targets
|
// setup draw targets
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
render_graph.setup_pipeline_draw_targets(world, resources, &mut self.global_context);
|
render_graph.setup_pipeline_draw_targets(world, resources, &mut render_context);
|
||||||
|
|
||||||
// get next swap chain texture on primary window
|
// get next swap chain texture on primary window
|
||||||
let primary_window_id = resources
|
let primary_window_id = resources
|
||||||
@ -297,10 +303,10 @@ impl WgpuRenderer {
|
|||||||
.get_primary()
|
.get_primary()
|
||||||
.map(|window| window.id);
|
.map(|window| window.id);
|
||||||
if let Some(primary_window_id) = primary_window_id {
|
if let Some(primary_window_id) = primary_window_id {
|
||||||
self.global_context
|
render_context
|
||||||
.render_resources
|
.render_resources
|
||||||
.next_swap_chain_texture(primary_window_id);
|
.next_swap_chain_texture(primary_window_id);
|
||||||
self.global_context.primary_window = Some(primary_window_id);
|
render_context.primary_window = Some(primary_window_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin render passes
|
// begin render passes
|
||||||
@ -310,7 +316,7 @@ impl WgpuRenderer {
|
|||||||
for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() {
|
for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() {
|
||||||
let global_render_resource_assignments =
|
let global_render_resource_assignments =
|
||||||
resources.get::<RenderResourceAssignments>().unwrap();
|
resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
self.global_context.begin_pass(
|
render_context.begin_pass(
|
||||||
pass_descriptor,
|
pass_descriptor,
|
||||||
&global_render_resource_assignments,
|
&global_render_resource_assignments,
|
||||||
&mut |render_pass| {
|
&mut |render_pass| {
|
||||||
@ -346,14 +352,14 @@ impl WgpuRenderer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let command_buffer = self.global_context.finish_encoder();
|
let command_buffer = render_context.finish();
|
||||||
if let Some(command_buffer) = command_buffer {
|
if let Some(command_buffer) = command_buffer {
|
||||||
self.queue.submit(&[command_buffer]);
|
self.queue.submit(&[command_buffer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear primary swap chain texture
|
// clear primary swap chain texture
|
||||||
if let Some(primary_window_id) = primary_window_id {
|
if let Some(primary_window_id) = primary_window_id {
|
||||||
self.global_context
|
render_context
|
||||||
.render_resources
|
.render_resources
|
||||||
.drop_swap_chain_texture(primary_window_id);
|
.drop_swap_chain_texture(primary_window_id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
use crate::{
|
use crate::{renderer_2::WgpuRenderResourceContext, wgpu_type_converter::WgpuInto};
|
||||||
renderer_2::{WgpuRenderResourceContext, WgpuTransactionalRenderResourceContext},
|
|
||||||
wgpu_type_converter::WgpuInto,
|
|
||||||
};
|
|
||||||
use bevy_asset::Handle;
|
use bevy_asset::Handle;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||||
@ -13,85 +10,94 @@ use bevy_render::{
|
|||||||
texture::{SamplerDescriptor, TextureDescriptor},
|
texture::{SamplerDescriptor, TextureDescriptor},
|
||||||
};
|
};
|
||||||
use bevy_window::{Window, WindowId};
|
use bevy_window::{Window, WindowId};
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::{Arc, RwLock, RwLockReadGuard},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WgpuBindGroupInfo {
|
pub struct WgpuBindGroupInfo {
|
||||||
pub bind_groups: HashMap<RenderResourceSetId, wgpu::BindGroup>,
|
pub bind_groups: HashMap<RenderResourceSetId, wgpu::BindGroup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct WgpuResourcesReadLock<'a> {
|
||||||
|
pub buffers: RwLockReadGuard<'a, HashMap<RenderResource, wgpu::Buffer>>,
|
||||||
|
pub textures: RwLockReadGuard<'a, HashMap<RenderResource, wgpu::TextureView>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WgpuResources {
|
pub struct WgpuResources {
|
||||||
// TODO: remove this from WgpuResources. it doesn't need to be here
|
// TODO: remove this from WgpuResources. it doesn't need to be here
|
||||||
pub asset_resources: AssetResources,
|
pub asset_resources: AssetResources,
|
||||||
pub window_surfaces: HashMap<WindowId, wgpu::Surface>,
|
pub window_surfaces: Arc<RwLock<HashMap<WindowId, wgpu::Surface>>>,
|
||||||
pub window_swap_chains: HashMap<WindowId, wgpu::SwapChain>,
|
pub window_swap_chains: Arc<RwLock<HashMap<WindowId, wgpu::SwapChain>>>,
|
||||||
pub swap_chain_outputs: HashMap<WindowId, wgpu::SwapChainOutput>,
|
pub swap_chain_outputs: Arc<RwLock<HashMap<WindowId, wgpu::SwapChainOutput>>>,
|
||||||
pub buffers: HashMap<RenderResource, wgpu::Buffer>,
|
pub buffers: Arc<RwLock<HashMap<RenderResource, wgpu::Buffer>>>,
|
||||||
pub textures: HashMap<RenderResource, wgpu::TextureView>,
|
pub textures: Arc<RwLock<HashMap<RenderResource, wgpu::TextureView>>>,
|
||||||
pub samplers: HashMap<RenderResource, wgpu::Sampler>,
|
pub samplers: Arc<RwLock<HashMap<RenderResource, wgpu::Sampler>>>,
|
||||||
pub resource_info: HashMap<RenderResource, ResourceInfo>,
|
pub resource_info: Arc<RwLock<HashMap<RenderResource, ResourceInfo>>>,
|
||||||
pub shader_modules: HashMap<Handle<Shader>, wgpu::ShaderModule>,
|
pub shader_modules: Arc<RwLock<HashMap<Handle<Shader>, wgpu::ShaderModule>>>,
|
||||||
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
|
pub render_pipelines: Arc<RwLock<HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>>>,
|
||||||
pub bind_groups: HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>,
|
pub bind_groups: Arc<RwLock<HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>>>,
|
||||||
pub bind_group_layouts: HashMap<BindGroupDescriptorId, wgpu::BindGroupLayout>,
|
pub bind_group_layouts: Arc<RwLock<HashMap<BindGroupDescriptorId, wgpu::BindGroupLayout>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuResources {
|
impl WgpuResources {
|
||||||
pub fn consume(&mut self, wgpu_resources: WgpuResources) {
|
pub fn read(&self) -> WgpuResourcesReadLock {
|
||||||
// TODO: this is brittle. consider a single change-stream-based approach instead?
|
WgpuResourcesReadLock {
|
||||||
self.asset_resources.consume(wgpu_resources.asset_resources);
|
buffers: self.buffers.read().unwrap(),
|
||||||
self.window_surfaces.extend(wgpu_resources.window_surfaces);
|
textures: self.textures.read().unwrap(),
|
||||||
self.window_swap_chains
|
}
|
||||||
.extend(wgpu_resources.window_swap_chains);
|
}
|
||||||
self.swap_chain_outputs
|
|
||||||
.extend(wgpu_resources.swap_chain_outputs);
|
pub fn set_window_surface(&self, window_id: WindowId, surface: wgpu::Surface) {
|
||||||
self.buffers.extend(wgpu_resources.buffers);
|
self.window_surfaces
|
||||||
self.textures.extend(wgpu_resources.textures);
|
.write()
|
||||||
self.samplers.extend(wgpu_resources.samplers);
|
.unwrap()
|
||||||
self.resource_info.extend(wgpu_resources.resource_info);
|
.insert(window_id, surface);
|
||||||
self.shader_modules.extend(wgpu_resources.shader_modules);
|
|
||||||
self.render_pipelines.extend(wgpu_resources.render_pipelines);
|
|
||||||
self.bind_groups.extend(wgpu_resources.bind_groups);
|
|
||||||
self.bind_group_layouts
|
|
||||||
.extend(wgpu_resources.bind_group_layouts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_window_surface(&mut self, window_id: WindowId, surface: wgpu::Surface) {
|
pub fn next_swap_chain_texture(&self, window_id: WindowId) {
|
||||||
self.window_surfaces.insert(window_id, surface);
|
let mut swap_chain_outputs = self
|
||||||
}
|
.window_swap_chains
|
||||||
|
.write()
|
||||||
pub fn get_window_surface(&mut self, window_id: WindowId) -> Option<&wgpu::Surface> {
|
.unwrap();
|
||||||
self.window_surfaces.get(&window_id)
|
let swap_chain_output = swap_chain_outputs
|
||||||
}
|
.get_mut(&window_id)
|
||||||
|
.unwrap();
|
||||||
pub fn next_swap_chain_texture(&mut self, window_id: WindowId) -> Option<&wgpu::SwapChainOutput> {
|
|
||||||
let swap_chain_output = self.window_swap_chains.get_mut(&window_id).unwrap();
|
|
||||||
let next_texture = swap_chain_output.get_next_texture().unwrap();
|
let next_texture = swap_chain_output.get_next_texture().unwrap();
|
||||||
self.swap_chain_outputs.insert(window_id, next_texture);
|
self.swap_chain_outputs
|
||||||
self.swap_chain_outputs.get(&window_id)
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(window_id, next_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_swap_chain_texture(&mut self, window_id: WindowId) {
|
pub fn remove_swap_chain_texture(&self, window_id: WindowId) {
|
||||||
self.swap_chain_outputs.remove(&window_id);
|
self.swap_chain_outputs.write().unwrap().remove(&window_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_all_swap_chain_textures(&mut self) {
|
pub fn remove_all_swap_chain_textures(&self) {
|
||||||
self.swap_chain_outputs.clear();
|
self.swap_chain_outputs.write().unwrap().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_window_swap_chain(&mut self, device: &wgpu::Device, window: &Window) {
|
pub fn create_window_swap_chain(&self, device: &wgpu::Device, window: &Window) {
|
||||||
let swap_chain_descriptor: wgpu::SwapChainDescriptor = window.wgpu_into();
|
let swap_chain_descriptor: wgpu::SwapChainDescriptor = window.wgpu_into();
|
||||||
let surface = self
|
let surfaces = self.window_surfaces.read().unwrap();
|
||||||
.window_surfaces
|
let surface = surfaces
|
||||||
.get(&window.id)
|
.get(&window.id)
|
||||||
.expect("No surface found for window");
|
.expect("No surface found for window");
|
||||||
let swap_chain = device.create_swap_chain(surface, &swap_chain_descriptor);
|
let swap_chain = device.create_swap_chain(surface, &swap_chain_descriptor);
|
||||||
self.window_swap_chains.insert(window.id, swap_chain);
|
self.window_swap_chains
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(window.id, swap_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_resource_info(&mut self, resource: RenderResource, resource_info: ResourceInfo) {
|
pub fn add_resource_info(&self, resource: RenderResource, resource_info: ResourceInfo) {
|
||||||
self.resource_info.insert(resource, resource_info);
|
self.resource_info
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(resource, resource_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bind_group(
|
pub fn get_bind_group(
|
||||||
@ -99,7 +105,12 @@ impl WgpuResources {
|
|||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||||
render_resource_set_id: RenderResourceSetId,
|
render_resource_set_id: RenderResourceSetId,
|
||||||
) -> Option<&wgpu::BindGroup> {
|
) -> Option<&wgpu::BindGroup> {
|
||||||
if let Some(bind_group_info) = self.bind_groups.get(&bind_group_descriptor_id) {
|
if let Some(bind_group_info) = self
|
||||||
|
.bind_groups
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(&bind_group_descriptor_id)
|
||||||
|
{
|
||||||
bind_group_info.bind_groups.get(&render_resource_set_id)
|
bind_group_info.bind_groups.get(&render_resource_set_id)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -121,13 +132,16 @@ impl WgpuResources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bind_group(
|
pub fn set_bind_group(
|
||||||
&mut self,
|
&self,
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||||
render_resource_set_id: RenderResourceSetId,
|
render_resource_set_id: RenderResourceSetId,
|
||||||
bind_group: wgpu::BindGroup,
|
bind_group: wgpu::BindGroup,
|
||||||
) {
|
) {
|
||||||
let bind_group_info = self
|
let mut bind_groups = self
|
||||||
.bind_groups
|
.bind_groups
|
||||||
|
.write()
|
||||||
|
.unwrap();
|
||||||
|
let bind_group_info = bind_groups
|
||||||
.entry(bind_group_descriptor_id)
|
.entry(bind_group_descriptor_id)
|
||||||
.or_insert_with(|| WgpuBindGroupInfo::default());
|
.or_insert_with(|| WgpuBindGroupInfo::default());
|
||||||
bind_group_info
|
bind_group_info
|
||||||
@ -135,11 +149,7 @@ impl WgpuResources {
|
|||||||
.insert(render_resource_set_id, bind_group);
|
.insert(render_resource_set_id, bind_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_buffer(
|
pub fn create_buffer(&self, device: &wgpu::Device, buffer_info: BufferInfo) -> RenderResource {
|
||||||
&mut self,
|
|
||||||
device: &wgpu::Device,
|
|
||||||
buffer_info: BufferInfo,
|
|
||||||
) -> RenderResource {
|
|
||||||
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: buffer_info.size as u64,
|
size: buffer_info.size as u64,
|
||||||
@ -149,12 +159,12 @@ impl WgpuResources {
|
|||||||
let resource = RenderResource::new();
|
let resource = RenderResource::new();
|
||||||
self.add_resource_info(resource, ResourceInfo::Buffer(buffer_info));
|
self.add_resource_info(resource, ResourceInfo::Buffer(buffer_info));
|
||||||
|
|
||||||
self.buffers.insert(resource, buffer);
|
self.buffers.write().unwrap().insert(resource, buffer);
|
||||||
resource
|
resource
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_buffer_with_data(
|
pub fn create_buffer_with_data(
|
||||||
&mut self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
mut buffer_info: BufferInfo,
|
mut buffer_info: BufferInfo,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
@ -165,22 +175,18 @@ impl WgpuResources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
|
pub fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
|
||||||
self.resource_info.get(&resource)
|
self.resource_info.read().unwrap().get(&resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_buffer(&mut self, resource: RenderResource) {
|
pub fn remove_buffer(&self, resource: RenderResource) {
|
||||||
self.buffers.remove(&resource);
|
self.buffers.write().unwrap().remove(&resource);
|
||||||
self.resource_info.remove(&resource);
|
self.resource_info.write().unwrap().remove(&resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_buffer(
|
pub fn assign_buffer(&self, buffer: wgpu::Buffer, buffer_info: BufferInfo) -> RenderResource {
|
||||||
&mut self,
|
|
||||||
buffer: wgpu::Buffer,
|
|
||||||
buffer_info: BufferInfo,
|
|
||||||
) -> RenderResource {
|
|
||||||
let resource = RenderResource::new();
|
let resource = RenderResource::new();
|
||||||
self.add_resource_info(resource, ResourceInfo::Buffer(buffer_info));
|
self.add_resource_info(resource, ResourceInfo::Buffer(buffer_info));
|
||||||
self.buffers.insert(resource, buffer);
|
self.buffers.write().unwrap().insert(resource, buffer);
|
||||||
resource
|
resource
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,23 +206,8 @@ impl WgpuResources {
|
|||||||
mapped.finish()
|
mapped.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn begin_create_buffer_mapped_transactional_render_context(
|
|
||||||
buffer_info: &BufferInfo,
|
|
||||||
render_resources: &mut WgpuTransactionalRenderResourceContext,
|
|
||||||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext),
|
|
||||||
) -> wgpu::Buffer {
|
|
||||||
let device = render_resources.device.clone();
|
|
||||||
let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
|
||||||
size: buffer_info.size as u64,
|
|
||||||
usage: buffer_info.buffer_usage.wgpu_into(),
|
|
||||||
label: None,
|
|
||||||
});
|
|
||||||
setup_data(&mut mapped.data, render_resources);
|
|
||||||
mapped.finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn copy_buffer_to_buffer(
|
pub fn copy_buffer_to_buffer(
|
||||||
&mut self,
|
&self,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
source_buffer: RenderResource,
|
source_buffer: RenderResource,
|
||||||
source_offset: u64,
|
source_offset: u64,
|
||||||
@ -224,36 +215,40 @@ impl WgpuResources {
|
|||||||
destination_offset: u64,
|
destination_offset: u64,
|
||||||
size: u64,
|
size: u64,
|
||||||
) {
|
) {
|
||||||
let source = self.buffers.get(&source_buffer).unwrap();
|
let buffers = self.buffers.read().unwrap();
|
||||||
let destination = self.buffers.get(&destination_buffer).unwrap();
|
let source = buffers.get(&source_buffer).unwrap();
|
||||||
|
let destination = buffers.get(&destination_buffer).unwrap();
|
||||||
encoder.copy_buffer_to_buffer(source, source_offset, destination, destination_offset, size);
|
encoder.copy_buffer_to_buffer(source, source_offset, destination, destination_offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_shader_module(
|
pub fn create_shader_module(
|
||||||
&mut self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
shader_handle: Handle<Shader>,
|
shader_handle: Handle<Shader>,
|
||||||
shader: &Shader,
|
shader: &Shader,
|
||||||
) {
|
) {
|
||||||
let shader_module = device.create_shader_module(&shader.get_spirv(None));
|
let shader_module = device.create_shader_module(&shader.get_spirv(None));
|
||||||
self.shader_modules.insert(shader_handle, shader_module);
|
self.shader_modules
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(shader_handle, shader_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_sampler(
|
pub fn create_sampler(
|
||||||
&mut self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
sampler_descriptor: &SamplerDescriptor,
|
sampler_descriptor: &SamplerDescriptor,
|
||||||
) -> RenderResource {
|
) -> RenderResource {
|
||||||
let descriptor: wgpu::SamplerDescriptor = (*sampler_descriptor).wgpu_into();
|
let descriptor: wgpu::SamplerDescriptor = (*sampler_descriptor).wgpu_into();
|
||||||
let sampler = device.create_sampler(&descriptor);
|
let sampler = device.create_sampler(&descriptor);
|
||||||
let resource = RenderResource::new();
|
let resource = RenderResource::new();
|
||||||
self.samplers.insert(resource, sampler);
|
self.samplers.write().unwrap().insert(resource, sampler);
|
||||||
self.add_resource_info(resource, ResourceInfo::Sampler);
|
self.add_resource_info(resource, ResourceInfo::Sampler);
|
||||||
resource
|
resource
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_texture(
|
pub fn create_texture(
|
||||||
&mut self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
texture_descriptor: &TextureDescriptor,
|
texture_descriptor: &TextureDescriptor,
|
||||||
) -> RenderResource {
|
) -> RenderResource {
|
||||||
@ -262,12 +257,15 @@ impl WgpuResources {
|
|||||||
let texture_view = texture.create_default_view();
|
let texture_view = texture.create_default_view();
|
||||||
let resource = RenderResource::new();
|
let resource = RenderResource::new();
|
||||||
self.add_resource_info(resource, ResourceInfo::Texture);
|
self.add_resource_info(resource, ResourceInfo::Texture);
|
||||||
self.textures.insert(resource, texture_view);
|
self.textures
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(resource, texture_view);
|
||||||
resource
|
resource
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_texture_with_data(
|
pub fn create_texture_with_data(
|
||||||
&mut self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
texture_descriptor: &TextureDescriptor,
|
texture_descriptor: &TextureDescriptor,
|
||||||
@ -295,18 +293,21 @@ impl WgpuResources {
|
|||||||
|
|
||||||
let resource = RenderResource::new();
|
let resource = RenderResource::new();
|
||||||
self.add_resource_info(resource, ResourceInfo::Texture);
|
self.add_resource_info(resource, ResourceInfo::Texture);
|
||||||
self.textures.insert(resource, texture_view);
|
self.textures
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(resource, texture_view);
|
||||||
resource
|
resource
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_texture(&mut self, resource: RenderResource) {
|
pub fn remove_texture(&self, resource: RenderResource) {
|
||||||
self.textures.remove(&resource);
|
self.textures.write().unwrap().remove(&resource);
|
||||||
self.resource_info.remove(&resource);
|
self.resource_info.write().unwrap().remove(&resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_sampler(&mut self, resource: RenderResource) {
|
pub fn remove_sampler(&self, resource: RenderResource) {
|
||||||
self.samplers.remove(&resource);
|
self.samplers.write().unwrap().remove(&resource);
|
||||||
self.resource_info.remove(&resource);
|
self.resource_info.write().unwrap().remove(&resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_render_resources(&self) -> &AssetResources {
|
pub fn get_render_resources(&self) -> &AssetResources {
|
||||||
@ -318,13 +319,15 @@ impl WgpuResources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_bind_group_layout(
|
pub fn create_bind_group_layout(
|
||||||
&mut self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
bind_group_id: BindGroupDescriptorId,
|
bind_group_id: BindGroupDescriptorId,
|
||||||
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
||||||
) {
|
) {
|
||||||
let wgpu_bind_group_layout = device.create_bind_group_layout(descriptor);
|
let wgpu_bind_group_layout = device.create_bind_group_layout(descriptor);
|
||||||
self.bind_group_layouts
|
self.bind_group_layouts
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.insert(bind_group_id, wgpu_bind_group_layout);
|
.insert(bind_group_id, wgpu_bind_group_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,11 +340,13 @@ impl WgpuResources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_render_pipeline(
|
pub fn set_render_pipeline(
|
||||||
&mut self,
|
&self,
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
render_pipeline: wgpu::RenderPipeline,
|
render_pipeline: wgpu::RenderPipeline,
|
||||||
) {
|
) {
|
||||||
self.render_pipelines
|
self.render_pipelines
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.insert(pipeline_handle, render_pipeline);
|
.insert(pipeline_handle, render_pipeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user