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 crate::{render_resource::RenderResource, renderer_2::RenderContext, texture::Extent3d};
use std::{sync::{Arc, Mutex}, collections::VecDeque}; use std::sync::{Arc, Mutex};
pub enum Command { pub enum Command {
CopyBufferToBuffer { CopyBufferToBuffer {
@ -9,17 +9,28 @@ pub enum Command {
destination_offset: u64, destination_offset: u64,
size: 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)] #[derive(Default, Clone)]
pub struct CommandQueue { pub struct CommandQueue {
// TODO: this shouldn't really need a mutex. its just needs to be shared on whatever thread its scheduled on // 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 { impl CommandQueue {
fn push(&mut self, command: Command) { 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( 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) { pub fn execute(&mut self, render_context: &mut dyn RenderContext) {
for command in self.queue.lock().unwrap().drain(..) { for command in self.queue.lock().unwrap().drain(..) {
match command { match command {
@ -55,7 +93,27 @@ impl CommandQueue {
destination_offset, destination_offset,
size, 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( fn setup_uniform_texture_resources(
uniforms: &T, uniforms: &T,
command_queue: &mut CommandQueue,
texture_storage: &AssetStorage<Texture>, texture_storage: &AssetStorage<Texture>,
render_resource_context: &dyn RenderResourceContext, render_resource_context: &dyn RenderResourceContext,
render_resource_assignments: &mut RenderResourceAssignments, render_resource_assignments: &mut RenderResourceAssignments,
@ -395,6 +396,21 @@ where
render_resource_context.create_texture(&texture_descriptor); render_resource_context.create_texture(&texture_descriptor);
// TODO: queue texture copy // TODO: queue texture copy
// .create_texture_with_data(&texture_descriptor, &texture.data); // .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_descriptor: SamplerDescriptor = texture.into();
let sampler_resource = let sampler_resource =
@ -521,6 +537,7 @@ where
} else { } else {
Self::setup_uniform_texture_resources( Self::setup_uniform_texture_resources(
&uniforms, &uniforms,
&mut command_queue,
textures, textures,
render_resource_context, render_resource_context,
&mut renderable.render_resource_assignments, &mut renderable.render_resource_assignments,
@ -541,6 +558,7 @@ where
.expect("Handle points to a non-existent resource"); .expect("Handle points to a non-existent resource");
Self::setup_uniform_texture_resources( Self::setup_uniform_texture_resources(
&uniforms, &uniforms,
&mut command_queue,
textures, textures,
render_resource_context, render_resource_context,
&mut renderable.render_resource_assignments, &mut renderable.render_resource_assignments,

View File

@ -4,7 +4,7 @@ use crate::{
pipeline::{BindGroupDescriptor, PipelineDescriptor}, pipeline::{BindGroupDescriptor, PipelineDescriptor},
render_resource::{RenderResource, RenderResourceAssignments, RenderResourceSetId}, render_resource::{RenderResource, RenderResourceAssignments, RenderResourceSetId},
shader::Shader, shader::Shader,
texture::TextureDescriptor, texture::{Extent3d, TextureDescriptor},
}; };
use bevy_asset::{AssetStorage, Handle}; use bevy_asset::{AssetStorage, Handle};
@ -25,6 +25,17 @@ pub trait RenderContext {
destination_offset: u64, destination_offset: u64,
size: 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( fn create_bind_group(
&mut self, &mut self,
bind_group_descriptor: &BindGroupDescriptor, bind_group_descriptor: &BindGroupDescriptor,

View File

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

View File

@ -15,7 +15,7 @@ use bevy_render::{
}, },
renderer_2::{RenderContext, RenderResourceContext}, renderer_2::{RenderContext, RenderResourceContext},
shader::Shader, shader::Shader,
texture::TextureDescriptor, texture::{Extent3d, TextureDescriptor},
}; };
use bevy_window::WindowId; use bevy_window::WindowId;
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
@ -140,7 +140,7 @@ impl RenderContext for WgpuRenderContext {
let textures = self let textures = self
.render_resources .render_resources
.wgpu_resources .wgpu_resources
.textures .texture_views
.read() .read()
.unwrap(); .unwrap();
let samplers = self let samplers = self
@ -443,6 +443,29 @@ impl RenderContext for WgpuRenderContext {
self.command_encoder.set(encoder); 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>( pub fn create_render_pass<'a, 'b>(

View File

@ -5,7 +5,7 @@ use bevy_render::{
render_resource::{BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo}, render_resource::{BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo},
renderer_2::RenderResourceContext, renderer_2::RenderResourceContext,
shader::Shader, shader::Shader,
texture::{SamplerDescriptor, TextureDescriptor}, texture::{Extent3d, SamplerDescriptor, TextureDescriptor},
}; };
use bevy_window::{Window, WindowId}; use bevy_window::{Window, WindowId};
use std::{ use std::{
@ -77,7 +77,8 @@ pub struct WgpuResources {
pub window_swap_chains: Arc<RwLock<HashMap<WindowId, wgpu::SwapChain>>>, pub window_swap_chains: Arc<RwLock<HashMap<WindowId, wgpu::SwapChain>>>,
pub swap_chain_outputs: Arc<RwLock<HashMap<RenderResource, wgpu::SwapChainOutput>>>, pub swap_chain_outputs: Arc<RwLock<HashMap<RenderResource, wgpu::SwapChainOutput>>>,
pub buffers: Arc<RwLock<HashMap<RenderResource, wgpu::Buffer>>>, 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 samplers: Arc<RwLock<HashMap<RenderResource, wgpu::Sampler>>>,
pub resource_info: Arc<RwLock<HashMap<RenderResource, ResourceInfo>>>, pub resource_info: Arc<RwLock<HashMap<RenderResource, ResourceInfo>>>,
pub shader_modules: Arc<RwLock<HashMap<Handle<Shader>, wgpu::ShaderModule>>>, pub shader_modules: Arc<RwLock<HashMap<Handle<Shader>, wgpu::ShaderModule>>>,
@ -91,7 +92,7 @@ impl WgpuResources {
pub fn read(&self) -> WgpuResourcesReadLock { pub fn read(&self) -> WgpuResourcesReadLock {
WgpuResourcesReadLock { WgpuResourcesReadLock {
buffers: self.buffers.read().unwrap(), 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(), swap_chain_outputs: self.swap_chain_outputs.read().unwrap(),
render_pipelines: self.render_pipelines.read().unwrap(), render_pipelines: self.render_pipelines.read().unwrap(),
bind_groups: self.bind_groups.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) { 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) { 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); 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( pub fn create_shader_module(
&self, &self,
device: &wgpu::Device, device: &wgpu::Device,
@ -310,10 +351,14 @@ 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 self.texture_views
.write() .write()
.unwrap() .unwrap()
.insert(resource, texture_view); .insert(resource, texture_view);
self.textures
.write()
.unwrap()
.insert(resource, texture);
resource resource
} }
@ -346,7 +391,7 @@ 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 self.texture_views
.write() .write()
.unwrap() .unwrap()
.insert(resource, texture_view); .insert(resource, texture_view);
@ -354,6 +399,7 @@ impl WgpuResources {
} }
pub fn remove_texture(&self, resource: RenderResource) { pub fn remove_texture(&self, resource: RenderResource) {
self.texture_views.write().unwrap().remove(&resource);
self.textures.write().unwrap().remove(&resource); self.textures.write().unwrap().remove(&resource);
self.resource_info.write().unwrap().remove(&resource); self.resource_info.write().unwrap().remove(&resource);
} }