RenderGraph2: fix uniform node textures

This commit is contained in:
Carter Anderson 2020-04-24 12:48:12 -07:00
parent 512bf118bf
commit f47315afa3
6 changed files with 171 additions and 14 deletions

View file

@ -1,5 +1,5 @@
use crate::{renderer_2::RenderContext, render_resource::RenderResource};
use std::{sync::{Arc, Mutex}, collections::VecDeque};
use crate::{render_resource::RenderResource, renderer_2::RenderContext, texture::Extent3d};
use std::sync::{Arc, Mutex};
pub enum Command {
CopyBufferToBuffer {
@ -9,17 +9,28 @@ pub enum Command {
destination_offset: u64,
size: u64,
},
CopyBufferToTexture {
source_buffer: RenderResource,
source_offset: u64,
source_bytes_per_row: u32,
destination_texture: RenderResource,
destination_origin: [u32; 3],
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
},
FreeBuffer(RenderResource),
}
#[derive(Default, Clone)]
pub struct CommandQueue {
// TODO: this shouldn't really need a mutex. its just needs to be shared on whatever thread its scheduled on
queue: Arc<Mutex<VecDeque<Command>>>,
queue: Arc<Mutex<Vec<Command>>>,
}
impl CommandQueue {
fn push(&mut self, command: Command) {
self.queue.lock().unwrap().push_front(command);
self.queue.lock().unwrap().push(command);
}
pub fn copy_buffer_to_buffer(
@ -39,6 +50,33 @@ impl CommandQueue {
});
}
pub fn copy_buffer_to_texture(
&mut self,
source_buffer: RenderResource,
source_offset: u64,
source_bytes_per_row: u32,
destination_texture: RenderResource,
destination_origin: [u32; 3],
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
) {
self.push(Command::CopyBufferToTexture {
source_buffer,
source_offset,
source_bytes_per_row,
destination_texture,
destination_origin,
destination_mip_level,
destination_array_layer,
size,
});
}
pub fn free_buffer(&mut self, buffer: RenderResource) {
self.push(Command::FreeBuffer(buffer));
}
pub fn execute(&mut self, render_context: &mut dyn RenderContext) {
for command in self.queue.lock().unwrap().drain(..) {
match command {
@ -55,7 +93,27 @@ impl CommandQueue {
destination_offset,
size,
),
Command::CopyBufferToTexture {
source_buffer,
source_offset,
source_bytes_per_row,
destination_texture,
destination_origin,
destination_mip_level,
destination_array_layer,
size,
} => render_context.copy_buffer_to_texture(
source_buffer,
source_offset,
source_bytes_per_row,
destination_texture,
destination_origin,
destination_mip_level,
destination_array_layer,
size,
),
Command::FreeBuffer(buffer) => render_context.resources().remove_buffer(buffer),
}
}
}
}
}

View file

