render: rename "Assignment" to "Binding" and "AssignmentSet" to "BindGroup"

This commit is contained in:
Carter Anderson 2020-06-14 12:02:19 -07:00
parent 0f608fc90f
commit 0fec350411
26 changed files with 500 additions and 501 deletions

View file

@ -1,7 +1,7 @@
use bevy_render::{
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{
BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
BufferInfo, BufferUsage, RenderResourceBinding, RenderResourceBindings,
},
renderer::{RenderContext, RenderResources},
};
@ -62,7 +62,7 @@ impl SystemNode for LightsNode {
(move |world: &mut SubWorld,
render_resources: Res<RenderResources>,
// TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same
mut render_resource_assignments: ResMut<RenderResourceAssignments>,
mut render_resource_bindings: ResMut<RenderResourceBindings>,
query: &mut Query<(Read<Light>, Read<Transform>, Read<Translation>)>| {
if !lights_are_dirty {
return;
@ -80,9 +80,9 @@ impl SystemNode for LightsNode {
| BufferUsage::COPY_DST,
..Default::default()
});
render_resource_assignments.set(
render_resource_bindings.set(
uniform::LIGHTS,
RenderResourceAssignment::Buffer {
RenderResourceBinding::Buffer {
buffer,
range: 0..light_uniform_size as u64,
dynamic_index: None,

View file

@ -1,8 +1,8 @@
use crate::{
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
render_resource::{
BufferId, BufferUsage, RenderResource, RenderResourceAssignment, RenderResourceAssignments,
RenderResourceSet, RenderResourceSetId, SharedBuffers,
BufferId, BufferUsage, RenderResource, RenderResourceBinding, RenderResourceBindings,
BindGroup, BindGroupId, SharedBuffers,
},
renderer::{RenderResourceContext, RenderResources},
};
@ -32,7 +32,7 @@ pub enum RenderCommand {
SetBindGroup {
index: u32,
bind_group_descriptor: BindGroupDescriptorId,
render_resource_set: RenderResourceSetId,
bind_group: BindGroupId,
dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
},
DrawIndexed {
@ -63,7 +63,7 @@ pub struct RenderPipelines {
pub pipelines: Vec<Handle<PipelineDescriptor>>,
// TODO: make these pipeline specific
#[property(ignore)]
pub render_resource_assignments: RenderResourceAssignments,
pub render_resource_bindings: RenderResourceBindings,
#[property(ignore)]
pub compiled_pipelines: Vec<Handle<PipelineDescriptor>>,
}
@ -71,7 +71,7 @@ pub struct RenderPipelines {
impl Default for RenderPipelines {
fn default() -> Self {
Self {
render_resource_assignments: Default::default(),
render_resource_bindings: Default::default(),
compiled_pipelines: Default::default(),
pipelines: vec![Handle::default()],
}
@ -83,14 +83,14 @@ impl Draw {
&'a mut self,
pipelines: &'a Assets<PipelineDescriptor>,
render_resource_context: &'a dyn RenderResourceContext,
render_resource_assignments: &'a RenderResourceAssignments,
render_resource_bindings: &'a RenderResourceBindings,
shared_buffers: &'a SharedBuffers,
) -> DrawContext {
DrawContext {
draw: self,
pipelines,
render_resource_context,
render_resource_assignments,
render_resource_bindings: render_resource_bindings,
shared_buffers,
current_pipeline: None,
}
@ -117,7 +117,7 @@ pub struct DrawContext<'a> {
pub draw: &'a mut Draw,
pub pipelines: &'a Assets<PipelineDescriptor>,
pub render_resource_context: &'a dyn RenderResourceContext,
pub render_resource_assignments: &'a RenderResourceAssignments,
pub render_resource_bindings: &'a RenderResourceBindings,
pub shared_buffers: &'a SharedBuffers,
pub current_pipeline: Option<&'a PipelineDescriptor>,
}
@ -126,14 +126,14 @@ impl<'a> DrawContext<'a> {
pub fn get_uniform_buffer<T: RenderResource>(
&self,
render_resource: &T,
) -> Result<RenderResourceAssignment, DrawError> {
) -> Result<RenderResourceBinding, DrawError> {
self.get_buffer(render_resource, BufferUsage::UNIFORM)
}
pub fn get_buffer<T: RenderResource>(
&self,
render_resource: &T,
buffer_usage: BufferUsage,
) -> Result<RenderResourceAssignment, DrawError> {
) -> Result<RenderResourceBinding, DrawError> {
self.shared_buffers
.get_buffer(render_resource, buffer_usage)
.ok_or_else(|| DrawError::BufferAllocationFailure)
@ -169,13 +169,13 @@ impl<'a> DrawContext<'a> {
pub fn set_bind_group(
&mut self,
bind_group_descriptor: &BindGroupDescriptor,
render_resource_set: &RenderResourceSet,
bind_group: &BindGroup,
) {
self.render_command(RenderCommand::SetBindGroup {
index: bind_group_descriptor.index,
bind_group_descriptor: bind_group_descriptor.id,
render_resource_set: render_resource_set.id,
dynamic_uniform_indices: render_resource_set.dynamic_uniform_indices.clone(),
bind_group: bind_group.id,
dynamic_uniform_indices: bind_group.dynamic_uniform_indices.clone(),
});
}
@ -207,17 +207,17 @@ impl Drawable for RenderPipelines {
let pipeline = draw.pipelines.get(pipeline_handle).unwrap();
let layout = pipeline.get_layout().unwrap();
draw.set_pipeline(*pipeline_handle)?;
for bind_group in layout.bind_groups.iter() {
if let Some(local_render_resource_set) = self
.render_resource_assignments
.get_bind_group_render_resource_set(bind_group.id)
for bind_group_descriptor in layout.bind_groups.iter() {
if let Some(local_bind_group) = self
.render_resource_bindings
.get_descriptor_bind_group(bind_group_descriptor.id)
{
draw.set_bind_group(bind_group, local_render_resource_set);
} else if let Some(global_render_resource_set) = draw
.render_resource_assignments
.get_bind_group_render_resource_set(bind_group.id)
draw.set_bind_group(bind_group_descriptor, local_bind_group);
} else if let Some(global_bind_group) = draw
.render_resource_bindings
.get_descriptor_bind_group(bind_group_descriptor.id)
{
draw.set_bind_group(bind_group, global_render_resource_set);
draw.set_bind_group(bind_group_descriptor, global_bind_group);
}
}
let mut indices = 0..0;
@ -225,7 +225,7 @@ impl Drawable for RenderPipelines {
layout.vertex_buffer_descriptors.iter().enumerate()
{
if let Some((vertex_buffer, index_buffer)) = self
.render_resource_assignments
.render_resource_bindings
.get_vertex_buffer(&vertex_buffer_descriptor.name)
{
draw.set_vertex_buffer(slot as u32, vertex_buffer, 0);
@ -251,7 +251,7 @@ impl Drawable for RenderPipelines {
pub fn draw_system<T: Drawable + Component>(
pipelines: Res<Assets<PipelineDescriptor>>,
render_resource_assignments: Res<RenderResourceAssignments>,
render_resource_bindings: Res<RenderResourceBindings>,
render_resources: Res<RenderResources>,
shared_buffers: Res<SharedBuffers>,
mut draw: ComMut<Draw>,
@ -261,7 +261,7 @@ pub fn draw_system<T: Drawable + Component>(
let mut draw_context = draw.get_context(
&pipelines,
context,
&render_resource_assignments,
&render_resource_bindings,
&shared_buffers,
);
draw_context.draw(drawable.as_mut()).unwrap();

View file

@ -26,7 +26,7 @@ pub use once_cell;
use self::{
mesh::Mesh,
pipeline::{PipelineCompiler, PipelineDescriptor, VertexBufferDescriptors},
render_resource::RenderResourceAssignments,
render_resource::RenderResourceBindings,
shader::Shader,
texture::Texture,
};
@ -40,7 +40,7 @@ use legion::prelude::IntoSystem;
use mesh::mesh_resource_provider_system;
use pipeline::compile_pipelines_system;
use render_graph::{system::render_graph_schedule_executor_system, RenderGraph};
use render_resource::render_resource_sets_system;
use render_resource::bind_groups_system;
use std::ops::Range;
use texture::{PngTextureLoader, TextureResourceSystemState};
@ -89,7 +89,7 @@ impl AppPlugin for RenderPlugin {
.register_property_type::<Range<f32>>()
.init_resource::<RenderGraph>()
.init_resource::<PipelineCompiler>()
.init_resource::<RenderResourceAssignments>()
.init_resource::<RenderResourceBindings>()
.init_resource::<VertexBufferDescriptors>()
.init_resource::<TextureResourceSystemState>()
.add_system_to_stage(bevy_app::stage::PRE_UPDATE, clear_draw_system.system())
@ -117,7 +117,7 @@ impl AppPlugin for RenderPlugin {
)
.add_system_to_stage(
stage::RENDER_GRAPH_SYSTEMS,
render_resource_sets_system.system(),
bind_groups_system.system(),
)
.add_system_to_stage(stage::DRAW, draw_system::<RenderPipelines>.system());

View file

@ -409,7 +409,7 @@ pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box<dyn Sched
for (handle, mut render_pipelines) in query.iter_mut(world) {
if let Some(mesh) = meshes.get(&handle) {
render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
.primitive_topology = mesh.primitive_topology;
}
@ -418,7 +418,7 @@ pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box<dyn Sched
render_resources.get_asset_resource(*handle, VERTEX_BUFFER_ASSET_INDEX)
{
render_pipelines
.render_resource_assignments
.render_resource_bindings
.set_vertex_buffer(
"Vertex",
vertex_buffer,

View file

@ -1,6 +1,6 @@
use crate::{
pipeline::{PipelineDescriptor, BindGroupDescriptorId},
render_resource::{RenderResourceSetId, BufferId},
render_resource::{BindGroupId, BufferId},
renderer::RenderContext,
};
use bevy_asset::Handle;
@ -19,7 +19,7 @@ pub trait RenderPass {
&mut self,
index: u32,
bind_group_descriptor: BindGroupDescriptorId,
render_resource_set: RenderResourceSetId,
bind_group: BindGroupId,
dynamic_uniform_indices: Option<&[u32]>,
);
}

View file

@ -7,7 +7,7 @@ use super::{
BindType, PipelineLayout, VertexBufferDescriptors,
};
use crate::{
render_resource::{RenderResourceAssignment, RenderResourceAssignments},
render_resource::{RenderResourceBinding, RenderResourceBindings},
shader::{Shader, ShaderStages},
texture::TextureFormat,
};
@ -122,14 +122,14 @@ impl PipelineDescriptor {
/// 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 `render_resource_assignments` is set, shader uniforms will be set to "dynamic" if there is a matching "dynamic uniform"
/// If `render_resource_bindings` 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: &Assets<Shader>,
bevy_conventions: bool,
vertex_buffer_descriptors: Option<&VertexBufferDescriptors>,
render_resource_assignments: Option<&RenderResourceAssignments>,
render_resource_bindings: Option<&RenderResourceBindings>,
) {
let vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap();
let fragment_spirv = self
@ -148,17 +148,17 @@ impl PipelineDescriptor {
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
}
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.
if let Some(render_resource_bindings) = render_resource_bindings {
// set binding uniforms to dynamic if render resource bindings use dynamic
// TODO: this breaks down if different bindings 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(RenderResourceAssignment::Buffer {
if let Some(RenderResourceBinding::Buffer {
dynamic_index: Some(_),
..
}) = render_resource_assignments.get(&binding.name)
}) = render_resource_bindings.get(&binding.name)
{
if let BindType::Uniform {
ref mut dynamic, ..

View file

@ -86,7 +86,7 @@ impl PipelineCompiler {
shaders,
&pipeline_descriptor.shader_stages.vertex,
&render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
.shader_specialization,
);
@ -99,7 +99,7 @@ impl PipelineCompiler {
shaders,
fragment,
&render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
.shader_specialization,
)
@ -109,11 +109,11 @@ impl PipelineCompiler {
shaders,
true,
Some(vertex_buffer_descriptors),
Some(&render_pipelines.render_resource_assignments),
Some(&render_pipelines.render_resource_bindings),
);
compiled_pipeline_descriptor.primitive_topology = render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
.primitive_topology;
compiled_pipeline_descriptor
@ -141,7 +141,7 @@ impl PipelineCompiler {
.find(|(pipeline_specialization, _compiled_pipeline_handle)| {
*pipeline_specialization
== render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
}) {
*compiled_pipeline_handle
@ -166,7 +166,7 @@ impl PipelineCompiler {
.unwrap();
compiled_pipelines.push((
render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
.clone(),
compiled_pipeline_handle,
@ -231,7 +231,7 @@ pub fn compile_pipelines_system(
// reset shader_defs so they can be changed next frame
render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
.shader_specialization
.shader_defs

View file

@ -1,7 +1,7 @@
use crate::{
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{
BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
BufferInfo, BufferUsage, RenderResourceBinding, RenderResourceBindings,
},
renderer::{RenderContext, RenderResources},
Camera,
@ -51,7 +51,7 @@ impl SystemNode for CameraNode {
render_resources: Res<RenderResources>,
// PERF: this write on RenderResourceAssignments will prevent this system from running in parallel
// with other systems that do the same
mut render_resource_assignments: ResMut<RenderResourceAssignments>,
mut render_resource_bindings: ResMut<RenderResourceBindings>,
query: &mut Query<(Read<Camera>, Read<Transform>)>| {
let render_resources = &render_resources.context;
if camera_buffer.is_none() {
@ -61,9 +61,9 @@ impl SystemNode for CameraNode {
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
render_resource_assignments.set(
render_resource_bindings.set(
&uniform_name,
RenderResourceAssignment::Buffer {
RenderResourceBinding::Buffer {
buffer,
range: 0..size as u64,
dynamic_index: None,

View file

@ -3,7 +3,7 @@ use crate::{
pass::{PassDescriptor, TextureAttachment},
pipeline::PipelineDescriptor,
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
render_resource::{BufferId, RenderResourceAssignments, RenderResourceSetId, ResourceInfo},
render_resource::{BufferId, RenderResourceBindings, BindGroupId, ResourceInfo},
renderer::RenderContext,
};
use bevy_asset::{Assets, Handle};
@ -65,7 +65,7 @@ impl Node for MainPassNode {
input: &ResourceSlots,
_output: &mut ResourceSlots,
) {
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
let render_resource_bindings = resources.get::<RenderResourceBindings>().unwrap();
let pipelines = resources.get::<Assets<PipelineDescriptor>>().unwrap();
for (i, color_attachment) in self.descriptor.color_attachments.iter_mut().enumerate() {
@ -86,7 +86,7 @@ impl Node for MainPassNode {
render_context.begin_pass(
&self.descriptor,
&render_resource_assignments,
&render_resource_bindings,
&mut |render_pass| {
let mut draw_state = DrawState::default();
for draw in <Read<Draw>>::query().iter(&world) {
@ -132,18 +132,18 @@ impl Node for MainPassNode {
RenderCommand::SetBindGroup {
index,
bind_group_descriptor,
render_resource_set,
bind_group,
dynamic_uniform_indices,
} => {
render_pass.set_bind_group(
*index,
*bind_group_descriptor,
*render_resource_set,
*bind_group,
dynamic_uniform_indices
.as_ref()
.map(|indices| indices.as_slice()),
);
draw_state.set_bind_group(*index, *render_resource_set);
draw_state.set_bind_group(*index, *bind_group);
}
}
}
@ -157,14 +157,14 @@ impl Node for MainPassNode {
#[derive(Default)]
struct DrawState {
pipeline: Option<Handle<PipelineDescriptor>>,
bind_groups: Vec<Option<RenderResourceSetId>>,
bind_groups: Vec<Option<BindGroupId>>,
vertex_buffers: Vec<Option<BufferId>>,
index_buffer: Option<BufferId>,
}
impl DrawState {
pub fn set_bind_group(&mut self, index: u32, render_resource_set: RenderResourceSetId) {
self.bind_groups[index as usize] = Some(render_resource_set);
pub fn set_bind_group(&mut self, index: u32, bind_group: BindGroupId) {
self.bind_groups[index as usize] = Some(bind_group);
}
pub fn set_vertex_buffer(&mut self, index: u32, buffer: BufferId) {

View file

@ -2,8 +2,8 @@ use crate::{
draw::{Draw, RenderPipelines},
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{
self, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
RenderResourceAssignmentsId, RenderResourceHints,
self, BufferInfo, BufferUsage, RenderResourceBinding, RenderResourceBindings,
RenderResourceBindingsId, RenderResourceHints,
},
renderer::{RenderContext, RenderResourceContext, RenderResources},
texture,
@ -33,7 +33,7 @@ struct BufferArrayStatus {
queued_buffer_writes: Vec<QueuedBufferWrite>,
current_item_count: usize,
current_item_capacity: usize,
indices: HashMap<RenderResourceAssignmentsId, usize>,
indices: HashMap<RenderResourceBindingsId, usize>,
current_index: usize,
// TODO: this is a hack to workaround RenderResources without a fixed length
changed_size: usize,
@ -41,7 +41,7 @@ struct BufferArrayStatus {
}
impl BufferArrayStatus {
pub fn get_or_assign_index(&mut self, id: RenderResourceAssignmentsId) -> usize {
pub fn get_or_assign_index(&mut self, id: RenderResourceBindingsId) -> usize {
if let Some(offset) = self.indices.get(&id) {
*offset
} else {
@ -197,7 +197,7 @@ where
uniforms: &T,
dynamic_uniforms: bool,
render_resources: &dyn RenderResourceContext,
render_resource_assignments: &mut RenderResourceAssignments,
render_resource_bindings: &mut RenderResourceBindings,
staging_buffer: &mut [u8],
) {
for (i, render_resource) in uniforms.iter_render_resources().enumerate() {
@ -210,10 +210,10 @@ where
let (target_buffer, target_offset) = if dynamic_uniforms {
let buffer = uniform_buffer_status.buffer.unwrap();
let index = uniform_buffer_status
.get_or_assign_index(render_resource_assignments.id);
render_resource_assignments.set(
.get_or_assign_index(render_resource_bindings.id);
render_resource_bindings.set(
render_resource_name,
RenderResourceAssignment::Buffer {
RenderResourceBinding::Buffer {
buffer,
dynamic_index: Some(
(index * uniform_buffer_status.aligned_size) as u32,
@ -225,10 +225,10 @@ where
} else {
let mut matching_buffer = None;
let mut buffer_to_remove = None;
if let Some(assignment) =
render_resource_assignments.get(render_resource_name)
if let Some(binding) =
render_resource_bindings.get(render_resource_name)
{
let buffer_id = assignment.get_buffer().unwrap();
let buffer_id = binding.get_buffer().unwrap();
if let Some(BufferInfo {
size: current_size, ..
}) = render_resources.get_buffer_info(buffer_id)
@ -264,9 +264,9 @@ where
..Default::default()
});
render_resource_assignments.set(
render_resource_bindings.set(
render_resource_name,
RenderResourceAssignment::Buffer {
RenderResourceBinding::Buffer {
buffer,
range,
dynamic_index: None,
@ -398,7 +398,7 @@ where
setup_uniform_texture_resources::<T>(
&uniforms,
render_resource_context,
&mut render_pipelines.render_resource_assignments,
&mut render_pipelines.render_resource_bindings,
)
}
@ -413,7 +413,7 @@ where
&uniforms,
dynamic_uniforms,
render_resource_context,
&mut render_pipelines.render_resource_assignments,
&mut render_pipelines.render_resource_bindings,
&mut staging_buffer,
);
}
@ -434,7 +434,7 @@ where
&uniforms,
dynamic_uniforms,
render_resource_context,
&mut render_pipelines.render_resource_assignments,
&mut render_pipelines.render_resource_bindings,
&mut staging_buffer,
);
}
@ -499,8 +499,8 @@ where
let mut command_queue = self.command_queue.clone();
let mut uniform_buffer_arrays = UniformBufferArrays::<T>::default();
// let mut asset_event_reader = EventReader::<AssetEvent<T>>::default();
let mut asset_render_resource_assignments =
HashMap::<Handle<T>, RenderResourceAssignments>::default();
let mut asset_render_resource_bindings =
HashMap::<Handle<T>, RenderResourceBindings>::default();
let dynamic_uniforms = self.dynamic_uniforms;
(move |world: &mut SubWorld,
assets: Res<Assets<T>>,
@ -542,13 +542,13 @@ where
for asset_handle in modified_assets.iter() {
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
let mut render_resource_assignments = asset_render_resource_assignments
let mut render_resource_bindings = asset_render_resource_bindings
.entry(*asset_handle)
.or_insert_with(|| RenderResourceAssignments::default());
.or_insert_with(|| RenderResourceBindings::default());
setup_uniform_texture_resources::<T>(
&asset,
render_resource_context,
&mut render_resource_assignments,
&mut render_resource_bindings,
);
}
@ -556,15 +556,15 @@ where
let mut staging_buffer: [u8; 0] = [];
for asset_handle in modified_assets.iter() {
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
let mut render_resource_assignments = asset_render_resource_assignments
let mut render_resource_bindings = asset_render_resource_bindings
.entry(*asset_handle)
.or_insert_with(|| RenderResourceAssignments::default());
.or_insert_with(|| RenderResourceBindings::default());
// TODO: only setup buffer if we haven't seen this handle before
uniform_buffer_arrays.setup_uniform_buffer_resources(
&asset,
dynamic_uniforms,
render_resource_context,
&mut render_resource_assignments,
&mut render_resource_bindings,
&mut staging_buffer,
);
}
@ -578,15 +578,15 @@ where
&mut |mut staging_buffer, _render_resources| {
for asset_handle in modified_assets.iter() {
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
let mut render_resource_assignments = asset_render_resource_assignments
let mut render_resource_bindings = asset_render_resource_bindings
.entry(*asset_handle)
.or_insert_with(|| RenderResourceAssignments::default());
.or_insert_with(|| RenderResourceBindings::default());
// TODO: only setup buffer if we haven't seen this handle before
uniform_buffer_arrays.setup_uniform_buffer_resources(
&asset,
dynamic_uniforms,
render_resource_context,
&mut render_resource_assignments,
&mut render_resource_bindings,
&mut staging_buffer,
);
}
@ -599,12 +599,12 @@ where
}
for (asset_handle, _draw, mut render_pipelines) in query.iter_mut(world) {
if let Some(asset_assignments) =
asset_render_resource_assignments.get(&asset_handle)
if let Some(asset_bindings) =
asset_render_resource_bindings.get(&asset_handle)
{
render_pipelines
.render_resource_assignments
.extend(asset_assignments);
.render_resource_bindings
.extend(asset_bindings);
}
}
})
@ -615,7 +615,7 @@ where
fn setup_uniform_texture_resources<T>(
uniforms: &T,
render_resource_context: &dyn RenderResourceContext,
render_resource_assignments: &mut RenderResourceAssignments,
render_resource_bindings: &mut RenderResourceBindings,
) where
T: render_resource::RenderResources,
{
@ -631,13 +631,13 @@ fn setup_uniform_texture_resources<T>(
.get_asset_resource(texture_handle, texture::SAMPLER_ASSET_INDEX)
.unwrap();
render_resource_assignments.set(
render_resource_bindings.set(
render_resource_name,
RenderResourceAssignment::Texture(texture_resource.get_texture().unwrap()),
RenderResourceBinding::Texture(texture_resource.get_texture().unwrap()),
);
render_resource_assignments.set(
render_resource_bindings.set(
&sampler_name,
RenderResourceAssignment::Sampler(sampler_resource.get_sampler().unwrap()),
RenderResourceBinding::Sampler(sampler_resource.get_sampler().unwrap()),
);
continue;
}

View file

@ -1,4 +1,4 @@
use super::{BufferId, RenderResourceAssignment, SamplerId, TextureId};
use super::{BufferId, RenderResourceBinding, SamplerId, TextureId};
use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
@ -7,63 +7,62 @@ use std::{
};
#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
pub struct RenderResourceSetId(pub u64);
pub struct BindGroupId(pub u64);
#[derive(Eq, PartialEq, Debug)]
pub struct IndexedRenderResourceAssignment {
pub struct IndexedBinding {
pub index: u32,
pub assignment: RenderResourceAssignment,
pub binding: RenderResourceBinding,
}
// TODO: consider renaming this to BindGroup for parity with renderer terminology
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct RenderResourceSet {
pub id: RenderResourceSetId,
pub indexed_assignments: Arc<Vec<IndexedRenderResourceAssignment>>,
pub struct BindGroup {
pub id: BindGroupId,
pub indexed_bindings: Arc<Vec<IndexedBinding>>,
pub dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
}
impl RenderResourceSet {
pub fn build() -> RenderResourceSetBuilder {
RenderResourceSetBuilder::default()
impl BindGroup {
pub fn build() -> BindGroupBuilder {
BindGroupBuilder::default()
}
}
#[derive(Default)]
pub struct RenderResourceSetBuilder {
pub indexed_assignments: Vec<IndexedRenderResourceAssignment>,
pub struct BindGroupBuilder {
pub indexed_bindings: Vec<IndexedBinding>,
pub dynamic_uniform_indices: Vec<u32>,
pub hasher: DefaultHasher,
}
impl RenderResourceSetBuilder {
pub fn add_assignment(mut self, index: u32, assignment: RenderResourceAssignment) -> Self {
if let RenderResourceAssignment::Buffer {
impl BindGroupBuilder {
pub fn add_binding(mut self, index: u32, binding: RenderResourceBinding) -> Self {
if let RenderResourceBinding::Buffer {
dynamic_index: Some(dynamic_index),
..
} = assignment
} = binding
{
self.dynamic_uniform_indices.push(dynamic_index);
}
assignment.hash(&mut self.hasher);
self.indexed_assignments
.push(IndexedRenderResourceAssignment { index, assignment });
binding.hash(&mut self.hasher);
self.indexed_bindings
.push(IndexedBinding { index, binding });
self
}
pub fn add_texture(self, index: u32, texture: TextureId) -> Self {
self.add_assignment(index, RenderResourceAssignment::Texture(texture))
self.add_binding(index, RenderResourceBinding::Texture(texture))
}
pub fn add_sampler(self, index: u32, sampler: SamplerId) -> Self {
self.add_assignment(index, RenderResourceAssignment::Sampler(sampler))
self.add_binding(index, RenderResourceBinding::Sampler(sampler))
}
pub fn add_buffer(self, index: u32, buffer: BufferId, range: Range<u64>) -> Self {
self.add_assignment(
self.add_binding(
index,
RenderResourceAssignment::Buffer {
RenderResourceBinding::Buffer {
buffer,
range,
dynamic_index: None,
@ -78,9 +77,9 @@ impl RenderResourceSetBuilder {
range: Range<u64>,
dynamic_index: u32,
) -> Self {
self.add_assignment(
self.add_binding(
index,
RenderResourceAssignment::Buffer {
RenderResourceBinding::Buffer {
buffer,
range,
dynamic_index: Some(dynamic_index),
@ -88,12 +87,12 @@ impl RenderResourceSetBuilder {
)
}
pub fn finish(mut self) -> RenderResourceSet {
pub fn finish(mut self) -> BindGroup {
// this sort ensures that RenderResourceSets are insertion-order independent
self.indexed_assignments.sort_by_key(|i| i.index);
RenderResourceSet {
id: RenderResourceSetId(self.hasher.finish()),
indexed_assignments: Arc::new(self.indexed_assignments),
self.indexed_bindings.sort_by_key(|i| i.index);
BindGroup {
id: BindGroupId(self.hasher.finish()),
indexed_bindings: Arc::new(self.indexed_bindings),
dynamic_uniform_indices: if self.dynamic_uniform_indices.is_empty() {
None
} else {

View file

@ -2,8 +2,8 @@ mod buffer;
mod texture;
mod shared_buffer;
mod render_resource;
mod render_resource_set;
mod render_resource_assignments;
mod bind_group;
mod render_resource_bindings;
mod resource_info;
mod systems;
@ -11,7 +11,7 @@ pub use buffer::*;
pub use texture::*;
pub use shared_buffer::*;
pub use render_resource::*;
pub use render_resource_set::*;
pub use render_resource_assignments::*;
pub use bind_group::*;
pub use render_resource_bindings::*;
pub use resource_info::*;
pub use systems::*;

View file

@ -1,297 +0,0 @@
use super::{BufferId, RenderResourceId, RenderResourceSet, RenderResourceSetId, SamplerId, TextureId};
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization};
use std::{
collections::{HashMap, HashSet},
hash::Hash,
ops::Range,
};
use uuid::Uuid;
#[derive(Clone, Eq, PartialEq, Debug)]
pub enum RenderResourceAssignment {
Buffer {
buffer: BufferId,
range: Range<u64>,
dynamic_index: Option<u32>,
},
Texture(TextureId),
Sampler(SamplerId),
}
impl RenderResourceAssignment {
pub fn get_texture(&self) -> Option<TextureId> {
if let RenderResourceAssignment::Texture(texture) = self{
Some(*texture)
} else {
None
}
}
pub fn get_buffer(&self) -> Option<BufferId> {
if let RenderResourceAssignment::Buffer{ buffer, ..} = self{
Some(*buffer)
} else {
None
}
}
pub fn get_sampler(&self) -> Option<SamplerId> {
if let RenderResourceAssignment::Sampler(sampler) = self{
Some(*sampler)
} else {
None
}
}
}
impl Hash for RenderResourceAssignment {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
RenderResourceAssignment::Buffer {
buffer,
range,
dynamic_index: _, // dynamic_index is not a part of the binding
} => {
RenderResourceId::from(*buffer).hash(state);
range.hash(state);
}
RenderResourceAssignment::Texture(texture) => {
RenderResourceId::from(*texture).hash(state);
}
RenderResourceAssignment::Sampler(sampler) => {
RenderResourceId::from(*sampler).hash(state);
}
}
}
}
#[derive(Eq, PartialEq, Debug)]
pub enum RenderResourceSetStatus {
Changed(RenderResourceSetId),
Unchanged(RenderResourceSetId),
NoMatch,
}
// 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 {
// TODO: remove this. it shouldn't be needed anymore
pub id: RenderResourceAssignmentsId,
render_resources: HashMap<String, RenderResourceAssignment>,
vertex_buffers: HashMap<String, (BufferId, Option<BufferId>)>,
render_resource_sets: HashMap<RenderResourceSetId, RenderResourceSet>,
bind_group_render_resource_sets: HashMap<BindGroupDescriptorId, RenderResourceSetId>,
dirty_render_resource_sets: HashSet<RenderResourceSetId>,
pub pipeline_specialization: PipelineSpecialization,
}
impl RenderResourceAssignments {
pub fn get(&self, name: &str) -> Option<&RenderResourceAssignment> {
self.render_resources.get(name)
}
pub fn set(&mut self, name: &str, assignment: RenderResourceAssignment) {
self.try_set_dirty(name, &assignment);
self.render_resources.insert(name.to_string(), assignment);
}
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 crude. we shouldn't need to invalidate all render resource sets
for id in self.render_resource_sets.keys() {
self.dirty_render_resource_sets.insert(*id);
}
}
}
}
pub fn extend(&mut self, render_resource_assignments: &RenderResourceAssignments) {
for (name, assignment) in render_resource_assignments.render_resources.iter() {
self.set(name, assignment.clone());
}
for (name, (vertex_buffer, index_buffer)) in
render_resource_assignments.vertex_buffers.iter()
{
self.set_vertex_buffer(name, *vertex_buffer, index_buffer.clone());
}
}
pub fn get_vertex_buffer(&self, name: &str) -> Option<(BufferId, Option<BufferId>)> {
self.vertex_buffers.get(name).cloned()
}
pub fn set_vertex_buffer(
&mut self,
name: &str,
vertex_buffer: BufferId,
index_buffer: Option<BufferId>,
) {
self.vertex_buffers
.insert(name.to_string(), (vertex_buffer, index_buffer));
}
fn create_render_resource_set(
&mut self,
bind_group_descriptor: &BindGroupDescriptor,
) -> RenderResourceSetStatus {
let resource_set = self.build_render_resource_set(bind_group_descriptor);
if let Some(resource_set) = resource_set {
let id = resource_set.id;
self.render_resource_sets.insert(id, resource_set);
self.bind_group_render_resource_sets
.insert(bind_group_descriptor.id, id);
RenderResourceSetStatus::Changed(id)
} else {
RenderResourceSetStatus::NoMatch
}
}
pub fn update_bind_group(
&mut self,
bind_group_descriptor: &BindGroupDescriptor,
) -> RenderResourceSetStatus {
if let Some(id) = self
.bind_group_render_resource_sets
.get(&bind_group_descriptor.id)
{
if self.dirty_render_resource_sets.contains(id) {
self.dirty_render_resource_sets.remove(id);
self.create_render_resource_set(bind_group_descriptor)
} else {
RenderResourceSetStatus::Unchanged(*id)
}
} else {
self.create_render_resource_set(bind_group_descriptor)
}
}
pub fn get_render_resource_set(&self, id: RenderResourceSetId) -> Option<&RenderResourceSet> {
self.render_resource_sets.get(&id)
}
pub fn get_bind_group_render_resource_set(
&self,
id: BindGroupDescriptorId,
) -> Option<&RenderResourceSet> {
self.bind_group_render_resource_sets
.get(&id)
.and_then(|render_resource_set_id| {
self.get_render_resource_set(*render_resource_set_id)
})
}
fn build_render_resource_set(
&self,
bind_group_descriptor: &BindGroupDescriptor,
) -> Option<RenderResourceSet> {
let mut render_resource_set_builder = RenderResourceSet::build();
for binding_descriptor in bind_group_descriptor.bindings.iter() {
if let Some(assignment) = self.get(&binding_descriptor.name) {
render_resource_set_builder = render_resource_set_builder
.add_assignment(binding_descriptor.index, assignment.clone());
} else {
return None;
}
}
Some(render_resource_set_builder.finish())
}
}
#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
pub struct RenderResourceAssignmentsId(Uuid);
impl Default for RenderResourceAssignmentsId {
fn default() -> Self {
RenderResourceAssignmentsId(Uuid::new_v4())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::pipeline::{BindType, BindingDescriptor, UniformProperty, UniformPropertyType};
#[test]
fn test_render_resource_sets() {
let bind_group_descriptor = BindGroupDescriptor::new(
0,
vec![
BindingDescriptor {
index: 0,
name: "a".to_string(),
bind_type: BindType::Uniform {
dynamic: false,
properties: vec![UniformProperty {
name: "A".to_string(),
property_type: UniformPropertyType::Struct(vec![UniformProperty {
name: "".to_string(),
property_type: UniformPropertyType::Mat4,
}]),
}],
},
},
BindingDescriptor {
index: 1,
name: "b".to_string(),
bind_type: BindType::Uniform {
dynamic: false,
properties: vec![UniformProperty {
name: "B".to_string(),
property_type: UniformPropertyType::Float,
}],
},
},
],
);
let resource1 = RenderResourceAssignment::Texture(TextureId::new());
let resource2 = RenderResourceAssignment::Texture(TextureId::new());
let resource3 = RenderResourceAssignment::Texture(TextureId::new());
let resource4 = RenderResourceAssignment::Texture(TextureId::new());
let mut assignments = RenderResourceAssignments::default();
assignments.set("a", resource1.clone());
assignments.set("b", resource2.clone());
let mut different_assignments = RenderResourceAssignments::default();
different_assignments.set("a", resource3.clone());
different_assignments.set("b", resource4.clone());
let mut equal_assignments = RenderResourceAssignments::default();
equal_assignments.set("a", resource1.clone());
equal_assignments.set("b", resource2.clone());
let status = assignments.update_bind_group(&bind_group_descriptor);
let id = if let RenderResourceSetStatus::Changed(id) = status {
id
} else {
panic!("expected a changed render resource set");
};
let different_set_status = different_assignments.update_bind_group(&bind_group_descriptor);
if let RenderResourceSetStatus::Changed(different_set_id) = different_set_status {
assert_ne!(
id, different_set_id,
"different set shouldn't have the same id"
);
different_set_id
} else {
panic!("expected a changed render resource set");
};
let equal_set_status = equal_assignments.update_bind_group(&bind_group_descriptor);
if let RenderResourceSetStatus::Changed(equal_set_id) = equal_set_status {
assert_eq!(id, equal_set_id, "equal set should have the same id");
} else {
panic!("expected a changed render resource set");
};
let mut unmatched_assignments = RenderResourceAssignments::default();
unmatched_assignments.set("a", resource1.clone());
let unmatched_set_status = unmatched_assignments.update_bind_group(&bind_group_descriptor);
assert_eq!(unmatched_set_status, RenderResourceSetStatus::NoMatch);
}
}

View file

@ -0,0 +1,297 @@
use super::{BufferId, RenderResourceId, BindGroup, BindGroupId, SamplerId, TextureId};
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization};
use std::{
collections::{HashMap, HashSet},
hash::Hash,
ops::Range,
};
use uuid::Uuid;
#[derive(Clone, Eq, PartialEq, Debug)]
pub enum RenderResourceBinding {
Buffer {
buffer: BufferId,
range: Range<u64>,
dynamic_index: Option<u32>,
},
Texture(TextureId),
Sampler(SamplerId),
}
impl RenderResourceBinding {
pub fn get_texture(&self) -> Option<TextureId> {
if let RenderResourceBinding::Texture(texture) = self{
Some(*texture)
} else {
None
}
}
pub fn get_buffer(&self) -> Option<BufferId> {
if let RenderResourceBinding::Buffer{ buffer, ..} = self{
Some(*buffer)
} else {
None
}
}
pub fn get_sampler(&self) -> Option<SamplerId> {
if let RenderResourceBinding::Sampler(sampler) = self{
Some(*sampler)
} else {
None
}
}
}
impl Hash for RenderResourceBinding {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
RenderResourceBinding::Buffer {
buffer,
range,
dynamic_index: _, // dynamic_index is not a part of the binding
} => {
RenderResourceId::from(*buffer).hash(state);
range.hash(state);
}
RenderResourceBinding::Texture(texture) => {
RenderResourceId::from(*texture).hash(state);
}
RenderResourceBinding::Sampler(sampler) => {
RenderResourceId::from(*sampler).hash(state);
}
}
}
}
#[derive(Eq, PartialEq, Debug)]
pub enum BindGroupStatus {
Changed(BindGroupId),
Unchanged(BindGroupId),
NoMatch,
}
// PERF: if the bindings 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 RenderResourceBindings {
// TODO: remove this. it shouldn't be needed anymore
pub id: RenderResourceBindingsId,
bindings: HashMap<String, RenderResourceBinding>,
vertex_buffers: HashMap<String, (BufferId, Option<BufferId>)>,
bind_groups: HashMap<BindGroupId, BindGroup>,
bind_group_descriptors: HashMap<BindGroupDescriptorId, BindGroupId>,
dirty_bind_groups: HashSet<BindGroupId>,
pub pipeline_specialization: PipelineSpecialization,
}
impl RenderResourceBindings {
pub fn get(&self, name: &str) -> Option<&RenderResourceBinding> {
self.bindings.get(name)
}
pub fn set(&mut self, name: &str, binding: RenderResourceBinding) {
self.try_set_dirty(name, &binding);
self.bindings.insert(name.to_string(), binding);
}
fn try_set_dirty(&mut self, name: &str, binding: &RenderResourceBinding) {
if let Some(current_binding) = self.bindings.get(name) {
if current_binding != binding {
// TODO: this is crude. we shouldn't need to invalidate all bind groups
for id in self.bind_groups.keys() {
self.dirty_bind_groups.insert(*id);
}
}
}
}
pub fn extend(&mut self, render_resource_bindings: &RenderResourceBindings) {
for (name, binding) in render_resource_bindings.bindings.iter() {
self.set(name, binding.clone());
}
for (name, (vertex_buffer, index_buffer)) in
render_resource_bindings.vertex_buffers.iter()
{
self.set_vertex_buffer(name, *vertex_buffer, index_buffer.clone());
}
}
pub fn get_vertex_buffer(&self, name: &str) -> Option<(BufferId, Option<BufferId>)> {
self.vertex_buffers.get(name).cloned()
}
pub fn set_vertex_buffer(
&mut self,
name: &str,
vertex_buffer: BufferId,
index_buffer: Option<BufferId>,
) {
self.vertex_buffers
.insert(name.to_string(), (vertex_buffer, index_buffer));
}
fn create_bind_group(
&mut self,
descriptor: &BindGroupDescriptor,
) -> BindGroupStatus {
let bind_group = self.build_bind_group(descriptor);
if let Some(bind_group) = bind_group {
let id = bind_group.id;
self.bind_groups.insert(id, bind_group);
self.bind_group_descriptors
.insert(descriptor.id, id);
BindGroupStatus::Changed(id)
} else {
BindGroupStatus::NoMatch
}
}
pub fn update_bind_group(
&mut self,
bind_group_descriptor: &BindGroupDescriptor,
) -> BindGroupStatus {
if let Some(id) = self
.bind_group_descriptors
.get(&bind_group_descriptor.id)
{
if self.dirty_bind_groups.contains(id) {
self.dirty_bind_groups.remove(id);
self.create_bind_group(bind_group_descriptor)
} else {
BindGroupStatus::Unchanged(*id)
}
} else {
self.create_bind_group(bind_group_descriptor)
}
}
pub fn get_bind_group(&self, id: BindGroupId) -> Option<&BindGroup> {
self.bind_groups.get(&id)
}
pub fn get_descriptor_bind_group(
&self,
id: BindGroupDescriptorId,
) -> Option<&BindGroup> {
self.bind_group_descriptors
.get(&id)
.and_then(|bind_group_id| {
self.get_bind_group(*bind_group_id)
})
}
fn build_bind_group(
&self,
bind_group_descriptor: &BindGroupDescriptor,
) -> Option<BindGroup> {
let mut bind_group_builder = BindGroup::build();
for binding_descriptor in bind_group_descriptor.bindings.iter() {
if let Some(binding) = self.get(&binding_descriptor.name) {
bind_group_builder = bind_group_builder
.add_binding(binding_descriptor.index, binding.clone());
} else {
return None;
}
}
Some(bind_group_builder.finish())
}
}
#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
pub struct RenderResourceBindingsId(Uuid);
impl Default for RenderResourceBindingsId {
fn default() -> Self {
RenderResourceBindingsId(Uuid::new_v4())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::pipeline::{BindType, BindingDescriptor, UniformProperty, UniformPropertyType};
#[test]
fn test_bind_groups() {
let bind_group_descriptor = BindGroupDescriptor::new(
0,
vec![
BindingDescriptor {
index: 0,
name: "a".to_string(),
bind_type: BindType::Uniform {
dynamic: false,
properties: vec![UniformProperty {
name: "A".to_string(),
property_type: UniformPropertyType::Struct(vec![UniformProperty {
name: "".to_string(),
property_type: UniformPropertyType::Mat4,
}]),
}],
},
},
BindingDescriptor {
index: 1,
name: "b".to_string(),
bind_type: BindType::Uniform {
dynamic: false,
properties: vec![UniformProperty {
name: "B".to_string(),
property_type: UniformPropertyType::Float,
}],
},
},
],
);
let resource1 = RenderResourceBinding::Texture(TextureId::new());
let resource2 = RenderResourceBinding::Texture(TextureId::new());
let resource3 = RenderResourceBinding::Texture(TextureId::new());
let resource4 = RenderResourceBinding::Texture(TextureId::new());
let mut bindings = RenderResourceBindings::default();
bindings.set("a", resource1.clone());
bindings.set("b", resource2.clone());
let mut different_bindings = RenderResourceBindings::default();
different_bindings.set("a", resource3.clone());
different_bindings.set("b", resource4.clone());
let mut equal_bindings = RenderResourceBindings::default();
equal_bindings.set("a", resource1.clone());
equal_bindings.set("b", resource2.clone());
let status = bindings.update_bind_group(&bind_group_descriptor);
let id = if let BindGroupStatus::Changed(id) = status {
id
} else {
panic!("expected a changed bind group");
};
let different_bind_group_status = different_bindings.update_bind_group(&bind_group_descriptor);
if let BindGroupStatus::Changed(different_bind_group_id) = different_bind_group_status {
assert_ne!(
id, different_bind_group_id,
"different bind group shouldn't have the same id"
);
different_bind_group_id
} else {
panic!("expected a changed bind group");
};
let equal_bind_group_status = equal_bindings.update_bind_group(&bind_group_descriptor);
if let BindGroupStatus::Changed(equal_bind_group_id) = equal_bind_group_status {
assert_eq!(id, equal_bind_group_id, "equal bind group should have the same id");
} else {
panic!("expected a changed bind group");
};
let mut unmatched_bindings = RenderResourceBindings::default();
unmatched_bindings.set("a", resource1.clone());
let unmatched_bind_group_status = unmatched_bindings.update_bind_group(&bind_group_descriptor);
assert_eq!(unmatched_bind_group_status, BindGroupStatus::NoMatch);
}
}

View file

@ -1,4 +1,4 @@
use super::{BufferId, BufferInfo, RenderResource, RenderResourceAssignment};
use super::{BufferId, BufferInfo, RenderResource, RenderResourceBinding};
use crate::{render_resource::BufferUsage, renderer::RenderResourceContext};
use legion::systems::Res;
use std::sync::{Arc, RwLock};
@ -23,7 +23,7 @@ impl SharedBuffers {
&self,
render_resource: &T,
buffer_usage: BufferUsage,
) -> Option<RenderResourceAssignment> {
) -> Option<RenderResourceBinding> {
if let Some(size) = render_resource.buffer_byte_len() {
// PERF: this buffer will be slow
let buffer = self.render_resource_context.create_buffer_mapped(
@ -36,7 +36,7 @@ impl SharedBuffers {
},
);
self.buffers.write().unwrap().push(buffer);
Some(RenderResourceAssignment::Buffer {
Some(RenderResourceBinding::Buffer {
buffer,
range: 0..size as u64,
dynamic_index: None,

View file

@ -2,47 +2,47 @@ use bevy_asset::Assets;
use crate::{
draw::RenderPipelines,
pipeline::{PipelineCompiler, PipelineDescriptor},
render_resource::{RenderResourceAssignments, RenderResourceSetStatus},
render_resource::{RenderResourceBindings, BindGroupStatus},
renderer::{RenderResourceContext, RenderResources},
};
use legion::prelude::*;
fn update_bind_groups(
pipeline: &PipelineDescriptor,
render_resource_assignments: &mut RenderResourceAssignments,
render_resource_bindings: &mut RenderResourceBindings,
render_resource_context: &dyn RenderResourceContext,
) {
let layout = pipeline.get_layout().unwrap();
for bind_group in layout.bind_groups.iter() {
match render_resource_assignments.update_bind_group(bind_group) {
RenderResourceSetStatus::Changed(id) => {
let render_resource_set = render_resource_assignments
.get_render_resource_set(id)
for bind_group_descriptor in layout.bind_groups.iter() {
match render_resource_bindings.update_bind_group(bind_group_descriptor) {
BindGroupStatus::Changed(id) => {
let bind_group = render_resource_bindings
.get_bind_group(id)
.expect("RenderResourceSet was just changed, so it should exist");
render_resource_context.create_bind_group(bind_group.id, render_resource_set);
render_resource_context.create_bind_group(bind_group_descriptor.id, bind_group);
},
// TODO: Don't re-create bind groups if they havent changed. this will require cleanup of orphan bind groups and
// removal of global context.clear_bind_groups()
// PERF: see above
RenderResourceSetStatus::Unchanged(id) => {
let render_resource_set = render_resource_assignments
.get_render_resource_set(id)
BindGroupStatus::Unchanged(id) => {
let bind_group = render_resource_bindings
.get_bind_group(id)
.expect("RenderResourceSet was just changed, so it should exist");
render_resource_context.create_bind_group(bind_group.id, render_resource_set);
render_resource_context.create_bind_group(bind_group_descriptor.id, bind_group);
},
RenderResourceSetStatus::NoMatch => {
BindGroupStatus::NoMatch => {
// ignore unchanged / unmatched render resource sets
}
}
}
}
pub fn render_resource_sets_system(
pub fn bind_groups_system(
world: &mut SubWorld,
pipelines: Res<Assets<PipelineDescriptor>>,
pipeline_compiler: Res<PipelineCompiler>,
render_resources: Res<RenderResources>,
mut render_resource_assignments: ResMut<RenderResourceAssignments>,
mut render_resource_bindings: ResMut<RenderResourceBindings>,
query: &mut Query<Write<RenderPipelines>>,
) {
let render_resource_context = &*render_resources.context;
@ -50,7 +50,7 @@ pub fn render_resource_sets_system(
let pipeline = pipelines.get(compiled_pipeline_handle).unwrap();
update_bind_groups(
pipeline,
&mut render_resource_assignments,
&mut render_resource_bindings,
render_resource_context,
)
}
@ -60,7 +60,7 @@ pub fn render_resource_sets_system(
let pipeline = pipelines.get(pipeline).unwrap();
update_bind_groups(
pipeline,
&mut render_pipelines.render_resource_assignments,
&mut render_pipelines.render_resource_bindings,
render_resource_context,
)
}

View file

@ -1,7 +1,7 @@
use super::RenderResourceContext;
use crate::{
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSet, SamplerId, TextureId},
render_resource::{BufferId, BufferInfo, RenderResourceId, BindGroup, SamplerId, TextureId},
shader::Shader,
texture::{SamplerDescriptor, TextureDescriptor},
};
@ -102,7 +102,7 @@ impl RenderResourceContext for HeadlessRenderResourceContext {
fn create_bind_group(
&self,
_bind_group_descriptor_id: BindGroupDescriptorId,
_render_resource_set: &RenderResourceSet,
_bind_group: &BindGroup,
) {
}
fn create_shader_module_from_source(&self, _shader_handle: Handle<Shader>, _shader: &Shader) {}

View file

@ -1,7 +1,7 @@
use super::RenderResourceContext;
use crate::{
pass::{PassDescriptor, RenderPass},
render_resource::{BufferId, RenderResourceAssignments, TextureId},
render_resource::{BufferId, RenderResourceBindings, TextureId},
texture::Extent3d,
};
@ -29,7 +29,7 @@ pub trait RenderContext {
fn begin_pass(
&mut self,
pass_descriptor: &PassDescriptor,
render_resource_assignments: &RenderResourceAssignments,
render_resource_bindings: &RenderResourceBindings,
run_pass: &mut dyn Fn(&mut dyn RenderPass),
);
}

View file

@ -1,6 +1,6 @@
use crate::{
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSet, SamplerId, TextureId},
render_resource::{BufferId, BufferInfo, RenderResourceId, BindGroup, SamplerId, TextureId},
shader::Shader,
texture::{SamplerDescriptor, TextureDescriptor},
};
@ -57,7 +57,7 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
fn create_bind_group(
&self,
bind_group_descriptor_id: BindGroupDescriptorId,
render_resource_set: &RenderResourceSet,
bind_group: &BindGroup,
);
fn clear_bind_groups(&self);
}

View file

@ -61,7 +61,7 @@ where
{
for shader_def in shader_defs.iter_shader_defs() {
render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
.shader_specialization
.shader_defs
@ -79,7 +79,7 @@ pub fn asset_shader_def_system<T>(
let shader_defs = assets.get(&asset_handle).unwrap();
for shader_def in shader_defs.iter_shader_defs() {
render_pipelines
.render_resource_assignments
.render_resource_bindings
.pipeline_specialization
.shader_specialization
.shader_defs

View file

@ -61,7 +61,7 @@ impl<'a> Drawable for DrawableText<'a> {
// draw.set_global_bind_groups()?;
// // TODO: ideally the TexureAtlas bind group is automatically generated by AssetRenderResourcesNode and is retrievable
// // here using render_resource_context.get_asset_render_resource_set(texture_atlas)
// // here using render_resource_context.get_asset_bind_group(texture_atlas)
// let mut atlas_set = RenderResourceSet::build()
// .add_assignment(0, draw.get_uniform_buffer(&10)?)
// .finish();

View file

@ -2,7 +2,7 @@ use bevy_asset::{Assets, Handle};
use bevy_render::{
draw::Draw,
pipeline::PipelineDescriptor,
render_resource::{RenderResourceAssignments, SharedBuffers},
render_resource::{RenderResourceBindings, SharedBuffers},
renderer::RenderResources,
texture::Texture,
Color,
@ -79,7 +79,7 @@ impl Label {
pub fn draw_label_system(
_pipelines: Res<Assets<PipelineDescriptor>>,
_render_resource_assignments: Res<RenderResourceAssignments>,
_render_resource_bindings: Res<RenderResourceBindings>,
_render_resources: Res<RenderResources>,
_shared_buffers: Res<SharedBuffers>,
_fonts: Res<Assets<Font>>,
@ -93,7 +93,7 @@ impl Label {
// let mut draw_context = draw.get_context(
// &pipelines,
// context,
// &render_resource_assignments,
// &render_resource_bindings,
// &shared_buffers,
// );

View file

@ -6,7 +6,7 @@ use bevy_render::{
PassDescriptor, RenderPass, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor, TextureAttachment,
},
render_resource::{BufferId, RenderResourceAssignment, RenderResourceAssignments, TextureId},
render_resource::{BufferId, RenderResourceBinding, RenderResourceBindings, TextureId},
renderer::{RenderContext, RenderResourceContext},
texture::Extent3d,
};
@ -121,7 +121,7 @@ impl RenderContext for WgpuRenderContext {
fn begin_pass(
&mut self,
pass_descriptor: &PassDescriptor,
render_resource_assignments: &RenderResourceAssignments,
render_resource_bindings: &RenderResourceBindings,
run_pass: &mut dyn Fn(&mut dyn RenderPass),
) {
if !self.command_encoder.is_some() {
@ -133,7 +133,7 @@ impl RenderContext for WgpuRenderContext {
{
let render_pass = create_render_pass(
pass_descriptor,
render_resource_assignments,
render_resource_bindings,
&refs,
&mut encoder,
);
@ -153,7 +153,7 @@ impl RenderContext for WgpuRenderContext {
pub fn create_render_pass<'a, 'b>(
pass_descriptor: &PassDescriptor,
global_render_resource_assignments: &'b RenderResourceAssignments,
global_render_resource_bindings: &'b RenderResourceBindings,
refs: &WgpuResourceRefs<'a>,
encoder: &'a mut wgpu::CommandEncoder,
) -> wgpu::RenderPass<'a> {
@ -162,12 +162,12 @@ pub fn create_render_pass<'a, 'b>(
.color_attachments
.iter()
.map(|c| {
create_wgpu_color_attachment_descriptor(global_render_resource_assignments, refs, c)
create_wgpu_color_attachment_descriptor(global_render_resource_bindings, refs, c)
})
.collect::<Vec<wgpu::RenderPassColorAttachmentDescriptor>>(),
depth_stencil_attachment: pass_descriptor.depth_stencil_attachment.as_ref().map(|d| {
create_wgpu_depth_stencil_attachment_descriptor(
global_render_resource_assignments,
global_render_resource_bindings,
refs,
d,
)
@ -176,13 +176,13 @@ pub fn create_render_pass<'a, 'b>(
}
fn get_texture_view<'a>(
global_render_resource_assignments: &RenderResourceAssignments,
global_render_resource_bindings: &RenderResourceBindings,
refs: &WgpuResourceRefs<'a>,
attachment: &TextureAttachment,
) -> &'a wgpu::TextureView {
match attachment {
TextureAttachment::Name(name) => match global_render_resource_assignments.get(&name) {
Some(RenderResourceAssignment::Texture(resource)) => refs.textures.get(&resource).unwrap(),
TextureAttachment::Name(name) => match global_render_resource_bindings.get(&name) {
Some(RenderResourceBinding::Texture(resource)) => refs.textures.get(&resource).unwrap(),
_ => {
panic!("Color attachment {} does not exist", name);
}
@ -193,12 +193,12 @@ fn get_texture_view<'a>(
}
fn create_wgpu_color_attachment_descriptor<'a>(
global_render_resource_assignments: &RenderResourceAssignments,
global_render_resource_bindings: &RenderResourceBindings,
refs: &WgpuResourceRefs<'a>,
color_attachment_descriptor: &RenderPassColorAttachmentDescriptor,
) -> wgpu::RenderPassColorAttachmentDescriptor<'a> {
let attachment = get_texture_view(
global_render_resource_assignments,
global_render_resource_bindings,
refs,
&color_attachment_descriptor.attachment,
);
@ -206,7 +206,7 @@ fn create_wgpu_color_attachment_descriptor<'a>(
let resolve_target = color_attachment_descriptor
.resolve_target
.as_ref()
.map(|target| get_texture_view(global_render_resource_assignments, refs, &target));
.map(|target| get_texture_view(global_render_resource_bindings, refs, &target));
wgpu::RenderPassColorAttachmentDescriptor {
store_op: color_attachment_descriptor.store_op.wgpu_into(),
@ -218,12 +218,12 @@ fn create_wgpu_color_attachment_descriptor<'a>(
}
fn create_wgpu_depth_stencil_attachment_descriptor<'a>(
global_render_resource_assignments: &RenderResourceAssignments,
global_render_resource_bindings: &RenderResourceBindings,
refs: &WgpuResourceRefs<'a>,
depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor,
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> {
let attachment = get_texture_view(
global_render_resource_assignments,
global_render_resource_bindings,
refs,
&depth_stencil_attachment_descriptor.attachment,
);

View file

@ -7,7 +7,7 @@ use bevy_asset::{Assets, Handle, HandleUntyped};
use bevy_render::{
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
render_resource::{
BufferId, BufferInfo, RenderResourceId, RenderResourceAssignment, RenderResourceSet, SamplerId,
BufferId, BufferInfo, RenderResourceId, RenderResourceBinding, BindGroup, SamplerId,
TextureId,
},
renderer::RenderResourceContext,
@ -432,15 +432,15 @@ impl RenderResourceContext for WgpuRenderResourceContext {
fn create_bind_group(
&self,
bind_group_descriptor_id: BindGroupDescriptorId,
render_resource_set: &RenderResourceSet,
bind_group: &BindGroup,
) {
if !self
.resources
.has_bind_group(bind_group_descriptor_id, render_resource_set.id)
.has_bind_group(bind_group_descriptor_id, bind_group.id)
{
log::trace!(
"start creating bind group for RenderResourceSet {:?}",
render_resource_set.id
bind_group.id
);
let texture_views = self.resources.texture_views.read().unwrap();
let samplers = self.resources.samplers.read().unwrap();
@ -448,28 +448,28 @@ impl RenderResourceContext for WgpuRenderResourceContext {
let bind_group_layouts = self.resources.bind_group_layouts.read().unwrap();
let mut bind_groups = self.resources.bind_groups.write().unwrap();
let bindings = render_resource_set
.indexed_assignments
let bindings = bind_group
.indexed_bindings
.iter()
.map(|indexed_assignment| {
let wgpu_resource = match &indexed_assignment.assignment {
RenderResourceAssignment::Texture(resource) => {
.map(|indexed_binding| {
let wgpu_resource = match &indexed_binding.binding {
RenderResourceBinding::Texture(resource) => {
let texture_view = texture_views
.get(&resource)
.expect(&format!("{:?}", resource));
wgpu::BindingResource::TextureView(texture_view)
}
RenderResourceAssignment::Sampler(resource) => {
RenderResourceBinding::Sampler(resource) => {
let sampler = samplers.get(&resource).unwrap();
wgpu::BindingResource::Sampler(sampler)
}
RenderResourceAssignment::Buffer { buffer, range, .. } => {
RenderResourceBinding::Buffer { buffer, range, .. } => {
let wgpu_buffer = buffers.get(&buffer).unwrap();
wgpu::BindingResource::Buffer(wgpu_buffer.slice(range.clone()))
}
};
wgpu::Binding {
binding: indexed_assignment.index,
binding: indexed_binding.index,
resource: wgpu_resource,
}
})
@ -488,10 +488,10 @@ impl RenderResourceContext for WgpuRenderResourceContext {
.or_insert_with(|| WgpuBindGroupInfo::default());
bind_group_info
.bind_groups
.insert(render_resource_set.id, wgpu_bind_group);
.insert(bind_group.id, wgpu_bind_group);
log::trace!(
"created bind group for RenderResourceSet {:?}",
render_resource_set.id
bind_group.id
);
}
}

View file

@ -3,7 +3,7 @@ use bevy_asset::Handle;
use bevy_render::{
pass::RenderPass,
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
render_resource::{BufferId, RenderResourceSetId},
render_resource::{BufferId, BindGroupId},
renderer::RenderContext,
};
use std::ops::Range;
@ -53,7 +53,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
&mut self,
index: u32,
bind_group_descriptor: BindGroupDescriptorId,
render_resource_set: RenderResourceSetId,
bind_group: BindGroupId,
dynamic_uniform_indices: Option<&[u32]>,
) {
if let Some(bind_group_info) = self
@ -61,7 +61,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
.bind_groups
.get(&bind_group_descriptor)
{
if let Some(wgpu_bind_group) = bind_group_info.bind_groups.get(&render_resource_set) {
if let Some(wgpu_bind_group) = bind_group_info.bind_groups.get(&bind_group) {
const EMPTY: &'static [u32] = &[];
let dynamic_uniform_indices =
if let Some(dynamic_uniform_indices) = dynamic_uniform_indices {
@ -74,7 +74,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
"set bind group {:?} {:?}: {:?}",
bind_group_descriptor,
dynamic_uniform_indices,
render_resource_set
bind_group
);
self.render_pass
.set_bind_group(index, wgpu_bind_group, dynamic_uniform_indices);

View file

@ -1,7 +1,7 @@
use bevy_asset::{Handle, HandleUntyped};
use bevy_render::{
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSetId, SamplerId, TextureId},
render_resource::{BufferId, BufferInfo, RenderResourceId, BindGroupId, SamplerId, TextureId},
shader::Shader,
texture::TextureDescriptor,
};
@ -13,7 +13,7 @@ use std::{
#[derive(Default)]
pub struct WgpuBindGroupInfo {
pub bind_groups: HashMap<RenderResourceSetId, wgpu::BindGroup>,
pub bind_groups: HashMap<BindGroupId, wgpu::BindGroup>,
}
/// Grabs a read lock on all wgpu resources. When paired with WgpuResourceRefs, this allows
@ -100,7 +100,7 @@ impl WgpuResources {
pub fn has_bind_group(
&self,
bind_group_descriptor_id: BindGroupDescriptorId,
render_resource_set_id: RenderResourceSetId,
bind_group_id: BindGroupId,
) -> bool {
if let Some(bind_group_info) = self
.bind_groups
@ -110,7 +110,7 @@ impl WgpuResources {
{
bind_group_info
.bind_groups
.get(&render_resource_set_id)
.get(&bind_group_id)
.is_some()
} else {
false