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