@ -367,6 +367,7 @@ where
fn setup_uniform_texture_resources(
uniforms: &T,
command_queue: &mut CommandQueue,
texture_storage: &AssetStorage<Texture>,
render_resource_context: &dyn RenderResourceContext,
render_resource_assignments: &mut RenderResourceAssignments,
@ -395,6 +396,21 @@ where
render_resource_context.create_texture(&texture_descriptor);
// TODO: queue texture copy
// .create_texture_with_data(&texture_descriptor, &texture.data);
let texture_buffer = render_resource_context.create_buffer_with_data(BufferInfo {
buffer_usage: BufferUsage::COPY_SRC,
..Default::default()
}, &texture.data);
command_queue.copy_buffer_to_texture(
texture_buffer,
0,
(4 * texture.width) as u32,
texture_resource,
[0, 0, 0],
0,
0,
texture_descriptor.size.clone(),
);
command_queue.free_buffer(texture_buffer);
let sampler_descriptor: SamplerDescriptor = texture.into();
let sampler_resource =
@ -521,6 +537,7 @@ where
} else {
Self::setup_uniform_texture_resources(
&uniforms,
&mut command_queue,
textures,
render_resource_context,
&mut renderable.render_resource_assignments,
@ -541,6 +558,7 @@ where
.expect("Handle points to a non-existent resource");
Self::setup_uniform_texture_resources(
&uniforms,
&mut command_queue,
textures,
render_resource_context,
&mut renderable.render_resource_assignments,

View file

@ -4,7 +4,7 @@ use crate::{
pipeline::{BindGroupDescriptor, PipelineDescriptor},
render_resource::{RenderResource, RenderResourceAssignments, RenderResourceSetId},
shader::Shader,
texture::TextureDescriptor,
texture::{Extent3d, TextureDescriptor},
};
use bevy_asset::{AssetStorage, Handle};
@ -25,6 +25,17 @@ pub trait RenderContext {
destination_offset: u64,
size: u64,
);
fn copy_buffer_to_texture(
&mut self,
source_buffer: RenderResource,
source_offset: u64,
source_bytes_per_row: u32,
destination_texture: RenderResource,
destination_origin: [u32; 3],
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
);
fn create_bind_group(
&mut self,
bind_group_descriptor: &BindGroupDescriptor,

View file

@ -17,6 +17,7 @@ pub enum TextureDimension {
D3,
}
// TODO: use math type here
#[derive(Clone, Copy, Debug)]
pub struct Extent3d {
pub width: u32,

View file

@ -15,7 +15,7 @@ use bevy_render::{
},
renderer_2::{RenderContext, RenderResourceContext},
shader::Shader,
texture::TextureDescriptor,
texture::{Extent3d, TextureDescriptor},
};
use bevy_window::WindowId;
use std::{collections::HashMap, sync::Arc};
@ -140,7 +140,7 @@ impl RenderContext for WgpuRenderContext {
let textures = self
.render_resources
.wgpu_resources
.textures
.texture_views
.read()
.unwrap();
let samplers = self
@ -443,6 +443,29 @@ impl RenderContext for WgpuRenderContext {
self.command_encoder.set(encoder);
}
fn copy_buffer_to_texture(
&mut self,
source_buffer: RenderResource,
source_offset: u64,
source_bytes_per_row: u32,
destination_texture: RenderResource,
destination_origin: [u32; 3],
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
) {
self.render_resources.wgpu_resources.copy_buffer_to_texture(
self.command_encoder.get_or_create(&self.device),
source_buffer,
source_offset,
source_bytes_per_row,
destination_texture,
destination_origin,
destination_mip_level,
destination_array_layer,
size,
)
}
}
pub fn create_render_pass<'a, 'b>(

View file

@ -5,7 +5,7 @@ use bevy_render::{
render_resource::{BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo},
renderer_2::RenderResourceContext,
shader::Shader,
texture::{SamplerDescriptor, TextureDescriptor},
texture::{Extent3d, SamplerDescriptor, TextureDescriptor},
};
use bevy_window::{Window, WindowId};
use std::{
@ -77,7 +77,8 @@ pub struct WgpuResources {
pub window_swap_chains: Arc<RwLock<HashMap<WindowId, wgpu::SwapChain>>>,
pub swap_chain_outputs: Arc<RwLock<HashMap<RenderResource, wgpu::SwapChainOutput>>>,
pub buffers: Arc<RwLock<HashMap<RenderResource, wgpu::Buffer>>>,
pub textures: Arc<RwLock<HashMap<RenderResource, wgpu::TextureView>>>,
pub texture_views: Arc<RwLock<HashMap<RenderResource, wgpu::TextureView>>>,
pub textures: Arc<RwLock<HashMap<RenderResource, wgpu::Texture>>>,
pub samplers: Arc<RwLock<HashMap<RenderResource, wgpu::Sampler>>>,
pub resource_info: Arc<RwLock<HashMap<RenderResource, ResourceInfo>>>,
pub shader_modules: Arc<RwLock<HashMap<Handle<Shader>, wgpu::ShaderModule>>>,
@ -91,7 +92,7 @@ impl WgpuResources {
pub fn read(&self) -> WgpuResourcesReadLock {
WgpuResourcesReadLock {
buffers: self.buffers.read().unwrap(),
textures: self.textures.read().unwrap(),
textures: self.texture_views.read().unwrap(),
swap_chain_outputs: self.swap_chain_outputs.read().unwrap(),
render_pipelines: self.render_pipelines.read().unwrap(),
bind_groups: self.bind_groups.read().unwrap(),
@ -119,7 +120,10 @@ impl WgpuResources {
}
pub fn remove_swap_chain_texture(&self, render_resource: RenderResource) {
self.swap_chain_outputs.write().unwrap().remove(&render_resource);
self.swap_chain_outputs
.write()
.unwrap()
.remove(&render_resource);
}
pub fn remove_all_swap_chain_textures(&self) {
@ -274,6 +278,43 @@ impl WgpuResources {
encoder.copy_buffer_to_buffer(source, source_offset, destination, destination_offset, size);
}
pub fn copy_buffer_to_texture(
&self,
encoder: &mut wgpu::CommandEncoder,
source_buffer: RenderResource,
source_offset: u64,
source_bytes_per_row: u32,
destination_texture: RenderResource,
destination_origin: [u32; 3], // TODO: replace with math type
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
) {
let buffers = self.buffers.read().unwrap();
let textures = self.textures.read().unwrap();
let source = buffers.get(&source_buffer).unwrap();
let destination = textures.get(&destination_texture).unwrap();
encoder.copy_buffer_to_texture(
wgpu::BufferCopyView {
buffer: source,
offset: source_offset,
bytes_per_row: source_bytes_per_row,
rows_per_image: 0, // NOTE: Example sets this to 0, but should it be height?
},
wgpu::TextureCopyView {
texture: destination,
mip_level: destination_mip_level,
array_layer: destination_array_layer,
origin: wgpu::Origin3d {
x: destination_origin[0],
y: destination_origin[1],
z: destination_origin[2],
},
},
size.wgpu_into(),
);
}
pub fn create_shader_module(
&self,
device: &wgpu::Device,
@ -310,10 +351,14 @@ impl WgpuResources {
let texture_view = texture.create_default_view();
let resource = RenderResource::new();
self.add_resource_info(resource, ResourceInfo::Texture);
self.textures
self.texture_views
.write()
.unwrap()
.insert(resource, texture_view);
self.textures
.write()
.unwrap()
.insert(resource, texture);
resource
}
@ -346,7 +391,7 @@ impl WgpuResources {
let resource = RenderResource::new();
self.add_resource_info(resource, ResourceInfo::Texture);
self.textures
self.texture_views
.write()
.unwrap()
.insert(resource, texture_view);
@ -354,6 +399,7 @@ impl WgpuResources {
}
pub fn remove_texture(&self, resource: RenderResource) {
self.texture_views.write().unwrap().remove(&resource);
self.textures.write().unwrap().remove(&resource);
self.resource_info.write().unwrap().remove(&resource);
}