render: rename "Assignment" to "Binding" and "AssignmentSet" to "BindGroup"
This commit is contained in:
parent
0f608fc90f
commit
0fec350411
@ -1,7 +1,7 @@
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
|
BufferInfo, BufferUsage, RenderResourceBinding, RenderResourceBindings,
|
||||||
},
|
},
|
||||||
renderer::{RenderContext, RenderResources},
|
renderer::{RenderContext, RenderResources},
|
||||||
};
|
};
|
||||||
@ -62,7 +62,7 @@ impl SystemNode for LightsNode {
|
|||||||
(move |world: &mut SubWorld,
|
(move |world: &mut SubWorld,
|
||||||
render_resources: Res<RenderResources>,
|
render_resources: Res<RenderResources>,
|
||||||
// TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same
|
// 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>)>| {
|
query: &mut Query<(Read<Light>, Read<Transform>, Read<Translation>)>| {
|
||||||
if !lights_are_dirty {
|
if !lights_are_dirty {
|
||||||
return;
|
return;
|
||||||
@ -80,9 +80,9 @@ impl SystemNode for LightsNode {
|
|||||||
| BufferUsage::COPY_DST,
|
| BufferUsage::COPY_DST,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
render_resource_assignments.set(
|
render_resource_bindings.set(
|
||||||
uniform::LIGHTS,
|
uniform::LIGHTS,
|
||||||
RenderResourceAssignment::Buffer {
|
RenderResourceBinding::Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
range: 0..light_uniform_size as u64,
|
range: 0..light_uniform_size as u64,
|
||||||
dynamic_index: None,
|
dynamic_index: None,
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BufferId, BufferUsage, RenderResource, RenderResourceAssignment, RenderResourceAssignments,
|
BufferId, BufferUsage, RenderResource, RenderResourceBinding, RenderResourceBindings,
|
||||||
RenderResourceSet, RenderResourceSetId, SharedBuffers,
|
BindGroup, BindGroupId, SharedBuffers,
|
||||||
},
|
},
|
||||||
renderer::{RenderResourceContext, RenderResources},
|
renderer::{RenderResourceContext, RenderResources},
|
||||||
};
|
};
|
||||||
@ -32,7 +32,7 @@ pub enum RenderCommand {
|
|||||||
SetBindGroup {
|
SetBindGroup {
|
||||||
index: u32,
|
index: u32,
|
||||||
bind_group_descriptor: BindGroupDescriptorId,
|
bind_group_descriptor: BindGroupDescriptorId,
|
||||||
render_resource_set: RenderResourceSetId,
|
bind_group: BindGroupId,
|
||||||
dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
|
dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
|
||||||
},
|
},
|
||||||
DrawIndexed {
|
DrawIndexed {
|
||||||
@ -63,7 +63,7 @@ pub struct RenderPipelines {
|
|||||||
pub pipelines: Vec<Handle<PipelineDescriptor>>,
|
pub pipelines: Vec<Handle<PipelineDescriptor>>,
|
||||||
// TODO: make these pipeline specific
|
// TODO: make these pipeline specific
|
||||||
#[property(ignore)]
|
#[property(ignore)]
|
||||||
pub render_resource_assignments: RenderResourceAssignments,
|
pub render_resource_bindings: RenderResourceBindings,
|
||||||
#[property(ignore)]
|
#[property(ignore)]
|
||||||
pub compiled_pipelines: Vec<Handle<PipelineDescriptor>>,
|
pub compiled_pipelines: Vec<Handle<PipelineDescriptor>>,
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ pub struct RenderPipelines {
|
|||||||
impl Default for RenderPipelines {
|
impl Default for RenderPipelines {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
render_resource_assignments: Default::default(),
|
render_resource_bindings: Default::default(),
|
||||||
compiled_pipelines: Default::default(),
|
compiled_pipelines: Default::default(),
|
||||||
pipelines: vec![Handle::default()],
|
pipelines: vec![Handle::default()],
|
||||||
}
|
}
|
||||||
@ -83,14 +83,14 @@ impl Draw {
|
|||||||
&'a mut self,
|
&'a mut self,
|
||||||
pipelines: &'a Assets<PipelineDescriptor>,
|
pipelines: &'a Assets<PipelineDescriptor>,
|
||||||
render_resource_context: &'a dyn RenderResourceContext,
|
render_resource_context: &'a dyn RenderResourceContext,
|
||||||
render_resource_assignments: &'a RenderResourceAssignments,
|
render_resource_bindings: &'a RenderResourceBindings,
|
||||||
shared_buffers: &'a SharedBuffers,
|
shared_buffers: &'a SharedBuffers,
|
||||||
) -> DrawContext {
|
) -> DrawContext {
|
||||||
DrawContext {
|
DrawContext {
|
||||||
draw: self,
|
draw: self,
|
||||||
pipelines,
|
pipelines,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
render_resource_assignments,
|
render_resource_bindings: render_resource_bindings,
|
||||||
shared_buffers,
|
shared_buffers,
|
||||||
current_pipeline: None,
|
current_pipeline: None,
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ pub struct DrawContext<'a> {
|
|||||||
pub draw: &'a mut Draw,
|
pub draw: &'a mut Draw,
|
||||||
pub pipelines: &'a Assets<PipelineDescriptor>,
|
pub pipelines: &'a Assets<PipelineDescriptor>,
|
||||||
pub render_resource_context: &'a dyn RenderResourceContext,
|
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 shared_buffers: &'a SharedBuffers,
|
||||||
pub current_pipeline: Option<&'a PipelineDescriptor>,
|
pub current_pipeline: Option<&'a PipelineDescriptor>,
|
||||||
}
|
}
|
||||||
@ -126,14 +126,14 @@ impl<'a> DrawContext<'a> {
|
|||||||
pub fn get_uniform_buffer<T: RenderResource>(
|
pub fn get_uniform_buffer<T: RenderResource>(
|
||||||
&self,
|
&self,
|
||||||
render_resource: &T,
|
render_resource: &T,
|
||||||
) -> Result<RenderResourceAssignment, DrawError> {
|
) -> Result<RenderResourceBinding, DrawError> {
|
||||||
self.get_buffer(render_resource, BufferUsage::UNIFORM)
|
self.get_buffer(render_resource, BufferUsage::UNIFORM)
|
||||||
}
|
}
|
||||||
pub fn get_buffer<T: RenderResource>(
|
pub fn get_buffer<T: RenderResource>(
|
||||||
&self,
|
&self,
|
||||||
render_resource: &T,
|
render_resource: &T,
|
||||||
buffer_usage: BufferUsage,
|
buffer_usage: BufferUsage,
|
||||||
) -> Result<RenderResourceAssignment, DrawError> {
|
) -> Result<RenderResourceBinding, DrawError> {
|
||||||
self.shared_buffers
|
self.shared_buffers
|
||||||
.get_buffer(render_resource, buffer_usage)
|
.get_buffer(render_resource, buffer_usage)
|
||||||
.ok_or_else(|| DrawError::BufferAllocationFailure)
|
.ok_or_else(|| DrawError::BufferAllocationFailure)
|
||||||
@ -169,13 +169,13 @@ impl<'a> DrawContext<'a> {
|
|||||||
pub fn set_bind_group(
|
pub fn set_bind_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
bind_group_descriptor: &BindGroupDescriptor,
|
bind_group_descriptor: &BindGroupDescriptor,
|
||||||
render_resource_set: &RenderResourceSet,
|
bind_group: &BindGroup,
|
||||||
) {
|
) {
|
||||||
self.render_command(RenderCommand::SetBindGroup {
|
self.render_command(RenderCommand::SetBindGroup {
|
||||||
index: bind_group_descriptor.index,
|
index: bind_group_descriptor.index,
|
||||||
bind_group_descriptor: bind_group_descriptor.id,
|
bind_group_descriptor: bind_group_descriptor.id,
|
||||||
render_resource_set: render_resource_set.id,
|
bind_group: bind_group.id,
|
||||||
dynamic_uniform_indices: render_resource_set.dynamic_uniform_indices.clone(),
|
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 pipeline = draw.pipelines.get(pipeline_handle).unwrap();
|
||||||
let layout = pipeline.get_layout().unwrap();
|
let layout = pipeline.get_layout().unwrap();
|
||||||
draw.set_pipeline(*pipeline_handle)?;
|
draw.set_pipeline(*pipeline_handle)?;
|
||||||
for bind_group in layout.bind_groups.iter() {
|
for bind_group_descriptor in layout.bind_groups.iter() {
|
||||||
if let Some(local_render_resource_set) = self
|
if let Some(local_bind_group) = self
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.get_bind_group_render_resource_set(bind_group.id)
|
.get_descriptor_bind_group(bind_group_descriptor.id)
|
||||||
{
|
{
|
||||||
draw.set_bind_group(bind_group, local_render_resource_set);
|
draw.set_bind_group(bind_group_descriptor, local_bind_group);
|
||||||
} else if let Some(global_render_resource_set) = draw
|
} else if let Some(global_bind_group) = draw
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.get_bind_group_render_resource_set(bind_group.id)
|
.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;
|
let mut indices = 0..0;
|
||||||
@ -225,7 +225,7 @@ impl Drawable for RenderPipelines {
|
|||||||
layout.vertex_buffer_descriptors.iter().enumerate()
|
layout.vertex_buffer_descriptors.iter().enumerate()
|
||||||
{
|
{
|
||||||
if let Some((vertex_buffer, index_buffer)) = self
|
if let Some((vertex_buffer, index_buffer)) = self
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.get_vertex_buffer(&vertex_buffer_descriptor.name)
|
.get_vertex_buffer(&vertex_buffer_descriptor.name)
|
||||||
{
|
{
|
||||||
draw.set_vertex_buffer(slot as u32, vertex_buffer, 0);
|
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>(
|
pub fn draw_system<T: Drawable + Component>(
|
||||||
pipelines: Res<Assets<PipelineDescriptor>>,
|
pipelines: Res<Assets<PipelineDescriptor>>,
|
||||||
render_resource_assignments: Res<RenderResourceAssignments>,
|
render_resource_bindings: Res<RenderResourceBindings>,
|
||||||
render_resources: Res<RenderResources>,
|
render_resources: Res<RenderResources>,
|
||||||
shared_buffers: Res<SharedBuffers>,
|
shared_buffers: Res<SharedBuffers>,
|
||||||
mut draw: ComMut<Draw>,
|
mut draw: ComMut<Draw>,
|
||||||
@ -261,7 +261,7 @@ pub fn draw_system<T: Drawable + Component>(
|
|||||||
let mut draw_context = draw.get_context(
|
let mut draw_context = draw.get_context(
|
||||||
&pipelines,
|
&pipelines,
|
||||||
context,
|
context,
|
||||||
&render_resource_assignments,
|
&render_resource_bindings,
|
||||||
&shared_buffers,
|
&shared_buffers,
|
||||||
);
|
);
|
||||||
draw_context.draw(drawable.as_mut()).unwrap();
|
draw_context.draw(drawable.as_mut()).unwrap();
|
||||||
|
|||||||
@ -26,7 +26,7 @@ pub use once_cell;
|
|||||||
use self::{
|
use self::{
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
pipeline::{PipelineCompiler, PipelineDescriptor, VertexBufferDescriptors},
|
pipeline::{PipelineCompiler, PipelineDescriptor, VertexBufferDescriptors},
|
||||||
render_resource::RenderResourceAssignments,
|
render_resource::RenderResourceBindings,
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
};
|
};
|
||||||
@ -40,7 +40,7 @@ use legion::prelude::IntoSystem;
|
|||||||
use mesh::mesh_resource_provider_system;
|
use mesh::mesh_resource_provider_system;
|
||||||
use pipeline::compile_pipelines_system;
|
use pipeline::compile_pipelines_system;
|
||||||
use render_graph::{system::render_graph_schedule_executor_system, RenderGraph};
|
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 std::ops::Range;
|
||||||
use texture::{PngTextureLoader, TextureResourceSystemState};
|
use texture::{PngTextureLoader, TextureResourceSystemState};
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ impl AppPlugin for RenderPlugin {
|
|||||||
.register_property_type::<Range<f32>>()
|
.register_property_type::<Range<f32>>()
|
||||||
.init_resource::<RenderGraph>()
|
.init_resource::<RenderGraph>()
|
||||||
.init_resource::<PipelineCompiler>()
|
.init_resource::<PipelineCompiler>()
|
||||||
.init_resource::<RenderResourceAssignments>()
|
.init_resource::<RenderResourceBindings>()
|
||||||
.init_resource::<VertexBufferDescriptors>()
|
.init_resource::<VertexBufferDescriptors>()
|
||||||
.init_resource::<TextureResourceSystemState>()
|
.init_resource::<TextureResourceSystemState>()
|
||||||
.add_system_to_stage(bevy_app::stage::PRE_UPDATE, clear_draw_system.system())
|
.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(
|
.add_system_to_stage(
|
||||||
stage::RENDER_GRAPH_SYSTEMS,
|
stage::RENDER_GRAPH_SYSTEMS,
|
||||||
render_resource_sets_system.system(),
|
bind_groups_system.system(),
|
||||||
)
|
)
|
||||||
.add_system_to_stage(stage::DRAW, draw_system::<RenderPipelines>.system());
|
.add_system_to_stage(stage::DRAW, draw_system::<RenderPipelines>.system());
|
||||||
|
|
||||||
|
|||||||
@ -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) {
|
for (handle, mut render_pipelines) in query.iter_mut(world) {
|
||||||
if let Some(mesh) = meshes.get(&handle) {
|
if let Some(mesh) = meshes.get(&handle) {
|
||||||
render_pipelines
|
render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
.primitive_topology = mesh.primitive_topology;
|
.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_resources.get_asset_resource(*handle, VERTEX_BUFFER_ASSET_INDEX)
|
||||||
{
|
{
|
||||||
render_pipelines
|
render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.set_vertex_buffer(
|
.set_vertex_buffer(
|
||||||
"Vertex",
|
"Vertex",
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{PipelineDescriptor, BindGroupDescriptorId},
|
pipeline::{PipelineDescriptor, BindGroupDescriptorId},
|
||||||
render_resource::{RenderResourceSetId, BufferId},
|
render_resource::{BindGroupId, BufferId},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
};
|
};
|
||||||
use bevy_asset::Handle;
|
use bevy_asset::Handle;
|
||||||
@ -19,7 +19,7 @@ pub trait RenderPass {
|
|||||||
&mut self,
|
&mut self,
|
||||||
index: u32,
|
index: u32,
|
||||||
bind_group_descriptor: BindGroupDescriptorId,
|
bind_group_descriptor: BindGroupDescriptorId,
|
||||||
render_resource_set: RenderResourceSetId,
|
bind_group: BindGroupId,
|
||||||
dynamic_uniform_indices: Option<&[u32]>,
|
dynamic_uniform_indices: Option<&[u32]>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use super::{
|
|||||||
BindType, PipelineLayout, VertexBufferDescriptors,
|
BindType, PipelineLayout, VertexBufferDescriptors,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
render_resource::{RenderResourceAssignment, RenderResourceAssignments},
|
render_resource::{RenderResourceBinding, RenderResourceBindings},
|
||||||
shader::{Shader, ShaderStages},
|
shader::{Shader, ShaderStages},
|
||||||
texture::TextureFormat,
|
texture::TextureFormat,
|
||||||
};
|
};
|
||||||
@ -122,14 +122,14 @@ impl PipelineDescriptor {
|
|||||||
/// If `vertex_buffer_descriptors` is set, the pipeline's vertex buffers
|
/// 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.
|
/// 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.
|
/// render resource.
|
||||||
pub fn reflect_layout(
|
pub fn reflect_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
shaders: &Assets<Shader>,
|
shaders: &Assets<Shader>,
|
||||||
bevy_conventions: bool,
|
bevy_conventions: bool,
|
||||||
vertex_buffer_descriptors: Option<&VertexBufferDescriptors>,
|
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 vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap();
|
||||||
let fragment_spirv = self
|
let fragment_spirv = self
|
||||||
@ -148,17 +148,17 @@ impl PipelineDescriptor {
|
|||||||
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
|
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(render_resource_assignments) = render_resource_assignments {
|
if let Some(render_resource_bindings) = render_resource_bindings {
|
||||||
// set binding uniforms to dynamic if render resource assignments use dynamic
|
// set binding uniforms to dynamic if render resource bindings use dynamic
|
||||||
// TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes.
|
// 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
|
// 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 all permutations of dynamic/non-dynamic
|
||||||
for bind_group in layout.bind_groups.iter_mut() {
|
for bind_group in layout.bind_groups.iter_mut() {
|
||||||
for binding in bind_group.bindings.iter_mut() {
|
for binding in bind_group.bindings.iter_mut() {
|
||||||
if let Some(RenderResourceAssignment::Buffer {
|
if let Some(RenderResourceBinding::Buffer {
|
||||||
dynamic_index: Some(_),
|
dynamic_index: Some(_),
|
||||||
..
|
..
|
||||||
}) = render_resource_assignments.get(&binding.name)
|
}) = render_resource_bindings.get(&binding.name)
|
||||||
{
|
{
|
||||||
if let BindType::Uniform {
|
if let BindType::Uniform {
|
||||||
ref mut dynamic, ..
|
ref mut dynamic, ..
|
||||||
|
|||||||
@ -86,7 +86,7 @@ impl PipelineCompiler {
|
|||||||
shaders,
|
shaders,
|
||||||
&pipeline_descriptor.shader_stages.vertex,
|
&pipeline_descriptor.shader_stages.vertex,
|
||||||
&render_pipelines
|
&render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
.shader_specialization,
|
.shader_specialization,
|
||||||
);
|
);
|
||||||
@ -99,7 +99,7 @@ impl PipelineCompiler {
|
|||||||
shaders,
|
shaders,
|
||||||
fragment,
|
fragment,
|
||||||
&render_pipelines
|
&render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
.shader_specialization,
|
.shader_specialization,
|
||||||
)
|
)
|
||||||
@ -109,11 +109,11 @@ impl PipelineCompiler {
|
|||||||
shaders,
|
shaders,
|
||||||
true,
|
true,
|
||||||
Some(vertex_buffer_descriptors),
|
Some(vertex_buffer_descriptors),
|
||||||
Some(&render_pipelines.render_resource_assignments),
|
Some(&render_pipelines.render_resource_bindings),
|
||||||
);
|
);
|
||||||
|
|
||||||
compiled_pipeline_descriptor.primitive_topology = render_pipelines
|
compiled_pipeline_descriptor.primitive_topology = render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
.primitive_topology;
|
.primitive_topology;
|
||||||
compiled_pipeline_descriptor
|
compiled_pipeline_descriptor
|
||||||
@ -141,7 +141,7 @@ impl PipelineCompiler {
|
|||||||
.find(|(pipeline_specialization, _compiled_pipeline_handle)| {
|
.find(|(pipeline_specialization, _compiled_pipeline_handle)| {
|
||||||
*pipeline_specialization
|
*pipeline_specialization
|
||||||
== render_pipelines
|
== render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
}) {
|
}) {
|
||||||
*compiled_pipeline_handle
|
*compiled_pipeline_handle
|
||||||
@ -166,7 +166,7 @@ impl PipelineCompiler {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
compiled_pipelines.push((
|
compiled_pipelines.push((
|
||||||
render_pipelines
|
render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
.clone(),
|
.clone(),
|
||||||
compiled_pipeline_handle,
|
compiled_pipeline_handle,
|
||||||
@ -231,7 +231,7 @@ pub fn compile_pipelines_system(
|
|||||||
|
|
||||||
// reset shader_defs so they can be changed next frame
|
// reset shader_defs so they can be changed next frame
|
||||||
render_pipelines
|
render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
.shader_specialization
|
.shader_specialization
|
||||||
.shader_defs
|
.shader_defs
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
|
BufferInfo, BufferUsage, RenderResourceBinding, RenderResourceBindings,
|
||||||
},
|
},
|
||||||
renderer::{RenderContext, RenderResources},
|
renderer::{RenderContext, RenderResources},
|
||||||
Camera,
|
Camera,
|
||||||
@ -51,7 +51,7 @@ impl SystemNode for CameraNode {
|
|||||||
render_resources: Res<RenderResources>,
|
render_resources: Res<RenderResources>,
|
||||||
// PERF: this write on RenderResourceAssignments will prevent this system from running in parallel
|
// PERF: this write on RenderResourceAssignments will prevent this system from running in parallel
|
||||||
// with other systems that do the same
|
// 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>)>| {
|
query: &mut Query<(Read<Camera>, Read<Transform>)>| {
|
||||||
let render_resources = &render_resources.context;
|
let render_resources = &render_resources.context;
|
||||||
if camera_buffer.is_none() {
|
if camera_buffer.is_none() {
|
||||||
@ -61,9 +61,9 @@ impl SystemNode for CameraNode {
|
|||||||
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
render_resource_assignments.set(
|
render_resource_bindings.set(
|
||||||
&uniform_name,
|
&uniform_name,
|
||||||
RenderResourceAssignment::Buffer {
|
RenderResourceBinding::Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
range: 0..size as u64,
|
range: 0..size as u64,
|
||||||
dynamic_index: None,
|
dynamic_index: None,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use crate::{
|
|||||||
pass::{PassDescriptor, TextureAttachment},
|
pass::{PassDescriptor, TextureAttachment},
|
||||||
pipeline::PipelineDescriptor,
|
pipeline::PipelineDescriptor,
|
||||||
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
|
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
|
||||||
render_resource::{BufferId, RenderResourceAssignments, RenderResourceSetId, ResourceInfo},
|
render_resource::{BufferId, RenderResourceBindings, BindGroupId, ResourceInfo},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
};
|
};
|
||||||
use bevy_asset::{Assets, Handle};
|
use bevy_asset::{Assets, Handle};
|
||||||
@ -65,7 +65,7 @@ impl Node for MainPassNode {
|
|||||||
input: &ResourceSlots,
|
input: &ResourceSlots,
|
||||||
_output: &mut 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();
|
let pipelines = resources.get::<Assets<PipelineDescriptor>>().unwrap();
|
||||||
|
|
||||||
for (i, color_attachment) in self.descriptor.color_attachments.iter_mut().enumerate() {
|
for (i, color_attachment) in self.descriptor.color_attachments.iter_mut().enumerate() {
|
||||||
@ -86,7 +86,7 @@ impl Node for MainPassNode {
|
|||||||
|
|
||||||
render_context.begin_pass(
|
render_context.begin_pass(
|
||||||
&self.descriptor,
|
&self.descriptor,
|
||||||
&render_resource_assignments,
|
&render_resource_bindings,
|
||||||
&mut |render_pass| {
|
&mut |render_pass| {
|
||||||
let mut draw_state = DrawState::default();
|
let mut draw_state = DrawState::default();
|
||||||
for draw in <Read<Draw>>::query().iter(&world) {
|
for draw in <Read<Draw>>::query().iter(&world) {
|
||||||
@ -132,18 +132,18 @@ impl Node for MainPassNode {
|
|||||||
RenderCommand::SetBindGroup {
|
RenderCommand::SetBindGroup {
|
||||||
index,
|
index,
|
||||||
bind_group_descriptor,
|
bind_group_descriptor,
|
||||||
render_resource_set,
|
bind_group,
|
||||||
dynamic_uniform_indices,
|
dynamic_uniform_indices,
|
||||||
} => {
|
} => {
|
||||||
render_pass.set_bind_group(
|
render_pass.set_bind_group(
|
||||||
*index,
|
*index,
|
||||||
*bind_group_descriptor,
|
*bind_group_descriptor,
|
||||||
*render_resource_set,
|
*bind_group,
|
||||||
dynamic_uniform_indices
|
dynamic_uniform_indices
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|indices| indices.as_slice()),
|
.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)]
|
#[derive(Default)]
|
||||||
struct DrawState {
|
struct DrawState {
|
||||||
pipeline: Option<Handle<PipelineDescriptor>>,
|
pipeline: Option<Handle<PipelineDescriptor>>,
|
||||||
bind_groups: Vec<Option<RenderResourceSetId>>,
|
bind_groups: Vec<Option<BindGroupId>>,
|
||||||
vertex_buffers: Vec<Option<BufferId>>,
|
vertex_buffers: Vec<Option<BufferId>>,
|
||||||
index_buffer: Option<BufferId>,
|
index_buffer: Option<BufferId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawState {
|
impl DrawState {
|
||||||
pub fn set_bind_group(&mut self, index: u32, render_resource_set: RenderResourceSetId) {
|
pub fn set_bind_group(&mut self, index: u32, bind_group: BindGroupId) {
|
||||||
self.bind_groups[index as usize] = Some(render_resource_set);
|
self.bind_groups[index as usize] = Some(bind_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_vertex_buffer(&mut self, index: u32, buffer: BufferId) {
|
pub fn set_vertex_buffer(&mut self, index: u32, buffer: BufferId) {
|
||||||
|
|||||||
@ -2,8 +2,8 @@ use crate::{
|
|||||||
draw::{Draw, RenderPipelines},
|
draw::{Draw, RenderPipelines},
|
||||||
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
self, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
|
self, BufferInfo, BufferUsage, RenderResourceBinding, RenderResourceBindings,
|
||||||
RenderResourceAssignmentsId, RenderResourceHints,
|
RenderResourceBindingsId, RenderResourceHints,
|
||||||
},
|
},
|
||||||
renderer::{RenderContext, RenderResourceContext, RenderResources},
|
renderer::{RenderContext, RenderResourceContext, RenderResources},
|
||||||
texture,
|
texture,
|
||||||
@ -33,7 +33,7 @@ struct BufferArrayStatus {
|
|||||||
queued_buffer_writes: Vec<QueuedBufferWrite>,
|
queued_buffer_writes: Vec<QueuedBufferWrite>,
|
||||||
current_item_count: usize,
|
current_item_count: usize,
|
||||||
current_item_capacity: usize,
|
current_item_capacity: usize,
|
||||||
indices: HashMap<RenderResourceAssignmentsId, usize>,
|
indices: HashMap<RenderResourceBindingsId, usize>,
|
||||||
current_index: usize,
|
current_index: usize,
|
||||||
// TODO: this is a hack to workaround RenderResources without a fixed length
|
// TODO: this is a hack to workaround RenderResources without a fixed length
|
||||||
changed_size: usize,
|
changed_size: usize,
|
||||||
@ -41,7 +41,7 @@ struct BufferArrayStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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) {
|
if let Some(offset) = self.indices.get(&id) {
|
||||||
*offset
|
*offset
|
||||||
} else {
|
} else {
|
||||||
@ -197,7 +197,7 @@ where
|
|||||||
uniforms: &T,
|
uniforms: &T,
|
||||||
dynamic_uniforms: bool,
|
dynamic_uniforms: bool,
|
||||||
render_resources: &dyn RenderResourceContext,
|
render_resources: &dyn RenderResourceContext,
|
||||||
render_resource_assignments: &mut RenderResourceAssignments,
|
render_resource_bindings: &mut RenderResourceBindings,
|
||||||
staging_buffer: &mut [u8],
|
staging_buffer: &mut [u8],
|
||||||
) {
|
) {
|
||||||
for (i, render_resource) in uniforms.iter_render_resources().enumerate() {
|
for (i, render_resource) in uniforms.iter_render_resources().enumerate() {
|
||||||
@ -210,10 +210,10 @@ where
|
|||||||
let (target_buffer, target_offset) = if dynamic_uniforms {
|
let (target_buffer, target_offset) = if dynamic_uniforms {
|
||||||
let buffer = uniform_buffer_status.buffer.unwrap();
|
let buffer = uniform_buffer_status.buffer.unwrap();
|
||||||
let index = uniform_buffer_status
|
let index = uniform_buffer_status
|
||||||
.get_or_assign_index(render_resource_assignments.id);
|
.get_or_assign_index(render_resource_bindings.id);
|
||||||
render_resource_assignments.set(
|
render_resource_bindings.set(
|
||||||
render_resource_name,
|
render_resource_name,
|
||||||
RenderResourceAssignment::Buffer {
|
RenderResourceBinding::Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
dynamic_index: Some(
|
dynamic_index: Some(
|
||||||
(index * uniform_buffer_status.aligned_size) as u32,
|
(index * uniform_buffer_status.aligned_size) as u32,
|
||||||
@ -225,10 +225,10 @@ where
|
|||||||
} else {
|
} else {
|
||||||
let mut matching_buffer = None;
|
let mut matching_buffer = None;
|
||||||
let mut buffer_to_remove = None;
|
let mut buffer_to_remove = None;
|
||||||
if let Some(assignment) =
|
if let Some(binding) =
|
||||||
render_resource_assignments.get(render_resource_name)
|
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 {
|
if let Some(BufferInfo {
|
||||||
size: current_size, ..
|
size: current_size, ..
|
||||||
}) = render_resources.get_buffer_info(buffer_id)
|
}) = render_resources.get_buffer_info(buffer_id)
|
||||||
@ -264,9 +264,9 @@ where
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
render_resource_assignments.set(
|
render_resource_bindings.set(
|
||||||
render_resource_name,
|
render_resource_name,
|
||||||
RenderResourceAssignment::Buffer {
|
RenderResourceBinding::Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
range,
|
range,
|
||||||
dynamic_index: None,
|
dynamic_index: None,
|
||||||
@ -398,7 +398,7 @@ where
|
|||||||
setup_uniform_texture_resources::<T>(
|
setup_uniform_texture_resources::<T>(
|
||||||
&uniforms,
|
&uniforms,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&mut render_pipelines.render_resource_assignments,
|
&mut render_pipelines.render_resource_bindings,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,7 +413,7 @@ where
|
|||||||
&uniforms,
|
&uniforms,
|
||||||
dynamic_uniforms,
|
dynamic_uniforms,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&mut render_pipelines.render_resource_assignments,
|
&mut render_pipelines.render_resource_bindings,
|
||||||
&mut staging_buffer,
|
&mut staging_buffer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -434,7 +434,7 @@ where
|
|||||||
&uniforms,
|
&uniforms,
|
||||||
dynamic_uniforms,
|
dynamic_uniforms,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&mut render_pipelines.render_resource_assignments,
|
&mut render_pipelines.render_resource_bindings,
|
||||||
&mut staging_buffer,
|
&mut staging_buffer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -499,8 +499,8 @@ where
|
|||||||
let mut command_queue = self.command_queue.clone();
|
let mut command_queue = self.command_queue.clone();
|
||||||
let mut uniform_buffer_arrays = UniformBufferArrays::<T>::default();
|
let mut uniform_buffer_arrays = UniformBufferArrays::<T>::default();
|
||||||
// let mut asset_event_reader = EventReader::<AssetEvent<T>>::default();
|
// let mut asset_event_reader = EventReader::<AssetEvent<T>>::default();
|
||||||
let mut asset_render_resource_assignments =
|
let mut asset_render_resource_bindings =
|
||||||
HashMap::<Handle<T>, RenderResourceAssignments>::default();
|
HashMap::<Handle<T>, RenderResourceBindings>::default();
|
||||||
let dynamic_uniforms = self.dynamic_uniforms;
|
let dynamic_uniforms = self.dynamic_uniforms;
|
||||||
(move |world: &mut SubWorld,
|
(move |world: &mut SubWorld,
|
||||||
assets: Res<Assets<T>>,
|
assets: Res<Assets<T>>,
|
||||||
@ -542,13 +542,13 @@ where
|
|||||||
|
|
||||||
for asset_handle in modified_assets.iter() {
|
for asset_handle in modified_assets.iter() {
|
||||||
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
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)
|
.entry(*asset_handle)
|
||||||
.or_insert_with(|| RenderResourceAssignments::default());
|
.or_insert_with(|| RenderResourceBindings::default());
|
||||||
setup_uniform_texture_resources::<T>(
|
setup_uniform_texture_resources::<T>(
|
||||||
&asset,
|
&asset,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&mut render_resource_assignments,
|
&mut render_resource_bindings,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,15 +556,15 @@ where
|
|||||||
let mut staging_buffer: [u8; 0] = [];
|
let mut staging_buffer: [u8; 0] = [];
|
||||||
for asset_handle in modified_assets.iter() {
|
for asset_handle in modified_assets.iter() {
|
||||||
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
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)
|
.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
|
// TODO: only setup buffer if we haven't seen this handle before
|
||||||
uniform_buffer_arrays.setup_uniform_buffer_resources(
|
uniform_buffer_arrays.setup_uniform_buffer_resources(
|
||||||
&asset,
|
&asset,
|
||||||
dynamic_uniforms,
|
dynamic_uniforms,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&mut render_resource_assignments,
|
&mut render_resource_bindings,
|
||||||
&mut staging_buffer,
|
&mut staging_buffer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -578,15 +578,15 @@ where
|
|||||||
&mut |mut staging_buffer, _render_resources| {
|
&mut |mut staging_buffer, _render_resources| {
|
||||||
for asset_handle in modified_assets.iter() {
|
for asset_handle in modified_assets.iter() {
|
||||||
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
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)
|
.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
|
// TODO: only setup buffer if we haven't seen this handle before
|
||||||
uniform_buffer_arrays.setup_uniform_buffer_resources(
|
uniform_buffer_arrays.setup_uniform_buffer_resources(
|
||||||
&asset,
|
&asset,
|
||||||
dynamic_uniforms,
|
dynamic_uniforms,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&mut render_resource_assignments,
|
&mut render_resource_bindings,
|
||||||
&mut staging_buffer,
|
&mut staging_buffer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -599,12 +599,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (asset_handle, _draw, mut render_pipelines) in query.iter_mut(world) {
|
for (asset_handle, _draw, mut render_pipelines) in query.iter_mut(world) {
|
||||||
if let Some(asset_assignments) =
|
if let Some(asset_bindings) =
|
||||||
asset_render_resource_assignments.get(&asset_handle)
|
asset_render_resource_bindings.get(&asset_handle)
|
||||||
{
|
{
|
||||||
render_pipelines
|
render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.extend(asset_assignments);
|
.extend(asset_bindings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -615,7 +615,7 @@ where
|
|||||||
fn setup_uniform_texture_resources<T>(
|
fn setup_uniform_texture_resources<T>(
|
||||||
uniforms: &T,
|
uniforms: &T,
|
||||||
render_resource_context: &dyn RenderResourceContext,
|
render_resource_context: &dyn RenderResourceContext,
|
||||||
render_resource_assignments: &mut RenderResourceAssignments,
|
render_resource_bindings: &mut RenderResourceBindings,
|
||||||
) where
|
) where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
@ -631,13 +631,13 @@ fn setup_uniform_texture_resources<T>(
|
|||||||
.get_asset_resource(texture_handle, texture::SAMPLER_ASSET_INDEX)
|
.get_asset_resource(texture_handle, texture::SAMPLER_ASSET_INDEX)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
render_resource_assignments.set(
|
render_resource_bindings.set(
|
||||||
render_resource_name,
|
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,
|
&sampler_name,
|
||||||
RenderResourceAssignment::Sampler(sampler_resource.get_sampler().unwrap()),
|
RenderResourceBinding::Sampler(sampler_resource.get_sampler().unwrap()),
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use super::{BufferId, RenderResourceAssignment, SamplerId, TextureId};
|
use super::{BufferId, RenderResourceBinding, SamplerId, TextureId};
|
||||||
use std::{
|
use std::{
|
||||||
collections::hash_map::DefaultHasher,
|
collections::hash_map::DefaultHasher,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
@ -7,63 +7,62 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
|
#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
|
||||||
pub struct RenderResourceSetId(pub u64);
|
pub struct BindGroupId(pub u64);
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
pub struct IndexedRenderResourceAssignment {
|
pub struct IndexedBinding {
|
||||||
pub index: u32,
|
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)]
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
pub struct RenderResourceSet {
|
pub struct BindGroup {
|
||||||
pub id: RenderResourceSetId,
|
pub id: BindGroupId,
|
||||||
pub indexed_assignments: Arc<Vec<IndexedRenderResourceAssignment>>,
|
pub indexed_bindings: Arc<Vec<IndexedBinding>>,
|
||||||
pub dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
|
pub dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderResourceSet {
|
impl BindGroup {
|
||||||
pub fn build() -> RenderResourceSetBuilder {
|
pub fn build() -> BindGroupBuilder {
|
||||||
RenderResourceSetBuilder::default()
|
BindGroupBuilder::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RenderResourceSetBuilder {
|
pub struct BindGroupBuilder {
|
||||||
pub indexed_assignments: Vec<IndexedRenderResourceAssignment>,
|
pub indexed_bindings: Vec<IndexedBinding>,
|
||||||
pub dynamic_uniform_indices: Vec<u32>,
|
pub dynamic_uniform_indices: Vec<u32>,
|
||||||
pub hasher: DefaultHasher,
|
pub hasher: DefaultHasher,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderResourceSetBuilder {
|
impl BindGroupBuilder {
|
||||||
pub fn add_assignment(mut self, index: u32, assignment: RenderResourceAssignment) -> Self {
|
pub fn add_binding(mut self, index: u32, binding: RenderResourceBinding) -> Self {
|
||||||
if let RenderResourceAssignment::Buffer {
|
if let RenderResourceBinding::Buffer {
|
||||||
dynamic_index: Some(dynamic_index),
|
dynamic_index: Some(dynamic_index),
|
||||||
..
|
..
|
||||||
} = assignment
|
} = binding
|
||||||
{
|
{
|
||||||
self.dynamic_uniform_indices.push(dynamic_index);
|
self.dynamic_uniform_indices.push(dynamic_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
assignment.hash(&mut self.hasher);
|
binding.hash(&mut self.hasher);
|
||||||
self.indexed_assignments
|
self.indexed_bindings
|
||||||
.push(IndexedRenderResourceAssignment { index, assignment });
|
.push(IndexedBinding { index, binding });
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_texture(self, index: u32, texture: TextureId) -> 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 {
|
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 {
|
pub fn add_buffer(self, index: u32, buffer: BufferId, range: Range<u64>) -> Self {
|
||||||
self.add_assignment(
|
self.add_binding(
|
||||||
index,
|
index,
|
||||||
RenderResourceAssignment::Buffer {
|
RenderResourceBinding::Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
range,
|
range,
|
||||||
dynamic_index: None,
|
dynamic_index: None,
|
||||||
@ -78,9 +77,9 @@ impl RenderResourceSetBuilder {
|
|||||||
range: Range<u64>,
|
range: Range<u64>,
|
||||||
dynamic_index: u32,
|
dynamic_index: u32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.add_assignment(
|
self.add_binding(
|
||||||
index,
|
index,
|
||||||
RenderResourceAssignment::Buffer {
|
RenderResourceBinding::Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
range,
|
range,
|
||||||
dynamic_index: Some(dynamic_index),
|
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
|
// this sort ensures that RenderResourceSets are insertion-order independent
|
||||||
self.indexed_assignments.sort_by_key(|i| i.index);
|
self.indexed_bindings.sort_by_key(|i| i.index);
|
||||||
RenderResourceSet {
|
BindGroup {
|
||||||
id: RenderResourceSetId(self.hasher.finish()),
|
id: BindGroupId(self.hasher.finish()),
|
||||||
indexed_assignments: Arc::new(self.indexed_assignments),
|
indexed_bindings: Arc::new(self.indexed_bindings),
|
||||||
dynamic_uniform_indices: if self.dynamic_uniform_indices.is_empty() {
|
dynamic_uniform_indices: if self.dynamic_uniform_indices.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -2,8 +2,8 @@ mod buffer;
|
|||||||
mod texture;
|
mod texture;
|
||||||
mod shared_buffer;
|
mod shared_buffer;
|
||||||
mod render_resource;
|
mod render_resource;
|
||||||
mod render_resource_set;
|
mod bind_group;
|
||||||
mod render_resource_assignments;
|
mod render_resource_bindings;
|
||||||
mod resource_info;
|
mod resource_info;
|
||||||
mod systems;
|
mod systems;
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ pub use buffer::*;
|
|||||||
pub use texture::*;
|
pub use texture::*;
|
||||||
pub use shared_buffer::*;
|
pub use shared_buffer::*;
|
||||||
pub use render_resource::*;
|
pub use render_resource::*;
|
||||||
pub use render_resource_set::*;
|
pub use bind_group::*;
|
||||||
pub use render_resource_assignments::*;
|
pub use render_resource_bindings::*;
|
||||||
pub use resource_info::*;
|
pub use resource_info::*;
|
||||||
pub use systems::*;
|
pub use systems::*;
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
use super::{BufferId, BufferInfo, RenderResource, RenderResourceAssignment};
|
use super::{BufferId, BufferInfo, RenderResource, RenderResourceBinding};
|
||||||
use crate::{render_resource::BufferUsage, renderer::RenderResourceContext};
|
use crate::{render_resource::BufferUsage, renderer::RenderResourceContext};
|
||||||
use legion::systems::Res;
|
use legion::systems::Res;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
@ -23,7 +23,7 @@ impl SharedBuffers {
|
|||||||
&self,
|
&self,
|
||||||
render_resource: &T,
|
render_resource: &T,
|
||||||
buffer_usage: BufferUsage,
|
buffer_usage: BufferUsage,
|
||||||
) -> Option<RenderResourceAssignment> {
|
) -> Option<RenderResourceBinding> {
|
||||||
if let Some(size) = render_resource.buffer_byte_len() {
|
if let Some(size) = render_resource.buffer_byte_len() {
|
||||||
// PERF: this buffer will be slow
|
// PERF: this buffer will be slow
|
||||||
let buffer = self.render_resource_context.create_buffer_mapped(
|
let buffer = self.render_resource_context.create_buffer_mapped(
|
||||||
@ -36,7 +36,7 @@ impl SharedBuffers {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.buffers.write().unwrap().push(buffer);
|
self.buffers.write().unwrap().push(buffer);
|
||||||
Some(RenderResourceAssignment::Buffer {
|
Some(RenderResourceBinding::Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
range: 0..size as u64,
|
range: 0..size as u64,
|
||||||
dynamic_index: None,
|
dynamic_index: None,
|
||||||
|
|||||||
@ -2,47 +2,47 @@ use bevy_asset::Assets;
|
|||||||
use crate::{
|
use crate::{
|
||||||
draw::RenderPipelines,
|
draw::RenderPipelines,
|
||||||
pipeline::{PipelineCompiler, PipelineDescriptor},
|
pipeline::{PipelineCompiler, PipelineDescriptor},
|
||||||
render_resource::{RenderResourceAssignments, RenderResourceSetStatus},
|
render_resource::{RenderResourceBindings, BindGroupStatus},
|
||||||
renderer::{RenderResourceContext, RenderResources},
|
renderer::{RenderResourceContext, RenderResources},
|
||||||
};
|
};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
|
|
||||||
fn update_bind_groups(
|
fn update_bind_groups(
|
||||||
pipeline: &PipelineDescriptor,
|
pipeline: &PipelineDescriptor,
|
||||||
render_resource_assignments: &mut RenderResourceAssignments,
|
render_resource_bindings: &mut RenderResourceBindings,
|
||||||
render_resource_context: &dyn RenderResourceContext,
|
render_resource_context: &dyn RenderResourceContext,
|
||||||
) {
|
) {
|
||||||
let layout = pipeline.get_layout().unwrap();
|
let layout = pipeline.get_layout().unwrap();
|
||||||
for bind_group in layout.bind_groups.iter() {
|
for bind_group_descriptor in layout.bind_groups.iter() {
|
||||||
match render_resource_assignments.update_bind_group(bind_group) {
|
match render_resource_bindings.update_bind_group(bind_group_descriptor) {
|
||||||
RenderResourceSetStatus::Changed(id) => {
|
BindGroupStatus::Changed(id) => {
|
||||||
let render_resource_set = render_resource_assignments
|
let bind_group = render_resource_bindings
|
||||||
.get_render_resource_set(id)
|
.get_bind_group(id)
|
||||||
.expect("RenderResourceSet was just changed, so it should exist");
|
.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
|
// 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()
|
// removal of global context.clear_bind_groups()
|
||||||
// PERF: see above
|
// PERF: see above
|
||||||
RenderResourceSetStatus::Unchanged(id) => {
|
BindGroupStatus::Unchanged(id) => {
|
||||||
let render_resource_set = render_resource_assignments
|
let bind_group = render_resource_bindings
|
||||||
.get_render_resource_set(id)
|
.get_bind_group(id)
|
||||||
.expect("RenderResourceSet was just changed, so it should exist");
|
.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
|
// ignore unchanged / unmatched render resource sets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_resource_sets_system(
|
pub fn bind_groups_system(
|
||||||
world: &mut SubWorld,
|
world: &mut SubWorld,
|
||||||
pipelines: Res<Assets<PipelineDescriptor>>,
|
pipelines: Res<Assets<PipelineDescriptor>>,
|
||||||
pipeline_compiler: Res<PipelineCompiler>,
|
pipeline_compiler: Res<PipelineCompiler>,
|
||||||
render_resources: Res<RenderResources>,
|
render_resources: Res<RenderResources>,
|
||||||
mut render_resource_assignments: ResMut<RenderResourceAssignments>,
|
mut render_resource_bindings: ResMut<RenderResourceBindings>,
|
||||||
query: &mut Query<Write<RenderPipelines>>,
|
query: &mut Query<Write<RenderPipelines>>,
|
||||||
) {
|
) {
|
||||||
let render_resource_context = &*render_resources.context;
|
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();
|
let pipeline = pipelines.get(compiled_pipeline_handle).unwrap();
|
||||||
update_bind_groups(
|
update_bind_groups(
|
||||||
pipeline,
|
pipeline,
|
||||||
&mut render_resource_assignments,
|
&mut render_resource_bindings,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ pub fn render_resource_sets_system(
|
|||||||
let pipeline = pipelines.get(pipeline).unwrap();
|
let pipeline = pipelines.get(pipeline).unwrap();
|
||||||
update_bind_groups(
|
update_bind_groups(
|
||||||
pipeline,
|
pipeline,
|
||||||
&mut render_pipelines.render_resource_assignments,
|
&mut render_pipelines.render_resource_bindings,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use super::RenderResourceContext;
|
use super::RenderResourceContext;
|
||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||||
render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSet, SamplerId, TextureId},
|
render_resource::{BufferId, BufferInfo, RenderResourceId, BindGroup, SamplerId, TextureId},
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
texture::{SamplerDescriptor, TextureDescriptor},
|
texture::{SamplerDescriptor, TextureDescriptor},
|
||||||
};
|
};
|
||||||
@ -102,7 +102,7 @@ impl RenderResourceContext for HeadlessRenderResourceContext {
|
|||||||
fn create_bind_group(
|
fn create_bind_group(
|
||||||
&self,
|
&self,
|
||||||
_bind_group_descriptor_id: BindGroupDescriptorId,
|
_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) {}
|
fn create_shader_module_from_source(&self, _shader_handle: Handle<Shader>, _shader: &Shader) {}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use super::RenderResourceContext;
|
use super::RenderResourceContext;
|
||||||
use crate::{
|
use crate::{
|
||||||
pass::{PassDescriptor, RenderPass},
|
pass::{PassDescriptor, RenderPass},
|
||||||
render_resource::{BufferId, RenderResourceAssignments, TextureId},
|
render_resource::{BufferId, RenderResourceBindings, TextureId},
|
||||||
texture::Extent3d,
|
texture::Extent3d,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ pub trait RenderContext {
|
|||||||
fn begin_pass(
|
fn begin_pass(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_descriptor: &PassDescriptor,
|
pass_descriptor: &PassDescriptor,
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_bindings: &RenderResourceBindings,
|
||||||
run_pass: &mut dyn Fn(&mut dyn RenderPass),
|
run_pass: &mut dyn Fn(&mut dyn RenderPass),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||||
render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSet, SamplerId, TextureId},
|
render_resource::{BufferId, BufferInfo, RenderResourceId, BindGroup, SamplerId, TextureId},
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
texture::{SamplerDescriptor, TextureDescriptor},
|
texture::{SamplerDescriptor, TextureDescriptor},
|
||||||
};
|
};
|
||||||
@ -57,7 +57,7 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
|
|||||||
fn create_bind_group(
|
fn create_bind_group(
|
||||||
&self,
|
&self,
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||||
render_resource_set: &RenderResourceSet,
|
bind_group: &BindGroup,
|
||||||
);
|
);
|
||||||
fn clear_bind_groups(&self);
|
fn clear_bind_groups(&self);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@ where
|
|||||||
{
|
{
|
||||||
for shader_def in shader_defs.iter_shader_defs() {
|
for shader_def in shader_defs.iter_shader_defs() {
|
||||||
render_pipelines
|
render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
.shader_specialization
|
.shader_specialization
|
||||||
.shader_defs
|
.shader_defs
|
||||||
@ -79,7 +79,7 @@ pub fn asset_shader_def_system<T>(
|
|||||||
let shader_defs = assets.get(&asset_handle).unwrap();
|
let shader_defs = assets.get(&asset_handle).unwrap();
|
||||||
for shader_def in shader_defs.iter_shader_defs() {
|
for shader_def in shader_defs.iter_shader_defs() {
|
||||||
render_pipelines
|
render_pipelines
|
||||||
.render_resource_assignments
|
.render_resource_bindings
|
||||||
.pipeline_specialization
|
.pipeline_specialization
|
||||||
.shader_specialization
|
.shader_specialization
|
||||||
.shader_defs
|
.shader_defs
|
||||||
|
|||||||
@ -61,7 +61,7 @@ impl<'a> Drawable for DrawableText<'a> {
|
|||||||
// draw.set_global_bind_groups()?;
|
// draw.set_global_bind_groups()?;
|
||||||
|
|
||||||
// // TODO: ideally the TexureAtlas bind group is automatically generated by AssetRenderResourcesNode and is retrievable
|
// // 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()
|
// let mut atlas_set = RenderResourceSet::build()
|
||||||
// .add_assignment(0, draw.get_uniform_buffer(&10)?)
|
// .add_assignment(0, draw.get_uniform_buffer(&10)?)
|
||||||
// .finish();
|
// .finish();
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use bevy_asset::{Assets, Handle};
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
draw::Draw,
|
draw::Draw,
|
||||||
pipeline::PipelineDescriptor,
|
pipeline::PipelineDescriptor,
|
||||||
render_resource::{RenderResourceAssignments, SharedBuffers},
|
render_resource::{RenderResourceBindings, SharedBuffers},
|
||||||
renderer::RenderResources,
|
renderer::RenderResources,
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
Color,
|
Color,
|
||||||
@ -79,7 +79,7 @@ impl Label {
|
|||||||
|
|
||||||
pub fn draw_label_system(
|
pub fn draw_label_system(
|
||||||
_pipelines: Res<Assets<PipelineDescriptor>>,
|
_pipelines: Res<Assets<PipelineDescriptor>>,
|
||||||
_render_resource_assignments: Res<RenderResourceAssignments>,
|
_render_resource_bindings: Res<RenderResourceBindings>,
|
||||||
_render_resources: Res<RenderResources>,
|
_render_resources: Res<RenderResources>,
|
||||||
_shared_buffers: Res<SharedBuffers>,
|
_shared_buffers: Res<SharedBuffers>,
|
||||||
_fonts: Res<Assets<Font>>,
|
_fonts: Res<Assets<Font>>,
|
||||||
@ -93,7 +93,7 @@ impl Label {
|
|||||||
// let mut draw_context = draw.get_context(
|
// let mut draw_context = draw.get_context(
|
||||||
// &pipelines,
|
// &pipelines,
|
||||||
// context,
|
// context,
|
||||||
// &render_resource_assignments,
|
// &render_resource_bindings,
|
||||||
// &shared_buffers,
|
// &shared_buffers,
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use bevy_render::{
|
|||||||
PassDescriptor, RenderPass, RenderPassColorAttachmentDescriptor,
|
PassDescriptor, RenderPass, RenderPassColorAttachmentDescriptor,
|
||||||
RenderPassDepthStencilAttachmentDescriptor, TextureAttachment,
|
RenderPassDepthStencilAttachmentDescriptor, TextureAttachment,
|
||||||
},
|
},
|
||||||
render_resource::{BufferId, RenderResourceAssignment, RenderResourceAssignments, TextureId},
|
render_resource::{BufferId, RenderResourceBinding, RenderResourceBindings, TextureId},
|
||||||
renderer::{RenderContext, RenderResourceContext},
|
renderer::{RenderContext, RenderResourceContext},
|
||||||
texture::Extent3d,
|
texture::Extent3d,
|
||||||
};
|
};
|
||||||
@ -121,7 +121,7 @@ impl RenderContext for WgpuRenderContext {
|
|||||||
fn begin_pass(
|
fn begin_pass(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_descriptor: &PassDescriptor,
|
pass_descriptor: &PassDescriptor,
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_bindings: &RenderResourceBindings,
|
||||||
run_pass: &mut dyn Fn(&mut dyn RenderPass),
|
run_pass: &mut dyn Fn(&mut dyn RenderPass),
|
||||||
) {
|
) {
|
||||||
if !self.command_encoder.is_some() {
|
if !self.command_encoder.is_some() {
|
||||||
@ -133,7 +133,7 @@ impl RenderContext for WgpuRenderContext {
|
|||||||
{
|
{
|
||||||
let render_pass = create_render_pass(
|
let render_pass = create_render_pass(
|
||||||
pass_descriptor,
|
pass_descriptor,
|
||||||
render_resource_assignments,
|
render_resource_bindings,
|
||||||
&refs,
|
&refs,
|
||||||
&mut encoder,
|
&mut encoder,
|
||||||
);
|
);
|
||||||
@ -153,7 +153,7 @@ impl RenderContext for WgpuRenderContext {
|
|||||||
|
|
||||||
pub fn create_render_pass<'a, 'b>(
|
pub fn create_render_pass<'a, 'b>(
|
||||||
pass_descriptor: &PassDescriptor,
|
pass_descriptor: &PassDescriptor,
|
||||||
global_render_resource_assignments: &'b RenderResourceAssignments,
|
global_render_resource_bindings: &'b RenderResourceBindings,
|
||||||
refs: &WgpuResourceRefs<'a>,
|
refs: &WgpuResourceRefs<'a>,
|
||||||
encoder: &'a mut wgpu::CommandEncoder,
|
encoder: &'a mut wgpu::CommandEncoder,
|
||||||
) -> wgpu::RenderPass<'a> {
|
) -> wgpu::RenderPass<'a> {
|
||||||
@ -162,12 +162,12 @@ pub fn create_render_pass<'a, 'b>(
|
|||||||
.color_attachments
|
.color_attachments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| {
|
.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>>(),
|
.collect::<Vec<wgpu::RenderPassColorAttachmentDescriptor>>(),
|
||||||
depth_stencil_attachment: pass_descriptor.depth_stencil_attachment.as_ref().map(|d| {
|
depth_stencil_attachment: pass_descriptor.depth_stencil_attachment.as_ref().map(|d| {
|
||||||
create_wgpu_depth_stencil_attachment_descriptor(
|
create_wgpu_depth_stencil_attachment_descriptor(
|
||||||
global_render_resource_assignments,
|
global_render_resource_bindings,
|
||||||
refs,
|
refs,
|
||||||
d,
|
d,
|
||||||
)
|
)
|
||||||
@ -176,13 +176,13 @@ pub fn create_render_pass<'a, 'b>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_view<'a>(
|
fn get_texture_view<'a>(
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
global_render_resource_bindings: &RenderResourceBindings,
|
||||||
refs: &WgpuResourceRefs<'a>,
|
refs: &WgpuResourceRefs<'a>,
|
||||||
attachment: &TextureAttachment,
|
attachment: &TextureAttachment,
|
||||||
) -> &'a wgpu::TextureView {
|
) -> &'a wgpu::TextureView {
|
||||||
match attachment {
|
match attachment {
|
||||||
TextureAttachment::Name(name) => match global_render_resource_assignments.get(&name) {
|
TextureAttachment::Name(name) => match global_render_resource_bindings.get(&name) {
|
||||||
Some(RenderResourceAssignment::Texture(resource)) => refs.textures.get(&resource).unwrap(),
|
Some(RenderResourceBinding::Texture(resource)) => refs.textures.get(&resource).unwrap(),
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Color attachment {} does not exist", name);
|
panic!("Color attachment {} does not exist", name);
|
||||||
}
|
}
|
||||||
@ -193,12 +193,12 @@ fn get_texture_view<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_wgpu_color_attachment_descriptor<'a>(
|
fn create_wgpu_color_attachment_descriptor<'a>(
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
global_render_resource_bindings: &RenderResourceBindings,
|
||||||
refs: &WgpuResourceRefs<'a>,
|
refs: &WgpuResourceRefs<'a>,
|
||||||
color_attachment_descriptor: &RenderPassColorAttachmentDescriptor,
|
color_attachment_descriptor: &RenderPassColorAttachmentDescriptor,
|
||||||
) -> wgpu::RenderPassColorAttachmentDescriptor<'a> {
|
) -> wgpu::RenderPassColorAttachmentDescriptor<'a> {
|
||||||
let attachment = get_texture_view(
|
let attachment = get_texture_view(
|
||||||
global_render_resource_assignments,
|
global_render_resource_bindings,
|
||||||
refs,
|
refs,
|
||||||
&color_attachment_descriptor.attachment,
|
&color_attachment_descriptor.attachment,
|
||||||
);
|
);
|
||||||
@ -206,7 +206,7 @@ fn create_wgpu_color_attachment_descriptor<'a>(
|
|||||||
let resolve_target = color_attachment_descriptor
|
let resolve_target = color_attachment_descriptor
|
||||||
.resolve_target
|
.resolve_target
|
||||||
.as_ref()
|
.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 {
|
wgpu::RenderPassColorAttachmentDescriptor {
|
||||||
store_op: color_attachment_descriptor.store_op.wgpu_into(),
|
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>(
|
fn create_wgpu_depth_stencil_attachment_descriptor<'a>(
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
global_render_resource_bindings: &RenderResourceBindings,
|
||||||
refs: &WgpuResourceRefs<'a>,
|
refs: &WgpuResourceRefs<'a>,
|
||||||
depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor,
|
depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor,
|
||||||
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> {
|
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> {
|
||||||
let attachment = get_texture_view(
|
let attachment = get_texture_view(
|
||||||
global_render_resource_assignments,
|
global_render_resource_bindings,
|
||||||
refs,
|
refs,
|
||||||
&depth_stencil_attachment_descriptor.attachment,
|
&depth_stencil_attachment_descriptor.attachment,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use bevy_asset::{Assets, Handle, HandleUntyped};
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BufferId, BufferInfo, RenderResourceId, RenderResourceAssignment, RenderResourceSet, SamplerId,
|
BufferId, BufferInfo, RenderResourceId, RenderResourceBinding, BindGroup, SamplerId,
|
||||||
TextureId,
|
TextureId,
|
||||||
},
|
},
|
||||||
renderer::RenderResourceContext,
|
renderer::RenderResourceContext,
|
||||||
@ -432,15 +432,15 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
|||||||
fn create_bind_group(
|
fn create_bind_group(
|
||||||
&self,
|
&self,
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||||
render_resource_set: &RenderResourceSet,
|
bind_group: &BindGroup,
|
||||||
) {
|
) {
|
||||||
if !self
|
if !self
|
||||||
.resources
|
.resources
|
||||||
.has_bind_group(bind_group_descriptor_id, render_resource_set.id)
|
.has_bind_group(bind_group_descriptor_id, bind_group.id)
|
||||||
{
|
{
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"start creating bind group for RenderResourceSet {:?}",
|
"start creating bind group for RenderResourceSet {:?}",
|
||||||
render_resource_set.id
|
bind_group.id
|
||||||
);
|
);
|
||||||
let texture_views = self.resources.texture_views.read().unwrap();
|
let texture_views = self.resources.texture_views.read().unwrap();
|
||||||
let samplers = self.resources.samplers.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 bind_group_layouts = self.resources.bind_group_layouts.read().unwrap();
|
||||||
let mut bind_groups = self.resources.bind_groups.write().unwrap();
|
let mut bind_groups = self.resources.bind_groups.write().unwrap();
|
||||||
|
|
||||||
let bindings = render_resource_set
|
let bindings = bind_group
|
||||||
.indexed_assignments
|
.indexed_bindings
|
||||||
.iter()
|
.iter()
|
||||||
.map(|indexed_assignment| {
|
.map(|indexed_binding| {
|
||||||
let wgpu_resource = match &indexed_assignment.assignment {
|
let wgpu_resource = match &indexed_binding.binding {
|
||||||
RenderResourceAssignment::Texture(resource) => {
|
RenderResourceBinding::Texture(resource) => {
|
||||||
let texture_view = texture_views
|
let texture_view = texture_views
|
||||||
.get(&resource)
|
.get(&resource)
|
||||||
.expect(&format!("{:?}", resource));
|
.expect(&format!("{:?}", resource));
|
||||||
wgpu::BindingResource::TextureView(texture_view)
|
wgpu::BindingResource::TextureView(texture_view)
|
||||||
}
|
}
|
||||||
RenderResourceAssignment::Sampler(resource) => {
|
RenderResourceBinding::Sampler(resource) => {
|
||||||
let sampler = samplers.get(&resource).unwrap();
|
let sampler = samplers.get(&resource).unwrap();
|
||||||
wgpu::BindingResource::Sampler(sampler)
|
wgpu::BindingResource::Sampler(sampler)
|
||||||
}
|
}
|
||||||
RenderResourceAssignment::Buffer { buffer, range, .. } => {
|
RenderResourceBinding::Buffer { buffer, range, .. } => {
|
||||||
let wgpu_buffer = buffers.get(&buffer).unwrap();
|
let wgpu_buffer = buffers.get(&buffer).unwrap();
|
||||||
wgpu::BindingResource::Buffer(wgpu_buffer.slice(range.clone()))
|
wgpu::BindingResource::Buffer(wgpu_buffer.slice(range.clone()))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
wgpu::Binding {
|
wgpu::Binding {
|
||||||
binding: indexed_assignment.index,
|
binding: indexed_binding.index,
|
||||||
resource: wgpu_resource,
|
resource: wgpu_resource,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -488,10 +488,10 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
|||||||
.or_insert_with(|| WgpuBindGroupInfo::default());
|
.or_insert_with(|| WgpuBindGroupInfo::default());
|
||||||
bind_group_info
|
bind_group_info
|
||||||
.bind_groups
|
.bind_groups
|
||||||
.insert(render_resource_set.id, wgpu_bind_group);
|
.insert(bind_group.id, wgpu_bind_group);
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"created bind group for RenderResourceSet {:?}",
|
"created bind group for RenderResourceSet {:?}",
|
||||||
render_resource_set.id
|
bind_group.id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use bevy_asset::Handle;
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pass::RenderPass,
|
pass::RenderPass,
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||||
render_resource::{BufferId, RenderResourceSetId},
|
render_resource::{BufferId, BindGroupId},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
};
|
};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
@ -53,7 +53,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
index: u32,
|
index: u32,
|
||||||
bind_group_descriptor: BindGroupDescriptorId,
|
bind_group_descriptor: BindGroupDescriptorId,
|
||||||
render_resource_set: RenderResourceSetId,
|
bind_group: BindGroupId,
|
||||||
dynamic_uniform_indices: Option<&[u32]>,
|
dynamic_uniform_indices: Option<&[u32]>,
|
||||||
) {
|
) {
|
||||||
if let Some(bind_group_info) = self
|
if let Some(bind_group_info) = self
|
||||||
@ -61,7 +61,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
|
|||||||
.bind_groups
|
.bind_groups
|
||||||
.get(&bind_group_descriptor)
|
.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] = &[];
|
const EMPTY: &'static [u32] = &[];
|
||||||
let dynamic_uniform_indices =
|
let dynamic_uniform_indices =
|
||||||
if let Some(dynamic_uniform_indices) = 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 {:?} {:?}: {:?}",
|
"set bind group {:?} {:?}: {:?}",
|
||||||
bind_group_descriptor,
|
bind_group_descriptor,
|
||||||
dynamic_uniform_indices,
|
dynamic_uniform_indices,
|
||||||
render_resource_set
|
bind_group
|
||||||
);
|
);
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_bind_group(index, wgpu_bind_group, dynamic_uniform_indices);
|
.set_bind_group(index, wgpu_bind_group, dynamic_uniform_indices);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use bevy_asset::{Handle, HandleUntyped};
|
use bevy_asset::{Handle, HandleUntyped};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||||
render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSetId, SamplerId, TextureId},
|
render_resource::{BufferId, BufferInfo, RenderResourceId, BindGroupId, SamplerId, TextureId},
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
texture::TextureDescriptor,
|
texture::TextureDescriptor,
|
||||||
};
|
};
|
||||||
@ -13,7 +13,7 @@ use std::{
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WgpuBindGroupInfo {
|
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
|
/// 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(
|
pub fn has_bind_group(
|
||||||
&self,
|
&self,
|
||||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||||
render_resource_set_id: RenderResourceSetId,
|
bind_group_id: BindGroupId,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some(bind_group_info) = self
|
if let Some(bind_group_info) = self
|
||||||
.bind_groups
|
.bind_groups
|
||||||
@ -110,7 +110,7 @@ impl WgpuResources {
|
|||||||
{
|
{
|
||||||
bind_group_info
|
bind_group_info
|
||||||
.bind_groups
|
.bind_groups
|
||||||
.get(&render_resource_set_id)
|
.get(&bind_group_id)
|
||||||
.is_some()
|
.is_some()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user