wgpu: upgrade to latest master. use pollster instead of futures. texture copy alignment

This commit is contained in:
Carter Anderson 2020-06-04 15:58:02 -07:00
parent 69ac775bfb
commit e72b5583d1
15 changed files with 69 additions and 107 deletions

View file

@ -109,6 +109,8 @@ impl BaseRenderGraphBuilder for RenderGraph {
depth_store_op: StoreOp::Store,
stencil_load_op: LoadOp::Clear,
stencil_store_op: StoreOp::Store,
stencil_read_only: false,
depth_read_only: false,
clear_depth: 1.0,
clear_stencil: 0,
}),

View file

@ -44,6 +44,8 @@ pub struct RenderPassDepthStencilAttachmentDescriptor {
pub clear_depth: f32,
pub stencil_load_op: LoadOp,
pub stencil_store_op: StoreOp,
pub depth_read_only: bool,
pub stencil_read_only: bool,
pub clear_stencil: u32,
}

View file

@ -17,7 +17,6 @@ pub enum Command {
destination_texture: RenderResource,
destination_origin: [u32; 3],
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
},
// TODO: Frees probably don't need to be queued?
@ -60,7 +59,6 @@ impl CommandQueue {
destination_texture: RenderResource,
destination_origin: [u32; 3],
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
) {
self.push(Command::CopyBufferToTexture {
@ -70,7 +68,6 @@ impl CommandQueue {
destination_texture,
destination_origin,
destination_mip_level,
destination_array_layer,
size,
});
}
@ -102,7 +99,6 @@ impl CommandQueue {
destination_texture,
destination_origin,
destination_mip_level,
destination_array_layer,
size,
} => render_context.copy_buffer_to_texture(
source_buffer,
@ -111,7 +107,6 @@ impl CommandQueue {
destination_texture,
destination_origin,
destination_mip_level,
destination_array_layer,
size,
),
Command::FreeBuffer(buffer) => render_context.resources().remove_buffer(buffer),

View file

@ -14,6 +14,11 @@ pub struct TextureCopyNode {
pub texture_event_reader: EventReader<AssetEvent<Texture>>,
}
pub const ALIGNMENT: usize = 256;
fn get_aligned(data_size: f32) -> usize {
ALIGNMENT * ((data_size / ALIGNMENT as f32).ceil() as usize)
}
impl Node for TextureCopyNode {
fn update(
&mut self,
@ -30,12 +35,20 @@ impl Node for TextureCopyNode {
AssetEvent::Created { handle } | AssetEvent::Modified { handle } => {
if let Some(texture) = textures.get(&handle) {
let texture_descriptor: TextureDescriptor = texture.into();
let width = texture.size.x() as usize;
let aligned_width = get_aligned(texture.size.x());
let format_size = 4; // TODO: this will be incorrect for some formats
let mut aligned_data = vec![0; format_size * aligned_width * texture.size.y() as usize];
texture.data.chunks_exact(format_size * width).enumerate().for_each(|(index, row)| {
let offset = index * aligned_width * format_size;
aligned_data[offset..(offset + width * format_size)].copy_from_slice(row);
});
let texture_buffer = render_context.resources().create_buffer_with_data(
BufferInfo {
buffer_usage: BufferUsage::COPY_SRC,
..Default::default()
},
&texture.data,
&aligned_data,
);
let texture_resource = render_context
@ -43,15 +56,13 @@ impl Node for TextureCopyNode {
.get_asset_resource(*handle, TEXTURE_ASSET_INDEX)
.unwrap();
// TODO: bytes_per_row could be incorrect for some texture formats
render_context.copy_buffer_to_texture(
texture_buffer,
0,
4 * texture.size.x() as u32,
(format_size * aligned_width) as u32,
texture_resource,
[0, 0, 0],
0,
0,
texture_descriptor.size.clone(),
);
render_context.resources().remove_buffer(texture_buffer);

View file

@ -2,18 +2,12 @@ use super::RenderResourceContext;
use crate::{
pass::{PassDescriptor, RenderPass},
render_resource::{RenderResource, RenderResourceAssignments},
texture::{Extent3d, TextureDescriptor},
texture::{Extent3d},
};
pub trait RenderContext {
fn resources(&self) -> &dyn RenderResourceContext;
fn resources_mut(&mut self) -> &mut dyn RenderResourceContext;
fn create_texture_with_data(
&mut self,
texture_descriptor: TextureDescriptor,
bytes: &[u8],
) -> RenderResource;
fn copy_buffer_to_buffer(
&mut self,
source_buffer: RenderResource,
@ -30,7 +24,6 @@ pub trait RenderContext {
destination_texture: RenderResource,
destination_origin: [u32; 3],
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
);
fn begin_pass(

View file

@ -11,7 +11,8 @@ pub struct SamplerDescriptor {
pub mipmap_filter: FilterMode,
pub lod_min_clamp: f32,
pub lod_max_clamp: f32,
pub compare_function: CompareFunction,
pub compare_function: Option<CompareFunction>,
pub anisotropy_clamp: Option<u8>,
}
impl Default for SamplerDescriptor {
@ -25,7 +26,8 @@ impl Default for SamplerDescriptor {
mipmap_filter: FilterMode::Nearest,
lod_min_clamp: -100.0,
lod_max_clamp: 100.0,
compare_function: CompareFunction::Always,
compare_function: Some(CompareFunction::Always),
anisotropy_clamp: None,
}
}
}
@ -41,7 +43,8 @@ impl From<&Texture> for SamplerDescriptor {
mipmap_filter: FilterMode::Nearest,
lod_min_clamp: -100.0,
lod_max_clamp: 100.0,
compare_function: CompareFunction::Always,
compare_function: Some(CompareFunction::Always),
anisotropy_clamp: None,
}
}
}

View file

@ -19,10 +19,10 @@ bevy_winit = { path = "../bevy_winit", optional = true }
legion = { path = "../bevy_legion" }
# render
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "89ee5bffd3c37279f733b76b05e5d030aba035db" }
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "ff41d31200a5c5f0d7ddcd9a87b370c566936257" }
# wgpu = { version = "0.5.0" }
futures = "0.3"
pollster = "0.2.0"
log = { version = "0.4", features = ["release_max_level_info"] }
crossbeam-channel = "0.4.2"
crossbeam-utils = "0.7.2"

View file

@ -125,7 +125,7 @@ impl WgpuResourceDiagnosticsPlugin {
Self::SWAP_CHAIN_OUTPUTS,
render_resource_context
.resources
.swap_chain_outputs
.swap_chain_frames
.read()
.unwrap()
.len() as f64,

View file

@ -29,7 +29,7 @@ pub fn wgpu_render_system(resources: &mut Resources) -> impl FnMut(&mut World, &
let mut wgpu_renderer = {
let window_resized_event = resources.get::<Events<WindowResized>>().unwrap();
let window_created_event = resources.get::<Events<WindowCreated>>().unwrap();
futures::executor::block_on(WgpuRenderer::new(
pollster::block_on(WgpuRenderer::new(
window_resized_event.get_reader(),
window_created_event.get_reader(),
))

View file

@ -8,7 +8,7 @@ use bevy_render::{
},
render_resource::{RenderResource, RenderResourceAssignment, RenderResourceAssignments},
renderer::{RenderContext, RenderResourceContext},
texture::{Extent3d, TextureDescriptor},
texture::Extent3d,
};
use std::{collections::HashMap, sync::Arc};
@ -71,17 +71,6 @@ impl WgpuRenderContext {
}
impl RenderContext for WgpuRenderContext {
fn create_texture_with_data(
&mut self,
texture_descriptor: TextureDescriptor,
bytes: &[u8],
) -> RenderResource {
self.render_resources.create_texture_with_data(
self.command_encoder.get_or_create(&self.device),
texture_descriptor,
bytes,
)
}
fn copy_buffer_to_buffer(
&mut self,
source_buffer: RenderResource,
@ -108,7 +97,6 @@ impl RenderContext for WgpuRenderContext {
destination_texture: RenderResource,
destination_origin: [u32; 3],
destination_mip_level: u32,
destination_array_layer: u32,
size: Extent3d,
) {
self.render_resources.copy_buffer_to_texture(
@ -119,7 +107,6 @@ impl RenderContext for WgpuRenderContext {
destination_texture,
destination_origin,
destination_mip_level,
destination_array_layer,
size,
)
}
@ -200,7 +187,7 @@ fn get_texture_view<'a>(
panic!("Color attachment {} does not exist", name);
}
},
TextureAttachment::RenderResource(render_resource) => refs.textures.get(&render_resource).unwrap_or_else(|| &refs.swap_chain_outputs.get(&render_resource).unwrap().view),
TextureAttachment::RenderResource(render_resource) => refs.textures.get(&render_resource).unwrap_or_else(|| &refs.swap_chain_frames.get(&render_resource).unwrap().output.view),
TextureAttachment::Input(_) => panic!("Encountered unset TextureAttachment::Input. The RenderGraph executor should always set TextureAttachment::Inputs to TextureAttachment::RenderResource before running. This is a bug"),
}
}
@ -257,5 +244,7 @@ fn create_wgpu_depth_stencil_attachment_descriptor<'a>(
stencil_store_op: depth_stencil_attachment_descriptor
.stencil_store_op
.wgpu_into(),
depth_read_only: depth_stencil_attachment_descriptor.depth_read_only,
stencil_read_only: depth_stencil_attachment_descriptor.stencil_read_only,
}
}

View file

@ -36,46 +36,6 @@ impl WgpuRenderResourceContext {
window_surfaces.insert(window_id, surface);
}
pub fn create_texture_with_data(
&mut self,
command_encoder: &mut wgpu::CommandEncoder,
texture_descriptor: TextureDescriptor,
bytes: &[u8],
) -> RenderResource {
let mut resource_info = self.resources.resource_info.write().unwrap();
let mut texture_views = self.resources.texture_views.write().unwrap();
let mut textures = self.resources.textures.write().unwrap();
let descriptor: wgpu::TextureDescriptor = (&texture_descriptor).wgpu_into();
let texture = self.device.create_texture(&descriptor);
let texture_view = texture.create_default_view();
let temp_buf = self
.device
.create_buffer_with_data(bytes, wgpu::BufferUsage::COPY_SRC);
command_encoder.copy_buffer_to_texture(
wgpu::BufferCopyView {
buffer: &temp_buf,
offset: 0,
bytes_per_row: 4 * descriptor.size.width,
rows_per_image: 0, // NOTE: Example sets this to 0, but should it be height?
},
wgpu::TextureCopyView {
texture: &texture,
mip_level: 0,
array_layer: 0,
origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
},
descriptor.size,
);
let resource = RenderResource::new();
resource_info.insert(resource, ResourceInfo::Texture(texture_descriptor));
texture_views.insert(resource, texture_view);
textures.insert(resource, texture);
resource
}
pub fn copy_buffer_to_buffer(
&self,
command_encoder: &mut wgpu::CommandEncoder,
@ -107,7 +67,6 @@ impl WgpuRenderResourceContext {
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.resources.buffers.read().unwrap();
@ -118,14 +77,15 @@ impl WgpuRenderResourceContext {
command_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?
layout: wgpu::TextureDataLayout {
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],
@ -207,6 +167,7 @@ impl RenderResourceContext for WgpuRenderResourceContext {
label: None,
size: buffer_info.size as u64,
usage: buffer_info.buffer_usage.wgpu_into(),
mapped_at_creation: false,
});
let resource = RenderResource::new();
@ -220,14 +181,24 @@ impl RenderResourceContext for WgpuRenderResourceContext {
buffer_info: BufferInfo,
setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext),
) -> RenderResource {
let mut mapped = self.device.create_buffer_mapped(&wgpu::BufferDescriptor {
let usage: wgpu::BufferUsage = buffer_info.buffer_usage.wgpu_into();
let buffer = self.device.create_buffer(&wgpu::BufferDescriptor {
size: buffer_info.size as u64,
usage: buffer_info.buffer_usage.wgpu_into(),
usage: usage | wgpu::BufferUsage::MAP_WRITE,
label: None,
mapped_at_creation: false,
});
setup_data(&mut mapped.data(), self);
let buffer = mapped.finish();
let data = buffer.map_async(wgpu::MapMode::Write, 0, wgpu::BufferSize::WHOLE);
self.device.poll(wgpu::Maintain::Wait);
if let Ok(()) = pollster::block_on(data) {
let data = buffer.get_mapped_range_mut(0, wgpu::BufferSize::WHOLE);
setup_data(data, self);
} else {
panic!("failed to map buffer to host");
}
buffer.unmap();
let resource = RenderResource::new();
let mut resource_info = self.resources.resource_info.write().unwrap();
let mut buffers = self.resources.buffers.write().unwrap();
@ -326,10 +297,10 @@ impl RenderResourceContext for WgpuRenderResourceContext {
fn next_swap_chain_texture(&self, window_id: bevy_window::WindowId) -> RenderResource {
let mut window_swap_chains = self.resources.window_swap_chains.write().unwrap();
let mut swap_chain_outputs = self.resources.swap_chain_outputs.write().unwrap();
let mut swap_chain_outputs = self.resources.swap_chain_frames.write().unwrap();
let window_swap_chain = window_swap_chains.get_mut(&window_id).unwrap();
let next_texture = window_swap_chain.get_next_texture().unwrap();
let next_texture = window_swap_chain.get_next_frame().unwrap();
// TODO: Add ResourceInfo
let render_resource = RenderResource::new();
@ -338,12 +309,12 @@ impl RenderResourceContext for WgpuRenderResourceContext {
}
fn drop_swap_chain_texture(&self, render_resource: RenderResource) {
let mut swap_chain_outputs = self.resources.swap_chain_outputs.write().unwrap();
let mut swap_chain_outputs = self.resources.swap_chain_frames.write().unwrap();
swap_chain_outputs.remove(&render_resource);
}
fn drop_all_swap_chain_textures(&self) {
let mut swap_chain_outputs = self.resources.swap_chain_outputs.write().unwrap();
let mut swap_chain_outputs = self.resources.swap_chain_frames.write().unwrap();
swap_chain_outputs.clear();
}
@ -521,10 +492,7 @@ impl RenderResourceContext for WgpuRenderResourceContext {
}
RenderResourceAssignment::Buffer { resource, range , .. } => {
let buffer = buffers.get(&resource).unwrap();
wgpu::BindingResource::Buffer {
buffer,
range: range.clone(),
}
wgpu::BindingResource::Buffer(buffer.slice(range.clone()))
}
};
wgpu::Binding {

View file

@ -25,7 +25,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64) {
let buffer = self.render_resources.buffers.get(&resource).unwrap();
self.render_pass
.set_vertex_buffer(start_slot, &buffer, offset, 0);
.set_vertex_buffer(start_slot, buffer.slice(offset..));
}
fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32) {
@ -39,7 +39,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64) {
let buffer = self.render_resources.buffers.get(&resource).unwrap();
self.render_pass.set_index_buffer(&buffer, offset, 0);
self.render_pass.set_index_buffer(buffer.slice(offset..));
}
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {

View file

@ -39,9 +39,7 @@ impl WgpuRenderer {
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
extensions: wgpu::Extensions::empty(),
limits: wgpu::Limits::default(),
},
None,

View file

@ -40,7 +40,7 @@ pub struct WgpuBindGroupInfo {
pub struct WgpuResourcesReadLock<'a> {
pub buffers: RwLockReadGuard<'a, HashMap<RenderResource, wgpu::Buffer>>,
pub textures: RwLockReadGuard<'a, HashMap<RenderResource, wgpu::TextureView>>,
pub swap_chain_outputs: RwLockReadGuard<'a, HashMap<RenderResource, wgpu::SwapChainOutput>>,
pub swap_chain_frames: RwLockReadGuard<'a, HashMap<RenderResource, wgpu::SwapChainFrame>>,
pub render_pipelines:
RwLockReadGuard<'a, HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>>,
pub bind_groups: RwLockReadGuard<'a, HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>>,
@ -51,7 +51,7 @@ impl<'a> WgpuResourcesReadLock<'a> {
WgpuResourceRefs {
buffers: &self.buffers,
textures: &self.textures,
swap_chain_outputs: &self.swap_chain_outputs,
swap_chain_frames: &self.swap_chain_frames,
render_pipelines: &self.render_pipelines,
bind_groups: &self.bind_groups,
}
@ -62,7 +62,7 @@ impl<'a> WgpuResourcesReadLock<'a> {
pub struct WgpuResourceRefs<'a> {
pub buffers: &'a HashMap<RenderResource, wgpu::Buffer>,
pub textures: &'a HashMap<RenderResource, wgpu::TextureView>,
pub swap_chain_outputs: &'a HashMap<RenderResource, wgpu::SwapChainOutput>,
pub swap_chain_frames: &'a HashMap<RenderResource, wgpu::SwapChainFrame>,
pub render_pipelines: &'a HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
pub bind_groups: &'a HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>,
}
@ -72,7 +72,7 @@ pub struct WgpuResources {
pub resource_info: Arc<RwLock<HashMap<RenderResource, ResourceInfo>>>,
pub window_surfaces: Arc<RwLock<HashMap<WindowId, wgpu::Surface>>>,
pub window_swap_chains: Arc<RwLock<HashMap<WindowId, wgpu::SwapChain>>>,
pub swap_chain_outputs: Arc<RwLock<HashMap<RenderResource, wgpu::SwapChainOutput>>>,
pub swap_chain_frames: Arc<RwLock<HashMap<RenderResource, wgpu::SwapChainFrame>>>,
pub buffers: Arc<RwLock<HashMap<RenderResource, wgpu::Buffer>>>,
pub texture_views: Arc<RwLock<HashMap<RenderResource, wgpu::TextureView>>>,
pub textures: Arc<RwLock<HashMap<RenderResource, wgpu::Texture>>>,
@ -89,7 +89,7 @@ impl WgpuResources {
WgpuResourcesReadLock {
buffers: self.buffers.read().unwrap(),
textures: self.texture_views.read().unwrap(),
swap_chain_outputs: self.swap_chain_outputs.read().unwrap(),
swap_chain_frames: self.swap_chain_frames.read().unwrap(),
render_pipelines: self.render_pipelines.read().unwrap(),
bind_groups: self.bind_groups.read().unwrap(),
}

View file

@ -506,7 +506,8 @@ impl WgpuFrom<SamplerDescriptor> for wgpu::SamplerDescriptor<'_> {
mipmap_filter: sampler_descriptor.mipmap_filter.wgpu_into(),
lod_min_clamp: sampler_descriptor.lod_min_clamp,
lod_max_clamp: sampler_descriptor.lod_max_clamp,
compare: sampler_descriptor.compare_function.wgpu_into(),
compare: sampler_descriptor.compare_function.map(|c| c.wgpu_into()),
anisotropy_clamp: sampler_descriptor.anisotropy_clamp.clone(),
}
}
}