RenderResourceAssignment refactor

This commit is contained in:
Carter Anderson 2020-05-11 13:55:23 -07:00
parent ef2e5a1ba3
commit 7a71873a32
12 changed files with 206 additions and 184 deletions

View file

@ -1,6 +1,8 @@
use bevy_render::{
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments},
render_resource::{
resource_name, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
},
renderer::{RenderContext, RenderResources},
};
@ -78,7 +80,14 @@ impl SystemNode for LightsNode {
| BufferUsage::COPY_DST,
..Default::default()
});
render_resource_assignments.set(resource_name::uniform::LIGHTS, buffer);
render_resource_assignments.set(
resource_name::uniform::LIGHTS,
RenderResourceAssignment::Buffer {
resource: buffer,
range: 0..light_uniform_size as u64,
dynamic_index: None,
},
);
light_buffer = Some(buffer);
}

View file

@ -4,12 +4,15 @@ use super::{
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor,
},
PipelineLayout, VertexBufferDescriptors, BindType,
BindType, PipelineLayout, VertexBufferDescriptors,
};
use crate::{
render_resource::{ResourceInfo, RenderResourceAssignments, BufferInfo},
render_resource::{
BufferInfo, RenderResourceAssignment, RenderResourceAssignments, ResourceInfo,
},
renderer::RenderResourceContext,
shader::{Shader, ShaderStages},
texture::TextureFormat, renderer::RenderResourceContext,
texture::TextureFormat,
};
use bevy_asset::AssetStorage;
@ -134,21 +137,21 @@ impl PipelineDescriptor {
}
/// Reflects the pipeline layout from its shaders.
///
///
/// If `bevy_conventions` is true, it will be assumed that the shader follows "bevy shader conventions". These allow
/// richer reflection, such as inferred Vertex Buffer names and inferred instancing.
///
/// If `vertex_buffer_descriptors` is set, the pipeline's vertex buffers
/// will inherit their layouts from global descriptors, otherwise the layout will be assumed to be complete / local.
///
/// If `dynamic_uniform_lookup` is set, shader uniforms will be set to "dynamic" if there is a matching "dynamic uniform"
/// If `render_resource_assignments` is set, shader uniforms will be set to "dynamic" if there is a matching "dynamic uniform"
/// render resource.
pub fn reflect_layout(
&mut self,
shaders: &AssetStorage<Shader>,
bevy_conventions: bool,
vertex_buffer_descriptors: Option<&VertexBufferDescriptors>,
dynamic_uniform_lookup: Option<(&RenderResourceAssignments, &dyn RenderResourceContext)>,
render_resource_assignments: Option<&RenderResourceAssignments>,
) {
let vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap();
let fragment_spirv = self
@ -167,30 +170,23 @@ impl PipelineDescriptor {
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
}
if let Some((render_resource_assignments, render_resource_context)) = dynamic_uniform_lookup {
if let Some(render_resource_assignments) = render_resource_assignments
{
// set binding uniforms to dynamic if render resource assignments use dynamic
// TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes.
// the fix would be to add "dynamic bindings" to the existing shader_def sets. this would ensure new pipelines are generated
// for all permutations of dynamic/non-dynamic
for bind_group in layout.bind_groups.iter_mut() {
for binding in bind_group.bindings.iter_mut() {
if let Some(render_resource) = render_resource_assignments.get(&binding.name) {
render_resource_context.get_resource_info(
render_resource,
&mut |resource_info| {
if let Some(ResourceInfo::Buffer(BufferInfo {
is_dynamic, ..
})) = resource_info
{
if let BindType::Uniform {
ref mut dynamic, ..
} = binding.bind_type
{
*dynamic = *is_dynamic
}
}
},
);
if let Some(RenderResourceAssignment::Buffer { dynamic_index: Some(_), .. }) =
render_resource_assignments.get(&binding.name)
{
if let BindType::Uniform {
ref mut dynamic, ..
} = binding.bind_type
{
*dynamic = true;
}
}
}
}

View file

@ -84,7 +84,6 @@ impl PipelineCompiler {
&mut self,
vertex_buffer_descriptors: &VertexBufferDescriptors,
shaders: &mut AssetStorage<Shader>,
render_resource_context: &dyn RenderResourceContext,
pipeline_descriptor: &PipelineDescriptor,
render_resource_assignments: &RenderResourceAssignments,
) -> PipelineDescriptor {
@ -115,7 +114,7 @@ impl PipelineCompiler {
shaders,
true,
Some(vertex_buffer_descriptors),
Some((render_resource_assignments, render_resource_context)),
Some(render_resource_assignments),
);
compiled_pipeline_descriptor.primitive_topology = render_resource_assignments
@ -128,7 +127,6 @@ impl PipelineCompiler {
&mut self,
vertex_buffer_descriptors: &VertexBufferDescriptors,
shader_pipeline_assignments: &mut PipelineAssignments,
render_resource_context: &dyn RenderResourceContext,
pipeline_storage: &mut AssetStorage<PipelineDescriptor>,
shader_storage: &mut AssetStorage<Shader>,
pipelines: &[Handle<PipelineDescriptor>],
@ -154,7 +152,6 @@ impl PipelineCompiler {
let compiled_pipeline = self.compile_pipeline(
vertex_buffer_descriptors,
shader_storage,
render_resource_context,
pipeline_descriptor,
render_resource_assignments,
);
@ -230,7 +227,6 @@ pub fn update_shader_assignments(world: &mut World, resources: &Resources) {
let mut pipeline_compiler = resources.get_mut::<PipelineCompiler>().unwrap();
let mut shader_storage = resources.get_mut::<AssetStorage<Shader>>().unwrap();
let vertex_buffer_descriptors = resources.get::<VertexBufferDescriptors>().unwrap();
let render_resources = resources.get::<RenderResources>().unwrap();
let mut pipeline_descriptor_storage = resources
.get_mut::<AssetStorage<PipelineDescriptor>>()
.unwrap();
@ -248,7 +244,6 @@ pub fn update_shader_assignments(world: &mut World, resources: &Resources) {
pipeline_compiler.update_shader_assignments(
&vertex_buffer_descriptors,
&mut shader_pipeline_assignments,
&*render_resources.context,
&mut pipeline_descriptor_storage,
&mut shader_storage,
&renderable.pipelines,

View file

@ -4,7 +4,7 @@ use bevy_window::WindowResized;
use crate::{
camera::{ActiveCamera2d, Camera},
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments},
render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments, RenderResourceAssignment},
renderer::{RenderContext, RenderResources},
};
@ -52,12 +52,20 @@ impl SystemNode for Camera2dNode {
query| {
let render_resources = &render_resource_context.context;
if camera_buffer.is_none() {
let size = std::mem::size_of::<[[f32; 4]; 4]>();
let buffer = render_resources.create_buffer(BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>(),
size,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
render_resource_assignments.set(resource_name::uniform::CAMERA2D, buffer);
render_resource_assignments.set(
resource_name::uniform::CAMERA2D,
RenderResourceAssignment::Buffer {
resource: buffer,
range: 0..size as u64,
dynamic_index: None,
},
);
camera_buffer = Some(buffer);
}

View file

@ -1,6 +1,8 @@
use crate::{
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments},
render_resource::{
resource_name, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
},
renderer::{RenderContext, RenderResources},
ActiveCamera, Camera,
};
@ -52,12 +54,20 @@ impl SystemNode for CameraNode {
query| {
let render_resources = &render_resource_context.context;
if camera_buffer.is_none() {
let size = std::mem::size_of::<[[f32; 4]; 4]>();
let buffer = render_resources.create_buffer(BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>(),
size,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
render_resource_assignments.set(resource_name::uniform::CAMERA, buffer);
render_resource_assignments.set(
resource_name::uniform::CAMERA,
RenderResourceAssignment::Buffer {
resource: buffer,
range: 0..size as u64,
dynamic_index: None,
},
);
camera_buffer = Some(buffer);
}

View file

@ -2,8 +2,8 @@ use crate::{
pipeline::VertexBufferDescriptors,
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{
BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
RenderResourceAssignmentsId, ResourceInfo,
BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignment,
RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo,
},
renderer::{RenderContext, RenderResourceContext, RenderResources},
shader::{AsUniforms, FieldBindType},
@ -224,42 +224,40 @@ where
let (_name, uniform_buffer_status) = self.uniform_arrays[i].as_mut().unwrap();
let (target_buffer, target_offset) = if dynamic_uniforms {
let buffer = uniform_buffer_status.buffer.unwrap();
let mut offset = 0;
render_resources.get_resource_info(buffer, &mut |resource_info| {
if let Some(ResourceInfo::Buffer(BufferInfo {
array_info: Some(ref array_info),
is_dynamic: true,
..
})) = resource_info
{
let index = uniform_buffer_status
.get_or_assign_index(render_resource_assignments.id);
render_resource_assignments.set_indexed(
&field_info.uniform_name,
buffer,
(index * array_info.item_size) as u32,
);
offset = index * uniform_buffer_status.aligned_size;
} else {
panic!("Expected a dynamic uniform buffer");
}
});
(buffer, offset)
let index = uniform_buffer_status
.get_or_assign_index(render_resource_assignments.id);
render_resource_assignments.set(
&field_info.uniform_name,
RenderResourceAssignment::Buffer {
resource: buffer,
dynamic_index: Some(
(index * uniform_buffer_status.aligned_size) as u32,
),
range: 0..size as u64,
},
);
(buffer, index * uniform_buffer_status.aligned_size)
} else {
let resource = match render_resource_assignments
.get(field_info.uniform_name)
{
Some(render_resource) => render_resource,
None => {
let resource = render_resources.create_buffer(BufferInfo {
size,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
render_resource_assignments.set(&field_info.uniform_name, resource);
resource
}
};
let resource =
match render_resource_assignments.get(field_info.uniform_name) {
Some(assignment) => assignment.get_resource(),
None => {
let resource = render_resources.create_buffer(BufferInfo {
size,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
render_resource_assignments.set(
&field_info.uniform_name,
RenderResourceAssignment::Buffer {
resource,
range: 0..size as u64,
dynamic_index: None,
},
);
resource
}
};
(resource, 0)
};
@ -791,8 +789,14 @@ fn setup_uniform_texture_resources<T>(
}
};
render_resource_assignments.set(field_info.texture_name, texture_resource);
render_resource_assignments.set(field_info.sampler_name, sampler_resource);
render_resource_assignments.set(
field_info.texture_name,
RenderResourceAssignment::Texture(texture_resource),
);
render_resource_assignments.set(
field_info.sampler_name,
RenderResourceAssignment::Sampler(sampler_resource),
);
}
_ => {}
}

View file

@ -2,46 +2,63 @@ use super::RenderResource;
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization};
use std::{
collections::{hash_map::DefaultHasher, HashMap, HashSet},
hash::{Hash, Hasher},
hash::{Hash, Hasher}, ops::Range,
};
use uuid::Uuid;
#[derive(Clone, Eq, PartialEq, Debug)]
pub enum RenderResourceAssignment {
Buffer {
resource: RenderResource,
range: Range<u64>,
dynamic_index: Option<u32>,
},
Texture(RenderResource),
Sampler(RenderResource),
}
impl RenderResourceAssignment {
pub fn get_resource(&self) -> RenderResource {
match self {
RenderResourceAssignment::Buffer { resource, .. } => *resource,
RenderResourceAssignment::Texture(resource) => *resource,
RenderResourceAssignment::Sampler(resource) => *resource,
}
}
}
#[derive(Eq, PartialEq, Debug)]
pub struct RenderResourceSet {
pub id: RenderResourceSetId,
pub dynamic_uniform_indices: Option<Vec<u32>>,
}
// PERF: if the assignments are scoped to a specific pipeline layout, then names could be replaced with indices here for a perf boost
#[derive(Eq, PartialEq, Debug, Default)]
pub struct RenderResourceAssignments {
pub id: RenderResourceAssignmentsId,
render_resources: HashMap<String, (RenderResource, Option<u32>)>,
render_resources: HashMap<String, RenderResourceAssignment>,
vertex_buffers: HashMap<String, (RenderResource, Option<RenderResource>)>,
bind_group_resource_sets:
HashMap<BindGroupDescriptorId, (RenderResourceSetId, Option<Vec<u32>>)>,
HashMap<BindGroupDescriptorId, RenderResourceSet>,
dirty_bind_groups: HashSet<BindGroupDescriptorId>,
pub pipeline_specialization: PipelineSpecialization,
}
impl RenderResourceAssignments {
pub fn get(&self, name: &str) -> Option<RenderResource> {
self.render_resources.get(name).map(|(r, _i)| *r)
pub fn get(&self, name: &str) -> Option<&RenderResourceAssignment> {
self.render_resources.get(name)
}
pub fn get_indexed(&self, name: &str) -> Option<(RenderResource, Option<u32>)> {
self.render_resources.get(name).cloned()
}
pub fn set(&mut self, name: &str, resource: RenderResource) {
self.try_set_dirty(name, resource);
pub fn set(&mut self, name: &str, assignment: RenderResourceAssignment) {
self.try_set_dirty(name, &assignment);
self.render_resources
.insert(name.to_string(), (resource, None));
.insert(name.to_string(), assignment);
}
pub fn set_indexed(&mut self, name: &str, resource: RenderResource, index: u32) {
self.try_set_dirty(name, resource);
self.render_resources
.insert(name.to_string(), (resource, Some(index)));
}
fn try_set_dirty(&mut self, name: &str, resource: RenderResource) {
if let Some((render_resource, _)) = self.render_resources.get(name) {
if *render_resource != resource {
fn try_set_dirty(&mut self, name: &str, assignment: &RenderResourceAssignment) {
if let Some(current_assignment) = self.render_resources.get(name) {
if current_assignment != assignment {
// TODO: this is pretty crude. can we do better?
for bind_group_id in self.bind_group_resource_sets.keys() {
self.dirty_bind_groups.insert(*bind_group_id);
@ -76,53 +93,55 @@ impl RenderResourceAssignments {
.contains_key(&bind_group_descriptor.id)
|| self.dirty_bind_groups.contains(&bind_group_descriptor.id)
{
let result = self.generate_render_resource_set_id(bind_group_descriptor);
if let Some((set_id, indices)) = result {
let resource_set = self.generate_render_resource_set(bind_group_descriptor);
if let Some(resource_set) = resource_set {
let id = resource_set.id;
self.bind_group_resource_sets
.insert(bind_group_descriptor.id, (set_id, indices));
Some(set_id)
.insert(bind_group_descriptor.id, resource_set);
Some(id)
} else {
None
}
} else {
self.bind_group_resource_sets
.get(&bind_group_descriptor.id)
.map(|(set_id, _indices)| *set_id)
.map(|set| set.id)
}
}
pub fn get_render_resource_set_id(
pub fn get_render_resource_set(
&self,
bind_group_descriptor_id: BindGroupDescriptorId,
) -> Option<&(RenderResourceSetId, Option<Vec<u32>>)> {
) -> Option<&RenderResourceSet> {
self.bind_group_resource_sets.get(&bind_group_descriptor_id)
}
fn generate_render_resource_set_id(
fn generate_render_resource_set(
&self,
bind_group_descriptor: &BindGroupDescriptor,
) -> Option<(RenderResourceSetId, Option<Vec<u32>>)> {
) -> Option<RenderResourceSet> {
let mut hasher = DefaultHasher::new();
let mut indices = Vec::new();
for binding_descriptor in bind_group_descriptor.bindings.iter() {
if let Some((render_resource, index)) = self.get_indexed(&binding_descriptor.name) {
render_resource.hash(&mut hasher);
if let Some(index) = index {
indices.push(index);
if let Some(assignment) = self.get(&binding_descriptor.name) {
let resource = assignment.get_resource();
resource.hash(&mut hasher);
if let RenderResourceAssignment::Buffer { dynamic_index: Some(index), .. } = assignment {
indices.push(*index);
}
} else {
return None;
}
}
Some((
RenderResourceSetId(hasher.finish()),
if indices.is_empty() {
Some(RenderResourceSet {
id: RenderResourceSetId(hasher.finish()),
dynamic_uniform_indices: if indices.is_empty() {
None
} else {
Some(indices)
},
))
})
}
}
@ -176,22 +195,22 @@ mod tests {
],
);
let resource1 = RenderResource::new();
let resource2 = RenderResource::new();
let resource3 = RenderResource::new();
let resource4 = RenderResource::new();
let resource1 = RenderResourceAssignment::Texture(RenderResource::new());
let resource2 = RenderResourceAssignment::Texture(RenderResource::new());
let resource3 = RenderResourceAssignment::Texture(RenderResource::new());
let resource4 = RenderResourceAssignment::Texture(RenderResource::new());
let mut assignments = RenderResourceAssignments::default();
assignments.set("a", resource1);
assignments.set("b", resource2);
assignments.set("a", resource1.clone());
assignments.set("b", resource2.clone());
let mut different_assignments = RenderResourceAssignments::default();
different_assignments.set("a", resource3);
different_assignments.set("b", resource4);
different_assignments.set("a", resource3.clone());
different_assignments.set("b", resource4.clone());
let mut equal_assignments = RenderResourceAssignments::default();
equal_assignments.set("a", resource1);
equal_assignments.set("b", resource2);
equal_assignments.set("a", resource1.clone());
equal_assignments.set("b", resource2.clone());
let set_id = assignments.update_render_resource_set_id(&bind_group_descriptor);
assert_ne!(set_id, None);
@ -206,7 +225,7 @@ mod tests {
assert_eq!(equal_set_id, set_id);
let mut unmatched_assignments = RenderResourceAssignments::default();
unmatched_assignments.set("a", resource1);
unmatched_assignments.set("a", resource1.clone());
let unmatched_set_id =
unmatched_assignments.update_render_resource_set_id(&bind_group_descriptor);
assert_eq!(unmatched_set_id, None);

View file

@ -10,6 +10,7 @@ pub struct BufferArrayInfo {
pub struct BufferInfo {
pub size: usize,
pub buffer_usage: BufferUsage,
// TODO: remove array info and is_dynamic
pub array_info: Option<BufferArrayInfo>,
pub is_dynamic: bool,
}

View file

@ -121,10 +121,10 @@ impl RenderResourceContext for HeadlessRenderResourceContext {
bind_group_descriptor: &BindGroupDescriptor,
render_resource_assignments: &RenderResourceAssignments,
) -> Option<RenderResourceSetId> {
if let Some((render_resource_set_id, _indices)) =
render_resource_assignments.get_render_resource_set_id(bind_group_descriptor.id)
if let Some(resource_set) =
render_resource_assignments.get_render_resource_set(bind_group_descriptor.id)
{
Some(*render_resource_set_id)
Some(resource_set.id)
} else {
None
}

View file

@ -6,7 +6,7 @@ use bevy_render::{
PassDescriptor, RenderPass, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor, TextureAttachment,
},
render_resource::{RenderResource, RenderResourceAssignments},
render_resource::{RenderResource, RenderResourceAssignments, RenderResourceAssignment},
renderer::{RenderContext, RenderResourceContext},
texture::{Extent3d, TextureDescriptor},
};
@ -195,8 +195,8 @@ fn get_texture_view<'a>(
) -> &'a wgpu::TextureView {
match attachment {
TextureAttachment::Name(name) => match global_render_resource_assignments.get(&name) {
Some(resource) => refs.textures.get(&resource).unwrap(),
None => {
Some(RenderResourceAssignment::Texture(resource)) => refs.textures.get(&resource).unwrap(),
_ => {
panic!("Color attachment {} does not exist", name);
}
},

View file

@ -7,7 +7,8 @@ use bevy_asset::{AssetStorage, Handle, HandleUntyped};
use bevy_render::{
pipeline::{BindGroupDescriptor, BindType, PipelineDescriptor},
render_resource::{
BufferInfo, RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo,
BufferInfo, RenderResource, RenderResourceAssignment, RenderResourceAssignments,
RenderResourceSetId, ResourceInfo,
},
renderer::RenderResourceContext,
shader::Shader,
@ -287,11 +288,7 @@ impl RenderResourceContext for WgpuRenderResourceContext {
handle_info(info);
}
fn create_shader_module_from_source(
&self,
shader_handle: Handle<Shader>,
shader: &Shader,
) {
fn create_shader_module_from_source(&self, shader_handle: Handle<Shader>, shader: &Shader) {
let mut shader_modules = self.resources.shader_modules.write().unwrap();
let shader_module = self.device.create_shader_module(&shader.get_spirv(None));
shader_modules.insert(shader_handle, shader_module);
@ -484,21 +481,20 @@ impl RenderResourceContext for WgpuRenderResourceContext {
bind_group_descriptor: &BindGroupDescriptor,
render_resource_assignments: &RenderResourceAssignments,
) -> Option<RenderResourceSetId> {
if let Some((render_resource_set_id, _indices)) =
render_resource_assignments.get_render_resource_set_id(bind_group_descriptor.id)
if let Some(render_resource_set) =
render_resource_assignments.get_render_resource_set(bind_group_descriptor.id)
{
if !self
.resources
.has_bind_group(bind_group_descriptor.id, *render_resource_set_id)
.has_bind_group(bind_group_descriptor.id, render_resource_set.id)
{
log::trace!(
"start creating bind group for RenderResourceSet {:?}",
render_resource_set_id
render_resource_set.id
);
let texture_views = self.resources.texture_views.read().unwrap();
let samplers = self.resources.samplers.read().unwrap();
let buffers = self.resources.buffers.read().unwrap();
let resource_info = self.resources.resource_info.read().unwrap();
let bind_group_layouts = self.resources.bind_group_layouts.read().unwrap();
let mut bind_groups = self.resources.bind_groups.write().unwrap();
@ -506,43 +502,27 @@ impl RenderResourceContext for WgpuRenderResourceContext {
.bindings
.iter()
.map(|binding| {
if let Some(resource) = render_resource_assignments.get(&binding.name) {
let info = resource_info
.get(&resource)
.expect("referenced resource does not exist");
if let Some(assignment) = render_resource_assignments.get(&binding.name) {
log::trace!(
"found binding {} ({}) resource: {:?} {:?}",
"found binding {} ({}) assignment: {:?}",
binding.index,
binding.name,
resource,
resource_info
assignment,
);
let wgpu_resource = match &binding.bind_type {
BindType::SampledTexture { .. } => {
if let ResourceInfo::Texture = info {
let texture = texture_views.get(&resource).unwrap();
wgpu::BindingResource::TextureView(texture)
} else {
panic!("expected a Texture resource");
}
let wgpu_resource = match assignment {
RenderResourceAssignment::Texture(resource) => {
let texture = texture_views.get(&resource).unwrap();
wgpu::BindingResource::TextureView(texture)
}
BindType::Sampler { .. } => {
if let ResourceInfo::Sampler = info {
let sampler = samplers.get(&resource).unwrap();
wgpu::BindingResource::Sampler(sampler)
} else {
panic!("expected a Sampler resource");
}
RenderResourceAssignment::Sampler(resource) => {
let sampler = samplers.get(&resource).unwrap();
wgpu::BindingResource::Sampler(sampler)
}
BindType::Uniform { .. } => {
if let ResourceInfo::Buffer(buffer_info) = info {
let buffer = buffers.get(&resource).unwrap();
wgpu::BindingResource::Buffer {
buffer,
range: 0..buffer_info.size as u64,
}
} else {
panic!("expected a Buffer resource");
RenderResourceAssignment::Buffer { resource, range , .. } => {
let buffer = buffers.get(&resource).unwrap();
wgpu::BindingResource::Buffer {
buffer,
range: range.clone(),
}
}
_ => panic!("unsupported bind type"),
@ -574,12 +554,12 @@ impl RenderResourceContext for WgpuRenderResourceContext {
.or_insert_with(|| WgpuBindGroupInfo::default());
bind_group_info
.bind_groups
.insert(*render_resource_set_id, wgpu_bind_group);
.insert(render_resource_set.id, wgpu_bind_group);
log::trace!(
"created bind group for RenderResourceSet {:?}",
render_resource_set_id
render_resource_set.id
);
return Some(*render_resource_set_id);
return Some(render_resource_set.id);
}
}

View file

@ -89,17 +89,17 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
}
for bind_group in pipeline_layout.bind_groups.iter() {
if let Some((render_resource_set_id, dynamic_uniform_indices)) =
render_resource_assignments.get_render_resource_set_id(bind_group.id)
if let Some(resource_set) =
render_resource_assignments.get_render_resource_set(bind_group.id)
{
if let Some(bind_group_info) = self.render_resources.bind_groups.get(&bind_group.id)
{
if let Some(wgpu_bind_group) =
bind_group_info.bind_groups.get(render_resource_set_id)
bind_group_info.bind_groups.get(&resource_set.id)
{
const EMPTY: &'static [u32] = &[];
let dynamic_uniform_indices =
if let Some(dynamic_uniform_indices) = dynamic_uniform_indices {
if let Some(ref dynamic_uniform_indices) = resource_set.dynamic_uniform_indices {
dynamic_uniform_indices.as_slice()
} else {
EMPTY
@ -110,7 +110,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
if let Some(bound_render_resource_set) =
self.bound_bind_groups.get(&bind_group.index)
{
if *bound_render_resource_set == *render_resource_set_id
if *bound_render_resource_set == resource_set.id
&& dynamic_uniform_indices.len() == 0
{
continue;
@ -119,7 +119,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
if dynamic_uniform_indices.len() == 0 {
self.bound_bind_groups
.insert(bind_group.index, *render_resource_set_id);
.insert(bind_group.index, resource_set.id);
} else {
self.bound_bind_groups.remove(&bind_group.index);
}
@ -128,7 +128,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
"set bind group {} {:?}: {:?}",
bind_group.index,
dynamic_uniform_indices,
render_resource_set_id
resource_set.id
);
self.render_pass.set_bind_group(
bind_group.index,